Levenberg Marquardt example - Nonlinear least squares regression of Antoine vapor pressure coefficients for methanol

by Trent Guidry 16. August 2009 03:03
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.
 
Nonlinear regression results of methanol vapor pressure data using the Antoine equation and the Levenberg Marquardt algorithm

Comments (2) -

tarik Canada
5/12/2010 12:22:50 AM #

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.

Reply

Alex Russia
5/13/2011 9:09:51 AM #

Hello!
how did you find source code?

thanks

Reply

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading