Skip to content

Commit 524ef06

Browse files
committed
made numerical integrals work once again from the parser, fixed all updateArgs issues also.
1 parent d2a8d91 commit 524ef06

13 files changed

Lines changed: 574 additions & 702 deletions

File tree

‎BENCHMARK_RESULTS.md‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
### Results
1111

12+
Real JMH benchmarks
13+
14+
#### 1
1215
```
1316
Benchmark Test 1 (2GB Heap) Test 2 (Default) Winner
1417
────────────────────────────────────────────────────────────────
@@ -19,9 +22,24 @@ Speedup Factor 4.1x 3.36x
1922
Consistency (σ) 25 ns (tight) 206 ns (loose) ✅
2023
```
2124

25+
#### 2 `(7*x+y)-(3*x*y+4*x)-(4*x-5*y)/(3*x^2-5*y^3)`
26+
27+
```
28+
Benchmark Mode Cnt Score Error Units
29+
ParserNGWars.exp4j avgt 10 687.698 ± 7.916 ns/op
30+
ParserNGWars.parserNg avgt 10 292.933 ± 11.497 ns/op
31+
```
32+
33+
34+
#### 3. `sin(7*x+y)+cos(7*x-y)`
35+
```
36+
Benchmark Mode Cnt Score Error Units
37+
ParserNGWars.exp4j avgt 10 362.020 � 15.825 ns/op
38+
ParserNGWars.parserNg avgt 10 192.830 � 9.271 ns/op
39+
```
2240
### Key Insights
2341

