Structural deformable models
MStruct.cpp
Go to the documentation of this file.
1 #include <fstream>
2 #include <set>
3 #include <algorithm>
4 #include <iterator>
5 #include <iomanip>
6 #include <fxkeys.h>
7 #include "Brain.h"
8 #include "StructTable.h"
9 #include "MStruct.h"
10 #include "DMatrix.h"
11 #include "DMatrixUtil.h"
12 #include "DMatrixLinAlg.h"
13 #include "utils.h"
14 
15 using namespace std;
16 
17 //----------------------------------------------------------------------------
18 #define SUBSTRUCT_RATEWEIGHT 1.0f
19 #define STRUCT_SHAPEWEIGHT 0.1f
20 #define SUBSTRUCT_RATETH 0.0f
21 
22 //--------------------------- MStructure ------------------------------------
23 
24 MStructure::MStructure(const string& name, StructTable* psTable)
25  : m_PStructTable(psTable), m_Size(1.0f), m_Weight(1.0f)
26 {
27  setName(name);
28  if(m_PStructTable) {
31  }
32 }
33 
35 {
36  operator=(rhs);
37 }
38 
40 {
41  if(!m_RefProp.empty()) saveRefProp();
42  clear();
43 }
44 
46 {
47  if(this != &rhs) {
48  m_Name = rhs.m_Name;
49  m_Model = rhs.m_Model;
50  m_Size = rhs.m_Size;
54  m_RefProp = rhs.m_RefProp;
55  m_Weight = rhs.m_Weight;
57  }
58  return *this;
59 }
60 
62 {
63  m_Name.clear();
64  m_Model.clear();
65  m_Size = 1.0f;
66  m_Weight = 1.0f;
67  m_SupStructures.clear();
68  m_SubStructures.clear();
70  m_RefProp.clear();
71 }
72 
73 void MStructure::setName(const string& name)
74 {
75  m_Name = name;
76  m_FrameWinner.m_StructName = name; //just in case it is used
78 }
79 
81 {
82  if(isFrame() && wid==Winner::WID_FRAME)
83  return &m_FrameWinner;
84  else return m_Searcher.getWinner(wid);
85 }
86 
87 void MStructure::addSubStruct(const SubStructure& substruct)
88 {
89  m_SubStructures[substruct.m_SubStructName] = substruct;
90  m_SubStructures[substruct.m_SubStructName].m_SupStructName = m_Name;
91  //super structure references are updated in connectSubSuper()
92 }
93 
95 {
96  clear();
97  bool readon = true;
98  SubStructure substruct;
99  while(readon && is.getNextLine()) {
100  const string& key = is.getKey();
101  const string& value = is.getValue();
102  if(key == "struct") {
103  if(!m_Name.empty()) is.setParseError(
104  "struct inside struct. (rather use substruct?)");
105  else {
106  setName(value.c_str());
107  loadRefProp();
108  }
109  } else if(m_Name.empty()) {
110  is.pushLine(); return false;
111  } else if(key == "end") readon = false;
112  else if(key == "model") {
113  string filename = is.getPath()+is.getValue();
114  if(!m_Model.readFile(filename.c_str())) {
115  is.setParseError(string("couldn't load model ")+filename);
116  }
117  } else if(key == "size") {
118  istringstream(value) >> m_Size;
119  } else if(key == "weight") {
120  fromString(value, m_Weight);
121  } else if(key == "shapeweight") {
122  float shapeweight=STRUCT_SHAPEWEIGHT;
123  fromString(value, shapeweight);
124  m_Searcher.setShapeWeight(shapeweight);
125  } else if(substruct.read(is)) addSubStruct(substruct);
126  else is.setParseError(string("(parsing struct) unknown token ") + key);
127  }
128  if(is.error()) return false;
129  return true;
130 }
131 
132 void MStructure::write(ostream &os) const
133 {
134  if(!(*this)) return;
135  os << "struct " << m_Name << endl;
136  if(!m_Model.getFilename().empty()) {
137  string filename = m_Model.getFilename();
138  if(m_PStructTable) {
139  if(filename.substr(0,m_PStructTable->getPath().size())
140  == m_PStructTable->getPath())
141  filename = filename.substr(m_PStructTable->getPath().size());
142  }
143  os << " model " << filename << endl;
144  }
145  if(m_Weight != 1.f) os << " weight " << m_Weight << endl;
147  os << " shapeweight " << m_Searcher.getShapeWeight() << endl;
148  os << " size " << m_Size << endl;
149  for(map<string,SubStructure>::const_iterator si = m_SubStructures.begin();
150  si != m_SubStructures.end(); si++)
151  {
152  os << si->second;
153  }
154  os << "end # of struct" << endl << endl;
155 }
156 
157 string MStructure::getInfoFilename(const string& suffix) const {
158  string fn;
159  if(m_PStructTable) {
160  fn = m_PStructTable->getFilename();
161  fn = fn.substr(0, fn.rfind('.'));
162  } else fn = "struct";
163  fn = fn + "_" + m_Name + "_" + suffix + ".dm";
164  return fn;
165 }
166 
167 bool MStructure::getRefModel(dword id, Model& model) const
168 {
169  string filename = getInfoFilename(toString(id));
170  bool readf = model.readFile(filename.c_str());
171  return readf;
172 }
173 
174 bool MStructure::getRefProp(dword id, PropVec& prop) const
175 {
176  map<dword,PropVec>::const_iterator rp = m_RefProp.find(id);
177  if(rp != m_RefProp.end()) {
178  prop = rp->second;
179  return true;
180  } else return false;
181 }
182 
183 void MStructure::setRefProp(dword id, const PropVec& prop)
184 {
185  m_RefProp[id] = prop;
186 }
187 
188 void MStructure::setRefModel(dword id, const Model& model)
189 {
190  PropVec pv(model.getProperties());
191  model.convertPropToMM(pv);
192  m_RefProp[id] = pv;
193  //save model file for geometry internal statistics
194  string filename = getInfoFilename(toString(id));
195  model.writeFile(filename.c_str());
196 }
197 
199 {
200  if(!*this) return 0;
201  string filename(getInfoFilename("pvec"));
202  ParseFile pf(filename);
203  if(pf) {
204  m_RefProp.clear();
205  while(pf.getNextLine()) {
206  dword id=0;
207  fromString(pf.getKey(),id);
208  if(id) {
209  PropVec prop(0.0);
210  fromString(pf.getValue(), prop);
211  m_RefProp[id] = prop;
212  }
213  }
214  return m_RefProp.size();
215  } return 0;
216 }
217 
219 {
220  if(!*this) return;
221  string filename = getInfoFilename("pvec");
222  ofstream os(filename.c_str());
223  if(os)
224  for(map<dword,PropVec>::const_iterator rp=m_RefProp.begin();
225  rp != m_RefProp.end(); rp++)
226  {
227  if(rp->first)
228  os << rp->first << " " << rp->second << endl;
229  }
230 }
231 
233 {
234  set<dword> refmod;
235  getRefModelIDs( insert_iterator<set<dword> >(refmod, refmod.begin()) );
236  Model model; // not attached to anything
237  //ofstream infile("info.dat");
238  for(map<string,SubStructure>::iterator si = m_SubStructures.begin();
239  si != m_SubStructures.end(); si++)
240  {
241  SubStructure& subs = si->second;
243  set<dword> strefmod; st.getRefModelIDs(
244  insert_iterator<set<dword> >(strefmod, strefmod.begin()) );
245  list<dword> comod;
246  set_intersection( refmod.begin(), refmod.end(),
247  strefmod.begin(), strefmod.end(),
248  back_inserter(comod) );
249  dword ncomod = comod.size();
250  DMatrixf tfmat(PropVec::size(), ncomod);
251  dword rowind = 0;
252  for(list<dword>::const_iterator idi = comod.begin();
253  idi != comod.end(); idi++, rowind++)
254  {
255  Point2D pivot(0,0); bool usepivot = false;
256  if(subs.m_Pivot>=0 && m_Model.getNNodes()>subs.m_Pivot) {
257  if(getRefModel(*idi, model)) { // find pivot
258  pivot = model.getNode(subs.m_Pivot);
259  pivot -= model.getCenter();
260  model.convertPointToMM(pivot);
261  usepivot = true;
262  } else cout << "error: could not find reference model "
263  << getInfoFilename(toString(*idi)) << endl;
264  }
265  //compute transformation
266  PropVec prop, ssprop;
267  if(getRefProp(*idi, prop) && st.getRefProp(*idi, ssprop)) {
268  setPropPos(prop, getPropPos(prop) + pivot);
269  PropTF sstf = getPropTF(prop, ssprop);
270  DMatrixf tfvec(PropVec::size(), 1, sstf.begin());
271  tfmat.setRange(0,rowind,tfvec);
272  } else cerr << "error getting propvec for " << m_Name
273  << " or " << st.m_Name << " for species "
274  << *idi << endl;
275  }
276  subs.analyseTF(tfmat);
278  showStats(subs);
279  }
281 }
282 
283 bool MStructure::buildMasterModel(float scscale)
284 {
285  if(!m_Model) return false;
286  list<dword> refmod;
287  dword nrefmod = getRefModelIDs( back_inserter(refmod) );
288 // insert_iterator<list<dword> >(refmod, refmod.begin()) );
289  Model model; // not attached to anything
290  DMatrixf rlen(1, m_Model.getNEdges(), 0.f);
291  DMatrixf lenrat(1, m_Model.getNEdges(), 0.f);
292  dword nmod = 0;
293  for(list<dword>::const_iterator idi = refmod.begin();
294  idi != refmod.end(); idi++)
295  {
296  if(getRefModel(*idi, model)) { // get model instance
297  if(model.getNEdges() == m_Model.getNEdges()) {
298  for(int i=0;i<model.getNEdges();i++) {
299  const Edge& se = model.getEdge(i);
300  //Edge& me = m_Model.getEdge(i);
301  float rl = se.restlength/model.getDataScale();
302  float lr = se.lengthRatio();
303  if(lr>1) lr = 1/lr;
304  lr = 1-lr;
305  rlen.at(0,i) += rl;
306  lenrat.at(0,i) += lr;
307  }
308  nmod++;
309  }
310  }
311  }
312  if(nmod>1) { // setup spring constants according to statistics
313  float scmax = ParticleParam::global.springconst;
314  float minlr = 1/scmax;
315  int i;
316  float refallrl=0, nallrl=0;
317  for(int i=0;i<m_Model.getNEdges();i++) {
318  Edge& me = m_Model.getEdge(i);
319  float rl = rlen.at(0,i) /= nmod;
320  lenrat.at(0,i) /= nmod;
321  nallrl += rl;
322  refallrl += me.restlength;
323  }
324  nallrl *= m_Model.getDataScale();
325  m_Model.scale(nallrl/refallrl,true);
326  for(int i=0;i<m_Model.getNEdges();i++) {
327  Edge& me = m_Model.getEdge(i);
328  float rl = rlen.at(0,i);
329  float sc = lenrat.at(0,i);
330  sc *= scscale;
331  //DUMP(sc);
332  if(sc>minlr) sc = 1/sc;
333  else sc = scmax;
334  //cout << "springconst = " << sc << endl;
335  me.restlength = rl*m_Model.getDataScale();
336  me.springconstant = sc;
337  }
338 #define SHAPEADAPTTIMESTEP 0.01
339  float imgfscale = m_Model.phys.imgforce;
340  m_Model.phys.imgforce = 0; //disable image influence
342  float liveliness = 0;
343  dword timeout = 100;
344  while(abs(liveliness-m_Model.getLiveliness())>0.01 && timeout--) {
345  liveliness = m_Model.getLiveliness();
351  }
352  m_Model.phys.imgforce = imgfscale;
353  if(!timeout) cout << "timeout reached while calming model" << endl;
354 #undef SHAPEADAPTTIMESTEP
355  }
356  return true;
357 }
358 
359 void MStructure::refSubSuper(bool doclear)
360 {
361  if(doclear) { // just clear own list
362  m_SupStructures.clear();
363  return;
364  }
365  for(map<string,SubStructure>::iterator si = m_SubStructures.begin();
366  si != m_SubStructures.end(); si++)
367  {
368  MStructure& st = m_PStructTable->getStructs()[si->first];
369  st.m_SupStructures[m_Name] = &si->second;
370  }
371 }
372 
374  ExpectationMap& expmap, bool backwards) const
375 {
376 // if inverse look backwards to super structure
377 // MStructure& st = m_PStructTable->getStructs()
378 // [backwards ? subs.m_SupStructName : subs.m_SubStructName];
379  if(isFrame()) {
380  //cout << "is a frame" << endl;
381  float ppmm = (float)m_PStructTable->getDataset()->getPPMM();
382  PropVec frameprop(m_PStructTable->getDataset()->getPropVec());
383  if(!(subs.m_Mode&SubStructure::MODE_NOSPAWN)) {
384  EMDistribution* emdist =
385  subs.generateEMDist(frameprop,ppmm,backwards,
386  getSearchPara().m_PDist);
387  emdist->setCreator(m_FrameWinner);
389  if(olddist) emdist->setShootCount(olddist->getShootCount());
390  float exhaust =
391  float(emdist->getShootCount()) / getSearchPara().m_MaxShoot;
392  if(exhaust>1.f) exhaust = 0.f;
393  else exhaust = 1.f-exhaust;
394  emdist->setIntegral(exhaust); //1.f was default
395  expmap.add(emdist);
396  }
397  PropVec lb, ub;
398  subs.getLBUB(lb, ub, frameprop, ppmm);
400  expmap.setLB(lb);
401  expmap.setUB(ub);
402  return true;
403  }
404 // list<const Model*> winners;
405 // m_Searcher.getWinners( back_inserter(winners) );
406  if(subs.m_Mode&SubStructure::MODE_NOSPAWN) return true;
407  const map<dword,Winner>& winners = m_Searcher.getWinList();
408  dword nwinners = winners.size();
409  if(!nwinners) return false;
410  DMatrixf qof(1, nwinners);
411  map<dword,Winner>::const_iterator wi = winners.begin();
412  for(dword i=0; i<nwinners; i++, wi++)
413  qof.at(0,i) = wi->second.m_Model->getQualityOfFit();
414  float avgqof = dmutil::avg(qof).at(0,0);
415  float stdqof = dmutil::stdev(qof).at(0,0);
416  float maxqof = qof.max(), minqof = qof.min();
417  if(maxqof<0.0000001) return false; //DEBUG
418  const Winner* thebest = NULL;
419  float bestrating = 0;
420  dword maxshoot = 0;
421  for(wi = winners.begin(); wi!= winners.end(); wi++) {
422  const Winner& winner = wi->second;
423  if(m_Searcher.getGeneration(winner.m_Model) > 2) {
424  float wqof = winner.m_Model->getQualityOfFit();
425 #ifdef _SPAWN_FROM_BEST_
426  float rating = wqof/maxqof + subs.m_RateWeight*winner.m_BestRating;
427  if(rating > bestrating) {
428  thebest = &winner;
429  bestrating = rating;
430  }
431  }
432  }
433  if(thebest) {
434  {
435  const Winner& winner = *thebest;
436  float wqof = winner.m_Model->getQualityOfFit();
437 #endif
438  float ppmm = (float)winner.m_Model->getDataScale();
439  PropVec wprop = winner.m_Model->getProperties();
440  if(subs.m_Pivot>=0) setPropPos(wprop, winner.m_Model
441  ->getNode(subs.m_Pivot));
442  EMDistribution* emdist = subs.generateEMDist
443  (wprop,ppmm,backwards,getSearchPara().m_PDist);
444  emdist->setCreator(winner);
445  EMDistribution* olddist=expmap.getEDist(winner.m_WinnerID);
446  if(olddist) emdist->setShootCount(olddist->getShootCount());
447  if(maxshoot < emdist->getShootCount())
448  maxshoot = emdist->getShootCount();
449  float exhaust =
450  float(emdist->getShootCount()) / getSearchPara().m_MaxShoot;
451  if(exhaust>1.f) exhaust = 0.f;
452  else exhaust = 1.f-exhaust;
453  emdist->setIntegral((wqof/maxqof)*exhaust);
454  expmap.add(emdist);
455  PropVec lb, ub;
456  subs.getLBUB(lb, ub, wprop, ppmm);
458  PropVec olb = expmap.getLB(), oub = expmap.getUB();
459  setPropScale(lb, getPropScale(olb));
460  setPropScale(ub, getPropScale(oub));
463  expmap.setLB(lb);
464  expmap.setUB(ub);
465  }
466  }
467  if(thebest && false) {
468  PropVec lb, ub;
469  float ppmm = (float)thebest->m_Model->getDataScale();
470  subs.getLBUB(lb, ub, thebest->m_Model->getProperties(), ppmm);
472  PropVec olb = expmap.getLB(), oub = expmap.getUB();
473  setPropScale(olb, getPropScale(lb));
474  setPropScale(oub, getPropScale(ub));
475  expmap.setLB(olb);
476  expmap.setUB(oub);
477  }
478  DUMP(maxshoot << " --------------------" );
479  return true;
480 }
481 
483 {
484  if(!m_Model) return;
485  //cout << "rebuild expmap for " << m_Name << endl;
487  expmap.markAllOld();
488  expmap.setRepresentative(m_Model);
489  expmap.getRepresentative().setName(m_Name);
490 //calculate upper and lower bounds from dataset (and avg Model)
491  PropVec propl(0.), propu(0.);
492  Point2D dims((float)m_PStructTable->getDataset()->getDim1Size(),
493  (float)m_PStructTable->getDataset()->getDim2Size());
494  float scale = getPropScale(m_Model.getPropertiesMM());
495  scale *= m_PStructTable->getDataset()->getPPMM();
496  setPropPos(propu, dims);
497  setPropDir(propu, 2*M_PI);
498  setPropScale(propu, scale*1.1); // is that good?
499  setPropScale(propl, scale*0.9);
500  ExpectationMap::correctLBUB(propl, propu);
501  expmap.setLB(propl);
502  expmap.setUB(propu);
503 #ifdef _USE_BACKGROUND_DIST_
504 //add a background distribution over entire allowed search range
505  EMDRect* drect = new EMDRect(propl,propu);
506  //drect->setIntegral(0.2); keep it 1 (like the winner)
507  expmap.add(drect); //DEBUG
508 #endif
509 //add expectation from connected super structures
510  for(map<string,SubStructure*>::iterator si = m_SupStructures.begin();
511  si != m_SupStructures.end(); si++)
512  {
513  MStructure& st = m_PStructTable->getStructs()[si->first];
514  // [si->second->m_SupStructName]
515  st.addExpectation(*si->second, expmap);
516  }
517 #if DO_INVERSE_TRANSFORM
518 //add expectation backwards from sub structures
519  for(map<string,SubStructure>::iterator si = m_SubStructures.begin();
520  si != m_SubStructures.end(); si++)
521  {
522  MStructure& st = m_PStructTable->getStructs()[si->first];
523  st.addExpectation(si->second, expmap, true);
524  }
525 #endif
526  expmap.clear(true); // remove old ones only
528  DUMP(m_Name<<" "<<expmap.m_Integral);
529 }
530 
532 {
533  int okcount = 0;
534  map<dword,Winner>& wl = m_Searcher.getWinList();
535  for(map<dword,Winner>::iterator wi = wl.begin(); wi!=wl.end(); wi++)
536  { // for each Winner wi
537  for(Winner::Ratings::iterator refstruct = wi->second.m_Ratings.begin();
538  refstruct != wi->second.m_Ratings.end(); refstruct++)
539  { // for each rating parent structure
540  MStructure& st = m_PStructTable->getStructs()[refstruct->first];
541  if(!st.isFrame()) {
542  map<dword,float>::iterator wr= refstruct->second.begin();
543  while(wr != refstruct->second.end())
544  { // for each rating wr
545  map<dword,float>::iterator nextwr = wr; nextwr++;
546  const Winner* refwin=st.getSearcher().getWinner(wr->first);
547  if(refwin) {
548  okcount++;
549  } else {
550  refstruct->second.erase(wr);
551  }
552  wr = nextwr;
553  }
554  } else okcount += refstruct->second.size();
555  }
556  wi->second.updateBestRating();
557  }
558  cout << okcount << " good connections to struct " << m_Name << endl;
559 }
560 
561 void MStructure::showStats(const SubStructure& subs, std::ostream& os) const
562 {
563  os << " stats for ["<<subs.m_SupStructName<<"] --> ["
564  <<subs.m_SubStructName<<"]"<<endl;
565  set<dword> refmod;
566  getRefModelIDs( insert_iterator<set<dword> >(refmod, refmod.begin()) );
567  Model model; // not attached to anything
569  set<dword> strefmod; st.getRefModelIDs(
570  insert_iterator<set<dword> >(strefmod, strefmod.begin()) );
571  list<dword> comod;
572  set_intersection( refmod.begin(), refmod.end(),
573  strefmod.begin(), strefmod.end(),
574  back_inserter(comod) );
575  dword ncomod = comod.size();
576  DMatrixf tfmat(PropVec::size(), ncomod);
577  DMatrixf ratings(1,ncomod);
578  dword rowind = 0;
579  for(list<dword>::const_iterator idi = comod.begin();
580  idi != comod.end(); idi++, rowind++)
581  {
582  Point2D pivot(0,0); bool usepivot = false;
583  if(subs.m_Pivot>=0 && m_Model.getNNodes()>subs.m_Pivot) {
584  if(getRefModel(*idi, model)) { // find pivot
585  pivot = model.getNode(subs.m_Pivot);
586  pivot -= model.getCenter();
587  model.convertPointToMM(pivot);
588  usepivot = true;
589  } else os << "error: could not find reference model "
590  << getInfoFilename(toString(*idi)) << endl;
591  }
592  //compute transformation
593  PropVec prop, ssprop;
594  if(getRefProp(*idi, prop) && st.getRefProp(*idi, ssprop)) {
595  setPropPos(prop, getPropPos(prop) + pivot);
596  PropTF sstf = getPropTF(prop, ssprop);
597  DMatrixf tfvec(PropVec::size(), 1, sstf.begin());
598  tfmat.setRange(0,rowind,tfvec);
599  //determine rating
600  EMDistribution* ed = subs.generateEMDist(prop,1,false,
601  getSearchPara().m_PDist);
602  if(ed) {
603  ratings.at(0,rowind) = ed->ratePropVec(ssprop);
604  os << *idi << ": " << ratings.at(0,rowind) << " pv:"
605  << getPropTF(prop,ssprop) << endl;
606  delete ed;
607  } else os << "error generating exp.distr. for " << *idi << endl;
608  } else os << "error getting propvec for " << m_Name
609  << " or " << st.m_Name << " for species "
610  << *idi << endl;
611  }
612  EMDistribution* ed = subs.generateEMDist(getIdentityPropTF(),1,false,
613  getSearchPara().m_PDist);
614  if(ed) {
615  os << "central rating: " << ed->ratePropVec(subs.m_Mean) << endl;
616  DUMP(subs.m_Mean);
617  DUMP(subs.m_Stdev);
618  delete ed;
619 
620  os << "pcomp : " << PropVec(&subs.m_Sigma.at(0,0)) << endl;
621  os << "average: " << dmutil::avg(ratings).at(0,0) << endl;
622  os << "stdev : " << dmutil::stdev(ratings).at(0,0) << endl;
623  if(ncomod>0) {
624  os << "min : " << ratings.min() << endl;
625  os << "max : " << ratings.max() << endl;
626  }
627  } else os << "error generating exp.distr." << endl;
628 }
629 
631 {
632  return m_Searcher.step(dt) || isFrame();
633 }
634 
635 //---------------------------------------------------------------------------
636 SubStructure::SubStructure(const std::string& subStructName,
637  const std::string& supStructName,
638  const PropTF& transform,int pivot)
639  : m_SubStructName(subStructName),m_SupStructName(subStructName),
640  m_Transform(transform), m_Pivot(pivot),
641  m_Polar(false), m_RateWeight(SUBSTRUCT_RATEWEIGHT),
642  m_RateTH(SUBSTRUCT_RATETH), m_Mode(MODE_NONE)
643 {
644 }
645 
647 {
648  using namespace dmutil;
649  if(tfmat.empty() ||tfmat.sizeX()!=PropVec::size()) {
650  m_PC = m_IPC = makeIdentity<float>(PropVec::size()+1);
651  m_Sigma.resize(1,4); m_Sigma = 0.f;
652  m_Mean = m_Stdev = 0.f;
653  return;
654  }
655  bool show = false && (m_Mode&MODE_SHOWSTATS);
656  if(show) DUMP(tfmat);
657  DMatrixf ntfmat(tfmat);
658  DMatrixf angles(1,ntfmat.sizeY());
659  ntfmat.getRange(PVEC_DIR, 0, angles);
661  ntfmat.setRange(PVEC_DIR, 0, angles);
662  //todo: switch to polar position (translation)
663 // ofstream f1("tfmat.dat");
664 // f1 << tfmat;
665 // ofstream f2("ids.dat");
666 // copy(comod.begin(), comod.end(), ostream_iterator<dword>(f2, "\n"));
667  //build a (0,1) standardized matrix of the distribution
668  DMatrixf avghg(avg(ntfmat));
669  DMatrixf stdevhg(stdev(ntfmat));
670  DMatrixf mavg(expand(avghg, 1,ntfmat.sizeY()));
671  DMatrixf mstdev(expand(stdevhg, 1,ntfmat.sizeY()));
672  ntfmat -= mavg; ntfmat /= mstdev;
673  //build a normalized covariance matrix
674  DMatrixf tfcov(ntfmat);
675  tfcov.transpose();
676  tfcov = tfcov.mulRight(ntfmat);
677  tfcov *= (1.f/(ntfmat.sizeY())); //normalize by number of samples
678  if(show) DUMP(tfcov);
679  DMatrixf mU, mS, mV;
680  dmutil::SVD(tfcov, mU, mS, mV); // TODO
681  m_Sigma = mS.getDiag();
682  float relvar = 1.f/4; //1.f/dmutil::sum(m_Sigma).at(0,0); // has to be 1/4
683  for(dword i=0;i<m_Sigma.sizeY(); i++)
684  if(m_Sigma.at(0,i)*relvar < getSearchPara().m_PCTH)
685  m_Sigma.at(0,i) = 0.f;
687  m_Mean = &avghg.at(0,0);
688  m_Stdev = &stdevhg.at(0,0);
689  if(show) DUMP(mU << mS << mV);
690 //make a homogeneous matrix to integrate de-standardization
691  //m_Sigma.resize(1,m_Sigma.sizeY()+1,1.f);
692  //mS = makeDiag(m_Sigma);
693 // avghg.transpose();
694 // avghg.resize(1,avghg.sizeY()+1,1.f);
695 // stdevhg.transpose();
696 // stdevhg.resize(1,stdevhg.sizeY()+1,1.f);
697 // DMatrixf mVhg(makeIdentity<float>(mV.sizeX()+1));
698 // mVhg.setRange(0,0,mV);
699 // //mVhg.transpose(); //no transposed, or not?
700 // //m_PC = makeDiag(stdevhg).mulRight(mVhg.mulRight(mS));
701 // m_PC = makeDiag(stdevhg).mulRight(mVhg);
702 // m_PC.setRange(m_PC.sizeX()-1,0,avghg);
703  m_PC = mV;
704  m_IPC = inverse(m_PC);
705  //cout << m_Sigma << m_Mean << endl << m_Stdev << endl;
706 // DUMP(m_SubStructName);
707 // DUMP(m_Mean);
708 // DUMP(m_Stdev);
709 }
710 
712  bool backwards,
713  dword dtype) const
714 {
715  //ATTENTION: backward transform isn't working the way I'm doing it here
716  // so, only use forward transform
717  EMDistribution* emdist = NULL;
718  switch(DistrType(dtype)) {
719  case EMD_PCA:
720  {
721  if(m_Sigma.empty()) break;
722  //generate a transformed gaussian distribution (using PCA xform)
723  DMatrixf stddm(m_Sigma);
724  stddm *= getSearchPara().m_ScaleStd;
725  PropVec stdtf(&stddm.at(0,0));
726  EMDGauss* eminput = new EMDGauss(PropVec(0.f), stdtf);
727  //EMDRect* eminput = new EMDRect(stdtf*-1.f, stdtf);
728  DMatrixf tfmat = backwards ? m_IPC : m_PC;
729 #ifndef _PROPTF_NORMALIZE_SCALE_
730  DMatrixf mmmat = dmutil::makeIdentity<float>(tfmat.sizeX());
731  mmmat.at(PVEC_POSX,PVEC_POSX) = ppmm;
732  mmmat.at(PVEC_POSY,PVEC_POSY) = ppmm;
733  tfmat = tfmat.mulLeft(mmmat);
734 #endif
735  emdist = (EMDistribution*) new EMDXformer(eminput, wprop, tfmat);
736  ((EMDXformer*)emdist)->setMean(m_Mean);
737  ((EMDXformer*)emdist)->setStdev(m_Stdev);
738  }
739  break;
740  case EMD_RECT:
741  {
742  //generate a rectangular uniform distribution
743  PropVec propsd(m_Stdev);
744  //propsd*=sqrt(3.f);
745  PropVec lb(m_Mean-propsd);
746  PropVec ub(m_Mean+propsd);
747 #ifndef _PROPTF_NORMALIZE_SCALE_
748  setPropPos(lb, getPropPos(lb)*ppmm);
749  setPropPos(ub, getPropPos(ub)*ppmm);
750 #endif
751  PropVec olb(wprop), oub(wprop);
752  if(backwards) { invPropTF(olb, ub); invPropTF(oub, lb); }
753  else { fwdPropTF(olb, lb); fwdPropTF(oub, ub); }
754  PropVec mean(m_Mean);
755  setPropPos(mean, getPropPos(mean)*ppmm);
756  PropVec a(wprop);
757  ExpectationMap::correctLBUB(olb, oub);
758  emdist = (EMDistribution*) new EMDRect(olb,oub);
759  }
760  break;
761  case EMD_RECTTF:
762  {
763  //generate a rectangular uniform distribution
764  PropVec propsd(m_Stdev);
765  propsd*=sqrt(3.f);
766  PropVec lb(m_Mean-propsd);
767  PropVec ub(m_Mean+propsd);
768 #ifndef _PROPTF_NORMALIZE_SCALE_
769  setPropPos(lb, getPropPos(lb)*ppmm);
770  setPropPos(ub, getPropPos(ub)*ppmm);
771 #endif
773  if(backwards) { invPropTF(olb, lb); invPropTF(oub, ub); }
774  else { fwdPropTF(olb, lb); fwdPropTF(oub, ub); }
775  ExpectationMap::correctLBUB(olb, oub);
776  EMDistribution* inpdist = (EMDistribution*) new EMDRect(olb,oub);
777  emdist = (EMDistribution*) new EMDXformer(inpdist, wprop);
778  }
779  break;
780  case EMD_GAUSS:
781  {
782  //generate a multidimensional axis-aligned gaussian distribution
783  PropVec sdevpv(m_Stdev);
784  sdevpv *= getSearchPara().m_ScaleStd;
785  PropVec meanpv(m_Mean);
786 #ifndef _PROPTF_NORMALIZE_SCALE_
787  setPropPos(sdevpv, getPropPos(sdevpv)*ppmm);
788  setPropPos(meanpv, getPropPos(meanpv)*ppmm);
789 #endif
790  PropVec cprop(getIdentityPropTF());
791  if(backwards) invPropTF(cprop, meanpv);
792  else fwdPropTF(cprop, meanpv); //cool form of: cprop = meanpv
793  EMDistribution* inpdist =
794  (EMDistribution*) new EMDGauss(PropVec(0.f), sdevpv);
795  emdist = (EMDistribution*) new EMDXformer(inpdist, wprop);
796  ((EMDXformer*)emdist)->setMean(cprop);
797  }
798  break;
799  }
800  return emdist;
801 }
802 
804  const PropVec& wprop, float ppmm, float radius) const
805 {
806  lb = ub = wprop;
807  PropVec tflb(m_Mean);
808  tflb -= (m_Stdev*radius);
809  PropVec tfub(m_Mean);
810  tfub += (m_Stdev*radius);
811 #ifndef _PROPTF_NORMALIZE_SCALE_
812  setPropPos(tflb, getPropPos(tflb)*ppmm);
813  setPropPos(tfub, getPropPos(tfub)*ppmm);
814 #endif
815  fwdPropTF(lb, tflb);
816  fwdPropTF(ub, tfub);
817  if(getPropScale(lb)<0.001) setPropScale(lb, 0.001);
818  setPropDir(lb, 0);
819  setPropDir(ub, 2*M_PI);
820 }
821 
823 {
824  m_SubStructName.clear();
825  m_SupStructName.clear();
826  m_Transform = 0.f;
827  m_Pivot = -1;
828  m_Polar = false;
829  m_Mode = MODE_NONE;
832 }
833 
835 {
836  if(is.getKey() != "substruct") return false;
837  clear();
838  m_SubStructName = is.getValue();
839  bool readon = true;
840  while(readon && is.getNextLine()) {
841  const string& key = is.getKey();
842  const string& value = is.getValue();
843  if(key == "transform") {
844  fromString(value, m_Transform);
845  } else if(key == "pivot") {
846  fromString(value, m_Pivot);
847  m_Pivot--;
848  } else if(key == "rateweight") {
849  fromString(value, m_RateWeight);
850  } else if(key == "rateth") {
851  fromString(value, m_RateTH);
852  } else if(key == "mode") {
853  if(value.find("nospawn") != value.npos)
854  m_Mode |= MODE_NOSPAWN;
855  if(value.find("showstats") != value.npos)
857  } else if (key == "end") readon = false;
858  else { is.setParseError("error parsing substructure"); return false; }
859  }
860  if(is.error()) return false;
861  return true;
862 }
863 
864 ostream& operator<<(ostream& os, const SubStructure& ss)
865 {
866  os << " substruct " << ss.m_SubStructName << endl;
867  os << " transform " << ss.m_Transform << endl;
868  if(ss.m_Pivot>=0)
869  os << " pivot " << ss.m_Pivot+1 << endl;
870  if(ss.m_Polar) os << " polar" << endl;
872  os << " rateweight " << ss.m_RateWeight << endl;
873  if(ss.m_Mode != SubStructure::MODE_NONE) {
874  os << " mode"
875  << (ss.m_Mode&SubStructure::MODE_NOSPAWN ? " nospawn" : "")
876  << (ss.m_Mode&SubStructure::MODE_SHOWSTATS ? " showstats" : "")
877  << endl;
878  }
879  os << " end # of substruct" << endl;
880  return os;
881 }
MT & transpose()
Definition: DMatrix.h:260
float getLiveliness() const
Definition: Model.cpp:1222
float m_Integral
Definition: ExpMap.h:67
std::string m_StructName
Definition: ExpMap.h:38
float imgforce
Definition: PartParam.h:67
ExpectationMap & getExpectationMap()
Definition: Searcher.h:37
static ParticleParam global
Definition: PartParam.h:72
std::string getInfoFilename(const std::string &suffix) const
Definition: MStruct.cpp:157
#define NULL
Definition: simpletypes.h:9
Model m_Model
Definition: MStruct.h:120
float getGeneration(const Model *model) const
Definition: Searcher.cpp:303
void analyseTF(const DMatrixf &tfmat)
Definition: MStruct.cpp:646
#define DUMP(expr)
Definition: common.h:16
std::string m_SubStructName
Definition: MStruct.h:41
void setExpectationMap(const ExpectationMap &em)
Definition: Searcher.cpp:346
bool writeFile(const char *filename) const
Definition: Model.cpp:381
float getQualityOfFit() const
Definition: Model.cpp:1204
void showStats(const SubStructure &subs, std::ostream &os=std::cout) const
Definition: MStruct.cpp:561
DMatrix< T > inverse(const DMatrix< T > &dmat)
Definition: DMatrixLinAlg.h:67
int getNEdges() const
Definition: Model.h:78
PropVec & convertPropToMM(PropVec &prop) const
Definition: Model.cpp:1304
const std::string & getPath() const
Definition: StructTable.h:70
std::map< dword, Winner > & getWinList()
Definition: Searcher.h:30
void attachDataset(dataset_cptr dataset)
Definition: Model.cpp:85
T & fromString(const std::string &str, T &v)
Definition: utils.h:67
dword m_Mode
Definition: MStruct.h:48
std::map< std::string, SubStructure > m_SubStructures
Definition: MStruct.h:122
void buildAllStats()
Definition: MStruct.cpp:232
const Winner * getWinner(dword wid) const
Definition: MStruct.cpp:80
std::map< std::string, SubStructure * > m_SupStructures
Definition: MStruct.h:123
void mergeSensorCollection(SensorCollection *sensors)
Definition: Model.cpp:596
void clear(bool oldonly=false)
Definition: ExpMap.cpp:141
std::map< std::string, MStructure > & getStructs()
Definition: StructTable.h:71
#define SHAPEADAPTTIMESTEP
PropVec getPropertiesMM() const
return property vector using millimeter scale
Definition: Model.cpp:1274
StructTable * m_PStructTable
Definition: MStruct.h:118
const PropVec & getProperties() const
Definition: Model.cpp:1263
#define STRUCT_SHAPEWEIGHT
Definition: MStruct.cpp:19
~MStructure()
Definition: MStruct.cpp:39
MT getDiag(int offset=0)
Definition: DMatrix.h:231
void setShapeWeight(float shapeweight)
Definition: Searcher.h:46
bool empty() const
Definition: DMatrix.h:50
MStructure & operator=(const MStructure &rhs)
Definition: MStruct.cpp:45
bool read(ParseFile &is)
Definition: MStruct.cpp:834
EMDistribution * getEDist(dword wid)
Definition: ExpMap.cpp:65
Point2D getPropPos(const PropVec &prop)
Definition: PropVec.h:13
float m_PCTH
threshold for principle components
Definition: Searcher.h:188
dword loadRefProp()
Definition: MStruct.cpp:198
DMatrixf m_PC
Definition: MStruct.h:46
VVector< float, 4 > PropVec
Definition: PropVec.h:8
STL namespace.
std::string toString(T v)
Definition: utils.h:60
void clear()
Definition: MStruct.cpp:61
PropVec & invPropTF(PropVec &to, const PropTF &tf)
Definition: PropVec.h:66
static void correctLBUB(PropVec &lb, PropVec &ub)
Definition: ExpMap.cpp:193
dword getShootCount() const
Definition: ExpMap.h:62
PropTF getIdentityPropTF()
Definition: PropVec.h:81
Implements an Edge with spring functionality.
Definition: Edge.h:14
#define SUBSTRUCT_RATETH
Definition: MStruct.cpp:20
ParticleParam phys
physical parameter set
Definition: Model.h:257
float getPropScale(const PropVec &prop)
Definition: PropVec.h:19
float m_ScaleStd
scale stdev of link
Definition: Searcher.h:176
void scale(float factor, bool movepoints=false)
multiply all rest lengths by factor
Definition: Model.cpp:1140
float m_Size
stdradius in mm
Definition: MStruct.h:121
void add(EMDistribution *ed)
Definition: ExpMap.cpp:23
PropTF getPropTF(const PropVec &from, const PropVec &to)
Definition: PropVec.h:37
std::map< dword, PropVec > m_RefProp
Definition: MStruct.h:124
const std::string & getValue() const
Definition: ParseFile.h:57
bool error() const
Definition: ParseFile.h:50
friend std::ostream & operator<<(std::ostream &os, const SubStructure &ss)
Definition: MStruct.cpp:864
float m_RateWeight
Definition: MStruct.h:47
void setShootCount(dword scount)
Definition: ExpMap.h:61
void setCreator(const Winner &creator)
Definition: ExpMap.h:58
dword getRefModelIDs(Iter iter) const
Definition: MStruct.h:131
Model * m_Model
Definition: ExpMap.h:36
float m_Weight
Definition: MStruct.h:126
const Point getCenter() const
Definition: Model.cpp:852
int m_MaxShoot
maximum number of spawns from an exp map
Definition: Searcher.h:191
bool getRefModel(dword id, Model &model) const
Definition: MStruct.cpp:167
std::string m_SupStructName
Definition: MStruct.h:41
PropVec & setPropDir(PropVec &prop, float dir)
Definition: PropVec.h:28
const Searcher & getSearcher() const
Definition: MStruct.h:73
bool getRefProp(dword id, PropVec &prop) const
Definition: MStruct.cpp:174
bool isFrame() const
Definition: MStruct.h:75
int getNNodes() const
Definition: Model.h:77
void verifyWinnerRating()
Definition: MStruct.cpp:531
const std::string & getFilename() const
Definition: StructTable.h:69
MT & min(const MT &rhs)
Definition: DMatrix.h:129
bool step(float dt)
Definition: Searcher.cpp:288
PropVec & setPropPos(PropVec &prop, const Point2D &p)
Definition: PropVec.h:16
float springconstant
spring constant
Definition: Edge.h:134
void setName(const std::string &name)
Definition: MStruct.cpp:73
void clear()
Definition: MStruct.cpp:822
void setUB(const PropVec &ub)
Definition: ExpMap.h:87
float m_RateTH
Definition: MStruct.h:47
float m_BestRating
Definition: ExpMap.h:39
SensorCollection * getSensors()
Definition: StructTable.cpp:48
void addSubStruct(const SubStructure &substruct)
Definition: MStruct.cpp:87
void saveRefProp() const
Definition: MStruct.cpp:218
void setMean(const PropVec &mean)
Definition: ExpMap.h:134
const std::string & getPath() const
Definition: ParseFile.h:52
const std::string & getKey() const
Definition: ParseFile.h:56
void refSubSuper(bool doclear=false)
Definition: MStruct.cpp:359
SubStructure(const std::string &subStructName="", const std::string &supStructName="", const PropTF &transform=PropTF(0.f), int pivot=-1)
Definition: MStruct.cpp:636
DMatrix< T > & abs(DMatrix< T > &mat)
Definition: DMatrixUtil.h:132
Definition: ExpMap.h:73
const Winner * getWinner(dword id) const
Definition: Searcher.cpp:668
float getShapeWeight() const
Definition: Searcher.h:47
Point2D & convertPointToMM(Point2D &pt) const
Definition: Model.cpp:1291
void write(std::ostream &os) const
Definition: MStruct.cpp:132
dword sizeX() const
Definition: DMatrix.h:42
const Node & getNode(int index) const
Definition: Model.h:74
#define M_PI
Definition: mathutil.h:9
DMatrixf m_Sigma
Definition: MStruct.h:46
Definition: ExpMap.h:10
Definition: Model.h:33
virtual float ratePropVec(const PropVec &prop, Winner *winner=NULL) const
Definition: ExpMap.h:56
void setName(const std::string &name)
Definition: Model.cpp:399
bool SVD(const DMatrix< T > &dmat, DMatrix< T > &mU, DMatrix< T > &mS, DMatrix< T > &mV)
Definition: DMatrixLinAlg.h:74
std::string m_Name
Definition: MStruct.h:119
MT & resize(dword _sx, dword _sy, const T &inival=T())
Definition: DMatrix.h:30
const PropVec & getLB() const
Definition: ExpMap.h:86
TPtr begin()
Definition: VVector.h:37
float lengthRatio() const
Definition: Edge.h:91
SearcherParams & getSearchPara()
Definition: Searcher.h:194
bool m_Polar
Definition: MStruct.h:44
void setRefProp(dword id, const PropVec &prop)
Definition: MStruct.cpp:183
unsigned long dword
Definition: simpletypes.h:6
static DMatrixf & adjustByAvgDir(DMatrixf &mat)
MT mulLeft(const MT &rhs) const
Definition: DMatrix.h:159
PropVec & fwdPropTF(PropVec &from, const PropTF &tf)
Definition: PropVec.h:51
void setRefModel(dword id, const Model &model)
Definition: MStruct.cpp:188
Model & getRepresentative()
Definition: ExpMap.h:156
Searcher m_Searcher
Definition: MStruct.h:125
const Edge & getEdge(int index) const
Definition: Model.h:71
MT & max(const MT &rhs)
Definition: DMatrix.h:110
PropTF m_Transform
Definition: MStruct.h:42
void markAllOld()
Definition: ExpMap.cpp:159
void updateParticles(float dt, int method=0)
Definition: Model.cpp:752
float restlength
Definition: Edge.h:132
virtual void setIntegral(float integral)
Definition: ExpMap.h:51
dword m_WinnerID
Definition: ExpMap.h:37
const PropVec & getUB() const
Definition: ExpMap.h:85
const std::string & getFilename() const
Definition: Model.h:225
void setParseError(const std::string &msg="")
Definition: ParseFile.h:80
DMatrix< T > avg(const DMatrix< T > &mat)
Definition: DMatrixUtil.h:90
bool buildMasterModel(float scscale=1.f)
Definition: MStruct.cpp:283
MT & setRange(dword ox, dword oy, const MT &mat)
Definition: DMatrix.h:185
DMatrix< T > stdev(const DMatrix< T > &mat)
Definition: DMatrixUtil.h:106
bool readFile(const char *filename, bool fullread=true)
Definition: Model.cpp:365
dword sizeY() const
Definition: DMatrix.h:43
void clear()
remove and destroy all geometry information (nodes and edges)
Definition: Model.cpp:95
Definition: Point.h:16
EMDistribution * generateEMDist(const PropVec &wprop, float ppmm, bool inverse=false, dword dtype=EMD_RECT) const
Definition: MStruct.cpp:711
T & at(dword x, dword y)
Definition: DMatrix.h:46
float springconst
Definition: PartParam.h:64
MT & getRange(dword ox, dword oy, MT &mat) const
Definition: DMatrix.h:197
Winner m_FrameWinner
Definition: MStruct.h:127
PropVec & setPropScale(PropVec &prop, float pscale)
Definition: PropVec.h:22
void pushLine(const std::string &line)
Definition: ParseFile.h:74
bool stepSearch(float dt)
Definition: MStruct.cpp:630
DMatrix< T > expand(const DMatrix< T > &mat, dword mx, dword my)
Definition: DMatrixUtil.h:113
PropVec m_Stdev
Definition: MStruct.h:45
void rebuildExpMap()
Definition: MStruct.cpp:482
void getLBUB(PropVec &lb, PropVec &ub, const PropVec &wprop, float ppmm, float radius=3) const
Definition: MStruct.cpp:803
#define SUBSTRUCT_RATEWEIGHT
Definition: MStruct.cpp:18
dword getDataScale() const
Definition: Model.h:204
static unsigned int size()
Definition: VVector.h:41
DMatrixf m_IPC
Definition: MStruct.h:46
int m_Pivot
Definition: MStruct.h:43
const bool getNextLine()
Definition: ParseFile.h:59
bool addExpectation(const SubStructure &subs, ExpectationMap &expmap, bool inverse=false) const
Definition: MStruct.cpp:373
void setLB(const PropVec &lb)
Definition: ExpMap.h:88
bool read(ParseFile &is)
Definition: MStruct.cpp:94
MStructure(const std::string &name="", StructTable *psTable=NULL)
Definition: MStruct.cpp:24
void setRepresentative(const Model &model)
Definition: ExpMap.cpp:18
dataset_ptr getDataset()
Definition: StructTable.cpp:43
MT mulRight(const MT &rhs) const
Definition: DMatrix.h:149
DMatrix< T > & sqrt(DMatrix< T > &mat)
Definition: DMatrixUtil.h:81
PropVec m_Mean
Definition: MStruct.h:45