Skip to content

Commit

Permalink
fix: Update types and add tests as requested by review
Browse files Browse the repository at this point in the history
  • Loading branch information
gwhitney committed Jan 29, 2025
1 parent 699605c commit 40e18c7
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 41 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
20 changes: 20 additions & 0 deletions test/typescript-tests/testTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,26 @@ 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[] =

Check failure on line 1271 in test/typescript-tests/testTypes.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `⏎······math.matrixFromFunction([3],·(i:·number[])·=>·i[0]·*·i[0]` with `·math.matrixFromFunction(⏎······[3],⏎······(i:·number[])·=>·i[0]·*·i[0]⏎····`

Check failure on line 1271 in test/typescript-tests/testTypes.ts

View workflow job for this annotation

GitHub Actions / build-and-test

Replace `⏎······math.matrixFromFunction([3],·(i:·number[])·=>·i[0]·*·i[0]` with `·math.matrixFromFunction(⏎······[3],⏎······(i:·number[])·=>·i[0]·*·i[0]⏎····`
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
76 changes: 38 additions & 38 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ export type MathExpression = string | string[] | MathCollection

// add type for Matrix Callback Function and Matrix Storage Format
export type MatrixStorageFormat = 'dense' | 'sparse'

export interface MatrixFromFunctionCallback<T extends (number | BigNumber)[]> {
(value: T): number | BigNumber
}
export type MatrixFromFunctionCallback<T extends MathScalarType> =

Check failure on line 26 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `·(`

Check failure on line 26 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / build-and-test

Insert `·(`
(index: number[]) => T

Check failure on line 27 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `··(index:·number[]` with `index:·number[]⏎`

Check failure on line 27 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / build-and-test

Replace `··(index:·number[]` with `index:·number[]⏎`

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type FactoryFunction<T> = (scope: any) => T
Expand Down Expand Up @@ -759,12 +757,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 @@ -1333,52 +1331,54 @@ export interface MathJsInstance extends MathJsFactory {
* 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<T extends (number | BigNumber)[] | Matrix>(...rows: T[]): T[]
matrixFromRows<T extends (number | BigNumber)[] | Matrix>(rows: T): T[]
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<T extends (number | BigNumber)[] | Matrix>(
...cols: T[]
): T[] | Matrix
matrixFromColumns<T extends (number | BigNumber)[] | Matrix>(
cols: T
): T[] | 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 (number | BigNumber)[] | Matrix>(
size: T,
fn: MatrixFromFunctionCallback<(number | BigNumber)[]>
): T[] | Matrix
matrixFromFunction<T extends (number | BigNumber)[] | Matrix>(
size: T,
fn: MatrixFromFunctionCallback<(number | BigNumber)[]>,
format: MatrixStorageFormat
): T[] | Matrix
matrixFromFunction<T extends (number | BigNumber)[] | Matrix>(
size: T,
fn: MatrixFromFunctionCallback<(number | BigNumber)[]>,
format: MatrixStorageFormat,
datatype: string
): T[] | Matrix
matrixFromFunction<T extends (number | BigNumber)[] | Matrix>(
size: T,
matrixFromFunction<T extends MathScalarType>(
size: [number],
fn: MatrixFromFunctionCallback<T>
): T[]
matrixFromFunction<T extends MathScalarType>(
size: [number, number],

Check failure on line 1359 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `··`

Check failure on line 1359 in types/index.d.ts

View workflow job for this annotation

GitHub Actions / build-and-test

Delete `··`
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,
fn: MatrixFromFunctionCallback<(number | BigNumber)[]>
): T[] | Matrix
matrixFromFunction<T extends (number | BigNumber)[] | Matrix>(
size: T,
datatype?: string
): Matrix
matrixFromFunction(
size: number[] | Matrix<number>,
format: MatrixStorageFormat,
datatype: string,
fn: MatrixFromFunctionCallback<(number | BigNumber)[]>
): T[] | Matrix
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 40e18c7

Please sign in to comment.