最小二乘法拟合未知参数

想用matlab最小二乘法拟合非线性方程的4个未知参数,并画出原始数据和拟合曲线的图像。一直运行错误不知道怎么修改,错误使用 * 内部矩阵维度必须一致。

请指点~谢谢!函数如图片,a,b,c,d未知。

img


img

从报错原因上看是维度不一致,可以进行以下修改:

xdata=[1 2 3 4 5];
ydata=[20 40 60 80 100];
fun=@(a, x)x.^(a (1) .*x+a (2))./(a (3).*(a(4).^(a (1) .*x+a (2))) .*gamma (1+a (1) .*x+a(2))) ;
x0=[0.3,1.2,400,200];
A=lsqcurvefit(fun, x0, xdata, ydata)
ydata=fun(A, xdata) 
x=linspace(xdata(1),xdata(end)) ;
y=fun (A, x) ;
plot(xdata,ydata, 'o',xdata,ydata,'*',x,y)

结果为:

A =

   -0.3489    0.9364  399.9999  199.9995


ydata =

    0.0001    0.0009    0.0037    0.0092    0.0103

img


可见能够正常运行
如果问题得到解决请点 采纳~~

根据您提供的函数图片,我可以给您一些关于如何在 MATLAB 中使用最小二乘法拟合非线性方程的建议。最小二乘法是一种用于寻找最佳拟合曲线的方法,可以将测量数据点拟合到理论函数中。在 MATLAB 中,可以使用 'ls

% 生成一些虚拟数据点
x = linspace(0,10,100);
y = 2*sin(2*x) + 0.5*exp(-0.2*x) + 0.1*randn(size(x));

% 初始估计值
p0 = [1 1 1 1];

% 最小二乘拟合
p = lsqcurvefit(@(p,x) myfun(p,x), p0, x, y);

% 计算拟合的 y 值
yfit = myfun(p,x);

% 绘制原始数据和拟合曲线
plot(x,y,'o',x,yfit,'-')
legend('原始数据','拟合曲线')

% 定义您的函数 myfun,其中 a,b,c,d 是未知参数
function y = myfun(p,x)
   a = p(1);
   b = p(2);
   c = p(3);
   d = p(4);
   y = a*sin(b*x) + c*exp(-d*x);
end

在上述示例中,首先我们生成一些虚拟数据点。然后,我们定义了一个函数myfun,该函数接受未知参数a,b,c,d和自变量x作为输入,返回因变量y的值。我们还指定了初始估计值 'pp0,它是一个包含未知参数的向量。接下来,我们使用lsqcurvefit函数对数据进行最小二乘拟合,其中我们将myfun函数作为输入函数,并将数据点x,y和初始估计值 'p0作为其他参数。最后,我们计算拟合的 y 值并绘制原始数据和拟合曲线。

请注意,在您的情况中,您需要将您的函数 'fun替换为上述示例中的myfun函数,并根据您的情况修改自变量和因变量的定义。此外,您需要指定一个合适的初始估计值p0,以便算法能够收敛。如果您的代码仍然出现错误,您可能需要检查数据点的维度是否一致,以及是否正确指定了函数的输入参数。希望这些提示能够帮助您解决问题!

把矩阵乘除幂改成按元素乘除幂

fun=@(a, x)x.^(a (1) .*x+a (2))./(a (3).*(a(4).^(a (1) .*x+a (2))) .*gamma (1+a (1) .*x+a(2))) ;

根据您提供的信息,您正在使用MATLAB进行非线性最小二乘法拟合,但是遇到了矩阵维度不匹配的错误。这个错误通常表示矩阵乘法的操作中,矩阵的维度不一致,导致无法进行乘法运算。

以下是一般的解决步骤,供您参考:

将您的数据存储在两个列向量中,分别为x和y。

建立一个函数,用来表示您的非线性方程,其中a、b、c、d为未知参数,x为已知数据。该函数的形式为:

function yfit = myfun(p,x)
a = p(1);
b = p(2);
c = p(3);
d = p(4);
yfit = a*x.^3 + b*exp(-c*x) + d;
end

初始猜测值可以随意选择一个较好的值,例如[1,1,1,1]。然后使用lsqcurvefit函数进行求解,具体语法为:

p0 = [1,1,1,1];  % 初始猜测值
[p,resnorm] = lsqcurvefit(@myfun,p0,x,y);

其中,@myfun表示传递函数句柄。p为拟合后的参数向量,resnorm为残差平方和。

将求解得到的参数向量p代入上一步中定义的函数中,得到拟合曲线上的数据点。然后可以使用plot函数绘制原始数据和拟合曲线。

xplot = linspace(min(x),max(x),100);  % 生成一些用于绘制拟合曲线的点
yfit = myfun(p,xplot);
plot(x,y,'o',xplot,yfit);

