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