pimath 0.0.24 → 0.0.28

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 (127) hide show
  1. package/dev/demo.css +3 -0
  2. package/dev/index.html +220 -54
  3. package/dev/pi.js +573 -216
  4. package/dev/pi.js.map +1 -1
  5. package/dist/pi.js +1 -1
  6. package/dist/pi.js.map +1 -1
  7. package/docs/assets/search.js +1 -1
  8. package/docs/classes/algebra.Equation.html +11 -13
  9. package/docs/classes/algebra.LinearSystem.html +1 -1
  10. package/docs/classes/algebra.Logicalset.html +3 -3
  11. package/docs/classes/algebra.Monom.html +50 -49
  12. package/docs/classes/algebra.Polynom.html +12 -25
  13. package/docs/classes/algebra.Rational.html +3 -3
  14. package/docs/classes/coefficients.Fraction.html +10 -6
  15. package/docs/classes/coefficients.Nthroot.html +3 -1
  16. package/docs/classes/geometry.Circle.html +3 -1
  17. package/docs/classes/geometry.Line.html +3 -1
  18. package/docs/classes/geometry.Point.html +1 -1
  19. package/docs/classes/geometry.Triangle.html +6 -6
  20. package/docs/classes/geometry.Vector.html +1 -1
  21. package/docs/classes/numeric.Numeric.html +5 -5
  22. package/docs/classes/shutingyard.Shutingyard.html +5 -5
  23. package/docs/index.html +1 -1
  24. package/docs/interfaces/geometry.remarquableLines.html +1 -1
  25. package/docs/modules/algebra.html +1 -1
  26. package/docs/modules/coefficients.html +1 -1
  27. package/docs/modules/geometry.html +1 -1
  28. package/docs/modules/numeric.html +1 -1
  29. package/docs/modules/random.Random.html +1 -1
  30. package/docs/modules/random.html +1 -1
  31. package/docs/modules/shutingyard.html +1 -1
  32. package/docs/modules.html +1 -1
  33. package/esm/main.js +2 -0
  34. package/esm/main.js.map +1 -1
  35. package/esm/maths/algebra/equation.d.ts +11 -5
  36. package/esm/maths/algebra/equation.js +159 -52
  37. package/esm/maths/algebra/equation.js.map +1 -1
  38. package/esm/maths/algebra/linearSystem.d.ts +3 -4
  39. package/esm/maths/algebra/linearSystem.js +2 -5
  40. package/esm/maths/algebra/linearSystem.js.map +1 -1
  41. package/esm/maths/algebra/logicalset.d.ts +2 -2
  42. package/esm/maths/algebra/logicalset.js +1 -1
  43. package/esm/maths/algebra/logicalset.js.map +1 -1
  44. package/esm/maths/algebra/monom.d.ts +5 -3
  45. package/esm/maths/algebra/monom.js +29 -2
  46. package/esm/maths/algebra/monom.js.map +1 -1
  47. package/esm/maths/algebra/polynom.d.ts +6 -6
  48. package/esm/maths/algebra/polynom.js +4 -4
  49. package/esm/maths/algebra/polynom.js.map +1 -1
  50. package/esm/maths/algebra/rational.d.ts +1 -1
  51. package/esm/maths/algebra/rational.js +2 -2
  52. package/esm/maths/algebra/rational.js.map +1 -1
  53. package/esm/maths/coefficients/fraction.d.ts +2 -2
  54. package/esm/maths/coefficients/fraction.js +1 -1
  55. package/esm/maths/coefficients/fraction.js.map +1 -1
  56. package/esm/maths/coefficients/nthroot.d.ts +1 -1
  57. package/esm/maths/coefficients/nthroot.js +4 -1
  58. package/esm/maths/coefficients/nthroot.js.map +1 -1
  59. package/esm/maths/geometry/circle.d.ts +12 -3
  60. package/esm/maths/geometry/circle.js +125 -39
  61. package/esm/maths/geometry/circle.js.map +1 -1
  62. package/esm/maths/geometry/line.d.ts +1 -2
  63. package/esm/maths/geometry/line.js +0 -3
  64. package/esm/maths/geometry/line.js.map +1 -1
  65. package/esm/maths/geometry/point.d.ts +3 -4
  66. package/esm/maths/geometry/point.js +18 -15
  67. package/esm/maths/geometry/point.js.map +1 -1
  68. package/esm/maths/geometry/triangle.d.ts +0 -1
  69. package/esm/maths/geometry/triangle.js +3 -4
  70. package/esm/maths/geometry/triangle.js.map +1 -1
  71. package/esm/maths/geometry/vector.js +2 -1
  72. package/esm/maths/geometry/vector.js.map +1 -1
  73. package/esm/maths/numexp.d.ts +16 -0
  74. package/esm/maths/numexp.js +116 -0
  75. package/esm/maths/numexp.js.map +1 -0
  76. package/esm/maths/random/rndFraction.js +4 -3
  77. package/esm/maths/random/rndFraction.js.map +1 -1
  78. package/esm/maths/random/rndMonom.d.ts +1 -1
  79. package/esm/maths/random/rndMonom.js +12 -7
  80. package/esm/maths/random/rndMonom.js.map +1 -1
  81. package/esm/maths/random/rndPolynom.js +8 -2
  82. package/esm/maths/random/rndPolynom.js.map +1 -1
  83. package/esm/maths/random/rndTypes.d.ts +3 -1
  84. package/esm/maths/shutingyard.d.ts +21 -4
  85. package/esm/maths/shutingyard.js +72 -74
  86. package/esm/maths/shutingyard.js.map +1 -1
  87. package/package.json +3 -5
  88. package/src/main.ts +2 -0
  89. package/src/maths/algebra/equation.ts +183 -73
  90. package/src/maths/algebra/linearSystem.ts +262 -265
  91. package/src/maths/algebra/logicalset.ts +3 -3
  92. package/src/maths/algebra/monom.ts +54 -35
  93. package/src/maths/algebra/polynom.ts +10 -10
  94. package/src/maths/algebra/rational.ts +1 -1
  95. package/src/maths/coefficients/fraction.ts +11 -7
  96. package/src/maths/coefficients/nthroot.ts +8 -1
  97. package/src/maths/geometry/circle.ts +160 -45
  98. package/src/maths/geometry/line.ts +1 -5
  99. package/src/maths/geometry/point.ts +25 -18
  100. package/src/maths/geometry/triangle.ts +3 -5
  101. package/src/maths/geometry/vector.ts +4 -3
  102. package/src/maths/numexp.ts +136 -0
  103. package/src/maths/random/rndFraction.ts +4 -3
  104. package/src/maths/random/rndMonom.ts +39 -35
  105. package/src/maths/random/rndPolynom.ts +13 -3
  106. package/src/maths/random/rndTypes.ts +4 -2
  107. package/src/maths/shutingyard.ts +144 -94
  108. package/tests/algebra/monom.test.ts +18 -4
  109. package/tests/algebra/polynom.test.ts +19 -4
  110. package/tests/geometry/circle.test.ts +28 -0
  111. package/tests/shutingyard.test.ts +3 -3
  112. package/tsconfig.json +4 -1
  113. package/typedoc.katex.js +11 -0
  114. package/docs/classes/algebra.Algebra.Equation.html +0 -26
  115. package/docs/classes/algebra.Algebra.LinearSystem.html +0 -1
  116. package/docs/classes/algebra.Algebra.LogicalSet.html +0 -3
  117. package/docs/classes/algebra.Algebra.Monom.html +0 -111
  118. package/docs/classes/algebra.Algebra.Polynom.html +0 -36
  119. package/docs/classes/algebra.Algebra.Rational.html +0 -2
  120. package/docs/classes/geometry.Geometry.Circle.html +0 -1
  121. package/docs/classes/geometry.Geometry.Line.html +0 -1
  122. package/docs/classes/geometry.Geometry.Point.html +0 -1
  123. package/docs/classes/geometry.Geometry.Triangle.html +0 -9
  124. package/docs/classes/geometry.Geometry.Vector.html +0 -1
  125. package/docs/modules/algebra.Algebra.html +0 -1
  126. package/docs/modules/geometry.Geometry.html +0 -1
  127. package/src/maths/algebra/monom_bck.backup +0 -746
