UNPKG

9.31 kBJavaScriptView Raw
1'use strict'
2
3const util = require('../../utils/index')
4
5const string = util.string
6
7const isString = string.isString
8
9function factory (type, config, load, typed) {
10 /**
11 * @constructor Matrix
12 *
13 * A Matrix is a wrapper around an Array. A matrix can hold a multi dimensional
14 * array. A matrix can be constructed as:
15 *
16 * let matrix = math.matrix(data)
17 *
18 * Matrix contains the functions to resize, get and set values, get the size,
19 * clone the matrix and to convert the matrix to a vector, array, or scalar.
20 * Furthermore, one can iterate over the matrix using map and forEach.
21 * The internal Array of the Matrix can be accessed using the function valueOf.
22 *
23 * Example usage:
24 *
25 * let matrix = math.matrix([[1, 2], [3, 4]])
26 * matix.size() // [2, 2]
27 * matrix.resize([3, 2], 5)
28 * matrix.valueOf() // [[1, 2], [3, 4], [5, 5]]
29 * matrix.subset([1,2]) // 3 (indexes are zero-based)
30 *
31 */
32 function Matrix () {
33 if (!(this instanceof Matrix)) {
34 throw new SyntaxError('Constructor must be called with the new operator')
35 }
36 }
37
38 /**
39 * Attach type information
40 */
41 Matrix.prototype.type = 'Matrix'
42 Matrix.prototype.isMatrix = true
43
44 /**
45 * Get the Matrix storage constructor for the given format.
46 *
47 * @param {string} format The Matrix storage format.
48 *
49 * @return {Function} The Matrix storage constructor.
50 */
51 Matrix.storage = function (format) {
52 // check storage format is a string
53 if (!isString(format)) {
54 throw new TypeError('format must be a string value')
55 }
56
57 // get storage format constructor
58 const constructor = Matrix._storage[format]
59 if (!constructor) {
60 throw new SyntaxError('Unsupported matrix storage format: ' + format)
61 }
62
63 // return storage constructor
64 return constructor
65 }
66
67 // a map with all constructors for all storage types
68 Matrix._storage = {}
69
70 /**
71 * Get the storage format used by the matrix.
72 *
73 * Usage:
74 * const format = matrix.storage() // retrieve storage format
75 *
76 * @return {string} The storage format.
77 */
78 Matrix.prototype.storage = function () {
79 // must be implemented by each of the Matrix implementations
80 throw new Error('Cannot invoke storage on a Matrix interface')
81 }
82
83 /**
84 * Get the datatype of the data stored in the matrix.
85 *
86 * Usage:
87 * const format = matrix.datatype() // retrieve matrix datatype
88 *
89 * @return {string} The datatype.
90 */
91 Matrix.prototype.datatype = function () {
92 // must be implemented by each of the Matrix implementations
93 throw new Error('Cannot invoke datatype on a Matrix interface')
94 }
95
96 /**
97 * Create a new Matrix With the type of the current matrix instance
98 * @param {Array | Object} data
99 * @param {string} [datatype]
100 */
101 Matrix.prototype.create = function (data, datatype) {
102 throw new Error('Cannot invoke create on a Matrix interface')
103 }
104
105 /**
106 * Get a subset of the matrix, or replace a subset of the matrix.
107 *
108 * Usage:
109 * const subset = matrix.subset(index) // retrieve subset
110 * const value = matrix.subset(index, replacement) // replace subset
111 *
112 * @param {Index} index
113 * @param {Array | Matrix | *} [replacement]
114 * @param {*} [defaultValue=0] Default value, filled in on new entries when
115 * the matrix is resized. If not provided,
116 * new matrix elements will be filled with zeros.
117 */
118 Matrix.prototype.subset = function (index, replacement, defaultValue) {
119 // must be implemented by each of the Matrix implementations
120 throw new Error('Cannot invoke subset on a Matrix interface')
121 }
122
123 /**
124 * Get a single element from the matrix.
125 * @param {number[]} index Zero-based index
126 * @return {*} value
127 */
128 Matrix.prototype.get = function (index) {
129 // must be implemented by each of the Matrix implementations
130 throw new Error('Cannot invoke get on a Matrix interface')
131 }
132
133 /**
134 * Replace a single element in the matrix.
135 * @param {number[]} index Zero-based index
136 * @param {*} value
137 * @param {*} [defaultValue] Default value, filled in on new entries when
138 * the matrix is resized. If not provided,
139 * new matrix elements will be left undefined.
140 * @return {Matrix} self
141 */
142 Matrix.prototype.set = function (index, value, defaultValue) {
143 // must be implemented by each of the Matrix implementations
144 throw new Error('Cannot invoke set on a Matrix interface')
145 }
146
147 /**
148 * Resize the matrix to the given size. Returns a copy of the matrix when
149 * `copy=true`, otherwise return the matrix itself (resize in place).
150 *
151 * @param {number[]} size The new size the matrix should have.
152 * @param {*} [defaultValue=0] Default value, filled in on new entries.
153 * If not provided, the matrix elements will
154 * be filled with zeros.
155 * @param {boolean} [copy] Return a resized copy of the matrix
156 *
157 * @return {Matrix} The resized matrix
158 */
159 Matrix.prototype.resize = function (size, defaultValue) {
160 // must be implemented by each of the Matrix implementations
161 throw new Error('Cannot invoke resize on a Matrix interface')
162 }
163
164 /**
165 * Reshape the matrix to the given size. Returns a copy of the matrix when
166 * `copy=true`, otherwise return the matrix itself (reshape in place).
167 *
168 * @param {number[]} size The new size the matrix should have.
169 * @param {boolean} [copy] Return a reshaped copy of the matrix
170 *
171 * @return {Matrix} The reshaped matrix
172 */
173 Matrix.prototype.reshape = function (size, defaultValue) {
174 // must be implemented by each of the Matrix implementations
175 throw new Error('Cannot invoke reshape on a Matrix interface')
176 }
177
178 /**
179 * Create a clone of the matrix
180 * @return {Matrix} clone
181 */
182 Matrix.prototype.clone = function () {
183 // must be implemented by each of the Matrix implementations
184 throw new Error('Cannot invoke clone on a Matrix interface')
185 }
186
187 /**
188 * Retrieve the size of the matrix.
189 * @returns {number[]} size
190 */
191 Matrix.prototype.size = function () {
192 // must be implemented by each of the Matrix implementations
193 throw new Error('Cannot invoke size on a Matrix interface')
194 }
195
196 /**
197 * Create a new matrix with the results of the callback function executed on
198 * each entry of the matrix.
199 * @param {Function} callback The callback function is invoked with three
200 * parameters: the value of the element, the index
201 * of the element, and the Matrix being traversed.
202 * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
203 *
204 * @return {Matrix} matrix
205 */
206 Matrix.prototype.map = function (callback, skipZeros) {
207 // must be implemented by each of the Matrix implementations
208 throw new Error('Cannot invoke map on a Matrix interface')
209 }
210
211 /**
212 * Execute a callback function on each entry of the matrix.
213 * @param {Function} callback The callback function is invoked with three
214 * parameters: the value of the element, the index
215 * of the element, and the Matrix being traversed.
216 */
217 Matrix.prototype.forEach = function (callback) {
218 // must be implemented by each of the Matrix implementations
219 throw new Error('Cannot invoke forEach on a Matrix interface')
220 }
221
222 /**
223 * Create an Array with a copy of the data of the Matrix
224 * @returns {Array} array
225 */
226 Matrix.prototype.toArray = function () {
227 // must be implemented by each of the Matrix implementations
228 throw new Error('Cannot invoke toArray on a Matrix interface')
229 }
230
231 /**
232 * Get the primitive value of the Matrix: a multidimensional array
233 * @returns {Array} array
234 */
235 Matrix.prototype.valueOf = function () {
236 // must be implemented by each of the Matrix implementations
237 throw new Error('Cannot invoke valueOf on a Matrix interface')
238 }
239
240 /**
241 * Get a string representation of the matrix, with optional formatting options.
242 * @param {Object | number | Function} [options] Formatting options. See
243 * lib/utils/number:format for a
244 * description of the available
245 * options.
246 * @returns {string} str
247 */
248 Matrix.prototype.format = function (options) {
249 // must be implemented by each of the Matrix implementations
250 throw new Error('Cannot invoke format on a Matrix interface')
251 }
252
253 /**
254 * Get a string representation of the matrix
255 * @returns {string} str
256 */
257 Matrix.prototype.toString = function () {
258 // must be implemented by each of the Matrix implementations
259 throw new Error('Cannot invoke toString on a Matrix interface')
260 }
261
262 // exports
263 return Matrix
264}
265
266exports.name = 'Matrix'
267exports.path = 'type'
268exports.factory = factory