Skip to content

circuit_utils

Circuit(graph)

Bases: object

Class to simulate a circuit with trainable conductances

Parameters:

  • graph (str or Graph) –

    If str, it is the path to the file containing the graph. If networkx.Graph, it is the graph itself.

Attributes:

  • graph (Graph) –

    Graph specifying the nodes and edges in the network. A conductance parameter is associated with each edge. A trainable edge will be updated during training.

  • n (int) –

    Number of nodes in the graph.

  • ne (int) –

    Number of edges in the graph.

  • pts (ndarray) –

    Positions of the nodes in the graph.

Source code in src/pyrkm/circuit_utils.py
32
33
34
35
36
37
38
39
40
41
42
def __init__(self, graph):
    if isinstance(graph, str):
        self.graph = nx.read_gpickle(graph)
    else:
        self.graph = graph

    self.n = len(self.graph.nodes)
    self.ne = len(self.graph.edges)
    self.pts = np.array(
        [self.graph.nodes[node]['pos'] for node in graph.nodes])
    self.incidence_matrix = nx.incidence_matrix(self.graph, oriented=True)

constraint_matrix(indices_nodes)

Compute the constraint matrix Q for the circuit and the nodes represented by indices_nodes.

Parameters:

  • indices_nodes (ndarray) –

    Array with the indices of the nodes to be constrained. The nodes themselves are given by np.array(self.graph.nodes)[indices_nodes].

Returns:

  • csr_matrix –

    Constraint matrix Q: a sparse constraint rectangular matrix of size n x len(indices_nodes). Its entries are only 1 or 0. Q.Q^T is a projector onto to the space of the nodes.

Source code in src/pyrkm/circuit_utils.py
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def constraint_matrix(self, indices_nodes):
    ''' Compute the constraint matrix Q for the circuit and the nodes represented by indices_nodes.

    Parameters
    ----------
    indices_nodes : numpy.ndarray
        Array with the indices of the nodes to be constrained.
        The nodes themselves are given by
        np.array(self.graph.nodes)[indices_nodes].

    Returns
    -------
    scipy.sparse.csr_matrix
        Constraint matrix Q: a sparse constraint rectangular
        matrix of size n x len(indices_nodes).
        Its entries are only 1 or 0.
        Q.Q^T is a projector onto to the space of the nodes.
    '''
    if len(indices_nodes) == 0:
        raise ValueError('indicesNodes must be a non-empty array.')
    Q = csr_matrix((np.ones(len(indices_nodes)),
                    (indices_nodes, np.arange(len(indices_nodes)))),
                   shape=(self.n, len(indices_nodes)))
    return Q

plot_edge_state(edge_state, title=None, lw=0.5, cmap='RdYlBu_r')

Plot the state of the edges in the graph.

Parameters:

  • edge_state (ndarray) –

    State of the edges in the graph. edge_state has size ne.

  • title (str, default: None ) –

    Title of the plot.

  • lw (float, default: 0.5 ) –

    Line width of the edges.

  • cmap (str, default: 'RdYlBu_r' ) –

    Colormap to use for the plot.

Source code in src/pyrkm/circuit_utils.py
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
def plot_edge_state(self, edge_state, title=None, lw=0.5, cmap='RdYlBu_r'):
    ''' Plot the state of the edges in the graph.

    Parameters
    ----------
    edge_state : numpy.ndarray
        State of the edges in the graph. edge_state has size ne.
    title : str, optional
        Title of the plot.
    lw : float, optional
        Line width of the edges.
    cmap : str, optional
        Colormap to use for the plot.
    '''
    _cmap = plt.cm.get_cmap(cmap)
    pos_edges = np.array([
        np.array([
            self.graph.nodes[edge[0]]['pos'],
            self.graph.nodes[edge[1]]['pos']
        ]).T for edge in self.graph.edges()
    ])
    norm = plt.Normalize(vmin=np.min(edge_state), vmax=np.max(edge_state))
    fig, axs = plt.subplots(1, 1, figsize=(4, 4))
    for i in range(len(pos_edges)):
        axs.plot(pos_edges[i, 0],
                 pos_edges[i, 1],
                 color=_cmap(norm(edge_state[i])))
    axs.set_xticks([])
    axs.set_yticks([])
    fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap),
                 ax=axs,
                 shrink=0.5)
    axs.set_title(title)

