I have this code (*) and when I do:
»syms x
»newton_raphson({((5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360))}, diff(((5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360)),1), 0.001, eps, 5, 0.1)
this error appears:
Error using feval
Argument must contain a string or function_handle.
Error in newton_raphson (line 10)
fz = feval(f,z(1));
How can I fix this error?
(*)
function [raiz, zn, fz, i] = newton_raphson(f, flinha, x0, eps, iter_max, debug)
if nargin < 4
eps = 1e-6;
end
if nargin < 5
iter_max = 1e3;
end
z(1) = x0;
fz = feval(f,z(1));
fzlinha = feval(flinha,z(1));
if (nargin > 5 && debug > 0)
fprintf(2,'i=%d z=%23.18G fz=%G fzlinha=%G\n',0,x0,fz,fzlinha);
end
for i = 1:iter_max
if abs(fzlinha) == 0 % f'(x0) equal zero
disp('O valor da derivada em Xi não pode ser zero');
z(i+1) = x0;
return
end
z(i+1) = x0 - fz / fzlinha;
fz = feval(f,z(i+1));
fzlinha = feval(flinha,z(i+1));
dif = abs(z(i+1) - x0);
if (nargin > 5 && debug > 0)
fprintf(2,'i=%d z=%23.18G fz=%G fzlinha=%G dif=%E\n',i,z(i+1),fz,fzlinha,dif);
end
if dif < eps
break;
elseif i == iter_max
disp('Foi excedido o número máximo de iterações (iter_max)');
break
end
x0=z(i+1);
end
zn = z';
raiz = z(i+1);
end`
You are passing a symbolic expression to a function designed to evaluate an anonymous function, function handle, or a function on the Matlab path with it's name indicated by a string via feval. If you desire Matlab to do the differentiation for you, you can first use symbolic expressions and then convert them to anonymous functions via matlabFunction like this
syms x f Df
%
% Symbolic expressions
f = (5400.*(1 + x)*0^360) - (1450000.*x.*(1 + x).^360);
Df = diff(f,x);
%
% Convert to anonymous functions
f = matlabFunction(f ,'Vars',x);
Df = matlabFunction(Df,'Vars',x);
Related
I am trying to integrate over a constant function in MATLAB 2017a, but I am stuck. First of all when I integrate using the following script, I get the right output. So the script works for a x0 which depends on t.
function E=sol(n,k)
x0 = #(t) t^(2);
j = 0;
E = zeros(n,1);
while j < n+1 ;
K = matlabFunction(subs(po(j,k))) ;
eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
E(j+1,1) = subs(sprintf('x%d',j+1))
j = j+1;
end
end
Where function po(j,k) is as follows,
function A_j = po(j,k) % Adomian polynomials
if j >0
x = sym('x',[1 j]);
syms p; % Assinging a symbolic variable for p
syms x0;
S = x0+ sum(p.^(1:j) .* x) ; % Sum of p*x up to order j
Q =f(S,k); % Taking the k-th power of S, i.e.
A_nc = diff(Q,p,j)/factorial(j); % Taking the j-th order derivative
A_j = subs(A_nc,p,0) ; % Filling in p=0
else
syms x0;
S = x0;
A_j =f(S,k); % Taking the k-th power of S,
end
end
And where f(x,k) is,
function F = f(x,k) % Nonlinear function of k power
F = x^k ;
end
Now when I cal sol(n,k) it does work. But when I try to change my x0 function in sol(n,k) in a constant function like,
function E=solcon(n,k)
x0 = #(t) 2.*ones(size(t));
j = 0;
E = zeros(n,1);
while j < n+1 ;
K = matlabFunction(subs(po(j,k))) ;
eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
E(j+1,1) = subs(sprintf('x%d',j+1))
j = j+1;
end
end
It does not work, As you can see I added *ones(size(t)); just to make it a function of t. But unfortunately it still doesn't work when I call,
K = matlabFunction(subs(po(j,k))) ;
I get,
#()4.0
And then I get an error when I call,
eval(sprintf('x%d = integral(K,0,1);',j+1))
Could anyone help me out trying to integrate over a constant?
The error I get when I call solcon(10,2) is
Error using symengine>#()4.0
Too many input arguments.
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
Error in solcon1 (line 7)
eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
EDIT 2
I used the following script,
function E=solcon(n,k)
x0 = #(t) 2.*ones(size(t));
j = 0;
E = zeros(n,1);
while j < n+1 ;
K = matlabFunction(subs(po(j,k))) ;
fstr= func2str(K)
if fstr(3) == ')';
x{j+1} = K*(1-0)
else x{j+1} = integral(K,0,1)
end
E(j+1,1) = subs(x{j+1},1);
j = j+1
end
end
But the following error occurs,
Undefined operator '*' for input arguments of type 'function_handle'.
Error in solcone1 (line 9)
x{j+1} = K*(1-0);
I am going to ignore the terrible choice of using eval, especially when you can do
x{j+1} = integral(K,0,1);
Read more on why dynamic variables and eval are terrible
Your problem is that matlabFunction is a smartass. When it detects that your function does not have any dependency to x, it gives you a function with empty input arguments #()4.0. As you see, integral does not like that.
A way of solving the problem is detecting this before calling integral. You could check if it has input arguments, and if it does not, then evaluate the integral "by hand"
...
while j < n+1 ;
K = matlabFunction(subs(po(j,k))) ;
fstr=func2str(K);
if fstr(3)==')'
x{j+1}=K()*(1-0); % evaluate the integral yourself
else
x{j+1} = integral(K,0,1);
end
E(j+1,1) = subs(x{j+1});
j = j+1;
end
...
The problem is considerably more difficult that I though I was. Either rewrite the entire thing, or using eval:
...
while j < n+1 ;
K = matlabFunction(subs(po(j,k))) ;
fstr=func2str(K);
if j==0
eval(sprintf('x%d = K()*(1-0);;',j+1)) ;
else
eval(sprintf('x%d = integral(K,0,1);',j+1)) ;
end
E(j+1,1) = subs(sprintf('x%d',j+1));
j = j+1;
end
...
I am new to Matlab and trying to find a solution to the error of my code:
Not enough input arguments.
Error in F9>f (line 42)
y = (2 - 2*t*x) / (x^2 + 1) ;
Error in F9 (line 18)
e = euler(f, trange(1), y0_value, h, trange(end));
function [] = F9()
% Euler's Method to solve given functions
% Set initial values
hi = [1/2, 1/4];
trange = [0, 2];
y0_value = 1;
% Set functions' and exact functions' handles
% Calculate and show results
% Loop for functions
for i = 1:2
fprintf('###########\n');
fprintf('Function #%d\n', i)
fprintf('###########\n');
exact_value = f_exact(trange(end));
% Loop for h
for h = hi
% Euler calculations
e = euler(f, trange(1), y0_value, h, trange(end));
fprintf('\nh: %f\n', h);
fprintf('\nEuler: %f \n', e(end));
fprintf('Error: %f\n\n', abs((e(end)-exact_value)/exact_value));
end
fprintf('Exact: %f\n\n', exact_value);
end
end
% Euler's Method
function y = euler(f, t0, y0, h, tn)
n = (tn-t0)/h;
% Initialize t, y
[t, y] = deal(zeros(n, 1));
% Set t0, y0
t(1) = t0;
y(1) = y0;
for i = 1:n
t(i+1) = t(i) + h;
y(i+1) = y(i) + h/2 * (f(t(i), y(i))+ f(t(i+1) , y(i) + h * f(t(i), y(i))));
end
end
% Functions to solve
function y = f(t, x)
y = (2 - 2*t*x) / (x^2 + 1) ;
end
function y = f_exact(x)
y = (2*x + 1) / (x^2 + 1);
end
When you pass f to euler you need to pass it as a handle, i.e. precede it with a #:
e = euler(#f, trange(1), y0_value, h, trange(end));
I've trouble creating a code for finding roots of a function as an input by the fixed point method,
Here I've done it using Newton-Raphson method:
clc,close all
syms x;
fprintf('Newton Raphson\n');
Fun = input('\nType a function \n');
x0 = input('\nType initial value \n');
f = sym(Fun);
df = diff(f,x);
while (1)
a = subs(f, 'x', x0);
b = subs(df, 'x', x0);
x1 = x0 - a/b
er = (abs((x1 - x0)/x1))*100
if ( er <= 0.05)
break;
end
x0 = x1;
end
And here's a code using the fixed point method but on a fixed function not taken as an input:
clc,close all
x0 = 0.5
while (1)
x1 = (exp(-x0) - sin(x0)) / 5
er = (abs((x1 - x0)/x1))*100
if ( er <= 0.05)
break;
end
x0 = x1;
end
But I can't do it using function as an input because the fixed point method sperates the variable x in the left side.
How can I do it?
I am not so much experiences with Matlab. I just need it for the sake of solving some lengthy non-linear equations. Instead of using fzero, I wanna use Newton-Raphson's to solve the equation.
newton.m file contains the following code.
function [ x, ex ] = newton( f, df, x0, tol, nmax )
if nargin == 3
tol = 1e-4;
nmax = 1e1;
elseif nargin == 4
nmax = 1e1;
elseif nargin ~= 5
error('newton: invalid input parameters');
end
x(1) = x0 - (f(x0)/df(x0));
ex(1) = abs(x(1)-x0);
k = 2;
while (ex(k-1) >= tol) && (k <= nmax)
x(k) = x(k-1) - (f(x(k-1))/df(x(k-1)));
ex(k) = abs(x(k)-x(k-1));
k = k+1;
end
end
And in the main file, I have called this function as follows:
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
When I run this function, it gives me the following error.
Error using sym/subsref (line 9)
Error using maplemex
Error, (in MTM:-subsref) Array index out of range
Error in newton (line 37)
x(1) = x0 - (f(x0)/df(x0));
Error in main (line 104)
ext_H = newton( exp(x) + x^3, diff(exp(x) + x^3), 9, 0.5*10^-5, 10);
Could anyone please help me to get through this?
You can probably use Matlab's fsolve (http://uk.mathworks.com/help/optim/ug/fsolve.html) with a couple of options
x0 = 9;
options = optimoptions('fsolve','Algorithm','levenberg-marquardt','TolFun',5*10^-6,'MaxIter',100);
x = fsolve(#(x)(exp(x) + x^3), x0,options);
or just fzero (http://uk.mathworks.com/help/optim/ug/fzero.html) which implements BD algorithm
x = fzero(#(x)(exp(x) + x^3), x0);
I need to write a proper implementation of the Ridder's method in Matlab. I must define the function as
function [x sol, f at x sol, N iterations] = Ridders(f, x1, x2, eps f, eps x)
The explanation I was given is:
bracket the roots (x1, x2)
evaluate the midpoint (x1 + x2)/2
find new approximation for the root
x4 = x3 + sign(f1 - f2) [f3/((f3)^2 - f1f2)^1/2)](x3 - x1)
check if x4 satisfies the convergence condition. if yes, stop. if not...
rebracket the root using x4 and whichever of x1, x2, or x3 is closer to the root
loop back to 1
I have no idea how to implement this in matlab. Help?
In Matlab, you would define your function as:
function [list of outputs] = myfunc(list of input variables)
%function definition to compute outputs using the input variables.
In your case if you would like x4 (i.e root) to be your output, you would do:
function root = riddler(func, x1, x2, xaccuracy, N)
xl = x1;
xh = x2;
fl=func(x1)
fh=func(x2)
for i = 1:N
xm = 0.5*(xl+xh);
fm = func(xm);
s = sqrt(fm*fm - fl*fh)
if s == 0
return;
end
xnew = xm + (xm - xl)*sign(fl - fh)*fm/s %update formula
.
.
. % extra code to check convergence and assign final answer for root
. % code to update xl, xh, fl, fh, etc. (i.e rebracket)
.
end % end for
I wrote a Matlab implementation of Ridder's method on the Matlab file exchange: submission 54458. I've copied the code below for reference:
function xZero = rootSolve(func,xLow,xUpp)
% XZERO = ROOTSOLVE(FUNC, XLOW, XUPP)
%
% FUNCTION: This function uses Ridder's Method to return a root, xZero,
% of func on the interval [xLow,xUpp]
%
% INPUTS:
% func = a function for a SISO function: y = f(x)
% xLow = the lower search bound
% xUpp = the upper search bound
%
% OUTPUTS:
% xZero = the root of the function on the domain [xLow, xUpp]
%
% NOTES:
% 1) The function must be smooth
% 2) sign(f(xLow)) ~= sign(f(xUpp))
% 3) This function will return a root if one exists, and the function is
% not crazy. If there are multiple roots, it will return the first one
% that it finds.
maxIter = 50;
fLow = feval(func,xLow);
fUpp = feval(func,xUpp);
xZero = [];
tol = 10*eps;
if (fLow > 0.0 && fUpp < 0.0) || (fLow < 0.0 && fUpp > 0.0)
for i=1:maxIter
xMid = 0.5*(xLow+xUpp);
fMid = feval(func,xMid);
s = sqrt(fMid*fMid - fLow*fUpp);
if s==0.0, break; end
xTmp = (xMid-xLow)*fMid/s;
if fLow >= fUpp
xNew = xMid + xTmp;
else
xNew = xMid - xTmp;
end
xZero = xNew;
fNew = feval(func,xZero);
if abs(fNew)<tol, break; end
%Update
if sign(fMid) ~= sign(fNew)
xLow = xMid;
fLow = fMid;
xUpp = xZero;
fUpp = fNew;
elseif sign(fLow) ~= sign(fNew)
xUpp = xZero;
fUpp = fNew;
elseif sign(fUpp) ~= sign(fNew)
xLow = xZero;
fLow = fNew;
else
error('Something bad happened in riddersMethod!');
end
end
else
if fLow == 0.0
xZero = xLow;
elseif fUpp == 0.0
xZero = xUpp;
else
error('Root must be bracketed in Ridder''s Method!');
end
end
Some principal concepts that might help:
function handles (you need to provide f in this format)
valid variable names (many variable names in your definition are not valid)