Ignore:
Timestamp:
01/19/18 19:37:43 (6 years ago)
Author:
Maciej Komosinski
Message:
  • Changed Model::singleStepBuild() to Model::addFromString() to create model elements; the latter requires explicit indication of element type (P/J/N/C)
  • Removed old compatibility source (#ifdef MODEL_V1_COMPATIBLE) from f1->f0 converter and neuron definitions
File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/model/model.cpp

    r720 r726  
    2222        startenergy = 1.0;
    2323        checklevel = 1;
    24 #ifdef MODEL_V1_COMPATIBLE
    25         oldneurocount=-1; // == unknown
    26         oldconnections=0;
    27 #endif
    2824        map = 0;
    2925        f0map = 0;
     
    295291}
    296292
     293Model::ItemType Model::itemTypeFromLinePrefix(const char* line)
     294{
     295struct PrefixAndItem { const char* prefix; ItemType type; };
     296static const PrefixAndItem types[]={ {"m:",ModelType},{"p:",PartType},{"j:",JointType},{"n:",NeuronType},{"c:",NeuronConnectionType},{NULL} };
     297for(const PrefixAndItem *t=types;t->prefix!=NULL;t++)
     298        {
     299        const char* in=line;
     300        const char* pattern=t->prefix;
     301        for(;*in==*pattern;in++,pattern++)
     302                if (*pattern==':')
     303                        return t->type;
     304        }
     305return UnknownType;
     306}
     307
    297308void Model::build()
    298309{
     
    322333        for (; f0txt.getNextToken(pos, line, '\n'); lnum++)
    323334        {
     335                const char* line_ptr=line.c_str();
     336                for (; *line_ptr; line_ptr++)
     337                        if (!strchr(" \r\t", *line_ptr)) break;
     338                if (*line_ptr == '#') continue;
     339                if (!*line_ptr) continue;
     340
     341                const char* colon=strchr(line_ptr,':');
     342                ItemType type=UnknownType;
     343                SString excluding_prefix;
     344                if (colon!=NULL)
     345                        {
     346                        colon++;
     347                        type=itemTypeFromLinePrefix(line_ptr);
     348                        for (; *colon; colon++)
     349                                if (!strchr(" \r\t", *colon)) break;
     350                        excluding_prefix=colon;
     351                        }
     352               
    324353                if (autobuildmaps)
    325354                {
     
    328357                }
    329358                mh.reset();
    330                 if (singleStepBuild(line, lnum, autobuildmaps ? (&frommap) : 0) == -1)
     359                if (addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1)
    331360                {
    332361                        buildstatus = invalid;
     
    558587}
    559588
    560 int Model::singleStepBuild(const SString &singleline, const MultiRange* srcrange)
    561 {
    562         return singleStepBuild(singleline, 0, srcrange);
    563 }
    564 
    565 int Model::singleStepBuild(const SString &singleline, int line_num, const MultiRange* srcrange)
     589int Model::addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange)
     590{
     591        return addFromString(item_type,singleline, 0, srcrange);
     592}
     593
     594int Model::addFromString(ItemType item_type, const SString &singleline, int line_num, const MultiRange* srcrange)
    566595{
    567596        SString error_message;
    568         int result = singleStepBuildNoLog(singleline, error_message, srcrange);
     597        int result = addFromStringNoLog(item_type, singleline, error_message, srcrange);
    569598        if (result < 0)
    570599        {
     
    579608}
    580609
    581 int Model::singleStepBuildNoLog(const SString &line, SString& error_message, const MultiRange* srcrange)
     610int Model::addFromStringNoLog(ItemType item_type, const SString &line, SString& error_message, const MultiRange* srcrange)
    582611{
    583612        error_message = SString::empty();
    584         const char*t = line.c_str();
    585613        ParamInterface::LoadOptions opts;
    586         for (; *t; t++, opts.offset++)
    587                 if (!strchr(" \r\t", *t)) break;
    588         if (*t == '#') return 0;
    589         if (!*t) return 0;
    590         if (!strncmp(t, "p:", 2))
    591         {
     614        switch(item_type)
     615                {
     616                case PartType:
     617                {
    592618                Param partparam(f0_part_paramtab);
    593619                Part *p = new Part();
    594620                partparam.select(p);
    595                 opts.offset += 2;
    596621                partparam.load(ParamInterface::FormatSingleLine, line, &opts);
    597622                if (opts.parse_failed) { delete p; error_message = "Invalid 'p:'"; return -1; }
     
    601626                if (srcrange) p->setMapping(*srcrange);
    602627                return getPartCount() - 1;
    603         }
    604         if (!strncmp(t, "m:", 2))
    605         {
     628                }
     629
     630                case ModelType:
     631                {
    606632                Param modelparam(f0_model_paramtab);
    607633                modelparam.select(this);
    608                 opts.offset += 2;
    609634                modelparam.load(ParamInterface::FormatSingleLine, line, &opts);
    610635                if (opts.parse_failed) { error_message = "Invalid 'm:'"; return -1; }
    611636                return 0;
    612         }
    613         else if (!strncmp(t, "j:", 2))
    614         {
     637                }
     638
     639                case JointType:
     640                {
    615641                Param jointparam(f0_joint_paramtab);
    616642                Joint *j = new Joint();
    617643                jointparam.select(j);
    618                 opts.offset += 2;
    619644                j->owner = this;
    620645                jointparam.load(ParamInterface::FormatSingleLine, line, &opts);
     
    640665                        return -1;
    641666                }
    642         }
    643         else if (!strncmp(t, "n:", 2)) // neuro (or the old neuro object as the special case)
    644         {
     667                }
     668
     669                case NeuronType:
     670                {
    645671                Param neuroparam(f0_neuro_paramtab);
    646672                Neuro *nu = new Neuro();
    647673                neuroparam.select(nu);
    648                 opts.offset += 2;
    649674                neuroparam.load(ParamInterface::FormatSingleLine, line, &opts);
    650675                if (opts.parse_failed) { delete nu; error_message = "Invalid 'n:'"; return -1; }
    651 #ifdef MODEL_V1_COMPATIBLE
    652                 if (nu->neuro_refno>=0) // parent specified...
    653                 {
    654                         if (nu->neuro_refno >= getNeuroCount()) // and it's illegal
    655                         {
    656                                 delete nu;
    657                                 return -1;
    658                         }
    659                         Neuro *parentNU=getNeuro(nu->neuro_refno);
    660                         parentNU->addInput(nu,nu->weight);
    661                         // default class for parented units: n-n link
    662                         //if (nu->moredata.len()==0) nu->moredata="-";
    663                 }
    664                 else
    665 #endif
    666676                {
    667677                        // default class for unparented units: standard neuron
     
    680690                        }
    681691                        */
    682 #ifdef MODEL_V1_COMPATIBLE
    683                 nu->weight=1.0;
    684 #endif
    685692                nu->owner = this;
    686693                // attach to part/joint
     
    703710                if (srcrange) nu->setMapping(*srcrange);
    704711                // todo: check part/joint ref#
    705 #ifdef MODEL_V1_COMPATIBLE
    706                 if (hasOldNeuroLayout())
    707                 {
    708                         int count=old_getNeuroCount();
    709                         neurons.insert(count,nu);
    710                         oldneurocount=count+1;
    711                         return oldneurocount-1;
    712                 }
    713                 else
    714 #endif
    715712                {
    716713                        neurons += nu;
    717714                        return neurons.size() - 1;
    718715                }
    719         }
    720         else if (!strncmp(t, "c:", 2)) // add input
    721         {
     716                }
     717
     718                case NeuronConnectionType:                     
     719                {
    722720                Param ncparam(f0_neuroconn_paramtab);
    723721                NeuroConn c;
    724722                ncparam.select(&c);
    725                 opts.offset += 2;
    726723                ncparam.load(ParamInterface::FormatSingleLine, line, &opts);
    727724                if (opts.parse_failed) { error_message = "Invalid 'c:'"; return -1; }
     
    739736                error_message = SString::sprintf("Invalid reference to Neuro #%d", n1_ok ? c.n2_refno : c.n1_refno);
    740737                return -1;
    741         }
    742 #ifdef MODEL_V1_COMPATIBLE
    743         else if (!strncmp(t,"ni:",3)) // old neuroitem
    744         {
    745                 // we always use old layout for "ni:"
    746                 Param neuroitemparam(f0_neuroitem_paramtab);
    747                 Neuro *nu=new Neuro();
    748                 neuroitemparam.select(nu);
    749                 opts.offset+=3;
    750                 neuroitemparam.loadSingleLine(line,opts);
    751                 if (opts.parse_failed) {delete nu; return -1;}
    752                 // illegal parent?
    753                 if ((nu->neuro_refno<0)||(nu->neuro_refno>=old_getNeuroCount()))
    754                 {
    755                         delete nu;
     738                }
     739
     740                case UnknownType: //handled by addFromString for uniform error handling
    756741                        return -1;
    757742                }
    758                 Neuro *parentN=getNeuro(nu->neuro_refno);
    759                 // copy part/joint refno from parent, if possible
    760                 if ((nu->part_refno<0)&&(parentN->part_refno>=0))
    761                         nu->part_refno=parentN->part_refno;
    762                 if ((nu->joint_refno<0)&&(parentN->joint_refno>=0))
    763                         nu->joint_refno=parentN->joint_refno;
    764                 nu->owner=this;
    765                 // attach to part/joint
    766                 if (nu->part_refno>=0)
    767                         nu->attachToPart(nu->part_refno);
    768                 if (nu->joint_refno>=0)
    769                         nu->attachToJoint(nu->joint_refno);
    770                 if (srcrange)
    771                         nu->setMapping(*srcrange);
    772                 // special case: old muscles
    773                 // PARENT neuron will be set up to be the CHILD of the current one (!)
    774                 if (nu->isOldEffector())
    775                 {
    776                         nu->neuro_refno=parentN->refno;
    777                         neurons+=nu;
    778                         nu->owner=this;
    779                         nu->addInput(parentN,nu->weight); // (!)
    780                         nu->weight=1.0;
    781                         parentN->invalidateOldItems();
    782                         return 0; // !!! -> ...getItemCount()-1;
    783                 }
    784                 parentN->addInput(nu,nu->weight);
    785                 neurons+=nu;
    786                 parentN->invalidateOldItems();
    787                 if (nu->getClassName().len()==0)
    788                 {
    789                         nu->setClassName("-");
    790                         // for compatibility, "ni" can define a n-n connection
    791                         // referring to non-existent neuron (which will be hopefully defined later)
    792                         // internal check will add the proper input to this unit
    793                         // if conn_refno >=0 and input count==0
    794                         oldconnections=1;
    795                         if (srcrange)
    796                                 parentN->addMapping(*srcrange);
    797                 }
    798                 else
    799                         nu->weight=1.0;
    800                 return 0; // !!! -> ...getItemCount()-1;
    801         }
    802 #endif
    803         else return -1;
    804 }
    805 
    806 #ifdef MODEL_V1_COMPATIBLE
    807 int Model::addOldConnectionsInputs()
    808 {
    809         if (!oldconnections) return 1;
    810         Neuro* n;
    811         for (int i=0;i<neurons.size();i++)
    812         {
    813                 n=(Neuro*)neurons(i);
    814                 if (n->conn_refno>=0)
    815                         if (n->isNNConnection())
    816                                 if (n->conn_refno < old_getNeuroCount())
    817                                 { // good reference
    818                         Neuro* parent=n->parent; // nn connection has exactly one parent
    819                         int inp=parent->findInput(n);
    820                         Neuro* target=getNeuro(n->conn_refno);
    821                         parent->setInput(inp,target,n->weight);
    822                         removeNeuro(i,0); // no need to remove references
    823                         i--;
    824                                 }
    825                                 else
    826                                 {
    827                                         logPrintf("Model","internalCheck",LOG_ERROR,
    828                                                 "illegal N-N connection #%d (reference to #%d)%s",
    829                                                 i,n->conn_refno,nameForErrors().c_str());
    830                                         return 0;
    831                                 }
    832         }
    833         oldconnections=0;
    834         return 1;
    835 }
    836 #endif
     743        return -1;
     744}
     745
    837746
    838747/////////////
     
    847756        neurons.insert(newpos, n);
    848757        // conn_refno could be broken -> fix it
    849 #ifdef MODEL_V1_COMPATIBLE
    850         for (int i=0;i<neurons.size();i++)
    851         {
    852                 Neuro *n2=getNeuro(i);
    853                 if (n2->isNNConnection())
    854                         if (n2->conn_refno == oldpos) n2->conn_refno=newpos;
    855                         else
    856                         { if (n2->conn_refno > oldpos) n2->conn_refno--;
    857                 if (n2->conn_refno >= newpos) n2->conn_refno++; }
    858         }
    859         invalidateOldNeuroCount();
    860 #endif
    861 }
    862 
    863 #ifdef MODEL_V1_COMPATIBLE
    864 /** move all old neurons (class "N") to the front of the neurons list.
    865         @return number of old neurons
    866         */
    867 int Model::reorderToOldLayout()
    868 {
    869         Neuro *n;
    870         int neurocount=0;
    871         for (int i=0;i<neurons.size();i++)
    872         {
    873                 n=(Neuro*)neurons(i);
    874                 if (n->isOldNeuron())
    875                 {
    876                         moveNeuro(i,neurocount);
    877                         neurocount++;
    878                         i=neurocount-1;
    879                 }
    880         }
    881         return neurocount;
    882 }
    883 #endif
     758}
     759
    884760////////////
    885761
     
    1058934                }
    1059935        }
    1060 #ifdef MODEL_V1_COMPATIBLE
    1061         if (!addOldConnectionsInputs())
    1062                 return 0;
    1063 #endif
    1064936
    1065937        updateNeuroRefno(); // valid refno is important for n-n connections check (later)
     
    1068940        {
    1069941                n = (Neuro*)neurons(i);
    1070 #ifdef MODEL_V1_COMPATIBLE
    1071                 VALIDMINMAX(n,Neuro,inertia);
    1072                 VALIDMINMAX(n,Neuro,force);
    1073                 VALIDMINMAX(n,Neuro,sigmo);
    1074                 n->conn_refno=-1;
    1075                 n->weight=1.0;
    1076                 n->neuro_refno=-1;
    1077 #endif
    1078942                n->part_refno = (n->part) ? n->part->refno : -1;
    1079943                n->joint_refno = (n->joint) ? n->joint->refno : -1;
     
    12451109}
    12461110
    1247 
    1248 ////////////////////
    1249 
    1250 #ifdef MODEL_V1_COMPATIBLE
    1251 void Model::calcOldNeuroCount()
    1252 {
    1253         if (oldneurocount>=0) return;
    1254         oldneurocount=reorderToOldLayout();
    1255 }
    1256 
    1257 int Model::old_getNeuroCount()
    1258 { calcOldNeuroCount();
    1259 return oldneurocount;}
    1260 
    1261 Neuro* Model::old_getNeuro(int i)
    1262 {calcOldNeuroCount();
    1263 return (i<oldneurocount)? (Neuro*)getNeuro(i) : (Neuro*)0;
    1264 }
    1265 
    1266 int Model::old_findNeuro(Neuro* n)
    1267 {calcOldNeuroCount();
    1268 return findNeuro(n);}
    1269 
    1270 Neuro *Model::old_addNewNeuro()
    1271 {
    1272         int count=old_getNeuroCount();
    1273         Neuro *nu=addNewNeuro();
    1274         nu->setClassName("N");
    1275         moveNeuro(nu->refno,oldneurocount);
    1276         oldneurocount=count+1;
    1277         return (Neuro*)nu;
    1278 }
    1279 #endif
    1280 
    12811111///////////////////////
    12821112
Note: See TracChangeset for help on using the changeset viewer.