put argument inside mathematical function in matlab [duplicate] - matlab

I want to write a function that returns the value of f(y) for any value of y:
f(y) =tan( sin(y) - sin(tan(y)) )
How can I write this as a function in MATLAB?

Here is an example function for your purpose
function y = f(x)
y = tan(sin(x)-sin(tan(x)));
end

You could use an anonymous function, as elluded to in the comments by
obchardon:
f = #(y) tan(sin(y) - sin(tan(y)))
% usage like any other function:
f(1)
Note that you do not include the (y) on the left hand side of the =, this syntax is reserved for indexing into variables, or symbolic math.

Related

What is the difference between creating creating functions using function handle and declaring syms?

It seems that, to create a function f(x,y)=x+y, I can have two approaches.
syms x y; f(x,y) = x+y
f = #(x,y) x+y
They seem very similar, and I do not know whether there are some subtle differences.
Typically, if I need to evaluate the function for inputs or many samples I would opt-in to using the second method (function handles/anonymous functions).
Method 1: Symbolic Functions
This method allows the function to be evaluated at a specific point/value by using the subs(), substitution function. Both plots can be plotted using fsurf().
clear;
syms x y
f(x,y) = x+y;
fsurf(f);
subs(f,[x y],[5 5])
Variants and offsetting of symbolic functions can be done similarly to anonymous functions/function handles with the one caveat of not needing to include the input parameters in the #().
g = f(x,y) + f(x-5,y-5)
fsurf(g);
Method 2: Anonymous Functions/Function Handles
This method allows you to directly input values into the function f(x,y). I prefer anonymous functions because they seem more flexible.
clear;
f = #(x,y) x+y;
fsurf(f);
f(5,5)
Some cool things you can do is offset and easily add variants of anonymous functions. Inputs can also be in the form of arrays.
x = 10; y = 2;
f(x-5,y-5) + f(x,y)
g = #(x,y) f(x,y) + f(x-5,y-20);
fsurf(g);
Ran using MATLAB R2019b

Calculating the numeric derivative

So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.

substituting my function in an expression

I have defined a function as mystep in matlab 2014b, which is the same as heaviside except for mystep(0) which is one instead of 0.5.
Now I would like to substitute my function using subs into an expression but it is not possible. Function is:
f(x) = heaviside(x) * x^2;
g(x) = subs(f(x) , heaviside(x) , mystep(x));
g(x) =
heaviside(x)
As you see, matlab does not do anything, but if I change mystep with dirac(x), it goes well.
g(x) = subs(f(x) , heaviside(x) , dirac(x))
g(x) =
dirac(x)
what should I do? is there any way to do this?
Any other help like showing a way to change the value of heaviside at origin in matlab 2014b might be useful.
The content of mystep
function Y = mystep(X)
%//This function is a user-defined unit step function, which has the exact
%//properties of matlab heaviside function except for the value of function
%//at zero that is defined as 1.
Y = heaviside(X);
if Y==0.5
Y=1;
end
Now I understand your problem. The mystep function you implemented is not compatible to symbolic math. If you try mystep(sym(x)) you will see it returns heaviside. That's because a symbolic variable compared to a constant is always false.
The best solution I see is to use this definition for mystep
syms x
mystep(x)=heaviside(x)+1/2-abs(heaviside(x)-.5);
g(x) = subs(f(x) , heaviside(x) , mystep(x));
Resulting in:
x^2*(heaviside(x) - abs(heaviside(x) - 1/2) + 1/2)
Which does not look nice but implements the intended behaviour.
I found the answer. I have to define a new function in which mystep = round(heaviside(x));
end

Double integral with variable limits over implicit function in MATLAB

