用L-M迭代算法生成 y = w*exp(-a*x^b)-w+1 的拟合公式

[复制链接]
匿名  发表于 2023-12-4 11:46:00 |阅读模式
用L-M迭代算法生成 y = w*exp(-a*x^b)-w+1 的拟合公式
回复

使用道具 举报

全部回复7 显示全部楼层
机器人Gpt 发表于 2023-12-4 11:47:48 | 显示全部楼层
李文尧 发表于 2023-12-04 11:47
能不能给出C#程序代码

当然,请看以下的C#程序代码示例:
  1. using System;
  2. using MathNet.Numerics.LinearAlgebra;
  3. class Program
  4. {
  5.     static void Main(string[] args)
  6.     {
  7.         // 给定的样本点坐标
  8.         double[] x = { 1, 2, 3, 4, 5 };
  9.         double[] y = { 0.5, 0.3, 0.2, 0.15, 0.1 };
  10.         // 初始化参数 w, a, b
  11.         double w = 0.5;
  12.         double a = 0.5;
  13.         double b = 0.5;
  14.         // 设置迭代停止条件和最大迭代次数
  15.         double epsilon = 1e-6;
  16.         int maxIterations = 100;
  17.         // 迭代更新参数
  18.         int iterations = 0;
  19.         double lambda = 0.01;
  20.         while (iterations < maxIterations)
  21.         {
  22.             iterations++;
  23.             // 计算误差函数的梯度矩阵 J 和残差向量 r
  24.             Matrix<double> J = BuildJacobianMatrix(x, w, a, b);
  25.             Vector<double> r = BuildResidualVector(x, y, w, a, b);
  26.             // 计算雅可比矩阵的转置矩阵 J_T,并进行QR分解,得到 Q 和 R
  27.             QR<double> qr = J.QR();
  28.             // 更新参数
  29.             Vector<double> delta = qr.R.TransposeThisAndMultiply(qr.R).Add(lambda * Matrix<double>.BuildIdentity(J.ColumnCount)).Inverse() * qr.R.TransposeThisAndMultiply(qr.Q.TransposeThisAndMultiply(r));
  30.             w += delta[0];
  31.             a += delta[1];
  32.             b += delta[2];
  33.             // 判断参数变化是否小于阈值
  34.             if (delta.L2Norm() < epsilon)
  35.                 break;
  36.         }
  37.         // 输出结果
  38.         Console.WriteLine("w = " + w);
  39.         Console.WriteLine("a = " + a);
  40.         Console.WriteLine("b = " + b);
  41.     }
  42.     // 计算误差函数的梯度矩阵 J
  43.     static Matrix<double> BuildJacobianMatrix(double[] x, double w, double a, double b)
  44.     {
  45.         int n = x.Length;
  46.         Matrix<double> J = Matrix<double>.Build.Dense(n, 3);
  47.         for (int i = 0; i < n; i++)
  48.         {
  49.             double xiPowB = Math.Pow(x[i], b);
  50.             J[i, 0] = Math.Exp(-a * xiPowB) - 1;
  51.             J[i, 1] = -w * xiPowB * Math.Exp(-a * xiPowB);
  52.             J[i, 2] = -w * a * xiPowB * Math.Exp(-a * xiPowB) * Math.Log(x[i]);
  53.         }
  54.         return J;
  55.     }
  56.     // 计算残差向量 r
  57.     static Vector<double> BuildResidualVector(double[] x, double[] y, double w, double a, double b)
  58.     {
  59.         int n = x.Length;
  60.         Vector<double> r = Vector<double>.Build.Dense(n);
  61.         for (int i = 0; i < n; i++)
  62.         {
  63.             r[i] = y[i] - (w * Math.Exp(-a * Math.Pow(x[i], b)) - w + 1);
  64.         }
  65.         return r;
  66.     }
  67. }
复制代码

请注意,上述代码使用了MathNet.Numerics库进行线性代数计算,需要先安装该库。可以通过NuGet包管理器或在项目中引用MathNet.Numerics库来使用。
--- 光学专家Gpt
回复 支持 1 反对 0

使用道具 举报

机器人Gpt 发表于 2023-12-4 11:46:20 | 显示全部楼层
L-M迭代算法(Levenberg-Marquardt Algorithm)是一种非线性最小二乘拟合方法,可以用于求解非线性函数的参数拟合问题。

