fixes1
							parent
							
								
									43af7c4ae4
								
							
						
					
					
						commit
						0d41941cda
					
				|  | @ -11,20 +11,21 @@ | |||
| #include <map> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| #include <unordered_set> | ||||
| 
 | ||||
| using namespace gtsam; | ||||
| using MFAS::KeyPair; | ||||
| using std::map; | ||||
| using std::pair; | ||||
| using std::unordered_map; | ||||
| using std::vector; | ||||
| using std::unordered_set; | ||||
| 
 | ||||
| // A node in the graph.
 | ||||
| struct GraphNode { | ||||
|   double inWeightSum;        // Sum of absolute weights of incoming edges.
 | ||||
|   double outWeightSum;       // Sum of absolute weights of outgoing edges.
 | ||||
|   vector<Key> inNeighbors;   // Nodes from which there is an incoming edge.
 | ||||
|   vector<Key> outNeighbors;  // Nodes to which there is an outgoing edge.
 | ||||
|   double inWeightSum;               // Sum of absolute weights of incoming edges
 | ||||
|   double outWeightSum;              // Sum of absolute weights of outgoing edges
 | ||||
|   unordered_set<Key> inNeighbors;   // Nodes from which there is an incoming edge
 | ||||
|   unordered_set<Key> outNeighbors;  // Nodes to which there is an outgoing edge
 | ||||
| 
 | ||||
|   // Heuristic for the node that is to select nodes in MFAS.
 | ||||
|   double heuristic() { return (outWeightSum + 1) / (inWeightSum + 1); } | ||||
|  | @ -33,24 +34,27 @@ struct GraphNode { | |||
| // A graph is a map from key to GraphNode. This function returns the graph from
 | ||||
| // the edgeWeights between keys.
 | ||||
| unordered_map<Key, GraphNode> graphFromEdges( | ||||
|     const map<KeyPair, double>& edgeWeights) { | ||||
|     const map<MFAS::KeyPair, double>& edgeWeights) { | ||||
|   unordered_map<Key, GraphNode> graph; | ||||
| 
 | ||||
|   for (const auto& [edge, weight] : edgeWeights) { | ||||
|   for (const auto& edgeWeight : edgeWeights) { | ||||
|     // The weights can be either negative or positive. The direction of the edge
 | ||||
|     // is the direction of positive weight. This means that the edges is from
 | ||||
|     // edge.first -> edge.second if weight is positive and edge.second ->
 | ||||
|     // edge.first if weight is negative.
 | ||||
|     MFAS::KeyPair& edge = edgeWeight.first; | ||||
|     double& weight = edgeWeight.second; | ||||
| 
 | ||||
|     Key edgeSource = weight >= 0 ? edge.first : edge.second; | ||||
|     Key edgeDest = weight >= 0 ? edge.second : edge.first; | ||||
| 
 | ||||
|     // Update the in weight and neighbors for the destination.
 | ||||
|     graph[edgeDest].inWeightSum += std::abs(weight); | ||||
|     graph[edgeDest].inNeighbors.push_back(edgeSource); | ||||
|     graph[edgeDest].inNeighbors.insert(edgeSource); | ||||
| 
 | ||||
|     // Update the out weight and neighbors for the source.
 | ||||
|     graph[edgeSource].outWeightSum += std::abs(weight); | ||||
|     graph[edgeSource].outNeighbors.push_back(edgeDest); | ||||
|     graph[edgeSource].outNeighbors.insert(edgeDest); | ||||
|   } | ||||
|   return graph; | ||||
| } | ||||
|  | @ -58,36 +62,37 @@ unordered_map<Key, GraphNode> graphFromEdges( | |||
| // Selects the next node in the ordering from the graph.
 | ||||
| Key selectNextNodeInOrdering(const unordered_map<Key, GraphNode>& graph) { | ||||
|   // Find the root nodes in the graph.
 | ||||
|   for (const auto& [key, node] : graph) { | ||||
|   for (const auto& keyNode : graph) { | ||||
|     // It is a root node if the inWeightSum is close to zero.
 | ||||
|     if (node.inWeightSum < 1e-8) { | ||||
|     if (keyNode.second.inWeightSum < 1e-8) { | ||||
|       // TODO(akshay-krishnan) if there are multiple roots, it is better to
 | ||||
|       // choose the one with highest heuristic. This is missing in the 1dsfm
 | ||||
|       // solution.
 | ||||
|       return key; | ||||
|       return keyNode.first; | ||||
|     } | ||||
|   } | ||||
|   // If there are no root nodes, return the node with the highest heuristic.
 | ||||
|   return std::max_element(graph.begin(), graph.end(), | ||||
|                           [](const std::pair<Key, GraphNode>& node1, | ||||
|                              const std::pair<Key, GraphNode>& node2) { | ||||
|                             return node1.second.heuristic() < | ||||
|                                    node2.second.heuristic(); | ||||
|                           [](const std::pair<Key, GraphNode>& keyNode1, | ||||
|                              const std::pair<Key, GraphNode>& keyNode2) { | ||||
|                             return keyNode1.second.heuristic() < | ||||
|                                    keyNode2.second.heuristic(); | ||||
|                           }) | ||||
|       ->first; | ||||
| } | ||||
| 
 | ||||
| // Returns the absolute weight of the edge between node1 and node2.
 | ||||
| double absWeightOfEdge(const Key node1, const Key node2, | ||||
|                        const map<KeyPair, double>& edgeWeights) { | ||||
|                        const map<MFAS::KeyPair, double>& edgeWeights) { | ||||
|   // Check the direction of the edge before returning.
 | ||||
|   return edgeWeights_.find(KeyPair(node1, node2)) != edgeWeights_.end() | ||||
|              ? std::abs(edgeWeights_.at(KeyPair(node1, node2))) | ||||
|              : std::abs(edgeWeights_.at(KeyPair(node2, node1))); | ||||
|   return edgeWeights_.find(MFAS::KeyPair(node1, node2)) != edgeWeights_.end() | ||||
|              ? std::abs(edgeWeights_.at(MFAS::KeyPair(node1, node2))) | ||||
|              : std::abs(edgeWeights_.at(MFAS::KeyPair(node2, node1))); | ||||
| } | ||||
| 
 | ||||
| // Removes a node from the graph and updates edge weights of its neighbors.
 | ||||
| void removeNodeFromGraph(const Key node, const map<KeyPair, double> edgeWeights, | ||||
| void removeNodeFromGraph(const Key node, | ||||
|                          const map<MFAS::KeyPair, double> edgeWeights, | ||||
|                          unordered_map<Key, GraphNode>& graph) { | ||||
|   // Update the outweights and outNeighbors of node's inNeighbors
 | ||||
|   for (const Key neighbor : graph[node].inNeighbors) { | ||||
|  | @ -95,12 +100,12 @@ void removeNodeFromGraph(const Key node, const map<KeyPair, double> edgeWeights, | |||
|     // (choice, *it) with a negative weight
 | ||||
|     graph[neighbor].outWeightSum -= | ||||
|         absWeightOfEdge(node, neighbor, edgeWeights); | ||||
|     graph[neighbor].outNeighbors.erase(graph[neighbor].outNeighbors.find(node)); | ||||
|     graph[neighbor].outNeighbors.erase(node); | ||||
|   } | ||||
|   // Update the inWeights and inNeighbors of node's outNeighbors
 | ||||
|   for (const Key neighbor : graph[node].outNeighbors) { | ||||
|     graph[neighbor].inWeightSum -= absWeightOfEdge(node, neighbor, edgeWeights); | ||||
|     graph[neighbor].inNeighbors.erase(graph[neighbor].inNeighbors.find(node)); | ||||
|     graph[neighbor].inNeighbors.erase(node); | ||||
|   } | ||||
|   // Erase node.
 | ||||
|   graph.erase(node); | ||||
|  | @ -148,10 +153,10 @@ std::map<KeyPair, double> MFAS::computeOutlierWeights() const { | |||
| 
 | ||||
|   map<KeyPair, double> outlierWeights; | ||||
|   // Check if the direction of each edge is consistent with the ordering.
 | ||||
|   for (const auto& [edge, weight] : edgeWeights_) { | ||||
|   for (const auto& edgeWeight : edgeWeights_) { | ||||
|     // Find edge source and destination.
 | ||||
|     Key source = edge.first; | ||||
|     Key dest = edge.second; | ||||
|     Key source = edgeWeight.first.first; | ||||
|     Key dest = edgeWeight.first.second; | ||||
|     if (weight < 0) { | ||||
|       std::swap(source, dest); | ||||
|     } | ||||
|  | @ -159,7 +164,7 @@ std::map<KeyPair, double> MFAS::computeOutlierWeights() const { | |||
|     // If the direction is not consistent with the ordering (i.e dest occurs
 | ||||
|     // before src), it is an outlier edge, and has non-zero outlier weight.
 | ||||
|     if (orderingPositions.at(dest) < orderingPositions.at(source)) { | ||||
|       outlierWeights[edge] = std::abs(weight); | ||||
|       outlierWeights[edge] = std::abs(edgeWeight.second); | ||||
|     } else { | ||||
|       outlierWeights[edge] = 0; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue