UNPKG

13.6 kBMarkdownView Raw
1# Matrices
2
3Math.js supports multi dimensional matrices and arrays. Matrices can be
4created, manipulated, and used in calculations. Both regular JavaScript
5arrays as well as the matrix type implemented by math.js can be used
6interchangeably in all relevant math.js functions. math.js supports both
7dense and sparse matrices.
8
9
10## Arrays and matrices
11
12Math.js supports two types of matrices:
13
14- `Array`, a regular JavaScript array. A multi dimensional array can be created
15 by nesting arrays.
16- `Matrix`, a matrix implementation by math.js. A `Matrix` is an object wrapped
17 around a regular JavaScript `Array`, providing utility functions for easy
18 matrix manipulation such as `subset`, `size`, `resize`, `clone`, and more.
19
20In most cases, the type of matrix output from functions is determined by the
21function input: An `Array` as input will return an `Array`, a `Matrix` as input
22will return a `Matrix`. In case of mixed input, a `Matrix` is returned.
23For functions where the type of output cannot be determined from the
24input, the output is determined by the configuration option `matrix`,
25which can be a string `'Matrix'` (default) or `'Array'`.
26
27```js
28// create an array and a matrix
29const array = [[2, 0], [-1, 3]] // Array
30const matrix = math.matrix([[7, 1], [-2, 3]]) // Matrix
31
32// perform a calculation on an array and matrix
33math.square(array) // Array, [[4, 0], [1, 9]]
34math.square(matrix) // Matrix, [[49, 1], [4, 9]]
35
36// perform calculations with mixed array and matrix input
37math.add(array, matrix) // Matrix, [[9, 1], [-3, 6]]
38math.multiply(array, matrix) // Matrix, [[14, 2], [-13, 8]]
39
40// create a matrix. Type of output of function ones is determined by the
41// configuration option `matrix`
42math.ones(2, 3) // Matrix, [[1, 1, 1], [1, 1, 1]]
43```
44
45
46## Creation
47
48A matrix can be created from an array using the function `math.matrix`. The
49provided array can contain nested arrays in order to create a multi-dimensional matrix. When called without arguments, an empty matrix will be
50created.
51
52```js
53// create matrices
54math.matrix() // Matrix, size [0]
55math.matrix([0, 1, 2]) // Matrix, size [3]
56math.matrix([[0, 1], [2, 3], [4, 5]]) // Matrix, size [3, 2]
57```
58
59Math.js supports regular Arrays. Multiple dimensions can be created
60by nesting Arrays in each other.
61
62```js
63// create arrays
64[] // Array, size [0]
65[0, 1, 2] // Array, size [3]
66[[0, 1], [2, 3], [4, 5]] // Array, size [3, 2]
67```
68
69Matrices can contain different types of values: numbers, complex numbers,
70units, or strings. Different types can be mixed together in a single matrix.
71
72```js
73// create a matrix with mixed types
74const a = math.matrix([2.3, 'hello', math.complex(3, -4), math.unit('5.2 mm')])
75a.subset(math.index(1)) // 'hello'
76```
77
78
79There are a number of functions to create a matrix with a specific size and
80content: `ones`, `zeros`, `identity`.
81
82```js
83// zeros creates a matrix filled with zeros
84math.zeros(3) // Matrix, size [3], [0, 0, 0]
85math.zeros(3, 2) // Matrix, size [3, 2], [[0, 0], [0, 0], [0, 0]]
86math.zeros(2, 2, 2) // Matrix, size [2, 2, 2],
87 // [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
88
89// ones creates a matrix filled with ones
90math.ones(3) // Matrix, size [3], [1, 1, 1]
91math.multiply(math.ones(2, 2), 5) // Matrix, size [2, 2], [[5, 5], [5, 5]]
92
93// identity creates an identity matrix
94math.identity(3) // Matrix, size [3, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
95math.identity(2, 3) // Matrix, size [2, 3], [[1, 0, 0], [0, 1, 0]]
96```
97
98
99The functions `ones`, `zeros`, and `identity` also accept a single array
100or matrix containing the dimensions for the matrix. When the input is an Array,
101the functions will output an Array. When the input is a Matrix, the output will
102be a Matrix. Note that in case of numbers as arguments, the output is
103determined by the option `matrix` as discussed in section
104[Arrays and matrices](#arrays-and-matrices).
105
106```js
107// Array as input gives Array as output
108math.ones([2, 3]) // Array, size [3, 2], [[1, 1, 1], [1, 1, 1]]
109math.ones(math.matrix([2, 3])) // Matrix, size [3, 2], [[1, 1, 1], [1, 1, 1]]
110```
111
112Ranges can be created using the function `range`. The function `range` is
113called with parameters start and end, and optionally a parameter step.
114The start of the range is included, the end of the range is excluded.
115
116```js
117math.range(0, 4) // [0, 1, 2, 3]
118math.range(0, 8, 2) // [0, 2, 4, 6]
119math.range(3, -1, -1) // [3, 2, 1, 0]
120```
121
122
123## Calculations
124
125All relevant functions of math.js support matrices and arrays.
126
127```js
128// perform a calculation on a matrix
129const a = math.matrix([1, 4, 9, 16, 25]) // Matrix, [1, 4, 9, 16, 25]
130math.sqrt(a) // Matrix, [1, 2, 3, 4, 5]
131
132// perform a calculation on an array
133const b = [1, 2, 3, 4, 5]
134math.factorial(b) // Array, [1, 2, 6, 24, 120]
135
136// multiply an array with a matrix
137const c = [[2, 0], [-1, 3]] // Array
138const d = math.matrix([[7, 1], [-2, 3]]) // Matrix
139math.multiply(c, d) // Matrix, [[14, 2], [-13, 8]]
140
141// add a number to a matrix
142math.add(c, 2) // Array, [[4, 2], [1, 5]]
143
144// calculate the determinant of a matrix
145math.det(c) // 6
146math.det(d) // 23
147```
148
149
150## Size and Dimensions
151
152Math.js uses geometric dimensions:
153
154- A scalar is zero-dimensional.
155- A vector is one-dimensional.
156- A matrix is two or multi-dimensional.
157
158The size of a matrix can be calculated with the function `size`. Function `size`
159returns a `Matrix` or `Array`, depending on the configuration option `matrix`.
160Furthermore, matrices have a function `size` as well, which always returns
161an Array.
162
163```js
164// get the size of a scalar
165math.size(2.4) // Matrix, []
166math.size(math.complex(3, 2)) // Matrix, []
167math.size(math.unit('5.3 mm')) // Matrix, []
168
169// get the size of a one-dimensional matrix (a vector) and a string
170math.size([0, 1, 2, 3]) // Array, [4]
171math.size('hello world') // Matrix, [11]
172
173// get the size of a two-dimensional matrix
174const a = [[0, 1, 2, 3]] // Array
175const b = math.matrix([[0, 1, 2], [3, 4, 5]]) // Matrix
176math.size(a) // Array, [1, 4]
177math.size(b) // Matrix, [2, 3]
178
179// matrices have a function size (always returns an Array)
180b.size() // Array, [2, 3]
181
182// get the size of a multi-dimensional matrix
183const c = [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
184math.size(c) // Array, [2, 2, 3]
185```
186
187
188## Resizing
189
190Matrices can be resized using their `resize` function. This function is called
191with an Array with the new size as the first argument, and accepts an optional
192default value. By default, new entries will be set to `0`, but it is possible
193to pass a different default value like `null` to clearly indicate that
194the entries haven't been explicitly set.
195
196```js
197const a = math.matrix() // Matrix, size [0], []
198a.resize([2, 3]) // Matrix, size [2, 3], [[0, 0, 0], [0, 0, 0]]
199a.resize([2, 2, 2]) // Matrix, size [2, 2, 2],
200 // [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
201
202const b = math.matrix()
203b.resize([3], 7) // Matrix, size [3], [7, 7, 7]
204b.resize([5], 9) // Matrix, size [5], [7, 7, 7, 9, 9]
205b.resize([2]) // Matrix, size [2], [7, 7]
206```
207
208
209Outer dimensions of a matrix can be squeezed using the function `squeeze`. When
210getting or setting a subset in a matrix, the subset is automatically squeezed
211or unsqueezed.
212
213```js
214// squeeze a matrix
215const a = [[[0, 1, 2]]]
216math.squeeze(a) // [0, 1, 2]
217math.squeeze([[3]]) // 3
218
219// subsets are automatically squeezed
220const b = math.matrix([[0, 1], [2, 3]])
221b.subset(math.index(1, 0)) // 2
222```
223
224
225## Getting or replacing subsets
226
227Subsets of a matrix can be retrieved or replaced using the function `subset`.
228Matrices have a `subset` function, which is applied to the matrix itself:
229`Matrix.subset(index [, replacement])`. For both matrices and arrays,
230the static function `subset(matrix, index [, replacement])` can be used.
231When parameter `replacement` is provided, the function will replace a subset
232in the matrix, and if not, a subset of the matrix will be returned.
233
234A subset can be defined using an `Index`. An `Index` contains a single value
235or a set of values for each dimension of a matrix. An `Index` can be
236created using the function `index`.
237Matrix indexes in math.js are zero-based, like most programming languages
238including JavaScript itself.
239
240Note that mathematical applications like Matlab and Octave work differently,
241as they use one-based indexes.
242
243```js
244// create some matrices
245const a = [0, 1, 2, 3]
246const b = [[0, 1], [2, 3]]
247const c = math.zeros(2, 2)
248const d = math.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
249const e = math.matrix()
250
251// get a subset
252math.subset(a, math.index(1)) // 1
253math.subset(a, math.index([2, 3])) // Array, [2, 3]
254math.subset(a, math.index(math.range(0,4))) // Array, [0, 1, 2, 3]
255math.subset(b, math.index(1, 0)) // 2
256math.subset(b, math.index(1, [0, 1])) // Array, [2, 3]
257math.subset(b, math.index([0, 1], 0)) // Matrix, [[0], [2]]
258
259// get a subset
260d.subset(math.index([1, 2], [0, 1])) // Matrix, [[3, 4], [6, 7]]
261d.subset(math.index(1, 2)) // 5
262
263// replace a subset. The subset will be applied to a clone of the matrix
264math.subset(b, math.index(1, 0), 9) // Array, [[0, 1], [9, 3]]
265math.subset(b, math.index(2, [0, 1]), [4, 5]) // Array, [[0, 1], [2, 3], [4, 5]]
266
267// replace a subset. The subset will be applied to the matrix itself
268c.subset(math.index(0, 1),1) // Matrix, [[0, 1], [0, 0]]
269c.subset(math.index(1, [0, 1]), [2, 3]) // Matrix, [[0, 1], [2, 3]]
270e.resize([2, 3], 0) // Matrix, [[0, 0, 0], [0, 0, 0]]
271e.subset(math.index(1, 2), 5) // Matrix, [[0, 0, 0], [0, 0, 5]]
272```
273
274## Iterating
275
276Matrices contain functions `map` and `forEach` to iterate over all elements of
277the (multidimensional) matrix. The callback function of `map` and `forEach` has
278three parameters: `value` (the value of the currently iterated element),
279`index` (an array with the index value for each dimension), and `matrix` (the
280matrix being iterated). This syntax is similar to the `map` and `forEach`
281functions of native JavaScript Arrays, except that the index is no number but
282an Array with numbers for each dimension.
283
284```js
285const a = math.matrix([[0, 1], [2, 3], [4, 5]])
286
287// The iteration below will output the following in the console:
288// value: 0 index: [0, 0]
289// value: 1 index: [0, 1]
290// value: 2 index: [1, 0]
291// value: 3 index: [1, 1]
292// value: 4 index: [2, 0]
293// value: 5 index: [2, 1]
294a.forEach(function (value, index, matrix) {
295 console.log('value:', value, 'index:', index)
296})
297
298// Apply a transformation on the matrix
299const b = a.map(function (value, index, matrix) {
300 return math.multiply(math.sin(value), math.exp(math.abs(value)))
301})
302console.log(b.format(5)) // [[0, 2.2874], [6.7188, 2.8345], [-41.32, -142.32]]
303
304// Create a matrix with the cumulative of all elements
305let count = 0
306const cum = a.map(function (value, index, matrix) {
307 count += value
308 return count
309})
310console.log(cum.toString()) // [[0, 1], [3, 6], [10, 15]]
311```
312
313## Storage types
314
315Math.js supports both dense matrices as well as sparse matrices. Sparse matrices are efficient for matrices largely containing zeros. In that case they save a lot of memory, and calculations can be much faster than for dense matrices.
316
317Math.js supports two type of matrices:
318
319- Dense matrix (`'dense'`, `default`) A regular, dense matrix, supporting multi-dimensional matrices. This is the default matrix type.
320- Sparse matrix (`'sparse'`): A two dimensional sparse matrix implementation.
321
322The type of matrix can be selected when creating a matrix using the construction functions `matrix`, `diag`, `identity`, `ones`, and `zeros`.
323
324```js
325// create sparse matrices
326const m1 = math.matrix([[0, 1], [0, 0]], 'sparse')
327const m2 = math.identity(1000, 1000, 'sparse')
328```
329
330## API
331
332All relevant functions in math.js support Matrices and Arrays. Functions like `math.add` and `math.subtract`, `math.sqrt` handle matrices element wise. There is a set of functions specifically for creating or manipulating matrices, such as:
333
334- Functions like `math.matrix` and `math.sparse`, `math.ones`, `math.zeros`, and `math.identity` to create a matrix.
335- Functions like `math.subset` and `math.index` to get or replace a part of a matrix
336- Functions like `math.transpose` and `math.diag` to manipulate matrices.
337
338A full list of matrix functions is available on the [functions reference page](../reference/functions.md#matrix-functions).
339
340Two types of matrix classes are available in math.js, for storage of dense and sparse matrices. Although they contain public functions documented as follows, using the following API directly is *not* recommended. Prefer using the functions in the "math" namespace wherever possible.
341
342- [DenseMatrix](../reference/classes/densematrix.md)
343- [SparseMatrix](../reference/classes/sparsematrix.md)