tree.linalg
1from __future__ import annotations 2from varname.core import varname 3from tree.network import Network 4from numpy import zeros as linalg_zeros 5from numpy import transpose as linalg_transpose 6 7class MatrixTree(Network): 8 """ 9 Represent the MatrixTree as a Matrix 10 11 Examples 12 -------- 13 14 Consider a complicated tree: 15 >>> A = MatrixTree() 16 >>> B = MatrixTree() 17 >>> tree = MatrixTree(A, B) 18 >>> tree.add(μ=0) 19 >>> A.hop(B, t=1) 20 21 The matrix representation of the tree is given by 22 >>> tree.matrix 23 array([[0., 1.], 24 [0., 0.]]) 25 """ 26 27 def __init__(self, *child: MatrixTree) -> None: 28 """ 29 A subclass of MatrixTree. 30 """ 31 super().__init__(*child) 32 33 try: 34 self.__dict__["__name__"] = varname() 35 except: 36 self.__dict__["__name__"] 37 38 @property 39 def matrix(self): 40 """ 41 Construct the matrix representation of the tree 42 43 >>> A = MatrixTree() 44 >>> B = MatrixTree() 45 >>> matrix = MatrixTree(A, B) 46 >>> matrix.add(μ=0.6) 47 >>> A.hop(B, t=1) 48 >>> matrix.matrix 49 array([[0.6, 1. ], 50 [0. , 0.6]]) 51 52 >>> A.t = 3 53 >>> matrix.matrix 54 array([[0.6, 3. ], 55 [0. , 0.6]]) 56 57 >>> A.t *= 3 58 >>> matrix.matrix 59 array([[0.6, 9. ], 60 [0. , 0.6]]) 61 """ 62 if not hasattr(self, "_matrix"): 63 self.__set_indices__() 64 self.__dict__["_matrix"] = linalg_zeros([self.n_leaves, self.n_leaves]) 65 66 diagonals, offdiagonals = self._diagonal, self._offdiagonal 67 68 for key, items in diagonals.items(): 69 for node, item in items.items(): 70 value = item["value"] 71 try: 72 previous_value = self._diagonal[key][node]["previous_value"] 73 value -= previous_value 74 except: 75 pass 76 77 if not value == 0: 78 indices = node.indices 79 slice = (indices, indices) 80 self._matrix[*slice] += value 81 self._diagonal[key][node]["previous_value"] = item["value"] 82 83 for key, items in offdiagonals.items(): 84 for node, neighbours in items.items(): 85 for neighbour, item in neighbours.items(): 86 value = item["value"] 87 try: 88 previous_value = self._offdiagonal[key][node][neighbour]["previous_value"] 89 value -= previous_value 90 except: 91 pass 92 93 if not value == 0: 94 slice = (node.indices, neighbour.indices) 95 self._matrix[*slice] += value 96 self._offdiagonal[key][node][neighbour]["previous_value"] = item["value"] 97 98 return self._matrix
8class MatrixTree(Network): 9 """ 10 Represent the MatrixTree as a Matrix 11 12 Examples 13 -------- 14 15 Consider a complicated tree: 16 >>> A = MatrixTree() 17 >>> B = MatrixTree() 18 >>> tree = MatrixTree(A, B) 19 >>> tree.add(μ=0) 20 >>> A.hop(B, t=1) 21 22 The matrix representation of the tree is given by 23 >>> tree.matrix 24 array([[0., 1.], 25 [0., 0.]]) 26 """ 27 28 def __init__(self, *child: MatrixTree) -> None: 29 """ 30 A subclass of MatrixTree. 31 """ 32 super().__init__(*child) 33 34 try: 35 self.__dict__["__name__"] = varname() 36 except: 37 self.__dict__["__name__"] 38 39 @property 40 def matrix(self): 41 """ 42 Construct the matrix representation of the tree 43 44 >>> A = MatrixTree() 45 >>> B = MatrixTree() 46 >>> matrix = MatrixTree(A, B) 47 >>> matrix.add(μ=0.6) 48 >>> A.hop(B, t=1) 49 >>> matrix.matrix 50 array([[0.6, 1. ], 51 [0. , 0.6]]) 52 53 >>> A.t = 3 54 >>> matrix.matrix 55 array([[0.6, 3. ], 56 [0. , 0.6]]) 57 58 >>> A.t *= 3 59 >>> matrix.matrix 60 array([[0.6, 9. ], 61 [0. , 0.6]]) 62 """ 63 if not hasattr(self, "_matrix"): 64 self.__set_indices__() 65 self.__dict__["_matrix"] = linalg_zeros([self.n_leaves, self.n_leaves]) 66 67 diagonals, offdiagonals = self._diagonal, self._offdiagonal 68 69 for key, items in diagonals.items(): 70 for node, item in items.items(): 71 value = item["value"] 72 try: 73 previous_value = self._diagonal[key][node]["previous_value"] 74 value -= previous_value 75 except: 76 pass 77 78 if not value == 0: 79 indices = node.indices 80 slice = (indices, indices) 81 self._matrix[*slice] += value 82 self._diagonal[key][node]["previous_value"] = item["value"] 83 84 for key, items in offdiagonals.items(): 85 for node, neighbours in items.items(): 86 for neighbour, item in neighbours.items(): 87 value = item["value"] 88 try: 89 previous_value = self._offdiagonal[key][node][neighbour]["previous_value"] 90 value -= previous_value 91 except: 92 pass 93 94 if not value == 0: 95 slice = (node.indices, neighbour.indices) 96 self._matrix[*slice] += value 97 self._offdiagonal[key][node][neighbour]["previous_value"] = item["value"] 98 99 return self._matrix
Represent the MatrixTree as a Matrix
Examples
Consider a complicated tree:
>>> A = MatrixTree()
>>> B = MatrixTree()
>>> tree = MatrixTree(A, B)
>>> tree.add(μ=0)
>>> A.hop(B, t=1)
The matrix representation of the tree is given by
>>> tree.matrix
array([[0., 1.],
[0., 0.]])
MatrixTree(*child: MatrixTree)
28 def __init__(self, *child: MatrixTree) -> None: 29 """ 30 A subclass of MatrixTree. 31 """ 32 super().__init__(*child) 33 34 try: 35 self.__dict__["__name__"] = varname() 36 except: 37 self.__dict__["__name__"]
A subclass of MatrixTree.
matrix
39 @property 40 def matrix(self): 41 """ 42 Construct the matrix representation of the tree 43 44 >>> A = MatrixTree() 45 >>> B = MatrixTree() 46 >>> matrix = MatrixTree(A, B) 47 >>> matrix.add(μ=0.6) 48 >>> A.hop(B, t=1) 49 >>> matrix.matrix 50 array([[0.6, 1. ], 51 [0. , 0.6]]) 52 53 >>> A.t = 3 54 >>> matrix.matrix 55 array([[0.6, 3. ], 56 [0. , 0.6]]) 57 58 >>> A.t *= 3 59 >>> matrix.matrix 60 array([[0.6, 9. ], 61 [0. , 0.6]]) 62 """ 63 if not hasattr(self, "_matrix"): 64 self.__set_indices__() 65 self.__dict__["_matrix"] = linalg_zeros([self.n_leaves, self.n_leaves]) 66 67 diagonals, offdiagonals = self._diagonal, self._offdiagonal 68 69 for key, items in diagonals.items(): 70 for node, item in items.items(): 71 value = item["value"] 72 try: 73 previous_value = self._diagonal[key][node]["previous_value"] 74 value -= previous_value 75 except: 76 pass 77 78 if not value == 0: 79 indices = node.indices 80 slice = (indices, indices) 81 self._matrix[*slice] += value 82 self._diagonal[key][node]["previous_value"] = item["value"] 83 84 for key, items in offdiagonals.items(): 85 for node, neighbours in items.items(): 86 for neighbour, item in neighbours.items(): 87 value = item["value"] 88 try: 89 previous_value = self._offdiagonal[key][node][neighbour]["previous_value"] 90 value -= previous_value 91 except: 92 pass 93 94 if not value == 0: 95 slice = (node.indices, neighbour.indices) 96 self._matrix[*slice] += value 97 self._offdiagonal[key][node][neighbour]["previous_value"] = item["value"] 98 99 return self._matrix
Construct the matrix representation of the tree
>>> A = MatrixTree()
>>> B = MatrixTree()
>>> matrix = MatrixTree(A, B)
>>> matrix.add(μ=0.6)
>>> A.hop(B, t=1)
>>> matrix.matrix
array([[0.6, 1. ],
[0. , 0.6]])
>>> A.t = 3
>>> matrix.matrix
array([[0.6, 3. ],
[0. , 0.6]])
>>> A.t *= 3
>>> matrix.matrix
array([[0.6, 9. ],
[0. , 0.6]])