@@ -2,15 +2,22 @@
2
2
  * Vector module contains everything necessary to handle 2d or 3d vectors.
3
3
  * @module Vector
4
4
  */
5
- import {Fraction} from "../coefficients/fraction";
5
+ import {Fraction} from "../coefficients"
6
+
7
+ /**
8
+ * Helper class - a way to identify an object {x: number, y: number}
9
+ */
10
+ class PointXY {
11
+ public x: number
12
+ public y: number
13
+ }
6
14
 
7
- //TODO: Ajouter une vérification si la droite existe.
8
15
  export class Point {
9
16
  private _x: Fraction; // 1st component
10
17
  private _y: Fraction; // 2nd component
11
18
  private _exist: Boolean;
12
19
 
13
- constructor(...values: any) {
20
+ constructor(...values: unknown[]) {
14
21
  this._x = new Fraction().zero();
15
22
  this._y = new Fraction().zero();
16
23
 
@@ -21,10 +28,6 @@ export class Point {
21
28
  return this
22
29
  };
23
30
 
24
- get isPoint() {
25
- return true;
26
- }
27
-
28
31
  // ------------------------------------------
29
32
  // Getter and setter
30
33
  // ------------------------------------------
@@ -66,7 +69,8 @@ export class Point {
66
69
  // Creation / parsing functions
67
70
  // ------------------------------------------
68
71
 
69
- parse = (...values: any): Point => {
72
+
73
+ parse = (...values: unknown[]): Point => {
70
74
  // Initialize the value.
71
75
  this.zero();
72
76
 
@@ -81,30 +85,33 @@ export class Point {
81
85
  if (values[0] instanceof Point) {
82
86
  this._x = values[0].x.clone()
83
87
  this._y = values[0].y.clone()
84
- return this;
88
+ return this
85
89
  }
86
90
 
87
91
  // Value is given as string, comma separated.
88
- if(typeof values[0] === 'string'){
92
+ if (typeof values[0] === 'string') {
89
93
  let xy = values[0].split(',')
90
- if(xy.length===2){
94
+ if (xy.length === 2) {
91
95
  this._x = new Fraction(xy[0]).reduce()
92
96
  this._y = new Fraction(xy[1]).reduce()
93
- return this;
97
+ return this
94
98
  }
95
99
  }
96
100
 
97
101
  // Value given as an object with {x: value, y: value}
98
- if (values[0].x !== undefined && values[0].y !== undefined) {
99
- this._x = new Fraction(values[0].x).reduce()
100
- this._y = new Fraction(values[0].y).reduce()
102
+ if(values[0] instanceof PointXY){
103
+ this._x = new Fraction(values[0].x).reduce()
104
+ this._y = new Fraction(values[0].y).reduce()
105
+ return this
101
106
  } else {
102
- return this.zero();
107
+ return this.zero()
103
108
  }
104
109
  }
110
+
105
111
  if (values.length === 2) {
106
112
  this._x = new Fraction(values[0]).reduce()
107
113
  this._y = new Fraction(values[1]).reduce()
114
+ return this
108
115
  }
109
116
 
110
117
  return this;
@@ -140,8 +147,8 @@ export class Point {
140
147
  texValues = (numberOfDigits: number): string => {
141
148
  let pts = [];
142
149
 
143
- pts.push(this._x.value.toFixed(numberOfDigits===undefined?2:numberOfDigits));
144
- pts.push(this._y.value.toFixed(numberOfDigits===undefined?2:numberOfDigits));
150
+ pts.push(this._x.value.toFixed(numberOfDigits === undefined ? 2 : numberOfDigits));
151
+ pts.push(this._y.value.toFixed(numberOfDigits === undefined ? 2 : numberOfDigits));
145
152
 
146
153
  return `\\left(${pts.join(';')}\\right)`
147
154
  }
@@ -56,8 +56,6 @@ export class Triangle {
56
56
  return this;
57
57
  }
58
58
 
59
- get isTriangle():boolean {return true;}
60
-
61
59
  // ------------------------------------------
62
60
  // Getter and setters
63
61
  // ------------------------------------------
@@ -158,7 +156,7 @@ export class Triangle {
158
156
  // - Three lines as text.
159
157
  if(values.filter((x:any) => typeof x === 'string').length===3) {
160
158
  return this.parse( ...values.map((x:string) => new Line(x)) )
161
- }else if(values.filter((x:any) => x.isLine === true).length===3) {
159
+ }else if(values.filter((x:any) => x instanceof Line).length===3) {
162
160
  // We have three lines
163
161
  this._lines = {
164
162
  'AB': values[0],
@@ -187,7 +185,7 @@ export class Triangle {
187
185
  }
188
186
  }else {
189
187
  // At least, one of the value is not a point.
190
- if (values.filter((x: any) => x.isPoint === true).length < 3) {
188
+ if (values.filter((x: any) => (x instanceof Point)).length < 3) {
191
189
  return this.parse(
192
190
  new Point(values[0]),
193
191
  new Point(values[1]),
@@ -207,7 +205,7 @@ export class Triangle {
207
205
  };
208
206
  }
209
207
  } else if (values.length === 1) {
210
- if (values[0].isTriangle === true) {
208
+ if (values[0] instanceof Triangle) {
211
209
  return values[0].clone();
212
210
  }
213
211
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import {Fraction} from "../coefficients/fraction";
6
6
  import {Numeric} from "../numeric";
7
+ import {Point} from "./point";
7
8
 
8
9
  export class Vector {
9
10
  private _x: Fraction; // 1st component
@@ -73,7 +74,7 @@ export class Vector {
73
74
 
74
75
  if (values.length >= 2) {
75
76
  // Two points are given - skip the third value.
76
- if (values[0].isPoint && values[1].isPoint) {
77
+ if (values[0] instanceof Point && values[1] instanceof Point) {
77
78
  this._x = values[1].x.clone().subtract(values[0].x)
78
79
  this._y = values[1].y.clone().subtract(values[0].y)
79
80
  return this;
@@ -159,7 +160,7 @@ export class Vector {
159
160
 
160
161
  static scalarProduct = (v1: Vector, v2: Vector): number => {
161
162
  // TODO: Transform to fraction with nthroot.
162
- return v1.x.value * v2.x.value + v1.y.value * v2.y.value;
163
+ return v1.x.value * v2.x.value + v1.y.value * v2.y.value;
163
164
  };
164
165
 
165
166
  normal = (): Vector => {
@@ -180,7 +181,7 @@ export class Vector {
180
181
  return this;
181
182
  }
182
183
 
183
- divideByScalar = (k:any): Vector => {
184
+ divideByScalar = (k: any): Vector => {
184
185
  return this.multiplyByScalar(new Fraction(k).invert());
185
186
  }
186
187
  // ------------------------------------------
@@ -0,0 +1,136 @@
1
+ import {Shutingyard, ShutingyardMode, ShutingyardType, tokenConstant} from "./shutingyard";
2
+ import {Fraction} from "./coefficients";
3
+
4
+ export class NumExp {
5
+ private _rpn: { token: string, tokenType: string }[]
6
+ private _expression: string
7
+
8
+ constructor(value: string) {
9
+ this._expression = value
10
+ this._rpn = new Shutingyard(ShutingyardMode.NUMERIC).parse(value).rpn
11
+ }
12
+
13
+ get rpn(): { token: string; tokenType: string }[] {
14
+ return this._rpn;
15
+ }
16
+
17
+ get expression(): string {
18
+ return this._expression;
19
+ }
20
+
21
+ private _extractDecimalPart(value: number): string {
22
+ let decimal = value.toString()
23
+
24
+ if (!decimal.includes('.')) {
25
+ return ''
26
+ }
27
+
28
+ decimal = decimal.split('.')[1]
29
+
30
+ return decimal.substring(0, decimal.length - 2)
31
+ }
32
+
33
+ private _numberCorrection(value: number): number {
34
+ // Must modify the number if it's like:
35
+ // a: 3.0000000000000003
36
+ // b: 3.9999999999999994
37
+ // remove the last character
38
+ // check if around n last characters are either 0 or 9
39
+ // if it is, 'round' the number.
40
+
41
+ const epsilon = 0.00000000000001,
42
+ number_of_digits = 6
43
+
44
+ let decimal = this._extractDecimalPart(value)
45
+ if(decimal===''){return value}
46
+
47
+ const n9 = decimal.match(/9+$/g)
48
+ const n0 = decimal.match(/0+$/g)
49
+
50
+ if (n9 && n9[0].length >= number_of_digits) {
51
+ // New tested values.
52
+ let mod = this._extractDecimalPart(value + epsilon),
53
+ mod0 = mod.match(/0+$/g)
54
+
55
+ if(mod0 && mod0[0].length>= number_of_digits){
56
+ // The value can be changed. Remove all zeros!
57
+ return +((value+epsilon).toString().split(mod0[0])[0])
58
+ }
59
+ }
60
+
61
+ if (n0 && n0[0].length >= number_of_digits) {
62
+ // New tested values.
63
+ let mod = this._extractDecimalPart(value - epsilon),
64
+ mod9 = mod.match(/9+$/g)
65
+
66
+ if(mod9 && mod9[0].length>= number_of_digits){
67
+ // The value can be changed. Remove all nines!
68
+ return +(value.toString().split(n0[0])[0])
69
+ }
70
+ }
71
+
72
+ return value
73
+ }
74
+
75
+ private _addToStack(stack:number[], value: number): void {
76
+ stack.push(this._numberCorrection(value))
77
+ }
78
+
79
+ evaluate(values: { [Key: string]: number }): number {
80
+ let stack: number[] = []
81
+ for (const element of this._rpn) {
82
+ if (element.tokenType === ShutingyardType.COEFFICIENT) {
83
+ // May be a numeric value or a Fraction.
84
+ if (!isNaN(+element.token)) {
85
+ this._addToStack(stack, +element.token)
86
+ } else {
87
+ this._addToStack(stack, new Fraction(element.token).value)
88
+ }
89
+ } else if (element.tokenType === ShutingyardType.VARIABLE) {
90
+ if (values[element.token] !== undefined) {
91
+ this._addToStack(stack, +values[element.token])
92
+ }
93
+ } else if (element.tokenType === ShutingyardType.CONSTANT) {
94
+ this._addToStack(stack, tokenConstant[element.token])
95
+ } else if (element.tokenType === ShutingyardType.OPERATION) {
96
+ if (element.token === '*') {
97
+ const b = +stack.pop(),
98
+ a = +stack.pop()
99
+ this._addToStack(stack, a * b)
100
+ } else if (element.token === '/') {
101
+ const b = +stack.pop(),
102
+ a = +stack.pop()
103
+ this._addToStack(stack, a / b)
104
+ } else if (element.token === '+') {
105
+ const b = +stack.pop(),
106
+ a = +stack.pop()
107
+ this._addToStack(stack, a + b)
108
+ } else if (element.token === '-') {
109
+ const b = +stack.pop(),
110
+ a = +stack.pop()
111
+ this._addToStack(stack, a - b)
112
+ } else if (element.token === '^') {
113
+ const b = +stack.pop(),
114
+ a = +stack.pop()
115
+ this._addToStack(stack, Math.pow(a, b))
116
+ }
117
+ } else if (element.tokenType === ShutingyardType.FUNCTION) {
118
+ const a = +stack.pop()
119
+ if (element.token === 'sin') {
120
+ this._addToStack(stack, Math.sin(a))
121
+ } else if (element.token === 'cos') {
122
+ this._addToStack(stack, Math.cos(a))
123
+ } else if (element.token === 'tan') {
124
+ this._addToStack(stack, Math.tan(a))
125
+ }
126
+ }
127
+ }
128
+
129
+ if (stack.length === 1) {
130
+ return stack[0]
131
+ } else {
132
+ console.error('There was a problem parsing', this._expression, '. The RPN array is', this._rpn)
133
+ return 0
134
+ }
135
+ }
136
+ }
@@ -15,6 +15,7 @@ export class rndFraction extends randomCore {
15
15
 
16
16
  this._defaultConfig = {
17
17
  negative: true,
18
+ max: 10,
18
19
  reduced: true,
19
20
  zero: true,
20
21
  natural: false
@@ -27,14 +28,14 @@ export class rndFraction extends randomCore {
27
28
  let Q = new Fraction()
28
29
 
29
30
  if(this._config.negative){
30
- Q.numerator = Random.numberSym(10, this._config.zero)
31
+ Q.numerator = Random.numberSym(this._config.max, this._config.zero)
31
32
  }else {
32
- Q.numerator = Random.number(this._config.zero ? 0 : 1, 10)
33
+ Q.numerator = Random.number(this._config.zero ? 0 : 1, this._config.max)
33
34
  }
34
35
  if(this._config.natural){
35
36
  Q.denominator = 1
36
37
  }else {
37
- Q.denominator = Random.number(1, 10)
38
+ Q.denominator = Random.number(1, this._config.max)
38
39
  }
39
40
 
40
41
  return this._config.reduced?Q.reduce():Q
@@ -1,53 +1,57 @@
1
1
  import {randomCore} from "./randomCore";
2
- import {randomMonomConfig, randomPolynomConfig} from "./rndTypes";
2
+ import {randomMonomConfig} from "./rndTypes";
3
3
  import {Random} from "./index";
4
- import {Monom} from "../algebra/monom";
4
+ import {Monom} from "../algebra";
5
5
 
6
6
  /**
7
7
  * Create a random monom based on a based configuration
8
8
  */
9
- export class rndMonom extends randomCore {
10
- declare protected _config: randomMonomConfig
11
- declare protected _defaultConfig: randomMonomConfig
12
-
13
- constructor(userConfig?: randomMonomConfig) {
14
- super();
15
-
16
- this._defaultConfig = {
17
- letters: 'x',
18
- degree: 2,
19
- fraction: true,
20
- zero: false
21
- }
22
-
23
- this._config = this.mergeConfig(userConfig, this._defaultConfig)
9
+ export class rndMonom extends randomCore {
10
+ declare protected _config: randomMonomConfig
11
+ declare protected _defaultConfig: randomMonomConfig
12
+
13
+ constructor(userConfig?: randomMonomConfig) {
14
+ super();
15
+
16
+ this._defaultConfig = {
17
+ letters: 'x',
18
+ degree: 2,
19
+ fraction: true,
20
+ zero: false
24
21
  }
25
22
 
26
- generate = (): Monom => {
27
- // Create a monom instance
28
- let M = new Monom()
23
+ this._config = this.mergeConfig(userConfig, this._defaultConfig)
24
+ }
25
+
26
+ generate = (): Monom => {
27
+ // Create a monom instance
28
+ let M = new Monom()
29
29
 
30
- // Generate the coefficient
30
+ // Generate the coefficient
31
+ if (typeof this._config.fraction === "boolean") {
31
32
  M.coefficient = Random.fraction({
32
33
  zero: this._config.zero,
33
34
  reduced: true,
34
35
  natural: !this._config.fraction
35
36
  })
37
+ } else {
38
+ M.coefficient = Random.fraction(this._config.fraction)
39
+ }
36
40
 
37
- // Calculate the degree of the monom
38
- if (this._config.letters.length > 1) {
39
- // Initialise each items...
40
- for (let L of this._config.letters.split('')) {
41
- M.setLetter(L, 0);
42
- }
43
- for (let i = 0; i < this._config.degree; i++) {
44
- const L = Random.item(this._config.letters.split(""))
45
- M.setLetter(L, M.degree(L).clone().add(1))
46
- }
47
- } else {
48
- M.setLetter(this._config.letters, this._config.degree)
41
+ // Calculate the degree of the monom
42
+ if (this._config.letters.length > 1) {
43
+ // Initialise each items...
44
+ for (let L of this._config.letters.split('')) {
45
+ M.setLetter(L, 0);
49
46
  }
50
-
51
- return M
47
+ for (let i = 0; i < this._config.degree; i++) {
48
+ const L = Random.item(this._config.letters.split(""))
49
+ M.setLetter(L, M.degree(L).clone().add(1))
50
+ }
51
+ } else {
52
+ M.setLetter(this._config.letters, this._config.degree)
52
53
  }
54
+
55
+ return M
53
56
  }
57
+ }
@@ -24,7 +24,8 @@ export class rndPolynom extends randomCore {
24
24
  unit: false,
25
25
  factorable: false,
26
26
  allowNullMonom: true,
27
- numberOfMonoms: 0
27
+ numberOfMonoms: 0,
28
+ positive: true
28
29
  }
29
30
 
30
31
  // Merge config with initialiser
@@ -39,6 +40,7 @@ export class rndPolynom extends randomCore {
39
40
  // Create the polynom
40
41
  let P = new Polynom().empty(),
41
42
  M: Monom
43
+
42
44
  for (let i = this._config.degree; i >= 0; i--) {
43
45
  // Create monom of corresponding degree.
44
46
  M = new rndMonom({
@@ -57,9 +59,17 @@ export class rndPolynom extends randomCore {
57
59
  P.add(M)
58
60
  }
59
61
 
60
- // If the number of monoms is greater than the allowed value, remove some of them...
62
+ // Make sure the first monom is positive.
63
+ if(this._config.positive && P.monomByDegree().coefficient.isNegative()){
64
+ P.monomByDegree().coefficient.opposed()
65
+ }
66
+
67
+ // If the number of monoms is greater than the allowed value, remove some of them... except the first one !
61
68
  if (this._config.numberOfMonoms > 0 && this._config.numberOfMonoms < P.length) {
62
- P.monoms = Random.array(P.monoms, this._config.numberOfMonoms)
69
+ // Get the greatest degree monom
70
+ let M = P.monomByDegree().clone()
71
+ P.monoms = Random.array(P.monoms.slice(1), this._config.numberOfMonoms-1)
72
+ P.add(M).reorder().reduce()
63
73
  }
64
74
  return P
65
75
  }
@@ -1,5 +1,6 @@
1
1
  export type randomCoefficientConfig = {
2
2
  negative?: boolean,
3
+ max?: number,
3
4
  reduced?: boolean,
4
5
  zero?:boolean,
5
6
  natural?:boolean
@@ -8,7 +9,7 @@ export type randomCoefficientConfig = {
8
9
  export type randomMonomConfig = {
9
10
  letters?: string,
10
11
  degree?: number,
11
- fraction?: boolean,
12
+ fraction?: boolean|randomCoefficientConfig,
12
13
  zero?: boolean
13
14
  }
14
15
 
@@ -16,5 +17,6 @@ export type randomPolynomConfig = randomMonomConfig & {
16
17
  unit?: boolean,
17
18
  factorable?: boolean,
18
19
  allowNullMonom?: boolean,
19
- numberOfMonoms?: number
20
+ numberOfMonoms?: number,
21
+ positive?: boolean
20
22
  }