I have a list of nodes that each decompose into more nodes. For example
- Node0 = w01 * Node1 + w02 * Node2 + w03 * Node3
- Node1 = w12 * Node2 + w14 * Node4
Therefore, we have Node0 = w01*w12 * Node2 + w03 * Node3 + w01*w14 Node4.
My C++ code for performing the above aggregation/decomposition/merging for a given set of weight decompositions looks as follows. However, I feel there are a lot of optimisations to be made. To name just one, I am looping over the keys of topWeights and collect them in topNodeNames, which seems terribly inefficient.
Are there any STL algorithms that could help me speed this up, and possibly avoid unnecessary copying?
#include <string>
#include <unordered_map>
template<class T, class U> using umap = std::unordered_map<T, U>;
umap<std::string, double> getWeights(const std::string& nodeName, const umap<std::string, umap<std::string, double>>& weightTrees)
{
const auto it = weightTrees.find(nodeName);
if (it == weightTrees.end())
return umap<std::string, double>();
umap<std::string, double> topWeights = it->second;
std::vector<std::string> topNodeNames;
for (const auto& kv : topWeights)
topNodeNames.push_back(kv.first);
for (const std::string& topNodeName : topNodeNames)
{
umap<std::string, double> subWeights = getWeights(topNodeName, weightTrees);
if (subWeights.size() > 0)
{
const double topWeight = topWeights[topNodeName];
topWeights.erase(topNodeName);
for (const auto& subWeight : subWeights)
{
const auto it = topWeights.find(subWeight.first);
if (it == topWeights.end())
topWeights[subWeight.first] = topWeight * subWeight.second;
else
it->second += topWeight * subWeight.second;
}
}
}
return topWeights;
}
int main()
{
umap<std::string, umap<std::string, double>> weightTrees = {{ "Node0", {{ "Node1",0.5 },{ "Node2",0.3 },{ "Node3",0.2 }} },
{ "Node1", {{ "Node2",0.1 },{ "Node4",0.9 }} }};
umap<std::string, double> w = getWeights("Node0", weightTrees); // gives {Node2: 0.35, Node3: 0.20, Node4: 0.45}
}