« 新型コロナウイルス、日本の陽性者数&ワクチン接種者数総計をプロット&中国、韓国、アメリカ、ドイツ、フランス、イギリスの陽性者数もプロット(8/28更新)日本の増加止まらず、韓国に近づいてきた。陽性者も人口の14.5%に。韓国は44.2%だけど… | トップページ | かつやで海老カツと鶏カツの合い盛り定食をいただく。タルタルソースがとても美味しい。 »

2022年8月29日 (月)

Visual C# (C_sharp)の数値計算ライブラリ MathNET Numericsを使う(7) OptimizationのLevenberg-Marquardt法(LevenbergMarquardtMinimizer)で非線形最小二乗法(回帰)でNISTの例題Rat43を計算する。

C#でMath.NET Numericsを使うシリーズ7回目。今回は非線形回帰(最小二乗法)で有名なLevenberg-Marquardt法だ。
どう使うかは公式サイト見てもよくわからん、、、のでGitHubを直接見に行って、Testしているところを見るのがいい。

https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics.Tests/OptimizationTests/NonLinearCurveFittingTests.cs

なるほど。ではここにも出ているNISTの非線形回帰のサンプル集、

https://www.itl.nist.gov/div898/strd/nls/nls_main.shtml

からRat43をやってみよう。Math.NET Numericsでは微分(Gradiant)は使わないでやっているがこちらは使ってみる。

C_sharp_optimization03

C_sharp_optimization04

結果はこちら。ちゃんとNISTの値と整合が取れた値が出ている。

C_sharp_optimization05 C_sharp_optimization06

 

テキストでもコードを書いておく。ただしグラフ部分以外。

 


using MathNet.Numerics;
using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;
using MathNet.Numerics.Optimization.TrustRegion;
using Series = System.Windows.Forms.DataVisualization.Charting.Series;
            var obj = ObjectiveFunction.NonlinearModel(OptimizeFunction, Gradient, Xdata, Ydata);
            var solver = new LevenbergMarquardtMinimizer() ;
            var result = solver.FindMinimum(obj, InitialValue1);
            for (int i = 0; i < Xdata.Count; i++)
            {
                series1.Points.AddXY(Xdata[i], Ydata[i]);
            }
            var x = Vector.Build.DenseOfArray(Generate.LinearSpaced(100, 1.0, 15.0));
            var y = OptimizeFunction(result.MinimizingPoint, x);
            for (int i = 0; i < x.Count; i++)
            {
                series2.Points.AddXY(x[i], y[i]);
            }

            for (int i =0; i < result.MinimizingPoint.Count; i++)
            {
                Console.WriteLine($"p[{i}] = {result.MinimizingPoint[i]}"); 
            }

        }
        private Vector Xdata = Vector.Build.DenseOfArray(new double[] {
            1.00,   2.00,   3.00,   4.00,   5.00,   6.00,   7.00,   8.00,   9.00,   10.00,
            11.00,  12.00,  13.00,  14.00,  15.00
        });
        private Vector Ydata = Vector.Build.DenseOfArray(new double[] {
             16.08, 33.83,  65.80,  97.20,  191.55, 326.20, 386.87, 520.53, 590.03, 651.92,
            724.93, 699.56, 689.96, 637.56, 717.41
        });
        private Vector InitialValue1 = Vector.Build.DenseOfArray(new double[] { 100, 10, 1, 1 });
        private Vector OptimizeFunction(Vector p, Vector x)
        {
            var y = Vector.Build.Dense(x.Count);
            for (int i = 0; i < x.Count; i++)
            {
                y[i] = p[0] / Math.Pow(1.0 + Math.Exp(p[1] - p[2] * x[i]), 1.0 / p[3]);
            }
            return y;
        }
        private Matrix Gradient(Vector p, Vector x)
        {
            var prime = Matrix.Build.Dense(x.Count, p.Count);
            for (int i = 0; i < x.Count; i++)
            {
                prime[i, 0] = 1.0 / Math.Pow(1.0 + Math.Exp(p[1] - p[2] * x[i]), 1.0 / p[3]);
                prime[i, 1] = - p[0]* Math.Exp(p[1] - p[2] * x[i]) / 
                    (p[3]*Math.Pow(1.0 + Math.Exp(p[1] - p[2] * x[i]), 1.0 / p[3]+1.0));
                prime[i, 2] = p[0] * x[i] * Math.Exp(p[1] - p[2] * x[i]) /
                    (p[3]  * Math.Pow(1.0 + Math.Exp(p[1] - p[2] * x[i]), 1.0 / p[3] + 1.0));
                prime[i, 3]= Math.Log(1.0 + Math.Exp(p[1] - p[2] * x[i])) * p[0] / 
                    (p[3] *p[3]* Math.Pow(1.0 + Math.Exp(p[1] - p[2] * x[i]), 1.0 / p[3] ));
            }
            return prime;
        }

 

 

 

過去のもの:

 

Visual C# (C_sharp)の数学ライブラリ Math.NET Numericsを使う(1) 複素行列を定義して一次方程式や逆行列、行列式などを計算する。

Visual C# (C_sharp)の数学ライブラリ Math.NET Numericsを使う(2) 補間を行う(Interpolate) リニア、3次スプライン、有理関数などいろいろ使える。

Visual C# (C_sharp)の数学ライブラリ Math.NET Numericsを使う(3) 高速フーリエ変換(FFT)を実行する。FourierOptionsにMatlabとNumerical Recipesがあるのが意外。

Visual C# (C_sharp)の数学ライブラリ Math.NET Numericsを使う(4) 多項式フィッティングをして、Array.ConvertAllで一括でフィッティングデータを得る。

Visual C# (C_sharp)の数学ライブラリ Math.NET Numericsを使う(5) 常微分方程式の数値解法、4段4次のルンゲクッタ法がRungeKutta.FourthOrderの一文でできる。ローレンツ方程式を例としてやってみる

Visual C# (C_sharp)の数値計算ライブラリ MathNET Numericsを使う(6) OptimizationのNelder-Mead SimplexでRosenbrock関数(5パラメータ)を最小になる点を探す。

« 新型コロナウイルス、日本の陽性者数&ワクチン接種者数総計をプロット&中国、韓国、アメリカ、ドイツ、フランス、イギリスの陽性者数もプロット(8/28更新)日本の増加止まらず、韓国に近づいてきた。陽性者も人口の14.5%に。韓国は44.2%だけど… | トップページ | かつやで海老カツと鶏カツの合い盛り定食をいただく。タルタルソースがとても美味しい。 »

パソコン・インターネット」カテゴリの記事

学問・資格」カテゴリの記事

日記・コラム・つぶやき」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« 新型コロナウイルス、日本の陽性者数&ワクチン接種者数総計をプロット&中国、韓国、アメリカ、ドイツ、フランス、イギリスの陽性者数もプロット(8/28更新)日本の増加止まらず、韓国に近づいてきた。陽性者も人口の14.5%に。韓国は44.2%だけど… | トップページ | かつやで海老カツと鶏カツの合い盛り定食をいただく。タルタルソースがとても美味しい。 »

最近の記事

最近のコメント

2024年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
フォト
無料ブログはココログ