I have to code the Secant Method: a variant of the Newton-Raphson method.
I have done the following:
function [SecantMethod] = SecantMethod(x0, x1);
%this is a variation on the Newton-Raphson MEthod, uses two inital guesses
%so that we do not have to explicitly work of the derivative of f(x).
x0 = 2;
x1 = 1;
%the two guesses
f0 = f(x0);
f1 = f(x1);
%two coressponding values of the function evaluated at x0 and x1
x = x1 - (f1*((x1 - x0)/(f1 - f0)));
%actual Secant Method (finds x axis intercept between two guesses
end
When I run the code in Matlab, an error appears "Undefined function or variable 'f'."
I dont have any particular function that I want to solve I just have to code it so I am not sure how to do so.
You can have a function take a function as an argument as follows:
function [SecantMethod] = SecantMethod(f,x0, x1);
disp(f(x0));
end
Then in your code:
%make anonymous function:
f=#(x)(x.^2);
%or:
f=#sin;
%and simply:
SecantMethod(f,1,2)
% or just:
SecantMethod(#myfucntion,1,2)
Working with trying to make an Olver's method, my code is working however I want to try and combine the 3 functions into multi output function with use of diff() but i'm struggling to manipulate the inputs without jeopardizing outputs.
% Defining the function in the equation f(x)=0
function y = f(x)
y = x-exp(1/x);
end
% Defining the derivative of the function in the equation f(x)=0
function y = fd(x)
y = 1+exp(1/x)/(x^2);
end
% Defining the second derivative of the function in the equation f(x)=0
function y = fdd(x)
y = exp(1/x)*(2*x+1)/(x^4);
end
It is not very clear but having all these as a single function (with the use of Symbolic Toolbox) can be done as follows:
function [y1, y2, y3] = getDerivatives(a)
syms f(x)
f(x) = x-exp(1/x);
fd = diff(f,x);
fdd = diff(f,x,2);
y1 = double(f(a));
y2 = double(fd(a));
y3 = double(fdd(a));
end
and you can run it as follows:
[y1, y2, y3] = getDerivatives(1)
y1 =
-1.7183
y2 =
3.7183
y3 =
-8.1548
I would like to find the values of the function for which its derivative is equal to zero.
function val = Heart(x1, x2)
val=(1.25*x2-sqrt(abs(x1))).^2+x1.^2-1;
endfunction;
I've tried it with the numderivative function.
Scilab cannot solve this problem in the way your function is currently defined because Heart() is an implicit function. As answered here, Scilab is not capable of doing implicit differentiation. Moreover, your equation actually defines a 3D surface, so what you can calculate are actually partial derivatives.
If you want to find the x1 values in which the derivative in relation to x1 of the implicit curve 0=Heart(x1,x2) are zero, you can use the method presented in this answer from your own previous question to solve this.
If you inspect the plot of heart curve, you'll see that there are only two points where the derivative is zero (two maxima): they are located in the upper part of the curve and are near x1=-0.6 and x1=0.6, respectively. To find more approximate values of these points, you should do the following:
Take the upper part of the heart (use Wolfram|Alpha to find it) and define a new function.
Use numderivative() to define its derivative, d_heart(). The answer we are looking for are the zeros of this function.
Use fsolve() to solve 0=d_heart(x1). You should input two guesses and they can be -0.6 and 0.6.
Something like this:
function y = heart_up(x1)
y = 4/5 * (sqrt(abs(x1))+sqrt(1-x1.^2))
endfunction
function y = d_heart(x1)
y = numderivative(heart_up, x1);
endfunction
x1 = fsolve(-0.6, d_heart); y1 = heart_up(x1);
x2 = fsolve( 0.6, d_heart); y2 = heart_up(x2);
You can visualize that heart_up() is really the upper part of the heart and that the results are right by plotting them:
x = -1:0.01:1;
contour2d(x, 2*x, Heart, [0 0]);
plot2d(x, heart_up(x), 2);
plot2d([x1 x2], [y1 y2], -2);
Is it possible to shorten (improve) this script? I think of the Jacobian Heart function, evaluate it and find the points where it is zero. Some rides !!!
Following the indications of luispauloml:
[function val = Heart(x1, x2)
val=(1.25*x2-sqrt(abs(x1))).^2+x1.^2-1;
endfunction;
function y = heart_up(x1)
y = 4/5 * (sqrt(abs(x1))+sqrt(1-x1.^2))
endfunction
function y = heart_down(x1)
y = 4/5 * (sqrt(abs(x1))-sqrt(1-x1.^2))
endfunction
function y = du_heart(x1)
y = numderivative(heart_up, x1);
endfunction
function y = dd_heart(x1)
y = numderivative(heart_down, x1);
endfunction
x1 = fsolve(-0.6, du_heart); y1 = heart_up(x1);disp(y1,"y1",x1,"x1");
x2 = fsolve( 0.6, du_heart); y2 = heart_up(x2);disp(y2,"y2",x2,"x2");
x3 = fsolve( 0.0, du_heart); y3 = heart_up(x3);disp(y3,"y3",x3,"x3");
x4 = fsolve( 0.0, dd_heart); y4 = heart_down(x4);disp(y4,"y4",x4,"x4");
x = -1:0.01:1;
contour2d(x, 2*x, Heart, \[0 0\]);
plot(\[x1 x2\],\[y1 y2\],'gd');
plot(\[x3 x4\],\[y3 y4\],'rx');
replot(\[-1.415,-1,1.415,1.415\]);][1]
Another possible solution is:
With this function we have begun to familiarize ourselves with Scilab.
In the script that I propose we have found the critical or extreme points of the Heart function.
We call your attention in reading the comments !!!!
function val = Hxyg(x,y)
val=(1.25*y-sqrt(abs(x))).^2+x.^2-1;
endfunction;
x = -1:0.01:1;
contour2d(x, 2*x, Hxyg, [0 0]);
replot([-1.415,-1,1.415,1.415]);
//We define the Hxy function with x as additional input argument( as a parameter)
//Since y, will be our unknown, we have interposed x and y in the argument list of the Hxy function
//(y it is the unknown and x is the parameter).
//This will be necessary to determine the intersects on the Y axis
function val = Hxy(y,x)
val=(1.25*y-sqrt(abs(x))).^2+x.^2-1; // switched .^ to ^ to handle vectors
endfunction;
function [val] = HH(v)//v:(y,x)
x=v(2);
y=v(1);
val=Hxy(y,x);
endfunction;
function Jpx=dfx(v)//v:(y,x)
Jpx=numderivative(HH,v);
Jpx=Jpx(2);
endfunction
//Find the local maxima.
function Z = flm(v)//v:(y,x)
Z = [ HH(v)
dfx(v)
]
endfunction
//v:(y,x)
xlm1=fsolve([1.4;-0.4],flm)
disp(xlm1)
xlm2=fsolve([1.4;0.4],flm)
disp(xlm2)
plot([xlm1(2) xlm2(2)],[xlm1(1) xlm2(1)],'gx')
//Find the y-intercepts. Hxy(y,x)
//the Hxy function uses x as a parameters.
//We define the Hxy function with x as additional input argument( as a parameter),
//which is declared after the y unknown. Then we pass a list as the second input argument
//of the fsolve function after initial value of Hxy function argument; in this situation only variable y.
//The first element of the list is the Hxy function. The additional variable x is directly passed to the Hxy function.
x=0.0;
yint1=fsolve(1,list(Hxy,x))// --->Hxy(y,x)=>1.5625*y^2-1
disp(yint1)
yint2=fsolve(-1,list(Hxy,x))// ---> Hxy(y,x)=>1.5625*y^2-1
disp(yint2)
plot([x x],[yint1 yint2],'rx')
Heart Critical points or extreme points
With an anonymous function, you can return any number of outputs. What I need is to be able to use functors (anonymous functions as arguments of other functions), while not knowing how many outputs I will get.
This is to avoid code duplication by injecting functions calls inside a while loop which is reused in many functions.
Example:
function y = foo( x )
y = x;
end
function [y1, y2] = goo( x1, x2 )
y1 = x1;
y2 = x2;
end
function [ varargout ] = yolo( functor, varargin )
varargout = functor(varargin{:});
end
I want to be able to call:
y = yolo(#foo, 2)
[y1, y2] = yolo(#goo, 3, 4);
Is there any way to achieve this ?
Thanks
It is not possible to get the number of outputs of an anonymous function (a function handle to an inline function) because the output is always varargout and therefore nargout is always going to return -1
myfunc = #(x, y) x + y;
nargout(myfunc)
% -1
However, it looks like you don't have anonymous functions, but rather just function handles to normal functions that are defined in an .m file and have an explicit number of output arguments. In this case, you can combine nargout with {:} indexing to fill varargout with all of the output arguments.
function y = foo(x)
y = x;
end
function [y1, y2] = goo(x1, x2)
y1 = x1;
y2 = x2;
end
function varargout = yolo(functor, varargin)
[varargout{1:nargout(functor)}] = functor(varargin{:});
end
y = yolo(#foo, 2)
[y1, y2] = yolo(#goo, 3, 4)
I'm trying to create a function, that has two output arguments:
1. The calculated f(x) value
2. The gradient
But it's calling itself recursively all the time.
What am I doing wrong?
function [y, gra] = f1(x)
y = x^2
syms z
gra = gradient(f1(z))
Thanks.
edit:
Now I have this:
function [y, gra] = f1(x)
y = x^2
if nargout == 2
syms x
gra = gradient(f1(x))
end
edit 2:
I'm trying to use the function in the following:
[y, grad] = f1(5);
y_derived = grad(10);
I think this is what you want to do:
function [y, gra] = f1(x)
f=#(x) x^2;
y=f(x); %// calculate y
syms z %// initialise symbolic variable
gra=gradient(f(z),z); %// symbolic differentiation
This will return g as a symbolic function. To calculate a value, you can use subs(gra,z,123), or, if you are going to evaluate it many times, do gradFunc=matlabFunction(gra) then gradFunc(v) where v is a vector or matrix of points you want to evaluate.
That's because the argument into gradient is your function name f1(z). As such, it keeps calling f1 when your original function is also called f1, and so the function keeps calling itself until you hit a recursion limit.
I think you meant to put gradient(y) instead. Try replacing your gradient call so that it is doing:
gra = gradient(y);