1 package org.catacomb.numeric.difnet.calc;
2
3 import org.catacomb.numeric.difnet.*;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 public final class OrderedNetMap {
26
27 NetMapNode[] node;
28 NetMapLink[] link;
29
30 boolean acyclic;
31 private boolean useIntrinsics;
32
33
34 OrderedNetMap(NetStructure dn) {
35 acyclic = true;
36
37 StructureNode[] difnetNode = dn.getNodes();
38 StructureLink[] difnetLink = dn.getLinks();
39
40
41 int nnode = difnetNode.length;
42 int nlink = difnetLink.length;
43 for (int i = 0; i < nnode; i++) {
44 difnetNode[i].setWork(i);
45 }
46
47
48
49 NetMapNode[] wkNode = new NetMapNode[nnode];
50 NetMapLink[] wkLink = new NetMapLink[nlink];
51
52 for (int i = 0; i < nnode; i++) {
53 wkNode[i] = new NetMapNode();
54 wkNode[i].peerIndex = i;
55 wkNode[i].fixed = difnetNode[i].hasFixedValue(null);
56 }
57
58 for (int i = 0; i < nlink; i++) {
59 wkLink[i] = new NetMapLink();
60 wkLink[i].peerIndex = i;
61
62 int iwka = difnetLink[i].getNodeA().getWork();
63 wkLink[i].nodeA = wkNode[iwka];
64
65 int iwkb = difnetLink[i].getNodeB().getWork();
66 wkLink[i].nodeB = wkNode[iwkb];
67 }
68
69
70
71
72
73
74
75
76 NetMapLink[][] linksPerNode = new NetMapLink[nnode][6];
77
78 linksPerNode[0] = new NetMapLink[nnode];
79
80
81
82 int[] nlinksPerNode = new int[nnode];
83
84 for (int i = 0; i < nlink; i++) {
85 if (wkLink[i].nodeA.fixed) {
86
87 } else {
88 int ia = wkLink[i].nodeA.peerIndex;
89 linksPerNode[ia][nlinksPerNode[ia]++] = wkLink[i];
90 }
91
92 if (wkLink[i].nodeB.fixed) {
93
94 } else {
95 int ib = wkLink[i].nodeB.peerIndex;
96 linksPerNode[ib][nlinksPerNode[ib]++] = wkLink[i];
97 }
98 }
99
100
101
102
103
104 node = new NetMapNode[nnode];
105 for (int i = 0; i < nnode; i++) {
106 wkNode[i].mark = false;
107 }
108 for (int i = 0; i < nlink; i++) {
109 wkLink[i].mark = false;
110 wkLink[i].flip = false;
111 }
112
113 int[] iin = { 0 };
114 for (int i = 0; i < nnode; i++) {
115 if (wkNode[i].fixed && !wkNode[i].mark) {
116 node[iin[0]++] = wkNode[i];
117 wkNode[i].mark = true;
118 }
119 }
120
121
122
123 int ntree = 0;
124 for (int i = 0; i < nnode; i++) {
125 if (!wkNode[i].mark) {
126 ntree++;
127 recindex(node, iin, linksPerNode, wkNode[i]);
128 }
129 }
130
131
132
133
134
135 for (int i = 0; i < nnode; i++) {
136 node[i].upLink = tidyLinkArray(node[i].upLink);
137 node[i].downLink = tidyLinkArray(node[i].downLink);
138 }
139
140
141
142 for (int i = 0; i < nnode; i++) {
143 node[i].index = i;
144 }
145
146
147
148
149 link = wkLink;
150 }
151
152
153 public boolean getUseIntrinsics() {
154 return useIntrinsics;
155 }
156
157
158 public void Sp(String s) {
159 System.out.println(s);
160 }
161
162
163 public void print() {
164 Sp("ordered net map with " + node.length + " nodes, structure indexes in brackets ");
165 for (int i = 0; i < node.length; i++) {
166 NetMapNode nmn = node[i];
167 Sp("node " + i + "(" + nmn.peerIndex + "), ndownlinks=" + nmn.downLink.length
168 + ", nuplink=" + nmn.upLink.length);
169 if (nmn.isFree()) {
170
171 } else {
172 Sp("fixed at " + nmn.value);
173 }
174 for (int j = 0; j < nmn.downLink.length; j++) {
175 printLink("down ", nmn.downLink[j], j);
176 }
177 for (int j = 0; j < nmn.upLink.length; j++) {
178 printLink(" up ", nmn.upLink[j], j);
179 }
180 }
181 }
182
183
184 public void printLink(String dir, NetMapLink lk, int lki) {
185 Sp(dir + lki + "(" + lk.peerIndex + "), nodeA=" + lk.nodeA.index + "(" + lk.nodeA.peerIndex
186 + "), nodeB=" + lk.nodeB.index + "(" + lk.nodeB.peerIndex + "), g=" + lk.conductance
187 + ", c=" + lk.capacitance);
188 }
189
190
191 NetMapNode[] getNodes() {
192 return node;
193 }
194
195
196 NetMapLink[] tidyLinkArray(NetMapLink[] cain) {
197 NetMapLink[] ca = cain;
198 if (ca == null)
199 return new NetMapLink[0];
200 int n = 0;
201 while (n < ca.length && ca[n] != null)
202 n++;
203 if (n < ca.length) {
204 NetMapLink[] cb = ca;
205 ca = new NetMapLink[n];
206 for (int i = 0; i < n; i++)
207 ca[i] = cb[i];
208 }
209 return ca;
210 }
211
212
213 private NetMapLink[] addLink(NetMapLink[] cain, NetMapLink c) {
214 NetMapLink[] ca = cain;
215 int n = 0;
216 if (ca == null)
217 ca = new NetMapLink[3];
218 while (n < ca.length && ca[n] != null)
219 n++;
220 if (n == ca.length)
221 ca = extendNetMapLinkArray(ca);
222 ca[n] = c;
223 return ca;
224 }
225
226
227 private NetMapLink[] extendNetMapLinkArray(NetMapLink[] ca) {
228 int n = ca.length;
229 NetMapLink[] cb = new NetMapLink[2 * n];
230 for (int i = 0; i < n; i++)
231 cb[i] = ca[i];
232 return cb;
233 }
234
235
236 private void recindex(NetMapNode[] nodeArray, int[] inxt, NetMapLink[][] linksPerNode,
237 NetMapNode currentNode) {
238 currentNode.mark = true;
239 nodeArray[inxt[0]++] = currentNode;
240 NetMapLink[] nbrs = linksPerNode[currentNode.peerIndex];
241
242
243 for (int i = 0; i < nbrs.length && nbrs[i] != null; i++) {
244 NetMapLink h = nbrs[i];
245 if (!h.mark) {
246 if (h.nodeB.fixed || h.nodeA.fixed) {
247 if (h.nodeB.fixed)
248 h.reverseEnds();
249
250 h.nodeA.upLink = addLink(h.nodeA.upLink, h);
251 h.nodeB.downLink = addLink(h.nodeB.downLink, h);
252 h.mark = true;
253 }
254 }
255 }
256
257
258 for (int i = 0; i < nbrs.length && nbrs[i] != null; i++) {
259 NetMapLink h = nbrs[i];
260 if (!h.mark) {
261 h.mark = true;
262 if (h.nodeA != currentNode)
263 h.reverseEnds();
264 h.nodeA.upLink = addLink(h.nodeA.upLink, h);
265 h.nodeB.downLink = addLink(h.nodeB.downLink, h);
266 if (h.nodeB.mark) {
267 System.out.println("WARNING found link which breaks acyclic prop?" + " from peers "
268 + h.nodeA.peerIndex + " to " + h.nodeB.peerIndex);
269 acyclic = false;
270 } else {
271 recindex(nodeArray, inxt, linksPerNode, h.nodeB);
272 }
273 }
274 }
275 }
276
277
278 boolean isAcyclic() {
279 return acyclic;
280 }
281
282
283 void readState(NetState dn) {
284 useIntrinsics = dn.useIntrinsics();
285
286 StateNode[] difnetNode = dn.getNodes();
287 for (int i = 0; i < node.length; i++) {
288 node[i].readState(difnetNode[node[i].peerIndex], dn.getTime());
289 }
290 StateLink[] difnetLink = dn.getLinks();
291 for (int i = 0; i < link.length; i++) {
292 link[i].readState(difnetLink[link[i].peerIndex]);
293 }
294 }
295
296
297 void writeState(NetState difnet) {
298 StateNode[] difnetNode = difnet.getNodes();
299 for (int i = 0; i < node.length; i++) {
300 node[i].writeState(difnetNode[node[i].peerIndex]);
301 }
302 }
303 }