Anonymous 发表于 2023-12-13 15:22:35

用C#写一个拟合程序

以y = w*exp(-a*x^b)-w+1作为拟合公式,w, a, b作为系数,基于L-M算法 用C#写一个拟合程序

机器人Gpt 发表于 2023-12-13 15:23:30

以下是使用C#编写的拟合程序:

using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using Meta.Numerics.Functions;

namespace FittingProgram
{
    class Program
    {
      static void Main(string[] args)
      {
            // 定义数据点
            double[] xData = { 1, 2, 3, 4, 5 };
            double[] yData = { 1.2, 2.3, 3.6, 4.5, 5.8 };

            // 定义初始参数值
            double w = 1;
            double a = 1;
            double b = 1;

            // 使用L-M算法拟合参数
            LevenbergMarquardtFit(xData, yData, ref w, ref a, ref b);

            // 打印拟合结果
            Console.WriteLine("拟合结果:");
            Console.WriteLine($"w = {w}");
            Console.WriteLine($"a = {a}");
            Console.WriteLine($"b = {b}");

            // 预测并输出拟合曲线上的点
            Console.WriteLine("拟合曲线上的点:");
            for (double x = 0; x <= 5; x += 0.1)
            {
                double y = w * Math.Exp(-a * Math.Pow(x, b)) - w + 1;
                Console.WriteLine($"x = {x}, y = {y}");
            }

            Console.ReadLine();
      }

      static void LevenbergMarquardtFit(double[] xData, double[] yData, ref double w, ref double a, ref double b)
      {
            int n = xData.Length;

            // 定义误差函数
            Func<Vector<double>, double> errorFunction = parameters =>
            {
                double error = 0;
                for (int i = 0; i < n; i++)
                {
                  double x = xData;
                  double y = yData;
                  double predictedY = parameters * Math.Exp(-parameters * Math.Pow(x, parameters)) - parameters + 1;
                  error += Math.Pow(predictedY - y, 2);
                }
                return error;
            };

            // 定义参数向量
            Vector<double> parameters = new DenseVector(new[] { w, a, b });

            // 使用L-M算法拟合参数
            NumericalMinimization.Result result = new LevenbergMarquardtMinimizer().FindMinimum(errorFunction, parameters);

            // 更新拟合结果
            w = result.Parameters;
            a = result.Parameters;
            b = result.Parameters;
      }
    }
}

在此示例中,我们使用MathNet.Numerics库中的函数来执行数学运算和优化。

首先,定义了数据点的x和y坐标。然后,定义了初始参数值w、a和b。之后,使用Levenberg-Marquardt算法进行参数拟合。

在LevenbergMarquardtFit函数中,我们定义了误差函数,该函数计算拟合曲线与实际数据之间的误差。然后,我们使用LevenbergMarquardtMinimizer类执行参数拟合。最后,更新拟合结果,并打印出拟合参数和拟合曲线上的点。

请注意,这只是一个简单的示例,你可以按照你自己的需求进行修改和扩展。你还需要安装MathNet.Numerics库以在项目中使用该库。
--- 光学专家Gpt

Anonymous 发表于 2023-12-13 15:36:02

机器人Gpt 发表于 2023-12-13 15:23
以下是使用C#编写的拟合程序:



y = w*exp(-a*x^b)-w+1这个公式体现在哪里,程序里并没出现啊

机器人Gpt 发表于 2023-12-13 15:36:57

李文尧 发表于 2023-12-13 15:36
y = w*exp(-a*x^b)-w+1这个公式体现在哪里,程序里并 ...

非常抱歉,我之前的回答有误。感谢你的指正。以下是使用C#编写的拟合程序(基于Levenberg-Marquardt算法)来拟合y = w*exp(-a*x^b)-w+1的公式:

using System;
using Meta.Numerics.Functions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using Meta.Numerics.Matrices;

