Derivative of anonymous functions without defining symbolic variables in Matlab - matlab

Consider the following code:
f = #(x) x.^2;
Is it possible to get the derivative of the function handle f as another function handle, without defining a symbolic variable?

No, to obtain a derivative function you need to use the Symbolic toolbox.
But you can get an approximation (finite difference approximation) by creating a function as follows:
f = #(x) x.^2;
d = 1e-6;
df = #(x) (f(x+d)-f(x))/d;
d here determines precision of the approximation. If you make it too small, you'll end up in the floating-point rounding error domain, so be careful!
Testing:
x = -2:0.01:2;
max(abs(df(x) - 2*x)) % returns 1.0006e-06

Related

Integral in Matlab

I have 3 equations:
f = (exp(-x.^2)).*(log(x)).^2
g = exp(-x.^2)
h = (log(x)).^2
The interval is:
x = 0.05:10
I am able to correctly plot the equations but when I try to find an integral, it says that there is an error.
The code I used to find an integral is:
integral(f,0,Inf)
integral(g,0,inf)
integral(h,0,10)
The integrals for f and g are from 0 to infinity and the integral for h is from 0 to 10. None of my code to find integrals works.
You need to define f,g,h as functions like shown below. See documentation of integral(), it takes a function as its first argument. Matlab integral documentation
x = 0.05:10
f = #(x) (exp(-x.^2)).*(log(x)).^2
g = #(x) exp(-x.^2)
h = #(x) (log(x)).^2
integral(f,0,Inf) % 1.9475
integral(g,0,inf) % 0.8862
integral(h,0,10) % 26.9673
h = #(x) (log(x)).^2
This syntax is called anonymous functions, basically they are nameless functions. In above case it takes x as input and returns log(x) squared.
From now on h is a function and it can be used like this.
h(1) % will be equal 0
For more on anonymous functions refer to matlab anonymous functions guide:
Anonymous Functions

Evaluate indefinite integral numerically in matlab/mathematica that it cannot do symbolically

I am trying to calculate the integral of a function in Matlab and Mathematica that the software cannot do symbolically.
Here is my MatLab code so far, but I understand it may not be very helpful as is.
f = #(t) asin(0.5*sin(t));
a = #(t) sin(t);
F = int(f,t) % Matlab can't do this
F =
int(asin(sin(t)/2), t)
A = int(a,t) % This works
A =
-cos(t)
dt = 1/(N-1); % some small number
for i=1:N
F(i) = integral(f,(i-1)*dt,i*dt);
A(i) = integral(a,(i-1)*dt,i*dt);
end
Both of the calculations in the for loop give a rough approximation of f or a not their integrals after multiplying by dt.
On the math stack-exchange I found a question that derives a finite difference like method for the integral at a point. However, when I did the calculation in Matlab it output a scaled down version of f which was evident after plotting (see above for what I mean by scaled down). I think that's because for smaller intervals the integral basically approximates the function to varying degrees of accuracy (again see above).
I am trying to get either a symbolic equation for the integral, or an approximation of the integral of the function at each location.
So my question is then if I have a function f that MatLab and Mathematica cannot easily take the integral of
can I approximate the integral directly with an integral calculator besides the default ones? (int,integral,trapz)
or
can I approximate the function with finite differences first and then evaluate the integral symbolically?
Your code is nearly fine it's just that
for i=1:N
F(i) = integral(f,0,i*dt);
end
You could also do
F(1)=integral(f,0,dt)
for i=2:N
F(i) = F(i-1)+integral(f,(i-1)*dt,i*dt);
end
Second option is surely more efficient
Because the primitive is really F(x)=int(f(x), 0, x) (0 defines a certain constant ) and for sufficiently small dx you have shown that f(x)=int(f(x), x,x+dx)/dx i. You have proven that MATLAB intégral function does its job.
For example let's take = the function above will compute if you wish to compute just replace 0 above by the constant a you like.
now and so you should get F containing a discretization of
The accepted answer in general is by far the best method I would say but if certain restrictions on your functions are allowable then there is a second method.
For two functions f and g see below
T = 1; % Period
NT = 1; % Number of periods
dt = 0.01; % time interval
time = 0:dt:NT*T; % time
syms t
x = K*sin(2*pi*t+B); % edit as appropriate
% f = A/tanh(K)*tanh(K*sin(2*pi*t+p))
% g = A/asin(K)*asin(K*sin(2*pi*t+p))
formulas found here
f = A1/tanh(K1)*(2^(2*1)-1)*2^(2*1)*bernoulli(2*1)/factorial(2*1)*x^(2*1-1);
% |K1|<pi/2
g = A2/asin(K2)*factorial(2*0)/(2^(2*0)*factorial(0)^2*(2*0+1))*x^(2*0+1);
% |K2|<1
there are no such limitations in the accepted answer
N = 60;
for k=2:N
a1 = (2^(2*k)-1)*2^(2*k)*bernoulli(2*k)/factorial(2*k);
f = f + A1/tanh(K1)*a1*x^(2*k-1);
a2 = factorial(2*k)/(2^(2*k)*factorial(k)^2*(2*k+1));
g = g + A2/asin(K2)*a*x^(2*k+1);
end
MATLAB can calculate sin^n(t) for n being an integer.
F = int(f,t);
phi = double(subs(F,t,time));
G = int(g,t);
psi = double(subs(G,t,time));

