From cc076744dc47669d699719507a88c92857678007 Mon Sep 17 00:00:00 2001 From: Amira Abdel-Rahman <aabdelrahman@gsd.harvard.edu> Date: Wed, 26 Jun 2019 17:45:20 -0400 Subject: [PATCH] multi-level search, order then parameters --- cpp_frep/frep_tree.cpp | 33 ++++-- cpp_frep/main.cpp | 256 ++++++++++++++++++++++++----------------- 2 files changed, 173 insertions(+), 116 deletions(-) diff --git a/cpp_frep/frep_tree.cpp b/cpp_frep/frep_tree.cpp index e34901f..2acf38c 100644 --- a/cpp_frep/frep_tree.cpp +++ b/cpp_frep/frep_tree.cpp @@ -79,7 +79,7 @@ namespace cpp_frep { return genome.size()-numPrimitives;//numPrimitives number of primitives } - int dimensions(){ + int dimension(){ int n=3; if(parametric)n=5; @@ -99,7 +99,7 @@ namespace cpp_frep { std::string getPrintedGenome(){ int n=2; - if (parametric) n=1; + if (parametric) n=2; std::string g=""; for (unsigned int i =0; i<genome.size()-numPrimitives;++i){ g+=to_string_with_precision(genome[i][0],n); @@ -107,12 +107,12 @@ namespace cpp_frep { g+=to_string_with_precision(genome[i][1],n); g+="/"; g+=to_string_with_precision(genome[i][2],n); - if(parametric){ + // if(parametric){ g+="/"; g+=to_string_with_precision(genome[i][3],n); g+="/"; g+=to_string_with_precision(genome[i][4],n); - } + // } g+=" "; } return g; @@ -138,7 +138,7 @@ namespace cpp_frep { const scalar nodeLength=12.0f; static const int numPrimitives=2; - static const int storageSpace=20; + static const int storageSpace=30; Add ArrayAdd [storageSpace]; Subtract ArraySubtract [storageSpace]; @@ -288,6 +288,7 @@ namespace cpp_frep { std::cout<<")"; ArrayMorph[n].weight=0.5; if (parametric) ArrayMorph[n].weight=genome[index][3]; + else genome[index][3]=ArrayMorph[n].weight; return &ArrayMorph[n]; } case 4: { @@ -301,6 +302,9 @@ namespace cpp_frep { if (parametric) { ArrayTranslate[n].dx=genome[index][3]*bound*2.0f-bound; ArrayTranslate[n].dy=genome[index][4]*bound*2.0f-bound; + }else{ + genome[index][3]=(ArrayTranslate[n].dx+bound)/bound/2.0f; + genome[index][4]=(ArrayTranslate[n].dy+bound)/bound/2.0f; } return &ArrayTranslate[n]; } @@ -315,6 +319,10 @@ namespace cpp_frep { if (parametric) { ArrayScale[n].sx=genome[index][3]*bound*0.75f+0.5f; ArrayScale[n].sy=genome[index][4]*bound*0.75f+0.5f; + }else{ + genome[index][3]=(ArrayScale[n].sx-0.5f)/(bound*0.75); + genome[index][4]=(ArrayScale[n].sy-0.5f)/(bound*0.75); + } return &ArrayScale[n]; } @@ -327,6 +335,7 @@ namespace cpp_frep { else ArrayRotate[n].setShape(getNode(shapeIndex,0)); std::cout<<")"; if (parametric) ArrayRotate[n].angle=genome[index][3]*360.0; + else genome[index][3]=ArrayRotate[n].angle/360.0f; return &ArrayRotate[n]; } case 7: { @@ -338,9 +347,11 @@ namespace cpp_frep { else ArrayLinearArrayX[n].setShape(getNode(shapeIndex,0)); std::cout<<")"; if (parametric) { - // ArrayLinearArrayX[n].size=genome[index][3]*bound; ArrayLinearArrayX[n].spacing=genome[index][3]*bound/2.0f; ArrayLinearArrayX[n].number=(int)(genome[index][4]*bound); + }else{ + genome[index][3]=ArrayLinearArrayX[n].spacing*2.0f/bound; + genome[index][4]=(scalar)ArrayLinearArrayX[n].number/bound; } return &ArrayLinearArrayX[n]; } @@ -353,9 +364,12 @@ namespace cpp_frep { else ArrayLinearArrayY[n].setShape(getNode(shapeIndex,0)); std::cout<<")"; if (parametric) { - ArrayLinearArrayY[n].size=genome[index][3]*bound; - ArrayLinearArrayY[n].spacing=ArrayLinearArrayY[n].size/2; + // ArrayLinearArrayY[n].size=genome[index][3]*bound; + ArrayLinearArrayY[n].spacing=genome[index][3]*bound/2.0f; ArrayLinearArrayY[n].number=(int)(genome[index][4]*bound); + }else{ + genome[index][3]=ArrayLinearArrayY[n].spacing*2.0f/bound; + genome[index][4]=(scalar)ArrayLinearArrayY[n].number/bound; } return &ArrayLinearArrayY[n]; } @@ -370,6 +384,9 @@ namespace cpp_frep { if (parametric) { ArrayPolarArray[n].angle=genome[index][3]*360.0f; ArrayPolarArray[n].radius=genome[index][4]*bound*0.75f+0.5f; + }else{ + genome[index][3]=ArrayPolarArray[n].angle/360.0; + genome[index][4]=(ArrayPolarArray[n].radius-0.5f)/(bound*0.75f); } return &ArrayPolarArray[n]; } diff --git a/cpp_frep/main.cpp b/cpp_frep/main.cpp index 1fac4dc..b123ad7 100755 --- a/cpp_frep/main.cpp +++ b/cpp_frep/main.cpp @@ -100,6 +100,8 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca } // std::cout << '\n'; + + ////////////////create image and save it////////////////////////// cv::Mat image = cv::Mat(width, height, CV_8UC4, pix); float scale=0.3; @@ -129,7 +131,7 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca } - std::string fileName=name+".jpg"; + std::string fileName="img/"+name+".jpg"; cv::imwrite( fileName, image ); if(preview){ cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE ); @@ -188,7 +190,7 @@ void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar cv::Scalar(0,0,0), // BGR Color 1); // Line Thickness (Optional) - std::string fileName=name+".jpg"; + std::string fileName="img/"+name+".jpg"; cv::imwrite( fileName, image ); if(preview){ cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE ); @@ -199,13 +201,20 @@ void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar } //compare between a target frep and target frep tree -float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name){ +float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar bound, scalar res ,std::string name, bool tuneParameters){ + + scalar minX=-bound; + scalar maxX=bound; + scalar minY=-bound; + scalar maxY=bound; + scalar dx=res; + scalar dy=res; int height=(int)((maxX-minX)/dx); int width=(int)((maxY-minY)/dy); const int size=height*width*4; - std::string fileName=name+".jpg"; + std::string fileName="img/"+name+".jpg"; int stride=0; unsigned char pix[size]; @@ -214,13 +223,22 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max std::vector<std::vector<scalar>> g= frep_tree->getGenome(); if (frep_tree->parametric){ - for (int i =0; i<frep_tree->numNodes();++i){ - g[i][0]=(v.at(i*5+0)); - g[i][1]=(v.at(i*5+1)); - g[i][2]=(v.at(i*5+2)); - g[i][3]=(v.at(i*5+3)); - g[i][4]=(v.at(i*5+4)); + if(tuneParameters){ + for (int i =0; i<frep_tree->numNodes();++i){ + g[i][3]=(v.at(i*2+0)); + g[i][4]=(v.at(i*2+1)); + } + + }else{ + for (int i =0; i<frep_tree->numNodes();++i){ + g[i][0]=(v.at(i*5+0)); + g[i][1]=(v.at(i*5+1)); + g[i][2]=(v.at(i*5+2)); + g[i][3]=(v.at(i*5+3)); + g[i][4]=(v.at(i*5+4)); + } } + }else{ for (int i =0; i<frep_tree->numNodes();++i){ g[i][0]=(v.at(i*3+0)); @@ -269,6 +287,9 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max float result= (float)same/((float)size/4.0f); std::cout<<result <<"\n"; + + ////////////////create image and save it////////////////////////// + cv::Mat image = cv::Mat(width, height, CV_8UC4, pix); float scale=0.3; @@ -306,24 +327,106 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max } //get random float between 0 and 1 -float getRandom(){//between 0 and 1 +scalar getRandom(){//between 0 and 1 return ((float) rand() / (RAND_MAX)); } +scalar getNoise(scalar scale){//between 0 and 1 + return ((scalar) rand() / (RAND_MAX))/scale-scale/2.0; +} //get random genome -Vector getRandomGenome(int n, bool parametric){ +Vector getRandomGenome(int n){ std::vector<float> v; - if(parametric){ - for(int i=0;i<n*5;++i){ - v.push_back(getRandom()); + for(int i=0;i<n;++i){ + v.push_back(getRandom()); + } + return Vector(v); +} + +Vector getParameters(std::vector<std::vector<scalar>> genome,bool noise, scalar scale){ + std::vector<scalar> v; + for (unsigned int i =0; i<genome.size();++i){ + if (noise){ + v.push_back(genome[i][3]+getNoise(scale)); + v.push_back(genome[i][4]+getNoise(scale)); + + }else{ + v.push_back(genome[i][3]); + v.push_back(genome[i][4]); } + } + return Vector(v); +} + +void nelderMead(Frep_tree* tree,Frep* target,float precision, int maxSteps, bool tuneParameters, scalar bound, scalar res){ + + scalar minX=-bound; + scalar maxX=bound; + scalar minY=-bound; + scalar maxY=bound; + scalar dx=res; + scalar dy=res; + + drawFrep(target,minX, maxX, minY, maxY, dx, dy,"target",false); + + + int dimension=tree->dimension(); + if (tuneParameters) dimension= tree->numNodes()*2; + NelderMeadOptimizer o(dimension, precision); + + // request a simplex to start with + + Vector v; + + + if(tuneParameters){ + + v=getParameters(tree->getGenome(),false, 0.001f); + o.insert(v); + o.insert(getParameters(tree->getGenome(),false, 0.001f)); + o.insert(getParameters(tree->getGenome(),false, 0.001f)); + std::cout<<"dim: "<<dimension<<", "<<v.dimension()<<"\n"; }else{ - for(int i=0;i<n*3;++i){ - v.push_back(getRandom()); - } + v=getRandomGenome(dimension); + o.insert(v); + o.insert(getRandomGenome(dimension)); + o.insert(getRandomGenome(dimension)); + } - return Vector(v); + + + int count=0; + float score=0.0f; + + // while ( !o.done(score)&&count<maxSteps) { //cap + while ( !o.done(score)) { + // if(count>maxSteps||o.done()){ + if(count>maxSteps){ + count=0; + std::cout<<"Counld't find solution, reset with random values!!!!!!!!!!!!!!!!!!!\n"; + o.reset(); + if(!tuneParameters){ + o.insert(v); + o.insert(getRandomGenome(dimension)); + o.insert(getRandomGenome(dimension)); + + }else{ + o.insert(getParameters(tree->getGenome(),false, 0.001f)); + o.insert(getParameters(tree->getGenome(),false, 0.001f)); + + } + + } + std::cout<<"Step:"<<count<<"\n"; + + std::string name1 = "i"; + if(tuneParameters) name1 = "j"; + std::string name=name1+std::to_string(count); + score=compareL1( v, target, tree, bound,res , name,tuneParameters); + v = o.step(v,score ); + count++; + } } @@ -334,9 +437,10 @@ int main(int const, char const**) { bool smooth=true; - bool parametric=true; + bool parametric=false; + bool tuneParameters=false; - float precision = 0.01; + float precision = 0.001; scalar minX=-bound; @@ -345,6 +449,8 @@ int main(int const, char const**) { scalar maxY=bound; scalar dx=res; scalar dy=res; + + std::vector<std::vector<scalar>> genome; @@ -352,20 +458,18 @@ int main(int const, char const**) { node1.push_back(0.34); node1.push_back(0.1); node1.push_back(0.95); - if (parametric){ - node1.push_back(0.5024); - node1.push_back(0.7475); - } + node1.push_back(0.5024); + node1.push_back(0.7475); + genome.push_back(node1); std::vector<scalar> node2; node2.push_back(0.48); node2.push_back(0.3); node2.push_back(0.9); - if (parametric){ - node2.push_back(0.17); - node2.push_back(0.227); - } + node2.push_back(0.17); + node2.push_back(0.227); + genome.push_back(node2); // std::vector<scalar> node3; @@ -379,98 +483,34 @@ int main(int const, char const**) { // genome.push_back(node3); Frep_tree tree(genome,smooth,parametric,bound); - // genome[0][0]=0.1; - // tree.updateGenome(genome); - // drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"image22",true); - - - - int dimension = tree.dimensions(); - NelderMeadOptimizer o(dimension, precision); - - // request a simplex to start with - - int n =tree.numNodes(); - Vector v=getRandomGenome(n,parametric); - o.insert(v); - o.insert(getRandomGenome(n,parametric)); - o.insert(getRandomGenome(n,parametric)); - - Circle c(1.0f,0.0f,0.0f); Rectangle r(-1.0f,1.0f,-1.0f,1.0f); Subtract s(&r,&c); PolarArray pa(&r,0.0f, 0.0f, 45.0f,-1.0f); - drawFrep(&pa,minX, maxX, minY, maxY, dx, dy,"target",false); - int count=0; - - float score=0.0f; - int maxSteps=100; - while ( !o.done(score)&&count<maxSteps) { - // while ( !o.done(score)) { - if(count>maxSteps||o.done()){ - count=0; - std::cout<<"Counld't find solution, reset with random values!!!!!!!!!!!!!!!!!!!\n"; - o.reset(); - o.insert(v); - o.insert(getRandomGenome(n,parametric)); - o.insert(getRandomGenome(n,parametric)); - } - std::cout<<"Step:"<<count<<"\n"; - - std::string name1 = "i"; - std::string name=name1+std::to_string(count); - score=compareL1( v, &s, &tree, minX, maxX, minY, maxY, dx, dy, name); - v = o.step(v,score ); - count++; - } - - - - - // Circle c(1.0f,0.0f,0.0f); - // // drawFrep(&c,minX, maxX, minY, maxY, dx, dy); - // Circle *cc; - // cc=new Circle(); - // c=*cc; - // drawFrep(cc,minX, maxX, minY, maxY, dx, dy); - // drawFrep(&c,minX, maxX, minY, maxY, dx, dy); + int maxSteps=50; + precision=0.01; + nelderMead(&tree,&pa, precision, maxSteps, tuneParameters, bound, res); + drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"final",false); - // Translate t(&c,0.0f,1.5f); - // drawFrep(&t,minX, maxX, minY, maxY, dx, dy); + tree.printGenome(); - // Scale sc(&t,0.0f,0.0f,2.0f,2.0f); - // drawFrep(&sc,minX, maxX, minY, maxY, dx, dy); - // sc.printName(); - // std::cout<<"\n"; + // //////////tune parameters////////// + std::cout<<"Tuning parameters!!!!!!!!!!!!!!!!!!!\n"; + parametric=true; + tree.parametric=parametric; + tuneParameters=true; + precision=0.0075; + maxSteps=20; - // Rectangle r(-1.0f,1.0f,-1.0f,1.0f); - // drawFrep(&r,minX, maxX, minY, maxY, dx, dy); + nelderMead(&tree,&pa, precision, maxSteps, tuneParameters, bound, res); - // Rotate rt(&r,0.0f,0.0f,15.0f); - // drawFrep(&rt,minX, maxX, minY, maxY, dx, dy); + drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"finalt",false); - // LinearArrayY la(&r,0.2f,4.0f,1.0); - // drawFrep(&la,minX, maxX, minY, maxY, dx, dy); - - // Add a(&t,&r); - // drawFrep(&a,minX, maxX, minY, maxY, dx, dy); - - // Subtract s(&r,&t); - // drawFrep(&s,minX, maxX, minY, maxY, dx, dy); - - // Intersect i(&t,&r); - // drawFrep(&i,minX, maxX, minY, maxY, dx, dy); - - // Clearance cl(&t,&r,1.0); - // drawFrep(&cl,minX, maxX, minY, maxY, dx, dy); - - // PolarArray pa(&r,0.0f, 0.0f, 45.0f,-1.0f); - // drawFrep(&pa,minX, maxX, minY, maxY, dx, dy); + //0 add, 1 subtract, 2 intersect, 3 morph, 4 translate, 5 scale, 6 rotate, 7 linearArray, 8 polar array return 0; -- GitLab