I have a characteristic function CF(t, param1, param2, ...) available (here params are parameters of some distribution and are considered fixed). I want to use Gil-Pelaez formula to obtain the CDF instead, so I wrote the following:
function [ F ] = CDF( x, param1, param2, ... )
integrand = #(v) imag(exp(-1i.*v.*x) .* CF(t, param1, param2, ...)) ./ v;
F = 0.5 - (1./pi) .* integral(integrand, 0, 100);
end
This works for single value, e.g. CDF(0.1, param1, param2, ...) gives me desired result. Now I want to plot CDF against a range of x, so I did
x = linspace(-1,1,100);
y = CDF(x, param1, param2, ...)
plot(x, y)
and I end up with the errors like these:
Not enough 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);
But y = CDF(x, param1, param2, ...) does work, so the culprit seems to be the exp(-1i.*v.*x) part of the integrand, as the size of v and x does not match. But I am not sure how to fix this.
You have guessed it right that the sizes of v and x don't match which is causing the error. integral passes vector values to the function handle to speed up computations by calculating function values for multiple points at once.
But in this case you should set the parameter 'ArrayValued' to true in the call to integral in the CDF function. This would force integral to pass scalar values of v to the function handle and then CDF would be able to return vector valued y for vector valued x
Related
I'm working in MATLAB and I have a problem with a system of differential equations. My system is dvdt = (-2*T)-4*v and dTdt = 6*T+v and I want to resolve it using Runge-Kutta of 4th order. I wrote the following code:
If I run only the function odefun, my code works! But my code didn't work if I run the complete program:
clear all
yy=#(t,y)[dvdt;dTdt]
[t,y]= ode45(#(t,y)yy,[0 1.5],[1 1/2 ]);
function res = odefun(t , y )
% i define two variable i will use: v and TT
v = y(1,:);
T = y(2,:);
% i define the two partial derivative:
res(1,:) = dvdt
res(2,:) = dTdt
dvdt = (-2*T)-4*v
dTdt = 6*T+v;
end
This is my results. I don't know to write a vector of a correct length:
Error using odearguments (line 95)
#(T,Y)YY returns a vector of length 1, but the length of initial conditions vector is 2. The vector returned by #(T,Y)YY and the initial conditions vector must have
the same number of elements.
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in sys_ode (line 4)
[t,y]= ode45(#(t,y)yy,[0 1.5],[1 1/2 ]);
y as passed from ode45 to odefun is a flat, one-dimensional array. Your variable assignment like you were dealing with a 2-dimensional array makes no sense. It should be v=y(1); T=y(2);.
In a code block, you need to observe causality. You need to declare/define a variable before you can use it in another code line.
Without calling odefun you will not get an error as each line in odefun is syntactically correct. However you get an error in its execution as the semantic is wrong.
Try
clear all
[t,y]= ode45(odefun,[0 1.5],[1 1/2 ]);
function res = odefun(t , y )
% i define two variable i will use: v and T
v = y(1);
T = y(2);
% i define the two derivatives:
dvdt = (-2*T)-4*v
dTdt = 6*T+v;
res = [ dvdt dTdt ]
end
I need to compute this kind of integral
I defined the two f(x,y) and g(x,y) inside a single function
h = {#(x,y) f, #(x,y) g};
where f and g are formulas defined before. In this way I have a 1x2 cell and I want to compute the scalar product as
F = #(x,y) dot(h,E)
where E is a vector 2x1 and then integrate
int = integral2(F,a,b,c,d);
giving me this error
Undefined function 'conj' for input arguments of type 'cell'.
Error in dot (line 37)
c = sum(conj(a).*b);
Error in tm_np>#(R,PHI)dot(e_n_even,E)
Error in integral2Calc>integral2t/tensor (line 228)
Z = FUN(X,Y); NFE = NFE + 1;
Error in integral2Calc>integral2t (line 55)
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
Error in integral2Calc (line 9)
[q,errbnd] = integral2t(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 106)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
I don't understand why is giving me this error. As result of the integral I should have a 2x1 vector
The problem is the generation of your data. integral2 accepts only functions that get #(x,y) as vector input and return the same size. in your case h is already not that, and F has no #(x,y) inputs (well, it has, but you decided not to pass them to h!!!).
% sample data
f=#(x,y)x.^2+y;
g=#(x,y)y.^2+x+3;
E=[3 1];
% Create auxiliary fucntion
mydot=#(x,y)(f(x,y).*E(1)+g(x,y).*E(2));
% work
int = integral2(mydot,0,3,1,5);
I am trying to use the numerical integration function 'integral'
I created a function of four polynomial functions
[x; x^2; x^3; x^4]
now I want to integrate this vector row by row using the integral function.
I tried making a function handle for the function and passed it to the 'integral' function
function f = test(x)
f = [x,x^2,x^3,x^4];
end
However, I get the following error when calling it command line:
test_var=#test
integral(test_var,0,1)
Error using ^
One argument must be a square matrix and the other must be a scalar.
Use POWER (.^) for elementwise power.
Error in test (line 2)
f = [x,x^2,x^3,x^4];
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);
According to the documentation of integral:
q = integral(fun, xmin, xmax)
For a scalar-valued function fun you need to define the function so that it accepts vector input and produces vector output.
For scalar-valued problems, the function y = fun(x) must accept a vector argument, x, and return a vector result, y. This generally means that fun must use array operators instead of matrix operators. For example, use .* (times) rather than * (mtimes).
If you have a vector-valued function fun you need to use the input flag 'ArrayValued':
Set this flag to true to indicate that fun is a function that accepts a scalar input and returns a vector, matrix, or N-D array output.
and in that case the requirement in item 1 above is not necessary:
If you set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.
So, you need to add the input flag 'ArrayValued' to indicate that you have a vector-valued function:
f = #(x) [x; x^2; x^3; x^4]; % or [x; x.^2; x.^3; x.^4];
integral(f, 0, 1, 'ArrayValued', true) % or integral(#f, 0, 1, 'ArrayValued', true)
% if f is defined in a file
gives
ans =
0.500000000000000
0.333333333333333
0.250000000000000
0.200000000000000
I'm using MATLAB R2016b - student edition to develop an m-file which takes as input a symbolic differential equation, f(t,y), and outputs a slope field and solution curve based on an initial condition. The code is
prompt={'dy/dt =','tspan','y0 ='};
title='Slope Field Calculator';
answer=inputdlg(prompt,title);
tspan = str2num(answer{2}); %#ok<*ST2NM>
y0 = str2double(answer{3});
syms t y
f = symfun(sym(answer{1}),[t,y]);
[t,y] = ode45(f, tspan, y0);
hold on
dirfield(f,-5:.3:5,-5,.3:5)
plot(t,y,'b','LineWidth',2)
The dirfield(f,-5:.3:5,-5:.3:5) function has input f as an # function, or an inline function, or the name of an m-file with quotes. The dirfield function then plots a direction field for a first order ODE of the form y' = f(t,y) using t-values from t1 to t2 with spacing of dt and using y-values from y1 to y2 with spacing of dy.
According to MATLAB help, the ode45 function solves differential equations.
[TOUT,YOUT] = ode45(ODEFUN,TSPAN,Y0) with TSPAN = [T0 TFINAL] then integrates the differential equation y' = f(t,y) from time T0 to TFINAL with initial conditions Y0. The input ODEFUN is a function handle. For a scalar T and a vector Y, ODEFUN(T,Y) must return a column vector corresponding to f(t,y).
When I run the code, the dialogue box runs nicely and accepts my inputs. But when I click "OK", the code throws this error:
Warning: Support of character vectors that are not valid variable names or
define a number will be removed in a
future release. To create symbolic expressions, first create symbolic
variables and then use operations on them.
> In sym>convertExpression (line 1559)
In sym>convertChar (line 1464)
In sym>tomupad (line 1216)
In sym (line 179)
In SlopeFieldsSolutionCurves (line 9)
Undefined function 'exist' for input arguments of type 'symfun'.
Error in odearguments (line 59)
if (exist(ode)==2)
Error in ode45 (line 115)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options,
varargin);
Error in SlopeFieldsSolutionCurves (line 10)
[t,y] = ode45(f, tspan, y0);
Where am I going wrong?
ode45 takes a function handle, not a symbolic function. Use matlabFunction instead:
[t,y] = ode45(matlabFunction(f), tspan, y0);
To get rid of the first warning, you need to define f a bit differently:
f = evalin( symengine, answer{1} );
f = symfun( f, [t,y] );
I try to get an integral of two function handles in Matlab. The first function handle would be a weibull probability density function and the second function handle is based on a cfit I created with linear interpolation of single points.
x = 0:0.1:35;
fun1 = #(x) wblpdf(x,weibullAlpha,weibullBeta);
fun2 = #(x) feval(cfitObject,x);
fun3 = #(x) (fun(x).*fun2(x));
y = integral(fun3,0,35); % Using quad(fun3,0,35) doesn't work either.
I receive the following error:
Error using integralCalc/finalInputChecks (line 515)
Output of the function must be the same size as the input. If FUN is an array-valued integrand,
set the 'ArrayValued' option to true.
Error in integralCalc/iterateScalarValued (line 315)
finalInputChecks(x,fx);
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 test (line 7) % "test" is the name of the script file.
y = integral(fun3,0,35);
The problem must have to do something with "fun2" since the code works just fine with e.g.
fun2 = x.^2;
Note: if I plot fun2 with the cfitObject I don't get an error. It's also possible to integrate the function using quad().
x = 0:0.1:35;
fun2 = #(x) feval(cfitObject,x);
y = quad(fun2,0,35);
plot(x, fun2(x))
Any help is greatly appreciated!
Your code seems to be ok. Probably the problem is that fun2 cannot take vectorized input, it could be resolved by modifying fun2 (cfitObject) to be able to handle vector input or telling the software that the function in the integral is array valued:
y = integral(fun3, 0, 35, 'ArrayValued', 1);