simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

matrices.md (14143B)


      1 # Matrices
      2 
      3 Math.js supports multi dimensional matrices and arrays. Matrices can be
      4 created, manipulated, and used in calculations. Both regular JavaScript
      5 arrays as well as the matrix type implemented by math.js can be used
      6 interchangeably in all relevant math.js functions. math.js supports both
      7 dense and sparse matrices.
      8 
      9 
     10 ## Arrays and matrices
     11 
     12 Math.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 
     20 In most cases, the type of matrix output from functions is determined by the
     21 function input: An `Array` as input will return an `Array`, a `Matrix` as input
     22 will return a `Matrix`. In case of mixed input, a `Matrix` is returned.
     23 For functions where the type of output cannot be determined from the
     24 input, the output is determined by the configuration option `matrix`,
     25 which can be a string `'Matrix'` (default) or `'Array'`.
     26 
     27 ```js
     28 // create an array and a matrix
     29 const array = [[2, 0], [-1, 3]]               // Array
     30 const matrix = math.matrix([[7, 1], [-2, 3]]) // Matrix
     31 
     32 // perform a calculation on an array and matrix
     33 math.square(array)                            // Array,  [[4, 0], [1, 9]]
     34 math.square(matrix)                           // Matrix, [[49, 1], [4, 9]]
     35 
     36 // perform calculations with mixed array and matrix input
     37 math.add(array, matrix)                       // Matrix, [[9, 1], [-3, 6]]
     38 math.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`
     42 math.ones(2, 3)                               // Matrix, [[1, 1, 1], [1, 1, 1]]
     43 ```
     44 
     45 
     46 ## Creation
     47 
     48 A matrix can be created from an array using the function `math.matrix`. The
     49 provided array can contain nested arrays in order to create a multi-dimensional matrix. When called without arguments, an empty matrix will be
     50 created.
     51 
     52 ```js
     53 // create matrices
     54 math.matrix()                           // Matrix, size [0]
     55 math.matrix([0, 1, 2])                  // Matrix, size [3]
     56 math.matrix([[0, 1], [2, 3], [4, 5]])   // Matrix, size [3, 2]
     57 ```
     58 
     59 Math.js supports regular Arrays. Multiple dimensions can be created
     60 by 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 
     69 Matrices can contain different types of values: numbers, complex numbers,
     70 units, or strings. Different types can be mixed together in a single matrix.
     71 
     72 ```js
     73 // create a matrix with mixed types
     74 const a = math.matrix([2.3, 'hello', math.complex(3, -4), math.unit('5.2 mm')]) 
     75 a.subset(math.index(1))  // 'hello'
     76 ```
     77 
     78 
     79 There are a number of functions to create a matrix with a specific size and
     80 content: `ones`, `zeros`, `identity`.
     81 
     82 ```js
     83 // zeros creates a matrix filled with zeros
     84 math.zeros(3)           // Matrix, size [3],    [0, 0, 0]
     85 math.zeros(3, 2)        // Matrix, size [3, 2], [[0, 0], [0, 0], [0, 0]]
     86 math.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
     90 math.ones(3)                        // Matrix, size [3],    [1, 1, 1]
     91 math.multiply(math.ones(2, 2), 5)   // Matrix, size [2, 2], [[5, 5], [5, 5]]
     92 
     93 // identity creates an identity matrix
     94 math.identity(3)      // Matrix, size [3, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
     95 math.identity(2, 3)   // Matrix, size [2, 3], [[1, 0, 0], [0, 1, 0]]
     96 ```
     97 
     98 
     99 The functions `ones`, `zeros`, and `identity` also accept a single array
    100 or matrix containing the dimensions for the matrix. When the input is an Array,
    101 the functions will output an Array. When the input is a Matrix, the output will
    102 be a Matrix. Note that in case of numbers as arguments, the output is
    103 determined 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
    108 math.ones([2, 3])               // Array,  size [3, 2], [[1, 1, 1], [1, 1, 1]]
    109 math.ones(math.matrix([2, 3]))  // Matrix, size [3, 2], [[1, 1, 1], [1, 1, 1]]
    110 ```
    111 
    112 Ranges can be created using the function `range`. The function `range` is
    113 called with parameters start and end, and optionally a parameter step.
    114 The start of the range is included, the end of the range is excluded.
    115 
    116 ```js
    117 math.range(0, 4)        // [0, 1, 2, 3]
    118 math.range(0, 8, 2)     // [0, 2, 4, 6]
    119 math.range(3, -1, -1)   // [3, 2, 1, 0]
    120 ```
    121 
    122 
    123 ## Calculations
    124 
    125 All relevant functions of math.js support matrices and arrays.
    126 
    127 ```js
    128 // perform a calculation on a matrix
    129 const a = math.matrix([1, 4, 9, 16, 25])  // Matrix, [1, 4, 9, 16, 25]
    130 math.sqrt(a)                              // Matrix, [1, 2, 3, 4, 5]
    131 
    132 // perform a calculation on an array
    133 const b = [1, 2, 3, 4, 5] 
    134 math.factorial(b)                         // Array,  [1, 2, 6, 24, 120]
    135 
    136 // multiply an array with a matrix
    137 const c = [[2, 0], [-1, 3]]               // Array
    138 const d = math.matrix([[7, 1], [-2, 3]])  // Matrix
    139 math.multiply(c, d)                       // Matrix, [[14, 2], [-13, 8]]
    140 
    141 // add a number to a matrix
    142 math.add(c, 2)                            // Array, [[4, 2], [1, 5]]
    143 
    144 // calculate the determinant of a matrix
    145 math.det(c)                               // 6
    146 math.det(d)                               // 23
    147 ```
    148 
    149 
    150 ## Size and Dimensions
    151 
    152 Math.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 
    158 The size of a matrix can be calculated with the function `size`. Function `size`
    159 returns a `Matrix` or `Array`, depending on the configuration option `matrix`.
    160 Furthermore, matrices have a function `size` as well, which always returns
    161 an Array.
    162 
    163 ```js
    164 // get the size of a scalar
    165 math.size(2.4)                                // Matrix, []
    166 math.size(math.complex(3, 2))                 // Matrix, []
    167 math.size(math.unit('5.3 mm'))                // Matrix, []
    168 
    169 // get the size of a one-dimensional matrix (a vector) and a string
    170 math.size([0, 1, 2, 3])                       // Array, [4]
    171 math.size('hello world')                      // Matrix, [11]
    172 
    173 // get the size of a two-dimensional matrix
    174 const a = [[0, 1, 2, 3]]                      // Array
    175 const b = math.matrix([[0, 1, 2], [3, 4, 5]]) // Matrix
    176 math.size(a)                                  // Array, [1, 4]
    177 math.size(b)                                  // Matrix, [2, 3]
    178 
    179 // matrices have a function size (always returns an Array)
    180 b.size()                                      // Array, [2, 3]
    181 
    182 // get the size of a multi-dimensional matrix
    183 const c = [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
    184 math.size(c)                                  // Array, [2, 2, 3]
    185 ```
    186 
    187 Note that the dimensions themselves do not have a meaning attached. 
    188 When creating and printing a two dimensional matrix, the first dimension is 
    189 normally rendered as the _column_, and the second dimension is rendered as 
    190 the _row_. For example:
    191 
    192 ```js
    193 console.table(math.zeros([2, 4]))
    194 // 0 0 0 0
    195 // 0 0 0 0
    196 ```
    197 
    198 If you have a matrix where the first dimension means `x` and the second 
    199 means `y`, this will look confusing since `x` is printed as _column_ 
    200 (vertically) and `y` as _row_ (horizontally).
    201 
    202 
    203 ## Resizing
    204 
    205 Matrices can be resized using their `resize` function. This function is called
    206 with an Array with the new size as the first argument, and accepts an optional
    207 default value. By default, new entries will be set to `0`, but it is possible
    208 to pass a different default value like `null` to clearly indicate that
    209 the entries haven't been explicitly set.
    210 
    211 ```js
    212 const a = math.matrix() // Matrix, size [0],       []
    213 a.resize([2, 3])        // Matrix, size [2, 3],    [[0, 0, 0], [0, 0, 0]]
    214 a.resize([2, 2, 2])     // Matrix, size [2, 2, 2],
    215                         //   [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
    216 
    217 const b = math.matrix()
    218 b.resize([3], 7)        // Matrix, size [3],    [7, 7, 7]
    219 b.resize([5], 9)        // Matrix, size [5],    [7, 7, 7, 9, 9]
    220 b.resize([2])           // Matrix, size [2],    [7, 7]
    221 ```
    222 
    223 
    224 Outer dimensions of a matrix can be squeezed using the function `squeeze`. When
    225 getting or setting a subset in a matrix, the subset is automatically squeezed
    226 or unsqueezed.
    227 
    228 ```js
    229 // squeeze a matrix
    230 const a = [[[0, 1, 2]]]
    231 math.squeeze(a)             // [0, 1, 2]
    232 math.squeeze([[3]])         // 3
    233 
    234 // subsets are automatically squeezed
    235 const b = math.matrix([[0, 1], [2, 3]])
    236 b.subset(math.index(1, 0))  // 2
    237 ```
    238 
    239 
    240 ## Getting or replacing subsets
    241 
    242 Subsets of a matrix can be retrieved or replaced using the function `subset`.
    243 Matrices have a `subset` function, which is applied to the matrix itself:
    244 `Matrix.subset(index [, replacement])`. For both matrices and arrays,
    245 the static function `subset(matrix, index [, replacement])` can be used.
    246 When parameter `replacement` is provided, the function will replace a subset
    247 in the matrix, and if not, a subset of the matrix will be returned.
    248 
    249 A subset can be defined using an `Index`. An `Index` contains a single value
    250 or a set of values for each dimension of a matrix. An `Index` can be
    251 created using the function `index`.
    252 Matrix indexes in math.js are zero-based, like most programming languages
    253 including JavaScript itself.
    254 
    255 Note that mathematical applications like Matlab and Octave work differently,
    256 as they use one-based indexes.
    257 
    258 ```js
    259 // create some matrices
    260 const a = [0, 1, 2, 3]
    261 const b = [[0, 1], [2, 3]]
    262 const c = math.zeros(2, 2)
    263 const d = math.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
    264 const e = math.matrix()
    265 
    266 // get a subset
    267 math.subset(a, math.index(1))                 // 1
    268 math.subset(a, math.index([2, 3]))            // Array, [2, 3]
    269 math.subset(a, math.index(math.range(0,4)))   // Array, [0, 1, 2, 3]
    270 math.subset(b, math.index(1, 0))              // 2
    271 math.subset(b, math.index(1, [0, 1]))         // Array, [2, 3]
    272 math.subset(b, math.index([0, 1], 0))         // Matrix, [[0], [2]]
    273 
    274 // get a subset
    275 d.subset(math.index([1, 2], [0, 1]))          // Matrix, [[3, 4], [6, 7]]
    276 d.subset(math.index(1, 2))                    // 5
    277 
    278 // replace a subset. The subset will be applied to a clone of the matrix
    279 math.subset(b, math.index(1, 0), 9)           // Array, [[0, 1], [9, 3]]
    280 math.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
    283 c.subset(math.index(0, 1),1)                  // Matrix, [[0, 1], [0, 0]]
    284 c.subset(math.index(1, [0, 1]), [2, 3])       // Matrix, [[0, 1], [2, 3]]
    285 e.resize([2, 3], 0)                           // Matrix, [[0, 0, 0], [0, 0, 0]]
    286 e.subset(math.index(1, 2), 5)                 // Matrix, [[0, 0, 0], [0, 0, 5]]
    287 ```
    288 
    289 ## Iterating
    290 
    291 Matrices contain functions `map` and `forEach` to iterate over all elements of
    292 the (multidimensional) matrix. The callback function of `map` and `forEach` has
    293 three parameters: `value` (the value of the currently iterated element),
    294 `index` (an array with the index value for each dimension), and `matrix` (the
    295 matrix being iterated). This syntax is similar to the `map` and `forEach`
    296 functions of native JavaScript Arrays, except that the index is no number but
    297 an Array with numbers for each dimension.
    298 
    299 ```js
    300 const 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]
    309 a.forEach(function (value, index, matrix) {
    310   console.log('value:', value, 'index:', index) 
    311 }) 
    312 
    313 // Apply a transformation on the matrix
    314 const b = a.map(function (value, index, matrix) {
    315   return math.multiply(math.sin(value), math.exp(math.abs(value))) 
    316 }) 
    317 console.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
    320 let count = 0
    321 const cum = a.map(function (value, index, matrix) {
    322   count += value 
    323   return count 
    324 }) 
    325 console.log(cum.toString())  // [[0, 1], [3, 6], [10, 15]]
    326 ```
    327 
    328 ## Storage types
    329 
    330 Math.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 
    332 Math.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 
    337 The 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
    341 const m1 = math.matrix([[0, 1], [0, 0]], 'sparse')
    342 const m2 = math.identity(1000, 1000, 'sparse')
    343 ```
    344 
    345 ## API
    346 
    347 All 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 
    353 A full list of matrix functions is available on the [functions reference page](../reference/functions.md#matrix-functions).
    354 
    355 Two 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)