1 | const inherits = require('inherits')
|
2 | const itemsPool = require('./itemsPool')
|
3 | const matrixMultiplication = require('matrix-multiplication')
|
4 | const operators = require('./operators.json')
|
5 | const staticProps = require('static-props')
|
6 | const TensorSpace = require('./TensorSpace')
|
7 | const toData = require('./toData')
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | function VectorSpace (Scalar) {
|
24 | const addition = Scalar.addition
|
25 | const multiplication = Scalar.multiplication
|
26 | const subtraction = Scalar.subtraction
|
27 |
|
28 | |
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 | return function (dimension) {
|
35 | const indices = [dimension]
|
36 |
|
37 | const AbstractVector = TensorSpace(Scalar)(indices)
|
38 |
|
39 | |
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | function crossProduct (vector1, vector2) {
|
51 | const vectorData1 = toData(vector1)
|
52 | const vectorData2 = toData(vector2)
|
53 |
|
54 | const ux = vectorData1[0]
|
55 | const uy = vectorData1[1]
|
56 | const uz = vectorData1[2]
|
57 |
|
58 | const vx = vectorData2[0]
|
59 | const vy = vectorData2[1]
|
60 | const vz = vectorData2[2]
|
61 |
|
62 | var vector = []
|
63 |
|
64 | vector.push(subtraction(multiplication(uy, vz), multiplication(uz, vy)))
|
65 | vector.push(subtraction(multiplication(uz, vx), multiplication(ux, vz)))
|
66 | vector.push(subtraction(multiplication(ux, vy), multiplication(uy, vx)))
|
67 |
|
68 | return vector
|
69 | }
|
70 |
|
71 | |
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | function multiplicationByMatrix (leftVector, rightMatrix) {
|
79 | const leftVectorData = toData(leftVector)
|
80 | const rightMatrixData = toData(rightMatrix)
|
81 |
|
82 | const rowByColumnMultiplication = matrixMultiplication(Scalar)(dimension)
|
83 |
|
84 | return rowByColumnMultiplication(leftVectorData, rightMatrixData)
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | function norm (vector) {
|
100 | const data = toData(vector)
|
101 |
|
102 | var value = multiplication(data[0], data[0])
|
103 |
|
104 | for (var i = 1; i < dimension; i++) {
|
105 | value = addition(value, multiplication(data[i], data[i]))
|
106 | }
|
107 |
|
108 | return new Scalar(value)
|
109 | }
|
110 |
|
111 | |
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | function scalarProduct (vector1, vector2) {
|
123 |
|
124 | const vectorData1 = toData(vector1)
|
125 | const vectorData2 = toData(vector2)
|
126 |
|
127 | if (vectorData1.length !== vectorData2.length) {
|
128 | throw new TypeError('Vectors have not the same dimension')
|
129 | }
|
130 |
|
131 | var result = multiplication(vectorData1[0], vectorData2[0])
|
132 |
|
133 | for (var i = 1; i < dimension; i++) {
|
134 | result = addition(result, multiplication(vectorData1[i], vectorData2[i]))
|
135 | }
|
136 |
|
137 | return result
|
138 | }
|
139 |
|
140 | |
141 |
|
142 |
|
143 |
|
144 | function Vector (data) {
|
145 | AbstractVector.call(this, data)
|
146 |
|
147 | staticProps(this)({
|
148 | norm: norm(data),
|
149 | dimension
|
150 | })
|
151 | }
|
152 |
|
153 | inherits(Vector, AbstractVector)
|
154 |
|
155 | Vector.prototype.scalarProduct = function (vector) {
|
156 | const data = this.data
|
157 |
|
158 | const result = scalarProduct(data, vector)
|
159 |
|
160 | return new Scalar(result)
|
161 | }
|
162 |
|
163 |
|
164 | function crossProductMethod (vector) {
|
165 | const data = this.data
|
166 |
|
167 | const result = crossProduct(data, vector)
|
168 |
|
169 | return new Vector(result)
|
170 | }
|
171 |
|
172 | if (dimension === 3) {
|
173 | Vector.crossProduct = crossProduct
|
174 |
|
175 | Vector.prototype.crossProduct = crossProductMethod
|
176 | Vector.prototype.cross = crossProductMethod
|
177 | }
|
178 |
|
179 | Vector.prototype.multiplication = function (rightMatrix) {
|
180 | const MatrixSpace = itemsPool.get('MatrixSpace')
|
181 |
|
182 | const leftVectorData = this.data
|
183 | const result = multiplicationByMatrix(leftVectorData, rightMatrix)
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | const rightNumRows = dimension
|
189 | const rightNumCols = result.length / rightNumRows
|
190 |
|
191 | const Matrix = MatrixSpace(Scalar)(rightNumRows, rightNumCols)
|
192 |
|
193 | return new Matrix(result)
|
194 | }
|
195 |
|
196 |
|
197 |
|
198 | Vector.multiplication = multiplicationByMatrix
|
199 | Vector.norm = norm
|
200 | Vector.scalarProduct = scalarProduct
|
201 |
|
202 | operators.comparison.forEach((operator) => {
|
203 | Vector[operator] = AbstractVector[operator]
|
204 | })
|
205 |
|
206 | operators.set.forEach((operator) => {
|
207 | Vector[operator] = AbstractVector[operator]
|
208 | })
|
209 |
|
210 | operators.group.forEach((operator) => {
|
211 | Vector[operator] = AbstractVector[operator]
|
212 | })
|
213 |
|
214 |
|
215 |
|
216 | Vector.mul = multiplicationByMatrix
|
217 | Vector.prototype.mul = Vector.prototype.multiplication
|
218 |
|
219 | const myOperators = ['scalarProduct'].concat(operators.group)
|
220 |
|
221 | myOperators.forEach((operator) => {
|
222 | operators.aliasesOf[operator].forEach((alias) => {
|
223 | Vector[alias] = Vector[operator]
|
224 | Vector.prototype[alias] = Vector.prototype[operator]
|
225 | })
|
226 | })
|
227 |
|
228 | if (dimension === 3) {
|
229 | Vector.cross = crossProduct
|
230 | }
|
231 |
|
232 | return Vector
|
233 | }
|
234 | }
|
235 |
|
236 | itemsPool.set('VectorSpace', VectorSpace)
|
237 |
|
238 | module.exports = VectorSpace
|