UNPKG

14.1 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
187Note that the dimensions themselves do not have a meaning attached.
188When creating and printing a two dimensional matrix, the first dimension is
189normally rendered as the _column_, and the second dimension is rendered as
190the _row_. For example:
191
192```js
193console.table(math.zeros([2, 4]))
194// 0 0 0 0
195// 0 0 0 0
196```
197
198If you have a matrix where the first dimension means `x` and the second
199means `y`, this will look confusing since `x` is printed as _column_
200(vertically) and `y` as _row_ (horizontally).
201
202
203## Resizing
204
205Matrices can be resized using their `resize` function. This function is called
206with an Array with the new size as the first argument, and accepts an optional
207default value. By default, new entries will be set to `0`, but it is possible
208to pass a different default value like `null` to clearly indicate that
209the entries haven't been explicitly set.
210
211```js
212const a = math.matrix() // Matrix, size [0], []
213a.resize([2, 3]) // Matrix, size [2, 3], [[0, 0, 0], [0, 0, 0]]
214a.resize([2, 2, 2]) // Matrix, size [2, 2, 2],
215 // [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
216
217const b = math.matrix()
218b.resize([3], 7) // Matrix, size [3], [7, 7, 7]
219b.resize([5], 9) // Matrix, size [5], [7, 7, 7, 9, 9]
220b.resize([2]) // Matrix, size [2], [7, 7]
221```
222
223
224Outer dimensions of a matrix can be squeezed using the function `squeeze`. When
225getting or setting a subset in a matrix, the subset is automatically squeezed
226or unsqueezed.
227
228```js
229// squeeze a matrix
230const a = [[[0, 1, 2]]]
231math.squeeze(a) // [0, 1, 2]
232math.squeeze([[3]]) // 3
233
234// subsets are automatically squeezed
235const b = math.matrix([[0, 1], [2, 3]])
236b.subset(math.index(1, 0)) // 2
237```
238
239
240## Getting or replacing subsets
241
242Subsets of a matrix can be retrieved or replaced using the function `subset`.
243Matrices have a `subset` function, which is applied to the matrix itself:
244`Matrix.subset(index [, replacement])`. For both matrices and arrays,
245the static function `subset(matrix, index [, replacement])` can be used.
246When parameter `replacement` is provided, the function will replace a subset
247in the matrix, and if not, a subset of the matrix will be returned.
248
249A subset can be defined using an `Index`. An `Index` contains a single value
250or a set of values for each dimension of a matrix. An `Index` can be
251created using the function `index`.
252Matrix indexes in math.js are zero-based, like most programming languages
253including JavaScript itself.
254
255Note that mathematical applications like Matlab and Octave work differently,
256as they use one-based indexes.
257
258```js
259// create some matrices
260const a = [0, 1, 2, 3]
261const b = [[0, 1], [2, 3]]
262const c = math.zeros(2, 2)
263const d = math.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
264const e = math.matrix()
265
266// get a subset
267math.subset(a, math.index(1)) // 1
268math.subset(a, math.index([2, 3])) // Array, [2, 3]
269math.subset(a, math.index(math.range(0,4))) // Array, [0, 1, 2, 3]
270math.subset(b, math.index(1, 0)) // 2
271math.subset(b, math.index(1, [0, 1])) // Array, [2, 3]
272math.subset(b, math.index([0, 1], 0)) // Matrix, [[0], [2]]
273
274// get a subset
275d.subset(math.index([1, 2], [0, 1])) // Matrix, [[3, 4], [6, 7]]
276d.subset(math.index(1, 2)) // 5
277
278// replace a subset. The subset will be applied to a clone of the matrix
279math.subset(b, math.index(1, 0), 9) // Array, [[0, 1], [9, 3]]
280math.subset(b, math.index(2, [0, 1]), [4, 5]) // Array, [[0, 1], [2, 3], [4, 5]]
281
282// replace a subset. The subset will be applied to the matrix itself
283c.subset(math.index(0, 1),1) // Matrix, [[0, 1], [0, 0]]
284c.subset(math.index(1, [0, 1]), [2, 3]) // Matrix, [[0, 1], [2, 3]]
285e.resize([2, 3], 0) // Matrix, [[0, 0, 0], [0, 0, 0]]
286e.subset(math.index(1, 2), 5) // Matrix, [[0, 0, 0], [0, 0, 5]]
287```
288
289## Iterating
290
291Matrices contain functions `map` and `forEach` to iterate over all elements of
292the (multidimensional) matrix. The callback function of `map` and `forEach` has
293three parameters: `value` (the value of the currently iterated element),
294`index` (an array with the index value for each dimension), and `matrix` (the
295matrix being iterated). This syntax is similar to the `map` and `forEach`
296functions of native JavaScript Arrays, except that the index is no number but
297an Array with numbers for each dimension.
298
299```js
300const a = math.matrix([[0, 1], [2, 3], [4, 5]])
301
302// The iteration below will output the following in the console:
303// value: 0 index: [0, 0]
304// value: 1 index: [0, 1]
305// value: 2 index: [1, 0]
306// value: 3 index: [1, 1]
307// value: 4 index: [2, 0]
308// value: 5 index: [2, 1]
309a.forEach(function (value, index, matrix) {
310 console.log('value:', value, 'index:', index)
311})
312
313// Apply a transformation on the matrix
314const b = a.map(function (value, index, matrix) {
315 return math.multiply(math.sin(value), math.exp(math.abs(value)))
316})
317console.log(b.format(5)) // [[0, 2.2874], [6.7188, 2.8345], [-41.32, -142.32]]
318
319// Create a matrix with the cumulative of all elements
320let count = 0
321const cum = a.map(function (value, index, matrix) {
322 count += value
323 return count
324})
325console.log(cum.toString()) // [[0, 1], [3, 6], [10, 15]]
326```
327
328## Storage types
329
330Math.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.
331
332Math.js supports two type of matrices:
333
334- Dense matrix (`'dense'`, `default`) A regular, dense matrix, supporting multi-dimensional matrices. This is the default matrix type.
335- Sparse matrix (`'sparse'`): A two dimensional sparse matrix implementation.
336
337The type of matrix can be selected when creating a matrix using the construction functions `matrix`, `diag`, `identity`, `ones`, and `zeros`.
338
339```js
340// create sparse matrices
341const m1 = math.matrix([[0, 1], [0, 0]], 'sparse')
342const m2 = math.identity(1000, 1000, 'sparse')
343```
344
345## API
346
347All 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:
348
349- Functions like `math.matrix` and `math.sparse`, `math.ones`, `math.zeros`, and `math.identity` to create a matrix.
350- Functions like `math.subset` and `math.index` to get or replace a part of a matrix
351- Functions like `math.transpose` and `math.diag` to manipulate matrices.
352
353A full list of matrix functions is available on the [functions reference page](../reference/functions.md#matrix-functions).
354
355Two 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.
356
357- [DenseMatrix](../reference/classes/densematrix.md)
358- [SparseMatrix](../reference/classes/sparsematrix.md)