In this article I will give an example of using the previously created Levenberg Marquardt class to solve a nonlinear least squares 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 code 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.

Subscribe

Hello,
I tried to use this code, but i got the following error concering this line "Func<double> regressionFunction = () => [b]Math.Exp(A - B / (T + C));"
Error: Cannot implicitly convert type 'double' to 'System.Func<double>'
also i got some errors with the lambda expression. could you please help me with that. Thanks.
Hello!
how did you find source code?
thanks