Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type definitions for matrixFrom* #3371

Merged
merged 8 commits into from
Jan 29, 2025
Merged
39 changes: 36 additions & 3 deletions src/function/matrix/matrixFromFunction.js
Original file line number Diff line number Diff line change
@@ -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:
*
@@ -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
@@ -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
22 changes: 22 additions & 0 deletions test/typescript-tests/testTypes.ts
Original file line number Diff line number Diff line change
@@ -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
64 changes: 61 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -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

@@ -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
@@ -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>

@@ -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,