UNPKG

4.04 kBJavaScriptView Raw
1import { factory } from '../../../utils/factory.js';
2import { DimensionError } from '../../../error/DimensionError.js';
3var name = 'algorithm08';
4var dependencies = ['typed', 'equalScalar'];
5export var createAlgorithm08 = /* #__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) = ┤ A(i,j) ; A(i,j) !== 0
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 algorithm08(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 } // sparse matrix cannot be a Pattern matrix
51
52
53 if (!avalues || !bvalues) {
54 throw new Error('Cannot perform operation on Pattern Sparse Matrices');
55 } // rows & columns
56
57
58 var rows = asize[0];
59 var columns = asize[1]; // datatype
60
61 var dt; // equal signature to use
62
63 var eq = equalScalar; // zero value
64
65 var zero = 0; // callback signature to use
66
67 var cf = callback; // process data types
68
69 if (typeof adt === 'string' && adt === bdt) {
70 // datatype
71 dt = adt; // find signature that matches (dt, dt)
72
73 eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype
74
75 zero = typed.convert(0, dt); // callback
76
77 cf = typed.find(callback, [dt, dt]);
78 } // result arrays
79
80
81 var cvalues = [];
82 var cindex = [];
83 var cptr = []; // workspace
84
85 var x = []; // marks indicating we have a value in x for a given column
86
87 var w = []; // vars
88
89 var k, k0, k1, i; // loop columns
90
91 for (var j = 0; j < columns; j++) {
92 // update cptr
93 cptr[j] = cindex.length; // columns mark
94
95 var mark = j + 1; // loop values in a
96
97 for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
98 // row
99 i = aindex[k]; // mark workspace
100
101 w[i] = mark; // set value
102
103 x[i] = avalues[k]; // add index
104
105 cindex.push(i);
106 } // loop values in b
107
108
109 for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
110 // row
111 i = bindex[k]; // check value exists in workspace
112
113 if (w[i] === mark) {
114 // evaluate callback
115 x[i] = cf(x[i], bvalues[k]);
116 }
117 } // initialize first index in j
118
119
120 k = cptr[j]; // loop index in j
121
122 while (k < cindex.length) {
123 // row
124 i = cindex[k]; // value @ i
125
126 var v = x[i]; // check for zero value
127
128 if (!eq(v, zero)) {
129 // push value
130 cvalues.push(v); // increment pointer
131
132 k++;
133 } else {
134 // remove value @ i, do not increment pointer
135 cindex.splice(k, 1);
136 }
137 }
138 } // update cptr
139
140
141 cptr[columns] = cindex.length; // return sparse matrix
142
143 return a.createSparseMatrix({
144 values: cvalues,
145 index: cindex,
146 ptr: cptr,
147 size: [rows, columns],
148 datatype: dt
149 });
150 };
151});
\No newline at end of file