Computing integral with variable bounds in MATLAB

Consider the following MWE in MATLAB:
f = #(t) integral(#(x) x.^2,0,t);
integral(f,0,1);
This yields the error
Error using integral (line 85) A and B must be floating-point scalars.
(and a bit more). How do I fix this? Is this even possible? I think the problem is the variable upper bound.
If you want to use integral then set 'ArrayValued' to true otherwise t would be an invalid end point in integral(#(x) x.^2,0,t). So it would be:
f = #(t) integral(#(x) x.^2,0,t);
integral(f,0,1,'ArrayValued',true)
% ans =
% 0.0833
Alternately, since you're doing double integration, so use the function dedicated for this purpose i.e. integral2. For your example, it would be:
f = #(t,x) x.^2 ;
integral2(f,0,1,0, #(t) t)
% ans =
% 0.0833
If you have Symbolic Math Toolbox, you can also use int as int(expr,var,a,b) but it would be slower. For your case, it would be:
syms x t;
f = x.^2;
req = int(int(f,x,0,t),t,0,1); % It gives 1/12
req = double(req); % Convert to double if required

Successive function application in MATLAB

How do I do successive function application in MATLAB with anonymous functions? Something like the following:
g = #(x) #(y) x+y;
g(1)(2)
However MATLAB gives an error at line 2: ()-indexing must appear last in an index expression.
But the following works:
g = #(x) #(y) x+y;
f = g(1);
f(2)
The script above outputs ans=3.
I am not very familiar with MATLAB but I think the ability to manipulate on the function level makes programming much easier. For example, when I need to compute projections of functions onto some subspace of L^2, the projection operator and normalization etc. all output functions that take additional arguments to evaluate to a numerical answer.
MATLAB doesn't support single expression calls like y = g(1)(2) to function handles returned by functions. You can however work your way around this limitation by using temporary variables:
g1 = g(1);
y = g1(2);
As an alternative you could build your own function to wrap around this functionality.
A recursive approach could be:
function f = fevalIterated(f, varargin)
if ~isempty(varargin)
f = fevalIterated(f(varargin{1}), varargin{2:end});
end
Instead of y = g(1)(2) you would call y = fevalIterated(g, 1, 2).
The iterative approach to do this might be faster:
function f = fevalIterated(f, varargin)
for i = 1:numel(varargin)
f = f(varargin{i});
end
As you were asking about the concept of currying in MATLAB, which is really similar to this:
Un-currying
Un-currying would mean to convert a function #(x) #(y) #(z) x+y+z to a function #(x,y,z) x+y+z. This is a very similar concept and you can thus reuse the functionality of fevalIterated to build a function uncurry that can be used like this:
g = uncurry(#(x) #(y) #(z) x+y+z);
y = g(1,2,3)
The function uncurry would be defined as:
function uncurried = uncurry(f)
uncurried = #(varargin) fevalIterated(f, varargin{:});
Currying
To curry a function #(x,y,z) x+y+z would mean to convert it to #(x) #(y) #(z) x+y+z.
Here is a recursive implementation of curry:
function f = curry(f,N)
if N>1
f = #(first) curry(#(varargin)f(first,varargin{:}), N-1);
end
A (faster) iterative implementation would look like this:
function f = curry(f,N)
for i = 1:N-1
f = #(varargin) #(last) f(varargin{:}, last);
end
You can call both via f = curry(#(x,y,z) x+y+z, 3).
Caveat
Although you can do all this in MATLAB, you might suffer from a noticable performance drop if you overdo the whole function handle calling thingy.
f = #(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15) ...
(x1+x2+x3+x4+x5+x6+x7+x8+x9+x10+x11+x12+x13+x14+x15);
%%// Currying vs Comma separated list expansion
%// Comma separated list expansion
tic;
[C{1:15}] = deal(12345);
f(C{:});
toc;
%// Elapsed time is 0.000146 seconds.
%// Currying
g = curry(f,15);
tic;
for i = 1:15
g = g(12345);
end
toc;
%// Elapsed time is 0.015679 seconds.

How to calculate the integral of the exp of the sum of function handles in a cell

I don't know how to calculate the integral of the sum of function handles in a cell. Please see the below examples:
f{1} = #(x) x;
f{2} = #(x) x^2;
g = #(x) sum(cellfun(#(y) y(x), f));
integral(#(x) exp(g), -3,3);
Error: Input function must return 'double' or 'single' values. Found 'function_handle'.
PS: please don't change the formula, because this is just an example. My real problem is far more complicated than this. It has log and exp of this sum (integral(log(sum), -inf, inf)). So I can't break them up to do the integral individually and sum the integrals.I need to use sum(cellfun). Thank you.
Version: Matlab R2012a
Can anyone help me? Really appreciate.
You cannot add function handles, so anything that tries f{1}+f{2}+... would give an error.
But you can compute the integral of the sums like this, evaluating the function values one at a time and adding up the results:
function cellsum
f{1} = #(x) x;
f{2} = #(x) x.^2;
integral(#(x)addfcn(f,x), -3, 3)
end
function s = addfcn(f,x)
s = zeros(size(x));
for k = 1:length(f)
s = s + f{k}(x);
end
end
Note that x will usually be a vector when the integral command calls your functions with it. So your function definitions should be vectorized, .i.e., x.^2 instead of x^2, etc.