Skip to content

Commit 2f0f403

Browse files
committed
applied changes to matAlgo13xDD
1 parent f95ca5a commit 2f0f403

File tree

8 files changed

+178
-216
lines changed

8 files changed

+178
-216
lines changed

src/function/logical/nullish.js

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,35 @@ export const createNullish = /* #__PURE__ */ factory(
5757

5858
// SparseMatrix-first with collection RHS: enforce exact shape match
5959
'SparseMatrix, Array | Matrix': (x, y) => {
60-
const sx = size(x)
61-
const sy = size(y)
62-
if (deepEqual(sx, sy)) return x
63-
throw new DimensionError(sx, sy)
60+
_validateSize(x, y)
61+
return x
6462
},
6563

6664
// DenseMatrix-first handlers (no broadcasting between collections)
67-
'DenseMatrix, DenseMatrix': typed.referToSelf(self => (x, y) => matAlgo13xDD(x, y, self)),
65+
'DenseMatrix, DenseMatrix': typed.referToSelf(self => (x, y) => _matAlgo13xDDnoBroadcast(x, y, self)
66+
),
6867
'DenseMatrix, SparseMatrix': typed.referToSelf(self => (x, y) => matAlgo03xDSf(x, y, self, false)),
69-
'DenseMatrix, Array': typed.referToSelf(self => (x, y) => matAlgo13xDD(x, matrix(y), self)),
68+
'DenseMatrix, Array': typed.referToSelf(self => (x, y) => _matAlgo13xDDnoBroadcast(x, y, self)),
7069
'DenseMatrix, any': typed.referToSelf(self => (x, y) => matAlgo14xDs(x, y, self, false)),
7170

7271
// Array-first handlers (bridge via matrix() where needed)
73-
'Array, Array': typed.referToSelf(self => (x, y) => matAlgo13xDD(matrix(x), matrix(y), self).valueOf()),
74-
'Array, DenseMatrix': typed.referToSelf(self => (x, y) => matAlgo13xDD(matrix(x), y, self)),
72+
'Array, Array': typed.referToSelf(self => (x, y) => _matAlgo13xDDnoBroadcast(x, y, self)),
73+
'Array, DenseMatrix': typed.referToSelf(self => (x, y) => matrix(_matAlgo13xDDnoBroadcast(x, y, self))),
7574
'Array, SparseMatrix': typed.referToSelf(self => (x, y) => matAlgo03xDSf(matrix(x), y, self, false)),
7675
'Array, any': typed.referToSelf(self => (x, y) => matAlgo14xDs(matrix(x), y, self, false).valueOf())
7776
}
7877
)
78+
function _validateSize (x, y) {
79+
const sx = size(x)
80+
const sy = size(y)
81+
if (!deepEqual(sx, sy)) {
82+
throw new DimensionError(sx, sy)
83+
}
84+
}
85+
// Remve broadcasting from matAlgo13xDD
86+
function _matAlgo13xDDnoBroadcast (x, y, callback) {
87+
_validateSize(x, y)
88+
return matAlgo13xDD(x, y, callback)
89+
}
7990
}
8091
)

src/type/matrix/utils/broadcast.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import { deepStrictEqual } from '../../../utils/object.js'
55
* Broadcasts two matrices, and return both in an array
66
* It checks if it's possible with broadcasting rules
77
*
8-
* @param {Matrix} A First Matrix
9-
* @param {Matrix} B Second Matrix
8+
* @param {Matrix|Array} A First Matrix
9+
* @param {Matrix|Array} B Second Matrix
1010
*
11-
* @return {Matrix[]} [ broadcastedA, broadcastedB ]
11+
* @return {Matrix|Array} [ broadcastedA, broadcastedB ]
1212
*/
1313

