Changeset 726 for cpp/frams/model/model.cpp
- Timestamp:
- 01/19/18 19:37:43 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/model/model.cpp
r720 r726 22 22 startenergy = 1.0; 23 23 checklevel = 1; 24 #ifdef MODEL_V1_COMPATIBLE25 oldneurocount=-1; // == unknown26 oldconnections=0;27 #endif28 24 map = 0; 29 25 f0map = 0; … … 295 291 } 296 292 293 Model::ItemType Model::itemTypeFromLinePrefix(const char* line) 294 { 295 struct PrefixAndItem { const char* prefix; ItemType type; }; 296 static const PrefixAndItem types[]={ {"m:",ModelType},{"p:",PartType},{"j:",JointType},{"n:",NeuronType},{"c:",NeuronConnectionType},{NULL} }; 297 for(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 } 305 return UnknownType; 306 } 307 297 308 void Model::build() 298 309 { … … 322 333 for (; f0txt.getNextToken(pos, line, '\n'); lnum++) 323 334 { 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 324 353 if (autobuildmaps) 325 354 { … … 328 357 } 329 358 mh.reset(); 330 if ( singleStepBuild(line, lnum, autobuildmaps ? (&frommap) : 0) == -1)359 if (addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1) 331 360 { 332 361 buildstatus = invalid; … … 558 587 } 559 588 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)589 int Model::addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange) 590 { 591 return addFromString(item_type,singleline, 0, srcrange); 592 } 593 594 int Model::addFromString(ItemType item_type, const SString &singleline, int line_num, const MultiRange* srcrange) 566 595 { 567 596 SString error_message; 568 int result = singleStepBuildNoLog(singleline, error_message, srcrange);597 int result = addFromStringNoLog(item_type, singleline, error_message, srcrange); 569 598 if (result < 0) 570 599 { … … 579 608 } 580 609 581 int Model:: singleStepBuildNoLog(const SString &line, SString& error_message, const MultiRange* srcrange)610 int Model::addFromStringNoLog(ItemType item_type, const SString &line, SString& error_message, const MultiRange* srcrange) 582 611 { 583 612 error_message = SString::empty(); 584 const char*t = line.c_str();585 613 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 { 592 618 Param partparam(f0_part_paramtab); 593 619 Part *p = new Part(); 594 620 partparam.select(p); 595 opts.offset += 2;596 621 partparam.load(ParamInterface::FormatSingleLine, line, &opts); 597 622 if (opts.parse_failed) { delete p; error_message = "Invalid 'p:'"; return -1; } … … 601 626 if (srcrange) p->setMapping(*srcrange); 602 627 return getPartCount() - 1; 603 } 604 if (!strncmp(t, "m:", 2)) 605 { 628 } 629 630 case ModelType: 631 { 606 632 Param modelparam(f0_model_paramtab); 607 633 modelparam.select(this); 608 opts.offset += 2;609 634 modelparam.load(ParamInterface::FormatSingleLine, line, &opts); 610 635 if (opts.parse_failed) { error_message = "Invalid 'm:'"; return -1; } 611 636 return 0; 612 } 613 else if (!strncmp(t, "j:", 2)) 614 { 637 } 638 639 case JointType: 640 { 615 641 Param jointparam(f0_joint_paramtab); 616 642 Joint *j = new Joint(); 617 643 jointparam.select(j); 618 opts.offset += 2;619 644 j->owner = this; 620 645 jointparam.load(ParamInterface::FormatSingleLine, line, &opts); … … 640 665 return -1; 641 666 } 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 { 645 671 Param neuroparam(f0_neuro_paramtab); 646 672 Neuro *nu = new Neuro(); 647 673 neuroparam.select(nu); 648 opts.offset += 2;649 674 neuroparam.load(ParamInterface::FormatSingleLine, line, &opts); 650 675 if (opts.parse_failed) { delete nu; error_message = "Invalid 'n:'"; return -1; } 651 #ifdef MODEL_V1_COMPATIBLE652 if (nu->neuro_refno>=0) // parent specified...653 {654 if (nu->neuro_refno >= getNeuroCount()) // and it's illegal655 {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 link662 //if (nu->moredata.len()==0) nu->moredata="-";663 }664 else665 #endif666 676 { 667 677 // default class for unparented units: standard neuron … … 680 690 } 681 691 */ 682 #ifdef MODEL_V1_COMPATIBLE683 nu->weight=1.0;684 #endif685 692 nu->owner = this; 686 693 // attach to part/joint … … 703 710 if (srcrange) nu->setMapping(*srcrange); 704 711 // todo: check part/joint ref# 705 #ifdef MODEL_V1_COMPATIBLE706 if (hasOldNeuroLayout())707 {708 int count=old_getNeuroCount();709 neurons.insert(count,nu);710 oldneurocount=count+1;711 return oldneurocount-1;712 }713 else714 #endif715 712 { 716 713 neurons += nu; 717 714 return neurons.size() - 1; 718 715 } 719 } 720 else if (!strncmp(t, "c:", 2)) // add input 721 { 716 } 717 718 case NeuronConnectionType: 719 { 722 720 Param ncparam(f0_neuroconn_paramtab); 723 721 NeuroConn c; 724 722 ncparam.select(&c); 725 opts.offset += 2;726 723 ncparam.load(ParamInterface::FormatSingleLine, line, &opts); 727 724 if (opts.parse_failed) { error_message = "Invalid 'c:'"; return -1; } … … 739 736 error_message = SString::sprintf("Invalid reference to Neuro #%d", n1_ok ? c.n2_refno : c.n1_refno); 740 737 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 756 741 return -1; 757 742 } 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 837 746 838 747 ///////////// … … 847 756 neurons.insert(newpos, n); 848 757 // 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 884 760 //////////// 885 761 … … 1058 934 } 1059 935 } 1060 #ifdef MODEL_V1_COMPATIBLE1061 if (!addOldConnectionsInputs())1062 return 0;1063 #endif1064 936 1065 937 updateNeuroRefno(); // valid refno is important for n-n connections check (later) … … 1068 940 { 1069 941 n = (Neuro*)neurons(i); 1070 #ifdef MODEL_V1_COMPATIBLE1071 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 #endif1078 942 n->part_refno = (n->part) ? n->part->refno : -1; 1079 943 n->joint_refno = (n->joint) ? n->joint->refno : -1; … … 1245 1109 } 1246 1110 1247 1248 ////////////////////1249 1250 #ifdef MODEL_V1_COMPATIBLE1251 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 #endif1280 1281 1111 /////////////////////// 1282 1112
Note: See TracChangeset
for help on using the changeset viewer.