UNPKG

4.22 kBJavaScriptView Raw
1'use strict'
2
3const array = require('../../utils/array')
4const isInteger = require('../../utils/number').isInteger
5
6function factory (type, config, load, typed) {
7 const matrix = load(require('../../type/matrix/function/matrix'))
8
9 /**
10 * Create a 2-dimensional identity matrix with size m x n or n x n.
11 * The matrix has ones on the diagonal and zeros elsewhere.
12 *
13 * Syntax:
14 *
15 * math.identity(n)
16 * math.identity(n, format)
17 * math.identity(m, n)
18 * math.identity(m, n, format)
19 * math.identity([m, n])
20 * math.identity([m, n], format)
21 *
22 * Examples:
23 *
24 * math.identity(3) // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
25 * math.identity(3, 2) // returns [[1, 0], [0, 1], [0, 0]]
26 *
27 * const A = [[1, 2, 3], [4, 5, 6]]
28 * math.identity(math.size(A)) // returns [[1, 0, 0], [0, 1, 0]]
29 *
30 * See also:
31 *
32 * diag, ones, zeros, size, range
33 *
34 * @param {...number | Matrix | Array} size The size for the matrix
35 * @param {string} [format] The Matrix storage format
36 *
37 * @return {Matrix | Array | number} A matrix with ones on the diagonal.
38 */
39 const identity = typed('identity', {
40 '': function () {
41 return (config.matrix === 'Matrix') ? matrix([]) : []
42 },
43
44 'string': function (format) {
45 return matrix(format)
46 },
47
48 'number | BigNumber': function (rows) {
49 return _identity(rows, rows, config.matrix === 'Matrix' ? 'default' : undefined)
50 },
51
52 'number | BigNumber, string': function (rows, format) {
53 return _identity(rows, rows, format)
54 },
55
56 'number | BigNumber, number | BigNumber': function (rows, cols) {
57 return _identity(rows, cols, config.matrix === 'Matrix' ? 'default' : undefined)
58 },
59
60 'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
61 return _identity(rows, cols, format)
62 },
63
64 'Array': function (size) {
65 return _identityVector(size)
66 },
67
68 'Array, string': function (size, format) {
69 return _identityVector(size, format)
70 },
71
72 'Matrix': function (size) {
73 return _identityVector(size.valueOf(), size.storage())
74 },
75
76 'Matrix, string': function (size, format) {
77 return _identityVector(size.valueOf(), format)
78 }
79 })
80
81 identity.toTex = undefined // use default template
82
83 return identity
84
85 function _identityVector (size, format) {
86 switch (size.length) {
87 case 0: return format ? matrix(format) : []
88 case 1: return _identity(size[0], size[0], format)
89 case 2: return _identity(size[0], size[1], format)
90 default: throw new Error('Vector containing two values expected')
91 }
92 }
93
94 /**
95 * Create an identity matrix
96 * @param {number | BigNumber} rows
97 * @param {number | BigNumber} cols
98 * @param {string} [format]
99 * @returns {Matrix}
100 * @private
101 */
102 function _identity (rows, cols, format) {
103 // BigNumber constructor with the right precision
104 const Big = (type.isBigNumber(rows) || type.isBigNumber(cols))
105 ? type.BigNumber
106 : null
107
108 if (type.isBigNumber(rows)) rows = rows.toNumber()
109 if (type.isBigNumber(cols)) cols = cols.toNumber()
110
111 if (!isInteger(rows) || rows < 1) {
112 throw new Error('Parameters in function identity must be positive integers')
113 }
114 if (!isInteger(cols) || cols < 1) {
115 throw new Error('Parameters in function identity must be positive integers')
116 }
117
118 const one = Big ? new type.BigNumber(1) : 1
119 const defaultValue = Big ? new Big(0) : 0
120 const size = [rows, cols]
121
122 // check we need to return a matrix
123 if (format) {
124 // get matrix storage constructor
125 const F = type.Matrix.storage(format)
126 // create diagonal matrix (use optimized implementation for storage format)
127 return F.diagonal(size, one, 0, defaultValue)
128 }
129
130 // create and resize array
131 const res = array.resize([], size, defaultValue)
132 // fill in ones on the diagonal
133 const minimum = rows < cols ? rows : cols
134 // fill diagonal
135 for (let d = 0; d < minimum; d++) {
136 res[d][d] = one
137 }
138 return res
139 }
140}
141
142exports.name = 'identity'
143exports.factory = factory