Changeset 671 for cpp/frams/genetics/f1
- Timestamp:
- 08/18/17 15:24:59 (7 years ago)
- Location:
- cpp/frams/genetics/f1
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/genetics/f1/conv_f1.cpp
r534 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 10 10 #include <ctype.h> 11 11 12 //#define v1f1COMPATIBLE 13 14 F1Props stdprops ={1, 0, 1, 0.4, 0.25, 0.25, 0.25, 0.25, 0.0, 1.0, 1.0, 1,15 0.2, 0.5,0.5,0.5 };12 //#define v1f1COMPATIBLE //as in ancient Framsticks 1.x 13 14 F1Props stdprops = { 1, 0, 1, 0.4, 0.25, 0.25, 0.25, 0.25, 0.0, 1.0, 1.0, 1, 15 0.2, 0.5, 0.5, 0.5 }; 16 16 17 17 class Builder 18 18 { 19 19 public: 20 Builder(const char*g,int mapping=0):invalid(0),genbegin(g),usemapping(mapping),first_part_mapping(NULL),energ(0),energ_div(0) {} 21 ~Builder() {SAFEDELETE(first_part_mapping);} 22 char tmp[222]; 23 bool invalid; 24 Model model; 25 const char *genbegin; 26 SList neuro_f1_to_f0; // neuro_f1_to_f0(f1_refno) = actual neuro pointer 27 Neuro *last_f1_neuro; 28 SyntParam *neuro_cls_param; 29 30 struct Connection { int n1,n2; double w; 31 Connection(int _n1,int _n2, double _w):n1(_n1),n2(_n2),w(_w) {} }; 32 33 SListTempl<Connection> connections; 34 int usemapping; 35 MultiRange range; 36 MultiRange *first_part_mapping; 37 double lastjoint_muscle_power; 38 double energ,energ_div; 39 void grow(int part1,const char*g,Pt3D k,F1Props c); 40 void setPartMapping(int p,const char* g); 41 int growJoint(int part1,int part2,Pt3D &angle,F1Props &c,const char *g); 42 int growPart(F1Props &c,const char *g); 43 const char *skipNeuro(const char *z); 44 const char* growNeuro(const char* t,F1Props &c,int&); 45 void growConnection(const char* begin,const char* colon,const char* end,F1Props& props); 46 int countBranches(const char*g,SList &out); 47 SyntParam* lastNeuroClassParam(); 48 void addClassParam(const char* name,double value); 49 void addClassParam(const char* name,const char* value); 50 51 const MultiRange* makeRange(const char*g) {return makeRange(g,g);} 52 const MultiRange* makeRange(const char*g,const char*g2); 53 Part *getLastPart() {return getLastJoint()->part2;} 54 Neuro *getLastNeuro() {return model.getNeuro(model.getNeuroCount()-1);} 55 Joint *getLastJoint() {return model.getJoint(model.getJointCount()-1);} 56 void addOrRememberInput(int n1,int n2,double w) 57 { 20 Builder(const char*g, int mapping = 0) :invalid(0), genbegin(g), usemapping(mapping), first_part_mapping(NULL), model_energy(0), model_energy_max(0) {} 21 ~Builder() { SAFEDELETE(first_part_mapping); } 22 char tmp[222]; 23 bool invalid; 24 Model model; 25 const char *genbegin; 26 SList neuro_f1_to_f0; // neuro_f1_to_f0(f1_refno) = actual neuro pointer 27 Neuro *last_f1_neuro; 28 SyntParam *neuro_cls_param; 29 30 struct Connection 31 { 32 int n1, n2; double w; 33 Connection(int _n1, int _n2, double _w) :n1(_n1), n2(_n2), w(_w) {} 34 }; 35 36 SListTempl<Connection> connections; 37 int usemapping; 38 MultiRange range; 39 MultiRange *first_part_mapping; 40 double lastjoint_muscle_power; 41 double model_energy, model_energy_max; 42 void grow(int part1, const char*g, Pt3D k, F1Props c); 43 void setPartMapping(int p, const char* g); 44 int growJoint(int part1, int part2, Pt3D &angle, F1Props &c, const char *g); 45 int growPart(F1Props &c, const char *g); 46 const char *skipNeuro(const char *z); 47 const char* growNeuro(const char* t, F1Props &c, int&); 48 void growConnection(const char* begin, const char* colon, const char* end, F1Props& props); 49 int countBranches(const char*g, SList &out); 50 SyntParam* lastNeuroClassParam(); 51 void addClassParam(const char* name, double value); 52 void addClassParam(const char* name, const char* value); 53 54 const MultiRange* makeRange(const char*g) { return makeRange(g, g); } 55 const MultiRange* makeRange(const char*g, const char*g2); 56 Part *getLastPart() { return getLastJoint()->part2; } 57 Neuro *getLastNeuro() { return model.getNeuro(model.getNeuroCount() - 1); } 58 Joint *getLastJoint() { return model.getJoint(model.getJointCount() - 1); } 59 void addOrRememberInput(int n1, int n2, double w) 60 { 58 61 //if (!addInput(n1,n2,w,false)) 59 connections +=Connection(n1,n2,w);60 61 bool addInput(int n1,int n2,double w,bool final)62 63 if ((n1 <0) || (n2<0) || (n1>=neuro_f1_to_f0.size()) || (n2>=neuro_f1_to_f0.size()))64 65 if (final) logPrintf("GenoConvF1", "addInput",LOG_WARN,66 "illegal neuron connection %d <- %d (ignored)",n1,n2);62 connections += Connection(n1, n2, w); 63 } 64 bool addInput(int n1, int n2, double w, bool final) 65 { 66 if ((n1 < 0) || (n2 < 0) || (n1 >= neuro_f1_to_f0.size()) || (n2 >= neuro_f1_to_f0.size())) 67 { 68 if (final) logPrintf("GenoConvF1", "addInput", LOG_WARN, 69 "illegal neuron connection %d <- %d (ignored)", n1, n2); 67 70 return 0; 68 69 Neuro *neuro =(Neuro*)neuro_f1_to_f0(n1);70 Neuro *input =(Neuro*)neuro_f1_to_f0(n2);71 neuro->addInput(input, w);71 } 72 Neuro *neuro = (Neuro*)neuro_f1_to_f0(n1); 73 Neuro *input = (Neuro*)neuro_f1_to_f0(n2); 74 neuro->addInput(input, w); 72 75 return 1; 73 74 void addPendingInputs()75 76 for (int i=0;i<connections.size();i++)77 78 Connection *c =&connections(i);79 addInput(c->n1, c->n2,c->w,true);80 81 76 } 77 void addPendingInputs() 78 { 79 for (int i = 0; i < connections.size(); i++) 80 { 81 Connection *c = &connections(i); 82 addInput(c->n1, c->n2, c->w, true); 83 } 84 } 82 85 }; 83 86 84 const MultiRange* Builder::makeRange(const char*g, const char*g2)85 { 86 if (!usemapping) return 0;87 range.clear();88 range.add(g-genbegin,g2-genbegin);89 return ⦥90 } 91 92 void F1Props:: wykluczanie()93 { 94 double s=ruch+asym+odpor+wchl;95 ruch=ruch/s;96 asym=asym/s;97 odpor=odpor/s;98 wchl=wchl/s;87 const MultiRange* Builder::makeRange(const char*g, const char*g2) 88 { 89 if (!usemapping) return 0; 90 range.clear(); 91 range.add(g - genbegin, g2 - genbegin); 92 return ⦥ 93 } 94 95 void F1Props::normalizeBiol4() 96 { 97 double sum = muscle_power + assimilation + stamina + ingestion; 98 muscle_power /= sum; 99 assimilation /= sum; 100 stamina /= sum; 101 ingestion /= sum; 99 102 } 100 103 101 104 /** main conversion function - with conversion map support */ 102 SString GenoConv_f1::convert(SString &i, MultiMap *map)103 { 104 const char* g=i.c_str();105 Builder builder(g,map?1:0);106 builder.model.open();107 builder.grow(-1,g,Pt3D_0,stdprops); // uses Model::singleStepBuild to create model elements108 if (builder.invalid) return SString();109 builder.addPendingInputs();110 builder.model.startenergy=(builder.energ_div>0)?(builder.energ/builder.energ_div):1.0;111 builder.model.close(); // model is ready to use now112 if (map) builder.model.getCurrentToF0Map(*map); // generate f1-to-f0 conversion map113 return builder.model.getF0Geno().getGenes();114 } 115 116 void Builder::setPartMapping(int p, const char* g)117 { 118 if (!usemapping) return;119 const MultiRange *r=makeRange(g);120 if (p<0)105 SString GenoConv_f1::convert(SString &i, MultiMap *map) 106 { 107 const char* g = i.c_str(); 108 Builder builder(g, map ? 1 : 0); 109 builder.model.open(); 110 builder.grow(-1, g, Pt3D_0, stdprops); // uses Model::singleStepBuild to create model elements 111 if (builder.invalid) return SString(); 112 builder.addPendingInputs(); 113 builder.model.startenergy = (builder.model_energy_max > 0) ? (builder.model_energy / builder.model_energy_max) : 1.0; 114 builder.model.close(); // model is ready to use now 115 if (map) builder.model.getCurrentToF0Map(*map); // generate f1-to-f0 conversion map 116 return builder.model.getF0Geno().getGenes(); 117 } 118 119 void Builder::setPartMapping(int p, const char* g) 120 { 121 if (!usemapping) return; 122 const MultiRange *r = makeRange(g); 123 if (p < 0) 121 124 { //special case: mapping the part which is not yet created 122 if (first_part_mapping) first_part_mapping->add(*r);123 else first_part_mapping=new MultiRange(*r);124 } 125 else126 model.getPart(p)->addMapping(*r);127 } 128 129 void Builder::grow(int part1, const char*g,Pt3D k,F1Props c)130 { 131 int hasmuscles=0;132 k+=Pt3D(c.rot,0,c.skr);133 while(1)134 {135 switch(*g)136 {137 case 0: case ',': case ')': return;138 case 'R': k.x+=0.7853; setPartMapping(part1,g); break;139 case 'r': k.x-=0.7853; setPartMapping(part1,g); break;140 case 'Q': c.rot+=(1.58-c.rot)*0.3; setPartMapping(part1,g); break;141 case 'q': c.rot+=(-1.58-c.rot)*0.3; setPartMapping(part1,g); break;125 if (first_part_mapping) first_part_mapping->add(*r); 126 else first_part_mapping = new MultiRange(*r); 127 } 128 else 129 model.getPart(p)->addMapping(*r); 130 } 131 132 void Builder::grow(int part1, const char*g, Pt3D k, F1Props c) 133 { 134 int hasmuscles = 0; 135 k += Pt3D(c.twist, 0, c.curvedness); 136 while (1) 137 { 138 switch (*g) 139 { 140 case 0: case ',': case ')': return; 141 case 'R': k.x += 0.7853; setPartMapping(part1, g); break; 142 case 'r': k.x -= 0.7853; setPartMapping(part1, g); break; 143 case 'Q': c.twist += (1.58 - c.twist)*0.3; setPartMapping(part1, g); break; 144 case 'q': c.twist += (-1.58 - c.twist)*0.3; setPartMapping(part1, g); break; 142 145 #ifdef v1f1COMPATIBLE 143 case 'L': c.dlug+=(3.0-c.dlug)*0.3; setPartMapping(part1,g); break;146 case 'L': c.length += (3.0 - c.length)*0.3; setPartMapping(part1, g); break; 144 147 #else 145 case 'L': c.dlug+=(2.0-c.dlug)*0.3; setPartMapping(part1,g); break;148 case 'L': c.length += (2.0 - c.length)*0.3; setPartMapping(part1, g); break; 146 149 #endif 147 case 'l': c.dlug+=(0.33-c.dlug)*0.3; setPartMapping(part1,g); break;148 case 'A': c.asym+=(1-c.asym)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;149 case 'a': c.asym-=c.asym*0.4; c.wykluczanie(); setPartMapping(part1,g); break;150 case 'I': c.wchl+=(1-c.wchl)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;151 case 'i': c.wchl-=c.wchl*0.4; c.wykluczanie(); setPartMapping(part1,g); break;152 case 'S': c.odpor+=(1-c.odpor)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;153 case 's': c.odpor-=c.odpor*0.4; c.wykluczanie(); setPartMapping(part1,g); break;154 case 'M': c.ruch+=(1-c.ruch)*0.8; c.wykluczanie(); setPartMapping(part1,g); break;155 case 'm': c.ruch-=c.ruch*0.4; c.wykluczanie(); setPartMapping(part1,g); break;156 case 'C': c.skr+=(2.0-c.skr)*0.25; setPartMapping(part1,g); break;157 case 'c': c.skr+=(-2.0-c.skr)*0.25; setPartMapping(part1,g); break;158 case 'F': c.tarcie+=(4-c.tarcie)*0.2; setPartMapping(part1,g); break;159 case 'f': c.tarcie-=c.tarcie*0.2; setPartMapping(part1,g); break;160 case 'W': c.masa+=(2.0-c.masa)*0.3; setPartMapping(part1,g); break;161 case 'w': c.masa+=(0.5-c.masa)*0.3; setPartMapping(part1,g); break;162 case 'E': c.energ+=(10.0-c.energ)*0.1; setPartMapping(part1,g); break;163 case 'e': c.energ-=c.energ*0.1; setPartMapping(part1,g); break;164 165 case 'D': c.cred+=(1.0-c.cred)*0.25; setPartMapping(part1,g); break;166 case 'd': c.cred+=(0.0-c.cred)*0.25; setPartMapping(part1,g); break;167 case 'G': c.cgreen+=(1.0-c.cgreen)*0.25; setPartMapping(part1,g); break;168 case 'g': c.cgreen+=(0.0-c.cgreen)*0.25; setPartMapping(part1,g); break;169 case 'B': c.cblue+=(1.0-c.cblue)*0.25; setPartMapping(part1,g); break;170 case 'b': c.cblue+=(0.0-c.cblue)*0.25; setPartMapping(part1,g); break;171 case 'H': c.grub+=(0.7-c.grub)*0.25; setPartMapping(part1,g); break;172 case 'h': c.grub+=(0.05-c.grub)*0.25; setPartMapping(part1,g); break;173 174 case '[': //neuron175 // setdebug(g-(char*)geny,DEBUGNEURO | !l_neu);176 if (model.getJointCount())177 g=growNeuro(g+1,c,hasmuscles);178 else179 { 180 logMessage("GenoConv_F1","grow",1,"Illegal neuron position (ignored)");181 g=skipNeuro(g+1);182 } 183 break;184 case 'X':185 { 186 int freshpart=0;187 //setdebug(g-(char*)geny,DEBUGEST | !l_est);188 if (part1<0) //initial grow189 { 190 if (model.getPartCount()>0)191 part1=0;192 193 194 part1=growPart(c,g);195 freshpart=1;196 197 198 199 200 if (!freshpart)201 { 202 Part *part=model.getPart(part1);203 part->density=((part->mass*part->density)+1.0/c.masa)/(part->mass+1.0); // v=m*d204 // part->volume+=1.0/c.masa;205 part->mass+=1.0;206 } 207 energ+=0.9*c.energ+0.1;208 energ_div+=1.0;209 210 int part2 = growPart(c,g);211 growJoint(part1,part2,k,c,g);212 // est* e = new est(*s,*s2,k,c,zz,this);213 214 // oslabianie cech wzdluz struktury215 c.dlug=0.5*c.dlug+0.5*stdprops.dlug;216 c.grub=0.5*c.grub+0.5*stdprops.grub;217 c.skr=0.66*c.skr;218 c.rot=0.66*c.rot;219 c.tarcie=0.8*c.tarcie+0.2*stdprops.tarcie;220 221 c.asym=0.8*c.asym+0.2*stdprops.asym;222 c.odpor=0.8*c.odpor+0.2*stdprops.odpor;223 c.ruch=0.8*c.ruch+0.2*stdprops.ruch;224 c.wchl=0.8*c.wchl+0.2*stdprops.wchl;225 c.masa+=(stdprops.masa-c.masa)*0.5;226 c.wykluczanie();227 228 if (c.resetrange) c.bendrange=1.0; else c.resetrange=1;229 grow(part2,g+1,Pt3D_0,c);230 return;231 } 232 case '(':233 { 234 setPartMapping(part1,g);235 SList ga;236 int i,ile;237 ile=countBranches(g+1,ga);238 c.resetrange=0;239 c.bendrange=1.0/ile;240 for (i=0;i<ile;i++)241 grow(part1,(char*)ga(i),k+Pt3D(0,0,-3.141+(i+1)*(6.282/(ile+1))),c);242 return;243 } 244 case ' ': case '\t': case '\n': case '\r': break;245 default: invalid=1; return;246 }247 g++;150 case 'l': c.length += (0.33 - c.length)*0.3; setPartMapping(part1, g); break; 151 case 'A': c.assimilation += (1 - c.assimilation)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 152 case 'a': c.assimilation -= c.assimilation*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 153 case 'I': c.ingestion += (1 - c.ingestion)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 154 case 'i': c.ingestion -= c.ingestion*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 155 case 'S': c.stamina += (1 - c.stamina)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 156 case 's': c.stamina -= c.stamina*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 157 case 'M': c.muscle_power += (1 - c.muscle_power)*0.8; c.normalizeBiol4(); setPartMapping(part1, g); break; 158 case 'm': c.muscle_power -= c.muscle_power*0.4; c.normalizeBiol4(); setPartMapping(part1, g); break; 159 case 'C': c.curvedness += (2.0 - c.curvedness)*0.25; setPartMapping(part1, g); break; 160 case 'c': c.curvedness += (-2.0 - c.curvedness)*0.25; setPartMapping(part1, g); break; 161 case 'F': c.friction += (4 - c.friction)*0.2; setPartMapping(part1, g); break; 162 case 'f': c.friction -= c.friction*0.2; setPartMapping(part1, g); break; 163 case 'W': c.weight += (2.0 - c.weight)*0.3; setPartMapping(part1, g); break; 164 case 'w': c.weight += (0.5 - c.weight)*0.3; setPartMapping(part1, g); break; 165 case 'E': c.energy += (10.0 - c.energy)*0.1; setPartMapping(part1, g); break; 166 case 'e': c.energy -= c.energy*0.1; setPartMapping(part1, g); break; 167 168 case 'D': c.cred += (1.0 - c.cred)*0.25; setPartMapping(part1, g); break; 169 case 'd': c.cred += (0.0 - c.cred)*0.25; setPartMapping(part1, g); break; 170 case 'G': c.cgreen += (1.0 - c.cgreen)*0.25; setPartMapping(part1, g); break; 171 case 'g': c.cgreen += (0.0 - c.cgreen)*0.25; setPartMapping(part1, g); break; 172 case 'B': c.cblue += (1.0 - c.cblue)*0.25; setPartMapping(part1, g); break; 173 case 'b': c.cblue += (0.0 - c.cblue)*0.25; setPartMapping(part1, g); break; 174 case 'H': c.visual_size += (0.7 - c.visual_size)*0.25; setPartMapping(part1, g); break; 175 case 'h': c.visual_size += (0.05 - c.visual_size)*0.25; setPartMapping(part1, g); break; 176 177 case '[': //neuron 178 // setdebug(g-(char*)geny,DEBUGNEURO | !l_neu); 179 if (model.getJointCount()) 180 g = growNeuro(g + 1, c, hasmuscles); 181 else 182 { 183 logMessage("GenoConv_F1", "grow", 1, "Illegal neuron position (ignored)"); 184 g = skipNeuro(g + 1); 185 } 186 break; 187 case 'X': 188 { 189 int freshpart = 0; 190 //setdebug(g-(char*)geny,DEBUGEST | !l_est); 191 if (part1 < 0) //initial grow 192 { 193 if (model.getPartCount() > 0) 194 part1 = 0; 195 else 196 { 197 part1 = growPart(c, g); 198 freshpart = 1; 199 if (first_part_mapping) 200 model.getPart(part1)->setMapping(*first_part_mapping); 201 } 202 } 203 if (!freshpart) 204 { 205 Part *part = model.getPart(part1); 206 part->density = ((part->mass*part->density) + 1.0 / c.weight) / (part->mass + 1.0); // v=m*d 207 // part->volume+=1.0/c.weight; 208 part->mass += 1.0; 209 } 210 model_energy += 0.9*c.energy + 0.1; 211 model_energy_max += 1.0; 212 213 int part2 = growPart(c, g); 214 growJoint(part1, part2, k, c, g); 215 // est* e = new est(*s,*s2,k,c,zz,this); 216 217 // attenuate properties as they are propagated along the structure 218 c.length = 0.5*c.length + 0.5*stdprops.length; 219 c.visual_size = 0.5*c.visual_size + 0.5*stdprops.visual_size; 220 c.curvedness = 0.66*c.curvedness; 221 c.twist = 0.66*c.twist; 222 c.friction = 0.8*c.friction + 0.2*stdprops.friction; 223 224 c.assimilation = 0.8*c.assimilation + 0.2*stdprops.assimilation; 225 c.stamina = 0.8*c.stamina + 0.2*stdprops.stamina; 226 c.muscle_power = 0.8*c.muscle_power + 0.2*stdprops.muscle_power; 227 c.ingestion = 0.8*c.ingestion + 0.2*stdprops.ingestion; 228 c.weight += (stdprops.weight - c.weight)*0.5; 229 c.normalizeBiol4(); 230 231 if (c.muscle_reset_range) c.muscle_bend_range = 1.0; else c.muscle_reset_range = true; 232 grow(part2, g + 1, Pt3D_0, c); 233 return; 234 } 235 case '(': 236 { 237 setPartMapping(part1, g); 238 SList ga; 239 int i, count; 240 count = countBranches(g + 1, ga); 241 c.muscle_reset_range = false; 242 c.muscle_bend_range = 1.0 / count; 243 for (i = 0; i < count; i++) 244 grow(part1, (char*)ga(i), k + Pt3D(0, 0, -M_PI + (i + 1)*(2*M_PI / (count + 1))), c); 245 return; 246 } 247 case ' ': case '\t': case '\n': case '\r': break; 248 default: invalid = 1; return; 249 } 250 g++; 248 251 } 249 252 } … … 251 254 SyntParam* Builder::lastNeuroClassParam() 252 255 { 253 if (!neuro_cls_param)254 { 255 NeuroClass *cls=last_f1_neuro->getClass();256 if (cls)257 { 258 neuro_cls_param=new SyntParam(last_f1_neuro->classProperties());259 // this is equivalent to:260 // SyntParam tmp=last_f1_neuro->classProperties();261 // neuro_cls_param=new SyntParam(tmp);262 // interestingly, some compilers eliminate the call to new SyntParam,263 // realizing that a copy constructor is redundant when the original object is264 // temporary. there are no side effect of such optimization, as long as the265 // copy-constructed object is exact equivalent of the original.266 } 267 } 268 return neuro_cls_param;269 } 270 271 void Builder::addClassParam(const char* name, double value)272 { 273 lastNeuroClassParam();274 if (neuro_cls_param)275 neuro_cls_param->setDoubleById(name,value);276 } 277 278 void Builder::addClassParam(const char* name, const char* value)279 { 280 lastNeuroClassParam();281 if (neuro_cls_param)282 { 283 ExtValue e(value);284 const ExtValue &re(e);285 neuro_cls_param->setById(name,re);286 } 287 } 288 289 int Builder::countBranches(const char*g, SList &out)290 { 291 int gl=0;292 out+=(void*)g;293 while (gl>=0)294 { 295 switch(*g)296 { 297 case 0: gl =-1; break;256 if (!neuro_cls_param) 257 { 258 NeuroClass *cls = last_f1_neuro->getClass(); 259 if (cls) 260 { 261 neuro_cls_param = new SyntParam(last_f1_neuro->classProperties()); 262 // this is equivalent to: 263 // SyntParam tmp=last_f1_neuro->classProperties(); 264 // neuro_cls_param=new SyntParam(tmp); 265 // interestingly, some compilers eliminate the call to new SyntParam, 266 // realizing that a copy constructor is redundant when the original object is 267 // temporary. there are no side effect of such optimization, as long as the 268 // copy-constructed object is exact equivalent of the original. 269 } 270 } 271 return neuro_cls_param; 272 } 273 274 void Builder::addClassParam(const char* name, double value) 275 { 276 lastNeuroClassParam(); 277 if (neuro_cls_param) 278 neuro_cls_param->setDoubleById(name, value); 279 } 280 281 void Builder::addClassParam(const char* name, const char* value) 282 { 283 lastNeuroClassParam(); 284 if (neuro_cls_param) 285 { 286 ExtValue e(value); 287 const ExtValue &re(e); 288 neuro_cls_param->setById(name, re); 289 } 290 } 291 292 int Builder::countBranches(const char*g, SList &out) 293 { 294 int gl = 0; 295 out += (void*)g; 296 while (gl >= 0) 297 { 298 switch (*g) 299 { 300 case 0: gl = -1; break; 298 301 case '(': case '[': ++gl; break; 299 302 case ')': case ']': --gl; break; 300 case ',': if (!gl) out +=(void*)(g+1);301 } 302 g++;303 } 304 return out.size();305 } 306 307 int Builder::growJoint(int part1, int part2,Pt3D &angle,F1Props &c,const char *g)308 { 309 double len=min(2.0,c.dlug);310 sprintf(tmp,"j:p1=%ld,p2=%ld,dx=%lg,rx=%lg,ry=%lg,rz=%lg,stam=%lg,vr=%g,vg=%g,vb=%g",311 part1,part2,len,angle.x,angle.y,angle.z,c.odpor, c.cred,c.cgreen,c.cblue);312 lastjoint_muscle_power=c.ruch;313 return model.singleStepBuild(tmp,makeRange(g));314 } 315 316 int Builder::growPart(F1Props &c, const char *g)317 { 318 sprintf(tmp,"p:dn=%lg,fr=%lg,ing=%lg,as=%lg,vs=%g,vr=%g,vg=%g,vb=%g",319 1.0/c.masa,c.tarcie,c.wchl,c.asym, c.grub, c.cred,c.cgreen,c.cblue);320 return model.singleStepBuild(tmp,makeRange(g));303 case ',': if (!gl) out += (void*)(g + 1); 304 } 305 g++; 306 } 307 return out.size(); 308 } 309 310 int Builder::growJoint(int part1, int part2, Pt3D &angle, F1Props &c, const char *g) 311 { 312 double len = min(2.0, c.length); 313 sprintf(tmp, "j:p1=%ld,p2=%ld,dx=%lg,rx=%lg,ry=%lg,rz=%lg,stam=%lg,vr=%g,vg=%g,vb=%g", 314 part1, part2, len, angle.x, angle.y, angle.z, c.stamina, c.cred, c.cgreen, c.cblue); 315 lastjoint_muscle_power = c.muscle_power; 316 return model.singleStepBuild(tmp, makeRange(g)); 317 } 318 319 int Builder::growPart(F1Props &c, const char *g) 320 { 321 sprintf(tmp, "p:dn=%lg,fr=%lg,ing=%lg,as=%lg,vs=%g,vr=%g,vg=%g,vb=%g", 322 1.0 / c.weight, c.friction, c.ingestion, c.assimilation, c.visual_size, c.cred, c.cgreen, c.cblue); 323 return model.singleStepBuild(tmp, makeRange(g)); 321 324 } 322 325 323 326 const char *Builder::skipNeuro(const char *z) 324 327 { 325 for (;*z;z++) if ((*z==']')||(*z==')')) break;326 return z-1;327 } 328 329 const char* Builder::growNeuro(const char* t, F1Props& props, int &hasmuscles)330 { 331 const char*neuroend=skipNeuro(t);332 last_f1_neuro=model.addNewNeuro();333 neuro_cls_param=NULL;334 last_f1_neuro->attachToPart(getLastPart());335 const MultiRange *mr=makeRange(t-1,neuroend+1);336 if (mr) last_f1_neuro->addMapping(*mr);337 neuro_f1_to_f0+=last_f1_neuro;338 339 SString clsname;340 bool haveclass=0;341 while(*t && *t<=' ') t++;342 const char* next=(*t)?(t+1):t;343 while(*next && *next<=' ') next++;344 if (*t && *next!=',' && *next!=']') // old style muscles [|rest] or [@rest]345 switch(*t)346 { 347 case '@': if (t[1]==':') break;348 haveclass=1;349 // if (!(hasmuscles&1))350 351 hasmuscles|=1;352 Neuro *muscle=model.addNewNeuro();353 sprintf(tmp,"@:p=%lg",lastjoint_muscle_power);354 355 356 357 358 359 t++;360 break;361 case '|': if (t[1]==':') break;362 haveclass=1;363 // if (!(hasmuscles&2))364 365 hasmuscles|=2;366 Neuro *muscle=model.addNewNeuro();367 sprintf(tmp,"|:p=%lg,r=%lg",lastjoint_muscle_power,props.bendrange);368 369 370 371 372 373 t++;374 break;375 } 376 while(*t && *t<=' ') t++;377 bool finished=0;378 const char *begin=t;379 const char* colon=0;380 SString classparams;381 while(!finished)382 { 383 switch (*t)384 { 385 case ':': colon =t; break;386 case 0: case ']': case ')': finished =1;328 for (; *z; z++) if ((*z == ']') || (*z == ')')) break; 329 return z - 1; 330 } 331 332 const char* Builder::growNeuro(const char* t, F1Props& props, int &hasmuscles) 333 { 334 const char*neuroend = skipNeuro(t); 335 last_f1_neuro = model.addNewNeuro(); 336 neuro_cls_param = NULL; 337 last_f1_neuro->attachToPart(getLastPart()); 338 const MultiRange *mr = makeRange(t - 1, neuroend + 1); 339 if (mr) last_f1_neuro->addMapping(*mr); 340 neuro_f1_to_f0 += last_f1_neuro; 341 342 SString clsname; 343 bool haveclass = 0; 344 while (*t && *t <= ' ') t++; 345 const char* next = (*t) ? (t + 1) : t; 346 while (*next && *next <= ' ') next++; 347 if (*t && *next != ',' && *next != ']') // old style muscles [|rest] or [@rest] 348 switch (*t) 349 { 350 case '@': if (t[1] == ':') break; 351 haveclass = 1; 352 // if (!(hasmuscles&1)) 353 { 354 hasmuscles |= 1; 355 Neuro *muscle = model.addNewNeuro(); 356 sprintf(tmp, "@:p=%lg", lastjoint_muscle_power); 357 muscle->addInput(last_f1_neuro); 358 muscle->setDetails(tmp); 359 muscle->attachToJoint(getLastJoint()); 360 if (usemapping) muscle->addMapping(*makeRange(t)); 361 } 362 t++; 363 break; 364 case '|': if (t[1] == ':') break; 365 haveclass = 1; 366 // if (!(hasmuscles&2)) 367 { 368 hasmuscles |= 2; 369 Neuro *muscle = model.addNewNeuro(); 370 sprintf(tmp, "|:p=%lg,r=%lg", lastjoint_muscle_power, props.muscle_bend_range); 371 muscle->addInput(last_f1_neuro); 372 muscle->setDetails(tmp); 373 muscle->attachToJoint(getLastJoint()); 374 if (usemapping) muscle->addMapping(*makeRange(t)); 375 } 376 t++; 377 break; 378 } 379 while (*t && *t <= ' ') t++; 380 bool finished = 0; 381 const char *begin = t; 382 const char* colon = 0; 383 SString classparams; 384 while (!finished) 385 { 386 switch (*t) 387 { 388 case ':': colon = t; break; 389 case 0: case ']': case ')': finished = 1; 387 390 // NO break! 388 391 case ',': 389 if ( !haveclass && !colon && t>begin ) 392 if (!haveclass && !colon && t > begin) 393 { 394 haveclass = 1; 395 SString clsname(begin, t - begin); 396 clsname = trim(clsname); 397 last_f1_neuro->setClassName(clsname); 398 NeuroClass *cls = last_f1_neuro->getClass(); 399 if (cls) 390 400 { 391 haveclass=1; 392 SString clsname(begin,t-begin); 393 clsname=trim(clsname); 394 last_f1_neuro->setClassName(clsname); 395 NeuroClass *cls=last_f1_neuro->getClass(); 396 if (cls) 397 { 398 if (cls->getPreferredLocation()==2) 401 if (cls->getPreferredLocation() == 2) 399 402 last_f1_neuro->attachToJoint(getLastJoint()); 400 else if (cls->getPreferredLocation() ==1)403 else if (cls->getPreferredLocation() == 1) 401 404 last_f1_neuro->attachToPart(getLastPart()); 402 405 403 406 lastNeuroClassParam(); 404 407 //special handling: muscle properties (can be overwritten by subsequent property assignments) 405 if (!strcmp(cls->getName().c_str(),"|")) 406 { 407 neuro_cls_param->setDoubleById("p",lastjoint_muscle_power); 408 neuro_cls_param->setDoubleById("r",props.bendrange); 409 } 410 else if (!strcmp(cls->getName().c_str(),"@")) 411 { 412 neuro_cls_param->setDoubleById("p",lastjoint_muscle_power); 413 } 408 if (!strcmp(cls->getName().c_str(), "|")) 409 { 410 neuro_cls_param->setDoubleById("p", lastjoint_muscle_power); 411 neuro_cls_param->setDoubleById("r", props.muscle_bend_range); 412 } 413 else if (!strcmp(cls->getName().c_str(), "@")) 414 { 415 neuro_cls_param->setDoubleById("p", lastjoint_muscle_power); 414 416 } 415 417 } 416 else if (colon && (colon>begin) && (t>colon)) 417 growConnection(begin,colon,t,props); 418 if (t[0]!=',') t--; 419 begin=t+1; colon=0; 418 } 419 else if (colon && (colon > begin) && (t > colon)) 420 growConnection(begin, colon, t, props); 421 if (t[0] != ',') t--; 422 begin = t + 1; colon = 0; 420 423 break; 421 424 } 422 t++;423 } 424 SAFEDELETE(neuro_cls_param);425 return t;426 } 427 void Builder::growConnection(const char* begin, const char* colon, const char* end,F1Props& props)428 { 429 while(*begin && *begin<=' ') begin++;430 int i;431 if (isdigit(begin[0]) || (begin[0]=='-'))432 { 433 double weight=ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str());434 paInt relative=ExtValue::getInt(trim(SString(begin,colon-begin)).c_str(),false);435 int this_refno=neuro_f1_to_f0.size()-1;436 addOrRememberInput(this_refno,this_refno+relative,weight);437 } 438 else if ((i=last_f1_neuro->extraProperties().findIdn(begin,colon-begin))>=0)439 { 440 last_f1_neuro->extraProperties().set(i,colon+1);441 } 442 else if (isupper(begin[0]) || strchr("*|@",begin[0]))443 { 444 SString clsname(begin,colon-begin);445 trim(clsname);446 Neuro *receptor=model.addNewNeuro();447 receptor->setClassName(clsname);448 NeuroClass *cls=receptor->getClass();449 if (cls)450 { 451 if (cls->getPreferredLocation()==2) receptor->attachToJoint(getLastJoint());452 else if (cls->getPreferredLocation()==1) receptor->attachToPart(getLastPart());453 } 454 last_f1_neuro->addInput(receptor,ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));455 if (usemapping) receptor->addMapping(*makeRange(begin,end-1));456 } 457 else if ((begin[0]=='>')&&(begin[1]))458 { 459 Neuro *out=model.addNewNeuro();460 out->addInput(last_f1_neuro,ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));461 out->setClassName(SString(begin+1,end-colon-1));462 if (begin[1]=='@')463 { 464 sprintf(tmp,"p=%lg",lastjoint_muscle_power);465 out->setClassParams(tmp);466 } 467 else if (begin[1]=='|')468 { 469 sprintf(tmp,"p=%lg,r=%lg",lastjoint_muscle_power,props.bendrange);470 out->setClassParams(tmp);471 } 472 NeuroClass *cls=out->getClass();473 if (cls)474 { 475 if (cls->getPreferredLocation()==2) out->attachToJoint(getLastJoint());476 else if (cls->getPreferredLocation()==1) out->attachToPart(getLastPart());477 } 478 if (usemapping) out->addMapping(*makeRange(begin,end-1));479 } 480 else if (*begin=='!') addClassParam("fo",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));481 else if (*begin=='=') addClassParam("in",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));482 else if (*begin=='/') addClassParam("si",ExtValue::getDouble(trim(SString(colon+1,end-(colon+1))).c_str()));483 else if (islower(begin[0]))484 { 485 SString name(begin,colon-begin);486 SString value(colon+1,end-(colon+1));487 addClassParam(name.c_str(),value.c_str());488 } 489 } 425 t++; 426 } 427 SAFEDELETE(neuro_cls_param); 428 return t; 429 } 430 void Builder::growConnection(const char* begin, const char* colon, const char* end, F1Props& props) 431 { 432 while (*begin && *begin <= ' ') begin++; 433 int i; 434 if (isdigit(begin[0]) || (begin[0] == '-')) 435 { 436 double conn_weight = ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str()); 437 paInt relative = ExtValue::getInt(trim(SString(begin, colon - begin)).c_str(), false); 438 int this_refno = neuro_f1_to_f0.size() - 1; 439 addOrRememberInput(this_refno, this_refno + relative, conn_weight); 440 } 441 else if ((i = last_f1_neuro->extraProperties().findIdn(begin, colon - begin)) >= 0) 442 { 443 last_f1_neuro->extraProperties().set(i, colon + 1); 444 } 445 else if (isupper(begin[0]) || strchr("*|@", begin[0])) 446 { 447 SString clsname(begin, colon - begin); 448 trim(clsname); 449 Neuro *receptor = model.addNewNeuro(); 450 receptor->setClassName(clsname); 451 NeuroClass *cls = receptor->getClass(); 452 if (cls) 453 { 454 if (cls->getPreferredLocation() == 2) receptor->attachToJoint(getLastJoint()); 455 else if (cls->getPreferredLocation() == 1) receptor->attachToPart(getLastPart()); 456 } 457 last_f1_neuro->addInput(receptor, ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 458 if (usemapping) receptor->addMapping(*makeRange(begin, end - 1)); 459 } 460 else if ((begin[0] == '>') && (begin[1])) 461 { 462 Neuro *out = model.addNewNeuro(); 463 out->addInput(last_f1_neuro, ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 464 out->setClassName(SString(begin + 1, end - colon - 1)); 465 if (begin[1] == '@') 466 { 467 sprintf(tmp, "p=%lg", lastjoint_muscle_power); 468 out->setClassParams(tmp); 469 } 470 else if (begin[1] == '|') 471 { 472 sprintf(tmp, "p=%lg,r=%lg", lastjoint_muscle_power, props.muscle_bend_range); 473 out->setClassParams(tmp); 474 } 475 NeuroClass *cls = out->getClass(); 476 if (cls) 477 { 478 if (cls->getPreferredLocation() == 2) out->attachToJoint(getLastJoint()); 479 else if (cls->getPreferredLocation() == 1) out->attachToPart(getLastPart()); 480 } 481 if (usemapping) out->addMapping(*makeRange(begin, end - 1)); 482 } 483 else if (*begin == '!') addClassParam("fo", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 484 else if (*begin == '=') addClassParam("in", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 485 else if (*begin == '/') addClassParam("si", ExtValue::getDouble(trim(SString(colon + 1, end - (colon + 1))).c_str())); 486 else if (islower(begin[0])) 487 { 488 SString name(begin, colon - begin); 489 SString value(colon + 1, end - (colon + 1)); 490 addClassParam(name.c_str(), value.c_str()); 491 } 492 } -
cpp/frams/genetics/f1/conv_f1.h
r408 r671 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 5Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2017 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 11 11 struct F1Props 12 12 { 13 double dlug,skr,masa,tarcie,ruch,asym,odpor,wchl,rot,energ;14 double bendrange;15 int resetrange;16 double grub,cred,cgreen,cblue;17 void wykluczanie();13 double length, curvedness, weight, friction, muscle_power, assimilation, stamina, ingestion, twist, energy; 14 double muscle_bend_range; 15 bool muscle_reset_range; 16 double visual_size, cred, cgreen, cblue; 17 void normalizeBiol4(); 18 18 }; 19 19 … … 49 49 Another example: 50 50 51 "X[G][-1:2.3][-2:3.4]" - The first neuron is the standalone G receptor. Other neuron can use its output 51 "X[G][-1:2.3][-2:3.4]" - The first neuron is the standalone G receptor. Other neuron can use its output 52 52 signal by specifying it as regular input ("-1:2.3" and "-2:3.4"). This NN contains 3 neurons. 53 53 \image html nn-ex3.gif … … 57 57 Adding another neuron with "G" input will add another gyroscope object. This NN contains 4 neurons 58 58 (or 2 neurons if you try it in Framsticks v1). 59 60 61 */62 class GenoConv_f1 : public GenoConverter59 \image html nn-ex4.gif 60 61 */ 62 class GenoConv_f1 : public GenoConverter 63 63 { 64 64 public: 65 GenoConv_f1()65 GenoConv_f1() 66 66 { 67 name="Recursive encoding";68 in_format='1';69 mapsupport=1;67 name = "Recursive encoding"; 68 in_format = '1'; 69 mapsupport = 1; 70 70 } 71 SString convert(SString &i,MultiMap *map);72 ~GenoConv_f1() {}71 SString convert(SString &i, MultiMap *map); 72 ~GenoConv_f1() {} 73 73 }; 74 74
Note: See TracChangeset
for help on using the changeset viewer.