I'm trying to evaluate the integral using MATLAB with an equation containing 4 related random variables, thus the boundaries of the integrals are not constant.
There are 2 exponential pdfs, and 2 other hyper exponential , and 1 Reyleigh CDF all multiplied together and with (x - y - z).
I'm trying to evaluate it using integral Q = (#(w) integral3(#(x,y,z,w),xmin,xmax,ymin,ymax,zmin,zmax),wmin,wmax);
I'm getting an error always. this is my code down here :
u_x = 10; % rate!
x_th = .3;
sigma = 1.33;
u_y = 10;
u_w = 100;
a= 1;
fun = #(x,y,z,w) (x - y - z )*u_x*exp(-u_x*x)*u_y*exp(-u_y*y)*((a/(a+1))*(a*u_w)*exp(-a*u_w*w)+((1/(a+1))*(u_w/a))*exp(-u_w*w/a))*((a/(a+1))*(a*u_w)*exp(-a*u_w*z)+((1/(a+1))*(u_w/a))*exp(-u_w*z/a))*(1-exp(-x_th/sigma^2))
xmin = #(y)y;
xmax = #(y,w)y + w;
ymin = 0;
ymax = inf;
zmin = 0;
zmax = #(w) w;
wmin = 0;
wmax = inf;
Q = integral(#(w) integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax),wmin,wmax);
ERROR MESSAGE :
Error using integral3 (line 63)
XMIN must be a floating point scalar.
Error in numerical_int>#(w)integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax)
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 83)
[q,errbnd] = vadapt(#AToInfInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
Error in numerical_int (line 28)
Q = integral(#(w) integral3(fun,xmin,xmax,ymin,ymax,zmin,zmax),wmin,wmax);
integral3() requires all the lower bounds to be real
number
int() does not, but need to use syms function instead of function
handle
For element-wise calculation use the dot. operator followed by the
concerned operator like
1) * ---> .* 2) / ---> ./ 3) ^ ---> .^
Read this for more information on how to use int() for nd
integral
The code is as follows
syms x y z w
u_x = 10; % rate!
x_th = .3;
sigma = 1.33;
u_y = 10;
u_w = 100;
a= 1;
fun = (x - y - z ).*u_x.*exp(-u_x*x).*u_y.*exp(-u_y.*y)...
.*((a./(a+1)).*(a.*u_w).*exp(-a.*u_w.*w)+((1./(a+1)).*(u_w./a))...
.*exp(-u_w.*w./a)).*((a./(a+1)).*(a*u_w)*exp(-a.*u_w.*z)...
+((1./(a+1)).*(u_w./a))*exp(-u_w.*z./a)).*(1-exp(-x_th./sigma.^2));
xmin = y;
xmax = y + w;
ymin = 0;
ymax = inf;
zmin = 0;
zmax = w;
wmin = 0;
wmax = inf;
% Integrate along x
intx = int(fun, x, xmin, xmax);
% Integrate along y
intxy = int(intx, y, ymin, ymax);
% Integrate along z
intxyz = int(intxy, z, zmin, zmax);
% Integrate along w
intxyzw = int(intxyz, w, wmin, wmax);
value = vpa(intxyzw, 3);
% 2.14e-5
Related
I'm struggling to use piecewise function in this pdpk model in MATLAB I keep getting the error of
"Error using odearguments (line 113)
Inputs must be floats, namely single or double.
Error in ode45 (line 106)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);"
Please help!
listed code below***
vnf = 1; qnf = 1; vf = 1; qf = 1;
vb = 1; pf = 20; vl = 1; ql = 1;
vmax = 1; Km = 1; pl = 2; pb = 18;
Ci = 0.32; % benzene conc in inhaled air
Qp = 5.74; % alveolar ventilation rate
conds = [0 0 0 0]; %--- initial conditions order: [NF F B L]
pul = piecewise(t > 6, 0, t <= 6, 1);
f = #(t,x) [qnf*(x(3)/vb - x(1)/vnf);...
qf*(x(3)/vb - x(2)/vf/pf);...
-qnf*(x(3)/vb - x(1)/vnf) - qf*(x(3)/vb - x(2)/vf/pf) - ql*(x(3)/vb - x(4)/vl/pl) + pul*Qp*(Ci - (x(3)/vb - pb));...
ql*(x(3)/vb - x(4)/vl/pl) - vmax*x(4)/vl/(Km + x(4)/vl)];
[t,x] = ode45(f, [0 10], conds);
I am trying to create a function in matlabthat uses Euler's method for solving IVP's. My code for the function is:
function err = EulerIvp(f,fe, h, y0,start, stop)
w = y0;
j = 1;
for i = start:h:stop
err(j) = abs(w - feval(fe, i));
disp(err);
j = j + 1;
w = w + h.*feval(f, w);
end
and my other code is
clear;
clc;
fa = #(y) y(2-y);
fb = #(y) y^2 - (y^3)/3 + 1;
h1 = 0.1;
errb1 = EulerIvp(fa, fb, h1, 1, 0, 10);
I keep getting the error message:
Array indices must be positive integers or logical values.
Error in HW6_1>#(y)y(2-y) (line 4)
fa = #(y) y(2-y);
Error in EulerIvp (line 8)
w = w + h.*feval(f, w);
Error in HW6_1 (line 7)
errb1 = EulerIvp(fa, fb, h1, 1, 0, 10);
I think my code is right, but I don't know why I keep getting this error
I am not able to integrate heaviside(y-f) for x= 0 to pi/2 and y = 0 to pi/2 (only syms integration "int"). After running the code, output is shown in below and I am not able to get the numerical answer. Can you give some ideas on how to proceed?
code:
syms x y
f = sin(x);
integ = int( int(heaviside(y-f), x, 0, pi/2),y, 0, pi/2)
Result:
integ =
int(int(heaviside(y - sin(x)), x, 0, pi/2), y, 0, pi/2)
Avoid symbolic calculation whenever possible.
Notice the heaviside function can be defined as:
hvsd = #(x) (x > 0) + 0.5*(x == 0); % another name to do not overshadow heaviside
You can use either integral2 or trapz to evaluate the numerical integral.
heaviside = #(x) (x > 0) + 0.5*(x == 0);
fun = #(x,y) heaviside(y-sin(x));
% using integral2
I1 = integral2(fun,0,pi/2,0,pi/2)
nx = 100; ny = 100;
x = linspace(0,pi/2,nx);
y = linspace(0,pi/2,ny);
[X,Y] = meshgrid(x,y);
Z = fun(X,Y);
% using trapz
I2 = trapz(y,trapz(x,Z.*(Z>0),2))
I1 =
1.4674
I2 =
1.4695
I'm using ode45 to solve second order differential equation. the time span is determined based on how many numbers in txt file, therefore, the time span is defined as follows
i = 1;
t(i) = 0;
dt = 0.1;
numel(theta_d)
while ( i < numel(theta_d) )
i = i + 1;
t(i) = t(i-1) + dt;
end
Now the time elements should not exceed the size of txt (i.e. numel(theta_d)). In main.m, I have
x0 = [0; 0];
options= odeset('Reltol',dt,'Stats','on');
[t, x] = ode45('ODESolver', t, x0, options);
and ODESolver.m header is
function dx = ODESolver(t, x)
If I run the code, I'm getting this error
Attempted to access theta_d(56); index out of bounds because numel(theta_d)=55.
Error in ODESolver (line 29)
theta_dDot = ( theta_d(i) - theta_dPrev ) / dt;
Why the ode45 is not being fixed with the time span?
Edit: this is the entire code
main.m
clear all
clc
global error theta_d dt;
error = 0;
theta_d = load('trajectory.txt');
i = 1;
t(i) = 0;
dt = 0.1;
numel(theta_d)
while ( i < numel(theta_d) )
i = i + 1;
t(i) = t(i-1) + dt;
end
x0 = [pi/4; 0];
options= odeset('Reltol',dt,'Stats','on');
[t, x] = ode45(#ODESolver, t, x0, options);
%e = x(:,1) - theta_d; % Error theta
plot(t, x(:,2), 'r', 'LineWidth', 2);
title('Tracking Problem','Interpreter','LaTex');
xlabel('time (sec)');
ylabel('$\dot{\theta}(t)$', 'Interpreter','LaTex');
grid on
and ODESolver.m
function dx = ODESolver(t, x)
persistent i theta_dPrev
if isempty(i)
i = 1;
theta_dPrev = 0;
end
global error theta_d dt ;
dx = zeros(2,1);
%Parameters:
m = 0.5; % mass (Kg)
d = 0.0023e-6; % viscous friction coefficient
L = 1; % arm length (m)
I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)
g = 9.81; % acceleration due to gravity m/s^2
% PID tuning
Kp = 5;
Kd = 1.9;
Ki = 0.02;
% theta_d first derivative
theta_dDot = ( theta_d(i) - theta_dPrev ) / dt;
theta_dPrev = theta_d(i);
% u: joint torque
u = Kp*(theta_d(i) - x(1)) + Kd*( theta_dDot - x(2)) + Ki*error;
error = error + (theta_dDot - x(1));
dx(1) = x(2);
dx(2) = 1/I*(u - d*x(2) - m*g*L*sin(x(1)));
i = i + 1;
end
and this is the error
Attempted to access theta_d(56); index out of bounds because numel(theta_d)=55.
Error in ODESolver (line 28)
theta_dDot = ( theta_d(i) - theta_dPrev ) / dt;
Error in ode45 (line 261)
f(:,2) = feval(odeFcn,t+hA(1),y+f*hB(:,1),odeArgs{:});
Error in main (line 21)
[t, x] = ode45(#ODESolver, t, x0, options);
The problem here is because you have data at discrete time points, but ode45 needs to be able to calculate the derivative at any time point in your time range. Once it solves the problem, it will interpolate the results back onto your desired time points. So it will calculate the derivative many times more than at just the time points you specified, thus your i counter will not work at all.
Since you have discrete data, the only way to proceed with ode45 is to interpolate theta_d to any time t. You have a list of values theta_d corresponding to times 0:dt:(dt*(numel(theta_d)-1)), so to interpolate to a particular time t, use interp1(0:dt:(dt*(numel(theta_d)-1)),theta_d,t), and I turned this into an anonymous function to give the interpolated value of theta_p at a given time t
Then your derivative function will look like
function dx = ODESolver(t, x,thetaI)
dx = zeros(2,1);
%Parameters:
m = 0.5; % mass (Kg)
d = 0.0023e-6; % viscous friction coefficient
L = 1; % arm length (m)
I = 1/3*m*L^2; % inertia seen at the rotation axis. (Kg.m^2)
g = 9.81; % acceleration due to gravity m/s^2
% PID tuning
Kp = 5;
Kd = 1.9;
Ki = 0.02;
% theta_d first derivative
dt=1e-4;
theta_dDot = (thetaI(t) - theta(I-dt)) / dt;
%// Note thetaI(t) is the interpolated theta_d values at time t
% u: joint torque
u = Kp*(thetaI(t) - x(1)) + Kd*( theta_dDot - x(2)) + Ki*error;
error = error + (theta_dDot - x(1));
dx=[x(2); 1/I*(u - d*x(2) - m*g*L*sin(x(1)))];
end
and you will have to define thetaI=#(t) interp1(0:dt:(dt*(numel(theta_d)-1)),theta_d,t); before calling ode45 using [t, x] = ode45(#(t,x) ODESolver(t,x,thetaI, t, x0, options);.
I removed a few things from ODESolver and changed how the derivative was computed.
Note I can't test this, but it should get you on the way.
I tried to code the jexact of Mie Series, but it says "Matrix dimensions must agree.
how should it be fixed?
%wave_length
lamda = 2*pi/3.5;
%speed of light
c = 299792458;
%frequency
freq = c/lamda;
%Raduis
R = 1;
%Permeability
mu = 4.0e-7*pi;
%permittivity
epsilon = 1.0/c/mu/c;
% radian frequency (w)
w = 2.0*pi*freq;
% wavenumber
K = w*sqrt(mu*epsilon);
omega=2*pi*(0:N-1)/N;
x=cos(omega)*R;
y=sin(omega)*R;
phi = atan2(y,x);
Jexact = zeros(size(x));
for nu = -10:10;
Jexact= Jexact + (1j.^(-nu).*exp(1j*nu*phi)./besselh(nu,2,K*R))*(-2/(w.*mu.*pi.*R));
end