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
Related
Introduction
I am using Matlab to simulate some dynamic systems through numerically solving systems of Second Order Ordinary Differential Equations using ODE45. I found a great tutorial from Mathworks (link for tutorial at end) on how to do this.
In the tutorial the system of equations is explicit in x and y as shown below:
x''=-D(y) * x' * sqrt(x'^2 + y'^2)
y''=-D(y) * y' * sqrt(x'^2 + y'^2) + g(y)
Both equations above have form y'' = f(x, x', y, y')
Question
However, I am coming across systems of equations where the variables can not be solved for explicitly as shown in the example. For example one of the systems has the following set of 3 second order ordinary differential equations:
y double prime equation
y'' - .5*L*(x''*sin(x) + x'^2*cos(x) + (k/m)*y - g = 0
x double prime equation
.33*L^2*x'' - .5*L*y''sin(x) - .33*L^2*C*cos(x) + .5*g*L*sin(x) = 0
A single prime is first derivative
A double prime is second derivative
L, g, m, k, and C are given parameters.
How can Matlab be used to numerically solve a set of second order ordinary differential equations where second order can not be explicitly solved for?
Thanks!
Your second system has the form
a11*x'' + a12*y'' = f1(x,y,x',y')
a21*x'' + a22*y'' = f2(x,y,x',y')
which you can solve as a linear system
[x'', y''] = A\f
or in this case explicitly using Cramer's rule
x'' = ( a22*f1 - a12*f2 ) / (a11*a22 - a12*a21)
y'' accordingly.
I would strongly recommend leaving the intermediate variables in the code to reduce chances for typing errors and avoid multiple computation of the same expressions.
Code could look like this (untested)
function dz = odefunc(t,z)
x=z(1); dx=z(2); y=z(3); dy=z(4);
A = [ [-.5*L*sin(x), 1] ; [.33*L^2, -0.5*L*sin(x)] ]
b = [ [dx^2*cos(x) + (k/m)*y-g]; [-.33*L^2*C*cos(x) + .5*g*L*sin(x)] ]
d2 = A\b
dz = [ dx, d2(1), dy, d2(2) ]
end
Yes your method is correct!
I post the following code below:
%Rotating Pendulum Sym Main
clc
clear all;
%Define parameters
global M K L g C;
M = 1;
K = 25.6;
L = 1;
C = 1;
g = 9.8;
% define initial values for theta, thetad, del, deld
e_0 = 1;
ed_0 = 0;
theta_0 = 0;
thetad_0 = .5;
initialValues = [e_0, ed_0, theta_0, thetad_0];
% Set a timespan
t_initial = 0;
t_final = 36;
dt = .01;
N = (t_final - t_initial)/dt;
timeSpan = linspace(t_final, t_initial, N);
% Run ode45 to get z (theta, thetad, del, deld)
[t, z] = ode45(#RotSpngHndl, timeSpan, initialValues);
%initialize variables
e = zeros(N,1);
ed = zeros(N,1);
theta = zeros(N,1);
thetad = zeros(N,1);
T = zeros(N,1);
V = zeros(N,1);
x = zeros(N,1);
y = zeros(N,1);
for i = 1:N
e(i) = z(i, 1);
ed(i) = z(i, 2);
theta(i) = z(i, 3);
thetad(i) = z(i, 4);
T(i) = .5*M*(ed(i)^2 + (1/3)*L^2*C*sin(theta(i)) + (1/3)*L^2*thetad(i)^2 - L*ed(i)*thetad(i)*sin(theta(i)));
V(i) = -M*g*(e(i) + .5*L*cos(theta(i)));
E(i) = T(i) + V(i);
end
figure(1)
plot(t, T,'r');
hold on;
plot(t, V,'b');
plot(t,E,'y');
title('Energy');
xlabel('time(sec)');
legend('Kinetic Energy', 'Potential Energy', 'Total Energy');
Here is function handle file for ode45:
function dz = RotSpngHndl(~, z)
% Define Global Parameters
global M K L g C
A = [1, -.5*L*sin(z(3));
-.5*L*sin(z(3)), (1/3)*L^2];
b = [.5*L*z(4)^2*cos(z(3)) - (K/M)*z(1) + g;
(1/3)*L^2*C*cos(z(3)) + .5*g*L*sin(z(3))];
X = A\b;
% return column vector [ed; edd; ed; edd]
dz = [z(2);
X(1);
z(4);
X(2)];
How to do numerical multiple integral (more than triple) by using Matlab?
For example, I have a function,Y = Func. It has 5 var. Hence, Y= func(a,b,c,d,e). If I want to do the integration with respect to a,b,c,d,e. (var a is the first one, e is the last one.) And region of a = [0 ,b] (this is a function handle), b = [0,c], c= [0.d], d= [0,e], e=[0, Inf].
Now, here is my 'real' question. The code is below
%%%==== just some parameters ====
a=4;
la1=1/(pi*500^2); la2= la1*5;
p1=25; p2=p1/25;
sgma2=10^(-11);
index=1;
g=2./a;
syms r u1 u2 u3 u4 u5
index = -2;
powe= index ;
seta= 10^powe;
xNor = ( (u5./u1).^(a./2)+ (u5./u2).^(a./2) + (u5./u3).^(a./2)+ (u5./u4).^(a./2) + 1 ).^(2./a);
x = (xNor).^(0.5) * seta^(-1/a);
q=pi.*(la1.*p1.^(2./a)+la2.*p2.^(2./a));
%%%==== parameters end ====
fun1 = r./(1+ r.^a );
out1 = int(fun1, x, Inf) ;
out1fcn = matlabFunction(out1); %%===Convert symbolicto function handle
y = #(u5,u4,u3,u2,u1) exp(-u3.*(1+2.*... %%<== in method 3, replace as 'y= exp(-u3.*(1+2.*...'
( out1fcn )./... %%<== in method 3, replace as '( out1 )./...'
( (( (u5./u1).^(a./2)+ (u5./u2).^(a./2) + (u5./u3).^(a./2)+ (u5./u4).^(a./2) + 1 ).^(2./a)).*seta.^(-2./a)))).*...
exp(-sgma2.*q.^(-a./2).* seta.*u3.^(a./2)./...
((( (u5./u1).^(a./2)+ (u5./u2).^(a./2) + (u5./u3).^(a./2)+ (u5./u4).^(a./2) + 1 ).^(2./a)).^(a./2)) );
%%%=== method 1, not working ============ upper ,lower bound should be a number
% y1 = integral( y ,0,#(u2) u2);
% y2 = integral( y1 ,0,#(u3) u3);
% y3 = integral( y2 ,0,#(u4) u4);
% y4 = integral( y3 ,0, Inf);
%%%=== method 2, not working, y1 is already wrong ===============
%%%Undefined function 'minus' for input arguments of type 'function_handle'.
% y1 = quad( y ,0,#(u2) u2);
% y2 = quad( y1 ,0,#(u3) u3);
% y3 = quad( y2 ,0,#(u4) u4);
% y4 = quad( y3 ,0, Inf);
%%%=== method 3. not working, DOUBLE cannot convert the input expression into a double array. ==============
% y1 = int( y ,0,#(u2) u2);
% y2 = int( y1 ,0,#(u3) u3);
% y3 = int( y2 ,0,#(u4) u4);
% y4 = int( y3 ,0, Inf);
% y5 = double(y4)
A Google search showed that it is possible that by 2011 there was no standard numerical option available. This is a library you could consider. Finally, how about using Monte Carlo?
It would depend on if your function is defined symbolically or otherwise. However, if it is defined symbolically then five nested int functions would do the trick.
Got one more problem with matrix multiplication in Matlab. I have to plot Taylor polynomials for the given function. This question is similar to my previous one (but this time, the function is f: R^2 -> R^3) and I can't figure out how to make the matrices in order to make it work...
function example
clf;
M = 40;
N = 20;
% domain of f(x)
x1 = linspace(0,2*pi,M).'*ones(1,N);
x2 = ones(M,1)*linspace(0,2*pi,N);
[y1,y2,y3] = F(x1,x2);
mesh(y1,y2,y3,...
'facecolor','w',...
'edgecolor','k');
axis equal;
axis vis3d;
axis manual;
hold on
% point for our Taylor polynom
xx1 = 3;
xx2 = 0.5;
[yy1,yy2,yy3] = F(xx1,xx2);
% plots one discrete point
plot3(yy1,yy2,yy3,'ro');
[y1,y2,y3] = T1(xx1,xx2,x1,x2);
mesh(y1,y2,y3,...
'facecolor','w',...
'edgecolor','g');
% given function
function [y1,y2,y3] = F(x1,x2)
% constants
R=2; r=1;
y1 = (R+r*cos(x2)).*cos(x1);
y2 = (R+r*cos(x2)).*sin(x1);
y3 = r*sin(x2);
function [y1,y2,y3] = T1(xx1,xx2,x1,x2)
dy = [
-(R + r*cos(xx2))*sin(xx1) -r*cos(xx1)*sin(xx2)
(R + r*cos(xx2))*cos(xx1) -r*sin(xx1)*sin(xx2)
0 r*cos(xx2) ];
y = F(xx1, xx2) + dy.*[x1-xx1; x2-xx2];
function [y1,y2,y3] = T2(xx1,xx2,x1,x2)
% ?
I know that my code is full of mistakes (I just need to fix my T1 function). dy represents Jacobian matrix (total derivation of f(x) - I hope I got it right...). I am not sure how would the Hessian matrix in T2 look, by I hope I will figure it out, I'm just lost in Matlab...
edit: I tried to improve my formatting - here's my Jacobian matrix
[-(R + r*cos(xx2))*sin(xx1), -r*cos(xx1)*sin(xx2)...
(R + r*cos(xx2))*cos(xx1), -r*sin(xx1)*sin(xx2)...
0, r*cos(xx2)];
function [y1,y2,y3]=T1(xx1,xx2,x1,x2)
R=2; r=1;
%derivatives
y1dx1 = -(R + r * cos(xx2)) * sin(xx1);
y1dx2 = -r * cos(xx1) * sin(xx2);
y2dx1 = (R + r * cos(xx2)) * cos(xx1);
y2dx2 = -r * sin(xx1) * sin(xx2);
y3dx1 = 0;
y3dx2 = r * cos(xx2);
%T1
[f1, f2, f3] = F(xx1, xx2);
y1 = f1 + y1dx1*(x1-xx1) + y1dx2*(x2-xx2);
y2 = f2 + y2dx1*(x1-xx1) + y2dx2*(x2-xx2);
y3 = f3 + y3dx1*(x1-xx1) + y3dx2*(x2-xx2);
I want to vectorize a 3D function, but the function does not have an analytical expression. For instance, I can vectorize the function
F(x, y, z) = (sin(y)*x, z*y, x*y)
by doing something like
function out = Vect_fn(x, y,z)
out(1) = x.*sin(y);
out(2) = z.*y;
out(3) = x.*y;
end
And then running the script
a = linspace(0,1,10);
[xx, yy, zz] = meshgrid(a, a, a);
D = Vect_fn(xx, yy, zz)
However, suppose the function does not have an analytical expression, for example
function y = Vect_Nexplicit(y0)
%%%%%%y0 is a 3x1 vector%%%%%%%%%%%%%%
t0 = 0.0;
tf = 3.0;
[t, z] = ode45('ODE_fn', [t0,tf], y0);
sz = size(z);
n = sz(1);
y = z(n, :);
end
where ODE_fn is just some function that spits out the right-hand side of a an ODE. Thus the function simply solves an ODE and so the function is not known explicitly. Of course I can use a for loop, but those are slower (esp. in Octave, which I prefer since it has lsode for solving ODEs)
Trying something like
a = linspace(0,1,10);
[xx, yy, zz] = meshgrid(a, a, a);
D = Vect_Nexplicit(xx, yy, zz)
does not work. Also here is the code for ODF_fn:
function ydot = ODE_fn(t, yin)
A = sqrt(3.0);
B = sqrt(2.0);
C = 1.0;
x = yin(1, 1);
y = yin(2,1);
z = yin(3, 1);
M = reshape(yin(4:12), 3, 3);
ydot(1,1) = A*sin(yin(3)) + C*cos(yin(2));
ydot(2,1) = B*sin(yin(1)) + A*cos(yin(3));
ydot(3,1) = C*sin(yin(2)) + B*cos(yin(1));
DV = [0 -C*sin(y) A*cos(z); B*cos(x) 0 -A*sin(z); -B*sin(x) C*cos(y) 0];
Mdot = DV*M;
ydot(4:12,1) = reshape(Mdot, 9, 1);
end
You can solve systems of differential equations with ode45, so if ODE_fn is vectorised you can use your approach. y0 just needs to be a vector too.
You can create a y0 that is [x1, ..., xn, y1, ..., yn, z1, ..., zn, M1_1-9, ... ,Mn_1-9] and then use for x, y, z just the appropriate indexes i.e. 1:n, n+1:2*n, 2*n+1:3n. Then use reshape(yin(3*n+1:end),3,3,n). But I am not sure how to vectorize the matrix multiplication.
i have a problem. that is :
y"^2 + 2*y'+ 3*y = sin(x), y'(0)=0, y(0)=1
I want solve this problem with MATLAB but I can't.
Can you help me ?
First, you have to reduce the order. Let z = y' => z' = y"
Your ODE then becomes
z' = sqrt(-2*z - 3*y + sin(x)), with z(0) = 0
y' = z, with y(0) = 1
You can now write a function in MATLAB to represent this ODE: (where M = [ z y ]')
function dMdx = odefunc(x,M)
z = M(1);
y = M(2);
dMdx(1) = sqrt(-2*z - 3*y + sin(x));
dMdx(2) = z;
end
You can then call this function as follows:
M0 = [ 0 1 ]; % Initial values of ODE
tfinal = 12; % Final integration time
[x,M] = ode45(#odefunc,[0 tfinal],M0) % Integration using the RK-45 algorithm