In this post I will give an example of using the previously created Levenberg Marquardt class to solve a nonlinear regression problem using the Levenberg Marquardt algorithm.
For this example, I will use the Antoine vapor pressure correlation, which in pressure explicit terms is shown below.
Psat = eA-B/(T+C)
For the data, I will use the vapor pressure data of methanol that I got from the 6th edition of Perry's Chemical Engineers' Handbook, which is shown below.
|
T K
|
P Pa
|
|
229.15
|
133.32249
|
|
247.85
|
666.61245
|
|
256.95
|
1333.2249
|
|
267.15
|
2666.4498
|
|
278.15
|
5332.8996
|
|
285.25
|
7999.3494
|
|
294.35
|
13332.249
|
|
307.95
|
26664.498
|
|
323.05
|
53328.996
|
|
337.85
|
101325.09
|
I then addded the class shown below to the Windows Loaded event.
double[] temperature =
new double[] { 229.15, 247.85, 256.95, 267.15, 278.15, 285.25, 294.35, 307.95, 323.05, 337.85 };
double[] pressure =
new double[] { 133.3224898, 666.6124489, 1333.224898, 2666.449795, 5332.899591, 7999.349386, 13332.24898, 26664.49795, 53328.99591, 101325.0922 };
double[,] z = new double[2, temperature.Length];
for (int i = 0; i < temperature.Length; i++)
{
z[0, i] = temperature[i];
z[1, i] = pressure[i];
}
Parameter A = new Parameter(20.0);
Parameter B = new Parameter(5000.0);
Parameter C = new Parameter(0.0);
Parameter T = new Parameter(1.0);
Func<double> regressionFunction = () => Math.Exp(A - B / (T + C));
Parameter[] regressionParameters = new Parameter[] { A, B, C };
Parameter[] observedParameters = new Parameter[] { T };
LevenbergMarquardt levenbergMarquardt = new LevenbergMarquardt(regressionFunction, regressionParameters, observedParameters, z);
for (int i = 0; i < 50; i++)
{
levenbergMarquardt.Iterate();
}
This code first loads the temperature and pressure data into variables temperature and pressure. It then fills in the data double array z. After that, it creates an instance of the class created above. A parameter array is also created called observedParameters, which specifies the independent variables. An instance of the Levenberg Marquardt class is then created and the function array, the instance of the model class, the array of independent parameters, and the number of points to use for computing the partial derivatives are passed in to the constructor. The function Iterate is then called 50 times.
This gives values of 26.9843 for A, 5780.219 for B, and 36.06304 for C.
Plugging these parameter values back into the Antoine equation gives the table shown below.
|
T K
|
P Pa
|
P Calc
|
|
229.15
|
133.3225
|
179.4100673
|
|
247.85
|
666.6125
|
753.8416198
|
|
256.95
|
1333.225
|
1418.660006
|
|
267.15
|
2666.45
|
2754.72538
|
|
278.15
|
5332.9
|
5369.232745
|
|
285.25
|
7999.349
|
8062.109335
|
|
294.35
|
13332.25
|
13231.83403
|
|
307.95
|
26664.5
|
26422.59293
|
|
323.05
|
53329
|
53555.81106
|
|
337.85
|
101325.1
|
101272.9498
|
A graph comparing the calculated values with the data values is shown below.
