-
Notifications
You must be signed in to change notification settings - Fork 767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Minimum Feedback Arc Set (MFAS) for 1dsfm #387
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please run Google formatting on these files.
gtsam/sfm/mfas.h
Outdated
@@ -0,0 +1,65 @@ | |||
/* | |||
This file defines functions used to solve a Minimum feedback arc set (MFAS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the file brief to the GTRC copyright. Do keep the comment about how this is taken from another source.
gtsam/sfm/mfas.h
Outdated
* @param edges reference to vector of KeyPairs | ||
* @param weights weights corresponding to edges | ||
*/ | ||
void flipNegEdges(std::vector<KeyPair> &edges, std::vector<double> &weights); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flipNegativeEdges
?
gtsam/sfm/mfas.h
Outdated
* @param ordered_positions: map from node to position in the ordering (0 | ||
* indexed) | ||
*/ | ||
void mfasRatio(const std::vector<KeyPair> &edges, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is mfas in the function name necessary if we've defined a mfas namespace?
gtsam/sfm/mfas.cpp
Outdated
FastMap<Key, double> win_deg; | ||
FastMap<Key, double> wout_deg; | ||
FastMap<Key, vector<pair<int, double> > > inbrs; | ||
FastMap<Key, vector<pair<int, double> > > onbrs; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use full names to make code more readable?
Thank you for reviewing @varunagrawal. I am currently working on changing this implementation, but I will make the changes you suggested too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Akshay, great first cut. A bunch of comments, but main one is this: I will need very strong arguments as to why any method would have to be non-const and you store intermediate results as instance variables. We try to be functional, even in C++ :-)
gtsam/sfm/MFAS.h
Outdated
|
||
// used to represent edges between two nodes in the graph | ||
using KeyPair = std::pair<Key, Key>; | ||
using TranslationEdges = std::map<KeyPair, Unit3>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe name it UnitTranslationEdges?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I do appreciate the name, I used the same that was used in TranslationRecovery.h for consistency. We might not use TranslationEdges now that we are changing the interface to vector of edges, so I'm not changing the name right now.
gtsam/sfm/MFAS.h
Outdated
* @brief Construct from the nodes in a graph (points in 3D), edges | ||
* that are translation directions in 3D and the direction in | ||
* which edges are to be projected. | ||
* @param nodes Nodes in the graph |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of nodes in a graph, we can add something more descriptive. Maybe something like pair of points in 3D?
Or are we making MFAS a generic class which works on any graph and not specific to SLAM?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the documentation to explain what these nodes represent when used in a translation averaging context.
gtsam/sfm/MFAS.cpp
Outdated
// in each iteration, one node is appended to the ordered list | ||
while (orderedNodes_.size() < nodes_->size()) { | ||
|
||
// finding the node with the max heuristic score |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
separate this in a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not used anywhere else, but yes, improves readability to factor that into a different function. I shall make that change in the next iteration if no other changes are suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a maxim that no function should have naked for loops, and no function should be bigger than 4 lines.
Thank you for the comments @dellaert and @ayushbaid. Prof. Frank, this class would be used on graphs with a large number of nodes (which represent cameras in our case). 1dsfm requires several instances of this class to compute the ordering for several sampled directions. These instances would run in parallel. I used the pointers for relativeTranslations_ and nodes_ to avoid storing/copying these large members for each instance. Yes, constant reference members would also serve the same purpose and I am happy to make that change, but for future reference please let me know why we prefer them. |
I can also make most intermediate results internal to the methods, but its a little tricky for |
No, in that case shared pointer is fine, but then document it :-) although, I’m wondering about the design: why not have one class and run a method in parallel? |
Anything that is computed in the constructor is fine as an instance variable. The functional pattern we use is: only constructor is non-const. |
Prof. @dellaert and @ayushbaid could you please re-review and let me know if more changes are necessary? I think it is better to make the change from the map to vector for representing edges in a separate PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard to review as the code is hard to follow and rather c++03 :-/ maybe one more iteration?
gtsam/sfm/MFAS.cpp
Outdated
// in each iteration, one node is appended to the ordered list | ||
while (orderedNodes_.size() < nodes_->size()) { | ||
|
||
// finding the node with the max heuristic score |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a maxim that no function should have naked for loops, and no function should be bigger than 4 lines.
gtsam/sfm/MFAS.cpp
Outdated
} | ||
|
||
// iterate over all edges | ||
for (auto it = edgeWeights_.begin(); it != edgeWeights_.end(); it++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gtsam/sfm/MFAS.cpp
Outdated
} | ||
} | ||
// find its in_neighbors, adjust their out_weights | ||
for (auto it = in_neighbors[choice].begin(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use c++11 for loops, at least :-)
gtsam/sfm/MFAS.cpp
Outdated
} | ||
} | ||
return outlier_weights; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add newline
gtsam/sfm/MFAS.cpp
Outdated
} | ||
} | ||
|
||
std::vector<Key> MFAS::computeOrdering() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe don’t go to four lines, but this function is indeed too long and complicated. Also ask yourself which STL algorithms you could be using.
@akshay-krishnan merge in develop before doing another push as we changed CI to GitHub actions... |
@dellaert I have made some changes to improve the modularity and readability. Please re-review and let me know if there are more changes I can make. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!
@varunagrawal please approve and merge or comment on what is missing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR implements a solution to the Minimum Feedback Arc Set (MFAS) problem. We use the solution from Kyle Wilson and Noah Snavely's ECCV14 paper.
This change is