Skip to content

Commit adf67a9

Browse files
committed
Package to solve ODE with Newton Raphson and nested Newton algorithm
1 parent c34f345 commit adf67a9

File tree

7 files changed

+456
-0
lines changed

7 files changed

+456
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* GNU GPL v3 License
3+
*
4+
* Copyright 2021 Niccolò Tubini, Giuseppe Formetta, Riccardo Rigon
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package it.geoframe.blogspot.numerical.ode;
21+
22+
23+
/**
24+
* @author Niccolò Tubini, Giuseppe Formetta
25+
*
26+
*/
27+
public class NestedNewton {
28+
29+
private double x0;
30+
31+
private double x_k;
32+
33+
private double tol = 1e-10;
34+
35+
private double error;
36+
37+
private int iteration;
38+
39+
private int maxIteration = 100;
40+
41+
private double f;
42+
43+
private double ff;
44+
45+
public double solve( double x, OrdinaryDifferentialEquation ode ) {
46+
47+
this.x0 = x;
48+
49+
error = 1.0;
50+
51+
iteration = 1;
52+
53+
54+
for(int outerIteration=0; outerIteration<maxIteration; outerIteration++) {
55+
56+
f = ode.compute(x0) - ode.computeRHS();
57+
58+
if(Math.abs(f)<tol) {
59+
60+
return x0;
61+
62+
}
63+
64+
x_k = x0;
65+
66+
for(int innerrIteration=0; innerrIteration<maxIteration; innerrIteration++) {
67+
68+
ff = ode.computePIntegral(x0) - (ode.computeQIntegral(x_k)+ode.computeQ(x_k)*(x0-x_k)) - ode.computeRHS();
69+
70+
if(Math.abs(ff)<tol) {
71+
72+
return x0;
73+
74+
}
75+
76+
x0 = x0 - 1/(ode.computeP(x0)-ode.computeQ(x_k))*ff;
77+
}
78+
}
79+
80+
return x0;
81+
}
82+
83+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* GNU GPL v3 License
3+
*
4+
* Copyright 2021 Niccolò Tubini, Giuseppe Formetta, Riccardo Rigon
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package it.geoframe.blogspot.numerical.ode;
21+
22+
23+
/**
24+
* @author Niccolò Tubini, Giuseppe Formetta
25+
*
26+
*/
27+
public class NewtonRaphson {
28+
29+
private double x0;
30+
31+
private double xNew;
32+
33+
private double tol = 1e-10;
34+
35+
private double error;
36+
37+
private int iteration;
38+
39+
private int maxIteration = 100;
40+
41+
42+
43+
public double solve( double x, OrdinaryDifferentialEquation ode ) {
44+
45+
this.x0 = x;
46+
47+
error = 1.0;
48+
49+
iteration = 1;
50+
51+
52+
while(error>tol) {
53+
54+
if(iteration>maxIteration) {
55+
56+
System.out.println("\t NewtonRaphson reach maximum numeber of iteration " + ode.toString());
57+
break;
58+
59+
}
60+
61+
xNew = -ode.compute(this.x0)/ode.computeDerivative(this.x0) + this.x0;
62+
63+
error = Math.abs(xNew-this.x0)/this.x0;
64+
65+
this.x0 = xNew;
66+
67+
iteration++;
68+
69+
}
70+
71+
return xNew;
72+
}
73+
74+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* GNU GPL v3 License
3+
*
4+
* Copyright 2021 Niccolò Tubini, Giuseppe Formetta, Riccardo Rigon
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package it.geoframe.blogspot.numerical.ode;
21+
22+
/**
23+
* @author Niccolò Tubini, Giuseppe Formetta
24+
*
25+
*/
26+
public class ODELiquidMass implements OrdinaryDifferentialEquation {
27+
28+
private double initialCondition;
29+
private double rainfall;
30+
private double freezing;
31+
private double melting;
32+
private double snowPorosity;
33+
34+
35+
public ODELiquidMass(double initialCondition, double rainfall, double freezing, double melting, double snowPorosity) {
36+
37+
this.initialCondition = initialCondition;
38+
this.rainfall = rainfall;
39+
this.freezing = freezing;
40+
this.melting = melting;
41+
this.snowPorosity = snowPorosity;
42+
43+
}
44+
45+
@Override
46+
public double compute(double liquidWater) {
47+
// TODO Auto-generated method stub
48+
49+
return Math.min(liquidWater,snowPorosity) + Math.max(liquidWater-snowPorosity, 0) - initialCondition - rainfall + freezing - melting;
50+
51+
}
52+
53+
@Override
54+
public double computeDerivative(double liquidWater) {
55+
// TODO Auto-generated method stub
56+
57+
// if(liquidWater>snowPorosity) {
58+
//
59+
// return 2;
60+
//
61+
// } else {
62+
63+
return 1;
64+
65+
// }
66+
67+
}
68+
69+
@Override
70+
public double computeP(double x) {
71+
// TODO Auto-generated method stub
72+
return 0;
73+
}
74+
75+
@Override
76+
public double computePIntegral(double x) {
77+
// TODO Auto-generated method stub
78+
return 0;
79+
}
80+
81+
@Override
82+
public double computeRHS() {
83+
// TODO Auto-generated method stub
84+
return 0;
85+
}
86+
87+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* GNU GPL v3 License
3+
*
4+
* Copyright 2021 Niccolò Tubini, Giuseppe Formetta, Riccardo Rigon
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package it.geoframe.blogspot.numerical.ode;
21+
22+
/**
23+
* @author Niccolò Tubini, Giuseppe Formetta
24+
*
25+
*/
26+
public class ODESolidMass implements OrdinaryDifferentialEquation {
27+
28+
private double initialCondition;
29+
private double snowfall;
30+
private double freezing;
31+
private double melting;
32+
33+
34+
public ODESolidMass(double initialCondition, double snowfall, double freezing, double melting) {
35+
36+
this.initialCondition = initialCondition;
37+
this.snowfall = snowfall;
38+
this.freezing = freezing;
39+
this.melting = melting;
40+
41+
}
42+
43+
@Override
44+
public double compute(double solidWater) {
45+
// TODO Auto-generated method stub
46+
47+
return solidWater - initialCondition - snowfall - freezing + melting;
48+
}
49+
50+
@Override
51+
public double computeDerivative(double x) {
52+
// TODO Auto-generated method stub
53+
return 1;
54+
}
55+
56+
@Override
57+
public double computeP(double x) {
58+
// TODO Auto-generated method stub
59+
return 0;
60+
}
61+
62+
@Override
63+
public double computePIntegral(double x) {
64+
// TODO Auto-generated method stub
65+
return 0;
66+
}
67+
68+
@Override
69+
public double computeRHS() {
70+
// TODO Auto-generated method stub
71+
return 0;
72+
}
73+
74+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* GNU GPL v3 License
3+
*
4+
* Copyright 2021 Niccolò Tubini, Giuseppe Formetta, Riccardo Rigon
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
package it.geoframe.blogspot.numerical.ode;
21+
22+
/**
23+
* @author Niccolò Tubini, Giuseppe Formetta
24+
*
25+
*/
26+
27+
public interface OrdinaryDifferentialEquation {
28+
29+
30+
public abstract double compute(double x);
31+
32+
public abstract double computeDerivative(double x);
33+
34+
public abstract double computeP(double x);
35+
36+
public abstract double computePIntegral(double x);
37+
38+
public abstract double computeRHS();
39+
40+
public default double computeQ(double x) {
41+
42+
return computeP(x) - computeDerivative(x);
43+
44+
}
45+
46+
public default double computeQIntegral(double x) {
47+
48+
return computePIntegral(x) - compute(x);
49+
50+
}
51+
52+
}

0 commit comments

Comments
 (0)