From 8e21dffd1354a36658f87b51116c399f267052c0 Mon Sep 17 00:00:00 2001 From: carlos_felix Date: Sun, 22 Oct 2023 22:22:52 +0100 Subject: [PATCH] network dynamics matrices --- include/CXXGraph/Graph/Graph.hpp | 127 ++++++++++++++++++++++++++- include/CXXGraph/Utility/Typedef.hpp | 18 ++++ 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/include/CXXGraph/Graph/Graph.hpp b/include/CXXGraph/Graph/Graph.hpp index 166766bc3..2312fa5ae 100644 --- a/include/CXXGraph/Graph/Graph.hpp +++ b/include/CXXGraph/Graph/Graph.hpp @@ -106,7 +106,9 @@ class Graph { T_NodeSet isolatedNodesSet = {}; shared> cachedAdjMatrix; - + shared> cachedDegreeMatrix; + shared> cachedLaplacianMatrix; + shared> cachedTransitionMatrix; // Private non-const getter for the set of nodes std::unordered_set>, nodeHash> nodeSet(); @@ -304,6 +306,33 @@ class Graph { virtual shared> getAdjMatrix() const; virtual void cacheAdjMatrix(); + /** + * @brief This function generates a list of the degree matrix with every element + * of the matrix containing the node where the link is directed and the + * corresponding edge to the link. + * Note: No Thread Safe + */ + virtual shared> getDegreeMatrix() const; + + virtual void cacheDegreeMatrix(); + /** + * @brief This function generates a list of the Laplacian matrix with every element + * of the matrix containing the node connected to the current node and the + * corresponding edge to the link. + * Note: No Thread Safe + */ + virtual shared> getLaplacianMatrix() const; + + virtual void cacheLaplacianMatrix(); + /** + * @brief This function generates a list of the transition matrix with every element + * of the matrix containing the node that can be transitioned to from the + * current node and the probability of the transition. + * Note: No Thread Safe + */ + virtual shared> getTransitionMatrix() const; + + virtual void cacheTransitionMatrix(); /** * \brief This function generates a set of nodes linked to the provided node * in a directed graph @@ -831,6 +860,9 @@ template Graph::Graph() { /* Caching the adjacency matrix */ cacheAdjMatrix(); + cacheDegreeMatrix(); + cacheLaplacianMatrix(); + cacheTransitionMatrix(); } template @@ -840,6 +872,9 @@ Graph::Graph(const T_EdgeSet &edgeSet) { } /* Caching the adjacency matrix */ cacheAdjMatrix(); + cacheDegreeMatrix(); + cacheLaplacianMatrix(); + cacheTransitionMatrix(); } template @@ -855,6 +890,8 @@ void Graph::setEdgeSet(const T_EdgeSet &edgeSet) { } /* Caching the adjacency matrix */ cacheAdjMatrix(); + cacheDegreeMatrix(); + cacheLaplacianMatrix(); } template @@ -1666,6 +1703,94 @@ void Graph::cacheAdjMatrix() { this->cachedAdjMatrix = adj; } +template +shared> Graph::getDegreeMatrix() const { + auto degreeMatrix = std::make_shared>(); + + for (const auto& nodePair : *this->cachedAdjMatrix) { + const shared>& node = nodePair.first; + const std::vector>, shared>>>& neighbors = nodePair.second; + + int degree = neighbors.size(); + + (*degreeMatrix)[node] = {degree}; + } + + return degreeMatrix; +} + +template +void Graph::cacheDegreeMatrix() { + const auto degreeMatrix = Graph::getDegreeMatrix(); + this->cachedDegreeMatrix = degreeMatrix; +} + +template +shared> Graph::getLaplacianMatrix() const { + const auto adjacencyMatrix = this->cachedAdjMatrix; + const auto degreeMatrix = this->cachedDegreeMatrix; + + auto laplacianMatrix = std::make_shared>(); + for (const auto& nodePair : *adjacencyMatrix) { + const shared>& node = nodePair.first; + (*laplacianMatrix)[node] = std::vector>, shared>>>(); + } + + for (const auto& nodePair : *adjacencyMatrix) { + const shared>& node = nodePair.first; + const std::vector>, shared>>>& neighbors = nodePair.second; + + int degree = neighbors.size(); + + (*laplacianMatrix)[node].emplace_back(node, nullptr); // Insere o nĂ³ na diagonal + for (const auto& neighborPair : neighbors) { + const shared>& neighbor = neighborPair.first; + (*laplacianMatrix)[node].emplace_back(neighbor, neighborPair.second); // Insere os pares de vizinhos + } + } + + return laplacianMatrix; +} + +template +void Graph::cacheLaplacianMatrix() { + const auto laplacianMatrix = Graph::getLaplacianMatrix(); + this->cachedLaplacianMatrix = laplacianMatrix; +} + +template +shared> Graph::getTransitionMatrix() const { + const auto adjacencyMatrix = this->cachedAdjMatrix; + + auto transitionMatrix = std::make_shared>(); + for (const auto& nodePair : *adjacencyMatrix) { + const shared>& node = nodePair.first; + (*transitionMatrix)[node] = std::vector>, double>>(); + } + + for (const auto& nodePair : *adjacencyMatrix) { + const shared>& node = nodePair.first; + const std::vector>, shared>>>& neighbors = nodePair.second; + + int degree = neighbors.size(); + + double transitionProbability = 1.0 / degree; + + for (const auto& neighborPair : neighbors) { + const shared>& neighbor = neighborPair.first; + (*transitionMatrix)[node].emplace_back(neighbor, transitionProbability); + } + } + + return transitionMatrix; +} + +template +void Graph::cacheTransitionMatrix() { + const auto transitionMatrix = Graph::getTransitionMatrix(); + this->cachedTransitionMatrix = transitionMatrix; +} + template const std::unordered_set>, nodeHash> Graph::outNeighbors(const Node *node) const { diff --git a/include/CXXGraph/Utility/Typedef.hpp b/include/CXXGraph/Utility/Typedef.hpp index 108101e40..7915a4457 100755 --- a/include/CXXGraph/Utility/Typedef.hpp +++ b/include/CXXGraph/Utility/Typedef.hpp @@ -254,6 +254,24 @@ using AdjacencyMatrix = std::unordered_map< std::vector>, shared>>>, nodeHash>; +template +using DegreeMatrix = std::unordered_map< + shared>, + std::vector, + nodeHash>; + +template +using LaplacianMatrix = std::unordered_map< + shared>, + std::vector>, shared>>>, + nodeHash>; + +template +using TransitionMatrix = std::unordered_map< + shared>, + std::vector>, double>>, + nodeHash>; + template using PartitionMap = std::unordered_map