plot_node_state(node_state, title=None, lw=0.5, cmap='RdYlBu_r', size_factor=100)

Plot the state of the nodes in the graph.

Parameters:

  • node_state (ndarray) –

    State of the nodes in the graph. node_state has size n.

  • title (str, default: None ) –

    Title of the plot.

  • lw (float, default: 0.5 ) –

    Line width of the edges.

  • cmap (str, default: 'RdYlBu_r' ) –

    Colormap to use for the plot.

  • size_factor (float, default: 100 ) –

    Factor to scale the size of the nodes.

Source code in src/pyrkm/circuit_utils.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def plot_node_state(self,
                    node_state,
                    title=None,
                    lw=0.5,
                    cmap='RdYlBu_r',
                    size_factor=100):
    ''' Plot the state of the nodes in the graph.

    Parameters
    ----------
    node_state : numpy.ndarray
        State of the nodes in the graph. node_state has size n.
    title : str, optional
        Title of the plot.
    lw : float, optional
        Line width of the edges.
    cmap : str, optional
        Colormap to use for the plot.
    size_factor : float, optional
        Factor to scale the size of the nodes.
    '''
    posX = self.pts[:, 0]
    posY = self.pts[:, 1]
    norm = plt.Normalize(vmin=np.min(node_state), vmax=np.max(node_state))
    fig, axs = plt.subplots(1,
                            1,
                            figsize=(4, 4),
                            constrained_layout=True,
                            sharey=True)
    axs.scatter(posX,
                posY,
                s=size_factor * np.abs(node_state[:]),
                c=node_state[:],
                edgecolors='black',
                linewidth=lw,
                cmap=cmap,
                norm=norm)
    axs.set(aspect='equal')
    axs.set_xticks([])
    axs.set_yticks([])
    fig.colorbar(plt.cm.ScalarMappable(norm=norm, cmap=cmap),
                 ax=axs,
                 shrink=0.5)
    axs.set_title(title)

setConductances(conductances)

Set the conductances of the edges in the graph.

Parameters:

  • conductances (list of float or numpy.ndarray) –

    Conductances of the edges. Must have the same length as the number of edges.

Source code in src/pyrkm/circuit_utils.py
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def setConductances(self, conductances):
    ''' Set the conductances of the edges in the graph.

    Parameters
    ----------
    conductances : list of float or numpy.ndarray
        Conductances of the edges. Must have the same length as the number of edges.
    '''
    assert len(
        conductances
    ) == self.ne, 'conductances must have the same length as the number of edges'
    if isinstance(conductances, list):
        conductances = np.array(conductances)
    self.conductances = conductances

solve(Q, f)

Solve the circuit with the constraint matrix Q and the source vector f.

Parameters:

  • Q (csr_matrix) –

    Constraint matrix Q

  • f (ndarray) –

    Source vector f. f has size len(indices_nodes).

Returns:

  • ndarray –

    Solution vector V. V has size n.

Source code in src/pyrkm/circuit_utils.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def solve(self, Q, f):
    ''' Solve the circuit with the constraint matrix Q and the source vector f.

    Parameters
    ----------
    Q : scipy.sparse.csr_matrix
        Constraint matrix Q
    f : numpy.ndarray
        Source vector f. f has size len(indices_nodes).

    Returns
    -------
    numpy.ndarray
        Solution vector V. V has size n.
    '''
    try:
        self.conductances
    except AttributeError:
        raise AttributeError('Conductances have not been set yet.')
    if len(f) != Q.shape[1]:
        raise ValueError('Source vector f has the wrong size.')
    H = self._extended_hessian(Q)
    f_extended = np.hstack([np.zeros(self.n), f])
    V = spsolve(H, f_extended)[:self.n]
    return V