UNPKG

2.87 kBJavaScriptView Raw
1import { factory } from '../../../utils/factory'
2
3const name = 'algorithm12'
4const dependencies = ['typed', 'DenseMatrix']
5
6export const createAlgorithm12 = /* #__PURE__ */ factory(name, dependencies, ({ typed, DenseMatrix }) => {
7 /**
8 * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
9 * Callback function invoked MxN times.
10 *
11 *
12 * ┌ f(Sij, b) ; S(i,j) !== 0
13 * C(i,j) = ┤
14 * └ f(0, b) ; otherwise
15 *
16 *
17 * @param {Matrix} s The SparseMatrix instance (S)
18 * @param {Scalar} b The Scalar value
19 * @param {Function} callback The f(Aij,b) operation to invoke
20 * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij)
21 *
22 * @return {Matrix} DenseMatrix (C)
23 *
24 * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
25 */
26 return function algorithm12 (s, b, callback, inverse) {
27 // sparse matrix arrays
28 const avalues = s._values
29 const aindex = s._index
30 const aptr = s._ptr
31 const asize = s._size
32 const adt = s._datatype
33
34 // sparse matrix cannot be a Pattern matrix
35 if (!avalues) { throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value') }
36
37 // rows & columns
38 const rows = asize[0]
39 const columns = asize[1]
40
41 // datatype
42 let dt
43 // callback signature to use
44 let cf = callback
45
46 // process data types
47 if (typeof adt === 'string') {
48 // datatype
49 dt = adt
50 // convert b to the same datatype
51 b = typed.convert(b, dt)
52 // callback
53 cf = typed.find(callback, [dt, dt])
54 }
55
56 // result arrays
57 const cdata = []
58 // matrix
59 const c = new DenseMatrix({
60 data: cdata,
61 size: [rows, columns],
62 datatype: dt
63 })
64
65 // workspaces
66 const x = []
67 // marks indicating we have a value in x for a given column
68 const w = []
69
70 // loop columns
71 for (let j = 0; j < columns; j++) {
72 // columns mark
73 const mark = j + 1
74 // values in j
75 for (let k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
76 // row
77 const r = aindex[k]
78 // update workspace
79 x[r] = avalues[k]
80 w[r] = mark
81 }
82 // loop rows
83 for (let i = 0; i < rows; i++) {
84 // initialize C on first column
85 if (j === 0) {
86 // create row array
87 cdata[i] = []
88 }
89 // check sparse matrix has a value @ i,j
90 if (w[i] === mark) {
91 // invoke callback, update C
92 cdata[i][j] = inverse ? cf(b, x[i]) : cf(x[i], b)
93 } else {
94 // dense matrix value @ i, j
95 cdata[i][j] = inverse ? cf(b, 0) : cf(0, b)
96 }
97 }
98 }
99
100 // return sparse matrix
101 return c
102 }
103})