pimath 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/pimath.js +856 -1882
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +2 -2
  4. package/src/algebra/equation.ts +562 -558
  5. package/src/algebra/equationSolver.ts +489 -489
  6. package/src/algebra/factor.ts +396 -392
  7. package/src/algebra/linearSystem.ts +446 -442
  8. package/src/algebra/matrix.ts +515 -511
  9. package/src/algebra/monom.ts +932 -928
  10. package/src/algebra/polyFactor.ts +724 -720
  11. package/src/algebra/polynom.ts +1233 -1229
  12. package/src/coefficients/fraction.ts +907 -748
  13. package/src/coefficients/root.ts +500 -359
  14. package/src/geometry/TupleN.ts +129 -129
  15. package/src/geometry/circle.ts +455 -455
  16. package/src/geometry/line.ts +658 -654
  17. package/src/geometry/point.ts +105 -105
  18. package/src/geometry/sphere3.ts +2 -2
  19. package/src/geometry/triangle.ts +488 -488
  20. package/src/geometry/vector.ts +230 -226
  21. package/src/numeric.ts +136 -51
  22. package/src/pimath.interface.ts +2 -0
  23. package/types/algebra/equation.d.ts +1 -0
  24. package/types/algebra/equation.d.ts.map +1 -1
  25. package/types/algebra/equationSolver.d.ts.map +1 -1
  26. package/types/algebra/factor.d.ts +1 -0
  27. package/types/algebra/factor.d.ts.map +1 -1
  28. package/types/algebra/linearSystem.d.ts +1 -0
  29. package/types/algebra/linearSystem.d.ts.map +1 -1
  30. package/types/algebra/matrix.d.ts +6 -5
  31. package/types/algebra/matrix.d.ts.map +1 -1
  32. package/types/algebra/monom.d.ts +1 -0
  33. package/types/algebra/monom.d.ts.map +1 -1
  34. package/types/algebra/polyFactor.d.ts +1 -0
  35. package/types/algebra/polyFactor.d.ts.map +1 -1
  36. package/types/algebra/polynom.d.ts +1 -0
  37. package/types/algebra/polynom.d.ts.map +1 -1
  38. package/types/coefficients/fraction.d.ts +62 -53
  39. package/types/coefficients/fraction.d.ts.map +1 -1
  40. package/types/coefficients/root.d.ts +3 -0
  41. package/types/coefficients/root.d.ts.map +1 -1
  42. package/types/geometry/TupleN.d.ts +1 -1
  43. package/types/geometry/TupleN.d.ts.map +1 -1
  44. package/types/geometry/circle.d.ts.map +1 -1
  45. package/types/geometry/line.d.ts +1 -0
  46. package/types/geometry/line.d.ts.map +1 -1
  47. package/types/geometry/point.d.ts.map +1 -1
  48. package/types/geometry/sphere3.d.ts +2 -2
  49. package/types/geometry/sphere3.d.ts.map +1 -1
  50. package/types/geometry/triangle.d.ts.map +1 -1
  51. package/types/geometry/vector.d.ts +1 -0
  52. package/types/geometry/vector.d.ts.map +1 -1
  53. package/types/index.d.ts +3 -3
  54. package/types/numeric.d.ts +4 -4
  55. package/types/numeric.d.ts.map +1 -1
  56. package/types/pimath.interface.d.ts +1 -0
  57. package/types/pimath.interface.d.ts.map +1 -1
  58. package/types/primes.data.d.ts +2 -0
  59. package/types/primes.data.d.ts.map +1 -0