24-
1. **ParserNG is 3-4x faster** across all heap configurations
42+
1. **ParserNG is 2-4x faster** across all heap configurations
2543
2. **ParserNG is 20x more consistent** (tight error bounds)
2644
3. **ParserNG scales better** with available memory
2745
4. **GC pressure minimal** - low object allocation
@@ -50,4 +68,4 @@ mvn clean install -DskipTests
5068
java -Xms2g -Xmx2g -jar target/benchmarks.jar
5169
```
5270

53-
Expected result: ParserNG 3-4x faster than Exp4J.
71+
Expected result: ParserNG 2-4x faster than Exp4J.

‎README.md‎

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,10 @@ This obviously will make graphing and other iterative tasks super responsive.
1515
ParserNG v0.2.4 is an extremely feature rich math tool which also doubles as (arguably) the fastest pure Java expression evaluator on the planet.
1616
In benchmarks, it beats com.expression.parser(Java Math Expression Parser) by almost (10x-14x) and edges out Exp4J (which is lightweight) in many benchmarks.
1717

18-
#### Here are some benchmarks
1918

20-
##### 1. (sin(3) + cos(4 - sin(2))) ^ (-2)
21-
```
22-
Benchmark Mode Cnt Score Error Units
23-
ParserNGWars.exp4j avgt 10 184.211 ± 10.622 ns/op
24-
ParserNGWars.parserNg avgt 10 175.858 ± 6.081 ns/op
25-
```
26-
27-
#### 2. ((12+5)*3 - (45/9))^2
28-
```
29-
Benchmark Mode Cnt Score Error Units
30-
ParserNGWars.exp4j avgt 10 102.845 ± 23.153 ns/op
31-
ParserNGWars.parserNg avgt 10 85.417 ± 4.763 ns/op
32-
```
19+
ParserNG 0.2.5 features strength reduction, constant folding and execution frame(array) based args passing(in contrast to Map based) to ensure O(1) complexity in passage of args to the evaluation stage.
20+
21+
[Here are a few benchmarks here](./BENCHMARK_RESULTS.md)
3322

3423
<br>
3524

‎pom.xml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.github.gbenroscience</groupId>
55
<artifactId>parser-ng</artifactId>
6-
<version>0.2.4</version>
6+
<version>0.2.5</version>
77
<packaging>jar</packaging>
88
<!--
99
I started this project 2009 and have been upgrading it since then.
@@ -12,7 +12,7 @@
1212
-->
1313

1414
<name>ParserNG</name>
15-
<description>Rich and Performant, Cross Platform Java Library(100% Java)... Major speed bump, by inner loop optimizations Consider donations through my Github Sponsor at
15+
<description>Rich and Performant, Cross Platform Java Library(100% Java)... Major optimizations in constant folding, strength reduction, and frame(array) based argument passing to enforce O(1) (faster than Map based) passing of arguments during the evaluation phase.
1616
</description>
1717
<url>https://github.com/gbenroscience/ParserNG</url>
1818

‎src/main/java/com/github/gbenroscience/math/matrix/expressParser/Matrix.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private Matrix(String name, int rows, int cols) {
7979

8080
/**
8181
*
82-
* @param array the 2D data supplied as a 1D array used to create this
82+
* @param flatArray the 2D data supplied as a 1D array used to create this
8383
* @param rows
8484
* @param columns Matrix object
8585
*/

‎src/main/java/com/github/gbenroscience/math/numericalmethods/Integration.java‎

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ public class Integration{
7070
private boolean setIntegration = false; // = true when integration performed
7171

7272
// ArrayLists to hold Gauss-Legendre Coefficients saving repeated calculation
73-
private static ArrayList<Integer> gaussQuadIndex = new ArrayList<Integer>(); // Gauss-Legendre indices
74-
private static ArrayList<double[]> gaussQuadDistArrayList = new ArrayList<double[]>(); // Gauss-Legendre distances
75-
private static ArrayList<double[]> gaussQuadWeightArrayList = new ArrayList<double[]>();// Gauss-Legendre weights
73+
private static ArrayList<Integer> gaussQuadIndex = new ArrayList<>(); // Gauss-Legendre indices
74+
private static ArrayList<double[]> gaussQuadDistArrayList = new ArrayList<>(); // Gauss-Legendre distances
75+
private static ArrayList<double[]> gaussQuadWeightArrayList = new ArrayList<>();// Gauss-Legendre weights
7676

7777
// Iterative trapezium rule
7878
private double requiredAccuracy = 0.0D; // required accuracy at which iterative trapezium is terminated
@@ -207,16 +207,17 @@ public double gaussQuad(){
207207

208208
// Perform summation
209209
for(int i=0; i<glPoints; i++){
210-
dx = xminus*gaussQuadDist[i];
211-
sum += gaussQuadWeight[i]*this.function.calc(xplus+dx);
210+
dx = xminus*gaussQuadDist[i];
211+
this.function.updateArgs(xplus+dx);
212+
sum += gaussQuadWeight[i]*this.function.calc();
212213
}
213214
this.integralSum = sum*xminus; // rescale
214215
this.setIntegration = true; // integration performed
215216
return this.integralSum; // return value
216217
}
217218

218219
// Numerical integration using n point Gaussian-Legendre quadrature (instance method)
219-
// All parametes except the number of points in the Gauss-Legendre integration preset
220+
// All parameters except the number of points in the Gauss-Legendre integration preset
220221
public double gaussQuad(int glPoints){
221222
this.glPoints = glPoints;
222223
this.setGLpoints = true;
@@ -291,18 +292,19 @@ public double trapezium(){
291292
double interval = (this.upperLimit - this.lowerLimit)/this.nIntervals;
292293
double x0 = this.lowerLimit;
293294
double x1 = this.lowerLimit + interval;
294-
double y0 = this.function.calc(x0);
295+
this.function.updateArgs(x0);
296+
double y0 = this.function.calc();
295297
this.integralSum = 0.0D;
296298

297299
for(int i=0; i<nIntervals; i++){
298300
// adjust last interval for rounding errors
299301
if(x1>this.upperLimit){
300302
x1 = this.upperLimit;
301303
interval -= (x1 - this.upperLimit);
302-
}
303-
304+
}
305+
this.function.updateArgs(x1);
304306
// perform summation
305-
y1 = this.function.calc(x1);
307+
y1 = this.function.calc();
306308
this.integralSum += 0.5D*(y0+y1)*interval;
307309
x0 = x1;
308310
y0 = y1;
@@ -395,7 +397,8 @@ public double backward(){
395397

396398
double interval = (this.upperLimit - this.lowerLimit)/this.nIntervals;
397399
double x = this.lowerLimit + interval;
398-
double y = this.function.calc(x);
400+
this.function.updateArgs(x);
401+
double y = this.function.calc();
399402
this.integralSum = 0.0D;
400403

401404
for(int i=0; i<this.nIntervals; i++){
@@ -404,9 +407,9 @@ public double backward(){
404407
x = this.upperLimit;
405408
interval -= (x - this.upperLimit);
406409
}
407-
410+
this.function.updateArgs(x);
408411
// perform summation
409-
y = this.function.calc(x);
412+
y = this.function.calc();
410413
this.integralSum += y*interval;
411414
x += interval;
412415
}
@@ -438,7 +441,8 @@ public double forward(){
438441

439442
double interval = (this.upperLimit - this.lowerLimit)/this.nIntervals;
440443
double x = this.lowerLimit;
441-
double y = this.function.calc(x);
444+
this.function.updateArgs(x);
445+
double y = this.function.calc();
442446
this.integralSum = 0.0D;
443447

444448
for(int i=0; i<this.nIntervals; i++){
@@ -447,9 +451,9 @@ public double forward(){
447451
x = this.upperLimit;
448452
interval -= (x - this.upperLimit);
449453
}
450-
454+
this.function.updateArgs(x);
451455
// perform summation
452-
y = this.function.calc(x);
456+
y = this.function.calc();
453457
this.integralSum += y*interval;
454458
x += interval;
455459
}
@@ -481,13 +485,13 @@ public static double foreward(Function integralFunc, double lowerLimit, double u
481485

482486
public static void main(String[] args) {
483487

484-
Function func = new Function("y=@(x)1/(x^2+1)");
485-
Integration intg = new Integration(func, 2, 30);
488+
Function func = new Function("y=@(x)sin(x)-cos(x)");
489+
Integration intg = new Integration(func, 2, 3);
486490
intg.gaussQuad(20);
487491
System.err.println("The value "+intg.getIntegralSum() );
488492

489493

490-
494+
//0.84887248854057823517082799192315
491495
}
492496

493497

‎src/main/java/com/github/gbenroscience/math/numericalmethods/NumericalDerivative.java‎

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,12 @@ public double getxPoint() {
8282
* @return the numerical value of the
8383
* derivative very near the given point.
8484
*/
85-
public String findDerivativeByPolynomialExpander(){
85+
public double findDerivativeByPolynomialExpander(){
8686
FunctionExpander expander = new FunctionExpander(xPoint-0.0001, xPoint+0.1, 20,FunctionExpander.DOUBLE_PRECISION, function );
8787
MathExpression polyDerivative = new MathExpression( expander.getPolynomialDerivative() );
88-
89-
String variable = function.getIndependentVariables().get(0).getName();
90-
polyDerivative.setValue(variable, xPoint);
91-
return polyDerivative.solve();
88+
89+
polyDerivative.updateArgs(xPoint);
90+
return polyDerivative.solveGeneric().scalar;
9291
}
9392

9493

@@ -99,16 +98,15 @@ public String findDerivativeByPolynomialExpander(){
9998
* @return the numerical value of the
10099
* derivative very near the given point.
101100
*/
102-
public String findDerivativeByLimit(double dx){
101+
public double findDerivativeByLimit(double dx){
103102
MathExpression func = function.getMathExpression();
104-
func.setValue(function.getIndependentVariables().get(0).getName(), xPoint+dx);
105-
String upper = func.solve();
103+
func.updateArgs(xPoint+dx);
104+
double upper = func.solveGeneric().scalar;
106105

107-
func.setValue(function.getIndependentVariables().get(0).getName(), xPoint-dx);
108-
String lower = func.solve();
106+
func.updateArgs(xPoint-dx);
107+
double lower = func.solveGeneric().scalar;
109108

110-
double derived = ( Double.parseDouble(upper) - Double.parseDouble(lower) )/(2.0*dx);
111-
return String.valueOf(derived);
109+
return ( upper - lower )/(2.0*dx);
112110
}//end method
113111

114112

0 commit comments

Comments
 (0)