首先,将拟合函数 y = w*exp(-a*x^b)-w+1 转化为最小二乘问题,定义误差函数 E(w, a, b):
E(w, a, b) = ∑(y_i - (w*exp(-a*x_i^b)-w+1))^2

其中,(x_i, y_i) 是给定的样本点坐标。

接下来,使用L-M迭代算法进行参数拟合,步骤如下:

1. 初始化参数 w, a, b。
2. 根据当前参数计算误差函数的梯度矩阵 J 和残差向量 r:
J = [∂E/∂w, ∂E/∂a, ∂E/∂b]
r = [y_1 - (w*exp(-a*x_1^b)-w+1), y_2 - (w*exp(-a*x_2^b)-w+1), ..., y_n - (w*exp(-a*x_n^b)-w+1)]
3. 计算雅可比矩阵 J 的转置矩阵 J_T,并进行QR分解,得到 Q 和 R。
4. 更新参数:
delta = (R^T * R + λ * I)^-1 * (R^T * Q^T * r)
w_new = w + delta[0]
a_new = a + delta[1]
b_new = b + delta[2]
其中, λ 是控制矩阵求逆的正则化参数。
5. 判断更新后的参数变化是否小于一定阈值,如果满足,则停止迭代;否则,返回第3步。

最后,当L-M迭代算法收敛后,得到拟合公式 y = w*exp(-a*x^b)-w+1 的参数 w, a, b。
--- 光学专家Gpt
回复 支持 反对

使用道具 举报

匿名  发表于 2023-12-4 11:47:06
能不能给出C#程序代码
回复 支持 反对

使用道具 举报

匿名  发表于 2023-12-13 15:05:18
机器人Gpt 发表于 2023-12-4 11:47
当然,请看以下的C#程序代码示例:

37行buildIdentity(J.ColumnCount)什么意思
回复 支持 反对

使用道具 举报

机器人Gpt 发表于 2023-12-13 15:05:31 | 显示全部楼层
李文尧 发表于 2023-12-13 15:05
37行buildIdentity(J.ColumnCount)什么意思

在第37行的代码 `Matrix.BuildIdentity(J.ColumnCount)` 中,`BuildIdentity` 是一个用于构建单位矩阵的方法,它会返回一个大小为 J 列数 x J 列数 的单位矩阵。单位矩阵是一个主对角线上的元素都为1,其余元素都为0的矩阵。在 L-M 迭代算法中,这个单位矩阵用于进行矩阵求逆的正则化,以提高矩阵求逆的稳定性。
--- 光学专家Gpt
回复 支持 反对

使用道具 举报

匿名  发表于 2023-12-13 15:16:10
机器人Gpt 发表于 2023-12-13 15:05
在第37行的代码 `Matrix.BuildIdentity(J.ColumnCount)` 中,`BuildIdentity` 是一个用于构建单位矩阵的 ...

`BuildIdentity`换成'DenseIdentity'可以吗
回复 支持 反对

使用道具 举报

机器人Gpt 发表于 2023-12-13 15:16:54 | 显示全部楼层
李文尧 发表于 2023-12-13 15:16
`BuildIdentity`换成'DenseIdentity'可以吗

是的,你可以把 `Matrix.BuildIdentity(J.ColumnCount)` 替换为 `Matrix.DenseIdentity(J.ColumnCount)`。

`Matrix.DenseIdentity` 方法也是用于构建单位矩阵的方法,它与 `BuildIdentity` 方法功能相同,都会返回一个大小为 J 列数 x J 列数 的单位矩阵。两者的区别在于它们返回的矩阵类型不同,`BuildIdentity` 返回的是稀疏矩阵,而 `DenseIdentity` 返回的是密集矩阵。

在 L-M 迭代算法中,你可以根据自己的需求选择使用稀疏矩阵或密集矩阵来构建单位矩阵。一般来说,如果参数数量较少,可以使用密集矩阵;如果参数数量较多,可以考虑使用稀疏矩阵以节省内存空间。

所以,你可以根据你的具体情况选择使用 `Matrix.BuildIdentity(J.ColumnCount)` 或者 `Matrix.DenseIdentity(J.ColumnCount)`,它们都可以正确构建单位矩阵。
--- 光学专家Gpt
回复 支持 反对

使用道具 举报

快速回帖

您需要登录后才可以回帖 登录 | 立即注册 手机动态码快速登录

本版积分规则

关于楼主

匿名用户组
  • 主题

    64
  • 回答

    19
  • 积分

    68
联系客服 关注微信 访问手机版 返回顶部 返回列表