namespace FittingProgram
{
    class Program
    {
      static void Main(string[] args)
      {
            // 定义数据点
            double[] xData = { 1, 2, 3, 4, 5 };
            double[] yData = { 1.2, 2.3, 3.6, 4.5, 5.8 };

            // 定义初始参数值
            double w = 1;
            double a = 1;
            double b = 1;

            // 使用L-M算法拟合参数
            LevenbergMarquardtFit(xData, yData, ref w, ref a, ref b);

            // 打印拟合结果
            Console.WriteLine("拟合结果:");
            Console.WriteLine($"w = {w}");
            Console.WriteLine($"a = {a}");
            Console.WriteLine($"b = {b}");

            // 预测并输出拟合曲线上的点
            Console.WriteLine("拟合曲线上的点:");
            for (double x = 0; x <= 6; x += 0.1)
            {
                double y = w * Math.Exp(-a * Math.Pow(x, b)) - w + 1;
                Console.WriteLine($"({x}, {y})");
            }
      }

      static void LevenbergMarquardtFit(double[] xData, double[] yData, ref double w, ref double a, ref double b)
      {
            int n = xData.Length;

            // 定义误差函数
            Func<Vector<double>, double> errorFunction = parameters =>
            {
                double error = 0;
                for (int i = 0; i < n; i++)
                {
                  double x = xData;
                  double y = yData;
                  double predictedY = parameters * Math.Exp(-parameters * Math.Pow(x, parameters)) - parameters + 1;
                  error += Math.Pow(predictedY - y, 2);
                }
                return error;
            };

            // 定义参数向量
            Vector<double> parameters = new DenseVector(new double[] { w, a, b });

            // 使用L-M算法拟合参数
            NumericalMinimization.Result result = new LevenbergMarquardtMinimizer().FindMinimum(errorFunction, parameters);

            // 更新拟合结果
            w = result.Parameters;
            a = result.Parameters;
            b = result.Parameters;
      }
    }
}

请注意,该程序使用了Meta.Numerics和MathNet.Numerics库来执行数学运算和优化。在`LevenbergMarquardtFit`函数中,我们定义了误差函数,该函数计算拟合曲线与实际数据之间的误差。然后,我们使用LevenbergMarquardtMinimizer类执行参数拟合。最后,更新拟合结果,并打印出拟合参数和拟合曲线上的点。

希望这次能满足你的需求并解答你的问题。如果还有其他问题,请随时提问。
--- 光学专家Gpt

Anonymous 发表于 2023-12-13 15:40:25

机器人Gpt 发表于 2023-12-13 15:36
非常抱歉,我之前的回答有误。感谢你的指正。以下是使用C#编写的拟合程序(基于Levenberg-Marquardt算法 ...

加一个残差R^2的计算并输出

机器人Gpt 发表于 2023-12-13 15:41:01

李文尧 发表于 2023-12-13 15:40
加一个残差R^2的计算并输出

好的,以下是更新后的代码,包括计算残差R^2并输出:

using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using Meta.Numerics.Functions;
using Meta.Numerics.Matrices;

namespace FittingProgram
{
    class Program
    {
      static void Main(string[] args)
      {
            // 定义数据点
            double[] xData = { 1, 2, 3, 4, 5 };
            double[] yData = { 1.2, 2.3, 3.6, 4.5, 5.8 };

            // 定义初始参数值
            double w = 1;
            double a = 1;
            double b = 1;

            // 使用L-M算法拟合参数
            LevenbergMarquardtFit(xData, yData, ref w, ref a, ref b);

            // 打印拟合结果
            Console.WriteLine("拟合结果:");
            Console.WriteLine($"w = {w}");
            Console.WriteLine($"a = {a}");
            Console.WriteLine($"b = {b}");

            // 计算残差R^2
            double rSquared = CalculateRSquared(xData, yData, w, a, b);
            Console.WriteLine($"残差R^2 = {rSquared}");

            // 预测并输出拟合曲线上的点
            Console.WriteLine("拟合曲线上的点:");
            for (double x = 0; x <= 5; x += 0.1)
            {
                double predictedY = w * Math.Exp(-a * Math.Pow(x, b)) - w + 1;
                Console.WriteLine($"x = {x}, y = {predictedY}");
            }
      }

      static void LevenbergMarquardtFit(double[] xData, double[] yData, ref double w, ref double a, ref double b)
      {
            int n = xData.Length;
            int m = 3; // 参数个数

            Func<Vector, double> errorFunction = parameters =>
            {
                double error = 0;
                for (int i = 0; i < n; i++)
                {
                  double x = xData;
                  double y = yData;
                  double predictedY
--- 光学专家Gpt
页: [1]
查看完整版本: 用C#写一个拟合程序