Skip to content

Commit

Permalink
fix: type definitions for matrixFrom* (#3371)
Browse files Browse the repository at this point in the history
* Addressed silentmissile's comment in #3125

* Added method overload to index.d.ts, have to revert commit due to changes to package-lock.json with using npm install to run the unit tests & lint tests

* Type definition missing for matrixFrom* #3115

* fix: Update types and add tests as requested by review

* chore: lint fix

---------

Co-authored-by: Hudsxn <[email protected]>
Co-authored-by: Hudsxn <[email protected]>
  • Loading branch information
3 people authored Jan 29, 2025
1 parent 393cc66 commit b56fbcb
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 6 deletions.
39 changes: 36 additions & 3 deletions src/function/matrix/matrixFromFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ 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.
* The simplest overload returns a multi-dimensional array as long as `size` is an array.
* Passing `size` as a Matrix or specifying a `format` will result in returning a Matrix.
* The simplest overload returns a multi-dimensional array as long as `size`
* is an array.
* Passing `size` as a Matrix or specifying a `format` will result in
* returning a Matrix.
*
* Syntax:
*
Expand All @@ -17,6 +19,37 @@ export const createMatrixFromFunction = /* #__PURE__ */ factory(name, dependenci
* math.matrixFromFunction(size, format, fn)
* math.matrixFromFunction(size, format, datatype, fn)
*
* Where:
*
* - `size: (number[] | Matrix)`
* A vector giving the extent of the array to be created in each
* dimension. If size has one entry, a vector is created; if it
* has two, a rectangular array/Matrix is created; if three, a
* three-dimensional array/Matrix is created; and so on.
* - `fn: (index: number[]) => MathType`
* The callback function that will generate the entries of the
* matrix. It is called in turn with the index of each entry of
* the matrix. The index is always an ordinary array of numbers
* with the same length as _size_. So for vectors, you will get
* indices like `[0]` or `[1]`, whereas for matrices, you will
* get indices like `[2, 0]` or `[1,3]`. The return value may
* be any type that can go in an array or Matrix entry, although
* if you supply the _datatype_ argument, you must yourself ensure
* the type of the return value matches. Note that currently,
* your callback _fn_ will receive 0-based indices for the matrix
* entries, regardless of whether matrixFromFunction is invoked
* directly from JavaScript or via the mathjs expression language.
* - `format: 'dense'|'sparse'`
* Specifies the storage format for the resulting Matrix. Note that
* if this argument is given, the return value will always be a
* Matrix (rather than possibly an Array).
* - `datatype: string`
* Specifies the data type of entries of the new matrix. If given,
* it should be the name of a data type that mathjs supports, as
* returned by the math.typeOf function. It is up to the caller
* to make certain that all values returned by _fn_ are consistent
* with this datatype if specified.
*
* Examples:
*
* math.matrixFromFunction([3,3], i => i[0] - i[1]) // an antisymmetric matrix
Expand All @@ -25,7 +58,7 @@ export const createMatrixFromFunction = /* #__PURE__ */ factory(name, dependenci
*
* See also:
*
* matrix, zeros
* matrix, typeOf, zeros
*
* @param {Array | Matrix} size The size of the matrix to be created
* @param {function} fn Callback function invoked for every entry in the matrix
Expand Down
22 changes: 22 additions & 0 deletions test/typescript-tests/testTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,28 @@ Matrices examples
const _c = math.multiply(a, b)
const f: Matrix = math.matrix([1, 0])
const _d: Matrix = f.subset(math.index(1))
const g: number[] = math.matrixFromFunction(
[3],
(i: number[]) => i[0] * i[0]
)
assert.strictEqual(g[2], 4)
const h: Matrix = math.matrixFromFunction(
[2, 2],
(i: number[]) => math.fraction(i[0], i[1] + 1),
'dense'
)
const j: number[][] = math.matrixFromRows(
[1, 2, 3],
math.matrix([[4], [5], [6]])
)
assert.strictEqual(j[1][2], 6)
const _k: Matrix = math.matrixFromRows(f, math.row(h, 1))
const l: number[][] = math.matrixFromColumns(
[1, 2, 3],
math.matrix([[4], [5], [6]])
)
assert.strictEqual(l[2][1], 6)
const _m: Matrix = math.matrixFromColumns(f, math.row(h, 1))
}

// get a sub matrix
Expand Down
64 changes: 61 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export type MathCollection<T = MathGeneric> = MathArray<T> | Matrix<T>
export type MathType = MathScalarType | MathCollection
export type MathExpression = string | string[] | MathCollection

// add type for Matrix Callback Function and Matrix Storage Format
export type MatrixStorageFormat = 'dense' | 'sparse'
export type MatrixFromFunctionCallback<T extends MathScalarType> = (
index: number[]
) => T

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type FactoryFunction<T> = (scope: any) => T

Expand Down Expand Up @@ -743,7 +749,7 @@ export interface MathJsInstance extends MathJsFactory {
* @param format The Matrix storage format
* @returns The created Matrix
*/
matrix(format?: 'sparse' | 'dense'): Matrix
matrix(format?: MatrixStorageFormat): Matrix
/**
* @param data A multi dimensional array
* @param format The Matrix storage format
Expand All @@ -752,12 +758,12 @@ export interface MathJsInstance extends MathJsFactory {
*/
matrix(
data: MathCollection | string[],
format?: 'sparse' | 'dense',
format?: MatrixStorageFormat,
dataType?: string
): Matrix
matrix<T extends MathScalarType>(
data: MathCollection<T>,
format?: 'sparse' | 'dense',
format?: MatrixStorageFormat,
dataType?: string
): Matrix<T>

Expand Down Expand Up @@ -1322,6 +1328,58 @@ export interface MathJsInstance extends MathJsFactory {
hypot<T extends number | BigNumber>(...args: T[]): T
hypot<T extends number | BigNumber>(args: T[]): T

/**
* Create a dense matrix from vectors as individual rows. If you pass column vectors, they will be transposed (but not conjugated!)
* @param rows - a multi-dimensional number array or matrix
*/
matrixFromRows(...rows: Matrix[]): Matrix
matrixFromRows<T extends MathScalarType>(
...rows: (T[] | [T][] | Matrix)[]
): T[][]

/**
* Create a dense matrix from vectors as individual columns. If you pass row vectors, they will be transposed (but not conjugated!)
* @param cols - a multi-dimensional number array or matrix
*/
matrixFromColumns(...cols: Matrix[]): Matrix
matrixFromColumns<T extends MathScalarType>(
...cols: (T[] | [T][] | Matrix)[]
): T[][]
/**
* Create a matrix by evaluating a generating function at each index. The simplest overload returns a multi-dimensional array as long as size is an array. Passing size as a Matrix or specifying a format will result in returning a Matrix.
* @param size - the size of the matrix to be created
* @param fn - Callback function invoked for every entry in the matrix
* @param format - The Matrix storage format, either 'dense' or 'sparse'
* @param datatype - Type of the values
*/
matrixFromFunction<T extends MathScalarType>(
size: [number],
fn: MatrixFromFunctionCallback<T>
): T[]
matrixFromFunction<T extends MathScalarType>(
size: [number, number],
fn: MatrixFromFunctionCallback<T>
): T[][]
matrixFromFunction<T extends MathScalarType>(
size: number[],
fn: MatrixFromFunctionCallback<T>
): MathArray<T>
matrixFromFunction(
size: Matrix<number>,
fn: MatrixFromFunctionCallback<MathScalarType>
): Matrix
matrixFromFunction(
size: number[] | Matrix<number>,
fn: MatrixFromFunctionCallback<MathScalarType>,
format: MatrixStorageFormat,
datatype?: string
): Matrix
matrixFromFunction(
size: number[] | Matrix<number>,
format: MatrixStorageFormat,
fn: MatrixFromFunctionCallback<MathScalarType>,
datatype?: string
): Matrix
/**
* Calculate the least common multiple for two or more values or arrays.
* lcm is defined as: lcm(a, b) = abs(a * b) / gcd(a, b) For matrices,
Expand Down

0 comments on commit b56fbcb

Please sign in to comment.