00001
00025 #include <inanna/annetwork.h>
00026 #include <inanna/initializer.h>
00027 #include <nhp/individual.h>
00028 #include <magic/mclass.h>
00029
00030 #include "annalee/cangelosi.h"
00031 #include "annalee/cangelosinet.h"
00032
00033 impl_dynamic (CangelosiEncoding, {NolfiEncoding});
00034
00035
00036
00038
00039
00040
00041
00042
00043
00044
00046
00047 CangelosiEncoding::CangelosiEncoding (const GeneticID& name, const StringMap& params) : NolfiEncoding (name, params) {
00048 }
00049
00050 CangelosiEncoding::CangelosiEncoding (const CangelosiEncoding& other) : NolfiEncoding (other) {
00051 }
00052
00053 void CangelosiEncoding::copy (const Genstruct& o) {
00054 NolfiEncoding::copy (o);
00055
00056 }
00057
00058 void CangelosiEncoding::addPrivateGenes (Gentainer& g, const StringMap& params) {
00059 Gentainer::addPrivateGenes (g, params);
00060
00061
00062 CangCellDescr::addGenesTo (*this, params);
00063
00064
00065 if (params["NolfiEncoding.tipRadius"] == "auto-network")
00066 add (&(new BitFloatGene ("tipr", 1, 10, 8, params))->hide());
00067 }
00068
00069 bool CangelosiEncoding::execute (const GeneticMsg& msg) const {
00070
00071
00072 Array<CangCellDescr> rules (16*2);
00073 for (int rule=0; rule<16; rule++)
00074 for (int daughter=0; daughter<2; daughter++)
00075 rules.put (new CangCellDescr (*this, rule, daughter), rule*2+daughter);
00076
00077
00078 double tipRadius = mTipRadius;
00079 if (getGene("tipr"))
00080 tipRadius = ((const AnyFloatGene*) getGene("tipr"))->getvalue();
00081
00082
00083 CangelosiNet cnet (mInputs, mMaxHidden, mOutputs, mXSize, mYSize, tipRadius, mAxonScale);
00084 cnet.rewrite (rules, int(log(mMaxHidden*1.0)/log(2.0)+0.99));
00085
00086
00087 ANNetwork* net = cnet.growNet ();
00088
00089
00090 if (net) {
00091 net->setInitializer (new GaussianInitializer ());
00092
00093
00094 bool takePics = int(dynamic_cast<const TakeBrainPicsMsg*>(&msg));
00095 if (takePics) {
00096 msg.host.set ("brainpic1", new String (cnet.drawEPS()));
00097 msg.host.set ("brainpic2", new String (net->drawEPS()));
00098 }
00099 net->cleanup (true, mPrunePassthroughs);
00100 if (takePics) {
00101 net->drawFeedForward();
00102 msg.host.set ("brainpic3", new String (net->drawEPS()));
00103 delete net;
00104 } else {
00105
00106 msg.host.set ("brainplan", net);
00107 }
00108 }
00109
00110 return true;
00111 }
00112
00113
00114
00116
00117
00118
00119
00120
00121
00122
00124
00125 void CangCellDescr::addGenesTo (Gentainer& g, const StringMap& params) {
00126 Array<String> slrange;
00127 params["CangelosiEncoding.segLenMulRange"].split (slrange, ',');
00128 double sMin = slrange[0].toDouble ();
00129 double sMax = slrange[1].toDouble ();
00130
00131 ASSERT (sMin>=-2 && sMin<=1 && sMax>0 && sMax<=5);
00132
00133
00134 for (int rule=0; rule<16; rule++)
00135 for (int daughter=0; daughter<2; daughter++) {
00136 String num = format ("%d%c", rule, daughter+'a');
00137 g.add (&(new BitIntGene (String("T")+num, 0, 15, 4, params))->hide());
00138 g.add (&(new BitFloatGene (String("b")+num, -1, 1, 10, params))->hide());
00139 g.add (&(new BitFloatGene (String("w")+num, -1, 1, 10, params))->hide());
00140 g.add (&(new BitIntGene (String("d")+num, 0, 7, 3, params))->hide());
00141 if (params["NolfiEncoding.faceGene"].toInt ())
00142 g.add (&(new BitFloatGene (String("f")+num, 0, 1, 4, params))->hide());
00143 g.add (&(new BitFloatGene (String("s")+num, sMin, sMax, 4, params))->hide());
00144 g.add (&(new BitFloatGene (String("a")+num, -1, 1, 6, params))->hide());
00145 if (params["NolfiEncoding.tipRadius"] == "auto-cell")
00146 g.add (&(new BitFloatGene (String("r")+num, 0, 2, 8, params))->hide());
00147 }
00148 }
00149
00150 void CangCellDescr::decodeFrom (const Gentainer& g, int r, int d) {
00151 char c = d + 'a';
00152 mNewType = ((const AnyIntGene&) g[format ("T%d%c", r, c)]).getvalue();
00153 mBiasVar = ((const AnyFloatGene&) g[format ("b%d%c", r, c)]).getvalue();
00154 mWeightVar = ((const AnyFloatGene&) g[format ("w%d%c", r, c)]).getvalue();
00155 mDaughterLoc = ((const AnyIntGene&) g[format ("d%d%c", r, c)]).getvalue();
00156 mSegLengthVar = ((const AnyFloatGene&) g[format ("s%d%c", r, c)]).getvalue();
00157 mSegAngleVar = ((const AnyFloatGene&) g[format ("a%d%c", r, c)]).getvalue();
00158 if (!isnull(g[format ("f%d%c", r, c)]))
00159 mFaceVar = ((const AnyFloatGene&) g[format ("f%d%c", r, c)]).getvalue();
00160 else
00161 mFaceVar = 0;
00162 if (!isnull(g[format ("r%d%c", r, c)])) {
00163 mTipRadiusMul = ((const AnyFloatGene&) g[format ("r%d%c", r, c)]).getvalue();
00164 TRACELINE;
00165 } else
00166 mTipRadiusMul = -666;
00167 }
00168
00169
00170
00172
00173
00174
00175
00176
00177
00178
00180
00181 CangelosiCell::CangelosiCell (const CangelosiCell& mother, const CangCellDescr& rule) : NolfiCell (mother) {
00182
00183
00184 add (rule);
00185 mFace = 0.0;
00186 if (mTipRadius<0.5)
00187 mTipRadius = 1.0;
00188 }
00189
00190 void CangelosiCell::make () {
00191 NolfiCell::make ();
00192
00193
00194
00195 mFace = 0.0;
00196 mSegmentLength = 0.0;
00197 mSegmentAngle = 0.0;
00198 if (mTipRadius<0.5)
00199 mTipRadius = 1.0;
00200 }
00201
00202 void CangelosiCell::copy (const CangelosiCell& o) {
00203 NolfiCell::copy (o);
00204 mFace = o.mFace;
00205 }
00206
00207 void CangelosiCell::add (const CangCellDescr& rule) {
00208 static double daughterlocx[] = {0,1,1,1,0,-1,-1,-1};
00209 static double daughterlocy[] = {1,1,0,-1,-1,-1,0,1};
00210
00211 mTypeID = rule.mNewType;
00212 mBias += rule.mBiasVar;
00213 mWeight += rule.mWeightVar;
00214 mFace += rule.mFaceVar;
00215 mSegmentLength += rule.mSegLengthVar;
00216 mSegmentAngle += 0.1*rule.mSegAngleVar;
00217 mCoord.x += daughterlocx[rule.mDaughterLoc];
00218 mCoord.y += daughterlocy[rule.mDaughterLoc];
00219 if (rule.mTipRadiusMul>0)
00220 mTipRadius *= rule.mTipRadiusMul;
00221 }
00222
00223 OStream& CangelosiCell::operator>> (OStream& out) const {
00224 out.printf ("face=%+02.2f, ", mFace);
00225 NolfiCell::operator>> (out);
00226 return out;
00227 }
00228
00229
00230
00232
00233
00234
00235
00236
00237
00238
00240
00241 CangelosiNet::CangelosiNet (int inputs, int maxhidden, int outputs, double xsize, double ysize, double tipRadius, double axonScale) : NolfiNet (inputs, maxhidden, outputs, xsize, ysize, tipRadius, axonScale) {
00242
00243 makeMother ();
00244 }
00245
00246 void CangelosiNet::makeMother () {
00247 cells.make (0);
00248 cells.add (new CangelosiCell ());
00249
00250 cells[0].setPos (0.0, 0.0);
00251 if (mTipRadius>0)
00252 cells[0].setTipRadius(mTipRadius);
00253 }
00254
00255 void CangelosiNet::rewrite (const Array<CangCellDescr>& rules, int cycles) {
00256 for (int cycle=0; cycle<cycles; cycle++) {
00257 Array<CangelosiCell> daughters (2 * cells.size());
00258
00259
00260 for (int mother=0; mother < cells.size(); mother++) {
00261 const CangelosiCell& mom = static_cast<const CangelosiCell&>(cells[mother]);
00262 for (int daughter=0; daughter<2; daughter++)
00263 daughters.put (new CangelosiCell (mom, rules[mom.mTypeID*2+daughter]),
00264 mother*2+daughter);
00265 }
00266
00267
00268 cells.empty ();
00269 cells.make (daughters.size());
00270 for (int i=0; i < daughters.size(); i++) {
00271 cells.put (&daughters[i], i);
00272 daughters.cut (i);
00273 }
00274 }
00275
00276
00277 for (int i=0; i<cells.size(); i++) {
00278 const Coord2D& coord = cells[i].pos ();
00279 cells[i].setPos (Coord2D(coord.x/(cycles*2+1)+0.5, coord.y/(cycles*2+1)+0.5));
00280 }
00281 }
00282