UNPKG

8.25 kBJavaScriptView Raw
1describe('MatrixSpace', () => {
2 const algebra = require('algebra')
3
4 const notDefined = require('not-defined')
5
6 const MatrixSpace = algebra.MatrixSpace
7 const Real = algebra.Real
8
9 const methodBinaryOperator = require('./features/methodBinaryOperator')
10 const staticBinaryOperator = require('./features/staticBinaryOperator')
11 const staticUnaryOperator = require('./features/staticUnaryOperator')
12
13 const R1x4 = MatrixSpace(Real)(1, 4)
14 const R2x3 = MatrixSpace(Real)(2, 3)
15 const R2x2 = MatrixSpace(Real)(2)
16 const R3x2 = MatrixSpace(Real)(3, 2)
17
18 it('has signature (Scalar)(numRows, numCols)', () => {
19 R2x3.numRows.should.be.eql(2)
20 R2x3.numCols.should.be.eql(3)
21 })
22
23 it('has signature (Scalar)(numRows) and numCols defaults to numRows', () => {
24 R2x2.numRows.should.be.eql(2)
25 R2x2.numCols.should.be.eql(2)
26 })
27
28 const matrix1 = new R2x2([ 2, 3,
29 1, 1 ])
30 const matrix2 = new R2x2([ 0, 1,
31 -1, 0 ])
32 const matrix3 = new R2x3([ 0, 1, 2,
33 -2, 1, 0 ])
34
35 describe('data', () => {
36 it('is enumerable', () => {
37 matrix1.propertyIsEnumerable('data').should.be.ok
38 })
39
40 it('is immutable', () => {
41 ;(() => {
42 'use strict'
43 matrix1.data = [2, 1,
44 5, 4]
45 }).should.throwError()
46 })
47 })
48
49 describe('numRows', () => {
50 it('returns the number of rows', () => {
51 matrix1.numRows.should.be.eql(2)
52 matrix2.numRows.should.be.eql(2)
53 matrix3.numRows.should.be.eql(2)
54 })
55 })
56
57 describe('numCols', () => {
58 it('returns the number of cols', () => {
59 matrix1.numCols.should.be.eql(2)
60 matrix2.numCols.should.be.eql(2)
61 matrix3.numCols.should.be.eql(3)
62 })
63 })
64
65 describe('determinant', () => {
66 it('returns a scalar', () => {
67 matrix1.determinant.should.be.instanceOf(Real)
68 matrix2.determinant.should.be.instanceOf(Real)
69
70 matrix1.determinant.data.should.be.eql(-1)
71 matrix2.determinant.data.should.be.eql(1)
72 })
73 })
74
75 describe('addition()', () => {
76 const operator = 'addition'
77
78 it('is a static method', staticBinaryOperator(R2x2, operator,
79 [ 2, 3,
80 1, 1 ],
81 [ 0, 1,
82 -1, 0 ],
83 [ 2, 4,
84 0, 1 ]
85 ))
86
87 it('is a class method', methodBinaryOperator(R2x2, operator,
88 [ 2, 3,
89 1, 1 ],
90 [ 0, 1,
91 -1, 0 ],
92 [ 2, 4,
93 0, 1 ]
94 ))
95
96 it('accepts multiple arguments', () => {
97 R2x2.addition([ 2, 3,
98 1, 1 ],
99 [ 0, 1,
100 -1, 0 ],
101 [ -2, -4,
102 0, -1 ]).should.deepEqual([0, 0,
103 0, 0])
104
105 const matrix = new R2x2([ 2, 3,
106 1, 1 ])
107 matrix.addition([ 0, 1,
108 -1, 0 ],
109 [ -2, -4,
110 0, -1 ]).data.should.deepEqual([0, 0,
111 0, 0])
112 })
113 })
114
115 describe('subtraction()', () => {
116 const operator = 'subtraction'
117
118 it('is a static method', staticBinaryOperator(R2x2, operator,
119 [2, 3,
120 1, 1],
121 [0, 1,
122 -1, 0],
123 [2, 2,
124 2, 1]
125 ))
126
127 it('is a class method', methodBinaryOperator(R2x2, operator,
128 [2, 3,
129 1, 1],
130 [0, 1,
131 -1, 0],
132 [2, 2,
133 2, 1]
134 ))
135
136 it('accepts multiple arguments', () => {
137 R2x2.subtraction([2, 3,
138 1, 1],
139 [0, 1,
140 -1, 0],
141 [2, 4,
142 0, 1]).should.deepEqual([0, -2,
143 2, 0])
144
145 const matrix = new R2x2([2, 3,
146 1, 1])
147 matrix.subtraction([0, 1,
148 -1, 0],
149 [2, 4,
150 0, 1]).data.should.deepEqual([0, -2,
151 2, 0])
152 })
153 })
154
155 describe('multiplication()', () => {
156 const operator = 'multiplication'
157
158 it('is a static method', staticBinaryOperator(R3x2, operator,
159 [2, 3,
160 1, 1,
161 1, 1],
162 [0, 1, 1, 1,
163 -1, 0, 2, 3],
164 [-3, 2, 8, 11,
165 -1, 1, 3, 4,
166 -1, 1, 3, 4]
167 ))
168
169 it('is a class method', methodBinaryOperator(R2x2, operator,
170 [2, 3,
171 1, 1],
172 [0, 1,
173 -1, 0],
174 [-3, 2,
175 -1, 1]
176 ))
177
178 it('accepts multiple arguments', () => {
179 R2x2.multiplication([1, 2,
180 3, 4],
181 [0, 1,
182 -1, 0],
183 [-1, 0,
184 0, 1]).should.deepEqual([-2, 1,
185 -4, 3])
186
187 const matrix = new R2x2([1, 2,
188 3, 4])
189 matrix.multiplication([0, 1,
190 -1, 0],
191 [-1, 0,
192 0, 1]).data.should.deepEqual([-2, 1,
193 -4, 3])
194 })
195 })
196
197 describe('trace()', () => {
198 const operator = 'trace'
199
200 it('is a static method', staticUnaryOperator(R2x2, operator,
201 [1, 2,
202 5, 6], 7
203 ))
204
205 it('is not available for no square matrices', () => {
206 notDefined(R3x2.trace).should.be.true
207 })
208 })
209
210 describe('trace', () => {
211 it('is a static attribute', () => {
212 const matrix2x2 = new R2x2([1, 2,
213 5, 6])
214
215 matrix2x2.trace.should.be.eql(7)
216 })
217
218 it('is not available for no square matrices', () => {
219 const matrix3x2 = new R3x2([1, 2,
220 3, 4,
221 5, 6])
222
223 notDefined(matrix3x2.trace).should.be.true
224 })
225 })
226
227 describe('transpose()', () => {
228 it('is a static operator', () => {
229 const matrix3x2 = new R3x2([1, 2,
230 3, 4,
231 5, 6])
232
233 const transposed = R3x2.transpose(matrix3x2)
234
235 transposed.should.deepEqual([1, 3, 5,
236 2, 4, 6])
237 })
238 })
239
240 describe('transposed', () => {
241 it('is a class attribute', () => {
242 const matrix3x2 = new R3x2([1, 2,
243 3, 4,
244 5, 6])
245
246 const transposed = matrix3x2.transposed
247
248 transposed.data.should.deepEqual([1, 3, 5,
249 2, 4, 6])
250 })
251
252 it('holds a transposed matrix', () => {
253 const matrix2x3 = new R2x3([1, 2, 3,
254 4, 5, 6])
255
256 matrix2x3.transposed.data.should.deepEqual([1, 4,
257 2, 5,
258 3, 6])
259
260 matrix2x3.numRows.should.be.eql(matrix2x3.transposed.numCols)
261 matrix2x3.numCols.should.be.eql(matrix2x3.transposed.numRows)
262 })
263
264 it('is an involution', () => {
265 const matrix2x2a = new R2x2([1, 2,
266 3, 4])
267
268 const matrix2x2b = matrix2x2a.transposed.transposed
269
270 matrix2x2a.data.should.deepEqual(matrix2x2b.data)
271 })
272
273 it('returns a vector if the Matrix has one row', () => {
274 const matrix1x4 = new R1x4([1, 2, 3, 4])
275
276 const vector = matrix1x4.transposed
277
278 matrix1x4.data.should.deepEqual(vector.data)
279 vector.dimension.should.be.eql(matrix1x4.numCols)
280 })
281 })
282
283 describe('mul()', () => {
284 it('is an alias of multiplication()', () => {
285 R2x2.mul.should.be.eql(R2x2.multiplication)
286
287 const matrix2x2 = new R2x2([1, 2,
288 3, 4])
289
290 matrix2x2.multiplication.should.be.eql(matrix2x2.mul)
291 })
292 })
293
294 describe('tr()', () => {
295 it('is an alias of transpose()', () => {
296 R2x2.tr.should.be.eql(R2x2.transpose)
297 })
298 })
299
300 describe('tr', () => {
301 it('is an alias of transposed', () => {
302 const matrix = new R3x2([0, 1,
303 1, 0,
304 2, 2])
305
306 matrix.tr.data.should.be.eql(matrix.transposed.data)
307 })
308 })
309})