forked from josdejong/mathjs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rotationMatrix.test.js
252 lines (214 loc) · 13.3 KB
/
rotationMatrix.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
import assert from 'assert'
import approx from '../../../../tools/approx'
import math from '../../../../src/bundleAny'
const bignumber = math.bignumber
const complex = math.complex
const unit = math.unit
const multiply = math.multiply
const matrix = math.matrix
const cos = math.cos
const sin = math.sin
const rotationMatrix = math.rotationMatrix
describe('rotationMatrix', function () {
const sqrtTwoInv = 0.7071067811865476 // = 1 / sqrt(2)
const minusSqrtTwoInv = -0.7071067811865476 // = - 1 / sqrt(2)
it('should create an empty matrix', function () {
assert.deepStrictEqual(rotationMatrix(), matrix())
assert.deepStrictEqual(rotationMatrix('sparse'), matrix('sparse'))
assert.deepStrictEqual(rotationMatrix('dense'), matrix('dense'))
const mathArray = math.create({ matrix: 'Array' })
assert.deepStrictEqual(mathArray.rotationMatrix(), [])
})
it('should create a 2D rotation matrix of given angle', function () {
approx.deepEqual(rotationMatrix(0.0), matrix([[1, 0.0], [0.0, 1]]))
approx.deepEqual(rotationMatrix(math.pi / 2), matrix([[0.0, -1], [1, 0.0]]))
approx.deepEqual(rotationMatrix(1), matrix([[cos(1), -sin(1)], [sin(1), cos(1)]]))
approx.deepEqual(rotationMatrix(math.pi / 4), matrix([[sqrtTwoInv, -sqrtTwoInv], [sqrtTwoInv, sqrtTwoInv]]))
})
it('should create a 2D rotation matrix of given bignumber angle', function () {
approx.deepEqual(rotationMatrix(bignumber(0.0)), matrix([[1, 0.0], [0.0, 1]]))
const bigmath = math.create({ number: 'BigNumber' })
const minusOne = bigmath.bignumber(-1)
const cos1 = bigmath.cos(bigmath.bignumber(1))
const sin1 = bigmath.sin(bigmath.bignumber(1))
const minusSin1 = bigmath.multiply(sin1, minusOne)
assert.deepStrictEqual(bigmath.rotationMatrix(bigmath.bignumber(1)),
bigmath.matrix([[cos1, minusSin1], [sin1, cos1]]))
const cos25 = bigmath.cos(bigmath.bignumber(2.5))
const sin25 = bigmath.sin(bigmath.bignumber(2.5))
const minusSin25 = bigmath.multiply(sin25, minusOne)
assert.deepStrictEqual(bigmath.rotationMatrix(bigmath.bignumber(2.5)),
bigmath.matrix([[cos25, minusSin25], [sin25, cos25]]))
})
it('should create a 2D rotation matrix of given complex angle', function () {
const reI = 1.5430806348152437784
const imI = 1.1752011936438014568
approx.deepEqual(rotationMatrix(math.i), matrix([[complex(reI, 0.0), complex(0.0, -imI)],
[complex(0.0, imI), complex(reI, 0.0)]]))
const reCos = 4.18962569096881
const imCos = 9.10922789375534
const reSin = 9.15449914691142
const imSin = 4.16890695996656
const cosComplex = complex(-reCos, -imCos)
const sinComplex = complex(reSin, -imSin)
approx.deepEqual(rotationMatrix(complex('2+3i')), matrix([[cosComplex, multiply(-1.0, sinComplex)], [sinComplex, cosComplex]]))
})
it('should create a 2D rotation matrix of given unit angle', function () {
approx.deepEqual(rotationMatrix(unit('45deg')), matrix([[sqrtTwoInv, minusSqrtTwoInv], [sqrtTwoInv, sqrtTwoInv]]))
approx.deepEqual(rotationMatrix(unit('-135deg')), matrix([[minusSqrtTwoInv, sqrtTwoInv], [minusSqrtTwoInv, minusSqrtTwoInv]]))
const cosComplex = complex(0.833730025131149, -0.988897705762865)
const sinComplex = complex(1.298457581415977, 0.63496391478473611)
approx.deepEqual(rotationMatrix(unit(complex(1, 1), 'rad')), matrix([[cosComplex, multiply(-1.0, sinComplex)], [sinComplex, cosComplex]]))
})
it('should create a 2D rotation matrix of given angle and given storage type', function () {
assert.deepStrictEqual(rotationMatrix(0.0, 'sparse'), matrix([[1.0, 0.0], [0.0, 1.0]], 'sparse'))
assert.deepStrictEqual(rotationMatrix(math.pi / 2, 'sparse'), matrix([[0, -1], [1, 0]], 'sparse'))
approx.deepEqual(rotationMatrix(math.pi / 4, 'sparse'), matrix([[sqrtTwoInv, -sqrtTwoInv], [sqrtTwoInv, sqrtTwoInv]], 'sparse'))
})
it('should create a 3D rotation matrix by given angle around given axis', function () {
assert.deepStrictEqual(math.rotationMatrix(0.0, [1, 1, 1]), matrix([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, [1, 0, 0]), matrix([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, [0, 1, 0]), matrix([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, [0, 0, 1]), matrix([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, [1, 0, 0]),
matrix([[1.0, 0.0, 0.0], [0.0, sqrtTwoInv, sqrtTwoInv], [0.0, minusSqrtTwoInv, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, [0, 1, 0]),
matrix([[sqrtTwoInv, 0.0, minusSqrtTwoInv], [0.0, 1.0, 0.0], [sqrtTwoInv, 0.0, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, [0, 0, 1]),
matrix([[sqrtTwoInv, sqrtTwoInv, 0.0], [minusSqrtTwoInv, sqrtTwoInv, 0.0], [0.0, 0.0, 1.0]]))
assert.deepStrictEqual(math.rotationMatrix(1, [1, 0, 0]),
matrix([[1, 0, 0],
[0, cos(1), -sin(1)],
[0, sin(1), cos(1)]]))
})
it('should create a 3D rotation matrix by given angle around given vector provided as matrix', function () {
assert.deepStrictEqual(math.rotationMatrix(0.0, matrix([1, 1, 1])),
matrix([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, matrix([1, 0, 0])),
matrix([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, matrix([0, 1, 0])),
matrix([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, matrix([0, 0, 1])),
matrix([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, matrix([1, 0, 0])),
matrix([[1.0, 0.0, 0.0], [0.0, sqrtTwoInv, sqrtTwoInv], [0.0, minusSqrtTwoInv, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, matrix([0, 1, 0])),
matrix([[sqrtTwoInv, 0.0, minusSqrtTwoInv], [0.0, 1.0, 0.0], [sqrtTwoInv, 0.0, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(-math.pi / 4, matrix([0, 0, 1])),
matrix([[sqrtTwoInv, sqrtTwoInv, 0.0], [minusSqrtTwoInv, sqrtTwoInv, 0.0], [0.0, 0.0, 1.0]]))
assert.deepStrictEqual(math.rotationMatrix(1, matrix([1, 0, 0])),
matrix([[1, 0, 0],
[0, cos(1), -sin(1)],
[0, sin(1), cos(1)]]))
})
it('should create a unitary 3D rotation matrix around non-unit vector', function () {
approx.deepEqual(math.rotationMatrix(math.pi / 2, [1000, 0, 0]),
matrix([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, [1000, 0, 1000]),
matrix([[0.5, minusSqrtTwoInv, 0.5], [sqrtTwoInv, 0.0, minusSqrtTwoInv], [0.5, sqrtTwoInv, 0.5]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, matrix([0, 0, 1000])),
matrix([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(math.pi / 2, matrix([0, 200, 200])),
matrix([[0.0, minusSqrtTwoInv, sqrtTwoInv], [sqrtTwoInv, 0.5, 0.5], [minusSqrtTwoInv, 0.5, 0.5]]))
})
it('should create a 3D rotation matrix by given bignumber angle around given axis', function () {
const zero = bignumber(0)
const one = bignumber(1)
const cos2 = cos(bignumber(2))
const sin2 = sin(bignumber(2))
const minusSin2 = multiply(bignumber(-1), sin2)
assert.deepStrictEqual(math.rotationMatrix(bignumber(2), [1, 0, 0]),
matrix([[one, zero, zero],
[zero, cos2, minusSin2],
[zero, sin2, cos2]]))
assert.deepStrictEqual(math.rotationMatrix(bignumber(2), [0, 1, 0]),
matrix([[cos2, zero, sin2],
[zero, one, zero],
[minusSin2, zero, cos2]]))
assert.deepStrictEqual(math.rotationMatrix(bignumber(2), [0, 0, 1]),
matrix([[cos2, minusSin2, zero],
[sin2, cos2, zero],
[zero, zero, one]]))
assert.deepStrictEqual(math.rotationMatrix(bignumber(2), matrix([0, 0, 1])),
matrix([[cos2, minusSin2, zero],
[sin2, cos2, zero],
[zero, zero, one]]))
})
it('should create a 3D rotation matrix by given complex angle around given axis', function () {
const complexZero = math.complex(0)
const cosTheta = math.cos(complex('2+3i'))
const sinTheta = math.sin(complex('2+3i'))
const minusSinTheta = math.multiplyScalar(-1, sinTheta)
assert.deepStrictEqual(math.rotationMatrix(complex('2+3i'), [1, 0, 0]),
math.complex(matrix([[1, 0, 0],
[complexZero, cosTheta, minusSinTheta],
[complexZero, sinTheta, cosTheta]])))
assert.deepStrictEqual(math.rotationMatrix(complex('2+3i'), [0, 1, 0]),
math.complex(matrix([[cosTheta, 0.0, sinTheta],
[0.0, 1.0, 0.0],
[minusSinTheta, 0.0, cosTheta]])))
assert.deepStrictEqual(math.rotationMatrix(complex('2+3i'), [0, 0, 1]),
math.complex(matrix([[cosTheta, minusSinTheta, 0.0],
[sinTheta, cosTheta, 0.0],
[0.0, 0.0, 1.0]])))
assert.deepStrictEqual(math.rotationMatrix(complex('2+3i'), matrix([0, 1, 0])),
math.complex(matrix([[cosTheta, 0.0, sinTheta],
[0.0, 1.0, 0.0],
[minusSinTheta, 0.0, cosTheta]])))
})
it('should create a 3D rotation matrix by given unit angle around given axis', function () {
approx.deepEqual(math.rotationMatrix(unit('45deg'), [1, 0, 0]),
matrix([[1.0, 0.0, 0.0], [0.0, sqrtTwoInv, minusSqrtTwoInv], [0.0, sqrtTwoInv, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(unit('45deg'), [0, 1, 0]),
matrix([[sqrtTwoInv, 0.0, sqrtTwoInv], [0.0, 1.0, 0.0], [minusSqrtTwoInv, 0.0, sqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(unit('45deg'), [0, 0, 1]),
matrix([[sqrtTwoInv, minusSqrtTwoInv, 0.0], [sqrtTwoInv, sqrtTwoInv, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(unit('-135deg'), [1, 0, 0]),
matrix([[1.0, 0.0, 0.0], [0.0, minusSqrtTwoInv, sqrtTwoInv], [0.0, minusSqrtTwoInv, minusSqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(unit('-135deg'), [0, 1, 0]),
matrix([[minusSqrtTwoInv, 0.0, minusSqrtTwoInv], [0.0, 1.0, 0.0], [sqrtTwoInv, 0.0, minusSqrtTwoInv]]))
approx.deepEqual(math.rotationMatrix(unit('-135deg'), [0, 0, 1]),
matrix([[minusSqrtTwoInv, sqrtTwoInv, 0.0], [minusSqrtTwoInv, minusSqrtTwoInv, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(rotationMatrix(unit(complex(1, 1), 'rad'), [1, 0, 1]),
math.evaluate('matrix([[0.5 * (1 + cos(1+i)), -sin(1+i) / sqrt(2), 0.5 * (1 - cos(1+i))],' +
'[sin(1+i) / sqrt(2), cos(1+i), -sin(1+i) / sqrt(2)],' +
'[0.5 * (1 - cos(1+i)), sin(1+i) / sqrt(2), 0.5 * (1 + cos(1+i))]])'))
approx.deepEqual(math.rotationMatrix(unit('45deg'), matrix([0, 0, 1])),
matrix([[sqrtTwoInv, minusSqrtTwoInv, 0.0], [sqrtTwoInv, sqrtTwoInv, 0.0], [0.0, 0.0, 1.0]]))
approx.deepEqual(math.rotationMatrix(unit('-135deg'), matrix([1, 0, 0])),
matrix([[1.0, 0.0, 0.0], [0.0, minusSqrtTwoInv, sqrtTwoInv], [0.0, minusSqrtTwoInv, minusSqrtTwoInv]]))
})
it('should create a 3D rotation matrix of given angle around given axis and given storage type', function () {
assert.deepStrictEqual(rotationMatrix(0.0, [0, 0, 1], 'sparse'),
matrix([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], 'sparse'))
assert.deepStrictEqual(rotationMatrix(math.pi / 2, [0, 0, 1], 'sparse'),
matrix([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], 'sparse'))
approx.deepEqual(rotationMatrix(math.pi / 4, [0, 1, 0], 'sparse'),
matrix([[sqrtTwoInv, 0.0, sqrtTwoInv], [0, 1, 0], [minusSqrtTwoInv, 0.0, sqrtTwoInv]], 'sparse'))
approx.deepEqual(rotationMatrix(math.pi / 4, matrix([0, 1, 0]), 'sparse'),
matrix([[sqrtTwoInv, 0.0, sqrtTwoInv], [0, 1, 0], [minusSqrtTwoInv, 0.0, sqrtTwoInv]], 'sparse'))
})
it('should return an array when mathjs is configured for this', function () {
const mathArray = math.create({ matrix: 'Array' })
approx.deepEqual(mathArray.rotationMatrix(mathArray.pi / 4),
[[sqrtTwoInv, minusSqrtTwoInv], [sqrtTwoInv, sqrtTwoInv]])
approx.deepEqual(mathArray.rotationMatrix(mathArray.pi / 2, [0, 0, 1]),
[[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
approx.deepEqual(mathArray.rotationMatrix(mathArray.pi / 2, matrix([0, 0, 1])),
[[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]])
})
it('should throw an error with an invalid input', function () {
assert.throws(function () { rotationMatrix('') }, /TypeError: Unknown matrix type /)
assert.throws(function () { rotationMatrix(null) }, /TypeError: Unexpected type of argument/)
assert.throws(function () { rotationMatrix(0, []) }, /RangeError: Vector must be of dimensions 1x3/)
assert.throws(function () { rotationMatrix(0, [1]) }, /RangeError: Vector must be of dimensions 1x3/)
assert.throws(function () { rotationMatrix(0, [0, 1]) }, /RangeError: Vector must be of dimensions 1x3/)
assert.throws(function () { rotationMatrix(0, [0, 1, 0], 'something') }, /TypeError: Unknown matrix type/)
assert.throws(function () { rotationMatrix(0, [0, 1, 0], 'sparse', 4) }, /TypeError: Too many arguments/)
assert.throws(function () { rotationMatrix(1, [0.0, 0.0, 0.0]) }, /Rotation around zero vector/)
})
it('should LaTeX rotationMatrix', function () {
const expression = math.parse('rotationMatrix(1)')
assert.strictEqual(expression.toTex(), '\\mathrm{rotationMatrix}\\left(1\\right)')
})
})