这里的linspace函数用于生成一些用于绘制拟合曲线的点,min(x)和max(x)表示x向量中的最小值和最大值。plot函数用于绘制数据点和拟合曲线,'o'表示绘制原始数据点,xplot和yfit表示绘制拟合曲线。

希望这些步骤对您有帮助。请采纳。

xdata=[1 2 3 4 5];
ydata=[20 40 60 80 100];
fun=@(a,x)x.^(a(1)x+a(2))/(a(3)(a(4).^(a(1)*x+a(2)))*gamma(1+a(1)x+a(2)));
x0=[0.3,1.2,400,200];
A=lsqcurvefit(fun,x0,xdata,ydata)
ydata=fun(A,xdata);
x=linspace(xdata(1),xdata(end));
y=fun(A,x);
plot(xdata,ydata,'o',xdata,ydata,'
',x,y)

修改后的代码


xdata = [1,2,3,4,5];
ydata = [20,40,60,80,100];

fun = @(a,x) x.*(a(1)*x+a(2)/(a(3)*(a(4).^(a(1)*x)+a(2))))*gamma(1+a(1)*x);

x0 = [0.3,1.2,400,200];

A = lsqcurvefit(fun,x0,xdata,ydata);

yfit = fun(A,xdata);
x = linspace(xdata(1),xdata(end));
y = fun(A,x);

plot(xdata,ydata,'o',xdata,yfit,'-',x,y,'--');
legend('Data','Fitted curve','Model curve');

https://blog.csdn.net/weixin_39665847/article/details/111176688

在使用 MATLAB 进行最小二乘法拟合非线性方程时,需要注意以下几点:

  1. 需要定义一个代表拟合函数的函数句柄,该函数需要包含待拟合参数,例如:@(x, p) p(1)*exp(-x/p(2))+p(3)*exp(-x/p(4)),其中 p 代表待拟合的四个参数。
  2. 需要提供原始数据,包括自变量和因变量,例如:x = [1, 2, 3, 4, 5],y = [2.1, 1.6, 1.2, 0.9, 0.5]。
  3. 初始参数的值需要进行估计。
  4. MATLAB 提供了 lsqcurvefit 函数,该函数可以自动拟合非线性方程,并返回最优参数值,同时可以用拟合函数计算出拟合曲线。

下面是一份代码示例,其中拟合的函数为指数函数:

% 定义拟合函数的函数句柄
fun = @(x,p) p(1)*exp(-x/p(2))+p(3)*exp(-x/p(4));

% 提供原始数据
x = [1, 2, 3, 4, 5];
y = [2.1, 1.6, 1.2, 0.9, 0.5];

% 初始参数的值
p0 = [1, 1, 1, 1];

% 进行最小二乘法拟合
p = lsqcurvefit(fun,p0,x,y);

% 计算拟合曲线
x_fit = linspace(1,5,100);
y_fit = fun(x_fit,p);

% 绘制图像
plot(x,y,'o',x_fit,y_fit)
xlabel('x')
ylabel('y')
legend('原始数据','拟合曲线')

如果出现错误使用 * 内部矩阵维度必须一致,可能是因为输入的矩阵维度不匹配导致的。可以检查一下输入的矩阵维度是否正确,或者试着转置一下矩阵。

第一个问题是,你的方程中有一些括号没有正确地匹配,例如你的方程的分子部分应该是x.(a(1)x+a(2)),而不是x.(a(1)x+a(2)),你的方程的分母部分应该是a(3)(a(4).(a(1)*x+a(2)))*gamma(1+a(1)*x+a(2)),而不是a(3)(a(4).(a(1)*x+a(2)))gamma(1+a(1)x+a(2))。你需要在乘法的地方加上号,以及在函数的参数的地方加上括号,否则matlab会认为你的变量或函数的名字是错误的。
第二个问题是,你的方程中有一些函数没有正确地使用,例如你的方程的分母部分中的gamma函数应该是gamma(1+a(1).*x+a(2)),而不是gamma(1+a(1)*x+a(2))。你需要在点乘的地方加上.号,以及在函数的参数的地方加上括号,否则matlab会认为你的函数的参数是错误的。
修改如下

xdata=[1 2 3 4 5];
ydata=[20 40 60 80 100];
fun=@(a,x)x.^(a(1)*x+a(2))./(a(3)*(a(4).^(a(1)*x+a(2)))*gamma(1+a(1).*x+a(2)));
x0=[0.3,1.2,400,200];
A=lsqcurvefit(fun,x0,xdata,ydata)
ydata=fun(A,xdata);
x=linspace(xdata(1),xdata(end));
y=fun(A,x);
plot(xdata,ydata,'o',x,y,'-')