source: cpp/geno_fx/geno_fx.cpp @ 98

Last change on this file since 98 was 66, checked in by Maciej Komosinski, 14 years ago

set 'eol-style' to 'native'

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1// This file is a part of the Framsticks GenoFX library.
2// Copyright (C) 2002-2011  Maciej Komosinski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <ctype.h>  //isupper()
6#include "geno_fx.h"
7#include "framsg.h"
8#include "rndutil.h"
9
10int Geno_fx::roulette(const double *probtab,const int count)
11{
12   double sum=0;
13   int i;
14   for (i=0;i<count;i++) sum+=probtab[i];
15   double sel=rnd01*sum;
16   for (sum=0,i=0;i<count;i++) {sum+=probtab[i]; if (sel<sum) return i;}
17   return -1;
18}
19
20bool Geno_fx::getMinMaxDef(ParamInterface *p,int i,double &mn,double &mx,double &def)
21{
22   mn=mx=def=0;
23   int defined=0;
24   if (p->type(i)[0]=='f')
25   {
26      double _mn=0,_mx=1,_def=0.5;
27      defined=p->getMinMax(i,_mn,_mx,_def);
28      if (defined==1) _mx=_mn+1.0;
29      if (_mx<_mn && defined==3) _mn=_mx=_def; //only default was defined, let's assume min=max=default
30      if (defined<3) _def=(_mn+_mx)/2.0;
31      mn=_mn; mx=_mx; def=_def;
32   }
33   if (p->type(i)[0]=='d')
34   {
35      long _mn=0,_mx=1,_def=0;
36      defined=p->getMinMax(i,_mn,_mx,_def);
37      if (defined==1) _mx=_mn+1;
38      if (_mx<_mn && defined==3) _mn=_mx=_def; //only default was defined, let's assume min=max=default
39      if (defined<3) _def=(_mn+_mx)/2;
40      mn=_mn; mx=_mx; def=_def;
41   }
42   return defined==3;
43}
44
45int Geno_fx::selectRandomProperty(Neuro* n)
46{
47   int neuext=n->extraProperties().getPropCount(),
48       neucls=n->getClass()==NULL?0:n->getClass()->getProperties().getPropCount();
49   if (neuext+neucls==0) return -1; //no properties in this neuron
50   int index=randomN(neuext+neucls);
51   if (index>=neuext) index=index-neuext+100;
52   return index;
53}
54
55double Geno_fx::mutateNeuProperty(double current,Neuro *n,int i)
56{
57   if (i==-1) return mutateCreepNoLimit('f',current,-10,10); //i==-1: mutating weight of neural connection
58   ParamInterface *pi;
59   if (i>=100) {i-=100; pi=&n->getClass()->getProperties();}
60      else pi=&n->extraProperties();
61   double newval=current;
62   /*bool ok=*/getMutatedProperty(*pi,i,current,newval);
63   return newval;
64}
65
66bool Geno_fx::mutatePropertyNaive(ParamInterface &p,int i)
67{
68   double mn,mx,df;
69   if (p.type(i)[0]!='f' && p.type(i)[0]!='d') return false; //don't know how to mutate
70   getMinMaxDef(&p,i,mn,mx,df);
71
72   ExtValue ev;
73   p.get(i,ev);
74   ev.setDouble(mutateCreep(p.type(i)[0],ev.getDouble(),mn,mx));
75   p.set(i,ev);
76   return true;
77}
78
79bool Geno_fx::mutateProperty(ParamInterface &p,int i)
80{
81   double newval;
82   ExtValue ev;
83   p.get(i,ev);
84   bool ok=getMutatedProperty(p,i,ev.getDouble(),newval);
85   if (ok) {ev.setDouble(newval); p.set(i,ev);}
86   return ok;
87}
88
89bool Geno_fx::getMutatedProperty(ParamInterface &p,int i,double oldval,double &newval)
90{
91   newval=0;
92   if (p.type(i)[0]!='f' && p.type(i)[0]!='d') return false; //don't know how to mutate
93   const char *n=p.id(i),*na=p.name(i);
94     if (strcmp(n,"si")==0 && strcmp(na,"Sigmoid")==0) newval=CustomRnd(distrib_sigmo); else
95     if (strcmp(n,"in")==0 && strcmp(na,"Inertia")==0) newval=CustomRnd(distrib_inertia); else
96     if (strcmp(n,"fo")==0 && strcmp(na,"Force")==0) newval=CustomRnd(distrib_force); else
97     {
98       double mn,mx,df;
99       getMinMaxDef(&p,i,mn,mx,df);
100       newval=mutateCreep(p.type(i)[0],oldval,mn,mx);
101     }
102   return true;
103}
104
105double Geno_fx::mutateCreepNoLimit(char type,double current,double mn,double mx)
106{
107   double result=RndGen.Gauss(current,(mx-mn)/2/5); // /halfinterval, 5 times narrower
108   if (type=='d') {result=int(result+0.5); if (result==current) result+=randomN(2)*2-1;}
109    else result=floor(result*1000+0.5)/1000.0; //round
110   return result;
111}
112
113double Geno_fx::mutateCreep(char type,double current,double mn,double mx)
114{
115   double result=mutateCreepNoLimit(type,current,mn,mx);
116   //reflect:
117   if (result>mx) result=mx-(result-mx); else
118    if (result<mn) result=mn+(mn-result);
119   //absorb (just in case 'result' exceeded the allowed range so much):
120   if (result>mx) result=mx; else
121    if (result<mn) result=mn;
122   return result;
123}
124
125NeuroClass* Geno_fx::getRandomNeuroClass()
126{
127        SListTempl<NeuroClass*> active;
128   for(int i=0;i<Neuro::getClassCount();i++)
129      if (Neuro::getClass(i)->genactive) active+=Neuro::getClass(i);
130   if (!active==0) return NULL; else return active(randomN(!active));
131}
132
133NeuroClass* Geno_fx::parseNeuroClass(char*& s)
134{
135   int len=strlen(s);
136   int Len=0;
137   NeuroClass *I=NULL;
138   for(int i=0;i<Neuro::getClassCount();i++)
139   {
140      const char *n=Neuro::getClass(i)->name;
141      int l=strlen(n);
142      if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=Neuro::getClass(i); Len=l;}
143   }
144   s+=Len;
145   return I;
146}
147
148Neuro* Geno_fx::findNeuro(const Model *m,const NeuroClass *nc)
149{
150  if (!m) return NULL;
151  for(int i=0;i<m->getNeuroCount();i++)
152     if (m->getNeuro(i)->getClass()==nc) return m->getNeuro(i);
153  return NULL; //neuron of class 'nc' was not found
154}
155
156int Geno_fx::neuroClassProp(char*& s,NeuroClass *nc,bool also_v1_N_props)
157{
158   int len=strlen(s);
159   int Len=0,I=-1;
160   if (nc)
161   {
162      Param p=nc->getProperties();
163      for(int i=0;i<p.getPropCount();i++)
164      {
165         const char *n=p.id(i);
166         int l=strlen(n);
167         if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=100+i; Len=l;}
168         if (also_v1_N_props) //recognize old properties symbols /=!
169         {
170            if (strcmp(n,"si")==0) n="/"; else
171            if (strcmp(n,"in")==0) n="="; else
172            if (strcmp(n,"fo")==0) n="!";
173            l=strlen(n);
174            if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=100+i; Len=l;}
175         }
176      }
177   }
178   Neuro n;
179   ParamInterface &p=n.extraProperties();
180   for(int i=0;i<p.getPropCount();i++)
181   {
182      const char *n=p.id(i);
183      int l=strlen(n);
184      if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=i; Len=l;}
185   }
186   s+=Len;
187   return I;
188}
189
190bool Geno_fx::isWS(const char c)
191{return c==' ' || c=='\n' || c=='\t' || c=='\r';}
192
193void Geno_fx::skipWS(char *&s)
194{ if (!s) FramMessage("Geno_fx","skipWS","NULL reference!",1); else
195     while (isWS(*s)) s++;
196}
197
198bool Geno_fx::areAlike(char *g1,char *g2)
199{
200        while (*g1 || *g2)
201        {
202                skipWS(g1);
203                skipWS(g2);
204                if (*g1 != *g2) return false; //when difference
205      if (!*g1 && !*g2) break; //both end
206      g1++;
207      g2++;
208        }
209        return true; //equal
210}
211
212char* Geno_fx::strchrn0(const char *str,char ch)
213{ return ch==0?NULL:strchr((char*)str,ch); }
214
215bool Geno_fx::isNeuroClassName(const char firstchar)
216{
217   return isupper(firstchar) || firstchar=='|' || firstchar=='@' || firstchar=='*';
218}
219
Note: See TracBrowser for help on using the repository browser.