14-
export function broadcast (A, B) {
14+
export function broadcastMatrices (A, B) {
1515
if (deepStrictEqual(A.size(), B.size())) {
16-
// If matrices have the same size return them
16+
// If matrices have the same size return them as such
1717
return [A, B]
1818
}
1919

@@ -50,7 +50,7 @@ function _broadcastTo (M, size) {
5050
* @param {function} callback The callback function to apply to each pair of elements
5151
* @returns {Array} The resulting array after applying the callback to each pair of elements
5252
*/
53-
export function broadcastTwo (array1, array2, size1, size2, callback) {
53+
export function broadcast (array1, array2, size1, size2, callback) {
5454
if (![array1, array2, size1, size2].every(Array.isArray)) {
5555
throw new Error('Arrays and their sizes must be provided')
5656
}

src/type/matrix/utils/matAlgo13xCC.js

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { factory } from '../../../utils/factory.js'
2-
import { DimensionError } from '../../../error/DimensionError.js'
2+
import { broadcast } from './broadcast.js'
3+
import { isMatrix } from '../../../utils/is.js'
4+
import { arraySize, validate } from '../../../utils/array.js'
35

46
const name = 'matAlgo13xDD'
57
const dependencies = ['typed']
@@ -11,36 +13,28 @@ export const createMatAlgo13xDD = /* #__PURE__ */ factory(name, dependencies, ({
1113
*
1214
* C(i,j,...z) = f(Aij..z, Bij..z)
1315
*
14-
* @param {Matrix} a The DenseMatrix instance (A)
15-
* @param {Matrix} b The DenseMatrix instance (B)
16+
* @param {Matrix|Array} a The DenseMatrix instance (A)
17+
* @param {Matrix|Array} b The DenseMatrix instance (B)
1618
* @param {Function} callback The f(Aij..z,Bij..z) operation to invoke
1719
*
18-
* @return {Matrix} DenseMatrix (C)
20+
* @return {Matrix|Array} DenseMatrix (C)
1921
*
2022
* https://github.com/josdejong/mathjs/pull/346#issuecomment-97658658
2123
*/
2224
return function matAlgo13xDD (a, b, callback) {
2325
// a arrays
24-
const adata = a._data
25-
const asize = a._size
26-
const adt = a._datatype
27-
// b arrays
28-
const bdata = b._data
29-
const bsize = b._size
30-
const bdt = b._datatype
31-
// c arrays
32-
const csize = []
33-
34-
// validate dimensions
35-
if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) }
26+
const aIsMatrix = isMatrix(a)
27+
const adata = aIsMatrix ? a._data : a
28+
const asize = aIsMatrix ? a._size : arraySize(a)
29+
if (!aIsMatrix) validate(adata, asize)
30+
const adt = aIsMatrix ? a._datatype : undefined
3631

37-
// validate each one of the dimension sizes
38-
for (let s = 0; s < asize.length; s++) {
39-
// must match
40-
if (asize[s] !== bsize[s]) { throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')') }
41-
// update dimension in c
42-
csize[s] = asize[s]
43-
}
32+
// b arrays
33+
const bIsMatrix = isMatrix(b)
34+
const bdata = bIsMatrix ? b._data : b
35+
const bsize = bIsMatrix ? b._size : arraySize(b)
36+
if (!bIsMatrix) validate(bdata, bsize)
37+
const bdt = bIsMatrix ? b._datatype : undefined
4438

4539
// datatype
4640
let dt
@@ -56,34 +50,16 @@ export const createMatAlgo13xDD = /* #__PURE__ */ factory(name, dependencies, ({
5650
}
5751

5852
// populate cdata, iterate through dimensions
59-
const cdata = csize.length > 0 ? _iterate(cf, 0, csize, csize[0], adata, bdata) : []
60-
61-
// c matrix
62-
return a.createDenseMatrix({
63-
data: cdata,
64-
size: csize,
65-
datatype: dt
66-
})
67-
}
53+
const cdata = broadcast(adata, bdata, asize, bsize, cf)
6854

69-
// recursive function
70-
function _iterate (f, level, s, n, av, bv) {
71-
// initialize array for this level
72-
const cv = []
73-
// check we reach the last level
74-
if (level === s.length - 1) {
75-
// loop arrays in last level
76-
for (let i = 0; i < n; i++) {
77-
// invoke callback and store value
78-
cv[i] = f(av[i], bv[i])
79-
}
55+
if (aIsMatrix) {
56+
const cMatrix = a.createDenseMatrix()
57+
cMatrix._data = cdata.data
58+
cMatrix._size = cdata.size
59+
cMatrix._datatype = dt
60+
return cMatrix
8061
} else {
81-
// iterate current level
82-
for (let j = 0; j < n; j++) {
83-
// iterate next level
84-
cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv[j])
85-
}
62+
return cdata.data
8663
}
87-
return cv
8864
}
8965
})

src/type/matrix/utils/matrixAlgorithmSuite.js

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import { factory } from '../../../utils/factory.js'
22
import { extend } from '../../../utils/object.js'
3-
// import { createMatAlgo13xDD } from './matAlgo13xDD.js'
3+
import { createMatAlgo13xDD } from './matAlgo13xDD.js'
44
import { createMatAlgo14xDs } from './matAlgo14xDs.js'
5-
import { createMatAlgo13xCC } from './matAlgo13xCC.js'
6-
import { broadcast } from './broadcast.js'
5+
import { broadcastMatrices } from './broadcast.js'
76

87
const name = 'matrixAlgorithmSuite'
98
const dependencies = ['typed', 'matrix']
109

1110
export const createMatrixAlgorithmSuite = /* #__PURE__ */ factory(
1211
name, dependencies, ({ typed, matrix }) => {
13-
// const matAlgo13xDD = createMatAlgo13xDD({ typed })
12+
const matAlgo13xDD = createMatAlgo13xDD({ typed })
1413
const matAlgo14xDs = createMatAlgo14xDs({ typed })
15-
const matAlgo13xCC = createMatAlgo13xCC({ typed })
1614

1715
/**
1816
* Return a signatures object with the usual boilerplate of
@@ -38,71 +36,71 @@ export const createMatrixAlgorithmSuite = /* #__PURE__ */ factory(
3836
if (elop) {
3937
// First the dense ones
4038
matrixSignatures = {
41-
'DenseMatrix, DenseMatrix': (x, y) => matAlgo13xCC(x, y, elop),
39+
'DenseMatrix, DenseMatrix': (x, y) => matAlgo13xDD(x, y, elop),
4240
'Array, Array': (x, y) =>
43-
matAlgo13xCC(matrix(x), matrix(y), elop).valueOf(),
44-
'Array, DenseMatrix': (x, y) => matAlgo13xCC(matrix(x), y, elop),
45-
'DenseMatrix, Array': (x, y) => matAlgo13xCC(x, matrix(y), elop)
41+
matAlgo13xDD(matrix(x), matrix(y), elop).valueOf(),
42+
'Array, DenseMatrix': (x, y) => matAlgo13xDD(matrix(x), y, elop),
43+
'DenseMatrix, Array': (x, y) => matAlgo13xDD(x, matrix(y), elop)
4644
}
4745
// Now incorporate sparse matrices
4846
if (options.SS) {
4947
matrixSignatures['SparseMatrix, SparseMatrix'] =
50-
(x, y) => options.SS(...broadcast(x, y), elop, false)
48+
(x, y) => options.SS(...broadcastMatrices(x, y), elop, false)
5149
}
5250
if (options.DS) {
5351
matrixSignatures['DenseMatrix, SparseMatrix'] =
54-
(x, y) => options.DS(...broadcast(x, y), elop, false)
52+
(x, y) => options.DS(...broadcastMatrices(x, y), elop, false)
5553
matrixSignatures['Array, SparseMatrix'] =
56-
(x, y) => options.DS(...broadcast(matrix(x), y), elop, false)
54+
(x, y) => options.DS(...broadcastMatrices(matrix(x), y), elop, false)
5755
}
5856
if (SD) {
5957
matrixSignatures['SparseMatrix, DenseMatrix'] =
60-
(x, y) => SD(...broadcast(y, x), elop, true)
58+
(x, y) => SD(...broadcastMatrices(y, x), elop, true)
6159
matrixSignatures['SparseMatrix, Array'] =
62-
(x, y) => SD(...broadcast(matrix(y), x), elop, true)
60+
(x, y) => SD(...broadcastMatrices(matrix(y), x), elop, true)
6361
}
6462
} else {
6563
// No elop, use this
6664
// First the dense ones
6765
matrixSignatures = {
6866
'DenseMatrix, DenseMatrix': typed.referToSelf(self => (x, y) => {
69-
return matAlgo13xCC(x, y, self)
67+
return matAlgo13xDD(x, y, self)
7068
}),
7169
'Array, Array': typed.referToSelf(self => (x, y) => {
72-
return matAlgo13xCC(matrix(x), matrix(y), self).valueOf()
70+
return matAlgo13xDD(matrix(x), matrix(y), self).valueOf()
7371
}),
7472
'Array, DenseMatrix': typed.referToSelf(self => (x, y) => {
75-
return matAlgo13xCC(matrix(x), y, self)
73+
return matAlgo13xDD(matrix(x), y, self)
7674
}),
7775
'DenseMatrix, Array': typed.referToSelf(self => (x, y) => {
78-
return matAlgo13xCC(x, matrix(y), self)
76+
return matAlgo13xDD(x, matrix(y), self)
7977
})
8078
}
8179
// Now incorporate sparse matrices
8280
if (options.SS) {
8381
matrixSignatures['SparseMatrix, SparseMatrix'] =
8482
typed.referToSelf(self => (x, y) => {
85-
return options.SS(...broadcast(x, y), self, false)
83+
return options.SS(...broadcastMatrices(x, y), self, false)
8684
})
8785
}
8886
if (options.DS) {
8987
matrixSignatures['DenseMatrix, SparseMatrix'] =
9088
typed.referToSelf(self => (x, y) => {
91-
return options.DS(...broadcast(x, y), self, false)
89+
return options.DS(...broadcastMatrices(x, y), self, false)
9290
})
9391
matrixSignatures['Array, SparseMatrix'] =
9492
typed.referToSelf(self => (x, y) => {
95-
return options.DS(...broadcast(matrix(x), y), self, false)
93+
return options.DS(...broadcastMatrices(matrix(x), y), self, false)
9694
})
9795
}
9896
if (SD) {
9997
matrixSignatures['SparseMatrix, DenseMatrix'] =
10098
typed.referToSelf(self => (x, y) => {
101-
return SD(...broadcast(y, x), self, true)
99+
return SD(...broadcastMatrices(y, x), self, true)
102100
})
103101
matrixSignatures['SparseMatrix, Array'] =
104102
typed.referToSelf(self => (x, y) => {
105-
return SD(...broadcast(matrix(y), x), self, true)
103+
return SD(...broadcastMatrices(matrix(y), x), self, true)
106104
})
107105
}
108106
}

test/unit-tests/expression/function/evaluate.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ describe('evaluate', function () {
206206
assert.deepStrictEqual(math.evaluate(math.matrix(['null ?? 1', '2 ?? null'])), math.matrix([1, 2]))
207207

208208
// Test shape mismatch with empty array
209-
assert.throws(() => math.evaluate('[] ?? [7, 8]'), /RangeError/)
210-
assert.throws(() => math.evaluate('[1] ?? [7, 8]'), /RangeError/)
209+
assert.throws(() => math.evaluate('[] ?? [7, 8]'), /Dimension mismatch/)
210+
assert.throws(() => math.evaluate('[1] ?? [7, 8]'), /Dimension mismatch/)
211211
})
212212

213213
it('should handle nullish coalescing with function calls', function () {

test/unit-tests/function/logical/nullish.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('nullish', function () {
123123
describe('shape handling and sparse matrices', function () {
124124
it('should throw on mismatched shapes', function () {
125125
assert.throws(() => nullish([1], [7, 8]), /Dimension mismatch/)
126-
assert.throws(() => nullish(matrix([1]), matrix([7, 8])), /RangeError/)
126+
assert.throws(() => nullish(matrix([1]), matrix([7, 8])), /Dimension mismatch/)
127127
assert.throws(() => nullish(sparse([[1]]), matrix([7, 8])), /DimensionError/)
128128
})
129129

0 commit comments

Comments
 (0)