Changeset 732 for cpp/frams/model/model.cpp
- Timestamp:
- 02/15/18 00:42:07 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/model/model.cpp
r726 r732 1 1 // This file is a part of Framsticks SDK. http://www.framsticks.com/ 2 // Copyright (C) 1999-201 7Maciej Komosinski and Szymon Ulatowski.2 // Copyright (C) 1999-2018 Maciej Komosinski and Szymon Ulatowski. 3 3 // See LICENSE.txt for details. 4 4 … … 9 9 #include <common/loggers/loggers.h> 10 10 11 #define F0_CHECKPOINT_LINE "checkpoint:" 12 11 13 Model::Model() 12 14 { … … 18 20 { 19 21 partmappingchanged = 0; 22 using_checkpoints = false; 23 is_checkpoint = false; 20 24 buildstatus = empty; 21 25 modelfromgenotype = 0; … … 47 51 f0genoknown = 0; 48 52 startenergy = mod.startenergy; 49 if (mod.getStatus() == valid) 50 { 51 modelfromgenotype = mod.modelfromgenotype; 52 {for (int i = 0; i < mod.getPartCount(); i++) 53 addPart(new Part(*mod.getPart(i))); } 54 {for (int i = 0; i < mod.getJointCount(); i++) 53 modelfromgenotype = mod.modelfromgenotype; 54 for (int i = 0; i < mod.getPartCount(); i++) 55 addPart(new Part(*mod.getPart(i))); 56 for (int i = 0; i < mod.getJointCount(); i++) 55 57 { 56 58 Joint *oldj = mod.getJoint(i); … … 58 60 addJoint(j); 59 61 j->attachToParts(oldj->part1->refno, oldj->part2->refno); 60 } }61 {for (int i = 0; i < mod.getNeuroCount(); i++)62 } 63 for (int i = 0; i < mod.getNeuroCount(); i++) 62 64 { 63 65 Neuro *oldn = mod.getNeuro(i); … … 66 68 if (oldn->part_refno >= 0) n->attachToPart(oldn->part_refno); 67 69 else n->attachToJoint(oldn->joint_refno); 68 }} 69 for (int i = 0; i < mod.getNeuroCount(); i++) 70 { 71 Neuro *oldn = mod.getNeuro(i); 72 Neuro *n = getNeuro(i); 73 for (int ni = 0; ni < oldn->getInputCount(); ni++) 74 { 75 double w; 76 Neuro *oldinput = oldn->getInput(ni, w); 77 SString info = n->getInputInfo(ni); 78 n->addInput(getNeuro(oldinput->refno), w, &info); 79 } 80 } 81 } 82 } 83 84 85 Model::Model(const Geno &src, bool buildmaps) 70 } 71 for (int i = 0; i < mod.getNeuroCount(); i++) 72 { 73 Neuro *oldn = mod.getNeuro(i); 74 Neuro *n = getNeuro(i); 75 for (int ni = 0; ni < oldn->getInputCount(); ni++) 76 { 77 double w; 78 Neuro *oldinput = oldn->getInput(ni, w); 79 SString info = n->getInputInfo(ni); 80 n->addInput(getNeuro(oldinput->refno), w, &info); 81 } 82 } 83 updateRefno(); 84 if (using_checkpoints) 85 for (vector<Model*>::const_iterator it = mod.checkpoints.begin(); it != mod.checkpoints.end(); it++) 86 { 87 Model *m = *it; 88 Model *n = new Model(*m, m->autobuildmaps, false, true); 89 checkpoints.push_back(n); 90 } 91 } 92 93 94 Model::Model(const Geno &src, bool buildmaps, bool _using_checkpoints, bool _is_checkpoint) 86 95 :autobuildmaps(buildmaps) 87 96 { 88 init(src );97 init(src, _using_checkpoints, _is_checkpoint); 89 98 } 90 99 … … 92 101 { 93 102 clear(); 94 open( );103 open(mod.isUsingCheckpoints(), mod.isCheckpoint()); 95 104 internalCopy(mod); 96 105 buildstatus = mod.buildstatus; 97 106 } 98 107 99 Model::Model(const Model &mod, bool buildmaps )108 Model::Model(const Model &mod, bool buildmaps, bool _using_checkpoints, bool _is_checkpoint) 100 109 :autobuildmaps(buildmaps) 101 110 { 102 111 init(); 103 open( );112 open(_using_checkpoints, _is_checkpoint); 104 113 internalCopy(mod); 105 buildstatus = mod.buildstatus; 106 } 107 108 void Model::init(const Geno &src) 114 if (is_checkpoint) 115 close(); 116 else 117 buildstatus = mod.buildstatus; 118 if (mod.map) 119 map = new MultiMap(*mod.map); 120 if (mod.f0map) 121 f0map = new MultiMap(*mod.f0map); 122 } 123 124 void Model::init(const Geno &src, bool _using_checkpoints, bool _is_checkpoint) 109 125 { 110 126 init(); 127 using_checkpoints = _using_checkpoints; 128 is_checkpoint = _is_checkpoint; 111 129 modelfromgenotype = 1; 112 130 geno = src; … … 146 164 geno = Geno(); 147 165 f0geno = Geno(); 166 for (vector<Model*>::iterator it = checkpoints.begin(); it != checkpoints.end(); it++) 167 delete *it; 168 checkpoints.clear(); 148 169 } 149 170 … … 293 314 Model::ItemType Model::itemTypeFromLinePrefix(const char* line) 294 315 { 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;316 struct PrefixAndItem { const char* prefix; ItemType type; }; 317 static const PrefixAndItem types[] = { { "m:", ModelType }, { "p:", PartType }, { "j:", JointType }, { "n:", NeuronType }, { "c:", NeuronConnectionType }, { F0_CHECKPOINT_LINE, CheckpointType }, { NULL } }; 318 for (const PrefixAndItem *t = types; t->prefix != NULL; t++) 319 { 320 const char* in = line; 321 const char* pattern = t->prefix; 322 for (; *in == *pattern; in++, pattern++) 323 if (*pattern == ':') 324 return t->type; 325 } 326 return UnknownType; 306 327 } 307 328 … … 311 332 f0warnposition = -1; 312 333 MultiMap *convmap = autobuildmaps ? new MultiMap() : NULL; 313 f0geno = (geno.getFormat() == '0') ? geno : geno.getConverted('0', convmap );334 f0geno = (geno.getFormat() == '0') ? geno : geno.getConverted('0', convmap, using_checkpoints); 314 335 f0genoknown = 1; 315 336 if (f0geno.isInvalid()) … … 331 352 MultiRange frommap; 332 353 LoggerToMemory mh(LoggerBase::Enable | LoggerBase::DontBlock); 354 Model *current_model = this; 333 355 for (; f0txt.getNextToken(pos, line, '\n'); lnum++) 334 356 { 335 const char* line_ptr =line.c_str();357 const char* line_ptr = line.c_str(); 336 358 for (; *line_ptr; line_ptr++) 337 359 if (!strchr(" \r\t", *line_ptr)) break; … … 339 361 if (!*line_ptr) continue; 340 362 341 const char* colon =strchr(line_ptr,':');342 ItemType type =UnknownType;363 const char* colon = strchr(line_ptr, ':'); 364 ItemType type = UnknownType; 343 365 SString excluding_prefix; 344 if (colon !=NULL)345 366 if (colon != NULL) 367 { 346 368 colon++; 347 type =itemTypeFromLinePrefix(line_ptr);369 type = itemTypeFromLinePrefix(line_ptr); 348 370 for (; *colon; colon++) 349 371 if (!strchr(" \r\t", *colon)) break; 350 excluding_prefix =colon;351 352 372 excluding_prefix = colon; 373 } 374 353 375 if (autobuildmaps) 354 376 { … … 357 379 } 358 380 mh.reset(); 359 if (addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1) 381 if (type == CheckpointType) 382 { 383 current_model->close(); 384 current_model = new Model; 385 current_model->open(false, true); 386 checkpoints.push_back(current_model); 387 } 388 else if (current_model->addFromString(type, excluding_prefix, lnum, autobuildmaps ? (&frommap) : 0) == -1) 360 389 { 361 390 buildstatus = invalid; … … 371 400 } 372 401 mh.disable(); 373 c lose();402 current_model->close(); 374 403 if (convmap) 375 404 { … … 503 532 } 504 533 } 534 535 for (vector<Model*>::const_iterator it = checkpoints.begin(); it != checkpoints.end(); it++) 536 { 537 Geno g = (*it)->getF0Geno(); 538 gen += F0_CHECKPOINT_LINE "\n"; 539 gen += g.getGenes(); 540 } 541 505 542 g = Geno(gen.c_str(), '0'); 506 543 } … … 508 545 ////////////// 509 546 510 void Model::open( )547 void Model::open(bool _using_checkpoints, bool _is_checkpoint) 511 548 { 512 549 if (buildstatus == building) return; 550 using_checkpoints = _using_checkpoints; 551 is_checkpoint = _is_checkpoint; 513 552 buildstatus = building; 514 553 modelfromgenotype = 0; … … 518 557 } 519 558 559 int Model::getCheckpointCount() 560 { 561 return checkpoints.size(); 562 } 563 564 Model* Model::getCheckpoint(int i) 565 { 566 return checkpoints[i]; 567 } 568 520 569 void Model::checkpoint() 521 {} 570 { 571 if (!using_checkpoints) return; 572 updateRefno(); 573 Model *m = new Model(*this, false, false, true); 574 checkpoints.push_back(m); 575 } 522 576 523 577 void Model::setGeno(const Geno& newgeno) … … 544 598 if (buildstatus != building) 545 599 logPrintf("Model", "close", LOG_WARN, "Unexpected close() - no open()"); 546 if (internalcheck( building_live_model ? LIVE_CHECK : FINAL_CHECK) > 0)600 if (internalcheck(is_checkpoint ? CHECKPOINT_CHECK : (building_live_model ? LIVE_CHECK : FINAL_CHECK)) > 0) 547 601 { 548 602 buildstatus = valid; … … 589 643 int Model::addFromString(ItemType item_type, const SString &singleline, const MultiRange* srcrange) 590 644 { 591 return addFromString(item_type, singleline, 0, srcrange);645 return addFromString(item_type, singleline, 0, srcrange); 592 646 } 593 647 … … 612 666 error_message = SString::empty(); 613 667 ParamInterface::LoadOptions opts; 614 switch (item_type)615 616 617 668 switch (item_type) 669 { 670 case PartType: 671 { 618 672 Param partparam(f0_part_paramtab); 619 673 Part *p = new Part(); … … 626 680 if (srcrange) p->setMapping(*srcrange); 627 681 return getPartCount() - 1; 628 629 630 631 682 } 683 684 case ModelType: 685 { 632 686 Param modelparam(f0_model_paramtab); 633 687 modelparam.select(this); … … 635 689 if (opts.parse_failed) { error_message = "Invalid 'm:'"; return -1; } 636 690 return 0; 637 638 639 640 691 } 692 693 case JointType: 694 { 641 695 Param jointparam(f0_joint_paramtab); 642 696 Joint *j = new Joint(); … … 665 719 return -1; 666 720 } 667 668 669 670 721 } 722 723 case NeuronType: 724 { 671 725 Param neuroparam(f0_neuro_paramtab); 672 726 Neuro *nu = new Neuro(); … … 714 768 return neurons.size() - 1; 715 769 } 716 717 718 case NeuronConnectionType:719 770 } 771 772 case NeuronConnectionType: 773 { 720 774 Param ncparam(f0_neuroconn_paramtab); 721 775 NeuroConn c; … … 736 790 error_message = SString::sprintf("Invalid reference to Neuro #%d", n1_ok ? c.n2_refno : c.n1_refno); 737 791 return -1; 738 739 740 741 742 792 } 793 794 case CheckpointType: case UnknownType: //handled by addFromString for uniform error handling 795 return -1; 796 } 743 797 return -1; 744 798 } … … 747 801 ///////////// 748 802 749 /** change the sequence of neuro units 750 and fix references in "-" objects (n-n connections) */ 751 void Model::moveNeuro(int oldpos, int newpos) 752 { 753 if (oldpos == newpos) return; // nop! 754 Neuro *n = getNeuro(oldpos); 755 neurons -= oldpos; 756 neurons.insert(newpos, n); 757 // conn_refno could be broken -> fix it 758 } 759 760 //////////// 761 762 void Model::updateNeuroRefno() 763 { 803 void Model::updateRefno() 804 { 805 for (int i = 0; i < parts.size(); i++) 806 getPart(i)->refno = i; 807 for (int i = 0; i < joints.size(); i++) 808 { 809 Joint *j = getJoint(i); 810 j->refno = i; 811 if (j->part1 && j->part2 && (j->part1 != j->part2)) 812 { 813 j->p1_refno = j->part1->refno; 814 j->p2_refno = j->part2->refno; 815 } 816 } 764 817 for (int i = 0; i < neurons.size(); i++) 765 { 766 Neuro* n = (Neuro*)neurons(i); 767 n->refno = i; 768 } 818 getNeuro(i)->refno = i; 769 819 } 770 820 … … 779 829 #define LINKFLAG 0x8000000 780 830 781 void Model::updateRefno()782 {783 int i;784 for (i = 0; i < getPartCount(); i++) getPart(i)->refno = i;785 for (i = 0; i < getJointCount(); i++) getJoint(i)->refno = i;786 for (i = 0; i < getNeuroCount(); i++) getNeuro(i)->refno = i;787 }788 789 831 SString Model::nameForErrors() const 790 832 { … … 802 844 int ret = 1; 803 845 shape = SHAPE_UNKNOWN; 846 updateRefno(); 804 847 if ((parts.size() == 0) && (neurons.size() == 0)) return 0; 805 848 if (parts.size() == 0) … … 812 855 p = (Part*)parts(i); 813 856 p->owner = this; 814 p->refno = i;815 857 if (checklevel > 0) 816 858 p->mass = 0.0; … … 907 949 } 908 950 } 909 if ( check != LIVE_CHECK)951 if ((check != LIVE_CHECK) && (check != CHECKPOINT_CHECK)) 910 952 { 911 953 if (j->shape != Joint::SHAPE_FIXED) … … 935 977 } 936 978 937 updateNeuroRefno(); // valid refno is important for n-n connections check (later)938 939 979 for (i = 0; i < neurons.size(); i++) 940 980 { … … 944 984 } 945 985 946 if ( parts.size() && (checklevel > 0))947 { 948 for (i = 0; i < parts.size(); i++) 949 {950 p = (Part*)parts(i);951 if (p->mass <= 0.001)952 p->mass = 1.0;953 p->flags &= ~LINKFLAG;954 }955 getPart(0)->flags |= LINKFLAG;956 int change = 1;957 while (change)958 {959 change = 0;960 for (i = 0; i < joints.size(); i++)961 { 962 j = (Joint*)joints(i);963 if (j->part1->flags&LINKFLAG)986 if (check != CHECKPOINT_CHECK) 987 { 988 989 if (parts.size() && (checklevel > 0)) 990 { 991 for (i = 0; i < parts.size(); i++) 992 { 993 p = (Part*)parts(i); 994 if (p->mass <= 0.001) 995 p->mass = 1.0; 996 p->flags &= ~LINKFLAG; 997 } 998 getPart(0)->flags |= LINKFLAG; 999 int change = 1; 1000 while (change) 1001 { 1002 change = 0; 1003 for (i = 0; i < joints.size(); i++) 964 1004 { 965 if (!(j->part2->flags&LINKFLAG)) 1005 j = (Joint*)joints(i); 1006 if (j->part1->flags&LINKFLAG) 966 1007 { 967 change = 1; 968 j->part2->flags |= LINKFLAG; 1008 if (!(j->part2->flags&LINKFLAG)) 1009 { 1010 change = 1; 1011 j->part2->flags |= LINKFLAG; 1012 } 969 1013 } 1014 else 1015 if (j->part2->flags&LINKFLAG) 1016 { 1017 if (!(j->part1->flags&LINKFLAG)) 1018 { 1019 change = 1; 1020 j->part1->flags |= LINKFLAG; 1021 } 1022 } 970 1023 } 971 else 972 if (j->part2->flags&LINKFLAG) 973 { 974 if (!(j->part1->flags&LINKFLAG)) 975 { 976 change = 1; 977 j->part1->flags |= LINKFLAG; 978 } 979 } 980 } 981 } 982 for (i = 0; i < parts.size(); i++) 983 { 984 p = (Part*)parts(i); 985 if (!(p->flags&LINKFLAG)) 986 { 987 logPrintf("Model", "internalCheck", LOG_ERROR, "Not all parts connected (eg. Part #0 and Part #%d)%s", i, nameForErrors().c_str()); 1024 } 1025 for (i = 0; i < parts.size(); i++) 1026 { 1027 p = (Part*)parts(i); 1028 if (!(p->flags&LINKFLAG)) 1029 { 1030 logPrintf("Model", "internalCheck", LOG_ERROR, "Not all parts connected (eg. Part #0 and Part #%d)%s", i, nameForErrors().c_str()); 1031 ret = 0; 1032 break; 1033 } 1034 } 1035 } 1036 1037 for (i = 0; i < joints.size(); i++) 1038 { 1039 j = (Joint*)joints(i); 1040 if (j->p1_refno == j->p2_refno) 1041 { 1042 logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal self connection, Joint #%d%s", i, nameForErrors().c_str()); 988 1043 ret = 0; 989 1044 break; 990 1045 } 991 } 992 } 993 994 for (i = 0; i < joints.size(); i++) 995 { 996 j = (Joint*)joints(i); 997 if (j->p1_refno == j->p2_refno) 998 { 999 logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal self connection, Joint #%d%s", i, nameForErrors().c_str()); 1000 ret = 0; 1001 break; 1002 } 1003 for (k = i + 1; k < joints.size(); k++) 1004 { 1005 Joint* j2 = (Joint*)joints(k); 1006 if (((j->p1_refno == j2->p1_refno) && (j->p2_refno == j2->p2_refno)) 1007 || ((j->p1_refno == j2->p2_refno) && (j->p2_refno == j2->p1_refno))) 1008 { 1009 logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal duplicate Joint #%d and Joint #%d%s", i, k, nameForErrors().c_str()); 1010 ret = 0; 1011 break; 1012 } 1013 } 1014 } 1046 for (k = i + 1; k < joints.size(); k++) 1047 { 1048 Joint* j2 = (Joint*)joints(k); 1049 if (((j->p1_refno == j2->p1_refno) && (j->p2_refno == j2->p2_refno)) 1050 || ((j->p1_refno == j2->p2_refno) && (j->p2_refno == j2->p1_refno))) 1051 { 1052 logPrintf("Model", "internalCheck", LOG_ERROR, "Illegal duplicate Joint #%d and Joint #%d%s", i, k, nameForErrors().c_str()); 1053 ret = 0; 1054 break; 1055 } 1056 } 1057 } 1058 } 1059 1015 1060 if (shape == SHAPE_ILLEGAL) 1016 1061 ret = 0; … … 1250 1295 ////////////////////// 1251 1296 1297 int Model::elementToMap(ItemType type, int index) 1298 { 1299 switch (type) 1300 { 1301 case PartType: return partToMap(index); 1302 case JointType: return jointToMap(index); 1303 case NeuronType: return neuroToMap(index); 1304 default: return -1; 1305 } 1306 } 1307 1308 Model::TypeAndIndex Model::mapToElement(int map_index) 1309 { 1310 if ((map_index >= 0) && (map_index < MODEL_MAPPING_OFFSET)) 1311 return TypeAndIndex(PartType, mapToPart(map_index)); 1312 if ((map_index >= MODEL_MAPPING_OFFSET) && (map_index < 2 * MODEL_MAPPING_OFFSET)) 1313 return TypeAndIndex(JointType, mapToJoint(map_index)); 1314 if ((map_index >= 2 * MODEL_MAPPING_OFFSET) && (map_index < 3 * MODEL_MAPPING_OFFSET)) 1315 return TypeAndIndex(NeuronType, mapToNeuro(map_index)); 1316 return TypeAndIndex(); 1317 } 1318 1319 int Model::partToMap(int i) { return MODEL_MAPPING_OFFSET + i; } 1320 int Model::jointToMap(int i) { return 2 * MODEL_MAPPING_OFFSET + i; } 1321 int Model::neuroToMap(int i) { return 3 * MODEL_MAPPING_OFFSET + i; } 1322 int Model::mapToPart(int i) { return i - MODEL_MAPPING_OFFSET; } 1323 int Model::mapToJoint(int i) { return i - 2 * MODEL_MAPPING_OFFSET; } 1324 int Model::mapToNeuro(int i) { return i - 3 * MODEL_MAPPING_OFFSET; } 1325 1326 1327 ////////////////////// 1328 1252 1329 class MinPart : public Part { public: MinPart() { Param par(f0_part_paramtab, this); par.setMin(); } }; 1253 1330 class MaxPart : public Part { public: MaxPart() { Param par(f0_part_paramtab, this); par.setMax(); } };
Note: See TracChangeset
for help on using the changeset viewer.