DHART
Loading...
Searching...
No Matches
spatialstructures_C.cpp
Go to the documentation of this file.
1#include "cost_algorithms.h"
3#include <HFExceptions.h>
4#include <graph.h>
5#include <edge.h>
6#include <node.h>
7#include <robin_hood.h>
8#include <iostream>
9
14using namespace HF::Exceptions;
15using std::vector;
16using std::string;
17
18
19inline bool parse_string(const char * c) {
20 if (!c) return false;
21
22 try {
23 std::string test_string(c);
24 }
25 catch (...) {
26 return false;
27 }
28
29 return true;
30}
31
32C_INTERFACE GetAllNodesFromGraph(const Graph* graph, vector<Node>** out_vector_ptr, Node** out_data_ptr)
33{
34 if (!graph)
35 return HF_STATUS::INVALID_PTR;
36
37 try {
38
39 std::vector<Node>* nodes = new vector<Node>();
40 auto i = (*graph);
41 *nodes = graph->Nodes();
42
43 *out_data_ptr = nodes->data();
44 *out_vector_ptr = nodes;
45 return OK;
46 }
47 catch (...) { return HF_STATUS::GENERIC_ERROR; }
48 return GENERIC_ERROR;
49}
51 const vector<Node>* node_list,
52 int* out_size
53) {
54 *out_size = node_list->size();
55 return OK;
56}
57
59 const vector<Edge>* edge_list,
60 int* out_size
61){
62 *out_size = edge_list->size();
63 return OK;
64}
65
67 const Graph* g,
68 int parent,
69 int child,
70 const char* cost_type,
71 float* out_float
72) {
73
74 try {
75 *out_float = g->GetCost(parent, child, std::string(cost_type));
76 if (!std::isfinite(*out_float)) *out_float = -1.0f;
77 }
79 {
80 return NO_COST;
81 }
82 catch (std::logic_error)
83 {
84 return NOT_COMPRESSED;
85 }
86 catch (...)
87 {
88 return GENERIC_ERROR;
89 }
90 return OK;
91
92}
93
95 const Graph* graph,
96 int agg,
97 bool directed,
98 const char* cost_type,
99 std::vector<float>** out_vector_ptr,
100 float** out_data_ptr
101) {
102
103 if (!parse_string(cost_type))
104 return NO_COST;
105
106 try {
107 std::string cost_string(cost_type);
108 *out_vector_ptr = new std::vector<float>();
109 **out_vector_ptr = graph->AggregateGraph(static_cast<HF::SpatialStructures::COST_AGGREGATE>(agg), directed, cost_string);
110 *out_data_ptr = (**out_vector_ptr).data();
111 }
112 catch (HF::Exceptions::NoCost) {
113 return NO_COST; // Cost doesn't exist
114 }
115 catch (std::logic_error) {
116 return NOT_COMPRESSED; // Graph isn't compressed
117 }
118 catch (std::exception & e){
119 return GENERIC_ERROR; // Graph likely doesn't exist, but something else is funky.
120 }
121 return OK;
122}
123
125 const float* nodes,
126 int num_nodes,
127 Graph** out_graph
128){
129 //TODO: Add node constructor
130 Graph * g = new Graph();
131 *out_graph = g;
132 return OK;
133}
134
136 Graph* graph,
137 const float* parent,
138 const float* child,
139 float score,
140 const char* cost_type
141){
142 Node parent_node, child_node;
143
144 if (!parse_string(cost_type))
145 return NO_COST;
146
147 std::string cost_name(cost_type);
148 try {
149 parent_node = Node(parent[0], parent[1], parent[2]);
150 child_node = Node(child[0], child[1], child[2]);
151 }
152 catch(std::exception & E){
153 std::cerr << "Invalid parent or child node " << std::endl;
155 }
156
157 try {
158 graph->addEdge(parent_node, child_node, score, cost_name);
159 }
160 catch (std::out_of_range) {
161 return OUT_OF_RANGE;
162 }
163 catch (std::logic_error){
164 return NOT_COMPRESSED;
165 }
166
167 return OK;
168}
169
170C_INTERFACE AddEdgeFromNodeIDs(Graph * graph, int parent_id, int child_id, float score, const char * cost_type) {
171 if (!parse_string(cost_type))
172 return NO_COST;
173
174 try {
175 graph->addEdge(parent_id, child_id, score, std::string(cost_type));
176 }
177 catch (std::out_of_range) {
178 return OUT_OF_RANGE;
179 }
180 catch (std::logic_error) {
181 return NOT_COMPRESSED;
182 }
183
184 return OK;
185}
186
188 Graph* graph,
189 int* out_nnz,
190 int* out_num_rows,
191 int* out_num_cols,
192 float** out_data_ptr,
193 int ** out_inner_indices_ptr,
194 int ** out_outer_indices_ptr,
195 const char * cost_type
196) {
197 try {
198 auto CSR = graph->GetCSRPointers(std::string(cost_type));
199 *out_nnz = CSR.nnz;
200 *out_num_rows = CSR.rows;
201 *out_num_cols = CSR.cols;
202
203 *out_data_ptr = CSR.data;
204 *out_inner_indices_ptr = CSR.inner_indices;
205 *out_outer_indices_ptr = CSR.outer_indices;
206
207 return OK;
208 }
209 catch (NoCost) {
210 return NO_COST;
211 }
212 catch (...) {
213 return GENERIC_ERROR;
214 }
215}
216
219 const float * point,
220 int* out_id
221) {
222
223 Node node(point[0], point[1], point[2]);
224 *out_id = graph->getID(node);
225 return OK;
226}
227
229{
230 graph->Compress();
231 return OK;
232}
233
235{
236 std::string cost_name(cost_type);
237
238 // If trying to delete the default cost type, clear everything
239 if (cost_name.empty())
240 graph->Clear();
241
242 // Otherwise, only clear the cost type that's specified by cost name
243 else {
244 try { graph->ClearCostArrays(cost_name); }
245
246 // Catch it if it throws due to not having a valid cost.
247 catch (NoCost) {
248 return NO_COST;
249 }
250 }
251 return OK;
252
253}
254
255C_INTERFACE DestroyNodes(vector<Node>* nodelist_to_destroy)
256{
257 if (nodelist_to_destroy) delete nodelist_to_destroy;
258 return OK;
259}
260
261C_INTERFACE DestroyEdges(vector<Edge>* edgelist_to_destroy)
262{
263 if (edgelist_to_destroy) delete edgelist_to_destroy;
264 return OK;
265}
266
268{
269 if (graph_to_destroy) delete graph_to_destroy;
270 return OK;
271}
272
274 // Collecting energy expenditure data for all parent nodes.
275
276 // In std::vector<std::vector<EdgeSet>> Graph::CalculateEnergyExpenditure(Graph& g),
277 // std::vector<EdgeSet> Graph::CalculateEnergyExpenditure(Subgraph& sg)
278 // is called for all Subgraph in g.
279
280 // result is a std::vector<std::vector<EdgeSet>>
282
283 // Now passing result, a std::vector<std::vector<EdgeSet>> to Graph::AddEdges.
284 // The result container will be ordered by parent id.
285
287
288 return OK;
289}
291 Graph* g,
292 const int* ids,
293 const char* attribute,
294 const char** scores,
295 int num_nodes
296) {
297
298 // It is easy to convert raw pointers that are known to point to buffers/arrays
299 // to a std::vector.
300
301 // ids is the base address, and ids + num_nodes is one-past the last address allocated for ids.
302 std::vector<int> v_ids(ids, ids + num_nodes);
303
304 // scores is the base address, and scores + num_nodes is one-past the last address allocated for scores.
305 std::vector<std::string> v_scores(scores, scores + num_nodes);
306
307 // If it turns out that v_ids and v_scores have different sizes,
308 // AddNodeAttributes will discover this.
309 try {
310 g->AddNodeAttributes(v_ids, std::string(attribute), v_scores);
311 }
312 catch (std::logic_error) {
313 //return HF_STATUS::OUT_OF_RANGE;
314 assert(false); // This is purely due to programmer error. The top of this function should
315 // ONLY read num_nodes elements from either array, and this exception will
316 // only throw if the length of scores and ids is different
317 }
318
319 return OK;
320}
321
323 char** out_scores, int* out_score_size) {
324
325 // Get the node attributes from tthe graph at attribute
326 vector<string> v_attrs = g->GetNodeAttributes(std::string(attribute));
327
328 // Iterate through each returned string and copy it into
329 // the output array
330 for (int i = 0; i < v_attrs.size(); i++){
331
332 // Get the string and its corresponding c_string
333 const string& v_str = v_attrs[i];
334 const char* cstr = v_str.c_str();
335
336 // Allocate space in the output array for this string
337 const int string_length = v_str.size() + 1; //NOTE: This must be +1 since the null terminator doesn't count
338 // towards the string's overall length
339 out_scores[i] = new char[string_length];
340
341 // Copy the contents of c_str into the output array
342 std::memcpy(out_scores[i], cstr, string_length);
343 }
344
345 // Update the *out_score_size value, which corresponds to v_attrs.size().
346 // (it also corresponds to i, but this notation using v_attrs.size() is easier to understand)
347 * out_score_size = v_attrs.size();
348
349 // If v_attrs.size() == 0, do we want to throw an exception,
350 // which would mean that attribute does not exist as a attribute type?
351 return OK;
352}
353
354C_INTERFACE DeleteScoreArray(char** scores_to_delete, int num_char_arrays) {
355 // If it's null, then just ignore it
356 if (scores_to_delete) {
357
358 // iterate through every char chara array in scores_to_delete.
359 // The heap knows how big these arrays are.
360 for (int i = 0; i < num_char_arrays; i++) {
361 char* score_string = scores_to_delete[i];
362 delete score_string; // Explictly delete the char array at victim
363 }
364 }
365 return OK;
366}
367
369 if (s) {
370 // Does not hurt to check if s is non-null
371 g->ClearNodeAttributes(std::string(s));
372 return OK;
373 }
374 // Inform the caller that they gave us a null pointer
375 else
376 return INVALID_PTR;
377
378}
379
380
382 // Collecting cross slope data for all parent nodes.
383
384 // In std::vector<std::vector<IntEdge>> Graph::CalculateCrossSlope(Graph& g),
385 // std::vector<IntEdge> Graph::CalculateCrossSlope(Subgraph& sg)
386 // is called for all Subgraph in g.
387
388 // result is a std::vector<std::vector<IntEdge>>
390
391 // Now passing result, a std::vector<std::vector<IntEdge>> to Graph::AddEdges.
392 // The result container will be ordered by parent id.
393
394 // TODO: implement void Graph::AddEdges(std::vector<std::vector<IntEdge>>& edges);
396
397 return OK;
398}
399
400C_INTERFACE GetSizeOfGraph(const Graph * g, int * out_size) {
401 *out_size = g->size();
402 return OK;
403}
404
407 const char* attr_key,
408 const char* cost_string,
410{
411 // Call the function in the graph to convert this cost
412 try {
413 graph_ptr->AttrToCost(std::string(attr_key), std::string(cost_string), dir);
414 }
415 catch (std::out_of_range) { // Catch if it throws out of range due to an invalid cost name
416 // return notfound to inform the caller that the node parameter they wanted didn't exist
418 }
419 // If we got past the trycatch without throwing then the postconditionsof attrtocost have been
420 // fulfilled.
421 return HF::Exceptions::OK;
422}
Contains definitions for the Exceptions namespace.
Contains implementation for the HF::SpatialStructures::CostAlgorithms namespace.
Contains definitions for the Edge structure.
Contains definitions for the Graph class.
Contains definitions for the Node structure.
#define C_INTERFACE
Definition: analysis_C.h:16
bool parse_string(const char *c)
Header file related to manipulating nodes, edges, and graphs via CInterface.
std::string AlgorithmCostTitle(COST_ALG_KEY key)
Get the cost algorithm title (as std::string) from the COST_ALG_KEY enum member.
@ CROSS_SLOPE
Cost created by CalculateAndStoreCrossSlope.
@ ENERGY_EXPENDITURE
Cost created by CalculateAndStoreEnergyExpenditure.
C_INTERFACE AddEdgeFromNodeIDs(Graph *graph, int parent_id, int child_id, float score, const char *cost_type)
Create a new edge between parent_id and child_id. If these IDs do not exist in the graph,...
C_INTERFACE AggregateCosts(const Graph *graph, int agg, bool directed, const char *cost_type, std::vector< float > **out_vector_ptr, float **out_data_ptr)
Get an ordered array of costs for each node aggregated by the desired function.
C_INTERFACE GetAllNodesFromGraph(const Graph *graph, vector< Node > **out_vector_ptr, Node **out_data_ptr)
Get a vector of every node in the given graph pointer.
C_INTERFACE CreateGraph(const float *nodes, int num_nodes, Graph **out_graph)
Create a new empty graph.
C_INTERFACE GetNodeID(HF::SpatialStructures::Graph *graph, const float *point, int *out_id)
Get the ID of the given node in the graph. If the node does not exist, out_id will be set to -1.
C_INTERFACE AddEdgeFromNodes(Graph *graph, const float *parent, const float *child, float score, const char *cost_type)
Add an edge between parent and child. If parent or child does not already exist in the graph,...
C_INTERFACE GetCSRPointers(Graph *graph, int *out_nnz, int *out_num_rows, int *out_num_cols, float **out_data_ptr, int **out_inner_indices_ptr, int **out_outer_indices_ptr, const char *cost_type)
Retrieve all information for a graph's CSR representation. This will compress the graph if it was not...
C_INTERFACE GetSizeOfGraph(const Graph *g, int *out_size)
Get the number of nodes in a graph.
C_INTERFACE DestroyGraph(Graph *graph_to_destroy)
Delete a graph.
C_INTERFACE GetSizeOfEdgeVector(const vector< Edge > *edge_list, int *out_size)
Get the size of an edge vector.
C_INTERFACE ClearAttributeType(HF::SpatialStructures::Graph *g, const char *s)
Deletes the node attribute values of the type denoted by s, from graph *g.
C_INTERFACE GraphAttrsToCosts(HF::SpatialStructures::Graph *graph_ptr, const char *attr_key, const char *cost_string, HF::SpatialStructures::Direction dir)
Create a cost in the graph based on a set of node parameters.
C_INTERFACE GetNodeAttributes(const HF::SpatialStructures::Graph *g, const char *attribute, char **out_scores, int *out_score_size)
Retrieve node attribute values from *g.
C_INTERFACE CalculateAndStoreEnergyExpenditure(HF::SpatialStructures::Graph *g)
Calculates energy expenditure for all subgraphs in *g and stores them in the graph at AlgorithmCostTi...
C_INTERFACE DestroyNodes(vector< Node > *nodelist_to_destroy)
Delete the vector of nodes at the given pointer.
C_INTERFACE GetEdgeCost(const Graph *g, int parent, int child, const char *cost_type, float *out_float)
Get the cost of traversing from parent to child
C_INTERFACE Compress(Graph *graph)
Compress the given graph into a CSR representation.
C_INTERFACE GetSizeOfNodeVector(const vector< Node > *node_list, int *out_size)
Get the size of a node vector.
C_INTERFACE DestroyEdges(vector< Edge > *edgelist_to_destroy)
Delete the vector of edges at the given pointer.
C_INTERFACE ClearGraph(HF::SpatialStructures::Graph *graph, const char *cost_type)
Clear the nodes/edges for the given graph, or clear a specific cost type.
C_INTERFACE DeleteScoreArray(char **scores_to_delete, int num_char_arrays)
Free the memory of every (char *) in scores_to_delete.
C_INTERFACE AddNodeAttributes(Graph *g, const int *ids, const char *attribute, const char **scores, int num_nodes)
Add a new node attribute in the graph for the nodes at ids.
C_INTERFACE CalculateAndStoreCrossSlope(HF::SpatialStructures::Graph *g)
Calculates cross slope for all subgraphs in *g.
A Subgraph consists of a parent Node m_parent and a container of Edge m_edges such that all Edge in m...
Definition: graph.h:364
COST_AGGREGATE
Methods of aggregating the costs for edges for each node in the graph.
Definition: graph.h:28
Direction
Node to use for calculating the cost of an edge when converting node attributes to edge costs.
Definition: graph.h:39
Custom exceptions and error codes used interally by DHARTAPI.
Definition: HFExceptions.h:22
@ OK
Operation was successful.
Definition: HFExceptions.h:32
@ NOT_FOUND
The path given did not lead to any file.
Definition: HFExceptions.h:39
@ GENERIC_ERROR
Not sure what happened here (If this gets thrown, either fix it or give it a status code!...
Definition: HFExceptions.h:38
@ NOT_COMPRESSED
Graph wasn't compressed!
Definition: HFExceptions.h:51
@ INVALID_PTR
One or more of the given pointers didn't lead to anything.
Definition: HFExceptions.h:47
@ NO_COST
There is no cost with the given name in the given graph.
Definition: HFExceptions.h:50
@ OUT_OF_RANGE
Tried to reference something not in the given container.
Definition: HFExceptions.h:48
std::vector< IntEdge > CalculateCrossSlope(const Subgraph &sg)
EdgeSet CalculateEnergyExpenditure(const Subgraph &sg)
Thrown when a dependency is missing such as Embree.
Definition: HFExceptions.h:90
A connection to a child node.
Definition: Edge.h:29
int nnz
Number of non-zeros contained by the CSR.
Definition: graph.h:55
A Graph of nodes connected by edges that supports both integers and HF::SpatialStructures::Node.
Definition: graph.h:486
void ClearNodeAttributes(std::string name)
Clears the attribute at name and all of its contents from the internal hashmap
int size() const
Determine how many nodes are in the graph.
float GetCost(int parent_id, int child_id, const std::string &cost_type="") const
get the cost from parent_id to child_id in the given cost_type.
void AddNodeAttributes(const std::vector< int > &id, const std::string &name, const std::vector< std::string > &scores)
Add an attribute to the node at id. If the node at id already has a score for the attribute at name,...
void addEdge(const Node &parent, const Node &child, float score=1.0f, const std::string &cost_type="")
Add a new edge to the graph from parent to child.
void Compress()
Compress the graph to a CSR and enable the usage of several functions.
std::vector< float > AggregateGraph(COST_AGGREGATE agg_type, bool directed=true, const std::string &cost_type="") const
Summarize the costs of every outgoing edge for every node in the graph.
void AddEdges(const EdgeSet &edges, const std::string &cost_name="")
Add multiple edges to the graph.
CSRPtrs GetCSRPointers(const std::string &cost_type="")
Obtain the size of and pointers to the 3 arrays that comprise this graph's CSR. graph if it isn't com...
void ClearCostArrays(const std::string &cost_name="")
Clear one or more cost arrays from the graph.
void Clear()
Clear all nodes and edges from the graph.
std::vector< Node > Nodes() const
Get a list of nodes from the graph sorted by ID.
void AttrToCost(const std::string &node_attribute, const std::string &cost_to_store_as, Direction consider=Direction::INCOMING)
Generate edge costs from a set of node attributes.
std::vector< std::string > GetNodeAttributes(std::string attribute) const
Get the score for the given attribute of every node in the graph. Nodes that do not have a score for ...
int getID(const Node &node) const
Retrieve the ID for node in this graph.
A point in space with an ID.
Definition: node.h:38