Fixed up iterative methods to use struct
							parent
							
								
									d814710575
								
							
						
					
					
						commit
						2cedda703c
					
				|  | @ -117,7 +117,7 @@ void KeyInfo::initialize(const GaussianFactorGraph &fg) { | ||||||
|   for (size_t i = 0; i < n; ++i) { |   for (size_t i = 0; i < n; ++i) { | ||||||
|     const size_t key = ordering_[i]; |     const size_t key = ordering_[i]; | ||||||
|     const size_t dim = colspec.find(key)->second; |     const size_t dim = colspec.find(key)->second; | ||||||
|     insert(make_pair(key, KeyInfoEntry(i, dim, start))); |     this->emplace(key, KeyInfoEntry(i, dim, start)); | ||||||
|     start += dim; |     start += dim; | ||||||
|   } |   } | ||||||
|   numCols_ = start; |   numCols_ = start; | ||||||
|  | @ -126,8 +126,8 @@ void KeyInfo::initialize(const GaussianFactorGraph &fg) { | ||||||
| /****************************************************************************/ | /****************************************************************************/ | ||||||
| vector<size_t> KeyInfo::colSpec() const { | vector<size_t> KeyInfo::colSpec() const { | ||||||
|   std::vector<size_t> result(size(), 0); |   std::vector<size_t> result(size(), 0); | ||||||
|   for ( const KeyInfo::value_type &item: *this ) { |   for ( const auto &item: *this ) { | ||||||
|     result[item.second.index()] = item.second.dim(); |     result[item.second.index] = item.second.dim; | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  | @ -135,8 +135,8 @@ vector<size_t> KeyInfo::colSpec() const { | ||||||
| /****************************************************************************/ | /****************************************************************************/ | ||||||
| VectorValues KeyInfo::x0() const { | VectorValues KeyInfo::x0() const { | ||||||
|   VectorValues result; |   VectorValues result; | ||||||
|   for ( const KeyInfo::value_type &item: *this ) { |   for ( const auto &item: *this ) { | ||||||
|     result.insert(item.first, Vector::Zero(item.second.dim())); |     result.emplace(item.first, Vector::Zero(item.second.dim)); | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -89,7 +89,7 @@ void GaussianFactorGraphSystem::multiply(const Vector &x, Vector& AtAx) const { | ||||||
|   VectorValues vvX = buildVectorValues(x, keyInfo_); |   VectorValues vvX = buildVectorValues(x, keyInfo_); | ||||||
| 
 | 
 | ||||||
|   // VectorValues form of A'Ax for multiplyHessianAdd
 |   // VectorValues form of A'Ax for multiplyHessianAdd
 | ||||||
|   VectorValues vvAtAx; |   VectorValues vvAtAx = keyInfo_.x0(); // crucial for performance
 | ||||||
| 
 | 
 | ||||||
|   // vvAtAx += 1.0 * A'Ax for each factor
 |   // vvAtAx += 1.0 * A'Ax for each factor
 | ||||||
|   gfg_.multiplyHessianAdd(1.0, vvX, vvAtAx); |   gfg_.multiplyHessianAdd(1.0, vvX, vvAtAx); | ||||||
|  | @ -132,14 +132,14 @@ VectorValues buildVectorValues(const Vector &v, const Ordering &ordering, | ||||||
| 
 | 
 | ||||||
|   DenseIndex offset = 0; |   DenseIndex offset = 0; | ||||||
|   for (size_t i = 0; i < ordering.size(); ++i) { |   for (size_t i = 0; i < ordering.size(); ++i) { | ||||||
|     const Key &key = ordering[i]; |     const Key key = ordering[i]; | ||||||
|     map<Key, size_t>::const_iterator it = dimensions.find(key); |     map<Key, size_t>::const_iterator it = dimensions.find(key); | ||||||
|     if (it == dimensions.end()) { |     if (it == dimensions.end()) { | ||||||
|       throw invalid_argument( |       throw invalid_argument( | ||||||
|           "buildVectorValues: inconsistent ordering and dimensions"); |           "buildVectorValues: inconsistent ordering and dimensions"); | ||||||
|     } |     } | ||||||
|     const size_t dim = it->second; |     const size_t dim = it->second; | ||||||
|     result.insert(key, v.segment(offset, dim)); |     result.emplace(key, v.segment(offset, dim)); | ||||||
|     offset += dim; |     offset += dim; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -150,8 +150,7 @@ VectorValues buildVectorValues(const Vector &v, const Ordering &ordering, | ||||||
| VectorValues buildVectorValues(const Vector &v, const KeyInfo &keyInfo) { | VectorValues buildVectorValues(const Vector &v, const KeyInfo &keyInfo) { | ||||||
|   VectorValues result; |   VectorValues result; | ||||||
|   for ( const KeyInfo::value_type &item: keyInfo ) { |   for ( const KeyInfo::value_type &item: keyInfo ) { | ||||||
|     result.insert(item.first, |     result.emplace(item.first, v.segment(item.second.start, item.second.dim)); | ||||||
|         v.segment(item.second.colstart(), item.second.dim())); |  | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -99,8 +99,8 @@ static vector<size_t> iidSampler(const vector<double> &weight, const size_t n) { | ||||||
|     const double value = rand() / denominator; |     const double value = rand() / denominator; | ||||||
|     /* binary search the interval containing "value" */ |     /* binary search the interval containing "value" */ | ||||||
|     const auto it = std::lower_bound(acc.begin(), acc.end(), value); |     const auto it = std::lower_bound(acc.begin(), acc.end(), value); | ||||||
|     const size_t idx = it - acc.begin(); |     const size_t index = it - acc.begin(); | ||||||
|     result.push_back(idx); |     result.push_back(index); | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  | @ -129,10 +129,10 @@ static vector<size_t> UniqueSampler(const vector<double> &weight, const size_t n | ||||||
| 
 | 
 | ||||||
|     /* sampling and cache results */ |     /* sampling and cache results */ | ||||||
|     vector<size_t> samples = iidSampler(localWeights, n-count); |     vector<size_t> samples = iidSampler(localWeights, n-count); | ||||||
|     for ( const size_t &id: samples ) { |     for ( const size_t &index: samples ) { | ||||||
|       if ( touched[id] == false ) { |       if ( touched[index] == false ) { | ||||||
|         touched[id] = true ; |         touched[index] = true ; | ||||||
|         result.push_back(id); |         result.push_back(index); | ||||||
|         if ( ++count >= n ) break; |         if ( ++count >= n ) break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | @ -143,8 +143,8 @@ static vector<size_t> UniqueSampler(const vector<double> &weight, const size_t n | ||||||
| /****************************************************************************/ | /****************************************************************************/ | ||||||
| Subgraph::Subgraph(const vector<size_t> &indices) { | Subgraph::Subgraph(const vector<size_t> &indices) { | ||||||
|   edges_.reserve(indices.size()); |   edges_.reserve(indices.size()); | ||||||
|   for ( const size_t &idx: indices ) { |   for ( const size_t &index: indices ) { | ||||||
|     edges_.emplace_back(idx, 1.0); |     edges_.emplace_back(index, 1.0); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -296,12 +296,12 @@ vector<size_t> SubgraphBuilder::buildTree(const GaussianFactorGraph &gfg, | ||||||
| /****************************************************************/ | /****************************************************************/ | ||||||
| vector<size_t> SubgraphBuilder::unary(const GaussianFactorGraph &gfg) const { | vector<size_t> SubgraphBuilder::unary(const GaussianFactorGraph &gfg) const { | ||||||
|   vector<size_t> result ; |   vector<size_t> result ; | ||||||
|   size_t idx = 0; |   size_t index = 0; | ||||||
|   for (const auto &factor : gfg) { |   for (const auto &factor : gfg) { | ||||||
|     if ( factor->size() == 1 ) { |     if ( factor->size() == 1 ) { | ||||||
|       result.push_back(idx); |       result.push_back(index); | ||||||
|     } |     } | ||||||
|     idx++; |     index++; | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  | @ -309,14 +309,14 @@ vector<size_t> SubgraphBuilder::unary(const GaussianFactorGraph &gfg) const { | ||||||
| /****************************************************************/ | /****************************************************************/ | ||||||
| vector<size_t> SubgraphBuilder::natural_chain(const GaussianFactorGraph &gfg) const { | vector<size_t> SubgraphBuilder::natural_chain(const GaussianFactorGraph &gfg) const { | ||||||
|   vector<size_t> result ; |   vector<size_t> result ; | ||||||
|   size_t idx = 0; |   size_t index = 0; | ||||||
|   for ( const GaussianFactor::shared_ptr &gf: gfg ) { |   for ( const GaussianFactor::shared_ptr &gf: gfg ) { | ||||||
|     if ( gf->size() == 2 ) { |     if ( gf->size() == 2 ) { | ||||||
|       const Key k0 = gf->keys()[0], k1 = gf->keys()[1]; |       const Key k0 = gf->keys()[0], k1 = gf->keys()[1]; | ||||||
|       if ( (k1-k0) == 1 || (k0-k1) == 1 ) |       if ( (k1-k0) == 1 || (k0-k1) == 1 ) | ||||||
|         result.push_back(idx); |         result.push_back(index); | ||||||
|     } |     } | ||||||
|     idx++; |     index++; | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  | @ -343,13 +343,13 @@ vector<size_t> SubgraphBuilder::bfs(const GaussianFactorGraph &gfg) const { | ||||||
|   /* traversal */ |   /* traversal */ | ||||||
|   while ( !q.empty() ) { |   while ( !q.empty() ) { | ||||||
|     const size_t head = q.front(); q.pop(); |     const size_t head = q.front(); q.pop(); | ||||||
|     for ( const size_t id: variableIndex[head] ) { |     for ( const size_t index: variableIndex[head] ) { | ||||||
|       const GaussianFactor &gf = *gfg[id]; |       const GaussianFactor &gf = *gfg[index]; | ||||||
|       for ( const size_t key: gf.keys() ) { |       for ( const size_t key: gf.keys() ) { | ||||||
|         if ( flags.count(key) == 0 ) { |         if ( flags.count(key) == 0 ) { | ||||||
|           q.push(key); |           q.push(key); | ||||||
|           flags.insert(key); |           flags.insert(key); | ||||||
|           result.push_back(id); |           result.push_back(index); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | @ -363,7 +363,7 @@ vector<size_t> SubgraphBuilder::kruskal(const GaussianFactorGraph &gfg, | ||||||
|                                         const vector<double> &weights) const { |                                         const vector<double> &weights) const { | ||||||
|   const VariableIndex variableIndex(gfg); |   const VariableIndex variableIndex(gfg); | ||||||
|   const size_t n = variableIndex.size(); |   const size_t n = variableIndex.size(); | ||||||
|   const vector<size_t> idx = sort_idx(weights) ; |   const vector<size_t> sortedIndices = sort_idx(weights) ; | ||||||
| 
 | 
 | ||||||
|   /* initialize buffer */ |   /* initialize buffer */ | ||||||
|   vector<size_t> result; |   vector<size_t> result; | ||||||
|  | @ -373,16 +373,16 @@ vector<size_t> SubgraphBuilder::kruskal(const GaussianFactorGraph &gfg, | ||||||
|   DSFVector dsf(n); |   DSFVector dsf(n); | ||||||
| 
 | 
 | ||||||
|   size_t count = 0 ; double sum = 0.0 ; |   size_t count = 0 ; double sum = 0.0 ; | ||||||
|   for (const size_t id: idx) { |   for (const size_t index: sortedIndices) { | ||||||
|     const GaussianFactor &gf = *gfg[id]; |     const GaussianFactor &gf = *gfg[index]; | ||||||
|     const auto keys = gf.keys(); |     const auto keys = gf.keys(); | ||||||
|     if ( keys.size() != 2 ) continue; |     if ( keys.size() != 2 ) continue; | ||||||
|     const size_t u = ordering.find(keys[0])->second, |     const size_t u = ordering.find(keys[0])->second, | ||||||
|                  v = ordering.find(keys[1])->second; |                  v = ordering.find(keys[1])->second; | ||||||
|     if ( dsf.find(u) != dsf.find(v) ) { |     if ( dsf.find(u) != dsf.find(v) ) { | ||||||
|       dsf.merge(u, v) ; |       dsf.merge(u, v) ; | ||||||
|       result.push_back(id) ; |       result.push_back(index) ; | ||||||
|       sum += weights[id] ; |       sum += weights[index] ; | ||||||
|       if ( ++count == n-1 ) break ; |       if ( ++count == n-1 ) break ; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -418,8 +418,8 @@ Subgraph::shared_ptr SubgraphBuilder::operator() (const GaussianFactorGraph &gfg | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Downweight the tree edges to zero.
 |   // Downweight the tree edges to zero.
 | ||||||
|   for ( const size_t id: tree ) { |   for ( const size_t index: tree ) { | ||||||
|     weights[id] = 0.0; |     weights[index] = 0.0; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* decide how many edges to augment */ |   /* decide how many edges to augment */ | ||||||
|  | @ -614,8 +614,8 @@ void SubgraphPreconditioner::transposeSolve(const Vector &y, Vector &x) const { | ||||||
| 
 | 
 | ||||||
|   /* in place back substitute */ |   /* in place back substitute */ | ||||||
|   for (const auto &cg : *Rc1_) { |   for (const auto &cg : *Rc1_) { | ||||||
|     const Vector rhsFrontal = getSubvector( |     const KeyVector frontalKeys(cg->beginFrontals(), cg->endFrontals()); | ||||||
|         x, keyInfo_, KeyVector(cg->beginFrontals(), cg->endFrontals())); |     const Vector rhsFrontal = getSubvector(x, keyInfo_, frontalKeys); | ||||||
|     const Vector solFrontal = |     const Vector solFrontal = | ||||||
|         cg->get_R().transpose().triangularView<Eigen::Lower>().solve( |         cg->get_R().transpose().triangularView<Eigen::Lower>().solve( | ||||||
|             rhsFrontal); |             rhsFrontal); | ||||||
|  | @ -625,13 +625,12 @@ void SubgraphPreconditioner::transposeSolve(const Vector &y, Vector &x) const { | ||||||
|       throw IndeterminantLinearSystemException(cg->keys().front()); |       throw IndeterminantLinearSystemException(cg->keys().front()); | ||||||
| 
 | 
 | ||||||
|     /* assign subvector of sol to the frontal variables */ |     /* assign subvector of sol to the frontal variables */ | ||||||
|     setSubvector(solFrontal, keyInfo_, |     setSubvector(solFrontal, keyInfo_, frontalKeys, x); | ||||||
|                  KeyVector(cg->beginFrontals(), cg->endFrontals()), x); |  | ||||||
| 
 | 
 | ||||||
|     /* substract from parent variables */ |     /* substract from parent variables */ | ||||||
|     for (auto it = cg->beginParents(); it != cg->endParents(); it++) { |     for (auto it = cg->beginParents(); it != cg->endParents(); it++) { | ||||||
|       const KeyInfoEntry &info = keyInfo_.find(*it)->second; |       const KeyInfoEntry &entry = keyInfo_.find(*it)->second; | ||||||
|       Eigen::Map<Vector> rhsParent(x.data() + info.colstart(), info.dim(), 1); |       Eigen::Map<Vector> rhsParent(x.data() + entry.start, entry.dim, 1); | ||||||
|       rhsParent -= Matrix(cg->getA(it)).transpose() * solFrontal; |       rhsParent -= Matrix(cg->getA(it)).transpose() * solFrontal; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -664,16 +663,16 @@ Vector getSubvector(const Vector &src, const KeyInfo &keyInfo, | ||||||
|   size_t dim = 0; |   size_t dim = 0; | ||||||
|   for (const Key &key : keys) { |   for (const Key &key : keys) { | ||||||
|     const KeyInfoEntry &entry = keyInfo.find(key)->second; |     const KeyInfoEntry &entry = keyInfo.find(key)->second; | ||||||
|     cache.emplace_back(entry.colstart(), entry.dim()); |     cache.emplace_back(entry.start, entry.dim); | ||||||
|     dim += entry.dim(); |     dim += entry.dim; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* use the cache to fill the result */ |   /* use the cache to fill the result */ | ||||||
|   Vector result = Vector::Zero(dim); |   Vector result(dim); | ||||||
|   size_t idx = 0; |   size_t index = 0; | ||||||
|   for (const auto &p : cache) { |   for (const auto &p : cache) { | ||||||
|     result.segment(idx, p.second) = src.segment(p.first, p.second); |     result.segment(index, p.second) = src.segment(p.first, p.second); | ||||||
|     idx += p.second; |     index += p.second; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return result; |   return result; | ||||||
|  | @ -681,11 +680,12 @@ Vector getSubvector(const Vector &src, const KeyInfo &keyInfo, | ||||||
| 
 | 
 | ||||||
| /*****************************************************************************/ | /*****************************************************************************/ | ||||||
| void setSubvector(const Vector &src, const KeyInfo &keyInfo, const KeyVector &keys, Vector &dst) { | void setSubvector(const Vector &src, const KeyInfo &keyInfo, const KeyVector &keys, Vector &dst) { | ||||||
|   size_t idx = 0; |   size_t index = 0; | ||||||
|   for ( const Key &key: keys ) { |   for ( const Key &key: keys ) { | ||||||
|     const KeyInfoEntry &entry = keyInfo.find(key)->second; |     const KeyInfoEntry &entry = keyInfo.find(key)->second; | ||||||
|     dst.segment(entry.colstart(), entry.dim()) = src.segment(idx, entry.dim()) ; |     const size_t keyDim = entry.dim; | ||||||
|     idx += entry.dim(); |     dst.segment(entry.start, keyDim) = src.segment(index, keyDim) ; | ||||||
|  |     index += keyDim; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -696,9 +696,9 @@ GaussianFactorGraph::shared_ptr buildFactorSubgraph( | ||||||
|   auto result = boost::make_shared<GaussianFactorGraph>(); |   auto result = boost::make_shared<GaussianFactorGraph>(); | ||||||
|   result->reserve(subgraph.size()); |   result->reserve(subgraph.size()); | ||||||
|   for ( const SubgraphEdge &e: subgraph ) { |   for ( const SubgraphEdge &e: subgraph ) { | ||||||
|     const size_t idx = e.index(); |     const size_t index = e.index(); | ||||||
|     if ( clone ) result->push_back(gfg[idx]->clone()); |     if ( clone ) result->push_back(gfg[index]->clone()); | ||||||
|     else result->push_back(gfg[idx]); |     else result->push_back(gfg[index]); | ||||||
|   } |   } | ||||||
|   return result; |   return result; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue