Edit Source

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
class MatrixTree(tree.network.Network):
 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]])