source: cpp/geno_fx/geno_fx.cpp @ 24

Last change on this file since 24 was 3, checked in by Maciej Komosinski, 16 years ago

added geno_fx, a base class for genetic operations on genotypes

File size: 6.2 KB
Line 
1// This file is a part of Framsticks GenoFX library.
2// Copyright (C) 2002-2009  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 mutateCreep('f',current,-10,10);
58   ParamInterface *pi;
59   if (i>=100) {i-=100; pi=&n->getClass()->getProperties();}
60      else pi=&n->extraProperties();
61   double newval;
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::mutateCreep(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)/1000.0;
110   if (result>mx) result=mx; else
111    if (result<mn) result=mn;
112   return result;
113}
114
115NeuroClass* Geno_fx::getRandomNeuroClass()
116{
117        SListTempl<NeuroClass*> active;
118   for(int i=0;i<Neuro::getClassCount();i++)
119      if (Neuro::getClass(i)->genactive) active+=Neuro::getClass(i);
120   if (!active==0) return NULL; else return active(randomN(!active));
121}
122
123NeuroClass* Geno_fx::parseNeuroClass(char*& s)
124{
125   int len=strlen(s);
126   int Len=0;
127   NeuroClass *I=NULL;
128   for(int i=0;i<Neuro::getClassCount();i++)
129   {
130      const char *n=Neuro::getClass(i)->name;
131      int l=strlen(n);
132      if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=Neuro::getClass(i); Len=l;}
133   }
134   s+=Len;
135   return I;
136}
137
138Neuro* Geno_fx::findNeuro(const Model *m,const NeuroClass *nc)
139{
140  if (!m) return NULL;
141  for(int i=0;i<m->getNeuroCount();i++)
142     if (m->getNeuro(i)->getClass()==nc) return m->getNeuro(i);
143  return NULL; //neuron of class 'nc' was not found
144}
145
146int Geno_fx::neuroClassProp(char*& s,NeuroClass *nc,bool also_v1_N_props)
147{
148   int len=strlen(s);
149   int Len=0,I=-1;
150   if (nc)
151   {
152      Param p=nc->getProperties();
153      for(int i=0;i<p.getPropCount();i++)
154      {
155         const char *n=p.id(i);
156         int l=strlen(n);
157         if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=100+i; Len=l;}
158         if (also_v1_N_props) //recognize old properties symbols /=!
159         {
160            if (strcmp(n,"si")==0) n="/"; else
161            if (strcmp(n,"in")==0) n="="; else
162            if (strcmp(n,"fo")==0) n="!";
163            l=strlen(n);
164            if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=100+i; Len=l;}
165         }
166      }
167   }
168   Neuro n;
169   ParamInterface &p=n.extraProperties();
170   for(int i=0;i<p.getPropCount();i++)
171   {
172      const char *n=p.id(i);
173      int l=strlen(n);
174      if (len>=l && l>Len && (strncmp(s,n,l)==0)) {I=i; Len=l;}
175   }
176   s+=Len;
177   return I;
178}
179
180bool Geno_fx::isWS(const char c)
181{return c==' ' || c=='\n' || c=='\t' || c=='\r';}
182
183void Geno_fx::skipWS(char *&s)
184{ if (!s) FramMessage("Geno_fx","skipWS","NULL reference!",1); else
185     while (isWS(*s)) s++;
186}
187
188bool Geno_fx::areAlike(char *g1,char *g2)
189{
190        while (*g1 || *g2)
191        {
192                skipWS(g1);
193                skipWS(g2);
194                if (*g1 != *g2) return false; //when difference
195      if (!*g1 && !*g2) break; //both end
196      g1++;
197      g2++;
198        }
199        return true; //equal
200}
201
202char* Geno_fx::strchrn0(const char *str,char ch)
203{ return ch==0?NULL:strchr((char*)str,ch); }
204
205bool Geno_fx::isNeuroClassName(const char firstchar)
206{
207   return isupper(firstchar) || firstchar=='|' || firstchar=='@' || firstchar=='*';
208}
209
Note: See TracBrowser for help on using the repository browser.