想用matlab最小二乘法拟合非线性方程的4个未知参数,并画出原始数据和拟合曲线的图像。一直运行错误不知道怎么修改,错误使用 * 内部矩阵维度必须一致。
请指点~谢谢!函数如图片,a,b,c,d未知。
从报错原因上看是维度不一致,可以进行以下修改:
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
根据您提供的函数图片,我可以给您一些关于如何在 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
下面是一份代码示例,其中拟合的函数为指数函数:
% 定义拟合函数的函数句柄
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,'-')