Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Nasser M. Abbasi
1 Control systems, Linear systems, transfer functions, state space related problems 5
1.1 Creating tf and state space and different Conversion of forms . . . . . . . . . . . . . . . 5
1.1.1 Create continuous time transfer function given the poles, zeros and gain . . . . 5
1.1.2 Convert transfer function to state space representation . . . . . . . . . . . . . . 6
1.1.3 Create a state space representation from A,B,C,D and find the step response . . 8
1.1.4 Convert continuous time to discrete time transfer function, gain and phase margins 9
1.1.5 Convert differential equation to transfer functions and to state space . . . . . . 11
1.1.6 Convert from continuous transfer function to discrete time transfer function . 12
1.1.7 Convert a Laplace transfer function to an ordinary differential equation . . . . 12
1.2 Obtain the step response of an LTI from its transfer function . . . . . . . . . . . . . . . 12
1.3 plot the impulse and step responses of a system from its transfer function . . . . . . . . 13
1.4 Obtain the response of a transfer function for an arbitrary input . . . . . . . . . . . . . 15
1.5 Obtain the poles and zeros of a transfer function . . . . . . . . . . . . . . . . . . . . . . 16
1.6 Generate Bode plot of a transfer function . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.7 How to check that state space system x 0 = Ax + Bu is controllable? . . . . . . . . . . . 18
1.8 Obtain partial-fraction expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.9 Obtain Laplace transform for a piecewise functions . . . . . . . . . . . . . . . . . . . . 20
1.10 Obtain Inverse Laplace transform of a transfer function . . . . . . . . . . . . . . . . . . 21
1.11 Display the response to a unit step of an under, critically, and over damped system . . 22
1.12 View steady state error of 2nd order LTI system with changing undamped natural fre-
quency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.12.1 Mathematica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.13 Show the use of the inverse Z transform . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.13.1 example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.13.2 example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.14 Find the Z transform of sequence x(n) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.14.1 example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.14.2 example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.15 Sample a continuous time system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.16 Find closed loop transfer function from the open loop transfer function for a unity feedback 31
1.17 Compute the Jordan canonical/normal form of a matrix A . . . . . . . . . . . . . . . . . 32
1.18 Solve the continuous-time algebraic Riccati equation . . . . . . . . . . . . . . . . . . . 33
1.19 Solve the discrete-time algebraic Riccati equation . . . . . . . . . . . . . . . . . . . . . 33
1.20 Display impulse response of H(z) and the impulse response of its continuous time ap-
proximation H(s) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.21 Find the system type given an open loop transfer function . . . . . . . . . . . . . . . . 38
1.22 Find the eigenvalues and eigenvectors of a matrix . . . . . . . . . . . . . . . . . . . . . 39
1.23 Find the characteristic polynomial of a matrix . . . . . . . . . . . . . . . . . . . . . . . 39
1.24 Verify the Cayley-Hamilton theorem that every matrix is zero of its characteristic poly-
nomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.25 How to check for stability of system represented as a transfer function and state space 40
1.25.1 Checking stability using transfer function poles . . . . . . . . . . . . . . . . . . 41
1.25.2 Checking stability using state space A matrix . . . . . . . . . . . . . . . . . . . 41
1.26 Check continuous system stability in the Lyapunov sense . . . . . . . . . . . . . . . . . 42
1.27 Given a closed loop block diagram, generate the closed loop Z transform and check its
stability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.28 Determine the state response of a system to only initial conditions in state space . . . . 45
1.29 Determine the response of a system to only initial conditions in state space . . . . . . . 46
1.30 Determine the response of a system to step input with nonzero initial conditions . . . . 47
1.31 Draw the root locus from the open loop transfer function . . . . . . . . . . . . . . . . . 47
1.32 Find e At where A is a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.33 Draw root locus for a discrete system . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3
4
1.34 Plot the response of the inverted pendulum problem using state space . . . . . . . . . . 50
1.35 How to build and connect a closed loop control systems and show the response? . . . . 53
1.35.1 example 1, single input, single output closed loop . . . . . . . . . . . . . . . . . 53
1.36 Compare the effect on the step response of a standard second order system as ζ changes 55
1.37 Plot the dynamic response factor Rd of a system as a function of r = ωωn for different
damping ratios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
1.38 How to find closed loop step response to a plant with a PID controller? . . . . . . . . . 58
1.39 How to make Nyquist plot? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.39.1 Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
1.39.2 Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4 Differential, PDE solving, integration, numerical and analytical solving of equations 165
4.1 Generate direction field plot of a first order differential equation . . . . . . . . . . . . . 165
4.2 Solve the 2-D Laplace PDE for a rectangular plate with Dirichlet boundary conditions . 167
4.3 Solve homogeneous 1st order ODE, constant coefficients and initial conditions . . . . . 168
4.4 Solve homogeneous 2nd order ODE with constant coefficients . . . . . . . . . . . . . . 169
4.5 Solve non-homogeneous 2nd order ODE, constant coefficients . . . . . . . . . . . . . . 170
6
4.6 Solve homogeneous 2nd order ODE, constant coefficients (BVP) . . . . . . . . . . . . . 171
4.7 Solve the 1-D heat partial differential equation (PDE) . . . . . . . . . . . . . . . . . . . 173
4.8 Show the effect of boundary/initial conditions on 1-D heat PDE . . . . . . . . . . . . . 175
4.9 Find particular and homogenous solution to undetermined system of equations . . . . 176
4.10 Plot the constant energy levels for a nonlinear pendulum . . . . . . . . . . . . . . . . . 178
0000
4.11 Solve numerically the ODE u + u = f using point collocation method . . . . . . . . . 182
4.12 How to numerically solve a set of non-linear equations? . . . . . . . . . . . . . . . . . 185
4.13 Solve 2nd order ODE (Van Der Pol) and generate phase plot . . . . . . . . . . . . . . . 186
4.14 How to numerically solve Poisson PDE on 2D using Jacobi iteration method? . . . . . . 189
4.15 How to solve BVP second order ODE using finite elements with linear shape functions
and using weak form formulation? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
4.16 How to solve Poisson PDE in 2D using finite elements methods using rectangular element? 195
4.16.1 Integrating the force vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
4.16.2 f (x, y) = 3 (cos(4πx) + sin(3πy)) . . . . . . . . . . . . . . . . . . . . . . . . . . 200
4.16.3 f (x, y) = 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
4.16.4 f (x, y) = xy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
4.16.5 f (x, y) = 3 (cos(4πx) + sin(3πy)) . . . . . . . . . . . . . . . . . . . . . . . . . . 205
4.16.6 Solving for reactangle grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
4.16.7 f (x, y) = 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
4.16.8 f (x, y) = xy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
4.16.9 f (x, y) = 3 (cos(4πx) + sin(3πy)) . . . . . . . . . . . . . . . . . . . . . . . . . . 210
4.17 How to solve Poisson PDE in 2D using finite elements methods using triangle element? 212
4.17.1 f (x, y) = 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
4.17.2 Program output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
4.17.3 f (x, y) = 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
4.18 How to solve wave equation using leapfrog method? . . . . . . . . . . . . . . . . . . . 221
4.19 Numerically integrate f (x) on the real line . . . . . . . . . . . . . . . . . . . . . . . . . 224
4.20 Numerically integrate f (x, y) in 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
4.21 How to solve set of differential equations in vector form . . . . . . . . . . . . . . . . . 225
4.22 How to implement Runge-Kutta to solve differential equations? . . . . . . . . . . . . . 227
4.22.1 First order ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
4.22.2 second order ODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
4.23 How to differentiate treating a combined expression as single variable? . . . . . . . . . 229
4.24 How to solve Poisson PDE in 2D with Neumann boundary conditions using Finite Elements 230
4.24.1 Mathematica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Matlab
clear all;
1 num/den =
m_zeros = [-1 -2];
2 5 s^2 + 15 s + 10
m_poles = [0 -4 -6];
3 -------------------
gain = 5;
4 s^3 + 10 s^2 + 24 s
sys = zpk(m_zeros,m_poles,gain);
[num,den] = tfdata(sys,'v');
printsys(num,den,'s')
7
8
Maple
1 restart;
2 alias(DS=DynamicSystems):
3 zeros :=[-1,-2]:
4 poles :=[0,-4,-6]:
h i
tf = 5 s 2 +15 s+10
5 gain :=5: s 3 +10 s 2 +24 s
6 sys :=DS:-TransferFunction(zeros,poles,gain
):
7 #print overview of the system object
8 DS:-PrintSystem(sys);
1 exports(sys);
2 #To see fields in the sys object, do the
following
3 # tf, inputcount, outputcount, statecount,
sampletime,
4 # discrete, systemname, inputvariable,
outputvariable,
5 # statevariable, parameters, systemtype,
5 ∗ s 2 + 15 ∗ s + 10
ModulePrint
6 tf:=sys[tf]; #reads the transfer function
7 Matrix(1,1,{(1,1)=(5*s^2+15*s+10)/(s^3+10*s
^2+24*s)})
8 numer(tf[1,1]); #get the numerator of the tf
1 denom(tf[1,1]); #get the denominator of the
tf s ∗ (s 2 + 10 ∗ s + 24)
Mathematica
1 Clear["Global`*"]; 0 1 0
2 sys = TransferFunctionModel[(5 s)/(s^2+4 s+25),s]; Out[48]= -25 -4 1
0 5 0
3 ss = MinimalStateSpaceModel[StateSpaceModel[sys]]
Out[49]//MatrixForm=
0 1
-25 -4
1 (a=Normal[ss][[1]])//MatrixForm Out[50]//MatrixForm=
2 (b=Normal[ss][[2]])//MatrixForm 0
3 (c=Normal[ss][[3]])//MatrixForm 1
4 (d=Normal[ss][[4]])//MatrixForm
Out[51]//MatrixForm=
(0 5)
Out[52]//MatrixForm=
(0)
9
1 A =
2 -4 -25
Matlab 3 1 0
4 B =
clear all;
5 1
s = tf('s');
6 0
sys_tf = (5*s) / (s^2 + 4*s + 25);
7 C =
[num,den] = tfdata(sys_tf,'v');
8 5 0
[A,B,C,D] = tf2ss(num,den)
9 D =
10 0
Maple
1 restart;
2 alias(DS=DynamicSystems): " #
3 sys := DS:-TransferFunction(5*s/(s^2+4*s+25)): 0 1
4 sys := DS:-StateSpace(sys); −25 −4
5 exports(sys); #to see what fields there are
6 a := sys:-a;
" #
1 b:=sys:-b; 0
1
1 c:=sys:-c;
h i
0 5
1 d:=sys:-d;
h i
0
problem 2
Problem: Given the continuous time S transfer function defined by
1+s
H (s) =
s2 + s + 1
convert to state space and back to transfer function.
Mathematica
1 Clear["Global`*"]; 0 1 0
© ª
2 sys = TransferFunctionModel[(s + 1)/(s^2 + 1 s + 1), s]; −1
−1 1 ®®
3 ss = MinimalStateSpaceModel[StateSpaceModel[sys]] « 1 1 0 ¬
1 TransferFunctionModel[ss] s +1
s2 +s +1
10
1 A =
2 -1 -1
3 1 0
Matlab 4
5 B =
clear all;
6 1
s = tf('s');
7 0
sys = ( s+1 )/(s^2 + s + 1);
8
[num,den]=tfdata(sys,'v');
9 C =
%convert to state space
10 1 1
[A,B,C,D] = tf2ss(num,den)
11
12 D =
13 0
%convert from ss to tf 1 sys =
[num,den] = ss2tf(A,B,C,D); 2 s + 1
sys=tf(num,den) 3 -----------
4 s^2 + s + 1
1.1.3 Create a state space representation from A,B,C,D and find the step response
Problem: Find the state space representation and the step response of the continuous time system
defined by the Matrices A,B,C,D as shown
1 A =
2 0 1 0 0
3 0 0 1 0
4 0 0 0 1
5 -100 -80 -32 -8
6
7 B =
8 0
9 0
10 5
11 60
12
13 C =
14 1 0 0 0
15
16 D =
17 0
Mathematica
1 Clear["Global`*"];
2
3 a = {{0,1,0,0},
4 {0,0,1,0},
5 {0,0,0,1},
6 {-100,-80,-32,-8}
1.2
7 };
1.0
8
0.8
10 c = {{1,0,0,0}}; 0.4
11 d = {{0}}; 0.2
12
sys = StateSpaceModel[{a,b,c,d}];
2 4 6 8 10
13
14 y = OutputResponse[sys,UnitStep[t],{t,0,10}];
15
16 p = Plot[Evaluate@y, {t, 0, 10},
17 PlotRange -> All,
18 GridLines -> Automatic,
19 GridLinesStyle -> LightGray]
11
Matlab
clear all;
A = [0 1 0 0;
0 0 1 0; 1.2
unit step response
0 0 0 1; 1
Amplitude
C = [1 0 0 0]; 0.6
D = [0]; 0.4
0.2
sys = ss(A,B,C,D); 0
0 1 2 3 4 5
Time (seconds)
step(sys);
grid;
title('unit step response');
Maple
1 restart:
2 alias(DS=DynamicSystems):
3 alias(size=LinearAlgebra:-Dimensions);
4 a:=Matrix([[0,1,0,0],[0,0,1,0],
5 [0,0,0,1],[-100,-90,-32,-8]]):
6 b:=Matrix([[0],[0],[5],[6]]):
7 c:=Matrix([[1,0,0,0]]):
8 d:=Matrix([[1]]):
9 sys:=DS:-StateSpace(a,b,c,d);
10
11 DS:-ResponsePlot(sys, DS:-Step(),
12 duration=10,color=red,legend="step");
1.1.4 Convert continuous time to discrete time transfer function, gain and phase
margins
Problem: Compute the gain and phase margins of the open-loop discrete linear time system sampled
from the continuous time S transfer function defined by
1+s
H (s) =
s2 +s +1
Use sampling period of 0.1 seconds.
12
Mathematica
1 Clear["Global`*"]; 1+s
Out[88]=
2 tf = TransferFunctionModel[(s+1)/(s^2+1 s+1),s]; 1+s+s 2
1 ds = ToDiscreteTimeModel[tf, 0.1, z,
2 Method -> "ZeroOrderHold"] Out[89]=
-0.0903292 + 0.0998375 z
0.904837 - 1.89533 z + z2 0.1
1 gm
2 Out
[28]={{31.4159,19.9833}}
1 {gm, pm} = GainPhaseMargins[ds];
3 pm
4 Out
[29]={{1.41451,1.83932},{0.,
Pi}}
1 max = 100;
2 yn = OutputResponse[ds, unit step response
1.4
3 Table[UnitStep[n],{n, 0, max}]];
4 1.2
5 ListPlot[yn, 1.0
6 Joined -> True,
0.8
7 InterpolationOrder -> 0, y[n]
1 0.09984 z - 0.09033
2 ----------------------
3 z^2 - 1.895 z + 0.9048
4
5 Sample time: 0.1 seconds
Matlab 6 Discrete-time transfer
function.
clear all; close all; 7
Ts = 0.1; %sec, sample period 8 Gm =
s = tf('s'); 9 19.9833
sys = ( s + 1 ) / ( s^2 + s + 1); 10
%convert s to z domain 11 Pm =
sysd = c2d(sys,Ts,'zoh'); 12 105.3851
tf(sysd) 13
14 Wcg =
15 31.4159
16
17 Wcp =
18 1.4145
Step Response
1.2
1
Amplitude
step(sysd,10); 0.8
[Gm,Pm,Wcg,Wcp] = margin(sysd)
0.6
0.4
0.2
0
0 5 10
Time (seconds)
13
d 2y dy
3 + 2 + y (t) = u(t)
dt 2 dt
Mathematica
1 Clear[y, u, t]; 2 1 1
2 eq = 3 y''[t] + 2 y'[t] + y[t] == u[t]; - -
Out[34]=
3 3 3
3 ss = StateSpaceModel[ {eq}, {{y'[t], 0}, 1 0 0
4 {y[t], 0}}, {{u[t], 0}}, {y[t]}, t];
5 ss = MinimalStateSpaceModel[ss]
0 1 0
1
1 tf = Simplify[TransferFunctionModel[ss]] Out[35]= . .2
1+2s
.+3s
.
Matlab
clear all;
syms y(t) Y 1 1
eq = 3*diff(y,2)+2*diff(y)+y; 2 --------------
lap = laplace(eq); 3 2
lap = subs(lap,'y(0)',0); 4 3 s + 2 s + 1
lap = subs(lap,'D(y)(0)',0);
lap = subs(lap,'laplace(y(t),t,s)',Y);
H = solve(lap-1,Y);
pretty(H)
1 A =
2 -0.6667 -0.3333
3 1.0000 0
[num,den] = numden(H); 4 B =
num = sym2poly(num); 5 1
den = sym2poly(den); 6 0
[A,B,C,D] = tf2ss(num,den) 7 C =
8 0 0.3333
9 D =
10 0
Maple
1 restart;
2 alias(DS=DynamicSystems):
3
4 ode:=3*diff(y(t),t$2)+2*diff(y(t),t)+y(t)=
5 Heaviside(t):
6
1
7 sys:=DS:-DiffEquation(ode, 3s 2 + 2s + 1
8 'outputvariable'=[y(t)],
9 'inputvariable'=[Heaviside(t)]):
10
11 sys:=DS:-TransferFunction(sys):
12 sys:-tf(1,1);
1 sys:=DS:-StateSpace(sys):
2 #show the state space matrices
0 1
0 h i h i
3 {sys:-a,sys:-b,sys:-c,sys:-d}; , , 1/3 , 0
0
−1/3
−2/3 1
14
1.1.6 Convert from continuous transfer function to discrete time transfer function
Problem: Convert
1
H (s) =
s2 + 10s + 10
To Z domain transfer function using sampling period of 0.01 seconds and using the zero order hold
method.
Mathematica
1 Clear["Global`*"]
2 sys = TransferFunctionModel[
3 1/(s^2 +10 s+20),s]; 0.0000467806 + 0.0000483662 z
4 0.904837 - 1.90293 z + z2 0.01
5 sysd= ToDiscreteTimeModel[sys,0.01,z,
6 Method->"ZeroOrderHold"]
1 sysz =
Matlab 2
3 4.837e-05 z + 4.678e-05
s = tf('s'); 4 -----------------------
sys = 1/(s^2 + 10*s + 20); 5 z^2 - 1.903 z + 0.9048
T = 0.01; %seconds 6
sysz = c2d(sys,T,'zoh') 7 Sample time: 0.01 seconds
8 Discrete-time transfer function.
Mathematica
1 tfToDiff[tf_, s_, t_, y_, u_]:=
2 Module[{rhs,lhs,n,m},
3 rhs = Numerator[tf];
4 lhs = Denominator[tf];
5 rhs = rhs /. m_. s^n_. -> m D[u[t], {t, n}]; 1 25 + 4 y'[t]+y''[t
6 lhs = lhs /. m_. s^n_. -> m D[y[t], {t, n}]; ]==5 u'[t]
7 lhs == rhs
8 ]
9
10 tf = (5s)/(s^2+4s+25);
11 tf = C0 s/(R0 C0 s + 1);
12 eq=tfToDiff[tf, s, t, y, u]
1.2 Obtain the step response of an LTI from its transfer function
Problem: Find the unit step response for the continuous time system defined by the transfer function
25
H (s) =
s2 + 4s + 25
15
Mathematica
1 Clear["Global`*"]; step response
1.4
2
3 tf=TransferFunctionModel[25/(s^2+4s+25),s]; 1.2
y(t)
8 Frame -> True, 0.6
Matlab
step response
1.4
clear all;
s = tf('s'); 1.2
sys = 25/(s^2+4*s+25);
1
[y,t] = step(sys,4);
0.8
plot(t,y,'r'); y(t)
xlim([0 4]); 0.6
ylim([0 1.4]);
0.4
title('step response');
xlabel('t'); 0.2
ylabel('y(t)');
0
grid 0 1 2 3 4
set(gcf,'Position',[10,10,310,310]); t
Maple
1 restart:
2 with(DynamicSystems):
3 sys := TransferFunction(25/(s^2+4*s+25)):
4 ResponsePlot(sys, Step(),duration=4);
1.3 plot the impulse and step responses of a system from its transfer
function
Problem: Find the impulse and step responses for the continuous time system defined by the transfer
function
1
H (s) = 2
s + 0.2s + 1
and display these on the same plot up to some t value.
Side note: It was easier to see the analytical form of the responses in Mathematica and Maple so it is
given below the plot.
16
Mathematica
1 {1 - E^(-t/10) Cos[(3 Sqrt
1 Clear["Global`*"];
[11] t)/10]
2 SetDirectory[NotebookDirectory[]]
2 - (
3 sys = TransferFunctionModel
3 E^(-t/10) Sin[(3 Sqrt[11]t)
4 [1/(s^2 + 2/10 s + 1), s];
/10])/
5
4 (3
6 yStep = Assuming[t > 0,
Sqrt[11])}
7 Simplify@OutputResponse[
8 sys, UnitStep[t], t]]
1 {(10 E^(-t/10) HeavisideTheta
1 yImpulse = Simplify@ [t]
2 OutputResponse[sys,DiracDelta[t],t] 2 Sin[(3 Sqrt[11] t)/10])/(3
Sqrt[11])}
1 p = Grid[{
2 {Plot[Evaluate@{yStep, yImpulse},
3 {t, 0, 50}, 2.0
step and impulse reponse
8 0.5
12 AspectRatio -> 1] 0 10 20 30 40 50
13 }, t
3 11 t ⅇ-t/10 Sin
3 11 t
step response=1 - ⅇ-t/10 Cos - 10
14 {Row[{"step response=", Re@yStep}]}, 10 3
3
11
11 t
10 ⅇ-t/10 HeavisideTheta[t] Sin
15 {Row[{"impulse response=",Re@yImpulse}]} impulse response= 10
3 11
Matlab
clear all; close all;
t = 0:0.05:50; Step and Impulse responses
2
s = tf('s');
step
sys = 1/(s^2+0.2*s+1); impulse
1.5
y = step(sys,t);
plot(t,y,'-r')
1
hold on
y = impulse(sys,t);
y(t)
0.5
plot(t,y,'-k')
title('Step and Impulse responses'); 0
xlabel('t');
ylabel('y(t)'); -0.5
xlim([0 50]);
ylim([-0.8 2]); 0 10 20 30 40 50
legend('step','impulse'); t
grid on;
set(gcf,'Position',[10,10,310,310]);
17
Maple
Mathematica
1 Clear["Global`*"];
2 SetDirectory[NotebookDirectory[]]
3 sys=TransferFunctionModel[1/(s^2+2/10 s+1),s];
4 u = Sin[t]; input and its reponse
5 y = OutputResponse[sys, u, t]; 4
6 p = Grid[{
7 {Plot[Evaluate@{y, u}, {t, 0, 50}, 2
Matlab
clear all;
close all; input and its response
5
t = 0:0.05:50;
u = sin(t);
s = tf('s');
sys = 1/(s^2+0.2*s+1);
[num,den] = tfdata(sys,'v');
y(t)
0
y = lsim(num,den,u,t);
plot(t,u,'k',t,y,'r');
title('input and its response');
xlabel('t'); ylabel('y(t)');
xlim([0 50]); -5
0 10 20 30 40 50
ylim([-5 5]); t
grid on;
set(gcf,'Position',[10,10,310,310]);
Maple
1 restart;
2 with(inttrans):H:=1/(s^2+0.2*s+1);
3 input:=sin(t);
4 inputS:=laplace(input,t,s):
5 y:=invlaplace(inputS*H,s,t);
6 plot([y,input],t=0..25,
7 title=`system response`,
8 labels=[`time`,`y(t)`],
9 color=[black,red],
10 legend=["response","input"]);
Mathematica
1 {{{}}}
1 Clear["Global`*"];
2 sys=TransferFunctionModel[25/(s^2+4 s+25),s];
3 TransferFunctionZeros[sys]
1 TransferFunctionPoles[sys]//N 1 {{{-2.-4.58258 I,-2.+4.58258
I}}}
19
Matlab
1
clear all; 2 z =
s = tf('s'); 3 Empty matrix: 0-by-1
sys = 25/(s^2+4*s+25); 4
[z,p,k] =zpkdata(sys,'v') 5 p =
6 -2.0000 + 4.5826i
7 -2.0000 - 4.5826i
Maple
1 zeros:= []
1 restart; 2 poles:=
2 alias(DS=DynamicSystems): [-2.000000000-4.582575695*
3 sys:=DS:-TransferFunction(25/(s^2+4*s+25)): I,
4 r :=DS:-ZeroPolePlot(sys,output=data): 3 -2.+4.582575695*I]
5 zeros := r[1];
6 poles := r[2];
Mathematica
1 Clear["Global`*"]; Bode plot
2 0
4
-40
5 BodePlot[tf, GridLines -> Automatic,
6 ImageSize -> 300, -60
0
11 ScalingFunctions -> {{"Log10", "dB"},
12 {"Log10", "Degree"}}, -50
15 ]
Bode Diagram
10
0
Magnitude (dB)
Matlab -10
-20
clear all;
s = tf('s'); -30
45
grid;
0
set(gcf,'Position',[10,10,400,400]);
-45
-90
10 -1 10 0 10 1 10 2
Frequency (rad/s)
20
Maple
1 restart:
2 alias(DS=DynamicSystems):
3 sys:=DS:-TransferFunction(5*s/(s^2+4*s+25)):
4 DS:-BodePlot(sys,output=dualaxis,
5 range=0.1..100);
or can plot the the two bode figures on top of each others as follows
1 DS:-BodePlot(sys,size=[400,300],
2 output=verticalplot,range=0.1..100);
x 0 = Ax + Bu
y = Cx + Du
Is controllable if for any initial state x 0 and any final state x f there exist an input u which moves the
system from x 0 to x f in finite time. Only the matrix A and B are needed to decide on controllability. If
the rank of
[B AB A2 B . . . An−1 B]
is n which is the number of states, then the system is controllable. Given the matrix
© 0 1 0 0 ª
0 0 −1 0 ®®
A=
®
0 0 0 1 ®®
« 0 0 5 0 ¬
And
© 0 ª
1 ®
B=
®
®
0 ®
®
« −2 ¬
Mathematica
1 A0 = {{0, 1, 0, 0},
2 {0, 0, -1, 0}, © 0 1 0 2 ª
3 {0, 0, 0, 1}, 1 0 2 0 ®®
{0, 0, 5, 0}};
4 ®
5 B0 = {{0}, {1}, {0}, {-2}};
0 −2 0 −10 ®®
6 sys = StateSpaceModel[{A0, B0}]; −2 0 −10 0 ¬
7 m = ControllabilityMatrix[sys]
«
1 ControllableModelQ[sys]
True
1 MatrixRank[m]
4
21
Matlab
A0 = [0 1 0 0; 1 m =
0 0 -1 0; 2 0 1 0 2
0 0 0 1; 3 1 0 2 0
0 0 5 0]; 4 0 -2 0 -10
B0 = [0 1 0 -2]'; 5 -2 0 -10 0
sys = ss(A0,B0,[],[]);
m = ctrb(sys)
rank(m)
4
Maple
1 restart:
2 alias(DS=DynamicSystems):
3 A:=Matrix( [ [0,1,0,0], 0 1 0 2
4 [0,0,-1,0],
5 [0,0,0,1], 1 0 2 0
[0,0,5,0]
6
7 ]
0 −2 0 −10
8 );
9 B:=Matrix([[0],[1],[0],[-2]]); −2 0 −10 0
10 sys:=DS:-StateSpace(A,B);
11 m:=DS:-ControllabilityMatrix(sys);
1 DS:-Controllable(sys,method=rank);
true
1 DS:-Controllable(sys,method=staircase);
true
1 LinearAlgebra:-Rank(m);
4
s 4 + 8s 3 + 16s 2 + 9s + 9
H (s) =
s 3 + 6s 2 + 11s + 6
obtain the partial-fractions decomposition.
Comment: Mathematica result is easier to see visually since the partial-fraction decomposition returned
in a symbolic form.
Mathematica
1 Remove["Global`*"]; 1 2 + s +3/(1+s) -4/(2+s)
2 expr = (s^4+8 s^3+16 s^2+9 s+6)/ -6/(3+s)
3 (s^3+6 s^2+11 s+6);
4 Apart[expr]
22
1 r =
2 -6.0000
Matlab 3 -4.0000
4 3.0000
clear all; 5
s=tf('s'); 6 p =
tf_sys = (s^4+8*s^3+16*s^2+9*s+6)/... 7 -3.0000
(s^3+6*s^2+11*s+6); 8 -2.0000
[num,den] = tfdata(tf_sys,'v'); 9 -1.0000
[r,p,k] = residue(num,den) 10
11 k =
12 1 2
Maple
7 9 9
1 p:=(s^4+8*s^3+16*s^2+9*s+9)/(s^3+6*s^2+11*s+6); s +2− − +
s + 2 2s + 6 2s + 2
2 p0:=convert(p,parfrac);
1 [op(p0)]; 7 9 9
[s, 2, ,− , ]
s + 2 2s + 6 2s + 2
f(t)
T t
Mathematica
1 Remove["Global`*"];
1 Out[]= (1 - E^((-s)*T))/s
2 f[t_] := Piecewise[{{0,t<0},
^2
3 {t,t>= 0 && t< T},
4 {T, t>T}}]
5 Simplify[LaplaceTransform[f[t],t,s] ,{T>0}]
Matlab
1 1 - exp(-T s)
clear all; 2 -------------
syms T t s; 3 2
syms s positive; 4 s
I1 = int(t*exp(-s*t),t,0,T);
I2 = int(T*exp(-s*t),t,T,Inf);
result = simple(I1+I2);
pretty(result)
23
Maple
With Maple, had to use Heaviside else Laplace will not obtain
the transform of a piecewise function.
1 restart; 1 − e −sT
2 assume(T>0):
3 interface(showassumed=0): s2
4 f:=t->piecewise(t<0,0,t>=0 and t<T,t,t>T,T):
5 r:=convert(f(t),Heaviside):
6 r:=inttrans[laplace](r,t,s);
s 4 + 5s 3 + 6s 2 + 9s + 30
H (s) =
s 4 + 6s 3 + 21s 2 + 46s + 30
Mathematica
1 Remove["Global`*"];
2 f = (s^4+5 s^3+6 s^2+9 s+30)/(s^4+6 s^3+21 s^2+46 s+30);
3 InverseLaplaceTransform[f,s,t];
4 Expand[FullSimplify[%]]
i 3e −3t 23e −t
1
δ (t) + + e (−1−3i)t (73 + 326i)e 6it + (−326 − 73i) − +
234 234 26 18
Matlab
clear all;
syms s t
f = (s^4+5*s^3+6*s^2+9*s+30)/(s^4+6*s^3+21*s^2+46*s+30);
pretty(f)
1 4 3 2
2 s + 5 s + 6 s + 9 s + 30
3 -----------------------------
4 4 3 2
5 s + 6 s + 21 s + 46 s + 30
pretty(ilaplace(f))
1 / 399 sin(3 t) \
2 253 exp(-t) | cos(3 t) + ------------ |
3 23 exp(-t) 3 exp(-3 t) \ 253 /
4 ---------- - ----------- + dirac(t) - ---------------------------------------
5 18 26 117
Maple
1 restart;
2 interface(showassumed=0):
3 p:=(s^4+5*s^3+6*s^2+9*s+30)/(s^4+6*s^3+21*s^2+46*s+30);
4 r:=inttrans[invlaplace](p,s,t);
1.5
ξ values
0.2
1.0
0.4
y(t)
0.6
0.8
0.5 1.
1.2
0.0
0 5 10 15 20
t
Matlab
clear; close all;
wn = 1;
z = .2:.2:1.2;
t = 0:0.05:20;
y = zeros(length(t),length(z));
legendStr = cell(length(z),1);
for i = 1:length(z)
[num,den] = ord2(wn,z(i));
num = num*wn^2;
[y(:,i),~,~] = step(num,den,t);
legendStr(i) = {sprintf('%1.1f',z(i))};
end
plot(t,y);
legend(legendStr);
title(sprintf(
'2nd order system step response with changing %s',
'\zeta'));
xlabel('time (sec)');
ylabel('amplitude');
grid on;
set(gcf,'Position',[10,10,400,400]);
25
amplitude
0.8
0.6
0.4
0.2
0
0 5 10 15 20
time (sec)
Maple
1 restart;
2 alias(DS=DynamicSystems):
3 H := (w,zeta)->w^2/(s^2+2*zeta*w*s+w^2):
4 sys := (w,zeta)->DS:-TransferFunction(H(w,zeta)):
5 zetaValues := [seq(i,i=0.1..1.2,.2)]:
6 sol:=map(z->DS:-Simulate(sys(1,z),
7 Heaviside(t)),zetaValues):
8 c :=ColorTools:-GetPalette("Niagara"):
9
10 plots:-display(seq(plots[odeplot]
11 (sol[i],t=0..20,color=c[i],
12
13 legend=typeset(zeta,"=",zetaValues[i]),
14 legendstyle=[location=right]),
15 i=1..nops(zetaValues)),
16 gridlines=true,
17 title="step response for different damping ratios",
18 labels=[typeset(t),typeset(y(t))]);
Instead of using Simulate as above, another option is to use ResponsePlot which gives same plot
as above.
1 restart;
2 alias(DS=DynamicSystems):
3 c:=ColorTools:-GetPalette("Niagara"):
4 H:=(w,zeta)->w^2/(s^2+2*zeta*w*s+w^2):
5 sys:= (w,zeta)->
6 DS:-TransferFunction(H(w,zeta)):
7 zetaValues := [seq(i,i=0.1..1.2,.2)]:
8
9 sol:=map(i->DS:-ResponsePlot(sys(1,zetaValues[i]),
10 Heaviside(t),
11 duration=14,
12 color=c[i],
13 legend=typeset(zeta,"=",zetaValues[i]),
14 legendstyle=[location=right]
15 ),
16 [seq(i,i=1..nops(zetaValues))]
17 ):
18
19 plots:-display(sol,gridlines=true,
20 title="step response for different damping ratios",
21 labels=[typeset(t),typeset(y(t))]
22 );
26
1.12 View steady state error of 2nd order LTI system with changing
undamped natural frequency
Problem: Given the transfer function
ωn2
H (s) =
s 2 + 2ξ ωn s + ωn2
Display the output and input on the same plot showing how the steady state error changes as the un
damped natural frequency ωn changes. Do this for ramp and step input.
The steady state error is the difference between the input and output for large time. In other words,
it the difference between the input and output at the time when the response settles down and stops
changing.
Displaying the curve of the output and input on the same plot allows one to visually see steady state
error.
Use maximum time of 10 seconds and ξ = 0.707 and change ωn from 0.2 to 1.2.
Do this for ramp input and for unit step input. It can be seen that with ramp input, the steady state do
not become zero even at steady state. While with step input, the steady state error can become zero.
1.12.1 Mathematica
ramp input
1 Remove["Global`*"];
2 sys = TransferFunctionModel[w^2 /(s^2+2 z w s+w^2 ),s];
3 z = .707;
4 nTrials = 6;
5 maxTime = 10;
6
7 tb = Table[Plot[
8 Evaluate@{t,OutputResponse[sys/.w->0.2*i,t,t]},
9 {t,0,maxTime},
10 Frame->True,
11 PlotRange->All,
12 FrameLabel->{
13 {"y(t)",None},
14 {"t","Subscript[\[Omega], n]="<>ToString[0.2*i]}
15 }
16 ],
17 {i,1,nTrials}];
18 Grid[Partition[tb,2]]
27
ωn =0.2 ωn =0.4
10 10
8 8
6 6
y(t)
y(t)
4 4
2 2
0 0
0 2 4 6 8 10 0 2 4 6 8 10
t t
ωn =0.6 ωn =0.8
10 10
8 8
6 6
y(t)
y(t)
4 4
2 2
0 0
0 2 4 6 8 10 0 2 4 6 8 10
t t
ωn =1. ωn =1.2
10 10
8 8
6 6
y(t)
y(t)
4 4
2 2
0 0
0 2 4 6 8 10 0 2 4 6 8 10
t t
step input
1 tb = Table[Plot[
2 Evaluate@{UnitStep[t],
3 OutputResponse[sys/.w->0.2*i,UnitStep[t],t]},
4 {t,0,maxTime},
5 Frame->True,
6 PlotRange->All,
7 FrameLabel->{
8 {"y(t)",None},
9 {"t","Subscript[\[Omega], n]="<>ToString[0.2*i]}
10 }
11 ],
12 {i,1,nTrials}];
13
14 Grid[Partition[tb,2]]
28
ωn =0.2 ωn =0.4
1.0 1.0
0.8 0.8
0.6 0.6
y(t)
y(t)
0.4 0.4
0.2 0.2
0.0 0.0
0 2 4 6 8 10 0 2 4 6 8 10
t t
ωn =0.6 ωn =0.8
1.0 1.0
0.8 0.8
0.6 0.6
y(t)
y(t)
0.4 0.4
0.2 0.2
0.0 0.0
0 2 4 6 8 10 0 2 4 6 8 10
t t
ωn =1. ωn =1.2
1.0 1.0
0.8 0.8
0.6 0.6
y(t)
y(t)
0.4 0.4
0.2 0.2
0.0 0.0
0 2 4 6 8 10 0 2 4 6 8 10
t t
29
1.13.1 example 1
Problem: Given
z
F (z) =
z−1
find x[n] = F −1 (z) which is the inverse Ztransform.
Mathematica
1 Clear["Global`*"];
2
3 x[n_]:= InverseZTransform[z/(z-1),z,n] Inverse Ztransform of
z
z-1
4 1.2
5 ListPlot[Table[{n,x[n]},{n,0,10}], 1.0 ● ● ● ● ● ● ● ● ● ● ●
6 Frame->True, 0.8
7 FrameLabel->{{"x[n]",None}, x[n]
0.6
8 {"n","Inverse Ztransform of z/(z-1)"}}, 0.4
9 FormatType->StandardForm, 0.2
10 RotateLabel->False, 0.0
0 2 4 6 8 10
11 Filling->Axis, n
12 FillingStyle->Red,
13 PlotRange->{Automatic,{0,1.3}},
14 PlotMarkers->{Automatic,12}]
Matlab
function e19()
nSamples = 10;
z = tf('z');
h = z/(z-1);
[num,den] = tfdata(h,'v');
[delta,~] = impseq(0,0,nSamples);
xn = filter(num,den,delta);
xlabel('n'); ylabel('x[n]'); 1
ylim([0 1.3]);
set(gcf,'Position',[10,10,400,400]);
0.8
x[n]
0.6
end
0.4
1.13.2 example 2
Problem: Given
5z
F (z) =
(z − 1)2
find x[n] = F −1 (z)
In Mathematica analytical expression of the inverse Z transform can be generated as well as shown
below
30
Mathematica
1 Clear["Global`*"];
2
3 x[n_]:= InverseZTransform[(5 z)/(z-1)^2,z,n];
4 Print["Inverse Z is ", x[n]]
5z
Inverse Ztransform of
(z - 1)2
60
Inverse Z is 5 n 50 ●
●
1 ListPlot[Table[{n,x[n]},{n,0,10}], 40
●
●
2 Frame->True, x[n] 30
●
●
3 FrameLabel->{{"x[n]",None}, 20
●
●
5 FormatType->StandardForm, 0 ●
0 2 4 6 8 10
RotateLabel->False,
n
6
7 Filling->Axis,
8 FillingStyle->Red,
9 PlotRange->{Automatic,{0,60}},
10 PlotMarkers->{Automatic,12},
11 ImageSize->350]
Matlab
function e19_2()
Inverse Z transform of 5z/(z-1)2
60
nSamples = 10;
z = tf('z'); 50
h = (5*z)/(z-1)^2;
[num,den] = tfdata(h,'v'); 40
[delta,~] = impseq(0,0,nSamples);
x[n]
xn = filter(num,den,delta); 30
20
stem(xn);
title('Inverse Z transform of 5z/(z-1)^2');
10
xlabel('n'); ylabel('x[n]');
ylim([0 60]); 0
set(gcf,'Position',[10,10,400,400]); 0 2 4 6 8 10 12
n
end
Mathematica
1
1 Remove["Global`*"]; 2 Out[] = z/(-1+z)
2 ZTransform[UnitStep[n],n,z]
Matlab
1
syms n 2 1
pretty(ztrans(heaviside(n))) 3 ----- + 1/2
4 z - 1
1.14.2 example 2
1 n
Find the Z transform for x[n] = u (n) + (0.9)n−3 u (n)
3
31
Mathematica
1 z (3/(-1+3 z)+10000/(729
1 f[n_]:=((1/3)^n+(9/10)^(n-3))UnitStep[n]; (-9+10 z)))
2 ZTransform[f[n],n,z]
Matlab
1 100 1
syms n 2 ------------- + ------- +
pretty(ztrans( 1729/1458
((1/3)^n+(0.9)^(n-3)) 3 81 (z - 9/10) 3 z - 1
*heaviside(n)))
ZOH
Plant
ut e t sint ukT ykT
1e Ts 3s
T1 s
Sampling s1s2
period
1 ut T
t
0 T
s = tf('s');
plant = (1/s)*(1/(s+0.5));
c2d(plant,sampleTime,'zoh')
In Matlab it is implemented
as follows
Use sampling frequency f = 1 Hz and show the result for up to 14 seconds. Use as input the signal
u(t) = exp(−0.3t) sin(2π (f /3)t).
Plot the input and output on separate plots, and also plot them on the same plot.
Mathematica
1
2 Clear["Global`*"];
3
4 nSamples =14;
5 f =1.0;
6 sampleTime =1/f;
7 u[t_] := Sin[2*Pi*(f/3)*t]*Exp[-0.3*t]
32
8 ud[n_]:= u[n*sampleTime];
9 plant = TransferFunctionModel[
10 (3 s)/((s+1)(s+2)),s];
11 sysd = ToDiscreteTimeModel[plant,
12 sampleTime,
13 z,
14 Method->"ZeroOrderHold"]
-0.697632 + 0.697632 z
0.0497871 - 0.503215 z + z 2 1.
1 opts = {Joined->True,PlotRange->All,
2 AspectRatio->1,InterpolationOrder->0,
3 ImageSize->200,Frame->True,
4 PlotRange->{{0,nSamples},{-0.5,0.5}},
5 GridLines->Automatic,GridLinesStyle->Dashed};
6
7 inputPlot = ListPlot[Table[ud[k],{k,0,nSamples}],
8 Evaluate[opts],
9 FrameLabel->{{"u(t)",None},
10 {"n","plant input u(nT)"}},
11 PlotStyle->{Thick,Red}];
12
13 plantPlot=ListPlot[OutputResponse[sysd,Table[ud[k],
14 {k,0,nSamples}]],
15 Evaluate[opts],
16 FrameLabel->{{"y(t)",None},
17 {"n","plant output y(nT)"}},
18 PlotStyle->{Thick,Blue}];
19
20 Grid[{{inputPlot,plantPlot}}]
0.6 0.4
0.4
0.2
0.2
0.0
u(t)
y(t)
0.0
-0.2
-0.2
-0.4
-0.4
-0.6
2 4 6 8 10 12 14 2 4 6 8 10 12 14
n n
1 Show[{inputPlot,plantPlot},
2 PlotLabel->"input/output plot"]
input/output plot
plant input u(nT)
0.6
0.4
0.2
u(t)
0.0
-0.2
-0.4
2 4 6 8 10 12 14
n
33
Matlab
clear all; close all;
nSamples = 14;
f = 1;
T = 1/f;
u=@(t) sin(2*pi*(f/3).*t).*exp(-0.3.*t);
ud=@(n) u(n*T);
U=ud(1:14); %sampled input
s=tf('s');
plant = (3*s)/((s+1)*(s+2));
plantD = c2d(plant,T,'zoh')
1 plantD =
2
3 0.6976 z - 0.6976
4 ------------------------
5 z^2 - 0.5032 z + 0.04979
6
7 Sample time: 1 seconds
8 Discrete-time transfer function.
lsim(plantD,U,0:nSamples-1)
grid
0.6
0.4
Amplitude
0.2
-0.2
-0.4
-0.6
0 5 10
Time (seconds)
1.16 Find closed loop transfer function from the open loop transfer
function for a unity feedback
Problem: Given
s
L(s) =
(s + 4)(s + 5)
as the open loop transfer function, how to find G(s), the closed loop transfer function for a unity
feedback?
34
Ls
Rs s Cs
s4 s5
Convert to
Rs
Gs Cs
Mathematica
1 Clear["Global`*"]; s
2 sys = TransferFunctionModel[
(4 + s) (5 + s)
3 s/((s+4)(s+5)),s]
1 closedLoop = SystemsModelFeedbackConnect[sys]; s
20 + 10 s + s 2
Matlab
1 Transfer function:
clear all; close all; 2 s
s=tf('s'); 3 ---------------
sys=s/((s+4)*(s+5)); 4 s^2 + 10 s + 20
closedloop=feedback(sys,1)
Mathematica
1 Remove["Global`*"]; © 3 −1 1 1 0 0 ª
2 m={{3,-1,1,1,0,0}, 1 1 −1 −1 0 0 ®®
{1, 1,-1,-1,0,0},
3 ®
4 {0,0,2,0,1,1},
0 0 2 0 1 1 ®®
5 {0,0,0,2,-1,-1},
0 0 0 2 −1 −1 ®®
6 {0,0,0,0,1,1}, ®
7 {0,0,0,0,1,1}};
0 0 0 0 1 1 ®®
8 MatrixForm[m] 0 0 0 0 1 1 ¬
«
© 0 0 0 0 0 0 ª
0 2 1 0 0 0 ®
®
1 {a,b}=JordanDecomposition[m]; ®
2 b
0 0 2 0 0 0 ®
®
0 0 0 2 1 0 ®
®
®
0 0 0 0 2 1 ®
®
« 0 0 0 0 0 2 ¬
35
Matlab
clear all; 1 ans =
A=[3 -1 1 1 0 0; 2 0 0 0 0 0 0
1 1 -1 -1 0 0; 3 0 2 1 0 0 0
0 0 2 0 1 1; 4 0 0 2 1 0 0
0 0 0 2 -1 -1; 5 0 0 0 2 0 0
0 0 0 0 1 1; 6 0 0 0 0 2 1
0 0 0 0 1 1;] 7 0 0 0 0 0 2
jordan(A)
A0X + XA − X BR −1 B 0X + C 0C = 0
given
!
−3 2
A=
1 1
!
0
B=
1
C = 1 −1
R=3
Mathematica
1 Clear ["Global`*"];
2 a={{-3,2},{1,1}}; !
3 b={{0},{1}}; 0.589517 1.82157
4 c={{1,-1}};
5 r={{3}}; 1.82157 8.81884
6 sol=RiccatiSolve[{a,b},{Transpose[c].c,r}];
7 MatrixForm[N[sol]]
Matlab
%needs control system
clear all; close all; 1 x =
a = [-3 2;1 1]; 2 0.5895 1.8216
b = [0 ; 1]; 3 1.8216 8.8188
c = [1 -1];
r = 3;
x = care(a,b,c'*c,r)
A0X + XA − X BR −1 B 0X + C 0C = 0
Let R = [3].
36
Mathematica
1 Clear["Global`*"];
2 sys=TransferFunctionModel[1/(s(s+.5)),s]; 0.360816 + 0.426123 z
3 dsys=ToDiscreteTimeModel[sys, 0.606531 - 1.60653 z + z2 1.
4 1,z,Method->"ZeroOrderHold"]
1 ss = StateSpaceModel[dsys] 0 1. 0
-0.606531 1.60653 1.
0.360816 0.426123 0 1.
1 a = ss[[1,1]];
2 b = ss[[1,2]];
3 c = ss[[1,3]];
4 d = ss[[1,4]]; !
5 r = {{3}}; 0.671414 −0.977632
6 DiscreteRiccatiSolve[{a,b}, −0.977632 2.88699
7 {Transpose[c].c,r}];
8 MatrixForm[%]
1 dsys =
Matlab 2 0.4261 z + 0.3608
3 ----------------------
clear all; close all; 4 z^2 - 1.607 z + 0.6065
s = tf('s'); 5
sys = 1/(s*(s+0.5)); 6 Sample time: 1 seconds
dsys = c2d(sys,1) 7 Discrete-time transfer
function.
1 A =
2 1.6065 -0.6065
3 1.0000 0
4 B =
5 1
6 0
[A,B,C,D]=dssdata(dsys) 7 C =
8 0.4261 0.3608
9 D =
10 0
11
12 2.8870 -0.9776
13 -0.9776 0.6714
1 ans =
2
dare(A,B,C'*C,3)
3 2.8870 -0.9776
4 -0.9776 0.6714
z
0.5 - 1.4 z + z2 0.5
1 {0.,1.,1.4,1.46,1.344,1.1516,0.94024,0.740536,
2 0.56663,0.423015,0.308905,0.22096,0.154891,
3 0.106368,0.0714694,0.0468732,0.0298878,
4 0.0184063,0.0108249,0.00595175,0.00291999}
5.60992 + 1.25559 s
0.560992 + 1.38629 s + s 2
1.4
1.2
1.0
0.8
0.6
0.4
0.2
0.0
0 2 4 6 8 10
1.5
1.0
0.5
0.0
0 2 4 6 8 10
1.4
1.2
1.0
response
0.8
0.6
0.4
0.2
0.0
0 2 4 6 8 10
time (sec)
Do the same plot above, using stair case approximation for the discrete plot
1 Show[
2 ListPlot[
3 discreteResponse,
4 Filling->None,PlotRange->All,DataRange->{0,maxSimulationTime},
5 ImageSize->300,ImagePadding->{{45,10},{35,50}},AspectRatio->0.9,
6 AxesOrigin->{0,0},Frame->True,Axes->None,
7 Joined->True,InterpolationOrder->0,PlotStyle->Red],
8 Plot[samplePeriod *continouseTimeResponse,{t,0,maxSimulationTime},
9 PlotRange->All],
10 PlotRange->All,FrameLabel->{{Style["response",10],None},
11 {Style["time (sec)",10],"impulse response"}}]
1.4
1.2
1.0
response
0.8
0.6
0.4
0.2
0.0
0 2 4 6 8 10
time (sec)
Matlab
clear all;
maxSimulationTime = 15;
samplePeriod = 0.5;
z=tf('z',samplePeriod);
tf=z/(z^2-1.4*z+0.5)
impulse(tf,0:samplePeriod:maxSimulationTime)
ctf=d2c(tf,'zoh')
hold on
impulse(ctf,0:maxSimulationTime)
title(['impulse response of discrete system with',...
' its continuous time approximation']);
xlabel('time (sec)');
ylabel('response');
40
2.5
response
1.5
0.5
-0.5
0 5 10 15
time (sec) (seconds)
1.21 Find the system type given an open loop transfer function
Problem: Find the system type for the following transfer functions
s+1
1. s 2 −s
s+1
2. s 3 −s 2
s+1
3. s5
To find the system type, the transfer function is put in the form s kM Pi (s−s i )
P
, then the system type is the
j s−s j
exponent M. Hence it can be seen that the first system above has type one since the denominator can be
written as s 1 (s − 1) and the second system has type 2 since the denominator can be written as s 2 (s − 1)
and the third system has type 5. The following computation determines the type
Mathematica
1 Clear["Global`*"];
2 p=TransferFunctionPoles[TransferFunctionModel[
Out[171]= 1
3 (s+1)/(s^2-s),s]];
4 Count[Flatten[p],0]
1 p=TransferFunctionPoles[TransferFunctionModel[
2 (s+1)/( s^3-s^2),s]];
3 Count[Flatten[p],0] Out[173]= 2
1 p=TransferFunctionPoles[
2 TransferFunctionModel[(s+1)/ s^5 ,s]];
3 Count[Flatten[p],0] Out[175]= 5
Matlab
clear all; 1 ans =
s=tf('s'); 2 1
[~,p,~]=zpkdata((s+1)/(s^2-s));
length(find(p{:}==0))
[~,p,~]=zpkdata((s+1)/(s^3-s^2)); 1 ans =
length(find(p{:}==0)) 2 2
[~,p,~]=zpkdata((s+1)/s^5); 1 ans =
length(find(p{:}==0)) 2 5
41
Mathematica
1 2 3
1 Remove["Global`*"] © ª
2 (a = {{1,2,3}, {4,5,6}, {7,8,9}}) 4 5 6 ®
®
3 // MatrixForm
« 7 8 9 ¬
3 √ 3 √
1 Eigenvalues[a] 5 + 33 , 5 − 33 , 0
2 N[%] 2 2
{16.1168, −1.11684, 0.}
√
√ 4 6+ 33
© − −15− √ 33
33+7 33
√ 1 ª®
33+7 √33
√
4 −6+ 33
®
15− √33
− −33+7 1 ®
®
√
1 Eigenvectors[a]
33 −33+7 33 ®
2 N[%] 1 −2 1 ¬
«
0.283349 0.641675 1.
© ª
−1.28335 −0.141675 1. ®
®
« 1. −2. 1. ¬
Matlab
1 v =
Matlab generated eigenvectors are such that the2 -0.2320 -0.7858 0.4082
3 -0.5253 -0.0868 -0.8165
sum of the squares of the eigenvector elements4 -0.8187 0.6123 0.4082
add to one. 5
clear all; close all; 6 e =
7 16.1168 0 0
A=[1 2 3;4 5 6;7 8 9]; 8 0 -1.1168 0
9 0 0 -0.0000
[v,e]=eig(A)
Mathematica
1 a = {{1,2,3},{4,5,6},{7,8,0}}; −x 3 + 6x 2 + 72x + 27
2 CharacteristicPolynomial[a,x]
42
Matlab
1 (-4 IdentityMatrix[n] - 3 a + !
2 MatrixPower[a,2])//MatrixForm 0 0
0 0
MATLAB has a build-in function polyvalm() to do this more easily than in Mathematica. Although the
method shown in Mathematica can easily be made into a Matlab function
Matlab
1 ans =
clear; 2 x^2 - 3 x - 4
A=[1 2;3 2]; 3 ans =
p=poly(A); 4 0 0
poly2str(p,'x') 5 0 0
polyvalm(p,A)
Mathematica
1 Remove["Global`*"]; 1 {{{-2-I Sqrt[21],-2+I Sqrt
2 sys =TransferFunctionModel[(5s)/(s^2+4s+25),s]; [21]}}}
3 poles=TransferFunctionPoles[sys]
1 Re[#]&/@poles 1 Out[42]= {{{-2,-2}}}
1 Select[%,#>=0&] 1 Out[44]= {}
Matlab
1 >>
clear all;
2 p =
s=tf('s');
3 -2.0000 + 4.5826i
sys=5*s/( s^2+4*s+25);
4 -2.0000 - 4.5826i
[z,p,k]=zpkdata(sys,'v');
p
find(real(p)>=0) 1 ans =
2 Empty matrix: 0-by-1
Mathematica
1 Out[49]= {{0,1},{-25,-4}}
1 ss=StateSpaceModel[sys];
2 a=ss[[1,1]]
1 Out[50]= {-2+I Sqrt[21],-2-I Sqrt
1 e=Eigenvalues[a]
[21]}
1 Re[#]&/@e 1 Out[51]= {-2,-2}
1 Select[%,#>=0&] 1 Out[52]= {}
Matlab
1 A =
sys=ss(sys); 2 -4.0000 -6.2500
[A,B,C,D]=ssdata(sys); 3 4.0000 0
A
1 e =
e=eig(A) 2 -2.0000 + 4.5826i
3 -2.0000 - 4.5826i
find(real(e)>=0) 1 ans =
2 Empty matrix: 0-by-1
44
0 1 0
A= 0 0 1
−1 −2 −3
The Lyapunov equation is solved using lyap() function in MATLAB and LyapunovSolve[] function in
Mathematica, and then the solution is checked to be positive definite (i.e. all its eigenvalues are positive).
We must transpose the matrix A when calling these functions, since the Lyapunov equation is defined
as AT P + PA = −Q and this is not how the software above defines them. By simply transposing the A
matrix when calling them, then the result will be correct.
Mathematica
0 1 0
1 Remove["Global`*"];
© ª
0 0 1 ®®
2 (mat = {{0,1,0},{0,0,1},{-1,-2,-3}})
« −1 −2 −3 ¬
1 p = LyapunovSolve[Transpose@mat, 2.3 2.1 0.5
2 -IdentityMatrix[Length[mat]]]; © ª
3 MatrixForm[N[p]]
2.1 4.6 1.3 ®
®
« 0.5 1.3 0.6 ¬
1 N[Eigenvalues[p]]
{6.18272, 1.1149, 0.202375}
Matlab
clear all;
1 p =
2 2.3 2.1 0.5
A=[0 1 0
3 2.1 4.6 1.3
0 0 1
4 0.5 1.3 0.6
-1 -2 -3];
p=lyap(A.',eye(length(A)))
1 e =
e=eig(p) 2 0.20238
3 1.1149
4 6.1827
Maple
1 with(LinearAlgebra): 6.18272045921436 + 0.0 i
2 A:=<<0,1,0;0,0,1;-1,-2,-3>>;
1.11490451203192 + 0.0 i
3 p,s:=LyapunovSolve(A^%T,-<<1,0,0;0,1,0;0,0,1>>);
4 Eigenvalues(p);
0.202375028753723 + 0.0 i
1.27 Given a closed loop block diagram, generate the closed loop Z
transform and check its stability
Problem: Given the following block diagram, with sampling time T = 0.1 sec, generate the closed loop
transfer function, and that poles of the closed loop transfer function are inside the unit circle
45
Gs
1. - 1. z
0.367879 - 1. z 1.
1 d = ToDiscreteTimeModel[
2 TransferFunctionModel[(s+1)/(s+5.0),s],
3 1,
4 z,
5 Method->"ZeroOrderHold"]
0.801348 - 1. z
0.00673795 - 1. z 1.
1 sys=SystemsModelSeriesConnect[d,plantd]
(0.801348 - 1. z) (1. - 1. z)
(0.00673795 - 1. z) (0.367879 - 1. z) 1.
1 loopBack=SystemsModelFeedbackConnect[sys]
plant response
0.5
0.4
0.3
y(k) 0.2
0.1
0.0
-0.1
5 10 15 20
n
1 ss=StateSpaceModel[loopBack]
0 1. 0
-0.401913 1.08798 1.
0.199717 -0.356683 0.5 1.
1 poles=TransferFunctionPoles[loopBack]
{0.633966, 0.633966}
s = tf('s');
plant = s/(s+1);
T = 1; %sampeling time;
plantd = c2d(plant,T,'zoh');
d = c2d( (s+1)/(s+5), T , 'zoh');
% obtain the open loop
sys = series(d,plantd);
% obtain the closed loop
loop = feedback(sys,1)
1 loop =
2
3 z^2 - 1.801 z + 0.8013
4 ------------------------
5 2 z^2 - 2.176 z + 0.8038
6
7 Sample time: 1 seconds
8 Discrete-time transfer function.
step(loop)
grid
47
Step Response
0.5
0.4
0.3
Amplitude
0.2
0.1
-0.1
-0.2
0 5 10 15 20 25
Time (seconds)
[z,p,k]=zpkdata(loop,'v');
fprintf('poles of closed loop discrete system as inside unit circle\n');
abs(p)
1 ans =
2 0.6340
3 0.6340
Mathematica
1 Remove["Global`*"];
2 a = {{-0.5572,-0.7814},{0.7814, 0}};
-0.5572 -0.7814 1
3 c = {{1.9691, 6.4493}}; 0.7814 0 0
4 sys=StateSpaceModel[ 1.9691 6.4493 0
5 {a,{{1},{0}},c,{{0}}}]
1 x0 = {1,0};
2 {x1,x2} = StateResponse[
3 {sys,x0},0,{t,0,20}];
4 first and second state change with time
5 Plot[{x1,x2},{t,0,20}, 1.0
6 PlotRange->All,
0.8
7 GridLines->Automatic,
8 GridLinesStyle->Dashed, 0.6
9 Frame->True,
0.4
10 ImageSize->350, y(t)
11 AspectRatio->1, 0.2
12 FrameLabel->{{"y(t)",None}, 0.0
13 {"t",
14 "first and second state\ -0.2
18 PlotStyle->{Red,Blue},
19 BaseStyle -> 12]
48
Matlab
clear;
x1 and x2 state change with time
A = [-0.5572 -0.7814;0.7814 0]; 1
B = [1;0];
0.8
C = [1.9691 6.4493];
x0 = [1 ; 0]; 0.6
0.4
sys = ss(A,B,C,[]);
x(t)
0.2
[y,t,x]=initial(sys,x0,20);
plot(t,x(:,1),'r',t,x(:,2),'b'); 0
Mathematica
1 Remove["Global`*"]; -0.5572 -0.7814 1
2 a = {{-0.5572, -0.7814}, {0.7814, 0}}; 0.7814 0 0
3 c = {{1.9691, 6.4493}}; 1.9691 6.4493 0
4 sys=StateSpaceModel[{a,{{1},{0}},c,{{0}}}]
1 x0 = {1,0}; (*initial state vector*) system response
2 y = OutputResponse[{sys,x0},0,{t,0,20}];
4
3 Plot[y,{t,0,20},
4 PlotRange->All, 3
5 GridLines->Automatic,
6 GridLinesStyle->Dashed, 2
y(t)
7 Frame->True,
1
8 ImageSize->300,
9 AspectRatio->1, 0
10 FrameLabel->{{"y(t)",None},
11 {"t","system response"}}, -1
12 RotateLabel->False,PlotStyle->Red]
0 5 10 15 20
t
Matlab
clear all;
A = [-0.5572 -0.7814; 5
y(t) plant response
0.7814 0];
B = [1;0]; 4
C = [1.9691 6.4493]; 3
x0 = [1 ; 0];
2
y(t)
sys = ss(A,B,C,[]); 1
[y,t,x]=initial(sys,x0,20); 0
plot(t,y); -1
title('y(t) plant response');
-2
xlabel('t (sec)'); 0 5 10 15 20
ylabel('y(t)'); t (sec)
grid
set(gcf,'Position',...
[10,10,320,320]);
49
Mathematica
1 Remove["Global`*"];
2 a = {{-0.5572, -0.7814}, {0.7814, 0}};
-0.5572 -0.7814 1
3 c = {{1.9691, 6.4493}}; 0.7814 0 0
4 sys=StateSpaceModel[ 1.9691 6.4493 0
5 {a,{{1},{0}},c,{{0}}}]
1 x0 = {1,0};
2 y = OutputResponse[{sys,x0}, system response to combined initial conditions and step input
3 UnitStep[t],{t,0,20}];
12
4
5 Plot[y,{t,0,20},
10
6 PlotRange->{{0,20},{0,13}},
7 GridLines->Automatic,
8
8 GridLinesStyle->Dashed,
9 Frame->True, y(t)
6
10 ImageSize->300,
11 AspectRatio->1,
4
12 FrameLabel->{{"y(t)",None},
13 {"t",
2
14 "system response to initial\
15 conditions and step input"}},
0
16 RotateLabel->False, 0 5 10 15 20
17 PlotStyle->Red] t
Matlab
initial conditions and step input response
A = [-0.5572 -0.7814;0.7814 0]; 12
B = [1;0];
C = [1.9691 6.4493]; 10
x0 = [1 ; 0];
8
sys = ss(A,B,C,[]);
y(t)
[y1,t] = initial(sys,x0,20); 6
y2 = step(sys,t);
4
plot(t,y1+y2,'r');
2
title(['initial conditions and step'...
'input response']);
xlabel('t *sec)'); ylabel('y(t)'); 0
0 5 10 15 20
grid
t *sec)
set(gcf,'Position',[10,10,320,320]);
1.31 Draw the root locus from the open loop transfer function
Problem: Given L(s), the open loop transfer function, draw the root locus. Let
s 2 + 2s + 4
L(s) =
s(s + 4)(s + 6)(s 2 + 1.4s + 1)
Root locus is the locus of the closed loop dominant pole as the gain k is varied from zero to infinity.
50
2
Mathematica
1 Remove["Global`*"]
1
2 sys = TransferFunctionModel[
3 k*(s^2+2 s+4)/
4 (s(s+4)(s+6)(s^2+1.4s+1)),s];
5 RootLocusPlot[sys,{k,0,100}, 0
6 ImageSize->300,
7 GridLines->Automatic,
8 GridLinesStyle->Dashed, -1
9 Frame->True,
10 AspectRatio -> 1]
-2
-8 -6 -4 -2 0
Root Locus
3
-3
-10 -8 -6 -4 -2 0 2
-1
Real Axis (seconds )
!
−e −2t + 2e −t −e −2t + e −t
2e −2t − 2e −t 2e −2t − e −t
Now verify the result by solving for e At using the method would one would do by hand, if a computer
was not around. There are a number of methods to do this by hand. The eigenvalue method, based on
the Cayley Hamilton theorem will be used here. Find the eigenvalues of |A − λI |
1 m = mat-lambda IdentityMatrix[Length[mat]]
!
−λ 1
−2 −λ − 3
1 Det[m]
λ2 + 3λ + 2
51
1 sol=Solve[%==0,lambda]
1 Out[15]= {{lambda->-2},{lambda->-1}}
1 eig1=lambda/.sol[[1]]
2 eig2=lambda/.sol[[2]]
1 Out[16]= -2
2 Out[17]= -1
1 (*setup the equations to find b0,b1*)
2 eq1 = Exp[eig1 t]==b0+b1 eig1;
3 eq2 = Exp[eig2 t]==b0+b1 eig2;
4 sol = First@Solve[{eq1,eq2},{b0,b1}]
b0 → e −2t 2e t − 1 , b1 → e −2t e t − 1
1 (*Now find e^At*)
2 b0=b0/.sol[[1]]
e −2t 2e t − 1
1 b1=b1/.sol[[2]]
e −2t e t − 1
1 b0 IdentityMatrix[Length[mat]]+b1 mat;
2 Simplify[%]
3 MatrixForm[%]
e −2t −1 + 2e t e −2t −1 + e t
!
1 ans =
2
3 [2/exp(t)-1/exp(2*t),1/exp(t)-1/exp(2*t)]
4 [2/exp(2*t)-2/exp(t),2/exp(2*t)-1/exp(t)]
pretty(ans)
1 +- -+
2 | 2 exp(-t)- exp(-2 t),exp(-t)-exp(-2 t) |
3 | |
4 | 2 exp(-2 t)-2 exp(-t),2 exp(-2 t)-exp(-t)|
5 +- -+
52
convert to discrete time using a sampling rate and display the root locus for the discrete system.
Mathematica
1 Remove["Global`*"];
2 sys=TransferFunctionModel[
3 k(5s+1)/(s^2+2s+3),s]; -19. k + 2. k z + 21. k z2
4 11. - 26. z + 27. z2 0.5
5 samplePeriod=0.5; (*sec*)
6 sysd=ToDiscreteTimeModel[sys,samplePeriod,z]
1 p1 = RootLocusPlot[sysd,{k,0,100},
2 ImageSize->300,
3 GridLines->Automatic, 1.0
4 GridLinesStyle->Dashed,
5 Frame->True,
6 AspectRatio->1, 0.5
7 PlotPoints->200,
8 PlotStyle->PointSize[0.01]];
9
-1.0 -0.5 0.5 1.0
10 p2=ParametricPlot[{Sin[t],Cos[t]},{t,0,2
Pi},
11 AspectRatio->1, -0.5
12 GridLines->Automatic,
13 GridLinesStyle->Dashed];
14 -1.0
15 Show[p2,p1]
Root Locus
1
0.5:/T
0.6:/T 0.4:/T
0.8 0.1
Matlab 0.7:/T 0.3:/T
0.2
0.3
0.6
0.8:/T 0.4 0.2:/T
0.2 0.9
sys = (5*s+1)/(s^2+2*s+3); 1:/T
Ts = 0.5; %sample time 0
1:/T
-0.4
rlocus(sysd) 0.8:/T 0.2:/T
grid -0.6
0.7:/T 0.3:/T
-0.8
0.6:/T 0.4:/T
0.5:/T
-1
-1 -0.5 0 0.5 1
Real Axis
1.34 Plot the response of the inverted pendulum problem using state
space
Problem: Given the inverted pendulum shown below, use state space using one input (the force on
the cart) and 2 outputs (the cart horizontal displacement, and the pendulum angle. Plot each output
separately for the same input.
53
mg
M=20 kg
m=1 kg
system input
g=9.8 m/s^2
u M L=1 meter
Mathematica
1 Remove["Global`*"];
2 a = {{0, 1, 0, 0},
3 {0, 0, ((-m)*g)/M, 0},
4 {0, 0, 0, 1},
5 {0, 0, ((M + m)*g)/(M*L), 0}};
0 1 0 0
дm
© ª
0 0 −M 0 ®
®
®
0 0 0 1 ®
д(m+M )
®
0 0 LM 0
« ¬
1 b = {{0}, {1/M}, {0}, {-(1/(M*L))}};
2 MatrixForm[b]
© 0 ª
1 ®
M ®
®
0 ®
®
1
« − LM ¬
1 c = {{1, 0, 0, 0}, {0, 0, 1, 0}};
2 MatrixForm[b]
!
1 0 0 0
0 0 1 0
1 sys=StateSpaceModel[{a,b ,c}]
0 1 0 0 0
gm 1
0 0 - 0
M M
0 0 0 1 0
g (m + M) 1
0 0 0 -
LM LM
1 0 0 0 0
0 0 1 0 0
54
It is now possible to obtain the response of the system as analytical expression or an interpolatingFunc-
tion.
It is much more efficient to obtain the response as interpolatingFunction. This requires that the time
domain be given.
Here is example of obtaining the analytical expression of the response
1 sys=sys/.{g->9.8,m->1,M->20,L->1};
2 y=Chop[OutputResponse[sys,UnitStep[t],t]]
e −6.41561t (0.0238095e 6.41561t t 2θ (t) + 0.000115693e 3.2078t θ (t) − 0.000231385e 6.41561t θ (t) + 0.000115693e 9.62341t θ (t))
, e −6.41561t (−0.00242954e 3.2078t θ (t) + 0.00485909e 6.41561t θ (t) − 0.00242954e 9.62341t θ (t))
1 Plot[y[[1]],{t,0,3},
2 PlotLabel->"y(t) response",
3 FrameLabel->{"time (sec)","y (meter)"},
4 Frame->True,
5 PlotRange->All,
6 ImageSize->300,
7 GridLines->Automatic,
8 GridLinesStyle->Dashed,
9 RotateLabel->False]
y(t) response
2.0
1.5
y (meter) 1.0
0.5
0.0
0.0 0.5 1.0 1.5 2.0 2.5 3.0
time (sec)
1 Plot[ y[[2]],{t,0,3},
2 PlotLabel->"\[Theta](t) response",
3 FrameLabel->{"time (sec)","\[Theta] (radians)"},
4 Frame->True,
5 PlotRange->All,
6 ImageSize->300,
7 GridLines->Automatic,
8 GridLinesStyle->Dashed,
9 RotateLabel->False]
θ(t) response
0
-10
θ (radians)
-20
-30
Matlab
55
A=[0 1 0 0;
0 0 -m*g/M 0;
0 0 0 1;
0 0 (M+m)*g/(M*L) 0
];
B=[0 1/M 0 -1/(M*L)]';
C=[1 0 0 0;
0 0 1 0];
D=[0];
sys=ss(A,B,C(1,:),0);
step(sys,3);
grid on;
set(gcf,'Position',[10,10,320,320]);
title('y(t) due to step input');
1.5
Amplitude
0.5
0
0 1 2 3
Time (seconds)
figure;
sys=ss(A,B,C(2,:),0);
step(sys,3);
title('\theta(t) due to step input');
grid on;
set(gcf,'Position',[10,10,320,320]);
-10
Amplitude
-20
-30
-40
0 1 2 3
Time (seconds)
1.35 How to build and connect a closed loop control systems and
show the response?
1.35.1 example 1, single input, single output closed loop
Given the following simple closed loop system, show the step response. Let mass M = 1kg, damping
coefficient c = 1newton-seconds per meter and let the stiffness coefficient be k = 20newton per meter.
56
es Fs
Yr s +
- J s Gs
Ys
Fs
1
Ys
ms 2 csk
controller plant
Using propertional controller J (s) = kp where kp = 400. First connect the system and then show y(t)
for 5 seconds when the reference yr (t) is a unit step function.
Mathematica
1 m = 1; c = 1; k = 20; kp = 400;
2 plant = TransferFunctionModel[1/(m s^2 + c s + k), s];
3 controller = TransferFunctionModel[kp, s];
4 sys = SystemsModelSeriesConnect[plant, controller];
5 sys = SystemsModelFeedbackConnect[sys];
6 o = OutputResponse[sys, UnitStep[t], t];
7 Plot[o, {t, 0, 10}, Frame -> True, PlotRange -> All,
8 FrameLabel -> {{"y(t)", None},
9 {"t (sec)", "response of closed loop"}},
10 BaseStyle -> 14]
1.5
1.0
y(t)
0.5
0.0
0 2 4 6 8 10
t (sec)
Matlab
close all;
m = 1; c = 1; k = 20;
s = tf('s');
plant = 1/(m*s^2+c*s+k);
controller = 400;
sys = series(controller,plant);
sys = feedback(sys,1);
[Y,T] = step(sys,0:.01:10);
plot(T,Y);
xlabel('time (sec)');
ylabel('y(t)');
title('response of closed loop');
1.8
1.6
1.4
1.2
y(t)
1
0.8
0.6
0.4
0.2
0
0 2 4 6 8 10
time (sec)
ωn2
G (s) =
s 2 + 2ζ ωn s + ωn2
Change ζ and plot the step response for each to see the effect of changing ζ (the damping coefficient).
It is easy to solve this using the step command in Matlab, and similarly in Mathematica and Maple. But
here it is solved directly from the differential equation.
The transfer function is written as
Y (s) ωn2
= 2
U (s) s + 2ζ ωn s + ωn2
Where Y (s) and U (s) are the Laplace transforms of the output and input respectively.
Hence the differential equation, assuming zero initial conditions becomes
To solve the above in Matlab using ode45, the differential equation is converted to 2 first order ODE’s
as was done before resulting in
" # " # " # " #
x 10 0 1 x1 0
= + 2 u (t)
x2 0 −ωn −2ζ ωn x 2
2 ωn
Now ODE45 can be used. In Mathematica the differential equation is solved directly using DSolve and
no conversion is needed.
58
Mathematica
1 solve[z_]:=Module[{sol,eq,y,t,w=1},
2 eq=y''[t]+2 z w y'[t]+
3 w^2 y[t]==w^2 UnitStep[t];
4 sol=First@NDSolve[{
5 eq,y[0]==0,y'[0]==0},y[t],{t,0,15}
6 ];
7
8 Plot[y[t]/.sol,{t,0,15},
9 PlotPoints->30,
10 PlotRange->All,
11 Frame->True,
12 FrameLabel->{{"y(t)",None},{"time (sec)",
13 "step response,Subscript[\[Omega], n]=1"
14 <>", different \[Xi]"}},
15 ImageSize->400,
16 PlotStyle->RGBColor[2z,z/2,z/3],
17 LabelStyle->Directive[14]]
18 ];
19
20 zeta = Range[0,1.4,.2];
21 r = Map[solve,zeta];
22 Show[r,GridLines->Automatic,
23 GridLinesStyle->Dashed]
1.5
y(t)
1.0
0.5
0.0
0 2 4 6 8 10 12 14
time (sec)
59
Matlab
function e73
close all; clear all;
t = 0:0.1:15;
ic = [0 0]';
zeta = 0:.2:1.4;
omega = 1;
sol = zeros(length(t),length(zeta));
for i = 1:length(zeta)
[t,y] = ode45(@f,t,ic,[],...
zeta(i),omega);
sol(:,i) = y(:,1);
end
plot(t,sol);
legend('0','.2','.4',...
'.6','.8','1','1.2','1.4');
title('step response, $\omega=1$ rad/sec,'...
'different $\zeta$ values',...
'interpreter','latex',...
'fontsize',12);
ylabel('y(t)');
xlabel('time sec');
grid on;
set(gcf,'Position',[10,10,600,600]);
function xdot=f(t,x,zeta,omega)
xdot=[x(2)
-omega^2*x(1)-2*zeta*omega*x(2)]+...
[0
omega^2];
1.2
y(t)
0.8
0.6
0.4
0.2
0
0 5 10 15
time sec
Mathematica
1 Rd[r_,z_]:=1/Sqrt[(1-r^2)^2+(2 z r)^2];
2
3 phase[r_,z_]:=Module[{t},
4 t=ArcTan[(2z r)/(1-r^2)];
5 If[t<0,t=t+Pi];
6 180/Pi t
7 ];
8 Dynamics Response vs. Frequency ratio for different ξ
9 plotOneZeta[z_,f_] := Module[{r,p1,p2}, 6
10 p1 = Plot[f[r,z],{r,0,3},PlotRange->All, 5
11 PlotStyle->Blue];
4
12 0.1
13 p2 = Graphics[Text[z,{1.1,1.1f[1.1,z]}]];
Rd
3
14 Show[{p1,p2}] 2
15 ]; 0.3
1 0.5
16 0.7
0.9
1.1
17 p1 = Graphics[{Red,Line[{{1,0},{1,6}}]}]; 0
r=
19 ωn
20 Show[p2,p1,
21 FrameLabel->{{"Subscript[R, d]",None},
22 {"r= \[Omega]/Subscript[\[Omega], n]",
23 "Dynamics Response vs. Frequency\
24 ratio for different \[Xi]"}},
25 Frame->True,
26 GridLines->Automatic,GridLinesStyle->Dashed,
27 ImageSize -> 300,AspectRatio -> 1]
1 p = Map[plotOneZeta[#,phase]&,Range[.1,1.2,.2]]; 150 0.1
2 Show[p,FrameLabel->{{"Phase in degrees",None},
Phase in degrees
0.3
3 {"r= \[Omega]/Subscript[\[Omega], n]", 100
0.5
0.7
0.9
1.1
1.38 How to find closed loop step response to a plant with a PID
controller?
Find and plot the step response of the plant 1
s 2 +2s+1
connected to a PID controller with P = 10, I =
3.7, D = 0.7. Use negative closed loopback.
Mathematica
1 plant= TransferFunctionModel[1/(s^2 + 2*s + 1),s];
2 kip = 10; ki = 3.7; kid = 0.7;
3 pid = TransferFunctionModel[
4 (kip*s + ki + kid*s^2)/s, s];
5 openLoop = SystemsModelSeriesConnect[ Step response
8 openLoop]; 0.8
input = UnitStep[t];
y(t)
9 0.6
0.2
11
0.0
12 Plot[{input, output}, {t, 0, 5}, PlotRange -> 0 1 2 3 4 5
Matlab
close all; clear;
s = tf('s'); 1.2
step response
BLKSYS = append(thePID,plant);
y(t)
0.6
Q = [2 1; 1 -2];
0.4
closedLoop = connect(BLKSYS,Q,1,2);
[y,t] = step(closedLoop); 0.2
plot(t(1:140),y(1:140)); 0
title('step response');
grid
1.39.1 Example 1
s
Given G(s) = 1−0.2s generate Nyquist plot.
Mathematica
1 NyquistPlot[s/(1 - 0.2 s),
-5 -4 -3 -2 -1
2 NyquistGridLines -> Automatic]
-1
-2
Nyquist Diagram
2.5
2 dB 0 dB -2 dB
2
1.5
4 dB -4 dB
Matlab 1
6 dB -6 dB
Imaginary Axis
0.5 10 dB -10 dB
clear all; close all; 0
nyquist([1 0],[-0.2 1]) -0.5
grid -1
-1.5
-2
-2.5
-5 -4 -3 -2 -1 0 1
Real Axis
1.39.2 Example 2
5(1−0.5s)
Given G(s) = s(1+0.1s)(1−0.25s) generate Nyquist plot.
62
Mathematica
1 NyquistPlot[5(1-0.5 s)/
-1
2 (s(1 + 0.1 s)(1 - 0.25 s))]
-2
Matlab 1
2 2.5 s - 5
clear all; close all; 3 ------------------------
s=tf('s'); 4 0.025 s^3 + 0.15 s^2 - s
sys=5*(1-0.5*s)/... 5
(s*(1+0.1*s)*(1-0.25*s)) 6 Continuous-time transfer function.
Nyquist Diagram
40
30
20
Imaginary Axis
10
nyquist(sys) 0
-10
-20
-30
-40
-1.8 -1.6 -1.4 -1.2 -1 -0.8 -0.6 -0.4 -0.2 0
Real Axis
However, there is a better function to do this called nyquist1.m which I downloaded and tried. Here is
its results
Nyquist Diagram
0.15
0.1
0.05
Imaginary Axis
-0.05
-0.1
-0.15
-1 -0.8 -0.6 -0.4 -0.2 0 0.2
Real Axis
Chapter 2
Mathematica and Matlab allow one to do pretty much the same operations in the area of linear algebra
and matrix manipulation. Two things to keep in mind is that Mathematica uses a more general way to
store data.
Mathematica uses ragged arrays or a list of lists. This means rows can have different sizes. (these are
the lists inside the list). So a Mathematica matrix is stored in a list of lists. This is similar in a way to
Matlab cell data structure, since each raw can have different length. In a standard matrix each row
must have the same length.
In Matlab one can also have ragged arrays, these are called cells. In Mathematica, there is one data
structure for both.
Another thing to keep in mind is that Matlab, due to its Fortran background is column major when
it comes to operations on matrices. This simple example illustrate this difference. Suppose we have a
matrix A of 3 rows, and want to find the location where A(i, j) = 2 where i is the row number and j is
the column number. Given this matrix
1 2 3 4
A = 2 3 1 5 ®®
© ª
« 5 6 7 2 ¬
Then the result of using the find() command in Matlab is
A=[1 2 3 4;
2 3 1 5;
5 6 7 2];
[I,J]=find(A==2)
1 I =
2 2
3 1
4 3
5 J =
6 1
7 2
8 4
9 s*(4 + s)*(6 + s)}, s]
The Matlab result gives the order of the rows it found the element at based on searching column wise
since it lists the second row first in its result. Compare this to Mathematica Position[] command
1 mat = {{1, 2, 3, 4},
2 {2, 3, 1, 5},
3 {5, 6, 7, 2}}
4 Position[mat, 2]
which gives
1 {{1,2},
2 {2,1},
3 {3,4}}
63
64
In Mathematica the dot ”.” is used for Matrix multiplication. In Matlab the ”*” is used. In Fortran,
MATMUL is used.
Mathematica
1 a={{1,2,3},{4,5,6},{7,8,8}};
1 Out[7]= {14,32,47}
2 x={1,2,3};
3
4 a.x
Matlab
1 14
A=[1 2 3;4 5 6;7 8 9]; 2 32
x=[1; 2; 3]; 3 50
c=A*x
Ada
1 with Ada.Text_Io; use Ada.Text_Io;
2 with Ada.Numerics.Real_Arrays;
3 use Ada.Numerics.Real_Arrays;
4
5 procedure t1 is
6 A : constant real_matrix :=
7 (( 1.0, 2.0, 3.0),
8 ( 4.0, 5.0, 6.0),
9 ( 7.0, 8.0, 9.0));
10
11 V : constant real_vector := (1.0,2.0,3.0);
12 procedure Put (X : real_vector) is
13 begin
14 FOR e of X LOOP
15 put_line(float'image(e));
16 END LOOP;
17 end put;
18 begin
19 put(A*v);
20 end t1;
Fortran
1 PROGRAM main
2 IMPLICIT NONE
3 integer, parameter :: dp = kind(1.D0)
4 integer, parameter :: N=3
5 real(kind=dp), parameter, DIMENSION(N, N) :: &
6 A=DBLE(reshape([ 1.0, 2.0, 3.0,&
7 4.0, 5.0, 6.0,&
8 7.0, 8.0, 9.0], shape(A), &
9 order=[2,1]))
10
11 real(kind=dp), parameter, DIMENSION(N, 1) :: &
12 x=DBLE(reshape([1.0, 2.0, 3.0], shape(x)))
13
14 real(kind=dp), DIMENSION(N, 1) :: result
15 integer, DIMENSION(2) :: siz
16
17 result = MATMUL(A,x)
18 siz = SHAPE(result)
19 Write(*,*) result
20
21 print *, "number of rows = ",siz(1)
22 print *, "number of columns = ",siz(2)
23
24 end program
Maple
14
1 A:=Matrix([[1,2,3],[4,5,6],[7,8,9]]):
x:=Vector([1,2,3]): #default is column vector 32
2
3 c:=A.x;
50
Python
1 import numpy as np 1 array([[14],
2 mat=np.array([[1,2,3],[4,5,6],[7,8,8]]) 2 [32],
3 b=np.array([1,2,3]) 3 [47]])
4 b.shape=(3,1)
5 r=dot(mat,b)
Mathematica
1 vec={1,2,3,4}; 1 Out[11]= {1,2,99,3,4}
2 vec=Insert[vec,99,3];
3 vec
Matlab
1 A =
A=[1 2 3 4]; 2 1 2 99 3 4
A=[ A(1:2) 99 A(3:end) ]
66
Fortran
1 program f
1 >gfortran -std=f2008 t2.f90
2 implicit none
2 >./a.out
3 REAL(4), ALLOCATABLE :: A(:)
3 1.0000000 2.0000000 99.000000
4 A=[1,2,3,4];
4 3.0000000 4.0000000
5 A=[A(1:2), 99.0, A(3:)]
6 Print *,A
7 end program f
Maple
1 v:=Vector[row]([1,2,3,4]);
2 v:=Vector[row]([v[1..2],99,v[3..]]);
1 v :=[ 1 2 99 3 4]
Using <> notation
1 v:=<1|2|3|4>;
2 v:=<v(1..2)|99|v(3..)>;
Python
Python uses zero index.
1 import numpy as np 1 Out[86]: array([ 1, 2, 99, 3,
2 b=np.array([1,2,3,4]) 4])
3 b=numpy.insert(b,2,99)
4 b
Mathematica
1 {{1,2,3},
1 mat={{1,2,3}, 2 {90,91,92},
2 {4,5,6}, 3 {4,5,6},
3 {7,8,9}} 4 {7,8,9}}
4 mat = Insert[mat,{90,91,92},2]
Matlab
1 1 2 3
A=[1 2 3; 2 90 91 92
4 5 6; 3 4 5 6
7 8 9] 4 7 8 9
A=[ A(1,:); [90 91 92]; A(2:end,:) ]
67
Maple
Python 1
array([[ 1, 2, 3],
1 import numpy as np 2 [90, 91, 92],
2 mat=np.array([[1,2,3], 3 [ 4, 5, 6],
3 [4,5,6], 4 [ 7, 8, 9]])
4 [7,8,9]])
5 mat=numpy.insert(mat,1,[90,91,92],0)
Fortran
1 program t3
2 implicit none
Compile and run
3 integer i,nRow,nCol
1 >gfortran -std=f2008
4 integer(4), ALLOCATABLE ::A(:,:)
t3.f90
5
2 >./a.out
6 A = reshape ([1,2,3, &
3 before
7 4,5,6, &
4 1 2
8 7,8,9], [3,3], order=[2,1])
3
9 nRow=size(A,1)
5 4 5
10 nCol=size(A,2)
6
11
6 7 8
12 print *, 'before'
9
13 do i=LBOUND(A, 1),UBOUND(A, 1)
7 after
14 print *,A(i,:)
8 1 2
15 end do
3
16
9 90 91
17 A = reshape ([A(1,:), &
92
18 90,91,92, &
10 4 7
19 A(2:,:)], [nRow+1,nCol] , order=[2,1])
5
20 print *, 'after'
11 8 6
21 do i=LBOUND(A, 1),UBOUND(A, 1)
9
22 print *,A(i,:)
23 end do
24
25 end program t3
Mathematica
1 mat = {{1, 2, 3},
2 {4, 5, 6}, 1 {{1,90,2,3},
3 {7, 8, 9}}; 2 {4,91,5,6},
4 3 {7,92,8,9}}
5 mat = Insert[Transpose[mat],
6 {90, 91, 92}, 2];
7 mat = Transpose[mat]
68
Matlab
A=[1 2 3; 1 1 90 2 3
4 5 6; 2 4 91 5 6
7 8 9]; 3 7 92 8 9
A=[A(:,1) [90 91 92]' A(:,2:end) ]
Fortran
1 program t4
2 implicit none
3 integer(4) ::i
4 integer(4), ALLOCATABLE ::A(:,:)
1 >gfortran t4.f90
5
2 >./a.out
6 A = reshape ([1,2,3, &
3 1 90 2
7 4,5,6, &
3
8 7,8,9], [3,3], order=[2,1])
4 4 91 5
9
6
10 A = reshape ([A(:,1), [90,91,92] ,
5 7 92 8
11 A(:,2:)] , [3,4])
9
12
13 do i=LBOUND(A, 1),UBOUND(A, 1)
14 print *,A(i,:)
15 end do
16
17 end program t4
Maple
1 A:=< <1|2|3>,<4|5|6>,<7|8|9>>;
2 A:=< A(..,1)|<90,91,92>|A(..,2..)>;
1 [ 1 90 2 3
2 4 91 5 6
Using Matrix/Vector 3 7 92 8 9]
1 A:=Matrix([ [1,2,3],[4,5,6],[7,8,9]]);
2 A:=Matrix([ [A[..,1],
3 Vector[column]([91,92,92]),
4 A[..,2..] ]]);
Python
1 import numpy as np
2 mat=np.array([[1,2,3], 1 array([[ 1, 90, 2, 3],
3 [4,5,6], 2 [ 4, 91, 5, 6],
4 [7,8,9]]) 3 [ 7, 92, 8, 9]])
5
6 mat=numpy.insert(mat,1,[90,91,92],1)
69
Mathematica
1 v1 = {1, 2, 3}; v2 = {4, 5, 6};
2 v3 = {7, 8, 9}; v4 = {10, 11, 12}; © 1 4 ª
3 m = ArrayFlatten[
2 5 ®®
4 {{Transpose@{v1}, Transpose@{v2}}, ®
5 {Transpose@{v3}, Transpose@{v4}}}
3 6 ®®
6 ] 7 10 ®®
®
8 11 ®®
« 9 12 ¬
1 m =
Matlab 2 1 4
3 2 5
v1=[1,2,3]'; v2=[4,5,6]'; 4 3 6
v3=[7,8,9]'; v4=[10,11,12]'; 5 7 10
m=[v1 v2;v3 v4] 6 8 11
7 9 12
Maple
1 restart; 1 4
2 v1:=<1,2,3>; #column by default
3 v2:=<4,5,6>;
2 5
4 v3:=<7,8,9>;
5 v4:=<10,11,12>;
3 6
6 m:=< <v1|v2>,
7 <v3|v4>>;
7 10
8 11
9 12
70
Python
1 import numpy as np
2 v1=np.array((1,2,3));
3 v2=np.array((4,5,6));
4 v3=np.array((7,8,9));
5 v4=np.array((10,11,12));
6
7 r1 =np.hstack([(v1,v2)]).T
8 r2 =np.hstack([(v3,v4)]).T 1 Out[211]:
9 mat = np.vstack((r1,r2))
2
array([[ 1, 4],
3 [ 2, 5],
4 [ 3, 6],
Another way 5 [ 7, 10],
1 v1=np.array([(1,2,3)]).T 6 [ 8, 11],
2 v2=np.array([(4,5,6)]).T 7 [ 9, 12]])
3 v3=np.array([(7,8,9)]).T
4 v4=np.array([(10,11,12)]).T
5
6 mat =np.hstack((
7 np.vstack((v1,v3)),
8 np.vstack((v2,v4)))
9 )
Fortran
1 PROGRAM main
2 IMPLICIT none
3 INTEGER :: i
4 INTEGER , DIMENSION(3) :: v1,v2,v3,v4
5 INTEGER , DIMENSION(6,2) :: m
6 v1 = [1,2,3]; v2=[4,5,6];
7 v3=[7,8,9]; v4=[10,11,12];
8
9 m(1:3,1) = v1; m(1:3,2)=v2;
10 m(4:,1)=v3; m(4:,2)=v4;
11
12 DO i=1,size(m,1)
13 PRINT *, m(i,:) 1 >gfortran -Wall foo.
14 END DO f90
15 2 >./a.out
16 END PROGRAM main 3 1 4
4 2 5
5 3 6
6 7 10
Using the RESHAPE command
7 8 11
1 PROGRAM main 8 9 12
2 IMPLICIT none
3 INTEGER :: i
4 INTEGER , DIMENSION(3) :: v1,v2,v3,v4
5 INTEGER , DIMENSION(6,2) :: m
6 v1 = [1,2,3]; v2=[4,5,6];
7 v3=[7,8,9]; v4=[10,11,12];
8
9 m = RESHAPE([v1,v3,v2,v4], SHAPE(m), ORDER=[1,2])
10
11 DO i=1,size(m,1)
12 PRINT *, m(i,:)
13 END DO
14
15 END PROGRAM main
71
Maple
1 restart;
2 v1:=<1,2,3>; #column by default
3 v2:=<<4|5>,
4 <6|7>,
5 <8|9>>;
6 v3:=<10,11,12>;
7 v4:=<13,14,15>;
8 v5:=<16,17,18>;
9 m:=< <v1|v2>,
10 <v3|v4|v5>>;
Matlab
v1=[1,2,3]';
v2=[4,5;6,7;8,9];
v3=[10,11,12]';
v4=[13,14,15]';
v5=[16,17,18]';
Fortran
1 PROGRAM main
2 IMPLICIT none
3 INTEGER :: i
4 INTEGER , DIMENSION(3) :: v1,v3,v4,v5
5 INTEGER , DIMENSION(3,2) :: v2 = RESHAPE([4,6,8,5,7,9],SHAPE(v2),ORDER
=[1,2])
6 INTEGER , DIMENSION(6,3) :: m
7 v1 = [1,2,3]; v3=[10,11,12];
8 v4 =[13,14,15]; v5=[16,17,18];
9 m = RESHAPE([v1,v3,v2(:,1),v4,v2(:,2),v5], SHAPE(m), ORDER=[1,2])
10
11 DO i=1,size(m,1)
12 PRINT *, m(i,:)
13 END DO
14
15 END PROGRAM main
1 >gfortran -Wall foo.f90
2 >./a.out
3 1 4 5
4 2 6 7
5 3 8 9
6 10 13 16
7 11 14 17
8 12 15 18
1 {{-0.226424,1.19553,0.601433,1.28032},
1 (*from normal, zero mean, 1 std*)
2 2 {1.66596,0.176225,-0.619644,0.371884},
3 mat=RandomReal[
4 NormalDistribution[0,1],{3,4}] 3 {0.895414,-0.394081,0.153507,-1.74643}}
1 mat =
2 0.6787 0.3922 0.7060
Matlab 0.0462
3 0.7577 0.6555 0.0318
mat=rand(3,4) 0.0971
4 0.7431 0.1712 0.2769
0.8235
1 mat =
2 0.3252 -1.7115 0.3192
-0.0301
mat=randn(3,4) 3 -0.7549 -0.1022 0.3129
-0.1649
4 1.3703 -0.2414 -0.8649
0.6277
73
1 [[0.93,0.66,0.92,0.80],
Maple
2
1 A:=ArrayTools:-RandomArray(3,4, [0.85,0.96,0.42,0.49],
2 distribution = uniform);
3 3
4 #just to round to 2 decimal points [0.04,0.79,0.14,0.96]
5 parse~(sprintf~("%0.2f",A));
4 ]
Or
1 interface(displayprecision=5):
2 A:=ArrayTools:-RandomArray(3,4,
3 distribution = uniform);
Fortran
1 program t5
2 implicit none
3 INTEGER(4) ::i=0,j
4 REAL ::A(3,3),mean,sd,pi,temp
5
6 CALL RANDOM_SEED(i)
7 CALL RANDOM_NUMBER(A)
8
9 print *, 'from uniform distribution'
10 do i=LBOUND(A, 1),UBOUND(A, 1)
11 print *,A(i,:)
12 end do
13
14 !this block below uses the logic as explained in
15 !http://rosettacode.org/wiki/Random_numbers#Fortran
16 !
17 mean=0.0
18 sd=1.0
19 pi = 4.0*ATAN(1.0)
20
21 ! Now convert to normal distribution
22 DO i = 1, SIZE(A,1)-1, 2
23 DO j = 1, SIZE(A,2)-1, 2
24 temp = sd * SQRT(-2.0*LOG(A(i,j))) * COS(2*pi*A(i+1,j+1)) + mean
25 A(i+1,j+1) = sd* SQRT(-2.0*LOG(A(i,j)))*SIN(2*pi*A(i+1,j+1))+mean
26 A(i,j) = temp
27 END DO
28 END DO
29
30 print *, 'from normal distribution'
31 do i=LBOUND(A, 1),UBOUND(A, 1)
32 print *,A(i,:)
33 end do
34
35 end program t5
1 >gfortran -Wall -std=f2008 t5.f90
2 >./a.out
3 from uniform distribution
4 0.99755955 0.74792767 7.37542510E-02
5 0.56682467 0.36739087 5.35517931E-03
6 0.96591532 0.48063689 0.34708124
7
8 from normal distribution
9 -4.70122509E-02 0.74792767 7.37542510E-02
10 0.56682467 5.17370142E-02 5.35517931E-03
11 0.96591532 0.48063689 0.34708124
74
Did not find a build-in support for random numbers from normal distribution, need to look more.
1 A =
Matlab 2 0 0 0 0
3 0 0 0 0
A=zeros(3,4)
4 0 0 0 0
Maple 0 0 0 0
LinearAlgebra:-ZeroMatrix(3,4); 0 0 0 0
1
0 0 0 0
Fortran
1 program f
2 implicit none
3 integer i
4 integer, parameter :: dp = kind(1.D0)
5 real(kind=dp), DIMENSION(3, 4):: A
6
7 A=0
8
9 do i=LBOUND(A, 1),UBOUND(A, 1)
10 print *,A(i,:)
11 end do
12 end program f
1 tmp>gfortran -std=f2008 f.f90
2 tmp>./a.out
3 0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
4 0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
5 0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
75
Ada
1 with Ada.Text_IO; use Ada.
Text_IO;
2 with Ada.Numerics.Real_Arrays; use Ada.
Numerics.Real_Arrays;
3
4 procedure t1 is
5 A : Real_Matrix (1 .. 3, 1 .. 4) := (
others => (others => 0.0));
6 begin
7 null;
8 end t1;
Mathematica
1 {{3,6,9},
1 mat = {{1, 2, 3},
2 {2,5,8},
2 {4, 5, 6},
3 {1,4,7}}
3 {7, 8, 9}};
4 mat = Reverse[Transpose[mat]]
Matlab
1 3 6 9
A=[1 2 3;
2 2 5 8
4 5 6;
3 1 4 7
7 8 9]
A=rot90(A)
Maple
1 A:=< <1|2|3>, 1 [[3,2,1],
2 <4|5|6>, 2 [6,5,4],
3 <7|8|9>>; 3 [9,8,7]]
4
5 A:=ArrayTools:-FlipDimension(A,2);
1 [[3,6,9],
1 A:=A^%T; 2 [2,5,8],
3 [1,4,7]]
76
Fortran
1 2 0 0 0
Matlab 2 0 4 0 0
3 0 0 6 0
diag(2*(1:4))
4 0 0 0 8
Maple
1 [[2,0,0,0],
1 A:=LinearAlgebra:-DiagonalMatrix([2,4,6,8]); 2 [0,4,0,0],
2 #or 3 [0,0,6,0],
3 A:=LinearAlgebra:-DiagonalMatrix( 4 [0,0,0,8]]
4 [seq(i,i=2..8,2)]);
77
Mathematica
1 mat = {{1, 2, 3},
1 Out[45]= 15
2 {4, 5, 6},
3 {7, 8, 9}}
4 Tr[mat]
Matlab
A=[1 2 3; 1 ans =
4 5 6; 2 15
7 8 9]
sum(diag(A))
Maple
1 A:=< <1|2|3>,
2 <4|5|6>,
3 <7|8|9>>;
4
5 d:=MTM:-diag(A);
6 add(x,x in d);
15
Another ways
1 LinearAlgebra:-Diagonal(A);
2 Student:-LinearAlgebra:-Diagonal(A);
Mathematica
1 mat= {{1, 2, 3},
2 {4, 5, 6},
Out[49]= 45
3 {7, 8, 9}}
4 Apply[Times,Diagonal[mat]]
Matlab
A=[1 2 3;
4 5 6; ans = 45
7 8 9]
prod(diag(A))
Maple
1 A:=< <1|2|3>,
2 <4|5|6>,
3 <7|8|9>>; 45
4 d:=MTM:-diag(A);
5 mul(x,x in d);
78
Mathematica
1 diagonalQ[m_List]/;ArrayDepth[m]===2&&Equal@@Dimensions[m
]:=
2 And@@Flatten[MapIndexed[#1===0||Equal@@#2&,m,{2}]];
3
4 diagonalQ[m_]:=Return[False];
1 Out[59]=
5 matA = {{1, 2},
False
6 {2, 4}};
2 Out[60]=
7
True
8 matB = {{1, 0},
3 Out[61]=
9 {0, 2}};
False
10
11 matC = {{1, 0, 2},
12 {0, 2, 4}};
13
14 diagonalQ[matA]
15 diagonalQ[matB]
16 diagonalQ[matC]
Maple
1 A:=Matrix([[1,0],[0,2]]);
true
2 Student:-NumericalAnalysis:-IsMatrixShape(A,'diagonal');
2.13 Find all positions of elements in a Matrix that are larger than
some value
The problem is to find locations or positions of all elements in a matrix that are larger or equal than
some numerical value such as 2 in this example.
Mathematica
1 mat = {{1, 2,3},
2 {2,1,-5}, 1 {{1,2},{1,3},{2,1},{3,1}}
3 {6,0,0}};
4
5 p = Position[mat, _?(#1 >= 2&)]
1 I =
2 2
Matlab 3 3
4 1
A=[1 2 3; 5 1
2 1 -5; 6 J =
6 0 0] 7 1
[I,J]=find(A>=2) 8 1
9 2
10 3
79
Maple
A:=< <1|2|3>,
1 [2, 1], [3, 1], [1,
<2|1|-5>,
2], [1, 3]
<6|0|0>>;
seq(seq(if(A[i,j]>=2,[i,j],NULL),i=1..3),j=1..3);
Generate a new matrix of size 2 by 3 where each element of the new matrix is the above matrix. Hence
the new matrix will look like
1 1 2 1 2 1 2
2 3 4 3 4 3 4
3 1 2 1 2 1 2
4 3 4 3 4 3 4
Mathematica
1 {{1,2,1,2,1,2},
1 mat = {{1,2},
2 {3,4,3,4,3,4},
2 {3,4}}
3 {1,2,1,2,1,2},
3
4 {3,4,3,4,3,4}}
4 r = Table[mat,{2},{3}];
5 ArrayFlatten[r]
1 ans =
2 1 2 1 2 1
2
Matlab 3 3 4 3 4 3
4
A=[1 2;3 4]
4 1 2 1 2 1
repmat(A,2,3)
2
5 3 4 3 4 3
4
Another way is to use kron() in matlab, and KroneckerProduct in Mathematica and LinearAlgebra[Kro-
neckerProduct] in Maple, which I think is a better way. As follows
Mathematica
1 mat = {{1,2},
2 {3,4}} 1 {{1,2,1,2,1,2},
3 2 {3,4,3,4,3,4},
4 kernel = Table[1, {2}, {3}]; 3 {1,2,1,2,1,2},
5 (* {{1, 1, 1}, 4 {3,4,3,4,3,4}}
6 {1, 1, 1}} *)
7
8 KroneckerProduct[kernel, mat]
80
Matlab 1 ans =
2 1 2 1 2 1
A=[1 2;3 4]
2
kernel=ones(2,3)
3 3 4 3 4 3
4
kernel =
4 1 2 1 2 1
1 1 1
2
1 1 1
5 3 4 3 4 3
4
kron(kernel,A)
Maple
1 A:=< <1|2>,
1 [[1,2,1,2,1,2],
2 <3|4>>;
2 [3,4,3,4,3,4],
3
3 [1,2,1,2,1,2],
4 kern:=<<1|1|1>,
4 [3,4,3,4,3,4]]
5 <1|1|1>>;
6
7 LinearAlgebra[KroneckerProduct](kern,A);
Mathematica
1 Out[142]= {{2,2},{3,3}}
1 mat ={{2,4,-3},
2 {7,9,5},
3 {0,5.4,9}}
4
5 m = Max[mat]; (*this gives values *)
6 Position[mat,m](*this find locations*)
Matlab
1 r =
h = [2, 4, -3;
2 2
7, 9, 5;
3 3
0, 5.4, 9]
4 c =
5 2
m = max(h(:));
6 3
[r,c]=find(h==m)
Maple
How to change it so that the second column becomes the first, and the first becomes the second? so
that the result become
1 2 1
2 4 3
3 6 5
Mathematica
1 Out[29]= {{2, 1},
1 a={{1,2},
2 {4, 3},
2 {3,4},
3 {6, 5}}
3 {5,6}}
4 Reverse[a,2]
Matlab
1 2 1
a =[1 2;
2 4 3
3 4;
3 6 5
5 6]
[a(:,2) a(:,1)]
Maple
1 [[2,1],
1 A:=<<1|2>,
2 [4,3],
2 <3|4>,
3 [6,5]]
3 <5|6>>;
4 A:=<A[..,2]|A[..,1]>;
82
Mathematica
In Mathematica, to join 2 matrices side-by-side, use Join1 Out[146]= {{8,5, 1},
with '2' as the third argument. To join them one on top2 {8,10,8},
3 {6,0, 8}}
of the other, use '1' as the third argument
1 a = RandomInteger[10, {3, 3}]
1 {{9, 0,1},
1 b = RandomInteger[10, {3, 3}] 2 {10,2,7},
3 {8, 0,8}}
1 {{8,5, 1, 9,0,1},
1 (*join side-by-side as in Matlab [A B]*)
2 {8,10,8,10,2,7},
2 Join[a, b, 2]
3 {6,0, 8, 8,0,8}}
1 {{8, 5 , 1},
2 {8, 10, 8},
1 (*join vertically as in Matlab [A;B]*) 3 {6, 0 , 8},
2 Join[a, b, 1] 4 {9, 0 , 1},
5 {10,2 , 7},
6 {8, 0 , 8}}
1 0.5472 0.2575 0.8143 0.3500 0.6160
Matlab 0.8308
2 0.1386 0.8407 0.2435 0.1966 0.4733
A=rand(3,3)
0.5853
B=rand(3,3)
3 0.1493 0.2543 0.9293 0.2511 0.3517
[A B]
0.5497
1 0.5472 0.2575 0.8143
2 0.1386 0.8407 0.2435
[A;B] 3 0.1493 0.2543 0.9293
4 0.3500 0.6160 0.8308
5 0.1966 0.4733 0.5853
6 0.2511 0.3517 0.5497
Maple
1 A:=ArrayTools:-RandomArray(3,3,
distribution = uniform);
2
3 B:=ArrayTools:-RandomArray(3,3,
distribution = uniform);
4 <A|B>; #side by side
5
6 <A,B>; #on top of each others
7 2 3 0 0
8 4 9 5 0
9 2 2 3 4
10
11 To give:
12
13 1 2 4 2
14 2 3 9 2
15 4 9 5 3
16 2 2 3 4
Many answers were given, below is my answer, and I also show how to do it in Matlab
Mathematica
1 {{1, 2, 4, 2},
1 a = {{1, 0, 0, 0},
2 {2, 3, 9, 2},
2 {2, 3, 0, 0},
3 {4, 9, 5, 3},
3 {4, 9, 5, 0},
4 {2, 2, 3, 4}
4 {2, 2, 3, 4}};
5 }
5
6 Transpose[LowerTriangularize[a, -1]] + a
Matlab
a = 1 ans =
1 0 0 0 2 1 2 4 2
2 3 0 0 3 2 3 9 2
4 9 5 0 4 4 9 5 3
2 2 3 4 5 2 2 3 4
a+tril(a,-1)'
Maple
1 A:=< <1|0|0|0>,
1 [[1,2,4,2],
2 <2|3|0|0>,
2 [2,3,9,2],
3 <4|9|5|0>,
3 [4,9,5,3],
4 <2|2|3|4>>;
4 [2,2,3,4]]
5
6 B:=ArrayTools[LowerTriangle](A,-1);
7 A:=A+B^%T;
Mathematica
1 mat={{1,2,3},
2 {4,5,6},
1 {1,9}
3 {7,8,9}}
4
5 pos = { {1,1},{3,3}};
6 Map[ mat[[Sequence@@ # ]] & , pos ]
Matlab
A=[1 2 3;
4 5 6; 1 ans =
7 8 9]; 2 1 9
I=[1 3]; % setup the I,J indices
J=[1 3];
A(sub2ind(size(A),I,J))
Maple
1 A:=<<1|2|3>,
2 <4|5|6>, 1 [1, 9]
3 <7|8|9>>;
4 loc:=[[1,1],[3,3]];
5 map(x->A[op(x)],loc);
Mathematica
1 a={{1,2,3},
2 {4,5,6}, 1 {1,2,3,4,5,6,7,8,9}
3 {7,8,9}}
4
5 Flatten[a]
Matlab
a=[1 2 3;
4 5 6;
1 1 4 7 2 5 8 3 6 9
7 8 9]
a=a(:);
a'
85
Maple
Select rows which has 9 in the second column and 10 in the last column. Hence the result will be the
first and third rows only
1 1 9 0 10
2 3 9 2 10
Mathematica
1 mat={{1,9,0,10},
2 {5,6,7,8}, 1 {{1},{3}}
3 {3,9,2,10}};
4
5 p = Position[mat[[All,{2,4}]],x_/;x==={9,10}]
1 {{1,9,0,10},
1 Extract[mat,p]
2 {3,9,2,10}}
Matlab
A=[1 9 0 10;
5 6 7 8; 1 ans =
3 9 2 10]; 2 1 9 0 10
3 3 9 2 10
r=bsxfun(@eq,A(:,[2 4]),[9 10]);
ind=all(r,2);
A(ind,:)
86
Maple
1 A:=<<1|9|0|10>,
2 <5|6|7|8>,
3 <3|9|2|10>>; 1 [[1,9,0,10],
4 2 [3,9,2,10]]
5 nRow:=op([1,1],A);
6 <seq(`if`(A[i,2]=9 and A[i,-1]=10,A[i,..],
NULL),
7 i=1..nRow)>;
Select elements in the first column only which has corresponding element in the second column greater
than 3, hence the result will be
1 [6 7 2]
Mathematica
1 mat = {{4, 3},
2 {6, 4},
3 {7, 6},
4 {2, 1},
5 {1, 3}, 1 {6, 7, 2}
6 {9, 2},
7 {2, 5},
8 {1, 2}};
9
10 r = Select[mat, #[[2]] > 3 &];
11 r[[All, 1]]
another way is to use Cases[]. This is the shortest way
1 {6, 7, 2}
1 Cases[mat, {x_, y_} /; y > 3 :> x]
87
Matlab
A=[4, 3;
6, 4;
7, 6;
1 6
2, 1;
2 7
1, 3;
3 2
9, 2;
2, 5;
1, 2];
A(A(:,2)>3,1)
Maple
1 A:=<<4|3>,
2 <6|4>,
3 <7|6>,
1 [[6],
4 <2|1>,
2 [7],
5 <1|3>,
3 [2]]
6 <9|2>,
7 <2|5>,
8 <1|2>>;
9 nRow:=op([1,1],A);
10 <seq(`if`(A[i,2]>3,A[i,1],NULL),i=1..nRow)>;
The problem is to select rows in which the string in the list is part of the string in the first column in
the matrix, and then sum the total in the second column for each row found. Hence the result of the
above should be
1 'foo' 'faa'
2 [126] [ 177]
88
Mathematica
1 mat = {{"foobar", 77},
2 {"faabar", 81},
3 {"foobur", 22},
4 {"faabaa", 8},
5 {"faabian", 88},
6 {"foobar", 27},
7 {"fiijii", 52}};
8 lst = {"foo", "faa"}; 1 {{"foo", 126}, {"faa", 177}}
9
10 foo[mat_, lst_] :=
11 Select[mat, StringMatchQ[lst,
12 StringTake[#[[1]], 3]] &];
13
14 r = Map[foo[mat, #] &, lst];
15
16 MapThread[{#1,
17 Total[#2[[All, 2]]]}&,{lst, r}]
Matlab
A = {'foobar', 77;
'faabar', 81;
'foobur', 22;
'faabaa', 8; 1 ans =
'faabian', 88; 2 'foo' 'faa'
'foobar', 27; 3 [126] [177]
'fiijii', 52};
lst= {'foo', 'faa'};
f=@(x) [x sum(cell2mat(A(strncmp(A(:,1),x,3),2)))];
r=arrayfun(@(i) f(lst(i)),1:2,'UniformOutput',false)
reshape([r{:}],2,2)
1 ans =
2 'foo' [126]
ans =
But notice that in Matlab, the answer is a cellarray. To access the3
4 'faa' [177]
numbers above 5
r{:} 6 ans =
r{1}{2} 7 126
r{2}{2} 8
9 ans =
10 177
I asked this question at SO, and more methods are shown there at HTML
method 1:
(credit for the idea to Mike Honeychurch at stackoverflow). It
turns out it is easier to work with what we want to keep instead
of what we want to delete so that Part[] can be used directly.
Hence, given a list of row numbers to remove, such as
1 pos = {2, 4};
1 {{0, 2, 1, 0},
2 {4, 3, 3, 2},
Start by generating list of the rows and columns to keep by using3 {3, 4, 3, 3},
the command Complement[], followed by using Part[] 4 {5, 4, 2, 0}
1 a = {{0, 5, 2, 3, 1, 0}, 5 }
2 {4, 3, 2, 5, 1, 3},
3 {4, 1, 3, 5, 3, 2},
4 {4, 4, 1, 1, 1, 5},
5 {3, 4, 4, 5, 3, 3},
6 {5, 1, 4, 5, 2, 0}
7 };
8 pos = {2, 4};
9 keep = Complement[Range[Length[a]], pos];
10 a[[keep, keep]]
1 {{0, 2, 1, 0},
method 2: (due to Mr Wizard at stackoverflow) 2 {4, 3, 3, 2},
1 ReplacePart[a, {{2},{4},{_, 2},{_, 4}} 3 {3, 4, 3, 3},
2 :> Sequence[]] 4 {5, 4, 2, 0}
5 }
method 3: (me)
use Pick. This works similar to Fortran pack(). Using a mask ma-
trix, we set the entry in the mask to False for those elements we
want removed. Hence this method is just a matter of making a1 Out[39]= {{0,2,1,0},
mask matrix and then using it in the Pick[] command. 2 {4,3,3,2},
1 {nRow,nCol} = Dimensions[a]; 3 {3,4,3,3},
2 mask = Table[True,{nRow},{nCol}]; 4 {5,4,2,0}}
3 pos = {2,4};
4 mask[[All,pos]]=False;
5 mask[[pos,All]]=False;
6 r=Pick[a,mask]/.{}->Sequence[]
90
Matlab
a = [0, 5, 2, 3, 1, 0;
4, 3, 2, 5, 1, 3;
4, 1, 3, 5, 3, 2; 1 a =
4, 4, 1, 1, 1, 5; 2 0 2 1 0
3, 4, 4, 5, 3, 3; 3 4 3 3 2
5, 1, 4, 5, 2, 0 4 3 4 3 3
] 5 5 4 2 0
list=[2 4];
a(list,:)=[];
a(:,list)=[];
Mathematica
1 a={{1,2},{5,3,7},{4}}; 1 List["12","537","4"]
2 Map[ToString[#]&,a,{2}];
3 Map[StringJoin[#]&,%]
Matlab
1 ans =
a={[1,2],[5,3,7],[4]}; 2 '1 2'
r=arrayfun(@(i) ... 3 '5 3 7'
cellstr(num2str(a{i})),1:length(a)); 4 '4'
r'
Matlab
1 ans =
d=[-9 1 3 -3 50 7 19]; 2 7 50
t =[0 7 2 50];
intersect(t,d)
In Matlab, the sort command is used. But in the Mathematica, the Sort command is the same the Matlab’s
sortrows() command, hence it can’t be used as is. Map is used with Sort to accomplish this.
Mathematica
1 {{2, 1, 2},
1 mat={{4,2,5}, 2 {4, 2, 5},
2 {2,7,9}, 3 {10,7, 9}}
3 {10,1,2}};
4
5 Map[Sort[#]&,Transpose[mat]];
6 mat=Transpose[%]
Matlab
1 2 1 2
A=[4 2 5;
2 4 2 5
2 7 9;
3 10 7 9
10 1 2];
sort(A,1)
Mathematica
1 {{2, 4, 5},
1 mat={{4, 2,5},
2 {2, 7, 9},
2 {2, 7,9},
3 {1, 2, 10}}
3 {10,1,2}};
4 Map[Sort[#]&,mat]
92
Matlab
1 2 4 5
A=[4 2 5;
2 2 7 9
2 7 9;
3 1 2 10
10 1 2];
sort(A,2)
Sort the matrix row-wise using first column as key so that the result is
1 2 7 9
2 4 2 5
3 10 1 2
In Matlab, the sortrows() command is used. In Mathematica the Sort[] command is now used as is.
Mathematica
1 {{2, 7, 9},
1 mat={{4, 2, 5},
2 {4, 2, 5},
2 {2, 7, 9},
3 {10, 1, 2}}
3 {10,1, 2}};
4 Sort[mat]
Matlab
1 2 7 9
A=[4 2 5;
2 4 2 5
2 7 9;
3 10 1 2
10 1 2];
sortrows(A)
Sort the matrix row-wise using the second column as key so that the result is
1 10 1 2
2 4 2 5
3 2 7 9
In Matlab, the sortrows() command is used, but now we tell it to use the second column as key.
In Mathematica the SortBy[] command is now used but we tell it to use the second slot as key.
Mathematica
1 mat={{4, 2, 5}, 1 {{10, 1, 2},
2 {2, 7, 9}, 2 {4, 2, 5},
3 {10,1, 2}}; 3 {2, 7, 9}}
4 (*sort by second element as key*)
5 SortBy[mat,#[[2]]&]
93
Matlab
1 10 1 2
A=[4 2 5;
2 4 2 5
2 7 9;
3 2 7 9
10 1 2];
sortrows(A,2)
©50 75 0 ª ©−1 75 0 ª
50 0 100® −1 0 100®
® ®
® ®
0 75 100® 0 −1 100®
A=
® will become B = −1 100 0 ®
® ®
75 100 0 ® ®
® ®
0 75 100® 0 −1 100®
® ®
« 0 75 100 ¬ « 0 −1 100 ¬
Mathematica
1 A={ {50, 75, 0},{50, 0, 100},
2 {0, 75, 100},{75, 100, 0},
3 {0, 75, 100},{0, 75, 100}};
4 ReplacePart[A,DeleteDuplicates[
5 Position[A,_?(#!=0&)],
6 (#1[[1]]==#2[[1]]&)]->-1]
2 {-1,100,0},{0,-1,100},{0,-1,100}}
Solution due to Adriano Pascoletti (from Mathematica news-
group)
1 r=(First /@ Split[#1,First[#1]===First
[#2]&]&)
2 [Position[A,x_/;x!=0]]
3 ReplacePart[A,r->-1]
Matlab
A=[50 75 0;
50 0 100;
0 75 100;
75 100 0;
0 75 100;
0 75 100]; 1 A =
2 -1 75 0
[I,J] = ind2sub(size(A),find(A~=0)); 3 -1 0 100
[b,c] = unique(I,'first'); 4 0 -1 100
A(sub2ind(size(A),b,J(c)))=-1 5 -1 100 0
6 0 -1 100
7 0 -1 100
This solution due to Bruno Luong (from matlab newsgroup)
B = cumsum(A~=0,2)>0
B = [false(size(B,1),1) B]
A(logical(diff(B,1,2))) = -1
2.32 Perform outer product and outer sum between two vector
Problem: Given 2 vectors, perform outer product and outer sum between them. The outer operation
takes the first element in one vector and performs this operation on each element in the second vector.
This results in first row. This is repeated for each of the elements in the first vector. The operation to
perform can be any valid operation on these elements.
Mathematica
using symbolic vectors. Outer product
1 {{a e, a f, a g},
1 Remove["Global`*"]
2 {b e, b f, b g},
2
3 {c e, c f, c g}}
3 v1={a,b,c};
4 v2={e,f,g};
5 Outer[Times,v1,v2]
Outer sum 1
{{a+e, a+f, a+g},
2 {b+e, b+f, b+g},
1 Outer[Plus,v1,v2]
3 {c+e, c+f, c+g}}
using numerical vectors. Outer product
1 {{4, 5, 6},
1 v1={1,2,3};
2 {8, 10, 12},
2 v2={4,5,6};
3 {12, 15, 18}}
3 Outer[Times,v1,v2]
1 {{5, 6, 7},
Outer sum
2 {6, 7, 8},
1 Outer[Plus,v1,v2]
3 {7, 8, 9}}
95
Matlab
1 ans =
Outer product 2 4 5 6
v1=[1 2 3]; 3 8 10 12
v2=[4 5 6]; 4 12 15 18
v1'*v2
Outer sum 1 ans =
v1=[1 2 3]; 2 5 6 7
v2=[4 5 6]; 3 6 7 8
meshgrid(v1)+meshgrid(v2)' 4 7 8 9
Maple
1 [a+d, a+e, a+f, b+d,
1 Outer(`+`,L1,L2); 2 b+e, b+f, c+d, c+e, c+f
]
2.33 Find the rank and the bases of the Null space for a matrix A
Problem: Find the rank and nullities of the following matrices, and find the bases of the range space
and the Null space.
2 3 3 4
A = 0 −1 −2 2®®
© ª
«0 0 0 1¬
Mathematica
1 mat={{2,3,3,4},
2 {0,-1,-2,2},
3 {0,0,0,1}}; 3,4
4
5 {nRow,nCol} = Dimensions[mat]
1 Print["Rank (or dimension of the range space
1 Rank (or dimension of the
)=",
range space)=3
2 MatrixRank[mat]]
1 Print["Dimension of the Null Space=", 1 Dimension of the Null
2 nCol-MatrixRank[mat]] Space=1
1 Print["Basis for Null Space=",NullSpace[mat1 Basis for Null Space
]] ={{3,-4,2,0}}
96
Matlab
A=[2 3 3 4;
1 A range space dimension=3
0 -1 -2 2;
2 A null space dimension= 1
0 0 0 1]
3 Basic for null space of A
=
[nRow,nCol]=size(A);
4
5 ans =
r = rank(A);
6 1.5000 -2.0000 1.0000
fprintf('A range space dimension=%d\n',r);
0
fprintf('A null space dimension= %d\n',nCol-r);
fprintf('Basic for null space of A =');
null(A,'r')'
1 (*Reconstruct A from its components *) 1 {{1.,2.,3.},
2 u.s.Transpose[v] 2 {4.,5.,6.}}
1 u =
2 -0.3863 -0.9224
3 -0.9224 0.3863
Matlab 4
5 s =
A=[1 2 3; 6
4 5 6]; 7 9.5080 0 0
[u,s,v]=svd(A); 8 0 0.7729 0
u 9
s 10 v =
v 11
12 -0.4287 0.8060 0.4082
13 -0.5663 0.1124 -0.8165
14 -0.7039 -0.5812 0.4082
1 ans =
u*s*v' 2 1.0000 2.0000 3.0000
3 4.0000 5.0000 6.0000
97
Maple
1 [1 2 3 ]
1 restart; 2 A := [ ]
2 with(LinearAlgebra): 3 [4 5 6.]
3 A:=Matrix([[1,2,3],[4,5,6.]]);
1 [0.386317703118612
1 m,n:=Dimensions(A): -0.922365780077058]
2 u,s,v:=SingularValues(A, 2 [
3 output=['U', 'S', 'Vt']): ]
4 u; 3 [0.922365780077058
0.386317703118612 ]
1 [9.50803200069572
0 0]
2 s := [
]
3 [ 0
0.772869635673485 0]
4
1 s:=DiagonalMatrix(s,m,n); 5 [0.428667133548626
2 v; 0.566306918848035
0.703946704147444 ]
6 v:= [0.805963908589298
0.112382414096594
-0.581199080396110]
7 [0.408248290463863
-0.816496580927726
0.408248290463863 ]
1 [9.50803200069572
0 0]
1 > s2:=DiagonalMatrix(SingularValues(A, 2 s2 := [
2 output=['S']),m,n); ]
3 [ 0
0.772869635673485 0]
1 [1. 2. 3.]
1 > evalf(u.s.v); 2 [ ]
3 [4. 5. 6.]
98
2.35 Solve Ax = b
Solve for x in the following system of equations
1 [ 1 2 3 ][x1] [ 1 ]
2 [ 7 5 6 ][x2]= [ 2 ]
3 [ 7 8 8 ][x3] [ 3 ]
Mathematica
1 mat={{1,2,3},
2 {7,5,6}, 1 {0,0,1/3}
3 {7,8,9}};
4 b = {1,2,3}
5 LinearSolve[mat,b]
Matlab
format long 1 ans =
A=[1 2 3; 2 0
7 5 6; 3 0
7 8 9]; 4 0.333333333333333
b=[1;2; 3];
A\b
Fortran
1 program t2
2 implicit none
3 integer, parameter :: N=3
4 real(8), DIMENSION(N, N) :: &
5 A=DBLE(reshape([ 1.0, 2.0, 3.0,&
6 7.0, 5.0, 6.0,&
7 7.0, 8.0, 9.0], shape(A), order=[2,1]))
8
9 real(8), parameter, DIMENSION(N, 1) :: &
10 b=DBLE(reshape([1.0, 2.0, 3.0], shape(b)))
11
12 real(8), DIMENSION(N, 1) :: IPIV
13 integer :: INFO
14
15 CALL DGETRF( N, N, A, N, IPIV, INFO )
16 if (INFO .eq. 0 ) then
17 CALL DGETRS( 'N', N,1, A, N, IPIV, b , N, INFO)
18 if ( INFO .eq. 0 ) then
19 print *, 'solution is',b
20 else
21 print *, 'failed DGETRS, INFO=',INFO
22 end if
23 else
24 print *, 'failed DGETRF, INFO=',INFO
25 end if
26 end program
0 0 1
© ª
10 0 2 ®
®
« 3 0 0 ¬
the positions returned will be (1, 3), (2, 1), (2, 3), (3, 1) and the corresponding values are 1, 10, 2, 3.
Mathematica
1 values=sp["NonzeroValues"] 1 {1,10,2,3,4}
1 (*find the index *)
1 {{1,3},{2,1},{2,3},{3,1},{3,2}}
2
3 Position[mat,x_/;x!=0]
1 values =
Matlab 2 10
3 3
A=[0 0 1; 10 0 2; 3 4 0]; 4 4
values= nonzeros(A) 5 1
6 2
1 I =
2 2
3 3
4 3
5 1
%find locations 6 2
[I,J]=find(A) 7 J =
8 1
9 1
10 2
11 3
12 3
Mathematica
1 Clear[f,x]
1 {1,4,9}
2 f[x_]:=x^2
3 v={1,2,3};
4 f[v]
Matlab
clear all; 1 ans =
v=[1 2 3] 2 1 4 9
f=@(x) x.^2
f(v)
Mathematica Matlab
1 x1=1; 1 clear all;
2 x2=3; 2 x1 = 1;
3 FindDivisions[{x1,x2},5] 3 x2 = 3;
4 4 linspace(x1,x2,5)
5 Out[48]= {1,3/2,2,5/2,3} 5
6 6 ans =
7 N[%] 7 1.0000 1.5000 2.0000 2.5000
8 Out[49]= {1.,1.5,2.,2.5,3.} 3.0000
3 PlotRange->All,
4 ColorFunction->"Rainbow",
5 AxesLabel->{"x","y","z"},
6 LabelStyle->12,
7 ImageSize->400]
I need to sort out the orientation difference between the two plots above.
Matlab
[X,Y] = meshgrid(-2:.2:2, -4:.2:4);
Z = X .* exp(-X.^2 - Y.^2);
surf(X,Y,Z)
xlabel('x');
ylabel('y');
zlabel('z');
Matlab
1 -0.276653966272994
A=rand(3,3);
det(A)
102
«7 8 9¬
1 2 3 0 0 0 0 0 0
© ª
4 5 6 0 0 0 0 0 0®®
7 8 9 0 0 0 0 0 0®
®
®
0 0 0 1 2 3 0 0 0®®
0 0 0 4 5 6 0 0 0®
®
®
0 0 0 7 8 9 0 0 0®®
0 0 0 0 0 0 1 2 3®
®
®
0 0 0 0 0 0 4 5 6®®
«0 0 0 0 0 0 7 8 9¬
1. 2. 3. 0 0 0 0 0 0
© ª
Mathematica 4. 5. 6. 0 0 0 0 0 0 ®
®
7. 8. 9. 0 0 0 0 0 0 ®
®
1 mat = N[{{1,2,3},{4,5,6},{7,8,9}}];
0 0 0 1. 2. 3. 0 0 0
®
sp = SparseArray[Band[{1,1}]->
®
2 ®
3 ConstantArray[mat,{3}]]
0 0 0 4. 5. 6. 0 0 0 ®
®
4 MatrixForm[sp] 0 0 0 7. 8. 9. 0 0 0
®
®
®
0 0 0 0 0 0 1. 2. 3. ®
®
0 0 0 0 0 0 4. 5. 6. ®
®
« 0 0 0 0 0 0 7. 8. 9. ¬
Matlab
1 ans =
A = [1 2 3;
2 1 0 0
4 5 6;
3 0 1 0
7 8 9];
4 0 0 1
Iy = speye(3);
full(Iy)
1 ans =
2 1 2 3 0 0 0 0 0 0
3 4 5 6 0 0 0 0 0 0
4 7 8 9 0 0 0 0 0 0
sp = kron(Iy,A); 5 0 0 0 1 2 3 0 0 0
full(sp) 6 0 0 0 4 5 6 0 0 0
7 0 0 0 7 8 9 0 0 0
8 0 0 0 0 0 0 1 2 3
9 0 0 0 0 0 0 4 5 6
10 0 0 0 0 0 0 7 8 9
Mathematica −2 1 0 0 0 0 0 0 0 0 0 0
© ª
1 −2 1 0 0 0 0 0 0 0 0 0 ®
®
1 numberOfInternalGridPoints = 4;
0 1 −2 1 0 0 0 0 0 0 0 0 ®
®
2 n = 3*internalGridPoints; 0 0 1 −2 1 0 0 0 0 0 0 0
®
®
3 sp = SparseArray[{Band[{1,1}]->-2,
®
0 0 0 1 −2 1 0 0 0 0 0 0 ®
Band[{1,2}]->1,
®
4
0 0 0 0 1 −2 1 0 0 0 0 0 ®
®
5 Band[{2,1}]->1},
0 0 0 0 0 1 −2 1 0 0 0 0
®
®
6 {n,n}]
®
0 0 0 0 0 0 1 −2 1 0 0 0 ®
Out[103]= SparseArray[<34>,{12,12}]
7
®
0 0 0 0 0 0 0 1 −2 1 0 0
®
®
8 MatrixForm[sp]
0 0 0 0 0 0 0 0 1 −2 1 0
®
®
®
0 0 0 0 0 0 0 0 0 1 −2 1 ®
®
« 0 0 0 0 0 0 0 0 0 0 1 −2 ¬
1 ans =
2 -2 1 0 0 0 0 0 0 0 0 0
0
3 1 -2 1 0 0 0 0 0 0 0 0
0
4 0 1 -2 1 0 0 0 0 0 0 0
0
5 0 0 1 -2 1 0 0 0 0 0 0
0
Matlab 6 0 0 0 1 -2 1 0 0 0 0 0
0
internalGridPoints = 4; 7 0 0 0 0 1 -2 1 0 0 0 0
n = 3*internalGridPoints; 0
e = ones(n,1); 8 0 0 0 0 0 1 -2 1 0 0 0
sp = spdiags([e -2*e e], -1:1, n,n); 0
full(sp) 9 0 0 0 0 0 0 1 -2 1 0 0
0
10 0 0 0 0 0 0 0 1 -2 1 0
0
11 0 0 0 0 0 0 0 0 1 -2 1
0
12 0 0 0 0 0 0 0 0 0 1 -2
1
13 0 0 0 0 0 0 0 0 0 0 1
-2
∂ 2u ∂ 2u ∂ 2u 1
+ 2 + 2 = 2 Ui−1,j,k + Ui+1,j,k + Ui,j−1,k + Ui,j+1,k + Ui,k ,k−1 + Ui,j,k+1 − 6Ui,j,k
∂x 2 ∂y ∂z h
1
Ui,j,k = Ui−1,j,k + Ui+1,j,k + Ui,j−1,k + Ui,j+1,k + Ui,k ,k−1 + Ui,j,k+1 − h 2 fi,j,k
6
To help make the A matrix, a small example with n = 2, is made. The following diagram uses the standard
numbering on each node
By traversing the grid, left to right, then inwards into the paper, then upwards, the following A matrix
results
105
The recursive pattern involved in these A matrices can now be seen. Each A matrix contains inside it a
block on its diagonal which repeats n times. Each block in turn contain inside it, on its diagonal, smaller
block, which also repeats n times.
It is easier to see the pattern of building A by using numbers for the grid points, and label them in the
same order as they would be visited, this allowes seeing the connection between each grid point to the
other easier. For example, for n = 2,
The connections are now more easily seen. Grid point 1 has connection to only points 2, 3, 5. This means
when looking at the A matrix, there will be a 1 in the first row, at columns 2, 3, 5. Similarly, point 2 has
connections only to 1, 4, 6, which means in the second row there will be a 1 at columns 1, 4, 6. Extending
the number of points to n = 3 to better see the pattern of A results in
From the above it is seen that for example point 1 is connected only to 2, 4, 10 and point 2 is connected
to 1, 3, 5, 11 and so on.
The above shows that each point will have a connection to a point which is numbered n 2 higher than
the grid point itself. n 2 is the size of the grid at each surface. Hence, the general A matrix, for the above
example, can now be written as
106
The recursive structure can be seen. There are n = 3 main repeating blocks on the diagonal, and each
one of them in turn has n = 3 repeating blocks on its own diagonal. Here n = 3, the number of grid
points along one dimension.
Now that the A structure is understood, the A matrix can be generated.
Example 1: Using n x = 2, ny = 2, nz = 2. These are the number of grid points in the x, y, z directions
respectively.
Matlab
nx=2;
ny=2;
ex=ones(nx,1);
Lx=spdiags([ex -3*ex ex],[-1 0 1],nx,nx);
ey=ones(ny,1); 1 ans =
Ly=spdiags([ey -3*ey ey],[-1 0 1],ny,ny);2 -6 1 1 0 1 0 0 0
3 1 -6 0 1 0 1 0 0
Ix=speye(nx); 4 1 0 -6 1 0 0 1 0
Iy=speye(ny); 5 0 1 1 -6 0 0 0 1
L2=kron(Iy,Lx)+kron(Ly,Ix); 6 1 0 0 0 -6 1 1 0
7 0 1 0 0 1 -6 0 1
nz=2; 8 0 0 1 0 1 0 -6 1
N=nx*ny*nz; 9 0 0 0 1 0 1 1 -6
e=ones(N,1);
L=spdiags([e e],[-nx*ny nx*ny],N,N);
Iz=speye(nz);
A=kron(Iz,L2)+L;
full(A)
Example 2: Using n x = 2, ny = 2, nz = 3.
107
1 ans =
2 -6 1 1 0 1 0 0 0 0 0 0
Matlab 0
3 1 -6 0 1 0 1 0 0 0 0 0
nx=2; 0
ny=2; 4 1 0 -6 1 0 0 1 0 0 0 0
ex=ones(nx,1); 0
Lx=spdiags([ex -3*ex ex],[-1 0 1],nx,nx);5 0 1 1 -6 0 0 0 1 0 0 0
ey=ones(ny,1); 0
Ly=spdiags([ey -3*ey ey],[-1 0 1],ny,ny);6 1 0 0 0 -6 1 1 0 1 0 0
0
Ix=speye(nx); 7 0 1 0 0 1 -6 0 1 0 1 0
Iy=speye(ny); 0
L2=kron(Iy,Lx)+kron(Ly,Ix); 8 0 0 1 0 1 0 -6 1 0 0 1
0
nz=3; 9 0 0 0 1 0 1 1 -6 0 0 0
N=nx*ny*nz; 1
e=ones(N,1); 10 0 0 0 0 1 0 0 0 -6 1 1
L=spdiags([e e],[-nx*ny nx*ny],N,N); 0
Iz=speye(nz); 11 0 0 0 0 0 1 0 0 1 -6 0
1
A=kron(Iz,L2)+L; 12 0 0 0 0 0 0 1 0 1 0 -6
full(A) 1
13 0 0 0 0 0 0 0 1 0 1 1
-6
Example 3: Using n x = 3, ny = 3, nz = 3.
Matlab
nx=3;
ny=3;
ex=ones(nx,1);
Lx=spdiags([ex -3*ex ex],[-1 0 1],nx,nx);
ey=ones(ny,1);
Ly=spdiags([ey -3*ey ey],[-1 0 1],ny,ny);
Ix=speye(nx);
Iy=speye(ny);
L2=kron(Iy,Lx)+kron(Ly,Ix);
nz=3;
N=nx*ny*nz;
e=ones(N,1);
L=spdiags([e e],[-nx*ny nx*ny],N,N);
Iz=speye(nz);
A=kron(Iz,L2)+L;
full(A)
1 2 3
© ª
4 5 6®
®
«7 8 9 ¬
−3 6 −3
© ª
6 −12 6 ®
®
«−3 6 −3¬
Mathematica
1 <<"Combinatorica`" (*not needed in V9*) 1 { {-3, 6, -3},
2 mat = {{1,2,3},{4,5,6},{7,8,9}}; 2 { 6, -12, 6},
3 cof = Table[Cofactor[mat,{i,j}], 3 {-3, 6, -3}}
4 {i,3},{j,3}];
5 adjugate = Transpose[cof]
1 Warning: Matrix is close to
Matlab singular
2 or badly scaled. Results may be
Will try to find function in Matlab to do this. But for inaccurate.
non-singular matrices only the direct method of find-3 RCOND = 1.541976e-18.
ing the inverse and then multiplying by the determi-4
5 ans =
nant to recover the adjunct can be used.
6 -3.0000 6.0000 -3.0000
A=[1 2 3;4 5 6;7 8 9]
7 6.0000 -12.0000 6.0000
det(A)*inv(A)
8 -3.0000 6.0000 -3.0000
Fortran
Thanks goes to James Van Buskirk and Louisa from comp.lang.fortran for the review and suggestions
which
lead to improvements of the code.
1 \begin{verbatimwrite}{toLua.txt}
2 !-- Find the Adjugate of a square matrix
3 !-- Version 6/22/2012 by Nasser M. Abbasi gfortran 4.6.3
4 program t44
5 implicit none
6 integer, parameter :: n=3
7 integer :: INFO,i,j,ii,IPIV(n-1),number_row_exchange
8 real (kind=kind(0.0d0)) :: A(n,n),B(n-1,n-1),C(n,n)
9 logical :: M(n,n)
10
11 A(1,:) = [1, 2, 3];
12 A(2,:) = [4, 5, 6];
13 A(3,:) = [7, 8, 9];
14
15 DO j=1,n
16 DO i=1,n
17
18 M = .true.
19 M(:,j) = .false.
109
20 M(i,:) = .false.
21 B = reshape(pack(A, M),[n-1,n-1])
22
23 !-- LU decomposition in order to obtain determinant
24 CALL DGETRF( n-1, n-1, B, n-1, IPIV, INFO )
25
26 !-- determinant of U is the product of diagonal
27 C(i,j)= PRODUCT( [(B(ii,ii),ii=1,n-1)] )
28
29 !-- Adjust sign based on number of row exchanges and (-1)^(i+j)
30 number_row_exchange = count(IPIV /= [(ii,ii=1,n-1)])
31 C(i,j) = C(i,j)*(1-2*MODULO(number_row_exchange+i+j,2))
32
33 END DO
34 END DO
35 write(*,'(3F15.4)') C
36 end program t44
1 #compile, link and run
2 export LD_LIBRARY_PATH=/usr/lib/atlas-base/:/usr/lib/atlas-base/atlas/
3 gfortran -fcheck=all -Wall t44.f90 -L/usr/lib/atlas-base/atlas/ -lblas -llapack
4 >./a.out
5 -3.0000 6.0000 -3.0000
6 6.0000 -12.0000 6.0000
7 -3.0000 6.0000 -3.0000
8 !>dpkg -l|grep -E "(blas|lapack)"
9 !ii libblas3gf 1.2.20110419-2ubuntu1 Basic Linear Algebra Reference
implementations, shared library
10 !ii liblapack-dev 3.3.1-1 library of linear algebra
routines 3 - static version
11 !ii liblapack-doc 3.3.1-1 library of linear algebra
routines 3 - documentation
12 !ii liblapack3gf 3.3.1-1 library of linear algebra
routines 3 - shared version
13 !ii libopenblas-base 0.1alpha2.2-3 Optimized BLAS (linear algebra)
library based on GotoBLAS2
14 !ii libopenblas-dev 0.1alpha2.2-3 Optimized BLAS (linear algebra)
library based on GotoBLAS2
15 !>
Ada
1 -- Ada implementation
2 with Ada.Text_Io; use Ada.Text_Io;
3 with Ada.Float_Text_Io; use Ada.Float_Text_Io;
4 with Ada.integer_Text_Io; use Ada.integer_Text_Io;
5 with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
6 procedure t44 is
7 A : constant real_matrix :=
8 (( 1.0, 2.0, 3.0),
9 ( 4.0, 5.0, 6.0),
10 ( 7.0, 8.0, 9.0));
11 --(( -3.0, 2.0, -5.0),
12 -- ( -1.0, 0.0, -2.0),
13 -- ( 3.0, -4.0, 1.0));
14 C : real_matrix(A'range(1), A'range(2));
15 B : real_matrix(1 .. 2, 1 .. 2);
16 -- Thanks goes to Dmitry A. Kazakov this function
17 function Exclude (A : Real_Matrix; I, J : Integer)
18 return Real_Matrix is
19 AI, AJ : Integer := A'First (1);
20 begin
21 return B : Real_Matrix (1..A'Length (1)-1, 1..A'Length (2)-1) do
22 AI := A'First (1);
23 for BI in B'Range (1) loop
24 if AI = I then
25 AI := AI + 1;
26 end if;
27 AJ := A'First (2);
28 for BJ in B'Range (2) loop
29 if AJ = J then
30 AJ := AJ + 1;
31 end if;
32 B (BI, BJ) := A (AI, AJ);
33 AJ := AJ + 1;
34 end loop;
35 AI := AI + 1;
110
36 end loop;
37 end return;
38 end Exclude;
39 -- Function to print a 2D matrix
40 procedure Put (X : Real_Matrix) is
41 begin
42 for I in X'Range (1) loop
43 for J in X'Range (2) loop
44 Put (X (I, J) ); put(" ");
45 end loop;
46 New_Line;
47 end loop;
48 end Put;
49 begin
50 FOR I in A'range(1) LOOP
51 FOR J in A'range(2) LOOP
52 B := Exclude (A, I, J);
53 C(I,J) := float((-1)**( ((I+J) rem 2) ))*determinant(B);
54 END LOOP;
55 END LOOP;
56 c := transpose(c);
57 put(c);
58 end t44;
a 11 a 12 r 1a 11 r 2a 12
r r 1 r 2 A a 21 a 22 r 1a 21 r 2a 22
a 31 a 32 r 1a 31 r 2a 32
Mathematica
Matlab
1 ans =
r=[2 3];
2 2 6
A=[1 2;
3 6 12
3 4;
4 10 18
5 6]
bsxfun(@times,r,A)
Fortran
1 program t45
2 implicit none
3
4 integer, parameter :: nRow=3, nCol=2
5
6 character(len=*), parameter :: FMT = "(2I5)"
7 integer :: v(nCol),A(nRow,nCol),B(nRow,nCol),i,j;
8
9 !-- initialization of data
10 v = [2,3]
11 A(1,:) = [1,2];
12 A(2,:) = [3,4];
13 A(3,:) = [5,6];
14
15 !F2008
16 !do concurrent (j = 1:nCol)
17 ! B(:,j) = v(j)*A(:,j)
18 !end do
19
20 do j=1,nCol
21 B(:,j) = v(j)*A(:,j)
22 end do
23
24 write(*,FMT) ( (B(i,j),j=1,nCol), i=1,nRow)
25
26 end program t45
1 #compile and run
2 >gfortran -std=f2008 t45.f90
3 >./a.out
4 2 6
5 6 12
6 10 18
Octave
Use automatic broadcasting
r .* A
112
1 B =
2 5 6
3 8 9
4 B =
5 4 6
6 7 9
7 B =
Matlab 8 4 5
9 7 8
A=[1 2 3; 10 B =
4 5 6; 11 2 3
7 8 9] 12 8 9
13 B =
for i=1:size(A,1) 14 1 3
for j=1:size(A,1) 15 7 9
B=A; 16 B =
B(i,:)=[]; 17 1 2
B(:,j)=[] 18 7 8
end 19 B =
end 20 2 3
21 5 6
22 B =
23 1 3
24 4 6
25 B =
26 1 2
27 4 5
113
Fortran
1 program t46
2 implicit none
3 integer, parameter:: dp=kind(0.d0), n=3
4 integer :: i,j,ii
5 real(dp) :: A(n,n) = dble(reshape([ 1.0, 2.0, 3.0, &
6 4.0, 5.0, 6.0, &
7 7.0, 8.0, 9.0], &
8 shape(A), &
9 order=[2,1]))
10 real(dp) :: B(n-1,n-1)
11 logical :: mask(n,n)
12 DO i=1,n
13 DO j=1,n
14 mask = .true.
15 mask(:,j) = .false.
16 mask(i,:) = .false.
17 !-- extract submatrix
18 B = reshape(pack(A, mask),[n-1,n-1])
19
20 DO ii=1,n-1
21 write(*,'(2F6.1)') B(ii,:)
22 END DO
23 write(*,'(/)')
24 END DO
25 END DO
26 end program t46
Ada
1 with Ada.Text_Io; use Ada.Text_Io;
2 with Ada.Float_Text_Io; use Ada.Float_Text_Io;
3 with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
4 procedure foo is
5 A : constant Real_Matrix :=
6 (( 1.0, 2.0, 3.0),
7 ( 4.0, 5.0, 6.0),
8 ( 7.0, 8.0, 9.0));
9 B : real_matrix(1 .. 2, 1 .. 2);
10 -- Thanks goes to Dmitry A. Kazakov
11 -- for providing this function
12 function Exclude (A : Real_Matrix; I, J : Integer)
13 return Real_Matrix is
14 AI, AJ : Integer := A'First (1);
15 begin
114
16 return B : Real_Matrix(1..A'Length(1)-1,1..A'Length(2)-1) do
17 AI := A'First (1);
18 for BI in B'Range (1) loop
19 if AI = I then
20 AI := AI + 1;
21 end if;
22 AJ := A'First (2);
23 for BJ in B'Range (2) loop
24 if AJ = J then
25 AJ := AJ + 1;
26 end if;
27 B (BI, BJ) := A (AI, AJ);
28 AJ := AJ + 1;
29 end loop;
30 AI := AI + 1;
31 end loop;
32 end return;
33 end Exclude;
34
35 -- Function to print a 2D matrix
36 procedure put(A: Real_Matrix) is
37 begin
38 for I in A'range(1) loop
39 for J in A'range(2) loop
40 put(A(I,J));
41 end loop;
42 new_line;
43 end loop;
44 end put;
45
46 begin
47 FOR I in A'range(1) LOOP
48 FOR J in A'range(2) LOOP
49 B := Exclude (A, I, J);
50 put(B);
51 new_line(1);
52 END LOOP;
53 END LOOP;
54 end foo;
Matlab 1 A =
2 1 2 3
A=[1 2 3;4 5 6;7 8 9];
3 7 8 9
A(2,:)=[]
Maple
1 [1 2 3]
1 A:=<1,2,3; 2 A := [ ]
2 4,5,6; 3 [7 8 9]
3 7,8,9>;
4 A:=LinearAlgebra:-DeleteRow(A,2);
Matlab 1 A =
2 1 3
A=[1 2 3;4 5 6;7 8 9]; 3 4 6
A(:,2)=[] 4 7 9
Maple
1 [1 3]
1 A:=<1,2,3;
2 A := [4 6]
2 4,5,6;
3 [7 9]
3 7,8,9>;
4 A:=LinearAlgebra:-DeleteColumn(A,2);
3
{0.534529,0.0291316,0.23062,0.180575},
4
{0.891017,0.812128,0.751813,0.417362}}
Mathematica 5
6 Out[22]= {2.38333,0.974855,2.87232}
1 mat = Table[RandomReal[],{3},{4}] 7
2 s = Total[mat,{2}] 8 Out[23]=
3 b = mat/s 9
4 Total[b,{2}] {{0.241573,0.269639,0.123339,0.365449},
10
{0.548316,0.029883,0.236568,0.185233},
11
{0.310208,0.282743,0.261744,0.145305}}
12
13 Out[24]= {1.,1.,1.}
1 A =
2 0.6787 0.3922 0.7060
0.0462
3 0.7577 0.6555 0.0318
0.0971
4 0.7431 0.1712 0.2769
0.8235
Matlab 5
6 B =
A = rand(3,4) 7 0.3723 0.2151 0.3873
s = sum(A,2); 0.0253
B = bsxfun(@rdivide,A,s) 8 0.4913 0.4250 0.0206
sum(B,2) 0.0630
9 0.3689 0.0850 0.1375
0.4087
10
11 ans =
12 1.0000
13 1.0000
14 1.0000
117
2
{0.515868,0.565691,0.800959,0.0302484},
3
{0.509004,0.143124,0.519455,0.264779}}
Mathematica
4
This method due to Bob Hanlon from the Math5 Out[32]=
{1.46526,1.65389,1.37314,0.832315}
group 6
1 mat = Table[RandomReal[],{3},{4}] 7
2 s = Total[mat,{1}] 8 Out[36]=
3 b = #/s& /@ mat {{0.300555,0.571426,0.038401,0.645535},
4 Total[b,{1}]
9
{0.352065,0.342036,0.583303,0.0363425},
10
{0.34738,0.0865376,0.378296,0.318123}}
11
12 Out[37]= {1.,1.,1.,1.}
1 A =
2 0.6948 0.0344 0.7655 0.4898
3 0.3171 0.4387 0.7952 0.4456
Matlab 4 0.9502 0.3816 0.1869 0.6463
5
A=rand(3,4) 6 B =
s=sum(A,1); 7 0.3541 0.0403 0.4380 0.3097
B=bsxfun(@rdivide,A,s) 8 0.1616 0.5133 0.4550 0.2817
sum(B,1) 9 0.4843 0.4464 0.1069 0.4086
10
11 ans =
12 1.0000 1.0000 1.0000 1.0000
Maple
1 A:=LinearAlgebra:-RandomMatrix(3,4);
1 [ 9 -95 51 24]
2 [ ]
3 A := [99 -20 76 65]
4 [ ]
5 [60 -25 -44 86]
1 b:=MTM:-sum(A,1); #sum columns
118
1 b := [168, -140, 83, 175]
1 nCol:=LinearAlgebra:-ColumnDimension(A):
2 B:=convert([seq(A[..,i]/b[i],i=1..nCol)],Matrix);
1 [3 19 51 24 ]
2 [-- -- -- ---]
3 [56 28 83 175]
4 [ ]
5 [33 1 76 13]
6 B := [-- - -- --]
7 [56 7 83 35]
8 [ ]
9 [5 5 -44 86 ]
10 [-- -- --- ---]
11 [14 28 83 175]
1 MTM:-sum(B,1);
1 [1, 1, 1, 1]
Matlab 1 ans =
2 6
A=[1 2 3;4 5 6;7 8 9]; 3 15
sum(A,2) 4 24
Mathematica Matlab
1 In[3]:= mat={{1,2,3}, 1 A=[1 2 3;4 5 6;7 8 9];
2 {4,5,6}, 2 sum(A,1)
3 {7,8,9}} 3
4 Total[mat,{1}] 4 ans =
5 5 12 15 18
6 Out[4]= {12,15,18}
first row, nonzero is in second column, and on the second row, nonzero is at first and third column, and
« ¬
Matlab
A=[0 39 0
55 100 0
34 0 0 1 2 1 2 1 2 3
0 9 0
0 0 50];
[I,~]=find(A'>0)
I'
2.55 How to remove values from one vector that exist in another
vector
Given vector v1 = {1, 3, 4, 5, 8, 9, 20.2, 30, −44} remove from it any element that exist in v2 = {1, 7, 4}.
Notice that Complement[] in Mathematica or setdiff() in Matlab can be used, but they will
sort the result. Hence they are not used here in order to keep the order the same.
120
Mathematica
1 #first method
2 v1={1,3,4,5,8,9,20.2,30,-44};
3,5,8,9,20.2,30,-44
3 v2={1,7,4};
4 v1=DeleteCases[v1,Alternatives@@v2]
1 #second method
2 v1={1,3,4,5,8,9,20.2,30,-44};
3 v2={1,7,4}; 3,5,8,9,20.2,30,-44
4 v1=DeleteCases[v1,x_/;MemberQ[v2,x]]
Matlab
1 v1 =
v1=[1,3,4,5,8,9,20.2,30,-44]; 2 3.0000 5.0000 8.0000 9.0000 20.2000
v2=[1,7,4]; 30.0000 -44.0000
v1(ismember(v1,v2))=[]
Fortran
1 program f
2 implicit none
3 REAL, ALLOCATABLE :: A(:),B(:)
4 A =[1.0,3.0,4.0,5.0,8.0,9.0,20.2,30.0,-44.0];
5 B =[1.0,7.0,4.0];
6 A = pack(A, A .NE. B)
7 Print *,A
8 end program f
1 >gfortran f2.f90
2 >./a.out
3 3.0000000 5.0000000 8.0000000 9.0000000 20.200001 30.000000 -44.000000
1 ans =
2 0.3026
3 0.3589
4 0.4745
Matlab 5 0.6249
6 0.3042
N = 52; 7 0.5428
n = 4; 8 0.2387
V = rand(N,1); 9 0.3200
mean(reshape(V,n,N/n))' 10 0.6224
11 0.4408
12 0.5657
13 0.5469
14 0.5696
121
2.57 find first value in column larger than some value and cut
matrix from there
Given matrix
© 1 5 ª
2 3 ®
®
®
4 8 ®
®
« 7 2 ¬
search in column 2 of matrix for the first time a value exceeds 6 and return the matrix up to that row.
The result should be
!
1 5
2 3
Mathematica
1 a = {{1, 5}, {2, 3}, {4, 8}, {7, 2}};
2 Min@Position[a, {x_, y_} /; y > 6] 1 {{1, 5}, {2, 3}}
3 (* 3 *)
4
5 a[[1 ;; % - 1]]
Matlab
A = [1,5;2,3;4,8;7,2];
A(1:find(A(:,2)>6)-1,:)
1 ans =
2 1 5
3 2 3
2.58 make copies of each value into matrix into a larger matrix
Do the following transformation. We want to take each element of matrix, and replace it by a 2 by 2
matrix with its values in places.
kron() in Matlab and KroneckerProduct in Mathematica can be used for this.
122
Mathematica
1 mat = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
2 kernel = {{1, 1}, {1, 1}}; 1 {{1, 1, 2, 2, 3, 3},
3 KroneckerProduct[mat, kernel]
2 {1, 1, 2, 2, 3, 3},
3 {4, 4, 5, 5, 6, 6},
4 {4, 4, 5, 5, 6, 6},
Another method that can be used in this, but I prefer the kron5 {7, 7, 8, 8, 9, 9},
method above: 6 {7, 7, 8, 8, 9, 9}}
1 mat = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
2 Map[ConstantArray[#, {2, 2}] &, mat, {2}]
3 ArrayFlatten[%, 2]
1 1 1 2 2 3 3
Matlab 2 1 1 2 2 3 3
3 4 4 5 5 6 6
A=[1 2 3; 4 5 6; 7 8 9]
4 4 4 5 5 6 6
kernel=ones(2,2)
5 7 7 8 8 9 9
kron(A,kernel)
6 7 7 8 8 9 9
Matlab 1 ans =
2 1 1 1 2 2 2 3 3 3 4 4
A=[1 2 3 4; 4
5 6 7 8; 3 5 5 5 6 6 6 7 7 7 8 8
9 10 11 12]; 8
kernel=ones(1,3); 4 9 9 9 10 10 10 11 11 11 12
kron(A,kernel) 12 12
Mathematica
1 Total[list]
55
Matlab
lst=1:10 55
sum(lst)
Maple
1 1,2,3,4,5,6,7,8,9,10
1 lst:=seq( i, i=1..10 );
1 convert([lst], `+`);
55
Matlab
1 2 4
A=[1 2;3 4];
max(A')
124
Matlab
1 3 4
A=[1 2;3 4];
max(A)
2.64 How to add the mean of each column of a matrix from each
column?
Given !
1 2
3 4
Find the mean of each column, and add this mean to each element of the corresponding column. The
result should be
!
3 5
5 7
To subtract the mean, just replace Plus with Subtract below for Mathematica and replace @plus with
@minus for Matlab. This shows that Matlab bsxfun is analogue to Mathematica’s MapThread.
Mathematica
1 {{3, 5}, {5, 7}}
1 mat = {{1, 2}, {3, 4}}
2 MapThread[Plus,{Transpose@mat, Mean[mat]}]
Matlab 1 ans =
2 3 5
A=[1 2;3 4];
3 5 7
bsxfun(@plus, A, mean(A))
2.65 How to add the mean of each row of a matrix from each row?
Given !
1 2
3 4
Find the mean of each row, and add this mean to each element of the corresponding row. The result
should be
!
2.5 3.5
6.5 7.5
125
To subtract the mean, just replace Plus with Subtract below for Mathematica and replace @plus with
@minus for Matlab. This shows that Matlab bsxfun is analogue to Mathematica’s MapThread..
The main difference is that Matlab is a little bit more consistent in this example, since in Matlab all
operations are done column wise. Hence mean(A) takes the mean of each column (same as Matematica
in this one case), but bsxfun also acts column wise on the matrix A, while Mathematica Map and
MapThread act row wise (list of lists). One just needs to be careful about this order difference.
Mathematica
1 {{2.5, 3.5}, {6.5,
1 mat = {{1, 2}, {3, 4}}; 7.5}}
2 MapThread[Plus,{mat, Mean@Transpose@mat}] // N
Matlab 1 ans =
2 2.5 6.5
A=[1 2;3 4];
3 3.5 7.5
bsxfun(@plus, A', mean(A'))
Mathematica
1 Remove["Global`*"];
2 1 {7,Sqrt[21],4}
3 v = {{1}, {2}, {4}};
4 p = {1, 2, Infinity};
5 Map[Norm[v,#]&,p]
Matlab
1 ans =
clear all; close all;
2 7.0000 4.5826
v=[1 2 4];
4.0000
p=[1,2,inf];
arrayfun(@(i) norm(v,p(i)),1:length(p))
Mathematica
1 mat = {{-1,1-3*I,0},
2 {1+3*I,0,-6*I},
3 {0,6*I,1}};
4 1 Out[32]= {{True,True,True},
5 mat2=Conjugate[Transpose[mat]]; 2 {True,True,True},
6 (diff=mat-mat2)//MatrixForm 3 {True,True,True}}
1 Count[%,False] 1 Out[33]= 0
Matlab
clear all;
i=sqrt(-1); 1 diff =
mat=[-1 1-3*i 0; 2 0 0 0
1+3*i 0 -6*i; 3 0 0 0
0 6*i 1]; 4 0 0 0
mat2=conj(transpose(mat));
diff = mat-mat2
1 r =
r=abs(diff)<eps('double') 2 1 1 1
3 1 1 1
4 1 1 1
all(r(:))
1
1 0 0
= 1 0 * 0
1 0 0
A L U
127
Mathematica
1 Remove["Global`*"]
1 {{{1,-3,5},
2 mat = {{1, -3, 5},
2 {2,2,-3},
3 {2, -4, 7},
3 {-1,-(5/2),-(3/2)}},
4 {-1, -2, 1}};
4 {1,2,3},1}
5
6 {lu,pivotVector,conditionNumber}=
7 LUDecomposition[mat]
1 {{1,0,0},
1 lower=lu*SparseArray[{i_,j_}/;j<i->1,{3,3}]+
2 {2,1,0},
2 IdentityMatrix[3]
3 {-1,-(5/2),1}}
1 {{1,-3,5},
1 upper=lu SparseArray[{i_,j_}/;j>=i->1,{3,3}] 2 {0,2,-3},
3 {0,0,-(3/2)}}
1 {{1,-3,5},
1 lower.upper 2 {2,-4,7},
3 {-1,-2,1}}
1 L =
2 1.0000 0 0
Matlab 3 -0.5000 1.0000 0
4 0.5000 0.2500 1.0000
clear all; 5
6 U =
A=[1 -3 5; 7 2.0000 -4.0000 7.0000
2 -4 7; 8 0 -4.0000 4.5000
-1 -2 1]; 9 0 0 0.3750
10 p =
[L,U,p]=lu(A) 11 0 1 0
12 0 0 1
13 1 0 0
1 ans =
L*U 2 2 -4 7
3 -1 -2 1
4 1 -3 5
Matlab
clear all; close all;
1 4 13 28 43 58 49 30
x1=[1 2 3 4 5];
x2=[4 5 6];
conv(x2,x1)
128
Mathematica
1 x1 = {2, 1, 2, 1};
2 x2 = {1, 2, 3, 4};
3 X1 = Chop[Fourier[x1, FourierParameters -> {1, -1} 1 {14., 16., 14.,
]]; 16.}
4 X2 = Chop[Fourier[x2, FourierParameters -> {1, -1}]];
Matlab
clear all; close all;
x1=[2 1 2 1]; 1 y =
x2=[1 2 3 4]; 2 14 16 14 16
X1=fft(x1);
X2=fft(x2);
y=real(ifft(X1.*X2))
Mathematica
1 Clear["Global`*"]
2 x1 = {1, 2, 3, 4, 5};
3 x2 = {4, 5, 6};
4 x2 = Append[x2, {0, 0}] // Flatten; 1 {53., 43., 28., 43.,
5 X1 = Chop[Fourier[x1, FourierParameters -> {1, 58.}
-1} ]];
6 X2 = Chop[Fourier[x2, FourierParameters -> {1,
-1}]];
7 Re[InverseFourier[X1*X2, FourierParameters ->
{1, -1}]]
Matlab
x1=[1 2 3 4 5];
x2=[4 5 6]; 1 y =
N=max(length(x1),length(x2)); 2 53 43 28 43 58
X1=fft(x1,N);
X2=fft(x2,N);
y=real(ifft(X1.*X2))
Convolve 2 sequences where the origin is assumed to be at the first element in each sequence.
1 x1={1,2,3,4,5};
2 x2={4,5,6};
3 ListConvolve[x2,x1,{1,-1},0]
1 {4,13,28,43,58,49,30}
case 2
Convolve 2 sequences where the origin is located at different location from the first element of the
sequence, use DiracDelta function, and the DTFT approach.
Example convolve x=1,2,0,2,1,4,01,2,2 with h=1/4,1/2,1/4 where the origin of h is under the second
element 1/2.
1 (*Write down the h and take its DTFT *)
2 Clear[n,w]
3 h = 1/4DiscreteDelta[n+1] +
4 1/2DiscreteDelta[n]+1/4 DiscreteDelta[n-1];
5 hTransformed = FourierSequenceTransform[h,n,w]
1 −iw
1 + e iw
2
e
4
- 14 n⩵2
1
n ⩵ -1
4
1
n⩵8
2
3
n ⩵ 1 || n ⩵ 5 || n ⩵ 6
4
1 n ⩵ 0 || n ⩵ 3
5
n⩵7
4
2 n⩵4
0 True
Now convolve z with h again, where z is the convolution of x and h found above. This can be done as
follows in one command
1 N@InverseFourierSequenceTransform[
2 xTransformed hTransformed hTransformed,w,n]
130
0.0625 n ⩵ -2.
0.125 n ⩵ 9.
0.3125 n ⩵ 2.
0.375 n ⩵ -1.
0.5625 n ⩵ 1. || n ⩵ 8.
0.75 n ⩵ 0.
0.875 n ⩵ 6.
0.9375 n ⩵ 3. || n ⩵ 7.
1.0625 n ⩵ 5.
1.4375 n ⩵ 4.
0. True
1 mat = HilbertMatrix[{20,10}];
2 ListPlot3D[mat,Mesh->None,InterpolationOrder->0,
3 ColorFunction->"SouthwestColors",
4 Filling->Axis,ImageSize->300]
Matlab
clear all; close all;
A = (100).*rand(20,20);
[X,Y] = meshgrid(1:20,1:20);
131
surfl(X,Y,A);
shading interp
colormap(gray);
figure;
A = hilb(20);
[X,Y] = meshgrid(1:20,1:20);
surfl(X,Y,A);
Maple
1 restart;
2 A := abs(LinearAlgebra[RandomMatrix](20,10,generator=0..100)):
3 plots[matrixplot](A,heights=histogram);
1 A := LinearAlgebra[HilbertMatrix](20,10):
2 A := convert(A,listlist):
3 plots[listplot3d](A);
132
Notice that the output sequence generated by Mathematica and Matlab are reversed with respect to
each others.
Also, MATLAB uses the length 2N − 1 as the length of cross correlation sequence, which in this example
is 23 because N is taken as the length of the larger of the 2 sequences if they are not of equal length
which is the case in this example.
In Mathematica, the length of the cross correlation sequence was 22, which is 2N .
133
Mathematica Matlab
1 Clear["Global`*"]; In MATLAB use the xcross in the signal process-
2 ing toolbox
3 a={0,0,2,-1,3,7,1,2,-3,0,0}; clear all; close all;
4 b={0,0,1,-1,2,-2,4,1,-2,5,0,0}; A=[0,0,2,-1,3,7,1,2,-3,0,0];
5 c=Reverse[ListCorrelate[a,b B=[0,0,1,-1,2,-2,4,1,-2,5,0,0];
,{-1,1},0]]
C=xcorr(A,B);
format long
C'
1 Out[31]= {0,
2 0,
3 0, 1 ans =
4 0, 2
5 10, 3 0.000000000000003
6 -9, 4 0.000000000000002
7 19, 5 -0.000000000000002
8 36, 6 0
9 -14, 7 9.999999999999998
10 33, 8 -9.000000000000002
11 0, 9 19.000000000000000
12 7, 10 36.000000000000000
13 13, 11 -14.000000000000000
14 -18, 12 33.000000000000000
15 16, 13 -0.000000000000002
16 -7, 14 6.999999999999998
17 5, 15 13.000000000000000
18 -3, 16 -18.000000000000000
19 0, 17 16.000000000000004
20 0, 18 -7.000000000000000
21 0, 19 4.999999999999999
22 0} 20 -2.999999999999998
21 -0.000000000000000
22 0.000000000000001
23 0.000000000000002
24 -0.000000000000004
25 0
Notice that A has rank 2, so we should get no more than 2 vectors in the orthonormal set.
With MATLAB use the orth(A) function, With Mathematica, use {u,s,v}=SingularValueDecomposi-
tion[A] , and since the rank is 2, then the first 2 columns of matrix u will give the answer needed (any
2 columns of u will also give a set of orthonormal vectors).
Mathematica
1 Remove["Global`*"];
2 mat = {{0, 1, 1, 2},
3 {1, 2, 3, 4}, 2
4 {2, 0, 2, 0}};
5 r = MatrixRank[mat]
1 {{0.378151, -0.308379},
1 {u,s,v}=SingularValueDecomposition[mat];
2 {0.887675, -0.146825},
2 orth=N[u[[All,{1,r}]]]
3 {0.262747, 0.939864}}
1 {{1.,0},
1 Chop[Transpose[orth].orth]
2 {0,1.}}
134
Matlab
1 R =
clear all;
2 -0.3782 0.3084
A=[0 1 1 2
3 -0.8877 0.1468
1 2 3 4
4 -0.2627 -0.9399
2 0 2 0];
R=orth(A)
R'*R 1 1.0000 0.0000
2 0.0000 1.0000
and !
5
b=
8
These 2 equations represent 2 straight lines in a 2D space. An exact solution exist if the 2 lines intersect
at a point. The 2 lines are x + 2y = 5 and x + 3y = 8.
4.0
Mathematica
1 Remove["Global`*"]; 3.5
2 ContourPlot[{x+2y==5,x+3y==8},
3 {x,-3,2},
4 {y,1.5,4}, 3.0
5 ContourStyle->{{Red,Thickness
[0.01]},
2.5
6 {Blue,Thickness
[0.01]}},
7 GridLines->Automatic,
2.0
8 GridLinesStyle->Dashed,
9 ImageSize->300]
1.5
-3 -2 -1 0 1 2
1 mat = {{1,2},{1,3}};
2 b = {5,8}; 1 {-1,3}
3 x = LinearSolve[mat,b]
Matlab
1 x =
A = [1 2;1 3]; 2 -1
b = [5;8]; 3 3
x = A\b
4
5 IF rank A < rank [A|b] THEN -- system is inconsistent
6 -- NO exact solution exist, but can use least square approximation
7
8 x= A/b -- Matlab.
9 x= PseudoInverse[A].b -- Mathematica uses SVD to computer pseduoInverse
10
11 ELSE -- we must have rank A == rank[A|b] -- system is consistent
12 IF rank(A) == N -- we have one solution.
13 IF M==N -- one unique solution, can use crammer rule.
14 x=A/b -- Matlab. Here we get exact solution from \ operator
15 x=LinearSolve[A,b] -- Mathematica
16 ELSE -- infinite solutions, pick one.
17 x=A/b -- Matlab. Here we get exact solution from \ operator
18 x=LinearSolve[A,b] -- Mathematica
19 END
20 ELSE
21 -- rank A < N, i.e. rank deficient, infinite solutions. will pick one
22 x=A/b
23 x=LinearSolve[A,b]
24 END
25 END
y =x −1
y = 2x + 1
So !
1 1
A=
−2 1
and !
1
b=
−1
Mathematica
1 Remove["Global`*"];
2 ContourPlot[{y==x-1,y==2 x+1} ,
3 {x,-3,2},{y,-6,3},
4 ContourStyle->{{Red,Thickness[0.01]},
5 {Blue,Thickness[0.01]}},
6 GridLinesStyle->Dashed,
7 ImageSize->300]
-2
-4
-6
-3 -2 -1 0 1 2
1 a = {{-2,1},{-1,1}};
2 b = {1,-1};
3 {nRow, nCol} = Dimensions[a];
4 aRank=MatrixRank[a]
2
136
1 abRank=MatrixRank[Insert[a,b,-1]]
2
The above algorithm can now be run as follows
1 If[aRank<abRank,
2 Print["System is no consistent, no exact solution"];
3 x=PseudoInverse[a].b,
4 If[aRank==nCol,
5 Print["System is consistent. Exact solution."];
6 x=LinearSolve[a,b]
7 ,
8 Print["consistent, rank deficient,infinite solutions"];
9 x=LinearSolve[a,b]
10 ]
11 ];
12
13 Print["Solution is x=",x];
Matlab
A=[-2 1;-1 1];
b=[1; -1];
[nRow,nCol]=size(A);
aRank=rank(A);
abRank=rank([A b]);
x=A\b;
if aRank<abRank
fprintf('System not consistent. no exact solution\n');
else
if aRank==nCol
fprintf('System consistent. Exact solution.\n');
else
fprintf('consistent,rank deficient,infinite solutions\n');
end
end
fprintf('solution is\n');
x
Output is
1 A rank=2, [A b] rank=2
2 Number of unknowns=2
3
4 System is consistent. Exact solution.
5 solution is
6 x =
7 -2
8 -3
137
Mathematica
1 Remove["Global`*"]
2 eqs = {4x+3y+2z==12,
3 5x+6y+3z ==7,
4 3 2
4 9x+7y+10z ==9}; © ª
5
5 6 3 ®
®
6 {b,a} = CoefficientArrays[eqs,{x,y,z
9 7 10
}]; « ¬
7
8 Normal[a]//MatrixForm
1 Normal[b]//MatrixForm
{−12, −7, −9}
1 LinearSolve[a,-b]//N 1 {6.71429,-2.85714,-3.14286}
1 0 0 2
1 MatrixForm[RowReduce[mat]]
© ª
0 1 0 −3 ®
®
« 0 0 1 −1 ¬
Matlab
1 ans =
clear all;
2 1 0 0 2
A=[1 1 -2 1
3 0 1 0 -3
3 2 4 -4
4 0 0 1 -1
4 3 3 -4];
rref(A)
138
Maple
1
0 0 2
1 A:=Matrix([
[1,1,-2,1],[3,2,4,-4],[4,3,3,-4]]); 0 1 0 −3
2 LinearAlgebra:-ReducedRowEchelonForm(A);
0
0 1 −1
© 41 45 49 53 ª
42 46 50 54 ®
A =
®
®
43 47 51 55 ®
®
« 44 48 52 56 ¬
© 1 1 41 ª
2 1 42
®
®
®
3 1 43 ®
®
4 1 44 ®
®
®
1 2 45 ®
®
2 2 46 ®
®
®
3 2 47 ®
®
4 2 48 ®
®
®
1 3 49 ®
®
2 3 50 ®
®
®
3 3 51 ®
®
4 3 52 ®
®
®
1 4 53 ®
®
2 4 54 ®
®
®
3 4 55 ®
®
« 4 4 56 ¬
Which gives at each row, the location and the value in the original matrix.
Mathematica
1 mat = {{41, 45, 49, 53}, {42, 46, 50, 54}, {43, 47, 51, 55}, {44, 48, 52, 56}};
2 Flatten[MapIndexed[Flatten[{{#2[[2]], #2[[1]]}, #1}] &, Transpose@mat,
{2}],1]
Another way
1 mat = {{41, 45, 49, 53}, {42, 46, 50, 54}, {43, 47, 51, 55}, {44, 48, 52, 56}};
2 {nRow, nCol} = Dimensions[mat];
3 idx = Flatten[Table[{i, j}, {j, nCol}, {i, nRow}], 1]; (*similar to ind2sub*)
4 val = Extract[mat, idx];
5 MapThread[Flatten[{#1, #2}] &, {idx, val}] (* similar to [I;J;A(:)']' *)
Matlab
139
A = [ 41 45 49 53;
42 46 50 54;
43 47 51 55;
44 48 52 56];
[I,J] = ind2sub(size(A),1:numel(A));
X = [I;J;A(:)']'
gives
1 X =
2 1 1 41
3 2 1 42
4 3 1 43
5 4 1 44
6 1 2 45
7 2 2 46
8 3 2 47
9 4 2 48
10 1 3 49
11 2 3 50
12 3 3 51
13 4 3 52
14 1 4 53
15 2 4 54
16 3 4 55
17 4 4 56
Out[295]=
Chapter 3
3.1 Generate and plot one pulse signal of different width and
amplitude
Problem: Generate one signal of some width and height.
2.0
1 Remove["Global`*"] 1.5
y(t)
2 f[x_,w_,h_]:=If[0<=x<w, 1.0
3 h*If[x-IntegerPart[x]<=0.5, 0.5
4 SquareWave[x], 0.0
5 -SquareWave[x]
-0.50.00.51.01.52.02.5
-1.0
6 ],
7 0] t
8 w = {0.5,1,2}; (*pulse width *) pulse of 1 sec width and amplitude1.5
9 h = {1,1.5,0.4}; (*pulse height *) 2.5
10 plots = MapThread[Plot[ 2.0
11 f[x,#1,#2],{x,-2,2.5}, 1.5
12 PlotRange->{{-1,2.5},{-0.3,2.5}},
y(t)
1.0
13 Frame->True,
0.5
14 Axes->False,
0.0
15 GridLines->Automatic,
16 GridLinesStyle->Dashed, -0.50.00.51.01.52.02.5
-1.0
17 PlotStyle->{Thick,Red}, t
18 FrameLabel->{{"y(t)",None},
pulse of 2 sec width and amplitude0.4
19 {"t","pulse of "<>ToString[#1]<> 2.5
20 " sec width and amplitude"<>
2.0
21 ToString[#2]}},
1.5
22 ImageSize -> 160,
y(t)
23 AspectRatio->1]&,{w,h}]; 1.0
24 0.5
25 Grid[{plots},Frame->All] 0.0
-0.50.00.51.01.52.02.5
-1.0
t
Matlab
clear all; close all;
f = [1 0.5 0.25];
w = [0.5 1 2];
h = [1 1.5 0.4];
figure;
for i=1:3
t=0:0.01:w(i);
y=h(i)*square(2*pi*f(i)*t);
subplot(3,1,i);
plot(t,y,'r','LineWidth',3);
grid on;
xlim([-2 2.5]);
ylim([-.6 2.5]);
141
142
title(sprintf...
('pulse of %2.1f sec width and amplitude=%2.1f',...
w(i),h(i)));
end
Mathematica
1
1 Remove["Global`*"]
2
y(t)
0
3 w = {0.25,0.125};
4 h = {1,1.5};
-1
5 plots = MapThread[Plot[#2 SquareWave[#1 x],
6 {x,-10,10},
7 PlotRange->{All,{-2,2}}, -2
-10 -5 0 5 10
8 Frame->True,
t
9 Axes->False,
10 PlotStyle->{Thick,Red}, pulse of 4. sec width and amplitude1.5
2
11 FrameLabel->{{"y(t)",None},
12 {"t","pulse of "<>ToString[1/(2*#1)]<>
13 " sec width and amplitude"<>ToString[#2]}}, 1
14 ImageSize->200,
15 AspectRatio->1,
y(t)
0
16 ExclusionsStyle->Dotted]&,{w,h}];
17
18 Grid[{plots},Frame->All] -1
-2
-10 -5 0 5 10
t
143
Matlab
clear all; close all;
f = [1 0.5];
h = [1 1.5];
t = -4:0.01:4;
pulse of 0.5 sec width and amplitude=1.0
2
figure; 1
for i=1:2 -1
y = h(i)*square(2*pi*f(i)*t); -2
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5
plot(t,y,'r','LineWidth',3); 2
1
grid on; 0
xlim([-2 2.5]); -1
ylim([-2 2.5]); -2
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5
title(sprintf...
('pulse of %2.1f sec width and amplitude=%2.1f'
,..
1/(2*f(i)),h(i)));
end
Mathematica
1
{6.,
2 -1.5 + 0.8660254037844386*I,
1 Chop[Fourier[{1, 2, 3},
3 -1.5 - 0.8660254037844386*I}
2 FourierParameters ->{1, -1}]]
1 ans =
Matlab 2 6.0000
3 -1.5000 - 0.8660i
fft([1,2,3])'
4 -1.5000 + 0.8660i
Maple
Maple need an Array for input, not list, so have to convert this1 [6.+0.*I,
is little strange 2 -1.5+.866025403784439*I,
1 lst:=[1,2,3]; 3 -1.5-.866025403784439*I]
2 SignalProcessing[FFT](convert(lst,Array),
3 normalization=none );
144
Ada I posted the code below on comp.lang.ada on June 8,2010. Thanks to Ludovic Brenta for making
improvement to the Ada code.
1 --
2 -- dtf.adb, compiled with GNAT 4.3.4 20090804 (release) 1
3 -- under CYGWIN 1.7.5
4 -- $ gnatmake dft.adb
5 -- gcc -c dft.adb
6 -- gnatbind -x dft.ali
7 -- gnatlink dft.ali
8 -- $ ./dft.exe
9 -- ( 6.00000E+00, 0.00000E+00)
10 -- (-1.50000E+00, 8.66026E-01)
11 -- (-1.50000E+00,-8.66025E-01)
12
13 with Ada.Text_IO; use Ada.Text_IO;
14 with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;
15
16 with Ada.Numerics; use Ada.Numerics;
17
18 with Ada.Numerics.Complex_Elementary_Functions;
19 use Ada.Numerics.Complex_Elementary_Functions;
20 with Ada.Complex_Text_IO; use Ada.Complex_Text_IO;
21
22 procedure dft is
23 N : constant := 3; -- named number, no conversion to Float needed
24 X : array(0 .. N-1) of Complex := (others=>(0.0,0.0));
25 data : constant array(0 .. N-1) of float :=(1.0,2.0,3.0);
26 Two_Pi_Over_N : constant := 2 * Pi / N;
27 -- named number, outside the loop, like in ARM 3.3.2(9)
28 begin
29 FOR k in X'range LOOP
30 FOR m in data'range LOOP
31 X(k) := X(k) + data(m)*exp(-J*Two_Pi_Over_N * float(m*k));
32 END LOOP;
33 put(X(k)); new_line;
34 END LOOP;
35 end dft;
Fortran
1 0.814723686393179
Matlab 2 0.905791937075619
3 0.126986816293506
rand(5,1) 4 0.913375856139019
5 0.632359246225410
Fortran
1 program t3
2 implicit none
3 real :: x(5)
4
5 CALL RANDOM_SEED()
6 CALL random_number(x)
7 print *,x
8
9 end program
1 -1.317217165004133
Matlab 2 -0.050512467930661
3 1.828170634434887
-2 + (5+2)*rand(5,1) 4 4.702547848040084
5 4.754219746394936
146
Fortran
1 program t3_2
2 implicit none
3 integer ::i
4 real, parameter :: a=-1.0,b=1.0
5 real :: x(5)
6
7 CALL RANDOM_SEED()
8 DO i=1,2
9 CALL random_number(x)
10 x = a+(b-a)*x
11 print *,x
12 END DO
13
14 end program
1 {{3.72173,-1.22006,3.52668,-0.685378,-0.310473},
2 {-1.53983,1.79573,-0.381918,0.772043,2.90332},
3 {-0.517218,3.2406,0.959955,-0.267537,4.8402},
4 {3.77614,4.47693,2.04639,0.0500882,-0.543643},
5 {2.06332,-1.09825,0.144992,2.98408,0.734073}}
Matlab
-2 + (5+2)*rand(5,5)
1 ans =
2 3.7642 1.0712 1.4284 -0.0678 1.4885
3 2.8638 0.6709 1.1191 2.7579 4.7182
4 0.2197 3.3586 2.5242 2.5857 0.3827
5 4.6516 3.5664 2.9656 -0.8617 2.0969
6 -1.7589 -0.6919 3.2828 -1.1670 -0.4333
147
Fortran
1 program t3_3
2 implicit none
3 integer ::i
4 real, parameter :: a=-1.0,b=1.0
5 real :: x(5,5)
6
7 CALL RANDOM_SEED()
8 DO i=1,2
9 CALL random_number(x)
10 x = a+(b-a)*x
11 CALL write(x)
12 END DO
13
14 !--- internal functions below ------
15 contains
16 SUBROUTINE write(A)
17 implicit none
18 REAL, DIMENSION(:,:) :: A
19 integer :: i,j
20
21 WRITE(*,*)
22 DO i = lbound(A,1), ubound(A,1)
23 WRITE(*,*) (A(i,j), j = lbound(A,2), ubound(A,2))
24 END DO
25
26 END SUBROUTINE write
27
28 end program
3.5 Determine and plot the Fourier Transform for continuous time
function
Plot the Fourier Transform of 3 sin(t)
Mathematica
1 Clear["Global`*"];
2 f = 3*Sin[t];
3 y = FourierTransform[f,t,w,FourierParameters->{1, -1}]
1 Out[138]= -3 I Pi DiracDelta[-1+w]+3 I Pi DiracDelta[1+w]
1 tab = Table[{k,y/.w->k},{k,-3,3}]
2 tab = tab/.DiracDelta[0]->1
3 tab[[All,2]]=Map[Sign[Im[#]]Abs[#]&,tab[[All,2]]]
4
5 ListPlot[tab,PlotStyle->AbsolutePointSize[5],
6 AxesLabel->{"frequency \[CapitalOmega] rad/sec",
7 "|F(\[CapitalOmega]|"},
8 PlotRange->{All,{-12,12}},
148
9 Filling->Axis,
10 FillingStyle->{{Thick,Red}}]
|F(Ω|
10
frequency Ω rad/sec
-3 -2 -1 1 2 3
-5
-10
Matlab
syms t;
F=fourier(3*sin(t))
1
2 F =
3 -pi*(dirac(w-1)-dirac(w+1))*3*i
Mathematica
1 {AudioChannels,
1 Remove["Global`*"]; AudioEncoding,
2 fname = "stereo.wav"; 2 Data,SampledSoundList,
3 SetDirectory[NotebookDirectory[]]; 3 SampleRate,Sound}
4 ele = Import[fname,"Elements"]
1 (*listen to it *)
2 sound = Import[fname,"Sound"];
3 EmitSound[sound] 1 22050
4
5 fs = Import[fname,"SampleRate"]
1 py = Fourier[data[[1,All]],
2 FourierParameters->{1,-1}]; 1 Out[117]= 14509
3 nUniquePts = Ceiling[(nSamples+1)/2]
1 py = py[[1;;nUniquePts]];
2 py = Abs[py];
3 py = py/nSamples;
4 py = py^2;
5
6 If[ OddQ[nSamples],
7 py[[2;;-1]]=2*py[[2;;-1]],
8 py[[2;;-2]]=2*py[[2;;-2]] 4. × 10-6
Magnitude spectrum
9 ];
3. × 10-6
10
11 f = (Range[0,nUniquePts-1] fs)/nSamples; |H(f)| 2. × 10-6
12 ListPlot[Transpose[{f,py}],
13 Joined->True, 1. × 10-6
14 FrameLabel->{{"|H(f)|",None}, 0
16 ImageSize->400,
17 Frame->True,
18 RotateLabel->False,
19 GridLines->Automatic,
20 GridLinesStyle->Dashed,
21 PlotRange->{{0,12000},All}]
Matlab
clear all; close all;
%
%This script plots the frequency spectrum of a wave file.
%This method of plotting the frequency spectrum is modeled after the
%example on Mathworks website tech note 1702
[data,Fs]=audioread('stereol.wav');
[nSamples,nChannels]=size(data);
waveFileLength=nSamples/Fs;
N = 2^(nextpow2(length(data(:,1))));
Y=fft(data(:,1),N);
NumUniquePts = ceil((N+1)/2);
Y = Y(1:NumUniquePts);
P = abs(Y);
P = P/length(data(:,1));
P = P.^2;
f = (0:NumUniquePts-1)*Fs/N;
plot(f,P);
title(sprintf('Power Spectrum of a wave file'));
xlabel('Frequency Hz');
ylabel('|H(f)|');
grid;
print(gcf, '-dpdf', '-r600', 'images/matlab_e52_1');
3.5
2.5
|H(f)|
1.5
0.5
0
0 2000 4000 6000 8000 10000 12000
Frequency Hz
f 1 = 20, f 2 = 30, f 3 = 50
and plot the signal power spectral density so that 3 spikes will show at the above 3 frequencies. Use
large enough sampling frequency to obtain a sharper spectrum
Mathematica
1 Clear ["Global`*"];
2 f1 = 20;
3 f2 = 30;
4 f3 = 100;
5 maxTime = 0.2;
6
7 y[t_]:=2 Sin[2 Pi f1 t]+4 Cos[2 Pi f2 t]+
8 5 Cos[2 Pi f3 t];
9
10 Plot[y[t],{t,0,maxTime},
11 Frame->True,
12 FrameLabel->{{"y(t)",None},
13 {"t (sec)","signal in time domain"}},
14 RotateLabel->False,
15 GridLines->Automatic,
16 GridLinesStyle->Dashed,
17 PlotRange->All,BaseStyle -> 12]
y(t) 0
-5
-10
4 py = Fourier[yn];
5 nUniquePts = Ceiling[(len+1)/2];
6 py = py[[1;;nUniquePts]];
7 py = Abs[py];
8 py = 2*(py^2);
9 py[[1]] = py[[1]]/2;
10 f = (Range[0,nUniquePts-1] fs)/len;
11
12 ListPlot[Transpose[{f,py}],Joined->False,
13 FrameLabel->{{"|H(f)|",None},
14 {"hz","Magnitude spectrum"}},
15 ImageSize->400,
16 Filling->Axis,
17 FillingStyle->{Thick,Red},
18 Frame->True,
19 RotateLabel->False,
20 GridLines->Automatic,
21 GridLinesStyle->Dashed,
22 PlotRange->All,BaseStyle -> 12]
Magnitude spectrum
11
1 × 10
8 × 1010
6 × 1010
|H(f)|
4 × 1010
2 × 1010
0
0 50 100 150 200 250 300 350
hz
1 × 1011
8 × 1010
6 × 1010
|H(f)|
4 × 1010
2 × 1010
0
0 50 100 150 200 250 300 350
hz
1 × 1011
8 × 1010
6 × 1010
|H(f)|
4 × 1010
2 × 1010
0
0 50 100 150 200 250 300 350
hz
Matlab
clear all; close all;
maxTime = 0.2;
t = 0:0.001:maxTime;
f1 =20; %Hz
f2 =30; %Hz
f3 =100; %Hz
y = @(t) 2*sin(2*pi*f1.*t)+4*cos(2*pi*f2.*t)+...
5*cos(2*pi*f3.*t);
plot(t,y(t));
set(gcf,'Position',[10,10,320,320]);
grid on
title('signal in time domain');
xlabel('time(msec)');
ylabel('Amplitude');
152
Amplitude
0
-5
-10
-15
0 0.05 0.1 0.15 0.2
time(msec)
fs = 7.0*max([f1 f2 f3]);
delT=1/fs;
yn = y(linspace(0,maxTime,maxTime/delT));
len = length(yn);
py = fft(yn);
nUniquePts = ceil((len+1)/2);
py = py(1:nUniquePts);
py = abs(py);
py = 2*(py.^2);
py(1) = py(1)/2;
f = 0:nUniquePts-1;
f = f*fs/len;
plot(f,py);
title('power spectral density');
xlabel('freq (Hz)');
ylabel('Energy content');
grid on
set(gcf,'Position',[10,10,320,320]);
2
Energy content
1.5
0.5
0
0 100 200 300 400
freq (Hz)
1 ImageDimensions[img]
1 {150,116}
1 (*see how many channels*)
2 ImageChannels[img]
1 3
1 data=ImageData[img]; (*get data*)
2 {nRow,nCol,nChannel}=Dimensions[data]
1 {116,150,3}
1 (*look at each channel*)
2 Map[Image[data[[All,All,#]],ImageSize->100]&,
3 Range[1,nChannel]]
, ,
1 (*get channel 2 to FFT but center it first*)
2 d = data[[All,All,2]];
3 d = d*(-1)^Table[i+j,{i,nRow},{j,nCol}];
4
5 (*make FFT,center, view spectrum and phase*)
6 fw = Fourier[d,FourierParameters->{1,1}];
7 (*adjust for better viewing as needed*)
8 fudgeFactor = 100;
9 abs = fudgeFactor * Log[1+Abs@fw];
10 Labeled[Image[abs/Max[abs],
11 ImageSize->300],
12 Style["Magnitude spectrum", 18]]
154
Magnitude spectrum
1 arg = Arg@fw;
2 Labeled[Image[arg/Max[arg],
3 ImageSize->300],
4 Style["Phase spectrum", 18]]
Phase spectrum
Matlab
close all; clear all;
%image in same folder.
img = imread('lena.tiff','tif');
imagesc(img)
50
100
150
200
250
300
350
400
450
500
50 100 150 200 250 300 350 400 450 500
img = fftshift(img(:,:,2));
F = fft2(img);
figure;
imagesc(100*log(1+abs(fftshift(F))));
colormap(gray);
title('magnitude spectrum');
155
magnitude spectrum
50
100
150
200
250
300
350
400
450
500
50 100 150 200 250 300 350 400 450 500
figure;
imagesc(angle(F)); colormap(gray);
title('phase spectrum');
phase spectrum
50
100
150
200
250
300
350
400
450
500
50 100 150 200 250 300 350 400 450 500
and
∫ T0
1 2
cn = x(t)e −jω0 nt dt
T0 T
− 20
Mathematica
1 Clear[T0, w0]
2 sol = FourierSeries[Sin[2 Pi/T0 t],
3 t, 3, FourierParameters -> {1, 2 Pi/T0}]
1 − 2i π t 1 2i π t
ie T0 − ie T0
2 2
1 data = Table[{i,
2 FourierCoefficient[Sin[2 Pi/T0 t], t, i,
3 FourierParameters -> {1, 2 Pi/T0}]}, {i, -5, 5}];
4 head = {"n", "cn"};
5 Grid[Insert[data, head, 1], Frame -> All]
156
n cn
-5 0
-4 0
-3 0
-2 0
ⅈ
-1 2
0 0
1 - ⅈ2
2 0
3 0
4 0
5 0
1 mag = data;
2 mag[[All,2]] = Map[Abs[#]&,data[[All,2]]];
3 ListPlot[mag,AxesOrigin->{0,0},
4 Filling->Axis,
5 FillingStyle->{{Thick,Red}},
6 AxesLabel->{"n","|Subscript[c, n]|"}]
|cn |
0.5
0.4
0.3
0.2
0.1
n
-4 -2 2 4
1 phase = data;
2 phase[[All,2]]=Map[Arg[#]&,
3 data[[All,2]]]* 180/Pi;
4 ListPlot[phase,AxesOrigin->{0,0},
5 Filling->Axis,
6 FillingStyle->{{Thick,Red}},
7 AxesLabel->{"n","Phase Subscript[c, n] degrees"},
8 ImageSize->300]
Phase cn degrees
100
50
n
-4 -2 2 4
-50
-100
1 (*Find Fourier Series for Cos[w0 t] + Sin[w0 t]^2*)
2
157
3 T0 = 2 Pi;
4 w0 = (2 Pi)/T0;
5 f[t_] := Cos[w0 t] + Sin[w0 t]^2;
6 Plot[f[t], {t, -10 Pi, 10 Pi},
7 PlotRange -> All,
8 ImageSize -> 300]
1.0
0.5
-0.5
-1.0
1 sol = FourierSeries[f[t],t,3,
2 FourierParameters->{1,(2 Pi)/T0}]
n cn
-5 0
-4 0
-3 0
- 2 - 14
1
-1 2
1
0 2
1
1 2
2 - 14
3 0
4 0
5 0
1 mag = data;
2 mag[[All,2]] = Map[Abs[#]&,data[[All,2]]];
3 ListPlot[mag,AxesOrigin->{0,0},
4 Filling->Axis,
5 FillingStyle->{{Thick,Red}},
6 AxesLabel->{"n","|Subscript[c, n]|"},
7 ImageSize->300]
158
|cn |
0.5
0.4
0.3
0.2
0.1
n
-4 -2 2 4
Plot phase
1 phase = data;
2 phase[[All, 2]] = Map[Arg[#] &,
3 data[[All, 2]]]* 180/Pi;
4 ListPlot[phase, AxesOrigin -> {0, 0},
5 Filling -> Axis,
6 FillingStyle -> {{Thick, Red}},
7 AxesLabel -> {"n", "Phase cn degrees"}]
Phase cn degrees
150
100
50
n
-4 -2 2 4
1.0
0.8
0.6
0.4
0.2
-6 -4 -2 2 4 6
1 T0 = 2;
2 sol = Chop[FourierSeries[f[t],t,6,
3 FourierParameters->{1,(2 Pi)/T0}]]
n cn
-8 0
- 7 - 0.0454728
-6 0
-5 0.063662
-4 0
- 3 - 0.106103
-2 0
-1 0.31831
0 0.5
1 0.31831
2 0
3 - 0.106103
4 0
5 0.063662
6 0
7 - 0.0454728
8 0
1 data=Table[{i,FourierCoefficient[f[t],t,i,
2 FourierParameters->{1,2 Pi/T}]},{i,-20,20}];
3 mag = data;
4 mag[[All,2]]=Map[Abs[#]&,data[[All,2]]];
5 ListPlot[mag,AxesOrigin->{0,0},
6 Filling->Axis,
7 FillingStyle->{{Thick,Red}},
8 PlotRange->All,
9 AxesLabel->{"n","|Subscript[c, n]|"},
10 ImageSize->300]
|cn |
0.5
0.4
0.3
0.2
0.1
n
-20 -10 10 20
Show phase
1 phase = data;
2 phase[[All,2]]=Map[Arg[#]&,data[[All,2]]]* 180/Pi;
3 ListPlot[phase,AxesOrigin->{0,0},
4 Filling->Axis,
5 FillingStyle->{{Thick,Red}},
6 AxesLabel->{"n","Phase cn degrees"},
7 ImageSize->300]
160
Phase cn degrees
150
100
50
n
-20 -10 10 20
Mathematica 0.4
0.3
1 data = RandomReal[NormalDistribution[],1000];
2 Histogram[data,30,"ProbabilityDensity", 0.2
0.0
-3 -2 -1 0 1 2 3
Matlab 0.45
0.4
0.05
bar(bin,freq) 0
-4 -3 -2 -1 0 1 2 3 4
Maple
1 restart;
2 with(Statistics):
3 nSamples:=1000:
4 data := Sample(RandomVariable(Normal(0, 1)),
5 nSamples):
6
7 plots[display](Histogram(data,bincount=20,
8 frequencyscale=relative));
1 1.0000
Matlab 2 3.3333
3 6.0000
data = [1 2 7 9 3 4 10 12]; 4 6.3333
filter = (1/3)*[1 1 1]; 5 5.3333
data(2:end-1) = conv(data,filter,'valid'); 6 5.6667
data' 7 8.6667
8 12.0000
Matlab
1 data =
data=[0 4 10 5 3;
2 0 4.0000 10.0000 5.0000
4,4,1,8,5;
3.0000
5,1,2,3,8;
3 4.0000 2.5000 6.0000 3.5000
8,6,8,8,10;
5.0000
10,3,7,7,8];
4 5.0000 4.2500 3.2500 6.5000
8.0000
filter= (1/4)*[0,1,0;
5 8.0000 5.0000 5.7500 7.0000
1,0,1;
10.0000
0,1,0];
6 10.0000 3.0000 7.0000 7.0000
8.0000
data(2:end-1,2:end-1)=...
conv2(data,filter,'valid')
Mathematica
1 0.9090909090909091
1 N[Sum[1/(k*(k + 1)), {k, 10}]]
Matlab
format long
1 0.909090909090909
k=1:10;
s=cumsum(1./(k.*(k+1)));
s(end)
163
Mathematica
For window size k = 2
1 {1.5,2.5,3.5,4.5,5.5,6.5,7.5}
1 v = {1, 2, 3, 4, 5, 6, 7, 8};
2 f = {1/2, 1/2};
3 ListConvolve[f, v] // N
Matlab
For a window size k = 2 1 ans =
V=[1 2 3 4 5 6 7 8]; 2 1.5000 2.5000 3.5000 4.5000 5.5000 6.5000 7.5000
f=[1/2 1/2];
conv(V,f,'valid')
Mathematica
method 1
1 a = {1, 2, 3, 5, 6, 7, 11, 12, 20, 21};
2 m = 5;
3 b = Table[0, {m}];
1 {6, 21, 3, 5, 11}
4 Do[k = RandomInteger[{1, Length[a]}];
5 b[[i]] = a[[k]];
6 a = Delete[a, k],
7 {i, 1, m}
8 ];
9 b
method 2 (Version 9)
1 {1, 6, 11, 7, 20} *)
1 RandomSample[a, m]
Matlab
A = [1,2,3,5,6,7,11,12,20,21];
1 B =
m = 5;
2 2
B = zeros(m,1);
3 20
for i = 1:m
4 7
k = randi(length(A),1);
5 11
B(i) = A(k);
6 1
A(k) = [];
end
B
164
1.0 3
2 4
0.5
f(t)
0.0 5
-0.5
6 8
-1.0 7
0.0 0.2 0.4 0.6 0.8 1.0
time (sec)
Matlab
clear all; close all;
period = 1;
f = 1/period;
fs = 8*f;
Ts = 1/fs;
nSamples = round(period/Ts);
x = linspace(0,period-Ts,nSamples);
signal = sin(2*pi*f*x);
stem(x,signal)
for i = 1:length(x)
text(x(i),sign(signal(i))*0.1+signal(i),num2str(i))
end
hold on;
x = linspace(0,period,10*nSamples);
plot(x,sin(2*pi*f*x))
ylim([-1.2,1.2]);
165
3
1
2 4
0.5
5
0 1
-0.5
6 8
-1
7
2. Taking the Fourier transform and assuming H (e iω ) is the Fourier transform of h[n] results in
1 1
H (e iω ) − H (e iω )e −iω = 1 − e −iω
2 4
1 − 14 e −iω
H (e iω ) =
1 − 12 e −iω
1 1 e −iω
= −
2e
1− 1 −iω 4 1 − 12 e −iω
Mathematica
1 Clear[w, n]
2 expr1 = -(1/4)*Exp[-I w]/(1 - (1/2)*Exp[-I w]);
3 expr2 = 1/(1 - (1/2)*Exp[-I w]);
4 sol1 = InverseFourierSequenceTransform[expr1, w, n];
5 sol2 = InverseFourierSequenceTransform[expr2, w, n];
6 sol = sol1 + sol2
1 1 1 1 1 1 1 1 1 1
1, , , , , , , , , ,
4 8 16 32 64 128 256 512 1024 2048
166
Chapter 4
dy (x)
= x2 − y
dx
Direction field plot (or slope plot) shows solutions for the ODE without actually solving the ODE.
dy
The following are the steps to generate direction field plot for dx = f (x, y)
1. generate 2 lists of numbers. The y list and the x list. These 2 lists are the coordinates at which a
small slop line will be plotted.
2. At each of the above coordinates (y, x) evaluate f (x, y).
3. Plot small line starting at the point (x, y) and having slop of f (x, y). The length of the line is kept
small. Normally it has an arrow at the end of it.
Using Matlab, the points are first generated (the (x, y) coordinates) then the slope f (x, y) evaluated at
each of these points, then the command quiver() is used. Next contour() command is used to plot few
lines of constant slope.
In Mathematica, the command VectorPlot is used. In Maple dfieldplot is used.
167
168
Mathematica 40
1 f[x_,y_]:= x^2-y
2 ListVectorPlot[Table[{1,f[x,y]}, 30
3 {x,-2,2,0.1},{y,-2,2,0.1}],
4 FrameLabel->{{"y(x)",None},
y(x)
20
5 {"x",
6 "direction fields for y'(x)=x^2-y"}
7 },
10
8 ImageSize->350,
9 LabelStyle->Directive[14]]
0
0 10 20 30 40
x
1 StreamPlot[{1,f[x,y]},{x,-2,2},{y,-2,2}, 1
2 FrameLabel->{{"y(x)",None},
3 {"x","direction fields for y'(x)=x^2-y"
y(x)
}}, 0
4 ImageSize->350,
5 LabelStyle->Directive[14]]
-1
-2
-2 -1 0 1 2
x
Matlab
clear all; close all;
0.5
quiver(X,Y,XlengthOfVector,
y
0
YlengthOfVector);
xlabel('x'); ylabel('y'); -0.5
hold on; -1
contour(X,Y,YlengthOfVector,... -1.5
[-5 -4 -3 -2 -1 0 1 2 3 4 5]); -2
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2
x
title(...
'direction fields for $\frac{dy}{dx}=x^2-
y$',...
'interpreter','latex','fontsize',12)
169
Maple
1 restart;
2 with(DEtools): with(plots):
3 ode1:=diff(y(x),x)=(y(x))^2-x;
4 dfieldplot(ode1,y(x),x=-6..10, y=-4..4,
5 arrows=MEDIUM,
6 title=`Line fields for an non-autonomous ODE
`);
1 restart;
2 with(DEtools): with(plots):
3 ode1:=diff(y(x),x)=(y(x))^2-x: √ (1)
4 p1:= dfieldplot(ode1,y(x),x=-6..10, y=-6..6, 3Ai (x) + Bi(1) (x)
5 arrows=MEDIUM): y (x) = − √
3Ai (x) + Bi (x)
6 sol:=dsolve({ode1,y(0)=0});
1 p2:=plot(rhs(sol),x=-6..10,
2 color=black,thickness=3):
3 display({p1,p2},
4 title=`Line fields and solution lines
5 for an non-autonomous ODE`);
4.2 Solve the 2-D Laplace PDE for a rectangular plate with Dirichlet
boundary conditions
Problem: Solve ∇2T (x, y) = 0 on the following plate, with height h = 30, and width w = 10, and with
its edges held at fixed temperature as shown, find the steady state temperature distribution
System boundary conditions.
T=100 degrees
10
T=0 degrees
Mathematica NDSolve[] does not currently support Laplace PDE as it is not an initial value problem.
Jacobi iterative method is used below to solve it. 100 iterations are made and then the resulting solution
plotted in 3D.
Mathematica Matlab
1 n = 32; (*grid size*) n = 32;
2 h = 1/(n-1);(*grid spacing*) h = 1/(n-1); %grid spacing
3 u = Table[0.,{n},{n}]; (*init to u = zeros(n,n);
zero*) u(1,:) = 100; %B.C.
4 u[[1,All]] = 100; (*B.C.*)
5 % coordinates
6 Do[ (*iterate 100 times*) [X,Y] = meshgrid(0:h:1,0:h:1);
7 tmp=u;
8 For[i=2,i<=n-1,i++, for k=1:100
9 For[j=2,j<=n-1,j++, tmp = u;
10 tmp[[i,j]]=
11 (1/4)(u[[i-1,j]]+u[[i+1,j]]+ for i=2:n-1
12 u[[i,j-1]]+u[[i,j+1]]) for j=2:n-1
13 ] tmp(i,j)=...
14 ]; (1/4)*(u(i-1,j)+u(i+1,j)+
15 ...
16 u=tmp, u(i,j-1)+u(i,j+1));
17 {100} end
18 ]; end
19
20 ListPlot3D[u,PlotRange->All, u=tmp;
21 ImagePadding->20, end
22 Mesh->{n,n},
23 ImageSize->300, mesh(X,Y,u);
24 PlotLabel->"solution of Laplace PDE title('solution of Laplace PDE on 2D'
on 2D" );
25 ] set(gcf,'Position',[10,10,320,320]);
Mathematica Matlab
1 Remove["Global`*"]; function e53
2 sol = First@DSolve[{y'[t]==3y[t], t = 0:0.001:2; % time
3 y[0]==1},y[t],t]; initial_y = 1;
4 y = y[t]/.sol
5 [t,y] = ode45( @rhs, t, initial_y);
6 Out[26]= E^(3 t)
7 plot(t,y)
8 Plot[y,{t,0,2}, title('Solution of y''=3y , y(0)=1');
9 FrameLabel->{{"y(t)",None}, xlabel('time');
10 {"t","Solution of y'=3y, y(0)=1"}}, ylabel('y(t)');
grid on
11 Frame->True, set(gcf,'Position',[10,10,420,420]);
12 GridLines->Automatic,
13 GridLinesStyle->Automatic, function dydt=rhs(t,y)
14 RotateLabel->False, dydt = 3*y;
15 ImageSize->300, end
16 AspectRatio->1] end
400
300
300
y(t)
y(t) 200
200
100
100
0
0
0.0 0.5 1.0 1.5 2.0
0 0.5 1 1.5 2
t
time
x1 = y
x2 = y 0
= x 10
hence
x 10 = x 2
and
x 20 = y 00
= 1.5y 0 − 5y
= 1.5x 2 − 5x 1
Mathematica Matlab
1 Remove["Global`*"]; function e54
2 eq = y''[t]-1.5y'[t]+5y[t]==0;
3 ic = {y'[0]==0,y[0]== 1}; t0 = 0; %initial time
4 sol = First@DSolve[{eq,ic},y[t],t]; tf = 10; %final time
5 y = y[t]/.sol
%initial conditions [y(0) y'(0)]
ic =[1 0]';
0.75t cos(2.10654t) − 0.356034e 0.75t sin(2.10654t)
1. 1.e
[t,y] = ode45(@rhs, [t0 tf], ic);
1 Plot[y,{t,0,10},
2 FrameLabel->{{"y(t)",None},
plot(t,y(:,1),'r')
3 {"t","Solution"}},
title('Solution using ode45');
4 Frame->True,
xlabel('time');
5 GridLines->Automatic,
ylabel('y(t)');
6 GridLinesStyle->Automatic,
grid on
7 RotateLabel->False,
set(gcf,'Position'
8 ImageSize->300,
,[10,10,320,320]);
9 AspectRatio->1,
10 PlotRange->All,
function dydt=rhs(t,y)
11 PlotStyle->{Thick,Red}]
dydt=[y(2) ;
-5*y(1)+1.5*y(2)];
end
Solution end
0 500
y(t) 0
-500
y(t)
-500
-1000
-1000
-1500 -1500
0 2 4 6 8 10 -2000
0 2 4 6 8 10
t
time
x1 = y
x2 = y 0
= x 10
hence
x 10 = x 2
and
x 20 = y 00
= 1.5y 0 − 5y + 4 cos (t)
= 1.5x 2 − 5x 1 + 4 cos (t)
Mathematica Matlab
1 Remove["Global`*"]; function e55
2 eq = y''[t]-15/10y'[t]+5y[t]==4 Cos[t]; t0 = 0; %initial time
3 ic = {y'[0]==0,y[0]== 1}; tf = 10; %final time
4 sol = First@DSolve[{eq,ic},y[t],t]; %initial conditions [y(0) y'(0)
]
√ √ ic =[1 0]';
71t
√
1
5183 (−1704 sin(t) sin
2
4 + 69 71e 3t /4 sin 71t +
√ √ 4 [t,y] = ode45(@rhs, [t0 tf], ic);
4544 cos(t) cos2 71t + 639e 3t /4 cos 71t −
√ 4 √ 4
plot(t,y(:,1),'r')
71t 71t
1704 sin(t) cos
2
4 + 4544 sin 2
4 cos(t))) title('Solution using ode45');
xlabel('time');
1 Plot[y,{t,0,10},
ylabel('y(t)');
2 FrameLabel->{{"y(t)",None},
grid on
3 {"t","Solution"}},
set(gcf,'Position'
4 Frame->True,
,[10,10,320,320]);
5 GridLines->Automatic,
6 GridLinesStyle->Automatic,
function dydt=rhs(t,y)
7 RotateLabel->False,
dydt=[y(2) ;
8 ImageSize->300,
-5*y(1)+1.5*y(2)+4*cos(t
9 AspectRatio->1,
)];
10 PlotRange->All,
end
11 PlotStyle->{Thick,Red}]
end
150
150
100
100
y(t)
50
y(t)
50 0
-50
0
-100
0 2 4 6 8 10
-50
time
0 2 4 6 8 10
t
x1 = y
x2 = y 0
= x 10
Therefore
x 10 = x 2
And
x 20 = y 00
= −t y
= −t x 1
174
√ √ √ √ √ √ √
− 3Ai 3 −1t + Bi 3 −1t − 3 32/3 Γ 23 Bi 20 3 −1 Ai 3 −1t + 3 32/3 Γ 2
Ai 20 3 −1 Bi 3 −1t
3
√ √ √
3Ai 20 3 −1 − Bi 20 3 −1
1 Plot[Re[y],{t,0,20},
2 FrameLabel->{{"y(t)",None},
3 {"t","Solution"}},
4 Frame->True,
5 GridLines->Automatic,
6 GridLinesStyle->Automatic,
7 RotateLabel->False,
8 ImageSize->300,
9 AspectRatio->1,
10 PlotRange->All,
11 PlotStyle->{Thick,Red},
12 Exclusions->None]
Solution
y(t)
0
-1
-2
0 5 10 15 20
t
175
Matlab
function e56
t0 = 0; %initial time
tf = 20; %final time
sol = bvp4c(@odefun,@bcfun,solinit);
plot(sol.x(1,:),sol.y(1,:),'r')
title('solution');
xlabel('time');
ylabel('y(t)');
grid;
set(gcf,'Position',[10,10,320,320]);
function dydt=odefun(t,y)
dydt=[y(2); -t.*y(1)];
function res=bcfun(yleft,yright)
res=[yleft(1)-3
yright(1)+1];
solution
3
1
y(t)
-1
-2
-3
0 5 10 15 20
time
∂T (x, t) ∂ 2T (x, t)
=k
∂t ∂x 2
Problem: given a bar of length L and initial conditions T (x, 0) = sin (πx) and boundary conditions
T (0, t) = 0,T (L, t) = 0, solve the above PDE and plot the solution on 3D.
Use bar length of 4 and k = 0.5 and show the solution for 1 second.
176
Mathematica
1 Clear[y,x,t];
2 barLength = 4;
3 timeDuration = 1;
4 eq = D[y[x, t], t] == k*D[y[x, t], x,
x];
5 eq = eq /. k -> 0.5;
6 boundaryConditions = {y[0,t]==0,
7 y[barLength,t
]==0};
8 initialConditions = y[x,0]==Sin[Pi x
];
9 sol=First@NDSolve[{eq,
10 boundaryConditions,initialConditions
},
11 y[x,t],{x,0,barLength},{t,0,
timeDuration}];
12 y = y[x,t]/.sol
13 Plot3D[y,{x,0,barLength},{t,0,
timeDuration},
14 PlotPoints->30,PlotRange->All,
15 AxesLabel->{"x","time","T[x,t]"},
16 ImageSize->300]
1 ContourPlot[y,{x,0,barLength},
2 {t,0,timeDuration},PlotPoints->15,
3 Contours->15,ContourLines->
False,
4 ColorFunction->Hue,PlotRange->
All,
5 ImageSize->300]
177
Matlab
function e57
m = 0;
x = linspace(0,4,30);
t = linspace(0,1,30);
sol = pdepe(m,@pde,
@pdeInitialConditions,...
@pdeBoundaryConditions,x,t);
u = sol(:,:,1);
surf(x,t,u)
title('Numerical PDE solution')
xlabel('x'); ylabel('Time t')
set(gcf,'Position',[10,10,320,320]);
% ----------------
function [c,f,s] = pde(x,t,u,DuDx)
k=0.5;
c = 1/k;
f = DuDx;
s = 0;
% ---------------
function T0 = pdeInitialConditions(x)
T0 = sin(pi*x);
% ---------------
function [pl,ql,pr,qr] = ...
pdeBoundaryConditions(xl,ul,xr,ur,t)
pl = ul;
ql = 0;
pr = 0;
qr = 1;
2 4 6 4 x 1 b1
b1 4
x
2
2 5 7 6 = b2 where b2 = 3
2 3 5 2 x 3 b3 b3 5
x
3
In Maple 11, the LinearAlgebra package was used. In Mathematica one can also get the general solu-
tion, but one must find the Null space specifically and add it to the result from LinearSolve[] since
LinearSolve[] finds particular solutions only.
In Matlab the same thing needs to be done. I am not sure now how to make Matlab give me the same
particular solution as Maple and Mathematica since Matlab A\b uses least square approach to determine
a solution. I am sure there is a way, will update this once I find out.
179
Mathematica
1 vars = {x1,x2,x3,x4};
2 eqs ={2 x1+4 x2+6 x3+4 x4==4,
2 4 6 4
3 2 x1+5 x2+7 x3+6 x4==3, © ª
4 2 x1+3 x2+5 x3+2 x4==5}; 2 5 7 6 ®
®
5
2 3 5 2
6 {b,mat} = CoefficientArrays[eqs,vars]; « ¬
7 Normal[mat]
1 Normal[b] 1 Out[163]= {-4,-3,-5}
1 generalSolution = vars/.sol
x1, x2, − x1 − x2
+ 32 , x1 x2 5
2 2 4 − 4 − 4
Matlab 1 Warning: Rank deficient,
2 rank = 2, tol = 4.033641e-15.
clear all; 3
A=[2 4 6 4; 4 particularSolution =
2 5 7 6; 5
2 3 5 2] 6 0
7 0
b=[4 3 5]' 8 1.5000
particularSolution=A\b 9 -1.2500
1 nullSolution =
2
nullSolution=null(A,'r') 3 -1 2
4 -1 -2
5 1 0
6 0 1
180
Maple
2 4 6 4
1 restart;
2 with(LinearAlgebra);
A= 2 5 7 6
3 vars := x[1], x[2], x[3], x[4];
sys := 2*x[1]+4*x[2]+6*x[3]+4*x[4] =
4
4,
2 3 5 2
5 2*x[1]+5*x[2]+7*x[3]+6*x[4] =
3,
6 2*x[1]+3*x[2]+5*x[3]+2*x[4] = 4
5;
7 b= 3
8 `eqs=`, convert([sys], Vector);
9 A, b := GenerateMatrix([sys], [vars]) 5
4 − x3 + 2 x4
1 `general solution=`, −1 − x − 2 x
3 4
2 LinearSolve(A, b, free = 'x')
x3
x4
Pendulum
If the energy is large enough to cause the pendulum to reach θ = π (the upright position) with non zero
angular velocity, then the pendulum will continue to rotate in the same direction and will not swing
back and forth.
The expression for the energy E for the pendulum is first derived as a function of θ, θÛ
E = PE + KE
1
= mдL (1 − cos θ ) + mL2θÛ2
2
The school PDF report contains more information on this topic.
This was solved in Mathematica using the ListContourPlot[] command after generating the energy
values.
The original Matlab implementation is left below as well as the Maple implementation. However, these
were not done using the contour method, which is a much simpler method. These will be updated later.
The following is the resulting plot for m = 1, д = 9.8m/s 2, L = 10m
Mathematica
1 SetDirectory[NotebookDirectory[]];
2 energy[theta_, speed_, m_, g_, len_] := m*g*len*(1 - Cos[theta]) + (1/2)*m*len
^2*speed^2;
3 m = 1; g = 9.8; len = 10;
4 data = Table[energy[i, j, m, g, len], {j, -4, 4, 0.01}, {i, -3*Pi, 3*Pi, Pi
/20.}];
5 ListContourPlot[data, InterpolationOrder -> 2, Contours -> 20,
MaxPlotPoints -> 30,
6 DataRange -> {{-3*Pi, 3*Pi}, {-4, 4}},
7 FrameTicks -> {{{-4, -3, -2, 0, 1, 2, 3, 4}, None},
8 {{-3*Pi, -2*Pi, -Pi, 0, Pi, 2*Pi, 3*Pi}, None}},
9 FrameLabel -> {{"\[Theta]'(t)", None},
10 {"\[Theta](t)", "constant energy levels for nonlinear pendulum model"}},
ImageSize -> 400,
11 LabelStyle -> 14, RotateLabel -> False]
Matlab
1 function HW2
2 %HW2 problem. MAE 200A. UCI, Fall 2005
3 %by Nasser Abbasi
4
5 %This MATLAB function generate the constant energy level
6 %curves for a nonlinear pendulum with no damping
7
8 close all; clear;
9 m=1; g=9.8; L=10;
10
11 %number of data points (positio vs speed) to find per curve
182
12 nPoints=40;
13
14 nEnergyLevels = 8; %number of energy levels
15 lowAnglesToVisit = linspace(0,pi,nEnergyLevels);
16 lowEnergyLevels(1:nEnergyLevels)=m*g*L*(1-cos(lowAnglesToVisit));
17 highAnglesToVisit = linspace(pi,2*pi,2*nEnergyLevels);
18 highEnergyLevels=zeros(1,2*nEnergyLevels);
19
20 initialHighEnergy=2*m*g*L;
21 Q=0.2;
22 for i=1:2*nEnergyLevels
23 highEnergyLevels(i) = initialHighEnergy+(Q*i*initialHighEnergy);
24 end
25
26 A = zeros(length(lowAnglesToVisit)+length(highAnglesToVisit),2);
27 A(:,1) = [lowAnglesToVisit highAnglesToVisit];
28 A(:,2) = [lowEnergyLevels highEnergyLevels];
29
30 [nAngles,~]=size(A);
31 data=zeros(nPoints,2);
32
33 for j=1:nAngles
34
35 currentAngle=A(j,1);
36 currentEnergyLevel =A(j,2) ;
37 angles=linspace(0,currentAngle,nPoints);
38 data(1:nPoints,1)=angles(:);
39
40 for m=1:nPoints
41 data(m,2)=speed(currentEnergyLevel,angles(m));
42 end
43 doPlots(data);
44 end
45
46 title(sprintf(['constant energy curves, nonlinear pendulum,'...
47 'quantum=%1.3f'],Q));
48 xlabel('angle (position)');
49 ylabel('speed');
50 set(gca,'xtick',[-4*pi,-3*pi,-2*pi,-pi,0,pi,2*pi,3*pi,4*pi]);
51 set(gca,'XTickLabel',{'-4pi','-3pi','-2pi','-pi',...
52 '0','pi','2pi','3pi','4pi'})
53
54 print(gcf, '-dpdf', '-r600', 'images/matlab_e77_1');
55
56 function s=speed(energy,angle)
57 m=1; g=9.8; L=10;
58 if angle<pi
59 s=sqrt(2/(m*L^2)*(energy-m*g*L*(1-cos(angle))));
60 else
61 s=sqrt(2/(m*L^2)*(energy-m*g*L*(1+cos(angle-pi))));
62 end
63
64 function doPlots(data)
65 plotCurves(data,0);
66 plotCurves(data,2*pi);
67 plotCurves(data,-2*pi);
68
69 function plotCurves(data,k)
70 plot(data(:,1)+k,data(:,2));
71 hold on;
72 plot(data(:,1)+k,-data(:,2));
73 plot(-data(:,1)+k,-data(:,2));
74 plot(-data(:,1)+k,data(:,2));
183
speed
0
-1
-2
-3
-4
-5
-4pi -3pi -2pi -pi 0 pi 2pi 3pi 4pi
angle (position)
Maple
0000
4.11 Solve numerically the ODE u + u = f using point collocation
method
Problem: Give the ODE
d 4u (x)
+ u (x) = f
dx 4
Solve numerically using the point collocation method. Use 5 points and 5 basis functions. Use the
Boundary conditions u (0) = u (1) = u 00 (0) = u 00 (1) = 0
Use the trial function
N =5
д (x) = ai (x (x − 1))i
X
i=1
Use f = 1
N =5
The solution is approximated using u (x) ≈ д (x) = ai (x (x − 1))i .
X
i=1
N equations are generated for N unknowns (the unknowns being the undetermined coefficients of the
basis functions). This is done by setting the error to zero at those points. The error being
d 4д (x)
+ д (x) − f
dx 4
Once д (x) (the trial function is found) the analytical solution is used to compare with the numerical
solution.
Mathematica
1 Clear["Global`*"];
2 nBasis = 5;
3 nPoints = 5;
4 a = Array[v,{nBasis}]
1 Out[392]= {v[1],v[2],v[3],v[4],v[5]}
1 trial = Sum[a[[n]] (x(x-1))^n,{n,1,nBasis}];
2 residual = D[trial,{x,4}]+trial-1;
3 mat = Flatten[Table[residual==0/.x->n/(2*nPoints-1),
4 {n,1,nPoints-1}]];
5
6 mat = Join[mat,{2 a[[1]]+2a[[2]]==0}];
7 sol = N@First@Solve[mat,a]
1 Out[397]= {v[1.]->-0.0412493,
2 v[2.]->0.0412493,
3 v[3.]->0.000147289,
4 v[4.]->-0.0000245233,
5 v[5.]->-3.28259*10^-8}
185
1 numericalSolution=Chop@
2 FullSimplify@Sum[sol[[n,2]](x(x-1))^n,
3 {n,1,nBasis}]
4
5 numericalSolutionDiff4 = D[numericalSolution,{x,4}];
6 numericalMoment = D[numericalSolution,{x,2}];
1−(1+i)x 1−(1−i)x
cos √ + cos √ + cosh 1−(1+i)x
√ + cosh 1−(1−i)x
√ − 2 cos √1 + cosh √1
2 2 2 2 2 2
−
2 cos √ + cosh √
1 1
2 2
1 analyticalMoment = D[analyticalSolution,{x,2}];
1−(1+i)x 1−(1−i)x 1−(1+i)x 1−(1−i)x
−i cos √ + i cos √ + i cosh √ − i cosh √
2 2 2 2
−
2 cos √1 + cosh √1
2 2
1 dispError[pt_] :=
2 ((analyticalSolution-numericalSolution)/.x->pt)/
3 (analyticalSolution/.x->.5)
4
5 momentError[pt_]:=
6 ((analyticalMoment-numericalMoment)/.x->pt)/
7 (analyticalMoment/.x->.5)
8
9 (*Now the percentage displacement
10 and moment errors are plotted*)
11 Plot[dispError[z],{z,0,1},
12 ImagePadding->70,
13 ImageSize->400,
14 Frame->True,
15 GridLines->Automatic,
16 GridLinesStyle->Dashed,
17 PlotStyle->Red,
18 FrameLabel->{{"error",None},
19 {"x","percentage displacement error"}},
20 LabelStyle->14]
1.5 × 10-10
1. × 10-10
5. × 10-11
0
0.0 0.2 0.4 0.6 0.8 1.0
x
186
1 Plot[momentError[z],{z,0,1},
2 ImagePadding->70,
3 ImageSize->400,
4 Frame->True,
5 GridLines->Automatic,
6 GridLinesStyle->Dashed,
7 PlotStyle->Red,
8 FrameLabel->{{"error",None},
9 {"x","percentage moment error"}},
10 LabelStyle->14,PlotRange->All]
1. × 10-10
5. × 10-11
0
0.0 0.2 0.4 0.6 0.8 1.0
x
1 (*Now the Residual error distribution
2 over x is plotted*)
3 Plot[Abs[numericalSolutionDiff4+
4 numericalSolution-1],{x,0,1},
5 ImagePadding->80,
6 ImageSize->400,
7 Frame->True,
8 GridLines->Automatic,
9 GridLinesStyle->Dashed,
10 PlotStyle->Red,
11 FrameLabel->{{"error",None},
12 {"x","Residual error distribution over x"}},
13 LabelStyle->14,
14 PlotRange->All]
2. × 10-8
1.5 × 10-8
error
1. × 10-8
5. × 10-9
0
0.0 0.2 0.4 0.6 0.8 1.0
x
187
Maple
1 #Solve u''''+u=1 using point collocation. Zero B.C.
2 #written by Nasser Abbasi for fun on April 25,2006.
3 restart;
4 Digits:=15;
5 nBasis := 5:
6 nPoints := 5:
7 coef := [seq(a[i],i=1..nBasis)]:
8 g := (x,n)-coef[n]*(x*(x-1))^n: #basis function
9 f := x-sum(g(x,k),k=1..nBasis): #trial function
10 moment := x-diff(f(x),x$2):
11 residual := x-diff(f(x),x$4)+f(x)-1:
12 A := seq(subs(x=N/(2*nPoints-1),residual(x)=0),N=1..nPoints-1):
13 A := A,2*(coef[1]+coef[2]=0):
14 sol := solve([A],coef):
15 coef := map(rhs,sol[1]):
16 evalf(coef):
17 numericalSolution:=x-sum(coef[n]*(x*(x-1))^n ,n=1..nBasis):
18 `The numerical solution is `, numericalSolution(x);
19 numericalSolutionMoment := x-diff(numericalSolution(x),x$2):
20
21 #Now obtain exact solution from Maple
22 eq := diff(W(x),x$4)+W(x)=1:
23 bc := W(0)=0,W(1)=0,D(D(W))(0)=0,D(D(W))(1)=0:
24
25 exact := unapply(rhs(dsolve({eq,bc})),x):
26
27 exactMoment := x-diff(exact(x),x$2):
28
29 displacmentError := x-(exact(x)-numericalSolution(x))/exact(.5):
30 momentError := x- (exactMoment(x)-numericalSolutionMoment(x))/evalf(subs(x=.5,
exactMoment(x))):
31
32 plot(displacmentError(x),x=0..1,labels=['x',"Disp. error %"]);
33 plot(momentError(x),x=0..1,labels=['x',"Moment error %"]);
eq1 = r 1 − a(e − 1)
s
a3
eq2 = delT − (e ∗ sinh(f ) − f )
µ
eq3 = r 2 − a(e cosh(f ) − 1)
Mathematica
1 ClearAll[a, e, f]
2 delT = 5.215*60*60;
3 r1 = 200 + 6378;
4 r2 = 130000;
5 mu = 3.986*10^5; 1 {{a->12029.39633,
6 eq1 = r1 - a*(e - 1) == 0; 2 e->1.546827108,
7 eq2 = delT - Sqrt[a^3/mu]* 3 f->2.721303232}}
8 (e*Sinh[f] - f) == 0;
9
10 eq3 = r2 - a*(e*Cosh[f]-1)==0;
11 sol = NSolve[{eq1, eq2, eq3},
12 {a, e, f}, Reals]
188
Matlab
clear all
syms a e f;
delT = 5.215*60*60;
r1 = 200+6378;
1 ans =
r2 = 130000;
2 [a == 12029.4, e ==
mu = 3.986*10^5;
1.54683, f == 2.7213]
eq1 = r1 - a*(e-1);
eq2 = delT - sqrt(a^3/mu)*(e*sinh(f)-f);
eq3 = r2 - a*(e*cosh(f)-1);
sol = feval(symengine,'numeric::solve',...
{eq1,eq2,eq3});
vpa(sol,6)
1 sol =
2 a: [1x1 sym]
3 e: [1x1 sym]
4 f: [1x1 sym]
5
6 sol.a
7 12029.396328714435126444927089827
Another option is solve but slower
sol = solve(eq1,eq2,eq3,a,e,f); 8
9 sol.e
10 1.5468271075497087492979481526009
11
12 sol.f
13 2.7213032317471583123822097902877
4.13 Solve 2nd order ODE (Van Der Pol) and generate phase plot
Problem: Solve
y 00 (t) − µ 1 − y 2 y 0 (t) + y (t) = 0
for different values of µ to compare effect of changing µ on the solution trajectories. The initial conditions
are
y (0) = 0.1
y 0 (t) = 0
Mathematica
1 process[mu_]:=Module[
2 {sol,p1,p2,p3,data,system,z,x1,
3 x2,t,ode1,ode2,timeScale},
4 ode1 =x1'[t]==x2[t];
5 ode2 =x2'[t]==z(1-x1[t]^2)x2[t]-x1[t];
6 timeScale ={t,0,80};
7 sol=First@NDSolve[
8 {ode1,ode2/.z->mu,x1[0]==0.01,x2[0]==0},
9 {x1[t],x2[t]},
10 timeScale,Method->{"Extrapolation",
11 Method->"LinearlyImplicitEuler"}];
12 sol = {x1[t],x2[t]}/.sol;
13 p1 = Plot[Evaluate[sol[[1]]],
14 Evaluate[timeScale],
15 Frame->True,
16 FrameLabel->{"time","y(t)"},
17 PlotLabel->"\[Mu]="<>ToString[mu]];
18 p2 = Plot[Evaluate[sol[[2]]],
19 Evaluate[timeScale],
20 Frame->True,
21 FrameLabel->{"time","y'(t)"},
22 PlotLabel->"\[Mu]="<>ToString[mu],
23 PlotStyle->RGBColor[1,0,0]];
24 data = Table[{evaluate[sol[[1]]],
25 Evaluate[sol[[2]]]},
26 Evaluate[timeScale]];
27 p3=ListPlot[data,Joined->True,Frame->True,
28 PlotLabel->"\[Mu]="<>ToString[mu],
29 FrameLabel->{"y(t)","y'(t)"},
30 PlotRange->All];
31 {p1,p2,p3}
32 ];
33 mu={0.1,.2,1,3,5,10};
34 r = process/@mu; Grid[r]
190
y'(t)
y'(t)
y(t)
0.0 0.0
0.0
-0.1
-0.1 -0.2
-0.2 -0.2
-0.4
-0.3 -0.3
0 20 40 60 80 0 20 40 60 80 -0.4 -0.2 0.0 0.2
time time y(t)
1 1 1
y'(t)
y'(t)
0
y(t)
0 0
-1 -1 -1
-2 -2 -2
0 20 40 60 80 0 20 40 60 80 -2 -1 0 1 2
time time y(t)
y'(t)
y'(t)
y(t)
0 0 0
-1 -1
-1
-2 -2
-2
0 20 40 60 80 0 20 40 60 80 -2 -1 0 1 2
time time y(t)
0 0 0
-1 -1 -2
-2 -4
-2
0 20 40 60 80 0 20 40 60 80 -2 -1 0 1 2
time time y(t)
0
y(t)
0 0.0
-1 -0.5
-5
-1.0
-2
0 20 40 60 80 0 20 40 60 80 -2 -1 0 1 2
time time y(t)
0 0.0
-6
-1 -0.2 -8
-0.4 -10
-2
0 20 40 60 80 0 20 40 60 80 -2 -1 0 1 2
Matlab
function e71
mu=[0.1,0.2,1,3,5,10];
for n=1:length(mu)
process(mu(n),n-1);
end
function process(mu,n)
timeScale=[0 80];
ic=[0.1;0];
[t,x]=ode45(@ode,timeScale,ic,[],mu);
subplot(6,3,(3*n)+1);
plot(t,x(:,1));
title(sprintf('mu=%1.2f',mu));
xlabel('time'); ylabel('y(t)');
subplot(6,3,(3*n)+2);
plot(t,x(:,2),'r');
title(sprintf('mu=%1.2f',mu));
xlabel('time'); ylabel('y''(t)');
subplot(6,3,(3*n)+3);
plot(x(:,2),x(:,1));
title(sprintf('mu=%1.2f',mu));
xlabel('y(t)'); ylabel('y''(t)');
function xdot=ode(t,x,mu)
xdot=[x(2) ; mu*(1-x(1)^2)*x(2)-x(1)];
y'(t)
y(t)
0 0 0
0 50 100 0 50 100 -2 0 2
time
mu=0.20 time
mu=0.20 y(t)
mu=0.20
2 5 2
y'(t)
y'(t)
y(t)
0 0 0
-2 mu=1.00 -5 mu=1.00 -2 mu=1.00
50 50 100 50 50 100 5-5 0 5
y'(t)
y'(t)
y(t)
y'(t)
y(t)
y'(t)
y(t)
y'(t)
y(t)
Mathematica
1 n = 21; (*number of grid points*)
2 uNew = Table[0, {n}, {n}]; (*solution grid*)
3 residual = uOld = uNew;
4
5 h = 1/(n - 1); (*spacing*)
6 c = 0.1; (*controls the tolerance*)
7 epsilon = c*h^2; (*error tolerance*)
8
9 grid = N@Table[{i*h,j*h},{i,0,n-1},{j,0,n-1}];
10
11 (*the force function*)
12 f[x_,y_] := -Exp[-(x - 0.25)^2 - (y - 0.6)^2];
13
14 (*evaluate force on the grid*)
15 force = Map[f[#[[1]],#[[2]]]&,grid,{2}];
16 normF = Sqrt[h]*Norm[Flatten@force,2];(*force norm*)
17 converged = False;
18
19 k = 0; (*iteration counter*)
20 While[Not[converged],
21 k++;
22 For[i = 2, i < n, i++,
23 For[j = 2, j < n, j++,
24 uNew[[i, j]] = (1/4)*(uOld[[i-1,j]]+uOld[[i+1,j]]
25 + uOld[[i,j-1]]+uOld[[i,j+1]]-h^2*force[[i,j]]);
26
27 residual[[i,j]] = force[[i, j]]-1/h^2*(uOld[[i-1,j]]+
28 uOld[[i+1,j]]+uOld[[i,j-1]]+uOld[[i,j+1]]-4*uOld[[i,j]])
29 ]
30 ];
31 uOld = uNew; (*updated at end*)
32 normR = Sqrt[h] Norm[Flatten@residual, 2];
33 If[normR/normF < epsilon, converged = True]
34 ];
35
36 (*plot solution*)
37 ListPlot3D[uOld, PlotRange -> All, ImagePadding -> 30,
38 ImageSize -> 400, Mesh -> {n, n},
39 AxesLabel -> {"x", "y", "u(x,y)"},
40 PlotRangePadding -> 0, BaseStyle -> 12,
41 PlotLabel -> Row[{"Converged in ", k, " iterations",
42 " ,epsilon=", epsilon, " ,h=", h}]]
193
Matlab
close all; clear all;
n = 21; % grid points, including internal points
c = 0.1; % constant of tolerance
myforce = @(X,Y) -exp( -(X-0.25).^2 - (Y-0.6).^2 );
while ~done
k = k+1;
u = uNew;
end
mesh(X,Y,u);
title(sprintf('solution at iteration %d',k))
0.08
0.06
0.04
0.02
0
1
1
0.8
0.5 0.6
0.4
0.2
0 0
4.15 How to solve BVP second order ODE using finite elements with
linear shape functions and using weak form formulation?
Solve y 00(x) − 3y(x) = −x 2 over x = 0 . . . 1 with boundary conditions x(0) = 0 and x(1) = 0 using
piecewise linear trial functions.
194
solution
Let the trial function be the linear function ŷ(x) = c 1x + c 2 . The residual is R = ŷ 00(x) − 3ŷ(x) + x 2 . Let
the test function be w(x). We need to solve for each element i the following equation
∫
Ii = w i Ri dx
dŷ x i +1
∫ x i +1
dw dŷ
Ii = − − 3w(x)ŷ(x) + w(x)x 2 dx + w(x)
xi dx dx dx x i
=0 (96.1)
or
i=M
I= Ii
X
i=1
i=M ∫ x i +1 x i +1 !
dw dŷ d ŷ
= − 3w(x)ŷ(x) + w(x)x 2 dx + w(x)
X
−
i=1 xi dx dx dx x i
=0
Where M is the number of elements. The above is the M equations we need to solve for the unknowns yi
at the internal nodes. In Galerkin method, the test function is w 1 (x) = H 1 (x) and w 2 (x) = H 2 (x) which
d ŷ(x )
comes from writing w i (x) = dyi
Rewriting the trial function ŷ(x) in terms of unknown values at nodes results in
Where H 1 (x) = x i +1h−x and H 2 (x) = x −xh where h is the length of each element. Hence (96.1) becomes
i
dŷ x i +1
∫ x i +1 ( 0 ) n ( ) ( ) ( ) ( )
H 1 (x) o y H o y H
i 1 (x) n
i 1 (x)
Ii = − H 1 (x)H 2 (x)
0 0 −3 H 1 (x)H 2 (x) + x dx + w(x)
2
xi H 20(x) yi+1 H 2 (x) yi+1 H 2 (x) dx x i
(96.2)
d ŷ x i +1 d ŷ 1
h i h i
The terms w(x) dx reduce to w(x) dx since intermediate values cancel each other leaving the
xi 0
two edge values over the whole domain.
x
But H 10(x) = −x
h and H 2 (x) = h . Plugging these into (96.2) and integrating gives the following
0
The algebra above was done with Mathematica. In the following code, x 1 is x i and x 2 is x i+1
1 h1 = (x2 - x)/h;
2 h2 = (x - x1)/h;
3 int1 = -{{D[h1, x]}, {D[h2, x]}}.{{D[h1, x],
D[h2, x]}}; 1 {{-(1/h), 1/h}, {1/h, -(1/h)}}
4 int2 = -3 {{h1}, {h2}}.{{h1, h2}};
5 int3 = {{h1}, {h2}} x^2;
6 sol1 = Integrate[int1, {x, x1, x2}];
7 sol1 /. {(x1 - x2) -> -h, (x2 - x1) -> h}
1 sol2 = Integrate[int2, {x, x1, x2}];
1 {{-h, -(h/2)}, {-(h/2), -h}}
2 sol2 /. {(x1 - x2) -> -h, (x2 - x1) -> h}
1
1 sol3 = Integrate[int3, {x, x1, x2}]; 2 {{(3 x1^4 - 4 x1^3 x2 + x2^4)
2 Simplify[%]; /(12 h)},
3 % /. {(x1 - x2) -> -h, (x2 - x1) -> h} 3 {(x1^4 - 4 x1 x2^3 + 3 x2^4)
/(12 h)}}
195
The above equation Ii is calculated for each element i, resulting in M equations where M is the number
of elements. Collecting all these local equations into a global stiffness matrix and then adjusting the
global stiffness matrix for boundary conditions by eliminating corresponding rows and columns, it is
then solved for the unknowns yi as a system Ax = f using direct solver. The following code illustrates
the method.
Matlab
M = 9; %number of elements
N = M+1; %number of nodes
dof = 2; %degree of freedom per element
kk = zeros(N);
f = zeros(N,1); %force vector
h = 1/M; %length of each element
k_local=1/h*[-1 1;1 -1]-h*[1 1/2;1/2 1];
plot(0:h:1,y,'or')
hold on;
plot(0:h:1,y,'-');
title(sprintf...
('FEM solution using to ODE using %d elements',M'));
xlabel('x');
ylabel('y(x)');
grid
0.03
0.025
0.02
y(x)
0.015
0.01
0.005
0
0 0.2 0.4 0.6 0.8 1
x
The analytical solution to the ODE is below. We can see it is very close to the FEM solution above with
11 elements. More elements leads to more accurate solution.
196
Mathematica
Analtical solution
1 ClearAll[y, x]
2 sol= y[x]/.First@DSolve[{y''[x]-3 y[x]==-x^2,
3 y[0] == 0, y[1] == 0}, y[x], x];
4 Plot[sol, {x, 0, 1}, Frame -> True,
5 FrameLabel -> {{"y(x)", None},
6 {"x", "analytical solution"}},
7 GridLines -> Automatic,
8 GridLinesStyle -> {{Dashed, LightGray},
9 {Dashed, LightGray}}
10 ]
analytical solution
0.030
0.025
0.020
y(x)
0.015
0.010
0.005
0.000
0.0 0.2 0.4 0.6 0.8 1.0
x
Numerical
1 m = 9;
2 n = m + 1;
3 dof = 2;
4 kk = Table[0., {n}, {n}];
5 f = Table[0., {n}];
6 h = 1/m;
7 kLocal = 1/h {{-1, 1}, {1, -1}} - h {{1, 1/2}, {1/2, 1}};
8 Do[
9 x1 = (i - 1) h;
10 x2 = i h;
11 fLocal = -1/(12 h) {3 x1^4 - 4 x1^3 x2 + x2^4,
12 x1^4 - 4 x1 x2^3 + 3 x2^4};
13 f[[i ;; i + dof - 1]] += fLocal;
14 kk[[i ;; i + dof - 1, i ;; i + dof - 1]] +=kLocal,
15 {i, m}
16 ];
17 kk[[1, ;;]] = 0;
18 kk[[1, 1]] = 1;
19 kk[[-1, ;;]] = 0;
20 kk[[-1, -1]] = 1;
21 f[[1]] = 0;
22 f[[-1]] = 0;
23 y = LinearSolve[kk, f];
24 x = Range[0, 1, h];
25
26 ListPlot[Transpose[{x, y}], Frame -> True, Joined -> True,
27 PlotMarkers -> Automatic, FrameLabel ->
28 {{"y(x)", None}, {"x",
29 Row[{"solution to y''(x)-3 y(x)=-x^2 using FEM, 9 elements"}]}},
30 GridLines -> Automatic,
31 GridLinesStyle -> LightGray
32 ]
197
0.025 ●
0.020 ●
●
y(x)
0.015
●
0.010
●
0.005
0.000 ● ●
0.0 0.2 0.4 0.6 0.8 1.0
x
13 14 15 16
node
7 8 9
10 11
9 12
4 5 6 element
5 6 7 8
1 2 3
1 2 3 4
ũ = c 1 + c 2x + c 3y + c 4xy (1)
Looking at one element, and using local coordinates systems with element having width 2a and height
2b gives
y
a, b a, b
4 3
b
x
(0,0)
Local node
a numbers, always
increase anti-
clockwise
1 2
a, b a, b
198
Evaluating the trial function (1) at each corner node of the above element gives
ũ 1 = c 1 − ac 2 − bc 3 + abc 4
ũ 2 = c 1 + ac 2 − bc 3 − abc 4
ũ 3 = c 1 + ac 2 + by3 + abc 4
ũ 4 = c 1 − ac 2 + bc 3 + abc 4
Or
ũ 1
©1 −a −b ab ª
c 1
ũ 2
1 a −b −ab ® c 2
®
=
ũ 3 1 a b ab ®® c3
®
ũ 4 b ab c
«
1 −a
¬ 4
Hence
−1
c1
©1 −a −b ab ª
ũ 1
c 1 a −b −ab ® ũ
2 2
=
®
c3 1 a b ab ®® ũ 3
®
c 4
«1 −a b ab ¬ ũ 4
© ab ab ab ab ª
ũ 1
1 −b b b −b ® ũ 2
®
=
(2)
4ab −a −a a a ® ũ 3
®
®
ũ 4
1 −1 1 −1
« ¬
1 coor = {{-a, -b}, {a, -b}, {a, b}, {-a, b}};
2 uVal = {u1, u2, u3, u4}; eq = c1 + c2 x + c3 y + c4 x y;
3 r = MapThread[eq /. {u -> #1, x -> #2[[1]], y -> #2[[2]]}&, {uVal, coor}];
4 mat = Last@Normal[CoefficientArrays[r, {c1, c2, c3, c4}]];
5 MatrixForm[Inverse[mat] // MatrixForm
Out[6]//MatrixForm=
1 -a -b a b
1 a -b -a b
1 a b ab
1 -a b -a b
Out[7]//MatrixForm=
1 1 1 1
4 4 4 4
1 1
- 41a - 41a
4a 4a
1 1
- 41b - 41b
4b 4b
1 1
- 4 1a b - 4 1a b
4ab 4ab
ũ = c 1 + c 2x + c 3y + c 4xy
1
= ((ab − bx − ay + xy) ũ 1 + (ab + bx − ay − xy) ũ 2 + (ab + bx + ay + xy) + (ab − bx + ay − xy))
4ab
Since ab is the 1
4 of the area of element, then the above becomes
1
ũ = ((ab − bx − ay + xy) ũ 1 + (ab + bx − ay − xy) ũ 2 + (ab + bx + ay + xy) + (ab − bx + ay − xy))
A
The above can now be written in term of what is called shape functions
Where
1 1
N1 = (ab − bx − ay + xy) = (a − x) (b − y)
A A
1 1
N 2 = (ab + bx − ay − xy) = (a + x) (b − y)
A A
1 1
N 3 = (ab + bx + ay + xy) = (a + x) (b + y)
A A
1 1
N 4 = (ab − bx + ay − xy) = (a − x) (b + y)
A A
Now that the shape functions are found, the next step is to determine the local element stiffness matrix.
This can be found from the weak form integral over the area of the element.
x∫=a y=b
∫
Ii = w ∇2u − f (x, y) dxdy (3)
x =−a y=−b
d ũ
Where w (x, y) is the test function. For Galerkin method, the test function w i = du i = Ni (x, y). Hence
N 1 (x, y)
A
1
(a − x) (b − y)
N 2 (x, y) 1 (a + x) (b − y)
w (x, y) = = 1A
N 3 (x, y)
A (a + x) (b + y)
N 4 (x, y) A1 (a − x) (b + y)
goes to zero
x∫=a y=b z }| {
∂w ∂ũ ∂ũ
∫ ∫
Ii = − − w f (x, y) dxdy + w
∂x i ∂x i ∂n
x =−a y=−b Γ
The term w ∂∂nũ is the integration over the boundary of the element. Since there is only an essential
∫
Γ
boundary condition over all the boundaries (this is the given Dirchilet boundary condition), w = 0 on
the boundary and this integral vanishes. There is no natural boundary conditions for this example.
For those elements not on the external edge of the overall grid (i.e. internal elements), each contribution
to this integral will cancel from the adjacent internal element. What this means is that the above reduces
to just the first integral
x∫=a y=b
∂w ∂ũ
∫
Ii = − − w f (x, y) dxdy
∂x i ∂x i
x =−a y=−b
∂N 1 ∂N 1
∂x
ũ 1
∂y
ũ 1
x∫=a y=b
∂N ∂N
ũ ũ
n 2
∫ 2
∂N 1 ∂N 2 ∂N 3 ∂N 4
o
2
∂y
n ∂N 1 ∂N 2 ∂N 3 ∂N 4
o
2
= ∂x
− ∂N 3 ∂x ∂x ∂x ∂x
− ∂N 3 ∂y ∂y ∂y ∂y
∂x
ũ 3
∂y
ũ 3
x =−a y=−b
∂N
ũ 4 ∂N4 ũ 4
4
∂x ∂y
N 1 (x, y)
x∫=a y=b
N 2 (x, y)
∫
f (x, y) dxdy
−
N 3 (x, y)
x =−a y=−b
N 4 (x, y)
Hence
200
∂N 1 ∂N 1 ∂N 3 ∂N 3
+ ∂N 1 ∂N 1 ∂N 1 ∂N 2
+ ∂N 1 ∂N 2 ∂N 1
+ ∂N 1 ∂N 1 ∂N 4
+ ∂N 1 ∂N 4
ũ 1
x∫=a y=b © ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ª
∂N2 ∂N1 + ∂N2 ∂N1 ∂N2 ∂N2 ∂N 2 ∂N 2 ∂N 2 ∂N 3 ∂N 2 ∂N 3 ∂N 2 ∂N 4 ∂N 2 ∂N 4 ®
+ + + ∂y ® ũ 2
∫
∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y
Ii =
− ∂N ∂N 3 ∂N 1 ∂N 3 ∂N 2 ∂N 3 ∂N 3 ∂N 3 ∂N 3 ∂N 3 ∂N 3 ∂N 3
∂x3 ∂N∂x + ∂y ∂y
1
∂x ∂x + ∂y
∂N 2
∂y ∂x ∂x + ∂y ∂y ∂x
∂N 4
∂x + ∂y
∂N 4 ®
® ũ 3
∂y ®
x =−a y=−b
∂N 4 ∂N 1 ∂N 4 ∂N 1 ∂N 4 ∂N 2 ∂N 4 ∂N 2 ∂N 4 ∂N 3 ∂N 4 ∂N 3 ∂N 4 ∂N 4 ∂N 4 ∂N 4
+ + + + ũ 4
« ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ∂x ∂x ∂y ∂y ¬
N 1 (x, y)
x∫=a y=b
∫
N 2 (x, y)
f (x, y) dxdy
−
N 3 (x, y)
x =−a y=−b
N 4 (x, y)
In the above, we have the from Ii = −ki {ũ} d Ω − {ũ} fi d Ω, hence the element stiffness matrix is
∫ ∫
Ω Ω
the first integral, and the force vector comes from the second integral.
The integration is now carried out to obtain the element stiffness matrix. This was done using Mathe-
matica. The local stiffness matrix for element i is
x∫=a y=b
∂w ∂ũ
∫
ki = dxdy
∂x i ∂x i
x =−a y=−b
a 2 +b 2 a b
− a6ab
+b a b
2 2
© 3ab 6b − 3a − 3b + 6a ª
a − b a 2 +b 2 a
− 3b b
+ 6a − a6ab
2 +b 2 ®
= 6b a 2 +b3a2 3ab
®
a b a 2 +b 2 a b ®
− 6ab
− 3b + 6a 3ab 6b − 3a ®
®
a b
− a6ab +b a b a 2 +b 2
2 2
«− 3b + 6a 6b − 3a 3ab ¬
2
© 3 − 16 − 13 − 16 ª
− 1 2
− 16 − 13 ®®
ki = 61 3
− 16 2
− 16 ®®
®
− 3 3
1
«− 6 − 13 − 16 2
3 ¬
1 ClearAll[a, b];
2 area = 4 a b;
3 phi = (1/area) {(a - x) (b - y),
4 (a + x) (b - y),
5 (a + x) (b + y),
6 (a - x) (b + y)};
7 vx = {{D[phi[[1]], x]},
8 {D[phi[[2]], x]},
9 {D[phi[[3]], x]},
10 {D[phi[[4]], x]}};
11 vy = {{D[phi[[1]], y]},
12 {D[phi[[2]], y]},
13 {D[phi[[3]], y]},
14 {D[phi[[4]], y]}};
15 k = Integrate[vx.Transpose[vx]+vy.Transpose[vy],{x, -a, a}, {y, -b, b}]
a 2 +b 2 a 2 2
6b
- 3ba - a6 +b
ab
- 3ab + b
6a
3ab
a a 2 +b 2 a 2 +b 2
6b
- 3ba - 3ab + b
6a
- 6ab
3ab
a 2 +b 2 a 2 +b 2
- 6ab
- 3ab + 6ba a
6b
- 3ba
3ab
a 2 +b 2 a 2 +b 2
- 3ab + b
6a
- 6ab
a
6b
- 3ba
3ab
Hence
201
ũ 1
N 1 (x, y)
x∫=a y=b
ũ 2 N 2 (x, y)
∫
Ii = −ki f (x, y) dxdy
−
ũ 3 N 3 (x, y)
x =−a y=−b
ũ 4 N 4 (x, y)
N 1 (x, y)
x∫=a y=b
N (x, y)
∫
f 2
Ii = f (x, y) dxdy
N 3 (x, y)
x =−a y=−b
N 4 (x, y)
A (a − x) (b − y)
1
x∫=a y=b
∫ 1 (a + x) (b − y)
= A f (x, y) dxdy
1 (a + x) (b + y)
A
x =−a y=−b
A1 (a − x) (b + y)
In the above, the integration depends on the physical location of the element. We used a local coordinate
system initially to obtain the shape functions. This has now to be transformed to the global coordinates
system. Taking the center of each element as (x 0, y0 ) then we need to replace a → x 0 + a and b → y0 +b
everywhere in the above integral. We did not have to do this for finding the local stiffness matrix, since
that did not depend on the physical location of the element (it was constant). But for the integration of
the force function, we need to do this mapping. In the code, the center of each element is found, and
the replacement is done.
f (x, y) = xy
For f (x, y) = xy the above gives a result as function of the center of the physical element.
1
A ((x 0 − a) − x) (y0 + b − y)
∫0 +a y=y∫0 +b
x =x
((x 0 − a) + x) (y0 + b − y)
1
f A
Ii = xy dxdy
A ((x 0 − a) + x) (y 0 + b + y)
1
x =(x 0 −a) y=(y0 −b)
1 ((x − a) − x) (y + b + y)
A
0 0
a 2b 2 (a − 3x 0 ) (b − 3y0 )
−ab a + 3ax 0 + 6x 0 (b − 3y0 )
2 2 2
1
f
Ii =
9 (x 0 + a) (y0 + b) ab a 2 + 3ax 0 + 6x 02 b 2 + 3by0 + 6y02
2 b 2 + + y 2
−ab (a − 3x 0 ) 3by 0 0
In[134]:= phi
Out[134]= {((a - x)*(b - y))/(4*a*b),
((a + x)*(b - y))/(4*a*b),
((a + x)*(b + y))/(4*a*b),
((a - x)*(b + y))/(4*a*b)}
Out[135]= {
202
Out[136]= {
(a^2*b^2*(a - 3*x0)*(b - 3*y0))/(9*(a + x0)*(b + y0)),
-((a*b^2*(a^2 + 3*a*x0 + 6*x0^2)*(b - 3*y0))/(9*(a + x0)*(b + y0))),
(a*b*(a^2 + 3*a*x0 + 6*x0^2)*(b^2 + 3*b*y0 + 6*y0^2))/(9*(a + x0)*(b + y0)),
-((a^2*b*(a - 3*x0)*(b^2 + 3*b*y0 + 6*y0^2))/(9*(a + x0)*(b + y0)))}
\end{X311}
f (x, y) = 1
1
A ((x 0 − a) − x) (y0 + b − y)
∫0 +a y=y∫0 +b
x =x
1 ((x − a) + x) (y + b − y)
f A 0 0
Ii = dxdy
A ((x 0 − a) + x) (y 0 + b + y)
1
x =(x 0 −a) y=(y0 −b)
A1 ((x 0 − a) − x) (y0 + b + y)
This was done using Mathematica
a 2b 2
(a+x 0 )(b+y0 )
ab (a+2x 0 )
2
f (a+x 0 )(b+y0 )
Ii =
ab(a+2x 0 )(b+2y0 )
(a+x 0 )(b+y0 )
a b(b+2y0 )
2
(a+x 0 )(b+y0 )
1 phi /. {a :> (x0 + a), b :> (y0 + b)}
2 Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + b}]
203
Now that the local ki and local fi are calculated, the next step is to assemble them to the global stiffness
and global force vector. For 1D this process was easy and direct. For higher dimensions we need to
make a table of mapping to help in the process. The following diagram shows this mapping table and
how it is applied in this example. The mapping table will have as many rows as there are elements, and
will have as many columns as the number of nodes per element. Hence in this example it will a matrix
of size 9 × 4. Each row gives the global node number for each local node number of that element. For
example, for element 1 the first row will show the global node number for each of the local nodes for
the first element.
Local node numbers are always incremented counter clockwise, starting from 1 to 4 in this case.
Global node numbering
1 2 3 4 13 14 15 16
1 1 2 6 5 7 8 9
10 11
9 12
2 2 3 7 6
4 5 6
3 3 4 8 7 6
5 7 8
4 4 6 10 9 1 2 3
5 6 7 11 10
1 2 3 4
6 7 8 12 11
7 9 10 14 13
4 3
8 10 11 15 14
i
9 11 12 16 15
1 2
Local node numbering for
Mapping from local to global element i
node numbering based on
element number. Used to fill
in the global stiffness matrix
Now that we have the mapping done, we can now assemble the global stiffness and vector matrix and
solve for the unknowns.
To evaluate the force vector, we also need a table of physical coordinates of the center of each element
relative to the origin of the global coordinates system, since the force vector integration depends on
physical coordinates.
The integration was carried out off-line as shown above, but it was done in terms of physical coordinates
of center of the element. The following diagram shows the mapping table of physical coordinates to
elements. This uses (0, 0) as the origin and the coordinates of the lower left corner of the global coordinate
system. Hence the coordinate the top right corner of the global grid will be (3h, 3h) where h is the grid
spacing.
y
Global node numbering
1 a b 7 8 9
10 11
9 12
2 3a b
4 5 6
3 5a b 6
5 7 8
4 a 3b 1 2 3
5 3a 3b X
1 2 3 4
6 5a 3b 0, 0 6a, 0
7 a 5b a
4 3
8 3a 5b b
9 5a 5b
1 2
Mapping from element number to physical
coordinate of the center of element Local node numbering for
element i
Now the solution can start. We loop over each element and fill in the global stiffness matrix using the
mapping above, and also evaluate the global force vector using the physical coordinates.
When the global stiffness matrix and the global force vector is filled, we adjust the global stiffness
204
matrix by putting zero in the row numbered i that correspond to the edge node i, and by putting 1 in
the diagonal entry (i, i). We also put a zero in the force vector for each node on the boundary conditions
since we are using Dirichlet boundary conditions which is zero. When this is done, the system Ax = f
is then solved for x where x now is the displacement or value of y at the nodes. The following is an
implementation of the above.
1 function matlab_97()
2 close all; clear all;
3
4 number_of_elements=[16 64 256 625];
5 function_string={'1','xy','3(\cos(4\pi x)+\sin(3 \pi y))'};
6 function_handles={@f_1,@f_xy,@f_2};
7
8 figure_image_file={'matlab_e97_1','matlab_e97_2','matlab_e97_3'};
9
10 for i=1:length(function_handles)
11 for j=1:length(number_of_elements)
12 plot_file=sprintf('%s_%d',figure_image_file{i},...
13 number_of_elements(j));
14 close all;
15 solve_poisson_2D_square(function_handles{i},...
16 function_string{i},number_of_elements(j),plot_file);
17 end
18 end
19 end
20
21 %----------------------------------
22 function k_local=getk(a,b)
23
24 k11=(a^2+b^2)/(3*a*b);
25 k12=a/(6*b)-b/(3*a);
26 k13=-(a^2+b^2)/(6*a*b);
27 k14=-a/(3*b)+b/(6*a);
28 k_local = [k11 k12 k13 k14;
29 k12 k11 k14 k13;
30 k13 k14 k11 k12;
31 k14 k13 k12 k11];
32 end
33 %----------------------------------------------------
34 %use this for f(x,y)=x*y
35 function f_local=f_xy(x0,y0,a,b)
36
37 f_local=1/(9*(a + x0)*(b + y0))*...
38 [a^2*b^2*(a-3*x0)*(b -3*y0);
39 -a*b^2*(a^2 + 3*a*x0 + 6*x0^2)*(b - 3*y0);
40 a*b*(a^2 + 3*a*x0 + 6*x0^2)*(b^2 + 3*b*y0 + 6*y0^2);
41 -a^2*b*(a - 3*x0)*(b^2 + 3*b*y0 + 6*y0^2)...
42 ];
43 end
44 %----------------------------------------------------
45 %use this for f(x,y)=1
46 function f_local=f_1(x0,y0,a,b)
47
48 f_local=[(a^2*b^2)/((a + x0)*(b + y0));
49 (a*b^2*(a + 2*x0))/((a + x0)*(b + y0));
50 (a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0));
51 (a^2*b*(b + 2*y0))/((a + x0)*(b + y0))];
52
53 end
54 %----------------------------------------------------
55 %use this for f(x,y)= 3(cos(4 pi x)+sin(3 pi y))
56 function f_local=f_2(x0,y0,a,b)
57 f_local=[(1/(96*pi^2*(a + x0)*(b + y0)))*...
58 (9*b^2*cos(4*pi*(-a + x0)) -...
59 9*b^2*cos(4*pi*(a + x0)) + ...
60 8*a*(12*a*b*pi*cos(3*pi*(b - y0)) -...
61 9*b^2*pi*sin(4*pi*(-a + x0)) - ...
62 2*a*(sin(3*pi*(b - y0)) +...
63 sin(3*pi*(b + y0)))));
64 (1/(96*pi^2*(a + x0)*(b + y0)))*...
65 (-9*b^2*cos(4*pi*(-a + x0)) + 9*b^2*cos(4*pi*(a + x0)) +...
66 8*(12*a*b*pi*(a + 2*x0)*cos(3*pi*(b - y0)) -...
67 9*b^2*pi*x0*sin(4*pi*(-a + x0)) + ...
68 9*a*b^2*pi*sin(4*pi*(a + x0)) +...
69 9*b^2*pi*x0*sin(4*pi*(a + x0)) - 2*a^2*sin(3*pi*(b - y0)) -...
70 4*a*x0*sin(3*pi*(b - y0)) - 2*a^2*sin(3*pi*(b + y0)) -...
71 4*a*x0*sin(3*pi*(b + y0))));
72 (1/(96*pi^2*(a + x0)*(b + y0)))*...
205
151 set(gcf,'defaulttextinterpreter','latex');
152 plot_title=sprintf('$\\nabla^2 u=%s$, number of elements $%d$',rhs,M);
153 title(plot_title,'fontweight','bold','fontsize',14);
154
155 print(gcf, '-dpdf', '-r300', ['images/',plot_file]);
156 print(gcf, '-dpng', '-r300', ['images/',plot_file]);
157
158 figure;
159 [C,h] = contourf(X,Y,Z);
160 clabel(C,h)
161 set(gcf,'defaulttextinterpreter','latex');
162 title(plot_title,'fontweight','bold','fontsize',14);
163 colormap cool
164 print(gcf, '-dpdf', '-r300', ['images/',[plot_file,'_c']]);
165 print(gcf, '-dpng', '-r300', ['images/',[plot_file,'_c']]);
166
167 end
168 %----------------------------------------------------
169 function mtb=generate_coordinates_table(M)
170 %M=number_of_elements_per_row
171 mtb=zeros(M^2,4);
172 for i=1:M
173 for j=1:M
174 mtb(j+M*(i-1),:) =[j j+1 j+(M+2) j+(M+1)]+(M+1)*(i-1);
175 end
176 end
177 end
178 %----------------------------------------------------
179 function fmtb=generate_physical_coordinates_table(M,a,b)
180 %2a is width of element
181 %2b is height of element
182 %M=number_of_elements_per_row
183 fmtb=zeros(M^2,2);
184 for i=1:M
185 for j=1:M
186 fmtb(j+M*(i-1),:) = [(2*j-1)*a (2*i-1)*b];
187 end
188 end
189 end
Here is the output for the three force functions, for different number of elements.
4.16.3 f (x, y) = 1
207
4.16.4 f (x, y) = xy
41 %----------------------------------------------------
42 %use this for f(x,y)=x*y
43 function f_local=f_xy(x0,y0,a,b)
44
45 f_local=1/(9*(a + x0)*(b + y0))*...
46 [a^2*b^2*(a-3*x0)*(b -3*y0);
47 -a*b^2*(a^2 + 3*a*x0 + 6*x0^2)*(b - 3*y0);
48 a*b*(a^2 + 3*a*x0 + 6*x0^2)*(b^2 + 3*b*y0 + 6*y0^2);
49 -a^2*b*(a - 3*x0)*(b^2 + 3*b*y0 + 6*y0^2)...
50 ];
51 end
52 %----------------------------------------------------
53 %use this for f(x,y)=1
54 function f_local=f_1(x0,y0,a,b)
55
56 f_local=[(a^2*b^2)/((a + x0)*(b + y0));
57 (a*b^2*(a + 2*x0))/((a + x0)*(b + y0));
58 (a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0));
59 (a^2*b*(b + 2*y0))/((a + x0)*(b + y0))];
60
61 end
62 %----------------------------------------------------
63 %use this for f(x,y)= 3(cos(4 pi x)+sin(3 pi y))
64 function f_local=f_2(x0,y0,a,b)
65 f_local=[(1/(96*pi^2*(a + x0)*(b + y0)))*...
66 (9*b^2*cos(4*pi*(-a + x0)) -...
67 9*b^2*cos(4*pi*(a + x0)) + 8*a*(12*a*b*pi*cos(3*pi*(b - y0)) -...
68 9*b^2*pi*sin(4*pi*(-a + x0)) - 2*a*(sin(3*pi*(b - y0)) +...
69 sin(3*pi*(b + y0)))));
70 (1/(96*pi^2*(a + x0)*(b + y0)))*...
71 (-9*b^2*cos(4*pi*(-a + x0)) + 9*b^2*cos(4*pi*(a + x0)) +...
72 8*(12*a*b*pi*(a + 2*x0)*cos(3*pi*(b - y0)) -...
73 9*b^2*pi*x0*sin(4*pi*(-a + x0)) + ...
74 9*a*b^2*pi*sin(4*pi*(a + x0)) +...
75 9*b^2*pi*x0*sin(4*pi*(a + x0)) - 2*a^2*sin(3*pi*(b - y0)) -...
76 4*a*x0*sin(3*pi*(b - y0)) - 2*a^2*sin(3*pi*(b + y0)) -...
77 4*a*x0*sin(3*pi*(b + y0))));
78 (1/(96*pi^2*(a + x0)*(b + y0)))*...
79 (-9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) + 9*b*(b + 2*y0)*...
80 cos(4*pi*(a + x0)) -...
81 72*b*pi*x0*(b + 2*y0)*sin(4*pi*(-a + x0)) + ...
82 72*b*pi*(a + x0)*(b + 2*y0)*...
83 sin(4*pi*(a + x0)) + 12*(a + x0)^2*(6*pi*y0*...
84 cos(3*pi*(b - y0)) -...
85 6*pi*(b + y0)*cos(3*pi*(b + y0)) + ...
86 sin(3*pi*(b - y0)) +...
87 sin(3*pi*(b + y0))) - 4*(-a + x0)*(a + 3*x0)*...
88 (6*pi*y0*cos(3*pi*(b - y0)) -...
89 6*pi*(b + y0)*cos(3*pi*(b + y0)) + ...
90 sin(3*pi*(b - y0)) +...
91 sin(3*pi*(b + y0))));
92 (1/(96*pi^2*(a + x0)*(b + y0)))*...
93 (9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) - 9*b*(b + 2*y0)*...
94 cos(4*pi*(a + x0)) +...
95 8*a*(12*a*pi*y0*cos(3*pi*(b - y0)) - 12*a*pi*(b + y0)*...
96 cos(3*pi*(b + y0)) -...
97 9*b^2*pi*sin(4*pi*(-a + x0)) - 18*b*pi*y0*sin(4*pi*(-a + x0)) +...
98 2*a*sin(3*pi*(b - y0)) + 2*a*sin(3*pi*(b + y0))))];
99
100 end
101 %----------------------------------------------------
102 function solve_poisson_2D_square(fh,rhs,M,Lx,Ly,plot_file)
103 %fh is function which evaluate the force vector
104 %rhs is string which is the f(x,y), for plotting only
105 %M=number of element per unit length
106 %Lx=length in x-direction
107 %Ly=length in y-direction
108 N = 4; %number of nodes per element
109 Mx=M*Lx;
110 My=M*Ly;
111 a=(1/M)/2;
112 b=a;
113 k_local=getk(a,b);
114 dof=4;
115
116 nodes = (Mx+1)*(My+1); %total number of nodes
117 kk = zeros(nodes); %global stiffness vector
118 f = zeros(nodes,1); %global force vector
210
197 end
198 end
Here is the output for the three force functions, for different number of elements.
4.16.7 f (x, y) = 1
4.16.8 f (x, y) = xy
212
13 14 15 16
18
14 16
15 17
13
10 11
9 12
3
8 10 12
element
7 9 11
1 2 6 7
5 2
1 3 2 13 2 1
8
3
2 4 6
1 3 5
1 3 1 3 1 3
2 2 2
1 2 3 4
x 3, y 3
3
1 2
x 1, y 1 x 2, y 2
area
1
A 2
x 1y 2 y 3 x 2y 3 y 1 x 3y 1 y 2
ũ = c 1 + c 2x + c 3y (1)
Evaluating the trial function (1) at each corner node of the above element gives
ũ 1 = c 1 + c 2x 1 + c 3y1
ũ 2 = c 1 + c 2x 2 + c 3y2
ũ 3 = c 1 + c 2x 3 + c 3y3
Hence
ũ 1 x 1 y1 c 1
© 1ª ©
ũ 2 ® = 1 x 2 y2 ® c 2 ®
ª© ª
® ® ®
«ũ 3 ¬ «1 x 3 y3 ¬ «c 3 ¬
215
Therefore
−1
c 1 x 1 y1 ũ
© 1ª © © 1ª
c 2 ® = 1 x 2 y2 ®
ª
ũ 2 ®
® ® ®
c
« 3¬ « 1 x 3 y 3¬ «ũ 3 ¬
x 2y3 − x 3y2 x 3y1 − x 1y3 x 1y2 − y1x 2 ũ 1
1 ©
=
ª© ª
y2 − y3 y3 − y1 y1 − y2 ®® ũ 2 ®® (2)
|D|
« x3 − x2 x1 − x3 x 2 − x 1 ¬ «ũ 3 ¬
1 x 1 y1
Where |D| is the determinant of 1 x 2 y2 ®® which is |D| = −y1x 2 + x 3y1 + x 1y2 − x 3y2 − x 1y3 + x 2y3 .
© ª
«1 x 3 y3 ¬
This quantity is twice the area of the triangle A = 1
2 (x 1 (y2 − y3 ) + x 2 (y3 − y1 ) + x 3 (y1 − y2 )).
Substituting (2) into (1) in order to find the shape functions gives
ũ = c 1 + c 2x + c 3y
1
= [(x 2y3 − x 3y2 ) ũ 1 + (x 3y1 − x 1y3 ) ũ 2 + (x 1y2 − y1x 2 ) ũ 3 ]
2A
1
+ [(y2 − y3 ) ũ 1 + (y3 − y1 ) ũ 2 + (y1 − y2 ) ũ 3 ] x
2A
1
+ [(x 3 − x 2 ) ũ 1 + (x 1 − x 3 ) ũ 2 + (x 2 − x 1 ) ũ 3 ] y
2A
1
ũ = ũ 1 ((x 2y3 − x 3y2 ) + (y2 − y3 ) x + (x 3 − x 2 ) y)
2A
1
+ ũ 2 ((x 3y1 − x 1y3 ) + (y3 − y1 ) x + (x 1 − x 3 ) y)
2A
1
+ ũ 3 ((x 1y2 − y1x 2 ) + (y1 − y2 ) x + (x 2 − x 1 ) y)
2A
Hence
1
N 1 (x, y) = ((x 2y3 − x 3y2 ) + (y2 − y3 ) x + (x 3 − x 2 ) y)
2A
1
N 2 (x, y) = ((x 3y1 − x 1y3 ) + (y3 − y1 ) x + (x 1 − x 3 ) y)
2A
1
N 3 (x, y) = ((x 1y2 − y1x 2 ) + (y1 − y2 ) x + (x 2 − x 1 ) y)
2A
Now that the shape functions are found, the test or weight function w (x, y) can be found. Since
w i (x, y) = ∂∂ũũi for i = 1, 2, 3, therefore this results in
∫ ©N 1 (x, y)ª
∂Ni ∂N j ∂Ni ∂N j ∂ũ
∫ ∫ ∫
Ii = − dΩ − dΩ + w dΓ − N 2 (x, y)® f (x, y) d Ω
∂x ∂x ∂y ∂y ∂n ®
Ω Ω Γ Ω «N 3 (x, y)¬
216
Hence
1 ∂N (x ,y) ũ 1
∫ © ∂x o
Ii = − ∂N∂x
2 (x ,y) ® ∂N 1 (x ,y) ∂N 2 (x ,y) ∂N 3 (x ,y)
ªn
ũ 2 d Ω
® ∂x ∂x ∂x
∂N 3 (x ,y)
Ω « ũ 3
∂x ¬
∂N 1 (x ,y) ũ 1
∫ © ∂y ª n o
∂N (x ,y) ® ∂N1 (x ,y) ∂N2 (x ,y) ∂N 3 (x ,y)
ũ 2 d Ω
− 2∂y ® ∂y ∂y ∂y
∂N (x ,y) ®
Ω 3 ũ 3
« ∂y ¬
∫ ©N 1 (x, y)ª ũ
1
∂ũ
+ N 2 (x, y)®® ũ 2 dΓ
∂n
Γ «N 3 (x, y)¬ ũ 3
∫ ©N 1 (x, y)ª
− N 2 (x, y)®® f (x, y) d Ω
Ω «N 3 (x, y)¬
Since w = 0 on the boundary with Dirichlet conditions, and since there are no natural boundary
conditions, the above simplifies to
∂N (x ,y)
∫ © ∂x 1
ũ 1
o
∂N
2 (x ,y) ® ∂N 1 (x ,y) ∂N 2 (x ,y) ∂N 3 (x ,y)
ªn
Ii = − ∂x ũ 2 d Ω
® ∂x ∂x ∂x
∂N 3 (x ,y)
Ω « ũ 3
∂x ¬
∂N 1 (x ,y)
∫ © ∂y ª n ũ N (x, y)
1 © 1
∫
∂N (x ,y) ® ∂N1 (x ,y) ∂N 2 (x ,y) ∂N 3 (x ,y)
o
d Ω ũ 2 − N 2 (x, y)® f (x, y) d Ω
ª
− 2∂y ® ∂y ∂y ∂y ®
∂N (x ,y) ®
Ω 3 ũ 3 N y)
Ω (x,
« 3
« ∂y ¬ ¬
Now each integral is calculated for the triangle element. First the derivatives are found
∂N (x ,y)
1
(y − y3 )
© ∂N∂x © 2
2 (x ,y) ® = 1 (y3 − y1 )®
ª ª
∂x ® 2A ®
∂N 3 (x ,y)
« ∂x ¬ (y
« 1 − y )
2 ¬
and
∂N 1 (x ,y)
© ∂y ª (x 3 − x 2 )
∂N2 (x ,y) ® 1 ©
∂y ® =
ª
(x 1 − x 3 )®®
∂N (x ,y) ® 2A
«(x 2 − x 1 )¬
3
« ∂y ¬
Hence
∂N 1 (x ,y)
© ∂N∂x ∂Ni ∂N j
2 (x ,y) ® ∂N1 (x ,y) ∂N 2 (x ,y) ∂N 3 (x ,y)
ªn o
∂x ® ∂x ∂x ∂x
=
∂N 3 (x ,y) ∂x ∂x
« ∂x ¬
(y2 − y3 )2 (y2 − y3 ) (y3 − y1 ) (y2 − y3 ) (y1 − y2 )
1 ©
=
ª
(y3 − y1 ) (y2 − y3 ) (y3 − y1 )2 (y3 − y1 ) (y1 − y2 )®®
(2A)2
«(y1 − y2 ) (y2 − y3 ) (y1 − y2 ) (y3 − y1 ) (y1 − y2 )2 ¬
And
∂N 1 (x ,y)
© ∂y ª n
∂N2 (x ,y) ® ∂N1 (x ,y) ∂N 2 (x ,y) ∂N 3 (x ,y)
o ∂Ni ∂N j
∂y ® ∂y ∂y ∂y =
∂N 3 (x ,y)
® ∂y ∂y
« ∂y ¬
(x 3 − x 2 )2 (x 3 − x 2 ) (x 1 − x 3 ) (x 3 − x 2 ) (x 2 − x 1 )
1
=
©
(x 1 − x 3 )2
ª
(x 1 − x 3 ) (x 3 − x 2 ) (x 1 − x 3 ) (x 2 − x 1 )®®
(2A)2
«(x 2 − x 1 ) (x 3 − x 2 ) (x 2 − x 1 ) (x 1 − x 3 ) (x 2 − x 1 )2 ¬
217
We see the above terms do not depend on x nor on y. Hence the next integration is done over the area
of the triangle as follow
ũ ũ
1
∂Ni ∂N j 1
∂Ni ∂N j
∫
∫
ũ 2 d Ω = dΩ
ũ 2
∂x ∂x ∂x ∂x
Ω ũ 3
ũ 3
Ω
ũ ũ
1
∂Ni ∂N j 1
∂Ni ∂N j
∫
ũ 2 d Ω = ũ 2 A
∂x ∂x ∂x ∂x
Ω ũ 3
ũ 3
∂N i ∂N j
Replacing ∂x ∂x by the expression we found for it above, gives
ũ ũ
1
∂Ni ∂N j 1
∂Ni ∂N j
∫
∫
ũ 2 d Ω = dΩ
ũ 2
∂y ∂y ∂y ∂y
Ω ũ 3
ũ 3 Ω
ũ ũ
1
∂Ni ∂N j 1
∂Ni ∂N j
∫
ũ 2 d Ω = ũ 2 A
∂y ∂y ∂y ∂y
Ω ũ 3
ũ 3
∂N i ∂N j
Replacing ∂y ∂y by the expression we found for it above, gives
ũ (x 3 − x 2 )2 (x 3 − x 2 ) (x 1 − x 3 ) (x 3 − x 2 ) (x 2 − x 1 ) ũ 1
∂Ni ∂N j 1 A
∫
ª
ũ 2 d Ω =
©
(x 1 − x 3 ) (x 3 − x 2 ) (x 1 − x 3 )2
(x 1 − x 3 ) (x 2 − x 1 ) ® ũ 2
∂x ∂x (2A)2 ®
Ω ũ 3
(x 2 − x 1 ) (x 3 − x 2 ) (x 2 − x 1 ) (x 1 − x 3 ) (x 2 − x 1 ) 2 ũ 3
« ¬
(x 3 − x 2 )2 (x 3 − x 2 ) (x 1 − x 3 ) (x 3 − x 2 ) (x 2 − x 1 ) ũ 1
1 ©
=
ª
(x 1 − x 3 ) (x 3 − x 2 ) (x 1 − x 3 ) 2
(x 1 − x 3 ) (x 2 − x 1 ) ® ũ 2 (4)
4A ®
«(x 2 − x 1 ) (x 3 − x 2 ) (x 2 − x 1 ) (x 1 − x 3 ) (x 2 − x 1 ) ¬ ũ 3
2
or
And the final integral (the force vector) depends on the nature of f (x, y). For f (x, y) = 1 we obtain
And similarly for other f (x, y). These were all integrated off-line and the resulting expression eval-
uated during the run of the program. These expression are all functions of the node coordinates
(x 1, y1, x 2, y2, x 3, y3 ). No actual integration is done in the code, but only evaluation of the integration
result obtained. The integration was done using Mathematica. These are the results for the three func-
tions of interest. The integration was done on two triangles. The odd numbered ones and the even
numbered ones due to the node numbering difference. For odd numbered triangles, the integration
x∫2 y3∫−x x∫1 y2∫−x
limits are dydx while on the even numbered elements the limits are dydx as shown in this
x 1 y1 x 2 y1
diagram
y
Odd numbered
triangle Even numbered
integration triangle 13 14 15 16
integration
x 3, y 3 14 16
18
3 x 2, y 2 x 1, y 1
y
17
2 1 13 15
10 11
y3
9 12
x
3
8 10 12
y
1 2 3 element
y2
9
x 1, y 1 x 2, y 2 x 3, y 3 7 11
6 7
x
1 2
5 2
1 3 2 13 2 1
8
3
x 2 y 3 x x 2 y 2 x 2 4 6
dydx dydx 1
1
2
3 1
3
3 1
5
3
x1 y1 x1 y1 (0,0)
1 2
2 2
4 X
3
Global node number
Note that this is not how integration is normally done in actual finite element methods. Using Gaussian
quadrature method is the recommended way. This method was done here for learning and to compare.
4.17.1 f (x, y) = 1
For odd numbered elements
1 n1 = (1/(2*area))*((x2*y3 - x3*y2) + (y2 - y3)*x + (x3 - x2)*y);
2 n2 = (1/(2*area))*((x2*y1 - x1*y3) + (y3 - y1)*x + (x1 - x3)*y);
3 n3 = (1/(2*area))*((x1*y2 - y1*x2) + (y1 - y2)*x + (x2 - x1)*y);
4 w = {{n1}, {n2}, {n3}};
5 Integrate[w, {x, x1, x2}, {y, y1, y3 - x}]
1, 2, 3
1 1 2 5
2 6 5 2
3 2 3 6 13 14 15 16
4 7 6 3 14 16
18
5 3 4 7 13 15 17
10 11
6 8 7 4 9
3
12
8 10 12
7 5 6 9 element
7 9 11
8 10 9 6 5
1
2
2 6 7
8
3 1 3 2 13 2 1
2 4
9 6 7 10 6
1 3 5
10 11 10 7 1 2
3 1
2
3 1
2
3
11 7 8 11 1 2 3 4
13 9 10 13
14 14 13 10
15 10 11 14
16 15 14 11
17 11 12 15
18 16 15 12
Element Global node numbers
numbers mapping
The mapping of physical coordinate location relative to the global frame of reference is shown below
220
x 1, y 1, x 2, y 2, x 3, y 3
1 0 0 h 0 0 h
2 h h 0 h h 0
y
3 h 0 2h 0 h h
4 2h h h h 2h 0
13 14 15 16
5 2h 0 3h 0 2h h
6 3h h 2h h 3h 0
18
14 16
17
7 0 h h h 0 2h 13
10
15
11
9 12
8 h 2h 0 2h h h 3
8 10 12
9 h h 2h h h 2h element
7 9 11
10 2h 2h h 2h 2h h 1 2 6 7
5 2
1 3 2 13 2 1
8
3
11 2h h 3h h 2h 2h 2 4
h 6
12 3h 2h 2h 2h 3h h 1
1
3 1
3
3 1
5
3
13 0 2h h 2h 0 3h (0,0)
2
2
2 2
4
X
1 3
14 h 3h 0 3h h 2h h Global node number
15 h 2h 2h 2h h 3h
16 2h 3h h 3h 2h 2h
17 2h 2h 3h 2h 2h 3h
18 3h 3h 2h 3h 3h 2h
Element (x,y)
number coordinates of
nodes 1,2,3 of
each element
1 function matlab_98()
2 close all; clear all;
3 number_of_elements=[16*2 64*2 256*2 625*2];
4 function_string={'1'};
5 %function_handles={@f_1,@f_xy,@f_2};%something wrong with the other
6 %cases, need to work more on it.
7 function_handles={@f_1};
8 figure_image_file={'matlab_e98_1'};
9
10 for i=1:length(function_handles)
11 for j=1:length(number_of_elements)
12 plot_file=sprintf('%s_%d',figure_image_file{i},...
13 number_of_elements(j));
14 close all;
15 solve_poisson_2D_square(function_handles{i},...
16 function_string{i},number_of_elements(j),plot_file);
17 end
18 end
19 end
20
21 %----------------------------------
22 function k_local=getk(area,x1,y1,x2,y2,x3,y3)
23
24 k11=(y2-y3)^2+(x3-x2)^2;
25 k12=(y2-y3)*(y3-y1)+(x3-x2)*(x1-x3);
26 k13=(y2-y3)*(y1-y2)+(x3-x2)*(x2-x1);
27 k22=(y3-y1)^2+(x1-x3)^2;
28 k23=(y3-y1)*(y1-y2)+(x1-x3)*(x2-x1);
29 k33=(y1-y2)^2+(x2-x1)^2;
30 k_local = [k11 k12 k13;
31 k12 k22 k23;
32 k13 k23 k33];
33
34 k_local = k_local/(4*area);
35 end
36 %----------------------------------------------------
37 %use this for f(x,y)=1
38 function f_local=f_1(area,x1,y1,x2,y2,x3,y3,ele)
39
40 if mod(ele,2)
41 f_local=[(1/(12*area))*((x1 - x2)*(x2^3 + x1^2*...
42 (x2 - x3 + 2*y2 - 2*y3) +...
43 3*x3*(y1 - y3)*(y1 - 2*y2 + y3) - x2^2*(x3 - 2*y2 + 2*y3) -...
44 3*x2*(y1^2 + x3*y2 - x3*y3 + y2*y3 - y1*(y2 + y3)) + x1*(x2^2 -...
45 3*(y2 - y3)*(x3 - y1 + y3) - x2*(x3 - 2*y2 + 2*y3))));
46 -((1/(12*area))*((x1 - x2)*(x1^3 + x1^2*(x2 - x3 + 2*y1 - 2*y3) -...
47 3*x3*(y1 - y3)^2 - 3*x2*(y1 - y3)*(x3 - y1 + y3) -...
48 x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 + 3*x3*(-y1 + y3) -...
49 x2*(x3 - 2*y1 + 2*y3)))));
50 ((x1 - x2)^2*(x1^2 + x2^2 + x1*(x2 + 2*y1 + y2 - 3*y3) +...
51 x2*(y1 + 2*y2 - 3*y3) + 3*(y1 - y3)*(y2 - y3)))/(12*area)];
52 else
53 f_local=[((x1 - x2)*(x2^3 + 3*x3*(y1 - y2)^2 + x1*(x2^2 +...
54 3*(y1 - y2)*(y2 - y3) - x2*(x3 + y2 - y3)) + x1^2*...
55 (x2 - x3 + 2*y2 - 2*y3) -...
56 3*x2*(y1 - y2)*(y1 - y3) - x2^2*(x3 + y2 - y3)))/(12*area);
57 -((1/(12*area))*((x1 - x2)*(x1^3 - 3*x3*(y1 - y2)^2 -...
58 3*x2*(y1 - y2)*(x3 - y1 + y3) + x1^2*...
59 (x2 - x3 + 2*y1 - 3*y2 + y3) -...
221
138
139 print(gcf, '-dpdf', '-r300', ['images/',plot_file,'_c']);
140 print(gcf, '-dpng', '-r300', ['images/',plot_file,'_c']);
141
142 end
143 %----------------------------------------------------
144 function A=generate_coordinates_table(M)
145 %M=number_of_elements
146 A=zeros(M,3);
147 n=2*sqrt(M/2); %number of elements per row
148
149 for i=1:n/2
150 for j=1:n
151 ele=j+n*(i-1);
152 if j==1
153 A(ele,:)=[(n/2+1)*(i-1)+1 (n/2+1)*(i-1)+2 (n/2+1)*i+1];
154 else
155 if mod(j,2)
156 A(ele,:) =[A(ele-1,3) A(ele-1,3)+1 A(ele-1,1)];
157 else
158 A(ele,:) =[A(ele-1,3)+1 A(ele-1,3) A(ele-1,2)];
159 end
160 end
161 end
162 end
163 end
164 %----------------------------------------------------
165 function A=generate_physical_coordinates_table(M,h)
166 %M=number_of_elements
167 A=zeros(M,6);
168 n=2*sqrt(M/2); %number of elements per row
169
170 for i=1:n/2
171 for j=1:n
172 ele=j+n*(i-1);
173 if j==1
174 A(ele,:)=[0 (i-1)*h h (i-1)*h 0 i*h];
175 else
176 if mod(j,2)
177 A(ele,:) =[A(ele-1,5) A(ele-1,6) ...
178 A(ele-1,5)+h A(ele-1,6) A(ele-1,1) A(ele-1,2)];
179 else
180 A(ele,:) =[A(ele-1,5)+h A(ele-1,6) ...
181 A(ele-1,5) A(ele-1,6) A(ele-1,3) A(ele-1,4)];
182 end
183 end
184 end
185 end
186 end
Here is the output for the three force functions, for different number of elements.
4.17.3 f (x, y) = 1
223
hline
0.5
-0.5
-1.0
Matlab
1 %Nasser M. Abbasi July 8, 2014
2 %solve u_tt = wave_speed * u_xx using leap frog
3 % 0<x<1
4 % initial data is f(x)
5 % initial speed = 0;
6 % fixed at x=0 and x=1
7
8 close all;
9 nPoints = 100;
10 speed = 351;
11 f = @(x) sin(2*pi*(x-0.2)/0.4).*(x>0.2&x<=0.6)
12 coord = linspace(0,1,nPoints);
13 ic = f(coord);
14 h = 1/(nPoints-1);
15 delT = h/speed;
16 last = ic;
17 now = last;
18 next = now;
19 nSteps = 500;
20
21 for n=1:nSteps
22 if n==1
23 next(2:end-1) = 1/2*(now(1:end-2)+now(3:end));
24 last = now;
25 now = next;
26 else
27 next(2:end-1) = now(1:end-2)+now(3:end)-last(2:end-1);
28 last = now;
29 now = next;
30 end
31 plot(now,'r');
32 xlim([0 nPoints]);
33 ylim([-1 1]);
34 grid;
35 pause(.1);
36 drawnow;
37 end
38
39 print(gcf, '-dpdf', '-r600', 'images/matlab_100');
225
0.8
0.6
0.4
0.2
-0.2
-0.4
-0.6
-0.8
-1
0 20 40 60 80 100
Ada
1 with Ada.Text_IO; use Ada.Text_IO;
2 with Ada.Float_Text_IO; use Ada.Float_Text_IO;
3 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
4 with Ada.Numerics; use Ada.Numerics;
5 with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
6
7 procedure foo is
8 nPoints : constant Integer := 100;
9 type grid_type is array (1 .. nPoints) of Float;
10 Output : File_Type;
11 nSteps : constant Integer := 500;
12 speed : constant Float := 351.0;
13 coord : array (1 .. nPoints) of Float;
14 h : constant Float := 1.0 / (Float (nPoints) - 1.0);
15 delT : constant Float := h / speed;
16 last : grid_type := (others => 0.0);
17 now : grid_type := last;
18 next : grid_type := last;
19
20 -- output one snapshot to file to plot later
21 procedure put_rec (rec : in grid_type) is
22 begin
23 for i in rec'Range loop
24 Put (Output, rec (i));
25 Put (Output,' ');
26 end loop;
27 end put_rec;
28
29 -- define function of initial data
30 function f (x : Float) return Float is
31 begin
32 if (x > 0.2 and x <= 0.6) then
33 return Sin (2.0 * Pi * (x - 0.2) / 0.4);
34 else
35 return 0.0;
36 end if;
37 end f;
38
39 begin
40 Create (File => Output, Mode => Out_File, Name => "output2.txt");
41
42 for i in 1 .. nPoints loop
43 coord (i) := Float (i - 1) * h;
44 last (i) := f (coord (i));
45 end loop;
46
47 now := last;
48 next := now;
49 put_rec (now);
50 New_Line (File => Output);
51
52 for i in 1 .. nSteps loop
53 if i = 1 then
54 for j in 2 .. nPoints - 1 loop
55 next (j) := (1.0 / 2.0) * (now (j - 1) + now (j + 1));
226
56 end loop;
57 last := now;
58 now := next;
59 put_rec (now);
60 New_Line (File => Output);
61 else
62 for j in 2 .. nPoints - 1 loop
63 next (j) := now (j - 1) + now (j + 1) - last (j);
64 end loop;
65 last := now;
66 now := next;
67 put_rec (now);
68 if i < nSteps then
69 New_Line (File => Output);
70 end if;
71 end if;
72
73 end loop;
74
75 Close (Output);
76 end foo;
The animation for Ada was done by reading the output and using the plot command in Matlab to show
the result.
1 close all;
2 A= dlmread('output2.txt');
3 [nRow,nCol]=size(A);
4 for i=1:2:nRow
5 plot(A(i,:))
6 ylim([-1 1]);
7 grid;
8 pause(.1);
9 drawnow;
10 end
x
∫2
1 1
(322 + 3x (98 + x (37 + x))) − 24 dx
−2 5 100 1 + x2
Mathematica
1 f[x_] := (1/5)(1/100(322+3*x(98+x(37+x)))- 1 Out[15]= 94/25
2 24(x/(1+x^2)))
3 r = Integrate[f[x],{x,-2,2}]
1 N[r] 1 Out[17]= 3.76
To compare with Matlab, replace 1 by 1.0 in the expression (or use N)
1 f[x_]:=(1.0/5)(1/100(322+3*x(98+x(37+x)))- 1 Out[62]=
2 24(x/(1+x^2))) 3.7600000000000007
3 r = Integrate[f[x],{x,-2,2}];
4 InputForm[r]
Matlab
1 ans =
clear all;
2
format long
3.760000000000001
f=@(x)(1/5)*(1/100*(322+3*x.*(98+x.*(37+x)))...
-24*(x/(1+x.^2)));
integral(f,-2,2)
1 ans =
2
integral(f,-2,2,'AbsTol',1e-6,'RelTol',1e-6)
3.760000000000001
∫ 10 ∫ 14
x 2 + 4y dxdy
7 11
Matlab
1 ans =
clear all;
2 1.719000000000004e
format long
+03
f=@(x,y) x.^2+4*y;
integral2(f,11,14,7,10)
Reference: mathematica.stackexchange.com/questions/76713
Maple
1 restart;
2 A:=<1,0,0>;
3 p:=t-> <p1(t),p2(t),p3(t)>:
4 q:=t-> <q1(t),q2(t),q3(t)>:
5 eq1:= diff~(p(t),t) = LinearAlgebra[CrossProduct](A,q(t));
d
dt p1 (t) 0
d
dt p2 (t)
= −q3 (t)
d
dt p3 (t)
q2 (t)
1 eq2:= diff~(q(t),t) = LinearAlgebra[CrossProduct](A,p(t));
d
dt q1 (t) 0
d
dt q2 (t)
= −p3 (t)
d
dt q3 (t)
p2 (t)
1 ic1:= p(0)=<0.5, 0.5, 0.3>;
p1 (0) 0.5
=
p2 (0) 0.5
p3 (0) 0.3
1 ic2:= q(0)=<0.1, 0.2, 0.3>;
q1 (0) 0.1
q2 (0) = 0.2
q3 (0) 0.3
1 sol:=dsolve({eq1,eq2,ic1,ic2},convert(<p(t),q(t)>,Vector));
Notice in the above, the dependent variable had to be converted to one vector, hence the use of the
convert() command. The result is
p1(t) 1/2
p2 (t) −3/10 sin (t) + 1/2 cos (t)
p3 (t) 1/5 sin (t) + 3/10 cos (t)
=
q1 (t) 1/10
q2 (t) 1/5 cos (t) − 3/10 sin (t)
q3 (t) 3/10 cos (t) + 1/2 sin (t)
Mathematica
229
1 Clear[P, A, t]
2 A = {1, 0, 0}
3 P[t_] = {P1[t], P2[t], P3[t]}
4 Q[t_] = {Q1[t], Q2[t], Q3[t]}
5 sol = DSolve[{P'[t] == Cross[A, Q[t]], Q'[t] == Cross[A, P[t]],
6 P[0] == {0.5, 0.5, 0.3}, Q[0] == {0.1, 0.2, 0.3}},
7 Flatten@{P[t], Q[t]}, t]
8 MatrixForm@{sol}
© © P1(t) → 0.5 ª ª
P2(t) → 0.5 cos(t) − 0.3 sin(t) ®
®
®
®
Q3(t) → 0.5 sin(t) + 0.3 cos(t)
® ®
® ®
® ®
P3(t) → 0.2 sin(t) + 0.3 cos(t) ®
®
®
®
Q2(t) → 0.2 cos(t) − 0.3 sin(t)
® ®
® ®
® ®
« « Q1(t) → 0.1 ¬ ¬
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0 1 2 3 4 5
3.8
3.6
3.4
3.2
2.8
2.6
2.4
2.2
2
0 1 2 3 4 5
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
0
0 1 2 3 4 5
A better way to do the above, which also generalized to any number of system of equations is to use
vectored approach. Writing
[x]
Û = [f (t, x, x 0, . . . )]
Where now [x] is the derivative of state vector and [f (t, x, x 0, . . . )] is the right hand side, in matrix
form. The above second order is now solved again using this method. This shows it is simpler approach
than the above method.
1 function [x,t] =nma_RK4_4( )
2 %solve x''(t)=x - 5 t x'(t) + (x'(t))^2 with x(0)=2,x'(0)=0.01,
3
4 delT = 0.001; %time grid
5 t = linspace(0,5,round(5/delT)); %time
6 N = length(t);
7 x = zeros(2,N);
8 x(1,1) = 2; %initial conditions
9 x(2,1) = 0.01;
10
11 for i = 1:(N-1)
12 k1 = delT * f( t(i) , x(:,i));
13 k2 = delT * f( t(i)+1/2*delT , x(:,i)+1/2*k1);
14 k3 = delT * f( t(i)+1/2*delT , x(:,i)+1/2*k2);
15 k4 = delT * f( t(i)+delT , x(:,i)+k3);
16
17 x(:,i+1) = x(:,i)+1/6*(k1+2*k2+2*k3+k4);
18 end
19
20 function r=f(t,x)
21 r=[x(2)
22 x(1)-5*t*x(2)+x(2)^2];
23 end
24 end
2
r r
2r
√
e a +3 √ + √
a a
w.r.t √r to produce
a
2r
√ r
2e a + 3 + 2√
a
e 2x + 3x + x 2
Mathematica
1 Clear[p, x, r, a]
2 p[x_] := Exp[2 x] + x^2 + 3*x;
2r
3 v = r/Sqrt[a]; √
Maple
4.24.1 Mathematica
In Mathematica 10.0, one can use Finite elements directly. Here is the code to solve the above.
1 Clear[u,x,y];
2 r=NDSolveValue[{D[u[x,y],{x,2}]+D[u[x,y],{y,2}]-20*u[x,y]==
3 -200+NeumannValue[0,x==0]
4 +NeumannValue[0,y==0],
5 DirichletCondition[u[x,y]==0,x==1],
6 DirichletCondition[u[x,y]==0,y==1]},
7 u,{x,0,1},{y,0,1},
8 Method->{"FiniteElement",
9 "MeshOptions"->{"BoundaryMeshGenerator"->"Continuation"}}];
1.0
0.8
0.6
0.4
0.2
0.0
0.0 0.2 0.4 0.6 0.8 1.0
234
Chapter 5
Mathematica
1 Remove["Global`*"]; plot of sin(x)
7 GridLinesStyle->Dashed, 0.0
8 ImageSize->300,
9 AspectRatio->1, -0.5
10 PlotStyle->Red,
11 FrameLabel->{{"sin(x)",None},
-1.0
12 {"x","plot of sin(x)"}}, -6 -4 -2 0 2 4 6
13 FrameTicks->{{-2Pi,-Pi,0,Pi,2Pi}, x
14 None,Automatic,None}
15 ]
clear all;
x = -2*pi:pi/100:2*pi;
0.5
plot(x,sin(x),'r');
grid on;
sin(x)
title('plot of sin(x)'); 0
xlabel('x');
ylabel('sin(x)');
set(gca,'XTick',-2*pi:pi:2*pi) -0.5
set(gca,'XTickLabel',...
{'-2*pi','-pi','0','pi','2*pi'})
-1
set(gcf,'Position',[10,10,340,340]); -2*pi -pi 0 pi 2*pi
x
Maple
1 restart; with(plots);
2 lis := [seq(sin((1/100)*theta), theta = 1 ..
1000)];
3 listplot(lis, axes = box)
235
236
Mathematica
1 Remove["Global`*"];
2 f[x_,y_]:=x^2-2x y+3y+2;
3 Plot3D[f[x,y],{x,-4,4},{y,-3,3},
4 PlotLabel->"Plot of x^2-2x y+3y+2",
5 ImageSize->300]
Matlab
60
clear all; close all;
x = -4:.3:4; 40
y = -3:.3:3;
20
[X,Y] = meshgrid(x,y);
Z = X.^2 - 2*(X.*Y) + 3*Y + 2; 0
surf(X,Y,Z)
title('plot of z=x^2-2(x y)+3y+2'); -20
4
set(gcf,'Position',[10,10,420,420]); 2 4
0 2
0
-2
-2
-4 -4
z = 2x + y
z = 2y
z=2
In Mathematica, plot the surfaces using the Plot3D command, and then use LinearSolve to solve the
system of equations in order to find point of intersection, then use ScatterPlot to plot the point solution.
In Matlab, use surf command to do the plotting, and solve the system of equations using Matlab
Mathematica
1 Remove["Global`*"];
2 eq1 = z-2x-y ==0;
3 eq2 = z-2y ==0;
4 eq3 = z- 2 ==0;
5 p1 = ContourPlot3D[Evaluate@eq1,
6 {x,-5,5},{y,-5,5},{z,-10,10},
7 AxesLabel->{"x","y","z"},
8 PlotLabel->"z=2x+y",
9 ImageSize->250];
10 p2 = ContourPlot3D[Evaluate@eq2,
11 {x,-5,5},{y,-5,5},{z,-10,10},
12 AxesLabel->{"x","y","z"},
13 PlotLabel->"z=2x",
14 ImageSize->250];
15 p3 = ContourPlot3D[Evaluate@eq3,
16 {x,-5,5},{y,-5,5},{z,-10,10},
17 AxesLabel->{"x","y","z"},
18 PlotLabel->"z=2",
19 ImageSize->250];
20 Grid[{{p1,p2,p3}},Frame->All]
237
1 {b,a} = CoefficientArrays[{eq1,eq2,eq3},
2 {x,y,z}];
3 sol = LinearSolve[a,-b]//N
1 Out[301]= {0.5,1.,2.}
1 Show[p1,p2,p3,
2 Graphics3D[{PointSize[0.2],
3 Red,Point[sol]}],
4 PlotLabel->"point where surfaces meet)"]
238
Matlab
clear all; close all;
x = -4:.5:4;
y = -3:.5:3;
[X,Y] = meshgrid(x,y);
subplot(1,3,1);
Z = 2*X + Y; surf(X,Y,Z);
title('z=2x+y');
subplot(1,3,2);
Z = 2*Y; surf(X,Y,Z);
title('z=2y');
subplot(1,3,3);
Z = zeros(length(y),length(x));
Z(1:end,1:end)=2;
surf(X,Y,Z);
title('z=2');
figure;
surf(X,Y,2*X + Y); hold on;
surf(X,Y,2*Y);
surf(X,Y,Z);
plot3(sol(1),sol(2),sol(3),...
'k.','MarkerSize',30)
1.0
Mathematica
0.5
1 a = 2;
2 b = 1;
-2 -1 1 2
3 Graphics[Circle[{0, 0}, {a, b}], Axes
-> True] -0.5
-1.0
1.5
Matlab 1
0.5
1 a=2;
2 b=1; 0
3 t=linspace(0,2*pi,50);
4 plot(a*cos(t),b*sin(t)) -0.5
5 axis equal
-1
-1.5
-1.5 -1 -0.5 0 0.5 1 1.5 2
5.4.2 draw an ellipse centered at (x, y) and given its semi-major/minor (a, b)
draw an ellipse centered at (1, 2) with a = 2, b = 1 being its semi-major and minor. The ellipse equation
for the above is xa 2 + bx 2 = 1
2 2
Mathematica
3.0
1 a = 2;
2 b = 1; 2.5
3 Graphics[
4 { 2.0
Matlab 3.5
3
close all;
a=2; b=1; 2.5
t=linspace(0,2*pi,50); 2
plot(a*cos(t)+1,b*sin(t)+2)
axis equal 1.5
xlim([-1,4]); 1
ylim([0,4]);
0.5
0
-1 0 1 2 3 4
5.4.3 draw an ellipse centered at origin and given its semi-major/minor (a, b) and
rotated at angle θ
draw an ellipse centered at (0, 0) with a = 2, b = 1 being its semi-major and minor titlted at angle
θ = 30 degrees anti-clockwise.
x2 x2
The ellipse equation for the above is a2
+ b2
= 1. After drawing it, we rotate it.
Mathematica
1 a = 2;
2 b = 1; 1.0
3 Graphics[
4 Rotate[ 0.5
9 , 30 Degree
10 ] -1.0
Matlab
a = 2;
b = 1; 0.5
t = linspace(0,2*pi,50);
0
rotateAngle = 30*pi/180;
mat = [cos(rotateAngle) -sin(rotateAngle) -0.5
sin(rotateAngle) cos(rotateAngle)];
-1
%2x2 times 2x50 = 2x50
data = mat*[a*cos(t);b*sin(t)]; -1.5 -1 -0.5 0 0.5 1 1.5
plot(data(1,:),data(2,:))
axis equal
Mathematica
1 Clear[x, y, z];
2 nElem = 10.;
3 h = 1/nElem
4 N@Range[-1, 1, h]
5 grid = N@Table[{i, j}, {i, -1, 1, h}, {j, -1, 1,
h}];
6 f[x_, y_] := Sin[x*10 y] Exp[-x y];
7 force = Map[f[#[[1]], #[[2]]] &, grid, {2}];
8 ListPlot3D[force, AxesLabel -> {x, y, z}]
To use the actual physical coordinates on the axis above, then replace the plot above with this below.
This also includes an implementation of meshgrid like function in Mathematica which makes it easier
to work with for someone familiar with Matlab:
1 meshgrid[x_List,y_List]:={ConstantArray[x,
Length[x]],
2 Transpose@ConstantArray[y, Length[y]]};
3
4 nElem = 10.;
5 h = 1/nElem;
6 {x, y} = meshgrid[Range[-1, 1, h], Range[-1, 1,
h]];
7 f[x_, y_] := Sin[x*10 y] Exp[-x y];
8 force = f[x, y];
9 pts = Flatten[{x, y, force}, {2, 3}];
10 ListPlot3D[pts, PlotRange -> All,
11 AxesLabel -> Automatic, ImagePadding ->
20,
12 ColorFunction -> "Rainbow", Boxed ->
False]
To see each point value, use InterpolationOrder -> 0 in the plot command.
Matlab
clear all; close all;
nElem = 10;
h = 1/nElem;
[X,Y] = meshgrid(-1:h:1,-1:h:1);
f = @(x,y) sin(x*10.*y) .* exp(-x.*y);
force = f(X,Y);
surf(X,Y,force)
Mathematica 0.5
1 lst=Table[{x, Sin[x]}, {x, -Pi, Pi, 1/10}]; -3 -2 -1 1 2 3
2 ListLinePlot[lst]
-0.5
-1.0
242
Matlab
Matlab does not have a nice function like Table so one can 1
either make the x variable and then use it to make sin(x) 0.8
close all;
0.4
0.2
x=-pi:.1:pi; 0
plot(x,sin(x)); -0.2
-0.4
-0.6
A=cell2mat(arrayfun(@(x) [x;sin(x)],... -1
-4 -3 -2 -1 0 1 2 3 4
-pi:.1:pi, 'UniformOutput',false));
plot(A(1,:),A(2,:))
Mathematica
15
6 PlotRangePadding -> 2] 0
0 5 10 15 20
Matlab
.90 5
5
91
.54
727
62
51
22
1.2
51
x = 0:0.05:20;
.90
83
41
62
418
91
81
y = 0:0.05:15;
.2
10
72
21
[x,y] = meshgrid(x,y);
10
.6
36
z = (11-x-y).^2 + (1+x+10*y-x.*y).^2;
4
64
[C,h] =contour(x,y,z,10); 10.
63
21
clabel(C,h) 5
0
0 5 10 15 20