我正在尝试构建一个函数,该函数可以在Matlab中使用牛顿方法求解n个未知数的n-1(非线性)方程组。
我在网上进行了一些研究,并采用了以下程序:
使用matlab的'null'函数应用于第一偏导数(雅可比)的数组,以获得m元素向量,(称为向量v,),它与部分的所有m-1向量正交。 。在沿着该向量进行距离h0之后,再次使用“空”函数,这次从该高级点找到与v正交的m-1维子空间。将所有原始坐标投影到该子空间中的坐标,您可以执行m-1维Newton-Raphson过程,如果步骤h0不太大,该过程应该非常快速地收敛。然后将其转换回原始坐标。
我有以下方程组:
fun = @(x,y,z)[x.^3+y.^2+z.^2,x.^2-y.^3+sin(z)]
这是Jacobian:
Jac = @(x,y,z)[3*x^2, 2*y, 2*z; 2*x, -3*y^2, cos(z)]
初步猜测: x0 = [1,1,1]
在我的函数中,我将向量转换为数字,因此我可以使用它们: x = num2cell(x0)
然后我想做N次迭代:
for numIterations = 1:N
%calculate the function values at the current iteration
F = fun(x{:})
%calculate the jacobian matrix
J = Jac(x{:})
%find direction in which the curve extends:
v = null(J)
xnew = xold + h0 * v
xnew = xnew'
subspace = null(xnew)
nextX = multinewton(f,df,xnew)
现在我陷入了使用牛顿方法计算下一个坐标的部分。我该怎么做?
我想用来计算下一个坐标的牛顿方法是以下方法:
function [zero,res,niter]=newton(f,df,x0,tol,nmax,varargin)
%NEWTON Find function zeros.
% ZERO=NEWTON(FUN,DFUN,X0,TOL,NMAX) tries to find the zero ZERO of the
% continuous and differentiable function FUN nearest to X0 using the Newton
% method. FUN and its derivative DFUN accept real scalar input x and returns
% a real scalar value. If the search fails an error message is displayed.
% FUN and DFUN can also be inline objects.
%
% [ZERO,RES,NITER]= NEWTON(FUN,...) returns the value of the residual in ZERO
% and the iteration number at which ZERO was computed.
x = x0;
fx = feval(f,x,varargin{:});
dfx = feval(df,x,varargin{:});
niter = 0;
diff = tol+1;
resultVector = [x];
while diff >= tol && niter <= nmax
disp(x)
niter = niter + 1;
diff = - dfx\fx;
x = x + diff;
diff = abs(diff);
fx = feval(f,x,varargin{:});
dfx = feval(df,x,varargin{:});
resultVector = [resultVector x];
end
if niter > nmax
fprintf(['newton stopped without converging to the desired tolerance',...
'because the maximum number of iterations was reached\n']);
end
res = fx
zero = x;
disp('Number of iterations is:');
disp(niter);
plot(resultVector);
return
我想我并不完全理解“将所有原始坐标投影到这个子空间中的坐标,你可以执行m-1维Newton-Raphson程序”。这是什么意思? 我将什么作为牛顿方法的输入?
非常感谢提前!
答案 0 :(得分:1)
我将通过调整牛顿法来回答一个问题,即如何通过Matlab 解决n个未知数的n-1方程组。我的改编不是你通过研究找到的 - 它更简单。
Newton方法的想法是我们围绕某个猜测点线性化系统并解决所得到的线性系统。解决方案成为我们的下一个猜测。
如果您的系统不确定(方程式少于未知数),线性系统也将不确定。 Matlab的\
运算符可以很好地处理这样的系统:返回最小范数的解。那么,为什么不使用它,如果它有效?与具有n个未知数的n个方程的情况相比,不需要改变代码。
以下是我的实现:调用newtonund(1,1,1)
以20个步骤找到根,即-1.226458955, 1.357877375, -0.031788652
。我稍微改变了你的方程组,用cos(z)代替sin(z)。它也以原始形式工作,但结果是(可预测)0, 0, 0
并不那么有趣。
function newtonund(x,y,z)
tol = 1e-6;
diff = tol+1;
n = 0
nmax = 1000;
disp(' n x(n) y(n) z(n) |f(x)|');
X = [x;y;z];
Y = F(X);
while diff>=tol & n<=nmax
changeX = -dF(X)\Y;
X = X + changeX;
Y = F(X);
diff = norm(changeX);
n = n+1;
fprintf('%3d %15.9f %15.9f %15.9f %10.5g \n', n, X(1), X(2), X(3), norm(Y));
end
if n>nmax
disp('Failed to converge');
else
disp('Root found');
end
end
function Y=F(X)
x=X(1); y=X(2); z=X(3);
Y=[x^3+y^2+z^2 ; x^2-y^3+cos(z)];
end
function J=dF(X)
x=X(1); y=X(2); z=X(3);
J=[3*x^2, 2*y, 2*z; 2*x, -3*y^2, -sin(z)];
end
第changeX = -dF(X)\Y
行表达了牛顿的方法。通常dF(X)
是方阵;在欠定的情况下,它是矩形的,但算法无论如何都有效。