UNPKG

3.56 kBJavaScriptView Raw
1import { factory } from '../../utils/factory.js';
2var name = 'Spa';
3var dependencies = ['addScalar', 'equalScalar', 'FibonacciHeap'];
4export var createSpaClass = /* #__PURE__ */factory(name, dependencies, _ref => {
5 var {
6 addScalar,
7 equalScalar,
8 FibonacciHeap
9 } = _ref;
10
11 /**
12 * An ordered Sparse Accumulator is a representation for a sparse vector that includes a dense array
13 * of the vector elements and an ordered list of non-zero elements.
14 */
15 function Spa() {
16 if (!(this instanceof Spa)) {
17 throw new SyntaxError('Constructor must be called with the new operator');
18 } // allocate vector, TODO use typed arrays
19
20
21 this._values = [];
22 this._heap = new FibonacciHeap();
23 }
24 /**
25 * Attach type information
26 */
27
28
29 Spa.prototype.type = 'Spa';
30 Spa.prototype.isSpa = true;
31 /**
32 * Set the value for index i.
33 *
34 * @param {number} i The index
35 * @param {number | BigNumber | Complex} The value at index i
36 */
37
38 Spa.prototype.set = function (i, v) {
39 // check we have a value @ i
40 if (!this._values[i]) {
41 // insert in heap
42 var node = this._heap.insert(i, v); // set the value @ i
43
44
45 this._values[i] = node;
46 } else {
47 // update the value @ i
48 this._values[i].value = v;
49 }
50 };
51
52 Spa.prototype.get = function (i) {
53 var node = this._values[i];
54
55 if (node) {
56 return node.value;
57 }
58
59 return 0;
60 };
61
62 Spa.prototype.accumulate = function (i, v) {
63 // node @ i
64 var node = this._values[i];
65
66 if (!node) {
67 // insert in heap
68 node = this._heap.insert(i, v); // initialize value
69
70 this._values[i] = node;
71 } else {
72 // accumulate value
73 node.value = addScalar(node.value, v);
74 }
75 };
76
77 Spa.prototype.forEach = function (from, to, callback) {
78 // references
79 var heap = this._heap;
80 var values = this._values; // nodes
81
82 var nodes = []; // node with minimum key, save it
83
84 var node = heap.extractMinimum();
85
86 if (node) {
87 nodes.push(node);
88 } // extract nodes from heap (ordered)
89
90
91 while (node && node.key <= to) {
92 // check it is in range
93 if (node.key >= from) {
94 // check value is not zero
95 if (!equalScalar(node.value, 0)) {
96 // invoke callback
97 callback(node.key, node.value, this);
98 }
99 } // extract next node, save it
100
101
102 node = heap.extractMinimum();
103
104 if (node) {
105 nodes.push(node);
106 }
107 } // reinsert all nodes in heap
108
109
110 for (var i = 0; i < nodes.length; i++) {
111 // current node
112 var n = nodes[i]; // insert node in heap
113
114 node = heap.insert(n.key, n.value); // update values
115
116 values[node.key] = node;
117 }
118 };
119
120 Spa.prototype.swap = function (i, j) {
121 // node @ i and j
122 var nodei = this._values[i];
123 var nodej = this._values[j]; // check we need to insert indeces
124
125 if (!nodei && nodej) {
126 // insert in heap
127 nodei = this._heap.insert(i, nodej.value); // remove from heap
128
129 this._heap.remove(nodej); // set values
130
131
132 this._values[i] = nodei;
133 this._values[j] = undefined;
134 } else if (nodei && !nodej) {
135 // insert in heap
136 nodej = this._heap.insert(j, nodei.value); // remove from heap
137
138 this._heap.remove(nodei); // set values
139
140
141 this._values[j] = nodej;
142 this._values[i] = undefined;
143 } else if (nodei && nodej) {
144 // swap values
145 var v = nodei.value;
146 nodei.value = nodej.value;
147 nodej.value = v;
148 }
149 };
150
151 return Spa;
152}, {
153 isClass: true
154});
\No newline at end of file