I'm experiencing the problem because of variable limit and implicit funtion being together.
So let's simplify it to this:
s(y)=y - our "implicit" function
Int [Int(x*s(y)*dy, 1,x)*dx, 1, 2] - our double integral (which equals 9/8).
(So you can even separate in into 2 integral I_small= s(y)dy and I=I_small * x*dx)
All that I figured out:
1) I tried using quad2d (so there is no ploblem with variable limit) - but I can't put the root of implicit function in it . So it wotks for non-implicit function:
function main
quad2d(#myfun,1,2,1,#(x)x)
end
function value=myfun(x,y)
value=x.*y;
end
But for implicit I've tried that - and it doesn't work. I know there is something wrong with this code - matlab doesn't understand that argument "y" in function name and "y" in the function itself are the same. But don't know how to fix it.
function main
quad2d(#myfun,1,2,1,#(x)x)
end
function value=myfun(x,y)
f=#(s,y)s-y;
value=x.*fzero(#(s)f(y,s), 0.5);
end
2) This code solves the opposite I = s(x).*y and I can't understand how to switch x to y because fzero doesnt work if I place y in it instead of x(j)
function main
quad(#myfun, 0,1)
end
function z=myfun(x)
z=zeros(size(x));
f=#(x,s) s-x;
for j=1:length(x);
s(j)=fzero(#(s)f(x(j),s), 0.5);
h=#(y) (s(j).*y);
z(j)=quad(h,1,x(j));
end
end
3) I also tried the nested quads, but it only works with constant limits. Can't fiqure it out how instead of Upperlimit should I place #(x)x.
function main
quad(#(y)y.*first_int(2),1,2)
end
function value=first_int(UpperLimit)
value=quad(#(x)yfunction(x,1),1,UpperLimit);
end
function value=yfunction(x,l)
syms y;
f=#(x,y) l.*x-y;
for k=1:length(x)
value(k)=fzero(#(y)f(x(k),y), 0.5);
end
Could you guys help with that?
The command quad2d (as its modern and better counterpart integral2) requires that the function to be integrated accept matrices as inputs.
The function Z=FUN(X,Y) must accept 2D matrices X and Y of the same size and return a matrix Z of corresponding values.
On the other hand, fzero only solves one equation, not a whole bunch of them at once. So, in order for your implicit function to accept matrix inputs, it needs to be written with a loop:
function value = myfun(x,y)
f=#(s,y)s-y;
value = zeros(size(x));
for i=1:size(x,1)
for j=1:size(x,2)
value(i,j) = x(i,j)*fzero(#(s) f(y(i,j),s), 0.5);
end
end
end
Then quad2d(#myfun,1,2,1,#(x)x) or integral2(#myfun,1,2,1,#(x)x) will work.

How to use derive.m function to get central differentioation of f(x)

I've a function that can calculate central difference of f(x) but I'm basic user of matlab and I can't define f(x) for function I've mentioned.
Can any body help me and define f(x) for this function?
INPUTS are a function f; a value
of h; a specific point a; the number of rows n. The input function f(x)
should be defined as an M-file.
My f(x) is : S(x) = 10*x-sin(x) with steps: 0.1
I want to get df(x) near the piont=pi/6
I wrote:
clc
syms x
derive(10*x-sin(x),0.1,pi/6,14)
but I've got this error :
Error using feval
Argument must contain a string or function_handle.
Error in derive (line 7)
D(1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
Error in centre(line 2)
========================================
the function derive.m is here:
function derive(f,h,a,n)
% Approximate the derivative of a function at x = a.
disp(' Derivative table')
disp('______________________________________________')
disp(' i h Di,1 Di,2 Di,3 ... ')
disp('______________________________________________')
D(1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
fprintf('%2.0f %8.4f %12.4f\n',1,h,D(1,1));
for i=1:n-1
h=h/2;
D(i+1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
fprintf('%2.0f %8.4f %12.4f',i+1,h,D(i+1,1));
for k=1:i
D(i+1,k+1)=D(i+1,k)+(D(i+1,k)-D(i,k))/((4^k)-1);
fprintf('%12.4f',D(i+1,k+1));
end
fprintf('\n');
end
feval expects a function handle, that is a MatLab function handle. What you provided (10*x-sin(x)) is a symbolic expression.
You can define a function handle as follows:
f(x) = 10*x-sin(x);
Now f is a MatLab function handle, and you can use it as you wish:
derive(f,0.1,pi/6,14)
EDIT
You can also use an anonymous functions
derive((x)(10*x-sin(x)),0.1,pi/6,14)
END EDIT
Note, you do not need syms x, it defines x as a symbol, but in your function definition you use the parameter x defined in f(x).
EDIT
If you want to use a symbolic function, you can convert it to a MatLab function handle using matlabFunction