forked from josdejong/mathjs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Matrix creation and conversion methods (josdejong#2155)
* made dense and sparse matrices iterable, fixed josdejong#1184 * added matrixFromFunction, fixes josdejong#2153 * added tests for matrixFromFunction * added matrixFromRows * added matrixFromColumns * added rows() and columns() for dense matrix * improved sparse documentation a tiny bit * fix linting issues * added matrixFromRow/Column to seealso of row and column * removed unnecessary duplication from matrixFromRows/Columns * added babel runtime Co-authored-by: Jos de Jong <[email protected]>
- Loading branch information
1 parent
1d72e2c
commit 0360517
Showing
21 changed files
with
14,802 additions
and
578 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/expression/embeddedDocs/function/matrix/matrixFromColumns.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export const matrixFromColumnsDocs = { | ||
name: 'matrixFromColumns', | ||
category: 'Matrix', | ||
syntax: [ | ||
'math.matrixFromColumns(...arr)', | ||
'math.matrixFromColumns(row1, row2)', | ||
'math.matrixFromColumns(row1, row2, row3)' | ||
], | ||
description: 'Create a dense matrix from vectors as individual columns.', | ||
examples: [ | ||
'matrixFromColumns([1, 2, 3], [[4],[5],[6]])' | ||
], | ||
seealso: [ | ||
'matrix', 'matrixFromRows', 'matrixFromFunction', 'zeros' | ||
] | ||
} |
22 changes: 22 additions & 0 deletions
22
src/expression/embeddedDocs/function/matrix/matrixFromFunction.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export const matrixFromFunctionDocs = { | ||
name: 'matrixFromFunction', | ||
category: 'Matrix', | ||
syntax: [ | ||
'math.matrixFromFunction(size, fn)', | ||
'math.matrixFromFunction(size, fn, format)', | ||
'math.matrixFromFunction(size, fn, format, datatype)', | ||
'math.matrixFromFunction(size, format, fn)', | ||
'math.matrixFromFunction(size, format, datatype, fn)' | ||
], | ||
description: 'Create a matrix by evaluating a generating function at each index.', | ||
examples: [ | ||
'f(I) = I[1] - I[2]', | ||
'matrixFromFunction([3,3], f)', | ||
'g(I) = I[1] - I[2] == 1 ? 4 : 0', | ||
'matrixFromFunction([100, 100], "sparse", g)', | ||
'matrixFromFunction([5], random)' | ||
], | ||
seealso: [ | ||
'matrix', 'matrixFromRows', 'matrixFromColumns', 'zeros' | ||
] | ||
} |
16 changes: 16 additions & 0 deletions
16
src/expression/embeddedDocs/function/matrix/matrixFromRows.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export const matrixFromRowsDocs = { | ||
name: 'matrixFromRows', | ||
category: 'Matrix', | ||
syntax: [ | ||
'math.matrixFromRows(...arr)', | ||
'math.matrixFromRows(row1, row2)', | ||
'math.matrixFromRows(row1, row2, row3)' | ||
], | ||
description: 'Create a dense matrix from vectors as individual rows.', | ||
examples: [ | ||
'matrixFromRows([1, 2, 3], [[4],[5],[6]])' | ||
], | ||
seealso: [ | ||
'matrix', 'matrixFromColumns', 'matrixFromFunction', 'zeros' | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { factory } from '../../utils/factory.js' | ||
|
||
const name = 'matrixFromColumns' | ||
const dependencies = ['typed', 'matrix', 'flatten', 'size'] | ||
|
||
export const createMatrixFromColumns = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, flatten, size }) => { | ||
/** | ||
* Create a dense matrix from vectors as individual columns. | ||
* If you pass row vectors, they will be transposed (but not conjugated!) | ||
* | ||
* Syntax: | ||
* | ||
* math.matrixFromColumns(...arr) | ||
* math.matrixFromColumns(col1, col2) | ||
* math.matrixFromColumns(col1, col2, col3) | ||
* | ||
* Examples: | ||
* | ||
* math.matrixFromColumns([1, 2, 3], [[4],[5],[6]]) | ||
* math.matrixFromColumns(...vectors) | ||
* | ||
* See also: | ||
* | ||
* matrix, matrixFromRows, matrixFromFunction, zeros | ||
* | ||
* @param {...Array | ...Matrix} cols | ||
* @return { number[][] | Matrix } if at least one of the arguments is an array, an array will be returned | ||
*/ | ||
return typed(name, { | ||
'...Array': function (arr) { | ||
return _createArray(arr) | ||
}, | ||
'...Matrix': function (arr) { | ||
return matrix(_createArray(arr.map(m => m.toArray()))) | ||
} | ||
|
||
// TODO implement this properly for SparseMatrix | ||
}) | ||
|
||
function _createArray (arr) { | ||
if (arr.length === 0) throw new TypeError('At least one column is needed to construct a matrix.') | ||
const N = checkVectorTypeAndReturnLength(arr[0]) | ||
|
||
// create an array with empty rows | ||
const result = [] | ||
for (let i = 0; i < N; i++) { | ||
result[i] = [] | ||
} | ||
|
||
// loop columns | ||
for (const col of arr) { | ||
const colLength = checkVectorTypeAndReturnLength(col) | ||
|
||
if (colLength !== N) { | ||
throw new TypeError('The vectors had different length: ' + (N | 0) + ' ≠ ' + (colLength | 0)) | ||
} | ||
|
||
const f = flatten(col) | ||
|
||
// push a value to each row | ||
for (let i = 0; i < N; i++) { | ||
result[i].push(f[i]) | ||
} | ||
} | ||
|
||
return result | ||
} | ||
|
||
function checkVectorTypeAndReturnLength (vec) { | ||
const s = size(vec) | ||
|
||
if (s.length === 1) { // 1D vector | ||
return s[0] | ||
} else if (s.length === 2) { // 2D vector | ||
if (s[0] === 1) { // row vector | ||
return s[1] | ||
} else if (s[1] === 1) { // col vector | ||
return s[0] | ||
} else { | ||
throw new TypeError('At least one of the arguments is not a vector.') | ||
} | ||
} else { | ||
throw new TypeError('Only one- or two-dimensional vectors are supported.') | ||
} | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { factory } from '../../utils/factory.js' | ||
|
||
const name = 'matrixFromFunction' | ||
const dependencies = ['typed', 'matrix', 'isZero'] | ||
|
||
export const createMatrixFromFunction = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, isZero }) => { | ||
/** | ||
* Create a matrix by evaluating a generating function at each index. | ||
* | ||
* Syntax: | ||
* | ||
* math.matrixFromFunction(size, fn) | ||
* math.matrixFromFunction(size, fn, format) | ||
* math.matrixFromFunction(size, fn, format, datatype) | ||
* math.matrixFromFunction(size, format, fn) | ||
* math.matrixFromFunction(size, format, datatype, fn) | ||
* | ||
* Examples: | ||
* | ||
* math.matrixFromFunction([3,3], i => i[0] - i[1]) // an antisymmetric matrix | ||
* math.matrixFromFunction([100, 100], 'sparse', i => i[0] - i[1] === 1 ? 4 : 0) // a sparse subdiagonal matrix | ||
* math.matrixFromFunction([5], i => math.random()) // a random vector | ||
* | ||
* See also: | ||
* | ||
* matrix, zeros | ||
*/ | ||
return typed(name, { | ||
'Array | Matrix, function, string, string': function (size, fn, format, datatype) { | ||
return _create(size, fn, format, datatype) | ||
}, | ||
'Array | Matrix, function, string': function (size, fn, format) { | ||
return _create(size, fn, format) | ||
}, | ||
'Array | Matrix, function': function (size, fn) { | ||
return _create(size, fn, 'dense') | ||
}, | ||
'Array | Matrix, string, function': function (size, format, fn) { | ||
return _create(size, fn, format) | ||
}, | ||
'Array | Matrix, string, string, function': function (size, format, datatype, fn) { | ||
return _create(size, fn, format, datatype) | ||
} | ||
}) | ||
|
||
function _create (size, fn, format, datatype) { | ||
let m | ||
if (datatype !== undefined) { | ||
m = matrix(format, datatype) | ||
} else { | ||
m = matrix(format) | ||
} | ||
|
||
m.resize(size) | ||
m.forEach(function (_, index) { | ||
const val = fn(index) | ||
if (isZero(val)) return | ||
m.set(index, val) | ||
}) | ||
|
||
return m | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { factory } from '../../utils/factory.js' | ||
|
||
const name = 'matrixFromRows' | ||
const dependencies = ['typed', 'matrix', 'flatten', 'size'] | ||
|
||
export const createMatrixFromRows = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, flatten, size }) => { | ||
/** | ||
* Create a dense matrix from vectors as individual rows. | ||
* If you pass column vectors, they will be transposed (but not conjugated!) | ||
* | ||
* Syntax: | ||
* | ||
* math.matrixFromRows(...arr) | ||
* math.matrixFromRows(row1, row2) | ||
* math.matrixFromRows(row1, row2, row3) | ||
* | ||
* Examples: | ||
* | ||
* math.matrixFromRows([1, 2, 3], [[4],[5],[6]]) | ||
* math.matrixFromRows(...vectors) | ||
* | ||
* See also: | ||
* | ||
* matrix, matrixFromColumns, matrixFromFunction, zeros | ||
* | ||
* @param {...Array | ...Matrix} rows | ||
* @return { number[][] | Matrix } if at least one of the arguments is an array, an array will be returned | ||
*/ | ||
return typed(name, { | ||
'...Array': function (arr) { | ||
return _createArray(arr) | ||
}, | ||
'...Matrix': function (arr) { | ||
return matrix(_createArray(arr.map(m => m.toArray()))) | ||
} | ||
|
||
// TODO implement this properly for SparseMatrix | ||
}) | ||
|
||
function _createArray (arr) { | ||
if (arr.length === 0) throw new TypeError('At least one row is needed to construct a matrix.') | ||
const N = checkVectorTypeAndReturnLength(arr[0]) | ||
|
||
const result = [] | ||
for (const row of arr) { | ||
const rowLength = checkVectorTypeAndReturnLength(row) | ||
|
||
if (rowLength !== N) { | ||
throw new TypeError('The vectors had different length: ' + (N | 0) + ' ≠ ' + (rowLength | 0)) | ||
} | ||
|
||
result.push(flatten(row)) | ||
} | ||
|
||
return result | ||
} | ||
|
||
function checkVectorTypeAndReturnLength (vec) { | ||
const s = size(vec) | ||
|
||
if (s.length === 1) { // 1D vector | ||
return s[0] | ||
} else if (s.length === 2) { // 2D vector | ||
if (s[0] === 1) { // row vector | ||
return s[1] | ||
} else if (s[1] === 1) { // col vector | ||
return s[0] | ||
} else { | ||
throw new TypeError('At least one of the arguments is not a vector.') | ||
} | ||
} else { | ||
throw new TypeError('Only one- or two-dimensional vectors are supported.') | ||
} | ||
} | ||
}) |
Oops, something went wrong.