Lodestar
An integrated real-time control package in C++
StronglyConnectedComponents.hpp
1 //
2 // Created by Hamza El-Kebir on 12/25/21.
3 //
4 
5 #ifndef LODESTAR_STRONGLYCONNECTEDCOMPONENTS_HPP
6 #define LODESTAR_STRONGLYCONNECTEDCOMPONENTS_HPP
7 
8 #include "DirectedGraph.hpp"
9 #include "Lodestar/blocks/BlockPack.hpp"
10 #include <stack>
11 #include <algorithm>
12 
13 namespace ls {
14  namespace blocks {
15  namespace aux {
17  public:
18  struct SCCResult {
19  SCCResult() : components(0, ::std::vector<int>(0))
20  {}
21 
22  SCCResult(const ::std::vector<::std::vector<int>> &v) : components(v.begin(), v.end())
23  {}
24 
25  SCCResult & operator=(SCCResult other)
26  {
27  ::std::swap(components, other.components);
28 
29  return *this;
30  }
31 
32  struct FullConnection {
33  const bool isInput;
34  const BlockProto *src;
35  const int srcSlot;
36  const BlockProto *dst;
37  const int dstSlot;
38  };
39 
40  ::std::vector<::std::vector<int>> components{};
41 
42  // External input connections, output connections
43  ::std::pair<
44  ::std::vector<FullConnection>,
45  ::std::vector<FullConnection>
46  >
47  getExternalIO(const BlockPack &bp,
48  int componentIdx = 0) const;
49 
50  // Internal input connections, output connections
51  ::std::vector<FullConnection>
52  getInternalIO(const BlockPack &bp,
53  int componentIdx = 0) const;
54 
55  bool isSubset(int sup, int sub) const;
56 
57  bool intersects(int idx1, int idx2) const;
58 
59  bool isAlgebraicLoop(const BlockPack &bp, int componentIdx = 0) const;
60 
61  bool containsAlgebraicLoops(const BlockPack &bp) const;
62 
63  ::std::vector<const BlockProto *>
64  extractBlocks(const ::std::vector<FullConnection> &connections) const;
65 
66  ::std::size_t getComponentLength(int componentIdx = 0) const;
67 
68 #ifdef LS_USE_GINAC
69 
70  GiNaC::lst getSymbolicEquationList(const BlockPack &bp, int componentIdx = 0) const;
71 
72  GiNaC::lst getInterconnectionEquationList(const BlockPack &bp, int componentIdx = 0) const;
73 
74  GiNaC::lst getBlockEquationList(const BlockPack &bp, int componentIdx = 0) const;
75 
76  GiNaC::lst getKnownSymbolList(const BlockPack &bp, int componentIdx = 0) const;
77 
78  GiNaC::lst getUnknownSymbolList(const BlockPack &bp, int componentIdx = 0) const;
79 
80  ::std::pair<GiNaC::lst, GiNaC::lst>
81  getAlgebraicEquations(const BlockPack &bp, int componentIdx = 0) const;
82 
83  static GiNaC::matrix
84  getAlgebraicEquationsJacobian(const GiNaC::lst &eqs, const GiNaC::lst &vars);
85 
86  static ::std::pair<GiNaC::matrix, GiNaC::matrix>
87  solveAlgebraicEquationsNewtonRaphson(const GiNaC::lst &eqs, const GiNaC::matrix &jac,
88  const GiNaC::lst &vars);
89 
90  static void expandListToSymbols(const GiNaC::lst &l, GiNaC::lst &g);
91 
92  static void expandListToSymbols(const GiNaC::matrix &l, GiNaC::lst &g);
93 
94  static void substituteExpressions(GiNaC::ex &ex, GiNaC::lst &subs);
95 
96 #endif
97  };
98 
99  static SCCResult
100  findComponents(const DirectedGraph &graph,
101  bool allowSingletons = false);
102 
103  protected:
104  // https://www.tutorialspoint.com/Tarjan-s-Algorithm-for-Strongly-Connected-Components
105  static void
106  findComponentsImpl(const DirectedGraph &graph, int u,
107  ::std::vector<int> &disc,
108  ::std::vector<int> &low,
109  ::std::stack<int> &stack,
110  ::std::vector<bool> &stackItem,
111  ::std::vector<::std::vector<int>> &components,
112  int &time,
113  bool allowSingletons);
114  };
115  }
116  }
117 }
118 
119 
120 #endif //LODESTAR_STRONGLYCONNECTEDCOMPONENTS_HPP
ls::blocks::aux::DirectedGraph
Definition: DirectedGraph.hpp:17
ls::blocks::aux::StronglyConnectedComponents
Definition: StronglyConnectedComponents.hpp:16
ls
Main Lodestar code.
Definition: BilinearTransformation.hpp:12
ls::blocks::aux::StronglyConnectedComponents::SCCResult::FullConnection
Definition: StronglyConnectedComponents.hpp:32
ls::blocks::BlockPack
Definition: BlockPack.hpp:17
ls::blocks::aux::StronglyConnectedComponents::SCCResult
Definition: StronglyConnectedComponents.hpp:18
ls::blocks::BlockProto
Definition: BlockProto.hpp:20