Пытаясь решить уравнения одновременности в Matlab, не может понять, как форматировать функции

Недавно один лектор дал мне фрагмент кода Matlab за способ решения одновременных уравнений с использованием метода Ньютона-Рафсона с помощью матрицы Якоби (я также оставил в его комментариях). Тем не менее, хотя он и предоставил мне основной код, я не могу заставить его работать, как бы я ни старался. Я потратил много часов, пытаясь представить функцию "func", но безрезультатно, часто получая сообщение о том, что не хватает входных данных. Буду признателен за любую помощь, особенно в том, как написать функцию 'func'.

  function root = newtonRaphson2(func,x,tol)

% Newton-Raphson method of finding a root of simultaneous    
% equations fi(x1,x2,...,xn) = 0, i = 1,2,...,n.    
% USAGE: root = newtonRaphson2(func,x,tol)    
% INPUT:    
% func = handle of function that returns[f1,f2,...,fn].
% x = starting solution vector [x1,x2,...,xn].
% tol = error tolerance (default is 1.0e4*eps).
% OUTPUT:
% root = solution vector.

if size(x,1) == 1; x = x'; end % x must be column vector    
for i = 1:30    
   [jac,f0] = jacobian(func,x);    
   if sqrt(dot(f0,f0)/length(x)) < tol   
      root = x; return
   end   

   dx = jac\(-f0);   
   x = x + dx;    
   if sqrt(dot(dx,dx)/length(x)) < tol    
      root = x; return    
   end
end

error('Too many iterations')

function [jac,f0] = jacobian(func,x)

% Returns the Jacobian matrix and f(x).

h = 1.0e-4;    
n = length(x);    
jac = zeros(n);    
f0 = feval(func,x);    
for i =1:n    
   temp = x(i);    
   x(i) = temp + h;    
   f1 = feval(func,x);    
   x(i) = temp;    
   jac(:,i) = (f1 - f0)/h;   
end

Решаемые одновременные уравнения:

sin(x)+y^2+ln(z)-7=0
3x+2^y-z^3+1=0
x+y+Z-=0

с отправной точкой (1,1,1).

Тем не менее, они являются произвольными и могут быть заменены на что угодно, в основном мне просто нужно знать общий формат. Большое спасибо, я знаю, что это может быть очень простой задачей, но я только недавно начал учить себя матлабу.

1 ответ

Вам нужно создать новый файл с именем myfunc.m (или любое другое имя), которое принимает один входной параметр - вектор столбца x - и возвращает один выходной вектор - вектор столбца y такой, что y = f(x),

Например,

function y = myfunc(x)

    y = zeros(3, 1);
    y(1) = sin(x(1)) + x(2)^2 + log(x(3)) - 7;
    y(2) = 3*x(1) + 2^x(2) - x(3)^3 + 1;
    y(3) = x(1) + x(2) + x(3);

end

Затем вы можете обратиться к этой функции как @myfunc как в

>> newtonRaphson2(@myfunc, [1;1;1], 1e-6);

Причина специальной записи в том, что Matlab позволяет вам вызывать функцию без параметров, опуская символы () которые следуют за этим. Так, например, Matlab интерпретирует myfunc когда вы вызываете функцию без аргументов (поэтому она пытается заменить ее своим результатом), тогда как @myfunc относится к самой функции, а не к ее результату.

В качестве альтернативы вы можете написать функцию напрямую, используя @ обозначение, как в

>> newtonRaphson2(@(x) exp(x) - 3*x, 2, 1e-2)
ans =
     1.5315
>> newtonRaphson2(@(x) exp(x) - 3*x, 1, 1e-2)
ans =
     0.6190

которые являются двумя корнями уравнения exp(x) - 3 * x = 0,


Отредактируйте - кроме этого, у вашего профессора ужасный стиль кодирования (если код в вашем вопросе является прямой копией того, что он вам дал, и вы не искали его по пути). Было бы лучше написать код, подобный этому, с отступом, поясняющим, какова структура кода.

function root = newtonRaphson2(func, x, tol)
% Newton-Raphson method of finding a root of simultaneous
% equations fi(x1,x2,...,xn) = 0, i = 1,2,...,n.
%
% USAGE: root = newtonRaphson2(func,x,tol)
%
% INPUT:
%   func = handle of function that returns[f1,f2,...,fn].
%   x    = starting solution vector [x1,x2,...,xn].
%   tol  = error tolerance (default is 1.0e4*eps).
%
% OUTPUT:
%   root = solution vector.

    if size(x, 1) == 1; % x must be column vector
        x = x';
    end 

    for i = 1:30
        [jac, f0] = jacobian(func, x);

        if sqrt(dot(f0, f0) / length(x)) < tol
            root = x; return
        end

        dx = jac \ (-f0);
        x  = x + dx;

        if sqrt(dot(dx, dx) / length(x)) < tol
            root = x; return
        end
    end

    error('Too many iterations')

end

function [jac, f0] = jacobian(func,x)
% Returns the Jacobian matrix and f(x).

    h = 1.0e-4;
    n = length(x);
    jac = zeros(n);
    f0 = feval(func,x);

    for i = 1:n
        temp = x(i);
        x(i) = temp + h;
        f1 = feval(func,x);
        x(i) = temp;
        jac(:,i) = (f1 - f0)/h;
    end

end
Другие вопросы по тегам