-
Notifications
You must be signed in to change notification settings - Fork 11
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
Edge Cost Query #94
Edge Cost Query #94
Conversation
out_scores[i] = v_costs[i]; | ||
} | ||
*out_score_size = v_costs.size(); | ||
//if (!std::isfinite(*out_float)) *out_float = -1.0f; |
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.
Reason?
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.
Removed. It was a reminder that invalid edges come out as NaN which isn't finite.
src/Cinterface/spatialstructures_C.h
Outdated
\brief Get the alternate costs of traversing a given path | ||
|
||
\param g The graph to traverse | ||
\param path A path to get costs from |
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 this common in other docs? it says path but the parameter is ids
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 mixed up the two docstrings between AlternateCostsAlongPathWithIDs and AlternateCostsAlongPathStruct. Should be resolved and other docs are fine
vector<float> Graph::GetEdgeCostsFromNodeIDs(vector<int>& ids, const string& cost_type) const { | ||
// Assume that ids is given in [parent1, child1, parent2, child2,...] | ||
// Return an empty array if this attribute doesn't exist | ||
// Need to raise error if odd number of ids |
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.
Do the check of odd ids.
there should be a unittest for testing what happens when invalid edge is given. maybe handled in GetCost
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.
For inputs with an odd number of ids, the C++ function GetEdgeCostsFromNodeIDs
now throws std::invalid_argument
and the C_Interface throws GENERIC_ERROR
if this is the case (I didn't want to add any new error codes). Moreover, NaN represents an invalid edge, which still gets added to the output array. If you want this to throw an error, then I can modify the code.
The corresponding UnitTest has been updated to check these two edge cases.
src/Python/dhart/spatialstructures/spatial_structures_native_functions.py
Show resolved
Hide resolved
src/Python/dhart/spatialstructures/spatial_structures_native_functions.py
Outdated
Show resolved
Hide resolved
|
||
def DestroyEdges(edge_list_ptr: c_void_p): | ||
""" Call the destructor for a list of edges """ | ||
HFPython.DestroyEdges(edge_list_ptr) |
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.
Did you make a list of 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.
No, but the C_Interface function was already implemented so I just used that.
return out_vals | ||
|
||
# Extract data from out_scores | ||
return list(out_scores[:out_scores_size.value]) |
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.
why is this cast to a list?
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 was the same concept as the for loop. I didn't really know what you were talking about at the time and I will replace it with the raw data when I fix all of the for loops.
elif error_code == HF_STATUS.OUT_OF_RANGE: | ||
# Tried to add an edge to an alternate cost type | ||
# that didn't exist | ||
raise InvalidCostOperation( |
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.
Did you test if any of these error codes are actually hit?
@@ -483,7 +502,7 @@ def GetEdgeCosts(self, cost_type: str, ids: List[int] | None = None) -> List[flo | |||
>>> g.AddEdgeToGraph(0,1,50) | |||
>>> g.AddEdgeToGraph(0,2,50) | |||
>>> g.AddEdgeToGraph(1,2,50) | |||
>>> csr = g.CompressToCSR() | |||
>>> _ = g.CompressToCSR() #doctest: +ELLIPSIS |
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 have wondered about this. The does the C function checks if the graph was compressed already? Historically we have said you always need to compress, and all of these examples do it, but what if not?
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.
If you're talking about CompressToCSR(), the C++ function checks if it was compressed before doing anything. The graph has a variable needs_compression
that is maintained.
dhart/src/Cpp/spatialstructures/src/graph.cpp
Lines 1106 to 1126 in 4482e69
void Graph::Compress() { | |
// Only do this if the graph needs compression. | |
if (needs_compression) { | |
// If this has cost arrays then we never should have come here | |
assert(!this->has_cost_arrays); | |
// Note that the matrix must have atleast one extra row/column | |
int array_size = this->size() + 1; | |
// Resize the edge matrix | |
ResizeIfNeeded(); | |
// Set the edge matrix from triplets. | |
edge_matrix.setFromTriplets(triplets.begin(), triplets.end()); | |
// Mark this graph as not requiring compression | |
needs_compression = false; | |
} | |
} |
Closes #65 #90
CountEdges
andCountEdgesFromEdgeSets
to count the number of edges of given cost type within the graph.GetEdgeCosts
to get all edge costs of given cost type within a graph. A new methodGetCostMap
that exposes the private attribute for the graph's cost map to public is utilized for this task. If only a subset of edge costs are needed, then the methodGetEdgeCostFromNodeIDs
is used instead. The user passes in an array of edges using the ids of the attached nodes (parent1, child1) and gets all costs of desired edges.AlternateCostsAlongPath
which takes a path and computes a given cost type of each edge in the path. This uses helper functionMapPathToVectorOfNodes
to map a vector of format[node1,node2,...,nodek]
to[node1,node2,node2,...,nodek]
to utilize theGetEdgeCosts
methods.GetEdgeCosts
, which gets all costs of a given type, andGetEdgeCostsFromNodeIDs
, which gets the costs of a subset of edges represented by node ids.CountNumberOfEdges
which counts the number of edges of a given cost type within the graph.AlternateCostsAlongPathWithIDs
andAlternateCostsAlongPathStruct
which sends the correspondingg C++ methods to Python.GetEdgeCosts
andNumEdges
call the new C_Interface functions to query cost type and count number of edges.AlternateCostsAlongPath
calls the corresponding C_Interface function to compute alternate costs along a path. It is possible to compute alternate costs of a path in the form of a list of ids, but support for path structures still need to be implemented.SizeOfEdgeVector
to compute the size of an edge vector in C++.DestroyEdges
to destroy a list of edges in C++.PathQuerying.py
which guides the user on how to get a shortest path and how to get the alternate costs for nodes along that path. Provides plots to help the user visualize the process.AddEdgeToGraph
Python implementation which took a node yet couldn't handle it properly. A new C_Interface functionAddEdgeFromNodeStructs
was added for this purpose andAddEdgeToGraph
now works as intended.EdgeStruct
Python implementation which resembles theEdge
structure (notIntEdge
) in C++. This comes along with theEdgeList
class and theCreateListOfEdgeStructs
method.GetEdgesForNode
in Python and C++, which takes in a node and a graph and finds all edges corresponding to that node. The Python implementation returns anEdgeList
containing all the edges.Attached is a screenshot of all the VS test cases (including three new test cases for the C++ and C_Interface functions, with the exception of HFUnitTests/CInterfaceTests/C_Pathfinder/CreateManyPathsPerformanceTest due to runtime issues) and the test_graph.py test cases passing.
![image](https://private-user-images.githubusercontent.com/109942147/408226025-9ef7bd3e-f2ac-4846-9d3a-62d66d1fca04.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzNTYyNjAsIm5iZiI6MTczOTM1NTk2MCwicGF0aCI6Ii8xMDk5NDIxNDcvNDA4MjI2MDI1LTllZjdiZDNlLWYyYWMtNDg0Ni05ZDNhLTYyZDY2ZDFmY2EwNC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjEyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxMlQxMDI2MDBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0xOWZlMTUzOWM2MzFiODAyYzRmNGI5Mzg1MmQ0NWZkYjdhMmU1YTRiY2VjZmJkOGRhMjVkZDA0MTY4MmZiNjRlJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.nilqA1tLm-AQ1GasbI2E2vLGKLsPDjVKh4pUrT1yjCw)
![image](https://private-user-images.githubusercontent.com/109942147/408225127-5fc3c6c3-9414-48bb-9b6d-d8aa4e7cfe86.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkzNTYyNjAsIm5iZiI6MTczOTM1NTk2MCwicGF0aCI6Ii8xMDk5NDIxNDcvNDA4MjI1MTI3LTVmYzNjNmMzLTk0MTQtNDhiYi05YjZkLWQ4YWE0ZTdjZmU4Ni5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMjEyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDIxMlQxMDI2MDBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT0wYmNmMDIwMjg0ZDA0OWViZGFmNWQwMjJkM2I2MjI1YzhiZmQ3ZTk0Y2NmY2MwY2RlNTcxZmUwNGIzY2E0NGYzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.CaFebo2kRkwlbVrTtxDhVQgMtfT0oMTyLcyrzJQxBC0)