C#, Cálculo Numérico - Método de cálculo y programa fuente de Métodos Cuasi-Newton o Métricos Variables en Multidimensiones

 

C#, Cálculo Numérico - Método de cálculo y programa fuente de Métodos Cuasi-Newton o Métricos Variables en Multidimensiones

1 Métodos cuasi-Newton (métrica variable)

Los métodos cuasi-Newton intentan generar una estimación de la inversa de la matriz de Hesse. 

. Luego se utiliza para determinar el siguiente punto de iteración.

El gradiente en la región alrededor de a está dado por

En el mínimo el gradiente es cero.

por lo tanto, el mejor siguiente paso de dirección viene dado por

El algoritmo BFGS (`Broyden-Fletcher-Goldfarb-Shanno') se basa en esta técnica.

2 programa fuente C#

usando Sistema;

namespace Legalsoft.Truffer
{     /// <summary>     /// Métodos de métricas variables o cuasi-Newton en multidimensiones     /// </summary>     public class QuasiNewton     {         public static void dfpmin(double[] p, double gtol, ref int iter , ref doble traste, función RealValueFunWithDiff)         {             const int ITMAX = 200;             const doble EPS = float.Epsilon; //numeric_limits<doble>.epsilon();             constante doble TOLX = 4 * EPS;             constante doble STPMX = 100,0;










            verificación bool = falso;
            int n = p.Longitud;
            doble[] dg = nuevo doble[n];
            doble[] g = nuevo doble[n];
            doble[] hdg = nuevo doble[n];
            doble[] pnew = nuevo doble[n];
            doble[] xi = nuevo doble[n];
            doble[,] hessin = nuevo doble[n, n];

            doble fp = funcd.funk(p);
            funcd.df(p,g);

            doble suma = 0,0;
            para (int i = 0; i < n; i++)
            {                 para (int j = 0; j < n; j++)                 {                     hessin[i, j] = 0.0;                 }                 hessin[i, i] = 1,0;                 xi[i] = -g[i];                 suma += p[i] * p[i];             }             doble stpmax = STPMX * Math.Max(Math.Sqrt(suma), (doble)n);             for (int su = 0; su < ITMAX; su++)             {                 iter = su;                 Roots.lnsrch(p, fp, g, xi, pnew, ref fret, stpmax, ref check, funcd);                 fp = traste;














                for (int i = 0; i < n; i++)
                {                     xi[i] = pnew[i] - p[i];                     p[i] = pnuevo[i];                 }                 prueba doble = 0,0;                 for (int i = 0; i < n; i++)                 {                     doble temperatura = Math.Abs(xi[i]) / Math.Max(Math.Abs(p[i]), 1.0);                     if (temperatura > prueba)                     {                         prueba = temperatura;                     }                 }                 if (prueba < TOLX)                 {                     retorno;                 }
















                for (int i = 0; i < n; i++)
                {                     dg[i] = g[i];                 }

                funcd.df(p,g);

                prueba = 0,0;
                doble guarida = Math.Max(Math.Abs(traste), 1.0);
                for (int i = 0; i < n; i++)
                {                     doble temperatura = Math.Abs(g[i]) * Math.Max(Math.Abs(p[i]), 1.0) / den;                     if (temperatura > prueba)                     {                         prueba = temperatura;                     }                 }                 if (prueba < gtol)                 {                     retorno;                 }                 for (int i = 0; i < n; i++)                 {                     dg[i] = g[i] - dg[i];                 }














                for (int i = 0; i < n; i++)
                {                     hdg[i] = 0.0;                     for (int j = 0; j < n; j++)                     {                         hdg[i] += hessin[i, j] * dg[j];                     }                 }                 doble cara = 0.0;                 doble fae = 0,0;                 suma doble = 0,0;                 doble sumaxi = 0,0;                 for (int i = 0; i < n; i++)                 {                     fac += dg[i] * xi[i];                     fae += dg[i] * hdg[i];                     sumdg += Globals.SQR(dg[i]);















                    sumxi += Globals.SQR(xi[i]);
                }
                if (fac > Math.Sqrt(EPS * sumdg * sumxi))
                {                     fac = 1.0 / fac;                     doble moda = 1,0 / fae;                     for (int i = 0; i < n; i++)                     {                         dg[i] = fac * xi[i] - moda * hdg[i];                     }                     for (int i = 0; i < n; i++)                     {                         for (int j = i; j < n; j++)                         {                             hessin[i, j] += fac * xi[i] * xi[j] - moda * hdg[i] * hdg[j] + fae * dg[i] * dg[j];











                            hessin[j, i] = hessin[i, j];
                        }
                    }
                }
                for (int i = 0; i < n; i++)
                {                     xi[i] = 0.0;                     for (int j = 0; j < n; j++)                     {                         xi[i] -= hessin[i, j] * g[j];                     }                 }             }             throw new Exception("demasiadas iteraciones en dfpmin");         } }     }










Supongo que te gusta

Origin blog.csdn.net/beijinghorn/article/details/132286523
Recomendado
Clasificación