Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用MATLAB编写一个实现Newton';二维s方法_Matlab_Newtons Method - Fatal编程技术网

用MATLAB编写一个实现Newton';二维s方法

用MATLAB编写一个实现Newton';二维s方法,matlab,newtons-method,Matlab,Newtons Method,我正在尝试编写一个在二维中实现牛顿方法的函数,当我这样做的时候,我现在必须调整我的脚本,使我的函数的输入参数必须是列向量中的f(x),雅可比矩阵f(x),初始猜测x0,以及函数f(x)的公差及其雅可比矩阵在单独的.m文件中 作为我编写的实现牛顿方法的脚本示例,我有: n=0; %initialize iteration counter eps=1; %initialize error x=[1;1]; %set start

我正在尝试编写一个在二维中实现牛顿方法的函数,当我这样做的时候,我现在必须调整我的脚本,使我的函数的输入参数必须是列向量中的f(x),雅可比矩阵
f(x)
,初始猜测
x0
,以及函数
f(x)的公差
及其雅可比矩阵在单独的.m文件中

作为我编写的实现牛顿方法的脚本示例,我有:

n=0;            %initialize iteration counter     
eps=1;          %initialize error     
x=[1;1];        %set starting value

%Computation loop     
while eps>1e-10&n<100 
    g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)];         %g(x)      
    eps=abs(g(1))+abs(g(2));                             %error     
    Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)];   %Jacobian     
    y=x-Jg\g;                                            %iterate     
    x=y;                                                 %update x     
    n=n+1;                                               %counter+1     
end 

n,x,eps       %display end values
n=0;%初始化迭代计数器
每股收益=1;%初始化错误
x=[1;1];%设定起始值
%计算循环

eps>1e-10&n如果您不介意的话,我想重新构造您的代码,使其更具动态性,更易于阅读

让我们从一些预备工作开始。如果您想让脚本真正动态,那么我建议您使用符号数学工具箱。这样,您可以使用MATLAB为您处理函数的导数。首先需要使用
syms
命令,然后是所需的任何变量。这告诉MATLAB,您现在将把这个变量视为“符号”(即不是常数)。让我们从一些基本知识开始:

syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x.  Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
                  % This should give 2*(3^2) + 6*3 + 3 = 39
因为这是2D,我们需要2D函数。。。因此,让我们将
x
y
定义为变量。调用
subs
命令的方式略有不同:

syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
                               % Should give 56
还有一件事。。。我们可以将方程放入向量或矩阵中,并使用
subs
x
y
的所有值同时替换到每个方程中

syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
我们可以对矩阵做同样的事情,但为了简单起见,我不会告诉你怎么做。我会遵从代码,到时候你就能看到了

现在我们已经确定了这一点,让我们一次只处理一部分代码,以真正实现动态。您的函数需要初始猜测
x0
,函数
f(x)
作为列向量,雅可比矩阵作为2 x 2矩阵,公差
tol

在运行脚本之前,需要生成参数:

syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector

% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];

% Initial vector
x0 = [1; 1];

% Tolerance:
tol = 1e-10;
现在,将脚本制作成函数:

% To run in MATLAB, do: 
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);

function [n, xout, tol] = Jacobian2D(f, J, x0, tol)

% Just to be sure...
syms x, y;

% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB

% Initialize counter
n = 0;

% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';

% Computation loop     
while ep > tol && n < 100 
   g = subs(f, {x,y}, xout);   %g(x)
   ep = abs(g(1)) + abs(g(2)); %error     
   Jg = subs(J, {x,y}, xout);  %Jacobian  
   yout = xout - Jg\g;         %iterate     
   xout = yout;                %update x     
   n = n + 1;                  %counter+1     
end

% Transpose and convert back to number representation
xout = double(xout');
%要在MATLAB中运行,请执行以下操作:
%[n,xout,tol]=Jacobian2D(f,J,x0,tol);
%disp('n=');disp(n);disp('x=');disp(xout);disp('tol=');disp(tol);
函数[n,xout,tol]=Jacobian2D(f,J,x0,tol)
%只是想确定一下。。。
符号x,y;
%初始化错误
ep=1;%注:eps是MATLAB中的保留关键字
%初始化计数器
n=0;
%对于循环的开始
%必须转换为行向量,因为SUB需要这样做
xout=x0';
%计算循环
而ep>tol&n<100
g=subs(f,{x,y},xout);%g(x)
ep=abs(g(1))+abs(g(2));%错误
Jg=subs(J,{x,y},xout);%雅可比
yout=xout-Jg\g;%迭代
xout=yout;%更新x
n=n+1;%计数器+1
结束
%转置并转换回数字表示法
xout=double(xout');
我可能应该告诉您,当您使用符号数学工具箱进行计算时,计算数字时,数字的数据类型是一个
sym
对象。您可能希望将这些值转换回实数,因此可以使用
double
将它们转换回实数。但是,如果您将它们保留为
sym
格式,它会将您的数字显示为整洁的分数(如果您正在查找的话)。如果需要小数点表示法,请强制转换为双精度

现在,当您运行此函数时,它应该会提供您所需的内容。我还没有测试过这段代码,但我很确定这会起作用

很高兴回答您可能还有的任何问题。希望这有帮助


干杯

它看起来很棒,但是我不理解这行代码。难道没有更简单的命令来计算雅可比矩阵吗?我有一个n维的推广…@bela83有一个雅可比函数,但我做了你在
J
行中看到的,以明确显示计算结果。-顺便说一句,如果你觉得这个答案很有用,你可以随时更新我的答案:D.这些文件需要不同的“.m”文件吗?还是要组合成一个脚本?在我的R2015a版本中,我似乎没有符号工具箱。因此,我无法使此示例正常工作。@tannman357 1)是单独的文件。2) 如果您已经知道导数是什么,您可以自己创建雅可比矩阵,而不必使用符号工具箱。我稍后会修改这篇文章来解释这一点,但我目前无法解释。