Levenberg Marquardt example

by Trent Guidry 16. August 2009 03:03

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.

 

Comments

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.

tarik | Reply

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading