UNPKG

4.54 kBJavaScriptView Raw
1import { factory } from '../../../utils/factory.js';
2import { DimensionError } from '../../../error/DimensionError.js';
3var name = 'algorithm05';
4var dependencies = ['typed', 'equalScalar'];
5export var createAlgorithm05 = /* #__PURE__ */factory(name, dependencies, _ref => {
6 var {
7 typed,
8 equalScalar
9 } = _ref;
10
11 /**
12 * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij).
13 * Callback function invoked MAX(NNZA, NNZB) times
14 *
15 *
16 * ┌ f(Aij, Bij) ; A(i,j) !== 0 || B(i,j) !== 0
17 * C(i,j) = ┤
18 * └ 0 ; otherwise
19 *
20 *
21 * @param {Matrix} a The SparseMatrix instance (A)
22 * @param {Matrix} b The SparseMatrix instance (B)
23 * @param {Function} callback The f(Aij,Bij) operation to invoke
24 *
25 * @return {Matrix} SparseMatrix (C)
26 *
27 * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
28 */
29 return function algorithm05(a, b, callback) {
30 // sparse matrix arrays
31 var avalues = a._values;
32 var aindex = a._index;
33 var aptr = a._ptr;
34 var asize = a._size;
35 var adt = a._datatype; // sparse matrix arrays
36
37 var bvalues = b._values;
38 var bindex = b._index;
39 var bptr = b._ptr;
40 var bsize = b._size;
41 var bdt = b._datatype; // validate dimensions
42
43 if (asize.length !== bsize.length) {
44 throw new DimensionError(asize.length, bsize.length);
45 } // check rows & columns
46
47
48 if (asize[0] !== bsize[0] || asize[1] !== bsize[1]) {
49 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
50 } // rows & columns
51
52
53 var rows = asize[0];
54 var columns = asize[1]; // datatype
55
56 var dt; // equal signature to use
57
58 var eq = equalScalar; // zero value
59
60 var zero = 0; // callback signature to use
61
62 var cf = callback; // process data types
63
64 if (typeof adt === 'string' && adt === bdt) {
65 // datatype
66 dt = adt; // find signature that matches (dt, dt)
67
68 eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype
69
70 zero = typed.convert(0, dt); // callback
71
72 cf = typed.find(callback, [dt, dt]);
73 } // result arrays
74
75
76 var cvalues = avalues && bvalues ? [] : undefined;
77 var cindex = [];
78 var cptr = []; // workspaces
79
80 var xa = cvalues ? [] : undefined;
81 var xb = cvalues ? [] : undefined; // marks indicating we have a value in x for a given column
82
83 var wa = [];
84 var wb = []; // vars
85
86 var i, j, k, k1; // loop columns
87
88 for (j = 0; j < columns; j++) {
89 // update cptr
90 cptr[j] = cindex.length; // columns mark
91
92 var mark = j + 1; // loop values A(:,j)
93
94 for (k = aptr[j], k1 = aptr[j + 1]; k < k1; k++) {
95 // row
96 i = aindex[k]; // push index
97
98 cindex.push(i); // update workspace
99
100 wa[i] = mark; // check we need to process values
101
102 if (xa) {
103 xa[i] = avalues[k];
104 }
105 } // loop values B(:,j)
106
107
108 for (k = bptr[j], k1 = bptr[j + 1]; k < k1; k++) {
109 // row
110 i = bindex[k]; // check row existed in A
111
112 if (wa[i] !== mark) {
113 // push index
114 cindex.push(i);
115 } // update workspace
116
117
118 wb[i] = mark; // check we need to process values
119
120 if (xb) {
121 xb[i] = bvalues[k];
122 }
123 } // check we need to process values (non pattern matrix)
124
125
126 if (cvalues) {
127 // initialize first index in j
128 k = cptr[j]; // loop index in j
129
130 while (k < cindex.length) {
131 // row
132 i = cindex[k]; // marks
133
134 var wai = wa[i];
135 var wbi = wb[i]; // check Aij or Bij are nonzero
136
137 if (wai === mark || wbi === mark) {
138 // matrix values @ i,j
139 var va = wai === mark ? xa[i] : zero;
140 var vb = wbi === mark ? xb[i] : zero; // Cij
141
142 var vc = cf(va, vb); // check for zero
143
144 if (!eq(vc, zero)) {
145 // push value
146 cvalues.push(vc); // increment pointer
147
148 k++;
149 } else {
150 // remove value @ i, do not increment pointer
151 cindex.splice(k, 1);
152 }
153 }
154 }
155 }
156 } // update cptr
157
158
159 cptr[columns] = cindex.length; // return sparse matrix
160
161 return a.createSparseMatrix({
162 values: cvalues,
163 index: cindex,
164 ptr: cptr,
165 size: [rows, columns],
166 datatype: dt
167 });
168 };
169});
\No newline at end of file