@@ -1,226 +1,230 @@
1
- /**
2
- * Vector2D module contains everything necessary to handle 2d vectors.
3
- * @module Vector
4
- */
5
- import type {InputValue, IPiMathObject} from "../pimath.interface"
6
- import {Fraction} from "../coefficients"
7
- import {Numeric} from "../numeric"
8
- import {areVectorsColinears, areVectorsEquals, dotProduct} from "./geomMath"
9
- import {DimensionError, InvalidArgumentError} from "../errors"
10
- import {TupleN} from "./TupleN"
11
- import {type Point} from "./point"
12
-
13
- export class Vector extends TupleN implements IPiMathObject<Vector> {
14
- constructor(...values: (Vector | Point)[] | InputValue<Fraction>[]) {
15
- super()
16
-
17
- if (values.length > 0) {
18
- this.parse(...values)
19
- }
20
-
21
- return this
22
- };
23
-
24
- // ------------------------------------------
25
- // Getter and setter
26
-
27
- public parse(...values: (Vector | Point)[] | InputValue<Fraction>[]): this {
28
- if (values.length === 0) {
29
- throw new InvalidArgumentError(`Invalid value`)
30
- }
31
-
32
- if (values.length === 1) {
33
- if (values[0] instanceof TupleN) {
34
- this.array = values[0].copy()
35
- return this
36
- }
37
-
38
- if (typeof values[0] === 'string') {
39
- return this.fromString(values[0])
40
- }
41
-
42
- throw new InvalidArgumentError(`Invalid value`)
43
- }
44
-
45
- // Two values are given
46
- if (values.length === 2) {
47
- const [A, B] = values
48
-
49
- // The two values are vectors
50
- if (A instanceof TupleN && B instanceof TupleN) {
51
- if (A.dimension !== B.dimension) {
52
- throw new DimensionError('Vectors must have the same dimension')
53
- }
54
-
55
- this.array = B.array.map((x, index) => x.clone().subtract(A.array[index]))
56
- return this
57
- }
58
- }
59
-
60
- // Two ore more values as number, string, fraction...
61
- this.array = values.map(x => new Fraction(x as InputValue<Fraction>))
62
- return this
63
- }
64
-
65
- public clone(): Vector {
66
- return new Vector(...this.copy())
67
- }
68
-
69
- get tex(): string {
70
- return `\\begin{pmatrix} ${this.array.map(x => x.tex).join(' \\\\ ')} \\end{pmatrix}`
71
- }
72
-
73
- get display(): string {
74
- return `((${this.array.map(x => x.display).join(',')}))`
75
- }
76
-
77
- static asDisplay(...values: string[]): string {
78
- return `((${values.join(',')}))`
79
- }
80
-
81
- static asTex(...values: string[]): string {
82
- return `\\begin{pmatrix} ${values.join(' \\\\ ')} \\end{pmatrix}`
83
- }
84
-
85
- add = (V: Vector): this => {
86
- this.array.forEach((x, index) => x.add(V.array[index]))
87
- return this
88
- }
89
-
90
- angle = (V: Vector, sharp?: boolean, radian?: boolean): number => {
91
-
92
- let scalar = this.dot(V).value
93
- if (sharp) {
94
- scalar = Math.abs(scalar)
95
- }
96
-
97
- const toDegree = radian ? 1 : 180 / Math.PI
98
-
99
- return toDegree * Math.acos(scalar / (this.norm * V.norm))
100
- }
101
-
102
- cross(value: Vector): Vector {
103
- if (this.dimension !== 3 || value.dimension !== 3) {
104
- throw new DimensionError('Cross product can only be determined in 3D')
105
- }
106
-
107
- return new Vector(
108
- this.y.clone().multiply(value.z).subtract(this.z.clone().multiply(value.y)),
109
- this.z.clone().multiply(value.x).subtract(this.x.clone().multiply(value.z)),
110
- this.x.clone().multiply(value.y).subtract(this.y.clone().multiply(value.x))
111
- )
112
- }
113
-
114
- // ------------------------------------------
115
- // Creation / parsing functions
116
-
117
- divideByScalar = (k: InputValue<Fraction>): this => {
118
- return this.multiplyByScalar(new Fraction(k).inverse())
119
- }
120
-
121
- dot = (V: Vector |Point): Fraction => {
122
- return dotProduct(this, V)
123
- }
124
-
125
- override fromString(value: string): this {
126
- if (value.startsWith('((') && value.endsWith('))')) {
127
- return super.fromString(value.slice(1, -1))
128
- }
129
-
130
- return super.fromString(value)
131
- }
132
-
133
- isColinearTo = (v: Vector): boolean => {
134
- return areVectorsColinears(this, v)
135
- }
136
-
137
- isEqual = (v: Vector): boolean => {
138
- return areVectorsEquals(this, v)
139
- }
140
-
141
- isNormalTo = (v: Vector): boolean => {
142
- return this.dot(v).isZero()
143
- }
144
-
145
- // ------------------------------------------
146
- get isNull(): boolean {
147
- return this.array.every(x => x.isZero())
148
- }
149
-
150
- isOne(): boolean {
151
- return this.array.every((x, index) => index === 0 ? x.isOne() : x.isZero())
152
- }
153
-
154
- isZero(): boolean {
155
- return this.array.every(x => x.isZero())
156
- }
157
-
158
- multiplyByScalar = (k: InputValue<Fraction>): this => {
159
- const scalar = new Fraction(k)
160
- this.array.forEach(x => x.multiply(scalar))
161
- return this
162
- }
163
-
164
- get norm(): number {
165
- return Math.sqrt(this.normSquare.value)
166
- }
167
-
168
- get normSquare(): Fraction {
169
- // Get the norm square of the vector
170
- return this.array.reduce((acc, x) => acc.add(x.clone().pow(2)), new Fraction(0))
171
- }
172
-
173
- normal = (): this => {
174
- if (this.dimension >= 3) {
175
- throw new DimensionError('Normal vector can only be determined in 2D')
176
- }
177
-
178
- const x = this.x.clone().opposite()
179
- const y = this.y.clone()
180
-
181
- this.array[0] = y
182
- this.array[1] = x
183
- return this
184
- }
185
-
186
- one = (): this => {
187
- this.zero()
188
- this.x.one()
189
- return this
190
- }
191
-
192
- opposite = (): this => {
193
- this.array.forEach(x => x.opposite())
194
- return this
195
- }
196
-
197
- simplify = (): this => {
198
- const lcm = Numeric.lcm(...this.array.map(x => x.denominator))
199
- const gcd = Numeric.gcd(...this.array.map(x => x.numerator))
200
-
201
- this.multiplyByScalar(new Fraction(lcm, gcd))
202
-
203
- if(this.x.isNegative()) this.opposite()
204
-
205
- return this
206
- }
207
-
208
- subtract = (V: Vector): this => {
209
- return this.add(V.clone().opposite())
210
- }
211
-
212
- translate(...values: Fraction[]): this {
213
- this.array.forEach((x, index) => x.add(values[index]))
214
- return this
215
- }
216
-
217
- unit = (): this => {
218
- const norm = this.norm
219
- if (norm === 0) {
220
- return this
221
- }
222
-
223
- return this.divideByScalar(norm)
224
- }
225
-
226
- }
1
+ /**
2
+ * Vector2D module contains everything necessary to handle 2d vectors.
3
+ * @module Vector
4
+ */
5
+ import type {InputValue, IPiMathObject} from "../pimath.interface"
6
+ import {Fraction} from "../coefficients"
7
+ import {Numeric} from "../numeric"
8
+ import {areVectorsColinears, areVectorsEquals, dotProduct} from "./geomMath"
9
+ import {DimensionError, InvalidArgumentError, NotImplementedError} from "../errors"
10
+ import {TupleN} from "./TupleN"
11
+ import {type Point} from "./point"
12
+
13
+ export class Vector extends TupleN implements IPiMathObject<Vector> {
14
+ constructor(...values: (Vector | Point)[] | InputValue<Fraction>[]) {
15
+ super()
16
+
17
+ if (values.length > 0) {
18
+ this.parse(...values)
19
+ }
20
+
21
+ return this
22
+ };
23
+
24
+ // ------------------------------------------
25
+ // Getter and setter
26
+
27
+ parse(...values: (Vector | Point)[] | InputValue<Fraction>[]): this {
28
+ if (values.length === 0) {
29
+ throw new InvalidArgumentError(`Invalid value`)
30
+ }
31
+
32
+ if (values.length === 1) {
33
+ if (values[0] instanceof TupleN) {
34
+ this.array = values[0].cloneCoordinates()
35
+ return this
36
+ }
37
+
38
+ if (typeof values[0] === 'string') {
39
+ return this.fromString(values[0])
40
+ }
41
+
42
+ throw new InvalidArgumentError(`Invalid value`)
43
+ }
44
+
45
+ // Two values are given
46
+ if (values.length === 2) {
47
+ const [A, B] = values
48
+
49
+ // The two values are vectors
50
+ if (A instanceof TupleN && B instanceof TupleN) {
51
+ if (A.dimension !== B.dimension) {
52
+ throw new DimensionError('Vectors must have the same dimension')
53
+ }
54
+
55
+ this.array = B.array.map((x, index) => x.clone().subtract(A.array[index]))
56
+ return this
57
+ }
58
+ }
59
+
60
+ // Two ore more values as number, string, fraction...
61
+ this.array = values.map(x => new Fraction(x as InputValue<Fraction>))
62
+ return this
63
+ }
64
+
65
+ clone(): Vector {
66
+ return new Vector(...this.cloneCoordinates())
67
+ }
68
+
69
+ copy(): this {
70
+ throw new NotImplementedError("copy() is not yet implemented for Vector")
71
+ }
72
+
73
+ get tex(): string {
74
+ return `\\begin{pmatrix} ${this.array.map(x => x.tex).join(' \\\\ ')} \\end{pmatrix}`
75
+ }
76
+
77
+ get display(): string {
78
+ return `((${this.array.map(x => x.display).join(',')}))`
79
+ }
80
+
81
+ static asDisplay(...values: string[]): string {
82
+ return `((${values.join(',')}))`
83
+ }
84
+
85
+ static asTex(...values: string[]): string {
86
+ return `\\begin{pmatrix} ${values.join(' \\\\ ')} \\end{pmatrix}`
87
+ }
88
+
89
+ add = (V: Vector): this => {
90
+ this.array.forEach((x, index) => x.add(V.array[index]))
91
+ return this
92
+ }
93
+
94
+ angle = (V: Vector, sharp?: boolean, radian?: boolean): number => {
95
+
96
+ let scalar = this.dot(V).value
97
+ if (sharp) {
98
+ scalar = Math.abs(scalar)
99
+ }
100
+
101
+ const toDegree = radian ? 1 : 180 / Math.PI
102
+
103
+ return toDegree * Math.acos(scalar / (this.norm * V.norm))
104
+ }
105
+
106
+ cross(value: Vector): Vector {
107
+ if (this.dimension !== 3 || value.dimension !== 3) {
108
+ throw new DimensionError('Cross product can only be determined in 3D')
109
+ }
110
+
111
+ return new Vector(
112
+ this.y.clone().multiply(value.z).subtract(this.z.clone().multiply(value.y)),
113
+ this.z.clone().multiply(value.x).subtract(this.x.clone().multiply(value.z)),
114
+ this.x.clone().multiply(value.y).subtract(this.y.clone().multiply(value.x))
115
+ )
116
+ }
117
+
118
+ // ------------------------------------------
119
+ // Creation / parsing functions
120
+
121
+ divideByScalar = (k: InputValue<Fraction>): this => {
122
+ return this.multiplyByScalar(new Fraction(k).inverse())
123
+ }
124
+
125
+ dot = (V: Vector |Point): Fraction => {
126
+ return dotProduct(this, V)
127
+ }
128
+
129
+ override fromString(value: string): this {
130
+ if (value.startsWith('((') && value.endsWith('))')) {
131
+ return super.fromString(value.slice(1, -1))
132
+ }
133
+
134
+ return super.fromString(value)
135
+ }
136
+
137
+ isColinearTo = (v: Vector): boolean => {
138
+ return areVectorsColinears(this, v)
139
+ }
140
+
141
+ isEqual = (v: Vector): boolean => {
142
+ return areVectorsEquals(this, v)
143
+ }
144
+
145
+ isNormalTo = (v: Vector): boolean => {
146
+ return this.dot(v).isZero()
147
+ }
148
+
149
+ // ------------------------------------------
150
+ get isNull(): boolean {
151
+ return this.array.every(x => x.isZero())
152
+ }
153
+
154
+ isOne(): boolean {
155
+ return this.array.every((x, index) => index === 0 ? x.isOne() : x.isZero())
156
+ }
157
+
158
+ isZero(): boolean {
159
+ return this.array.every(x => x.isZero())
160
+ }
161
+
162
+ multiplyByScalar = (k: InputValue<Fraction>): this => {
163
+ const scalar = new Fraction(k)
164
+ this.array.forEach(x => x.multiply(scalar))
165
+ return this
166
+ }
167
+
168
+ get norm(): number {
169
+ return Math.sqrt(this.normSquare.value)
170
+ }
171
+
172
+ get normSquare(): Fraction {
173
+ // Get the norm square of the vector
174
+ return this.array.reduce((acc, x) => acc.add(x.clone().pow(2)), new Fraction(0))
175
+ }
176
+
177
+ normal = (): this => {
178
+ if (this.dimension >= 3) {
179
+ throw new DimensionError('Normal vector can only be determined in 2D')
180
+ }
181
+
182
+ const x = this.x.clone().opposite()
183
+ const y = this.y.clone()
184
+
185
+ this.array[0] = y
186
+ this.array[1] = x
187
+ return this
188
+ }
189
+
190
+ one = (): this => {
191
+ this.zero()
192
+ this.x.one()
193
+ return this
194
+ }
195
+
196
+ opposite = (): this => {
197
+ this.array.forEach(x => x.opposite())
198
+ return this
199
+ }
200
+
201
+ simplify = (): this => {
202
+ const lcm = Numeric.lcm(...this.array.map(x => x.denominator))
203
+ const gcd = Numeric.gcd(...this.array.map(x => x.numerator))
204
+
205
+ this.multiplyByScalar(new Fraction(lcm, gcd))
206
+
207
+ if(this.x.isNegative()) this.opposite()
208
+
209
+ return this
210
+ }
211
+
212
+ subtract = (V: Vector): this => {
213
+ return this.add(V.clone().opposite())
214
+ }
215
+
216
+ translate(...values: Fraction[]): this {
217
+ this.array.forEach((x, index) => x.add(values[index]))
218
+ return this
219
+ }
220
+
221
+ unit = (): this => {
222
+ const norm = this.norm
223
+ if (norm === 0) {
224
+ return this
225
+ }
226
+
227
+ return this.divideByScalar(norm)
228
+ }
229
+
230
+ }