0% found this document useful (0 votes)
62 views448 pages

4a. Solving Basic Eng and Math Probs Using Maple - Part I

This document provides instructions for solving various basic engineering and mathematics problems using Mathematica, Matlab, and Maple. It contains over 40 sections covering topics like linear systems, control systems, linear algebra, matrices, vectors, differential equations, and more. Each section provides code snippets and step-by-step explanations for tasks like obtaining transfer functions, plotting impulse responses, solving systems of equations, and performing operations on matrices. The goal is to demonstrate how to use symbolic computation software to analyze and solve common problems in engineering and mathematics.

Uploaded by

Ben
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views448 pages

4a. Solving Basic Eng and Math Probs Using Maple - Part I

This document provides instructions for solving various basic engineering and mathematics problems using Mathematica, Matlab, and Maple. It contains over 40 sections covering topics like linear systems, control systems, linear algebra, matrices, vectors, differential equations, and more. Each section provides code snippets and step-by-step explanations for tasks like obtaining transfer functions, plotting impulse responses, solving systems of equations, and performing operations on matrices. The goal is to demonstrate how to use symbolic computation software to analyze and solve common problems in engineering and mathematics.

Uploaded by

Ben
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 448

General report

How to solve Basic Engineering and


Mathematics Problems

using Mathematica, Matlab and Maple

Nasser M. Abbasi

November 30, 2019


Contents

1 Control systems, Linear systems, transfer functions, state space related prob-
lems 3
1.1 Creating tf and state space and different Conversion of forms . . . . . . . . . 3
1.2 Obtain the step response of an LTI from its transfer function . . . . . . . . . 15
1.3 plot the impulse and step responses of a system from its transfer function . . 17
1.4 Obtain the response of a transfer function for an arbitrary input . . . . . . . 21
1.5 Obtain the poles and zeros of a transfer function . . . . . . . . . . . . . . . . 24
1.6 Generate Bode plot of a transfer function . . . . . . . . . . . . . . . . . . . . . 25
1.7 How to check that state space system 𝑥′ = 𝐴𝑥 + 𝐵𝑢 is controllable? . . . . . . 27
1.8 Obtain partial-fraction expansion . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.9 Obtain Laplace transform for a piecewise functions . . . . . . . . . . . . . . . 30
1.10 Obtain Inverse Laplace transform of a transfer function . . . . . . . . . . . . 32
1.11 Display the response to a unit step of an under, critically, and over damped
system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.12 View steady state error of 2nd order LTI system with changing undamped
natural frequency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.13 Show the use of the inverse Z transform . . . . . . . . . . . . . . . . . . . . . . 41
1.14 Find the Z transform of sequence x(n) . . . . . . . . . . . . . . . . . . . . . . 44
1.15 Sample a continuous time system . . . . . . . . . . . . . . . . . . . . . . . . . 45
1.16 Find closed loop transfer function from the open loop transfer function for
a unity feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.17 Compute the Jordan canonical/normal form of a matrix A . . . . . . . . . . . 51
1.18 Solve the continuous-time algebraic Riccati equation . . . . . . . . . . . . . . 52
1.19 Solve the discrete-time algebraic Riccati equation . . . . . . . . . . . . . . . . 53
1.20 Display impulse response of H(z) and the impulse response of its continuous
time approximation H(s) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
1.21 Find the system type given an open loop transfer function . . . . . . . . . . . 60
1.22 Find the eigenvalues and eigenvectors of a matrix . . . . . . . . . . . . . . . . 62
1.23 Find the characteristic polynomial of a matrix . . . . . . . . . . . . . . . . . . 63
1.24 Verify the Cayley-Hamilton theorem that every matrix is zero of its charac-
teristic polynomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
1.25 How to check for stability of system represented as a transfer function and
state space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
1.26 Check continuous system stability in the Lyapunov sense . . . . . . . . . . . 67

iii
Contents CONTENTS

1.27 Given a closed loop block diagram, generate the closed loop Z transform
and check its stability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
1.28 Determine the state response of a system to only initial conditions in state
space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
1.29 Determine the response of a system to only initial conditions in state space . 75
1.30 Determine the response of a system to step input with nonzero initial conditions 77
1.31 Draw the root locus from the open loop transfer function . . . . . . . . . . . 79
1.32 Find 𝑒𝐴𝑡 where 𝐴 is a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
1.33 Draw root locus for a discrete system . . . . . . . . . . . . . . . . . . . . . . . 82
1.34 Plot the response of the inverted pendulum problem using state space . . . . 84
1.35 How to build and connect a closed loop control systems and show the response? 89
1.36 Compare the effect on the step response of a standard second order system
as 𝜁 changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
𝜔
1.37 Plot the dynamic response factor 𝑅𝑑 of a system as a function of 𝑟 = 𝜔 for
𝑛
different damping ratios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
1.38 How to find closed loop step response to a plant with a PID controller? . . . 98
1.39 How to make Nyquist plot? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

2 Linear algebra, Linear solvers, common operations on vectors and matrices 103
2.1 Multiply matrix with a vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
2.2 Insert a number at specific position in a vector or list . . . . . . . . . . . . . . 109
2.3 Insert a row into a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
2.4 Insert a column into a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
2.5 Build matrix from other matrices and vectors . . . . . . . . . . . . . . . . . . 115
2.6 Generate a random 2D matrix from uniform (0 to 1) and from normal distri-
butions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
2.7 Generate an n by m zero matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 125
2.8 Rotate a matrix by 90 degrees . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
2.9 Generate a diagonal matrix with given values on the diagonal . . . . . . . . . 129
2.10 Sum elements in a matrix along the diagonal . . . . . . . . . . . . . . . . . . 130
2.11 Find the product of elements in a matrix along the diagonal . . . . . . . . . . 131
2.12 Check if a Matrix is diagonal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
2.13 Find all positions of elements in a Matrix that are larger than some value . . 133
2.14 Replicate a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
2.15 Find the location of the maximum value in a matrix . . . . . . . . . . . . . . 136
2.16 Swap 2 columns in a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
2.17 Join 2 matrices side-by-side and on top of each others . . . . . . . . . . . . . 139
2.18 Copy the lower triangle to the upper triangle of a matrix to make symmetric
matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
2.19 extract values from matrix given their index . . . . . . . . . . . . . . . . . . . 143
2.20 Convert 𝑁 by 𝑀 matrix to a row of length 𝑁𝑀 . . . . . . . . . . . . . . . . . . 145
2.21 find rows in a matrix based on values in different columns . . . . . . . . . . . 147
2.22 Select entries in one column based on a condition in another column . . . . 149
2.23 Locate rows in a matrix with column being a string . . . . . . . . . . . . . . . 152
2.24 Remove set of rows and columns from a matrix at once . . . . . . . . . . . . 154
iv
Contents CONTENTS

2.25 Convert list of separated numerical numbers to strings . . . . . . . . . . . . . 157


2.26 Obtain elements that are common to two vectors . . . . . . . . . . . . . . . . 158
2.27 Sort each column (on its own) in a matrix . . . . . . . . . . . . . . . . . . . . 159
2.28 Sort each row (on its own) in a matrix . . . . . . . . . . . . . . . . . . . . . . 160
2.29 Sort a matrix row-wise using first column as key . . . . . . . . . . . . . . . . . 161
2.30 Sort a matrix row-wise using non-first column as key . . . . . . . . . . . . . . 162
2.31 Replace the first nonzero element in each row in a matrix by some value . . 163
2.32 Perform outer product and outer sum between two vector . . . . . . . . . . . 166
2.33 Find the rank and the bases of the Null space for a matrix A . . . . . . . . . 168
2.34 Find the singular value decomposition (SVD) of a matrix . . . . . . . . . . . 170
2.35 Solve 𝐴𝑥 = 𝑏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
2.36 Find all nonzero elements in a matrix . . . . . . . . . . . . . . . . . . . . . . . 175
2.37 evaluate f(x) on a vector of values . . . . . . . . . . . . . . . . . . . . . . . . . 177
2.38 generates equally spaced N points between 𝑥1 and 𝑥2 . . . . . . . . . . . . . . 178
2.39 evaluate and plot a 𝑓(𝑥, 𝑦) on 2D grid of coordinates . . . . . . . . . . . . . . 179
2.40 Find determinant of matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
2.41 Generate sparse matrix with 𝑛 by 𝑛 matrix repeated on its diagonal . . . . . 182
2.42 Generate sparse matrix for the tridiagonal representation of second difference
operator in 1D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
2.43 Generate sparse matrix for the Laplacian differential operator ∇ 2 𝑢 for 2D grid186
2.44 Generate sparse matrix for the Laplacian differential operator ∇ 2 𝑢 for 3D grid187
2.45 Generate the adjugate matrix for square matrix . . . . . . . . . . . . . . . . . 194
2.46 Multiply each column by values taken from a row . . . . . . . . . . . . . . . . 199
2.47 extract submatrix from a larger matrix by removing row/column . . . . . . . 202
2.48 delete one row from a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
2.49 delete one column from a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . 210
2.50 generate random matrix so that each row adds to 1 . . . . . . . . . . . . . . . 212
2.51 generate random matrix so that each column adds to 1 . . . . . . . . . . . . . 213
2.52 sum all rows in a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
2.53 sum all columns in a matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
2.54 find in which columns values that are not zero . . . . . . . . . . . . . . . . . . 218
2.55 How to remove values from one vector that exist in another vector . . . . . . 220
2.56 How to find mean of equal sized segments of a vector . . . . . . . . . . . . . 222
2.57 find first value in column larger than some value and cut matrix from there . 223
2.58 make copies of each value into matrix into a larger matrix . . . . . . . . . . . 224
2.59 repeat each column of matrix number of times . . . . . . . . . . . . . . . . . . 225
2.60 How to apply a function to each value in a matrix? . . . . . . . . . . . . . . . 226
2.61 How to sum all numbers in a list (vector)? . . . . . . . . . . . . . . . . . . . . 227
2.62 How to find maximum of each row of a matrix? . . . . . . . . . . . . . . . . . 228
2.63 How to find maximum of each column of a matrix? . . . . . . . . . . . . . . . 229
2.64 How to add the mean of each column of a matrix from each column? . . . . 230
2.65 How to add the mean of each row of a matrix from each row? . . . . . . . . 231
2.66 Find the different norms of a vector . . . . . . . . . . . . . . . . . . . . . . . . 232
2.67 Check if a matrix is Hermite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
2.68 Obtain the LU decomposition of a matrix . . . . . . . . . . . . . . . . . . . . 235
v
Contents CONTENTS

2.69 Linear convolution of 2 sequences . . . . . . . . . . . . . . . . . . . . . . . . . 237


2.70 Circular convolution of two sequences . . . . . . . . . . . . . . . . . . . . . . . 238
2.71 Linear convolution of 2 sequences with origin at arbitrary position . . . . . . 240
2.72 Visualize a 2D matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
2.73 Find the cross correlation between two sequences . . . . . . . . . . . . . . . . 245
2.74 Find orthonormal vectors that span the range of matrix A . . . . . . . . . . . 248
2.75 Solve 𝐴𝑥 = 𝑏 and display the solution . . . . . . . . . . . . . . . . . . . . . . . 250
2.76 Determine if a set of linear equations 𝐴𝑥 = 𝑏 has a solution and what type of
solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
2.77 Given a set of linear equations automatically generate the matrix 𝐴 and
vector 𝑏 and solve 𝐴𝑥 = 𝑏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
2.78 Convert a matrix to row echelon form and to reduced row echelon form . . 255
2.79 Convert 2D matrix to show the location and values . . . . . . . . . . . . . . . 256
2.80 Find rows in matrix with zeros in them, and then remove the zeros . . . . . . 259
2.81 How to apply a function to two lists at the same time? . . . . . . . . . . . . . 260
2.82 How to apply a function to two lists are the same time, but with change to
entries? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
2.83 How to select all primes numbers from a list? . . . . . . . . . . . . . . . . . . 263
2.84 How to collect result inside a loop when number of interation is not known
in advance? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
2.85 How flip an array around? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
2.86 How to divide each element by its position in a list? . . . . . . . . . . . . . . 266

3 signal processing, Image processing, graphics, random numbers 267


3.1 Generate and plot one pulse signal of different width and amplitude . . . . . 267
3.2 Generate and plot train of pulses of different width and amplitude . . . . . . 270
3.3 Find the discrete Fourier transform of a real sequence of numbers . . . . . . 272
3.4 Generate uniform distributed random numbers . . . . . . . . . . . . . . . . . 275
3.5 Obtain Fourier Series coefficients for a periodic function . . . . . . . . . . . . 280
3.6 Determine and plot the CTFT (continuous time Fourier Transform) for con-
tinuous time function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
3.7 Determine the DTFT (Discrete time Fourier Transform) for discrete time
function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
3.8 Determine the Inverse DTFT (Discrete time Fourier Transform) . . . . . . . 290
3.9 Use FFT to display the power spectrum of the content of an audio wav file . 291
3.10 Plot the power spectral density of a signal . . . . . . . . . . . . . . . . . . . . 295
3.11 Display spectrum of 2D image . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
3.12 Obtain the statistical maximum likelihood estimates (MLE) of probability
distributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
3.13 Make a histogram of data sampled from some probability distribution . . . . 304
3.14 apply a filter on 1D numerical data (a vector) . . . . . . . . . . . . . . . . . . 305
3.15 apply an averaging Laplacian filter on 2D numerical data (a matrix) . . . . . 306
3.16 How to find cummulative sum . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
3.17 How to find the moving average of a 1D sequence? . . . . . . . . . . . . . . . 308
3.18 How to select N random values from a set of numbers? . . . . . . . . . . . . 309
vi
Contents CONTENTS

3.19 How to sample a sin signal and plot it? . . . . . . . . . . . . . . . . . . . . . . 310


3.20 How find the impulse response of a difference equation? . . . . . . . . . . . . 312

4 Differential, PDE solving, integration, numerical and analytical solving of


equations 315
4.1 Generate direction field plot of a first order differential equation . . . . . . . 315
4.2 Solve the 2-D Laplace PDE for a rectangular plate with Dirichlet boundary
conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
4.3 Solve homogeneous 1st order ODE, constant coefficients and initial conditions321
4.4 Solve homogeneous 2nd order ODE with constant coefficients . . . . . . . . 323
4.5 Solve non-homogeneous 2nd order ODE, constant coefficients . . . . . . . . 325
4.6 Solve homogeneous 2nd order ODE, constant coefficients (BVP) . . . . . . . 327
4.7 Solve the 1-D heat partial differential equation (PDE) . . . . . . . . . . . . . 330
4.8 Show the effect of boundary/initial conditions on 1-D heat PDE . . . . . . . . 333
4.9 Find particular and homogenous solution to undetermined system of equations335
4.10 Plot the constant energy levels for a nonlinear pendulum . . . . . . . . . . . 339

4.11 Solve numerically the ODE 𝑢 + 𝑢 = 𝑓 using point collocation method . . . . 345
4.12 How to numerically solve a set of non-linear equations? . . . . . . . . . . . . 350
4.13 Solve 2nd order ODE (Van Der Pol) and generate phase plot . . . . . . . . . 352
4.14 How to numerically solve Poisson PDE on 2D using Jacobi iteration method? 357
4.15 How to solve BVP second order ODE using finite elements with linear shape
functions and using weak form formulation? . . . . . . . . . . . . . . . . . . . 362
4.16 How to solve Poisson PDE in 2D using finite elements methods using rectan-
gular element? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
4.17 How to solve Poisson PDE in 2D using finite elements methods using triangle
element? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
4.18 How to solve wave equation using leapfrog method? . . . . . . . . . . . . . . 407
4.19 Numerically integrate 𝑓(𝑥) on the real line . . . . . . . . . . . . . . . . . . . . 413
4.20 Numerically integrate 𝑓(𝑥, 𝑦) in 2D . . . . . . . . . . . . . . . . . . . . . . . . . 414
4.21 How to solve set of differential equations in vector form . . . . . . . . . . . . 415
4.22 How to implement Runge-Kutta to solve differential equations? . . . . . . . . 417
4.23 How to differentiate treating a combined expression as single variable? . . . 421
4.24 How to solve Poisson PDE in 2D with Neumann boundary conditions using
Finite Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422

5 plotting how to, ellipse, 3D 425


5.1 Generate a plot using x and y data . . . . . . . . . . . . . . . . . . . . . . . . . 425
5.2 Plot the surface described by 2D function . . . . . . . . . . . . . . . . . . . . . 427
5.3 Find the point of intersection of 3 surfaces . . . . . . . . . . . . . . . . . . . . 428
5.4 How to draw an ellipse? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
5.5 How to plot a function on 2D using coordinates of grid locations? . . . . . . 435
5.6 How to make table of 𝑥, 𝑦 values and plot them . . . . . . . . . . . . . . . . . 437
5.7 How to make contour plot of 𝑓(𝑥, 𝑦) ? . . . . . . . . . . . . . . . . . . . . . . . 438

6 Some symbolic operations 439

vii
Contents CONTENTS

6.1 How to find all exponents of list of expressions? . . . . . . . . . . . . . . . . . 439

viii
Contents CONTENTS

This is a collection of how to examples showing the use of Mathematica and Matlab to solve
basic engineering and mathematics problems. Few examples are also in Maple, Ada, and
Fortran.
This was started as a cheat sheet few years ago, and I continue to update it all the time.
Few of the Matlab examples require the use of toolboxs such as signal processing toolbox
and the control systems toolbox (these come free as part of the student version). Most
examples require only the basic system installation.

1
Contents CONTENTS

2
Chapter 1

Control systems, Linear systems,


transfer functions, state space related
problems

1.1 Creating tf and state space and different Conversion


of forms
1.1.1 Create continuous time transfer function given the poles,
zeros and gain
Problem: Find the transfer function 𝐻(𝑠) given zeros 𝑠 = −1, 𝑠 = −2, poles 𝑠 = 0, 𝑠 = −4, 𝑠 = −6
and gain 5.

1.1.1.1 Mathematica

Clear["Global`*"];
num = (s+1)(s+2);
Out[30]= TransferFunctionModel[{
den = (s)(s+4)(s+6);
{{5*(1 + s)*(2 + s)}},
gain = 5;
s*(4 + s)*(6 + s)}, s]
sys = TransferFunctionModel[
gain (num/den),s]

3
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.1.1.2 Matlab

clear all;
m_zeros = [-1 -2];
num/den =
m_poles = [0 -4 -6];
5 s^2 + 15 s + 10
gain = 5;
-------------------
sys = zpk(m_zeros,m_poles,gain); s^3 + 10 s^2 + 24 s
[num,den] = tfdata(sys,'v');
printsys(num,den,'s')

1.1.1.3 Maple

restart;
alias(DS=DynamicSystems):
zeros :=[-1,-2]:
poles :=[0,-4,-6]:
gain :=5: 5 𝑠2 +15 𝑠+10
tf = � �
sys :=DS:-TransferFunction(zeros,poles, 𝑠3 +10 𝑠2 +24 𝑠
gain):
#print overview of the system object
DS:-PrintSystem(sys);

exports(sys);
#To see fields in the sys object, do the
following
# tf, inputcount, outputcount, statecount,
sampletime,
# discrete, systemname, inputvariable,
outputvariable,
5 ∗ 𝑠2 + 15 ∗ 𝑠 + 10
# statevariable, parameters, systemtype,
ModulePrint
tf:=sys[tf]; #reads the transfer function
Matrix(1,1,{(1,1)=(5*s^2+15*s+10)/(s^3+10*s
^2+24*s)})
numer(tf[1,1]); #get the numerator of the tf

denom(tf[1,1]); #get the denominator of


the tf 𝑠 ∗ (𝑠2 + 10 ∗ 𝑠 + 24)

4
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.1.2 Convert transfer function to state space representation


1.1.2.1 problem 1
Problem: Find the state space representation for the continuous time system defined by the
transfer function
5𝑠
𝐻(𝑠) =
𝑠2 + 4𝑠 + 25

1.1.2.2 Mathematica

Clear["Global`*"];
sys = TransferFunctionModel[(5 s)/(s^2+4 s+25),s]; 0 1 0 
Out[48]= -25 -4 1
ss = MinimalStateSpaceModel[StateSpaceModel[sys]] 0 5 0

Out[49]//MatrixForm=
0 1
 
-25 -4
(a=Normal[ss][[1]])//MatrixForm Out[50]//MatrixForm=
(b=Normal[ss][[2]])//MatrixForm 
0

(c=Normal[ss][[3]])//MatrixForm 1
(d=Normal[ss][[4]])//MatrixForm Out[51]//MatrixForm=
(0 5)

Out[52]//MatrixForm=
(0)

1.1.2.3 Matlab
A =
-4 -25
1 0
clear all;
B =
s = tf('s');
1
sys_tf = (5*s) / (s^2 + 4*s + 25);
0
[num,den] = tfdata(sys_tf,'v'); C =
[A,B,C,D] = tf2ss(num,den) 5 0
D =
0

5
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.1.2.4 Maple

restart;
alias(DS=DynamicSystems):
sys := DS:-TransferFunction(5*s/(s^2+4*s+25)): ⎡ ⎤
⎢⎢ 0 1 ⎥⎥
sys := DS:-StateSpace(sys); ⎢⎢ ⎥⎥
⎣ −25 −4 ⎦
exports(sys); #to see what fields there are
a := sys:-a;

⎡ ⎤
b:=sys:-b; ⎢⎢ 0 ⎥⎥
⎢⎢ ⎥⎥
⎣ 1 ⎦

c:=sys:-c; � 0 5 �

d:=sys:-d; � 0 �

1.1.2.5 problem 2
Problem: Given the continuous time S transfer function defined by

1+𝑠
𝐻(𝑠) =
𝑠2 +𝑠+1
convert to state space and back to transfer function.

Mathematica
⎛ ⎞
Clear["Global`*"]; ⎜⎜ 0 1 0 ⎟⎟
⎜⎜ ⎟⎟
sys = TransferFunctionModel[(s + 1)/(s^2 + 1 s + 1), s]; ⎜⎜ −1 −1 1 ⎟⎟⎟
⎜⎜ ⎟⎠

ss = MinimalStateSpaceModel[StateSpaceModel[sys]] 1 1 0

TransferFunctionModel[ss] 𝑠+1
𝑠2 + 𝑠 + 1

6
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

A =
-1 -1
Matlab 1 0

clear all; B =
s = tf('s'); 1
sys = ( s+1 )/(s^2 + s + 1); 0
[num,den]=tfdata(sys,'v');
C =
%convert to state space
1 1
[A,B,C,D] = tf2ss(num,den)
D =
0

%convert from ss to tf sys =


s + 1
[num,den] = ss2tf(A,B,C,D);
-----------
sys=tf(num,den)
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
A =
0 1 0 0
0 0 1 0
0 0 0 1
-100 -80 -32 -8

B =
0
0
5
60

C =
1 0 0 0

D =
0

7
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Clear["Global`*"];

a = {{0,1,0,0},
{0,0,1,0},
{0,0,0,1},
{-100,-80,-32,-8}
}; 1.2

1.0

b = {{0} ,{0}, {5},{60}};


0.8

0.6

c = {{1,0,0,0}}; 0.4

d = {{0}}; 0.2

2 4 6 8 10

sys = StateSpaceModel[{a,b,c,d}];
y = OutputResponse[sys,UnitStep[t],{t,0,10}];

p = Plot[Evaluate@y, {t, 0, 10},


PlotRange -> All,
GridLines -> Automatic,
GridLinesStyle -> LightGray]

Matlab

clear all;
A = [0 1 0 0;
0 0 1 0;
0 0 0 1; 1.2
unit step response

-100 -80 -32 -8]; 1

B = [0;0;5;60]; 0.8
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');

8
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

restart:
alias(DS=DynamicSystems):
alias(size=LinearAlgebra:-Dimensions);
a:=Matrix([[0,1,0,0],[0,0,1,0],
[0,0,0,1],[-100,-90,-32,-8]]):
b:=Matrix([[0],[0],[5],[6]]):
c:=Matrix([[1,0,0,0]]):
d:=Matrix([[1]]):
sys:=DS:-StateSpace(a,b,c,d);

DS:-ResponsePlot(sys, DS:-Step(),
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+𝑠
𝐻(𝑠) =
𝑠2 + 𝑠 + 1
Use sampling period of 0.1 seconds.

9
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Clear["Global`*"]; 1+s 
Out[88]=  
1+s+s 2
tf = TransferFunctionModel[(s+1)/(s^2+1 s+1),s];

ds = ToDiscreteTimeModel[tf, 0.1, z,
Method -> "ZeroOrderHold"] Out[89]= 
-0.0903292 + 0.0998375 z 

0.904837 - 1.89533 z + z2 0.1

gm
Out
[28]={{31.4159,19.9833}}
{gm, pm} = GainPhaseMargins[ds];
pm
Out
[29]={{1.41451,1.83932},{0.,
Pi}}

max = 100;
yn = OutputResponse[ds,
Table[UnitStep[n],{n, 0, max}]]; 1.4
unit step response

1.2
ListPlot[yn,
1.0
Joined -> True,
InterpolationOrder -> 0,
0.8
y[n]

PlotRange -> {{0, max}, {0, 1.4}}, 0.6

Frame -> True, 0.4

FrameLabel ->{{"y[n]", None}, 0.2

{"n", "unit step response"}}, 0.0


0 20 40 60 80 100

ImageSize -> 400, n

AspectRatio -> 1,BaseStyle -> 14]

10
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

0.09984 z - 0.09033
----------------------
z^2 - 1.895 z + 0.9048

Sample time: 0.1 seconds


Matlab
Discrete-time transfer
function.
clear all; close all;
Ts = 0.1; %sec, sample period Gm =
s = tf('s'); 19.9833
sys = ( s + 1 ) / ( s^2 + s + 1);
%convert s to z domain Pm =
sysd = c2d(sys,Ts,'zoh'); 105.3851
tf(sysd)
Wcg =
31.4159

Wcp =
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)

1.1.5 Convert differential equation to transfer functions and to state


space
Problem: Obtain the transfer and state space representation for the differential equation

𝑑2 𝑦 𝑑𝑦
3 2
+ 2 + 𝑦 (𝑡) = 𝑢(𝑡)
𝑑𝑡 𝑑𝑡

11
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Clear[y, u, t]; 2 1 1 
eq = 3 y''[t] + 2 y'[t] + y[t] == u[t]; -
3
-
3 3
ss = StateSpaceModel[ {eq}, {{y'[t], 0}, Out[34]=
1 0 0
{y[t], 0}}, {{u[t], 0}}, {y[t]}, t]; 0 1 0
ss = MinimalStateSpaceModel[ss]

1 
tf = Simplify[TransferFunctionModel[ss]] Out[35]= . .2
1+2s
.+3s
.

Matlab

clear all;

syms y(t) Y 1
eq = 3*diff(y,2)+2*diff(y)+y; --------------
lap = laplace(eq); 2
lap = subs(lap,'y(0)',0); 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)

A =
-0.6667 -0.3333
1.0000 0
[num,den] = numden(H); B =
num = sym2poly(num); 1
den = sym2poly(den); 0
[A,B,C,D] = tf2ss(num,den) C =
0 0.3333
D =
0

12
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

restart;
alias(DS=DynamicSystems):

ode:=3*diff(y(t),t$2)+2*diff(y(t),t)+y(t)=
Heaviside(t):
1
sys:=DS:-DiffEquation(ode, 3𝑠2 + 2𝑠 + 1
'outputvariable'=[y(t)],
'inputvariable'=[Heaviside(t)]):

sys:=DS:-TransferFunction(sys):
sys:-tf(1,1);

sys:=DS:-StateSpace(sys):
⎧⎡ ⎫
#show the state space matrices ⎪

⎪⎢⎢⎢ 0 1
⎤ ⎡
⎥⎥ ⎢⎢ 0 ⎥⎥
⎤ ⎪


⎨ ⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥ ⎬
{sys:-a,sys:-b,sys:-c,sys:-d}; ⎪
⎪⎢⎣ −1/3

⎩ −2/3
,
⎥⎥ ⎢⎢
⎦ ⎣
1
⎥⎥ , � 1/3

0 � , � 0 �⎪


1.1.6 Convert from continuous transfer function to discrete time


transfer function
Problem: Convert
1
𝐻 (𝑠) =
𝑠2 + 10𝑠 + 10

To 𝑍 domain transfer function using sampling period of 0.01 seconds and using the zero
order hold method.
Mathematica

Clear["Global`*"]
sys = TransferFunctionModel[
1/(s^2 +10 s+20),s]; 
0.0000467806 + 0.0000483662 z 

0.904837 - 1.90293 z + z2 0.01

sysd= ToDiscreteTimeModel[sys,0.01,z,
Method->"ZeroOrderHold"]

13
1.1. Creating tf and state space and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

sysz =
Matlab
4.837e-05 z + 4.678e-05
s = tf('s'); -----------------------
sys = 1/(s^2 + 10*s + 20); z^2 - 1.903 z + 0.9048
T = 0.01; %seconds
sysz = c2d(sys,T,'zoh') Sample time: 0.01 seconds
Discrete-time transfer function.

1.1.7 Convert a Laplace transfer function to an ordinary differential


equation
Problem: Give a continuous time transfer function, show how to convert it to an ordinary
differential equation. This method works for non-delay systems. The transfer function must
be ratio of polynomials. For additional methods see this question at stackexchange

Mathematica

tfToDiff[tf_, s_, t_, y_, u_]:=


Module[{rhs,lhs,n,m},
rhs = Numerator[tf];
lhs = Denominator[tf];
rhs = rhs /. m_. s^n_. -> m D[u[t], {t, n}]; 25 + 4 y'[t]+y''[t
lhs = lhs /. m_. s^n_. -> m D[y[t], {t, n}]; ]==5 u'[t]
lhs == rhs
]

tf = (5s)/(s^2+4s+25);
tf = C0 s/(R0 C0 s + 1);
eq=tfToDiff[tf, s, t, y, u]

14
1.2. Obtain the step response of an LTI . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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
𝐻(𝑠) =
𝑠2 + 4𝑠 + 25

Mathematica

Clear["Global`*"];
step response
1.4
tf=TransferFunctionModel[25/(s^2+4s+25),s];
y = OutputResponse[tf, UnitStep[t], t]; 1.2

1.0

Plot[Evaluate@y, {t, 0, 4},


0.8
PlotRange -> {{0, 4}, {0, 1.4}},

y(t)
Frame -> True, 0.6

FrameLabel -> {{"y(t)", None}, 0.4

{t, "step response"}},


0.2
GridLines -> Automatic,
GridLinesStyle -> Dashed, 0.0
0 1 2 3 4

ImageSize -> {300, 300}, t

PlotStyle -> Red,


AspectRatio -> 1]

Matlab

clear all;
step response
s = tf('s'); 1.4

sys = 25/(s^2+4*s+25); 1.2


[y,t] = step(sys,4); 1

0.8
plot(t,y,'r');
y(t)

xlim([0 4]); 0.6

ylim([0 1.4]); 0.4

title('step response'); 0.2


xlabel('t'); 0
ylabel('y(t)'); 0 1 2 3 4
t
grid
set(gcf,'Position',[10,10,310,310]);

15
1.2. Obtain the step response of an LTI . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

restart:
with(DynamicSystems):
sys := TransferFunction(25/(s^2+4*s+25)):
ResponsePlot(sys, Step(),duration=4);

16
1.3. plot the impulse and step responses . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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
𝐻 (𝑠) =
𝑠2
+ 0.2𝑠 + 1
and display these on the same plot up to some 𝑡 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.

17
1.3. plot the impulse and step responses . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Clear["Global`*"]; {1 - E^(-t/10) Cos[(3 Sqrt


SetDirectory[NotebookDirectory[]] [11] t)/10]
sys = TransferFunctionModel - (
[1/(s^2 + 2/10 s + 1), s]; E^(-t/10) Sin[(3 Sqrt[11]t)
/10])/
(3
yStep = Assuming[t > 0,
Sqrt[11])}
Simplify@OutputResponse[
sys, UnitStep[t], t]]

{(10 E^(-t/10) HeavisideTheta


yImpulse = Simplify@ [t]
OutputResponse[sys,DiracDelta[t],t] Sin[(3 Sqrt[11] t)/10])/(3
Sqrt[11])}

p = Grid[{
{Plot[Evaluate@{yStep, yImpulse},
{t, 0, 50},
PlotRange -> {{0, 50}, {-0.8, 2.0}}, 2.0
step and impulse reponse

Frame -> True,


1.5

FrameLabel -> {{"y(t)", None},


{t, "step and impulse reponse"}}, 1.0

GridLines -> Automatic,


y(t)

0.5

GridLinesStyle -> Dashed, 0.0

ImageSize -> {300, 300},


-0.5

PlotStyle -> {Red, Black}, 0 10 20 30 40 50

AspectRatio -> 1] t

ⅇ-t/10 Sin
3 11 t

step response=1 - ⅇ-t/10 Cos 3 11 t

},
10
10
 - 
3 11
3 11 t
10 ⅇ-t/10 HeavisideTheta[t] Sin 
impulse response=
{Row[{"step response=", Re@yStep}]},
10

3 11

{Row[{"impulse response=",Re@yImpulse}]}
}, Alignment -> Left, Frame -> True]

18
1.3. plot the impulse and step responses . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear all; close all;


t = 0:0.05:50;
s = tf('s');
sys = 1/(s^2+0.2*s+1);
Step and Impulse responses
2

y = step(sys,t); step
impulse
1.5
plot(t,y,'-r')
hold on 1

y = impulse(sys,t);

y(t)
0.5
plot(t,y,'-k')
title('Step and Impulse responses'); 0

xlabel('t');
-0.5
ylabel('y(t)');
xlim([0 50]); 0 10 20 30 40 50
t
ylim([-0.8 2]);
legend('step','impulse');
grid on;
set(gcf,'Position',[10,10,310,310]);

19
1.3. plot the impulse and step responses . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

Using Maple DynamicSystems


restart:
alias(DS=DynamicSystems):
sys:=DS:-TransferFunction(1/(s^2+0.2*s+1)):
p1:=DS:-ResponsePlot(sys, DS:-Step(),
duration=50,color=red,legend="step"):
p2:=DS:-ImpulseResponsePlot(sys,
50,
legend="impulse"):
plots:-display([p1,p2],axes=boxed,
title=`step and impulse reponses`);

Using Laplace transform method:


with(inttrans):
with(plottools):
H:=1/(s^2+0.2*s+1);
input:=laplace(Heaviside(t),t,s):
yStep:=invlaplace(input*H,s,t);
input:=laplace(Dirac(t),t,s):
yImpulse:=invlaplace(input*H,s,t);
plot([yStep,yImpulse],t=0.001..50,
title=`step response`,
labels=[`time`,`y(t)`],
color=[red,black],
legend=["step","impulse"]);

20
1.4. Obtain the response of a transfer . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.4 Obtain the response of a transfer function for an


arbitrary input
Problem: Find the response for the continuous time system defined by the transfer function

1
𝐻(𝑠) =
𝑠2 + 0.2𝑠 + 1
when the input is given by
𝑢(𝑡) = sin(𝑡)
and display the response and input on the same plot.
Side note: It was easier to see the analytical form of the responses in Mathematica and
Maple so it is given below the plot.

Mathematica

Clear["Global`*"];
SetDirectory[NotebookDirectory[]]
sys=TransferFunctionModel[1/(s^2+2/10 s+1),s];
u = Sin[t];
y = OutputResponse[sys, u, t]; input and its reponse

p = Grid[{ 4

{Plot[Evaluate@{y, u}, {t, 0, 50}, 2

PlotRange -> {{0, 50}, {-5, 5}},


Frame -> True,
y(t)

FrameLabel -> {{"y(t)", None}, -2

{"t", "input and its reponse"}},


GridLines -> Automatic, -4

GridLinesStyle -> Dashed,


0 10 20 30 40 50
t

ImageSize -> {300, 300},


PlotStyle -> {Red, Black},
AspectRatio -> 1]
}
}, Alignment -> Left, Frame -> True]

21
1.4. Obtain the response of a transfer . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear all;
close all;
t = 0:0.05:50; input and its response
u = sin(t); 5

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');
-5
xlabel('t'); ylabel('y(t)'); 0 10 20 30 40 50

xlim([0 50]); t

ylim([-5 5]);
grid on;
set(gcf,'Position',[10,10,310,310]);

22
1.4. Obtain the response of a transfer . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

restart;
with(inttrans):H:=1/(s^2+0.2*s+1);
input:=sin(t);
inputS:=laplace(input,t,s):
y:=invlaplace(inputS*H,s,t);
plot([y,input],t=0..25,
title=`system response`,
labels=[`time`,`y(t)`],
color=[black,red],
legend=["response","input"]);

Using DynamicSystem package


restart:
alias(DS=DynamicSystems):
sys :=DS:-TransferFunction(1/(s^2+0.2*s+1)):
p1:=DS:-ResponsePlot(sys, sin(t),
duration=25,color=black,legend="response"):
p2:=plot(sin(t),t=0..25,color=red,
legend="input",size=[400,"default"]):
plots:-display([p2,p1],axes=boxed,
title="step and impulse reponses",
legendstyle= [location=right]);

23
1.5. Obtain the poles and zeros of a . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.5 Obtain the poles and zeros of a transfer function


Problem: Find the zeros, poles, and gain for the continuous time system defined by the
transfer function
25
𝐻(𝑠) =
𝑠2 + 4𝑠 + 25

Mathematica
{{{}}}
Clear["Global`*"];
sys=TransferFunctionModel[25/(s^2+4 s+25),s];
TransferFunctionZeros[sys]

TransferFunctionPoles[sys]//N {{{-2.-4.58258 I,-2.+4.58258


I}}}

Matlab

clear all; z =
s = tf('s'); Empty matrix: 0-by-1
sys = 25/(s^2+4*s+25);
[z,p,k] =zpkdata(sys,'v') p =
-2.0000 + 4.5826i
-2.0000 - 4.5826i

Maple
zeros:= []
restart; poles:=
alias(DS=DynamicSystems): [-2.000000000-4.582575695*
sys:=DS:-TransferFunction(25/(s^2+4*s+25)): I,
r :=DS:-ZeroPolePlot(sys,output=data): -2.+4.582575695*I]
zeros := r[1];
poles := r[2];

24
1.6. Generate Bode plot of a transfer function CHAPTER 1. CONTROL SYSTEMS, . . .

1.6 Generate Bode plot of a transfer function


Problem: Generate a Bode plot for the continuous time system defined by the transfer
function
5𝑠
𝐻(𝑠) =
𝑠2 + 4𝑠 + 25

Mathematica

Clear["Global`*"];
Bode plot

tf=TransferFunctionModel[(5 s)/(s^2+4s+25),s]; 0

-20

magnitude (db)
BodePlot[tf, GridLines -> Automatic, -40

ImageSize -> 300, -60

FrameLabel -> {{{"magnitude (db)", None}, 0.1 1 10 100

{None, "Bode plot"}},


{{"phase(deg)", None}, 50

phase(deg)
{"Frequency (rad/sec)", None}}}, 0

ScalingFunctions -> {{"Log10", "dB"}, -50

{"Log10", "Degree"}}, 0.1 1 10 100

PlotRange -> {{{0.1, 100}, Automatic}, Frequency (rad/sec)

{{0.1, 100}, Automatic}}


]

Bode Diagram
Matlab 10

0
Magnitude (dB)

-10
clear all; -20

s = tf('s'); -30

sys = 5*s / (s^2 + 4*s + 25); -40


90

bode(sys);
Phase (deg)

45

grid; 0

set(gcf,'Position',[10,10,400,400]); -45

-90
10 -1 10 0 10 1 10 2
Frequency (rad/s)

25
1.6. Generate Bode plot of a transfer function CHAPTER 1. CONTROL SYSTEMS, . . .

Maple

restart:
alias(DS=DynamicSystems):
sys:=DS:-TransferFunction(5*s/(s^2+4*s+25)):
DS:-BodePlot(sys,output=dualaxis,
range=0.1..100);

or can plot the the two bode figures on top of each others
as follows
DS:-BodePlot(sys,size=[400,300],
output=verticalplot,range=0.1..100);

26
1.7. How to check that state space system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.7 How to check that state space system 𝑥′ = 𝐴𝑥 + 𝐵𝑢 is


controllable?
A system described by

𝑥′ = 𝐴𝑥 + 𝐵𝑢
𝑦 = 𝐶𝑥 + 𝐷𝑢

Is controllable if for any initial state 𝑥0 and any final state 𝑥𝑓 there exist an input 𝑢 which
moves the system from 𝑥0 to 𝑥𝑓 in finite time. Only the matrix 𝐴 and 𝐵 are needed to decide
on controllability. If the rank of

[𝐵 𝐴𝐵 𝐴2 𝐵 … 𝐴𝑛−1 𝐵]

is 𝑛 which is the number of states, then the system is controllable. Given the matrix
⎛ ⎞
⎜⎜ 0 1 0 0 ⎟⎟
⎜⎜ ⎟
⎜⎜ 0 0 −1 0 ⎟⎟⎟
𝐴 = ⎜⎜ ⎜ ⎟⎟
⎜⎜ 0 0 0 1 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
0 0 5 0

And ⎛ ⎞
⎜⎜ 0 ⎟⎟
⎜⎜ ⎟
⎜⎜ 1 ⎟⎟⎟
𝐵 = ⎜⎜ ⎜ ⎟⎟
⎜⎜ 0 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
−2

Mathematica

A0 = {{0, 1, 0, 0}, ⎛ ⎞
{0, 0, -1, 0}, ⎜⎜ 0 1 0 2 ⎟⎟
⎜⎜ ⎟⎟
{0, 0, 0, 1}, ⎜⎜ 1 0 2 0 ⎟⎟⎟
⎜⎜ ⎟⎟
{0, 0, 5, 0}}; ⎜⎜
⎜⎜ 0 −2 0 −10 ⎟⎟⎟
B0 = {{0}, {1}, {0}, {-2}}; ⎜⎝ ⎟⎠
sys = StateSpaceModel[{A0, B0}]; −2 0 −10 0
m = ControllabilityMatrix[sys]

ControllableModelQ[sys]
True

MatrixRank[m]
4

27
1.7. How to check that state space system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

A0 = [0 1 0 0; m =
0 0 -1 0; 0 1 0 2
0 0 0 1; 1 0 2 0
0 0 5 0]; 0 -2 0 -10
B0 = [0 1 0 -2]'; -2 0 -10 0
sys = ss(A0,B0,[],[]);
m = ctrb(sys)

rank(m)
4

Maple

restart:
alias(DS=DynamicSystems):
A:=Matrix( [ [0,1,0,0], ⎡ ⎤
⎢⎢ 0 1 0 2 ⎥⎥
[0,0,-1,0], ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
[0,0,0,1], ⎢⎢ 1 0 2 0 ⎥⎥⎥
⎢⎢ ⎥⎥
[0,0,5,0] ⎢⎢ ⎥⎥
⎢⎢
] ⎢⎢ 0 −2 0 −10 ⎥⎥⎥
⎢⎢ ⎥⎥
); ⎢⎣ ⎥
−2 0 −10 0 ⎦
B:=Matrix([[0],[1],[0],[-2]]);
sys:=DS:-StateSpace(A,B);
m:=DS:-ControllabilityMatrix(sys);

DS:-Controllable(sys,method=rank);
true

DS:-Controllable(sys,method=staircase);
true

LinearAlgebra:-Rank(m);
4

28
1.8. Obtain partial-fraction expansion CHAPTER 1. CONTROL SYSTEMS, . . .

1.8 Obtain partial-fraction expansion


Problem: Given the continuous time S transfer function defined by
𝑠4 + 8𝑠3 + 16𝑠2 + 9𝑠 + 9
𝐻(𝑠) =
𝑠3 + 6𝑠2 + 11𝑠 + 6
obtain the partial-fractions decomposition.
Comment: Mathematica result is easier to see visually since the partial-fraction decomposi-
tion returned in a symbolic form.

Mathematica

Remove["Global`*"]; 2 + s +3/(1+s) -4/(2+s) -6/(3+


expr = (s^4+8 s^3+16 s^2+9 s+6)/ s)
(s^3+6 s^2+11 s+6);
Apart[expr]

r =
-6.0000
Matlab
-4.0000
3.0000
clear all;
s=tf('s'); p =
tf_sys = (s^4+8*s^3+16*s^2+9*s+6)/... -3.0000
(s^3+6*s^2+11*s+6); -2.0000
[num,den] = tfdata(tf_sys,'v'); -1.0000
[r,p,k] = residue(num,den)
k =
1 2

Maple
7 9 9
p:=(s^4+8*s^3+16*s^2+9*s+9)/(s^3+6*s^2+11*s+6); 𝑠+2− − +
𝑠 + 2 2𝑠 + 6 2𝑠 + 2
p0:=convert(p,parfrac);

[op(p0)]; 7 9 9
[𝑠, 2, ,− , ]
𝑠 + 2 2𝑠 + 6 2𝑠 + 2

29
1.9. Obtain Laplace transform for a . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.9 Obtain Laplace transform for a piecewise functions


Problem: Obtain the Laplace transform for the function defined in the following figure.
f(t)

T t

Function f(t) to obtain its Laplace transform


Comment: Mathematica solution was easier than Matlab’s. In Matlab the definition of the
Laplace transform is applied to each piece separately and the result added. Not finding the
piecewise maple function to access from inside MATLAB did not help.

Mathematica
Out[]= (1 - E^((-s)*T))/s
Remove["Global`*"]; ^2
f[t_] := Piecewise[{{0,t<0},
{t,t>= 0 && t< T},
{T, t>T}}]
Simplify[LaplaceTransform[f[t],t,s] ,{T>0}]

Matlab
1 - exp(-T s)
clear all; -------------
syms T t s; 2
syms s positive; 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)

30
1.9. Obtain Laplace transform for a . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Maple
1 − 𝑒−𝑠𝑇
With Maple, had to use Heaviside else Laplace will not 𝑠2
obtain the transform of a piecewise function.
restart;
assume(T>0):
interface(showassumed=0):
f:=t->piecewise(t<0,0,t>=0 and t<T,t,t>T,T):
r:=convert(f(t),Heaviside):
r:=inttrans[laplace](r,t,s);

31
1.10. Obtain Inverse Laplace transform of . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.10 Obtain Inverse Laplace transform of a transfer


function
Problem: Obtain the inverse Laplace transform for the function

𝑠4 + 5𝑠3 + 6𝑠2 + 9𝑠 + 30
𝐻(𝑠) =
𝑠4 + 6𝑠3 + 21𝑠2 + 46𝑠 + 30

Mathematica
Remove["Global`*"];
f = (s^4+5 s^3+6 s^2+9 s+30)/(s^4+6 s^3+21 s^2+46 s+30);
InverseLaplaceTransform[f,s,t];
Expand[FullSimplify[%]]

1 𝑖 −3𝑡 23𝑒−𝑡
𝛿(𝑡) + � + 𝑒 (−1−3𝑖)𝑡 �(73 + 326𝑖)𝑒6𝑖𝑡 + (−326 − 73𝑖)� − 3𝑒 +

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)

4 3 2
s + 5 s + 6 s + 9 s + 30
-----------------------------
4 3 2
s + 6 s + 21 s + 46 s + 30

pretty(ilaplace(f))

/ 399 sin(3 t) \
253 exp(-t) | cos(3 t) + ------------ |
23 exp(-t) 3 exp(-3 t) \ 253 /
---------- - ----------- + dirac(t) - ---------------------------------------
18 26 117

Maple

restart;
interface(showassumed=0):
p:=(s^4+5*s^3+6*s^2+9*s+30)/(s^4+6*s^3+21*s^2+46*s+30);
r:=inttrans[invlaplace](p,s,t);
32
1.10. Obtain Inverse Laplace transform of . . . CHAPTER 1. CONTROL SYSTEMS, . . .

3 e−3 𝑡 (−506 cos (3 𝑡) − 798 sin (3 𝑡) + 299) e−𝑡


𝐷𝑖𝑟𝑎𝑐 (𝑡) − +
26 234

33
1.11. Display the response to a unit step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.11 Display the response to a unit step of an under,


critically, and over damped system
Problem: Obtain unit step response of the second order system given by the transfer function

𝜔𝑛2
𝐻 (𝑠) =
𝑠2 + 2𝜉𝜔𝑛 𝑠 + 𝜔𝑛2

in order to illustrate the response when the system is over, under, and critically damped.
use 𝜔𝑛 = 1 and change 𝜉 over a range of values that extends from under damped to over
damped.
Mathematica
Clear["Global`*"];
Needs["PlotLegends`"]

sys=TransferFunctionModel[w^2/(s^2+2*z*w*s+w^2),s];
zValues = Range[.2,1.2,.2];
fun = OutputResponse[sys/.{w->1,z->#}, UnitStep[t],
{t,0,20}]&/@zValues;

Plot[Evaluate@Flatten@Table[fun[[i]],
{i,1,Length[fun]}],
{t,0,20},
Frame->True,
FrameLabel->{{"y(t)",None},
{"t","step response for different \[Xi] values"}},
PlotRange->{{0,20},{0,1.6}},
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotLegend->zValues,
LegendPosition->{0.76,-0.5},LegendSize -> 1,
LegendLabel -> "\[Xi] values",
ImageSize -> 450,
LabelStyle -> 14,AspectRatio -> 1
]

34
1.11. Display the response to a unit step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

step response for different ξ values

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]);

35
1.11. Display the response to a unit step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

2nd order system step response with changing 1


1.6
0.2
1.4 0.4
0.6
0.8
1.2 1.0
1.2
1

amplitude
0.8

0.6

0.4

0.2

0
0 5 10 15 20
time (sec)

Maple
restart;
alias(DS=DynamicSystems):
H := (w,zeta)->w^2/(s^2+2*zeta*w*s+w^2):
sys := (w,zeta)->DS:-TransferFunction(H(w,zeta)):
zetaValues := [seq(i,i=0.1..1.2,.2)]:
sol:=map(z->DS:-Simulate(sys(1,z),
Heaviside(t)),zetaValues):
c :=ColorTools:-GetPalette("Niagara"):

plots:-display(seq(plots[odeplot]
(sol[i],t=0..20,color=c[i],

legend=typeset(zeta,"=",zetaValues[i]),
legendstyle=[location=right]),
i=1..nops(zetaValues)),
gridlines=true,
title="step response for different damping ratios",
labels=[typeset(t),typeset(y(t))]);

Instead of using Simulate as above, another option is to use ResponsePlot which gives
same plot as above.
restart;
alias(DS=DynamicSystems):
c:=ColorTools:-GetPalette("Niagara"):
H:=(w,zeta)->w^2/(s^2+2*zeta*w*s+w^2):
sys:= (w,zeta)->
DS:-TransferFunction(H(w,zeta)):
zetaValues := [seq(i,i=0.1..1.2,.2)]:

36
1.11. Display the response to a unit step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

sol:=map(i->DS:-ResponsePlot(sys(1,zetaValues[i]),
Heaviside(t),
duration=14,
color=c[i],
legend=typeset(zeta,"=",zetaValues[i]),
legendstyle=[location=right]
),
[seq(i,i=1..nops(zetaValues))]
):

plots:-display(sol,gridlines=true,
title="step response for different damping ratios",
labels=[typeset(t),typeset(y(t))]
);

37
1.12. View steady state error of 2nd order . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.12 View steady state error of 2nd order LTI system


with changing undamped natural frequency
Problem: Given the transfer function
𝜔𝑛2
𝐻 (𝑠) =
𝑠2 + 2𝜉𝜔𝑛 𝑠 + 𝜔𝑛2

Display the output and input on the same plot showing how the steady state error changes
as the un damped natural frequency 𝜔𝑛 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 𝜔𝑛 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
1.12.1.1 ramp input
Remove["Global`*"];
sys = TransferFunctionModel[w^2 /(s^2+2 z w s+w^2 ),s];
z = .707;
nTrials = 6;
maxTime = 10;

tb = Table[Plot[
Evaluate@{t,OutputResponse[sys/.w->0.2*i,t,t]},
{t,0,maxTime},
Frame->True,
PlotRange->All,
FrameLabel->{
{"y(t)",None},
{"t","Subscript[\[Omega], n]="<>ToString[0.2*i]}
}
],
{i,1,nTrials}];
Grid[Partition[tb,2]]

38
1.12. View steady state error of 2nd order . . . CHAPTER 1. CONTROL SYSTEMS, . . .

ω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

1.12.1.2 step input


tb = Table[Plot[
Evaluate@{UnitStep[t],
OutputResponse[sys/.w->0.2*i,UnitStep[t],t]},
{t,0,maxTime},
Frame->True,
PlotRange->All,
FrameLabel->{
{"y(t)",None},
{"t","Subscript[\[Omega], n]="<>ToString[0.2*i]}
}
],
{i,1,nTrials}];

Grid[Partition[tb,2]]

39
1.12. View steady state error of 2nd order . . . CHAPTER 1. CONTROL SYSTEMS, . . .

ω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

40
1.13. Show the use of the inverse Z transform CHAPTER 1. CONTROL SYSTEMS, . . .

1.13 Show the use of the inverse Z transform


These examples show how to use the inverse a Z transform.

1.13.1 example 1
Problem: Given
𝑧
𝐹 (𝑧) =
𝑧−1
find 𝑥[𝑛] = 𝐹−1 (𝑧) which is the inverse Ztransform.
Mathematica

Clear["Global`*"];

x[n_]:= InverseZTransform[z/(z-1),z,n]
z
Inverse Ztransform of
z-1

1.2
ListPlot[Table[{n,x[n]},{n,0,10}],
1.0 ● ● ● ● ● ● ● ● ● ● ●
Frame->True, 0.8

FrameLabel->{{"x[n]",None}, x[n]
0.6

{"n","Inverse Ztransform of z/(z-1)"}}, 0.4

0.2
FormatType->StandardForm,
0.0
RotateLabel->False, 0 2 4 6 8 10
n
Filling->Axis,
FillingStyle->Red,
PlotRange->{Automatic,{0,1.3}},
PlotMarkers->{Automatic,12}]

41
1.13. Show the use of the inverse Z transform CHAPTER 1. CONTROL SYSTEMS, . . .

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);

stem(xn);
title('Inverse Z transform of z/(z-1)'); Inverse Z transform of z/(z-1)

1.2
xlabel('n'); ylabel('x[n]');
ylim([0 1.3]); 1

set(gcf,'Position',[10,10,400,400]); 0.8

x[n]
0.6

end 0.4

0.2

%function from Signal Processing by Proakis


%corrected a little by me for newer matlab version
0
0 2 4 6 8 10 12
n

function [x,n] = impseq(n0,n1,n2)


% Generates x(n) = delta(n-n0); n1 <= n,n0 <= n2
% ----------------------------------------------
% [x,n] = impseq(n0,n1,n2)
%
if ((n0 < n1) || (n0 > n2) || (n1 > n2))
error('arguments must satisfy n1 <= n0 <= n2')
end
n = n1:n2;
x = (n-n0) == 0;
end

1.13.2 example 2
Problem: Given
5𝑧
𝐹 (𝑧) =
(𝑧 − 1)2
find 𝑥[𝑛] = 𝐹−1 (𝑧)
In Mathematica analytical expression of the inverse Z transform can be generated as well
as shown below

42
1.13. Show the use of the inverse Z transform CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Clear["Global`*"];

x[n_]:= InverseZTransform[(5 z)/(z-1)^2,z,n];


Print["Inverse Z is ", x[n]]

Inverse Z is 5 n Inverse Ztransform of


5z
(z - 1)2
60

ListPlot[Table[{n,x[n]},{n,0,10}], 50

Frame->True, 40

x[n] 30 ●
FrameLabel->{{"x[n]",None}, 20 ●

{"n","Inverse Ztransform of (5 z)/(z-1)^2"}}, 10




0
FormatType->StandardForm, ●
0 2 4
n
6 8 10

RotateLabel->False,
Filling->Axis,
FillingStyle->Red,
PlotRange->{Automatic,{0,60}},
PlotMarkers->{Automatic,12},
ImageSize->350]

Matlab

function e19_2()

nSamples = 10; Inverse Z transform of 5z/(z-1)2

z = tf('z');
60

h = (5*z)/(z-1)^2; 50

[num,den] = tfdata(h,'v'); 40
[delta,~] = impseq(0,0,nSamples);
xn = filter(num,den,delta);
x[n]

30

20

stem(xn);
title('Inverse Z transform of 5z/(z-1)^2'); 10

xlabel('n'); ylabel('x[n]'); 0
0 2 4 6 8 10 12
ylim([0 60]); n

set(gcf,'Position',[10,10,400,400]);

end

43
1.14. Find the Z transform of sequence x(n) CHAPTER 1. CONTROL SYSTEMS, . . .

1.14 Find the Z transform of sequence x(n)


1.14.1 example 1
Find the Z transform for the unit step discrete function
Given the unit step function 𝑥[𝑛] = 𝑢[𝑛] defined as 𝑥 = {1, 1, 1, ⋯} for 𝑛 ≥ 0 , find its Z
transform.
Mathematica

Remove["Global`*"]; Out[] = z/(-1+z)


ZTransform[UnitStep[n],n,z]

Matlab

syms n 1
pretty(ztrans(heaviside(n))) ----- + 1/2
z - 1

1.14.2 example 2
𝑛
1
Find the Z transform for 𝑥[𝑛] = � 3 � 𝑢 (𝑛) + (0.9)𝑛−3 𝑢 (𝑛)

Mathematica
z (3/(-1+3 z)+10000/(729
f[n_]:=((1/3)^n+(9/10)^(n-3))UnitStep[n]; (-9+10 z)))
ZTransform[f[n],n,z]

Matlab
100 1
syms n ------------- + ------- +
pretty(ztrans( 1729/1458
((1/3)^n+(0.9)^(n-3)) 81 (z - 9/10) 3 z - 1
*heaviside(n)))

44
1.15. Sample a continuous time system CHAPTER 1. CONTROL SYSTEMS, . . .

1.15 Sample a continuous time system


Given the following system, sample the input and find and plot the plant output

ZOH
Plant
ut  e t sint ukT ykT
1e Ts 3s
T1 s
Sampling s1s2
period
1  ut  T

t
0 T

Equivalent discrete time


system is given by the Z
1e Ts 3s
transform of the ZOH Z s s1s2
Laplace transform times
the plant transfer
function

In Mathematica, the above is implemented as follows

s = tf('s');
plant = (1/s)*(1/(s+0.5));
c2d(plant,sampleTime,'zoh')

In Matlab it is implemented
as follows

Use sampling frequency 𝑓 = 1 Hz and show the result for up to 14 seconds. Use as input the
signal 𝑢(𝑡) = exp(−0.3𝑡) sin(2𝜋(𝑓/3)𝑡).
Plot the input and output on separate plots, and also plot them on the same plot.
Mathematica

Clear["Global`*"];

45
1.15. Sample a continuous time system CHAPTER 1. CONTROL SYSTEMS, . . .

nSamples =14;
f =1.0;
sampleTime =1/f;
u[t_] := Sin[2*Pi*(f/3)*t]*Exp[-0.3*t]
ud[n_]:= u[n*sampleTime];
plant = TransferFunctionModel[
(3 s)/((s+1)(s+2)),s];
sysd = ToDiscreteTimeModel[plant,
sampleTime,
z,
Method->"ZeroOrderHold"]

-0.697632 + 0.697632 z 
 
0.0497871 - 0.503215 z + z 2 1.

opts = {Joined->True,PlotRange->All,
AspectRatio->1,InterpolationOrder->0,
ImageSize->200,Frame->True,
PlotRange->{{0,nSamples},{-0.5,0.5}},
GridLines->Automatic,GridLinesStyle->Dashed};

inputPlot = ListPlot[Table[ud[k],{k,0,nSamples}],
Evaluate[opts],
FrameLabel->{{"u(t)",None},
{"n","plant input u(nT)"}},
PlotStyle->{Thick,Red}];

plantPlot=ListPlot[OutputResponse[sysd,Table[ud[k],
{k,0,nSamples}]],
Evaluate[opts],
FrameLabel->{{"y(t)",None},
{"n","plant output y(nT)"}},
PlotStyle->{Thick,Blue}];

Grid[{{inputPlot,plantPlot}}]

46
1.15. Sample a continuous time system CHAPTER 1. CONTROL SYSTEMS, . . .

plant input u(nT) plant output y(nT)

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

Show[{inputPlot,plantPlot},
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

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')

47
1.15. Sample a continuous time system CHAPTER 1. CONTROL SYSTEMS, . . .

plantD =

0.6976 z - 0.6976
------------------------
z^2 - 0.5032 z + 0.04979

Sample time: 1 seconds


Discrete-time transfer function.

lsim(plantD,U,0:nSamples-1)
grid

Linear Simulation Results


0.8

0.6

0.4
Amplitude

0.2

-0.2

-0.4

-0.6
0 5 10
Time (seconds)

48
1.16. Find closed loop transfer function . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.16 Find closed loop transfer function from the open


loop transfer function for a unity feedback
Problem: Given
𝑠
𝐿(𝑠) =
(𝑠 + 4)(𝑠 + 5)
as the open loop transfer function, how to find 𝐺(𝑠), the closed loop transfer function for a
unity feedback?

Ls
Rs s Cs
s4 s5 

Convert to

Rs
Gs Cs

49
1.16. Find closed loop transfer function . . . CHAPTER 1. CONTROL SYSTEMS, . . .

s 
 
(4 + s) (5 + s)
Mathematica

Clear["Global`*"];
sys = TransferFunctionModel[
s/((s+4)(s+5)),s]

s 
 2

20 + 10 s + s

closedLoop = SystemsModelFeedbackConnect[sys];

The system wrapper can be removed in order to obtain


𝑠
the rational polynomial expression as follows
𝑠2 + 10𝑠 + 20
First[Flatten[closedLoop[[1,1]]/
closedLoop[[1,2]]]]

Matlab
Transfer function:
clear all; close all; s
s=tf('s'); ---------------
sys=s/((s+4)*(s+5)); s^2 + 10 s + 20
closedloop=feedback(sys,1)

50
1.17. Compute the Jordan . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.17 Compute the Jordan canonical/normal form of a


matrix A
Mathematica

Remove["Global`*"]; ⎛ ⎞
⎜⎜ 3 −1 1 1 0
0 ⎟⎟
m={{3,-1,1,1,0,0}, ⎜⎜ ⎟⎟
⎜⎜ 1 1 −1 −1 0 0 ⎟⎟⎟
{1, 1,-1,-1,0,0}, ⎜⎜ ⎟⎟
⎜⎜
{0,0,2,0,1,1}, ⎜⎜ 0 0 2 0 1 1 ⎟⎟⎟
⎜⎜ ⎟⎟
{0,0,0,2,-1,-1}, ⎜⎜ 0 0 0 2 −1 −1 ⎟⎟⎟
⎜⎜ ⎟⎟
⎜⎜
{0,0,0,0,1,1}, ⎜⎜ 0 0 0 0 1 1 ⎟⎟⎟
⎜⎝ ⎟⎠
{0,0,0,0,1,1}}; 0 0 0 0 1 1
MatrixForm[m]

⎛ ⎞
⎜⎜ 0 0 0 0 0 0 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 0 2 1 0 0 0 ⎟⎟⎟
⎜⎜ ⎟⎟
{a,b}=JordanDecomposition[m]; ⎜⎜
⎜⎜ 0 0 2 0 0 0 ⎟⎟⎟
b ⎜⎜ ⎟⎟
⎜⎜ 0 0 0 2 1 0 ⎟⎟⎟
⎜⎜ ⎟⎟
⎜⎜
⎜⎜ 0 0 0 0 2 1 ⎟⎟⎟
⎜⎝ ⎟⎠
0 0 0 0 0 2

Matlab

clear all; ans =


A=[3 -1 1 1 0 0; 0 0 0 0 0 0
1 1 -1 -1 0 0; 0 2 1 0 0 0
0 0 2 0 1 1; 0 0 2 1 0 0
0 0 0 2 -1 -1; 0 0 0 2 0 0
0 0 0 0 1 1; 0 0 0 0 2 1
0 0 0 0 1 1;] 0 0 0 0 0 2

jordan(A)

51
1.18. Solve the continuous-time algebraic . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.18 Solve the continuous-time algebraic Riccati


equation
Problem: Solve for 𝑋 in the Riccati equation

𝐴′ 𝑋 + 𝑋𝐴 − 𝑋𝐵𝑅−1 𝐵′ 𝑋 + 𝐶′ 𝐶 = 0

given
⎛ ⎞
⎜⎜−3 2⎟⎟
𝐴 = ⎜⎜⎝ ⎟⎟
1 1⎠
⎛ ⎞
⎜⎜0⎟⎟
𝐵 = ⎜⎝⎜ ⎟⎠⎟
1
𝐶 = �1 −1�
𝑅=3

Mathematica

Clear ["Global`*"];
a={{-3,2},{1,1}};
⎛ ⎞
b={{0},{1}}; ⎜⎜ 0.589517 1.82157 ⎟⎟
c={{1,-1}}; ⎜⎜ ⎟⎟
⎝ 1.82157 8.81884 ⎠
r={{3}};
sol=RiccatiSolve[{a,b},{Transpose[c].c,r}];
MatrixForm[N[sol]]

Matlab

%needs control system


clear all; close all; x =
a = [-3 2;1 1]; 0.5895 1.8216
b = [0 ; 1]; 1.8216 8.8188
c = [1 -1];
r = 3;
x = care(a,b,c'*c,r)

52
1.19. Solve the discrete-time algebraic . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.19 Solve the discrete-time algebraic Riccati equation


Problem: Given a continuous-time system represented by a transfer function

1
𝑠(𝑠 + 0.5)

convert this representation to state space and sample the system at sampling period of 1
second, and then solve the discrete-time Riccati equation.
The Riccati equation is given by

𝐴′ 𝑋 + 𝑋𝐴 − 𝑋𝐵𝑅−1 𝐵′ 𝑋 + 𝐶′ 𝐶 = 0

Let 𝑅 = [3].
Mathematica

Clear["Global`*"];
sys=TransferFunctionModel[1/(s(s+.5)),s]; 0.360816 + 0.426123 z 
 
0.606531 - 1.60653 z + z2 1.
dsys=ToDiscreteTimeModel[sys,
1,z,Method->"ZeroOrderHold"]

ss = StateSpaceModel[dsys] 0 1. 0 
-0.606531 1.60653 1.
0.360816 0.426123 0 1.

a = ss[[1,1]];
b = ss[[1,2]];
c = ss[[1,3]];
d = ss[[1,4]]; ⎛ ⎞
r = {{3}}; ⎜⎜ 0.671414 −0.977632 ⎟⎟
⎜⎜ ⎟
DiscreteRiccatiSolve[{a,b}, ⎝ −0.977632 2.88699 ⎟⎠
{Transpose[c].c,r}];
MatrixForm[%]

53
1.19. Solve the discrete-time algebraic . . . CHAPTER 1. CONTROL SYSTEMS, . . .

dsys =
Matlab 0.4261 z + 0.3608
----------------------
clear all; close all; z^2 - 1.607 z + 0.6065
s = tf('s');
sys = 1/(s*(s+0.5)); Sample time: 1 seconds
dsys = c2d(sys,1) Discrete-time transfer
function.

A =
1.6065 -0.6065
1.0000 0
B =
1
0
[A,B,C,D]=dssdata(dsys) C =
0.4261 0.3608
D =
0

2.8870 -0.9776
-0.9776 0.6714

ans =
dare(A,B,C'*C,3)
2.8870 -0.9776
-0.9776 0.6714

54
1.20. Display impulse response of H(z) . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.20 Display impulse response of H(z) and the impulse


response of its continuous time approximation H(s)
Plot the impulse response of 𝐻(𝑧) = 𝑧/(𝑧2 − 1.4𝑧 + 0.5) and using sampling period of 𝑇 = 0.5
find continuous time approximation using zero order hold and show the impulse response
of the system and compare both responses.
Mathematica

maxSimulationTime = 10;
samplePeriod = 0.5;
tf = TransferFunctionModel[z/(z^2-1.4 z+0.5),
z,
SamplingPeriod->samplePeriod];

z 
 
0.5 - 1.4 z + z2 0.5

Find its impulse response


discreteResponse=First@OutputResponse[tf,DiscreteDelta[k],
{k,0,maxSimulationTime}]

{0.,1.,1.4,1.46,1.344,1.1516,0.94024,0.740536,
0.56663,0.423015,0.308905,0.22096,0.154891,
0.106368,0.0714694,0.0468732,0.0298878,
0.0184063,0.0108249,0.00595175,0.00291999}

approximate to continuous time, use ZeroOrderHold


ctf = ToContinuousTimeModel[tf, s, Method -> "ZeroOrderHold"]

5.60992 + 1.25559 s 
 
0.560992 + 1.38629 s + s2

Find the impulse response of the continuous time system


continouseTimeResponse=Chop@First@OutputResponse[ctf,DiracDelta[t],t]

−1.25559𝑒−0.693147𝑡 (−13.3012𝜃(𝑡) sin(0.283794𝑡) − 1.𝜃(𝑡) cos(0.283794𝑡))

continouseTimeResponse=Chop@First@OutputResponse[ctf,DiracDelta[t],
{t,0,maxSimulationTime}]
55
1.20. Display impulse response of H(z) . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Domain: {{0., 10.}}


InterpolatingFunction [t]
Output: scalar

Plot the impulse response of the discrete system


ListPlot[
discreteResponse,
DataRange->{0,maxSimulationTime},
Filling->Axis,
FillingStyle->{Red,
PlotMarkers->Graphics[{PointSize[0.03],
Point[{0,0}]}]},PlotRange->All,
ImageSize->300,ImagePadding->{{45,10},{35,10}},
AspectRatio->0.9,AxesOrigin->{0,0},Frame->True,Axes->None,
ImageSize->300,
Frame->True
]

1.4

1.2

1.0

0.8

0.6

0.4

0.2

0.0
0 2 4 6 8 10

Plot the impulse response of the continuous system


Plot[samplePeriod *continouseTimeResponse,{t,0,maxSimulationTime},
PlotRange->All,Frame->True,ImageSize->300]

56
1.20. Display impulse response of H(z) . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.5

1.0

0.5

0.0
0 2 4 6 8 10

Plot both responses on the same plot


p = Show[
ListPlot[
discreteResponse,
Filling -> Axis,
FillingStyle -> {Red,
PlotMarkers -> Graphics[{PointSize[0.03], Point[{0, 0}]}]},
PlotRange -> All,
DataRange -> {0, maxSimulationTime},
ImageSize -> 300,
ImagePadding -> {{45, 10}, {35, 50}},
AspectRatio -> 0.9,
AxesOrigin -> {0, 0},
Frame -> True,
Axes -> None],
Plot[samplePeriod *continouseTimeResponse, {t, 0, maxSimulationTime},
PlotRange -> All],
PlotRange -> All,
FrameLabel -> {{Style["response", 10], None},
{Style["time (sec)", 10],
"impulse response of discrete system \
with its continouse time approximatio"}}
]

57
1.20. Display impulse response of H(z) . . . CHAPTER 1. CONTROL SYSTEMS, . . .

impulse response of discrete system with its continouse time approximatio

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
Show[
ListPlot[
discreteResponse,
Filling->None,PlotRange->All,DataRange->{0,maxSimulationTime},
ImageSize->300,ImagePadding->{{45,10},{35,50}},AspectRatio->0.9,
AxesOrigin->{0,0},Frame->True,Axes->None,
Joined->True,InterpolationOrder->0,PlotStyle->Red],
Plot[samplePeriod *continouseTimeResponse,{t,0,maxSimulationTime},
PlotRange->All],
PlotRange->All,FrameLabel->{{Style["response",10],None},
{Style["time (sec)",10],"impulse response"}}]

impulse response of discrete system with its continouse time approximation

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)

58
1.20. Display impulse response of H(z) . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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');

impulse response of discrete system with its continuous time approximation


3

2.5

2
response

1.5

0.5

-0.5
0 5 10 15
time (sec) (seconds)

59
1.21. Find the system type given an open . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.21 Find the system type given an open loop transfer


function
Problem: Find the system type for the following transfer functions
𝑠+1
1. 𝑠2 −𝑠
𝑠+1
2. 𝑠3 −𝑠2
𝑠+1
3. 𝑠5
𝑘 ∑ (𝑠−𝑠𝑖 )
𝑖
To find the system type, the transfer function is put in the form , then the system
𝑠𝑀 ∑ 𝑗
�𝑠−𝑠𝑗 �
type is the exponent 𝑀. Hence it can be seen that the first system above has type one
since the denominator can be written as 𝑠1 (𝑠 − 1) and the second system has type 2 since
the denominator can be written as 𝑠2 (𝑠 − 1) and the third system has type 5. The following
computation determines the type

Mathematica

Clear["Global`*"];
p=TransferFunctionPoles[TransferFunctionModel[ Out[171]= 1
(s+1)/(s^2-s),s]];
Count[Flatten[p],0]

p=TransferFunctionPoles[TransferFunctionModel[
(s+1)/( s^3-s^2),s]];
Count[Flatten[p],0] Out[173]= 2

p=TransferFunctionPoles[
TransferFunctionModel[(s+1)/ s^5 ,s]];
Count[Flatten[p],0] Out[175]= 5

60
1.21. Find the system type given an open . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear all; ans =


s=tf('s'); 1
[~,p,~]=zpkdata((s+1)/(s^2-s));
length(find(p{:}==0))

[~,p,~]=zpkdata((s+1)/(s^3-s^2)); ans =
length(find(p{:}==0)) 2

[~,p,~]=zpkdata((s+1)/s^5); ans =
length(find(p{:}==0)) 5

61
1.22. Find the eigenvalues and . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.22 Find the eigenvalues and eigenvectors of a matrix


Problem, given the matrix
⎛ ⎞
⎜⎜ 1 2 3 ⎟⎟
⎜⎜ ⎟
⎜⎜ 4 5 6 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
7 8 9
Find its eigenvalues and eigenvectors.

Mathematica ⎛ ⎞
⎜⎜ 1 2 3 ⎟⎟
⎜⎜ ⎟
Remove["Global`*"] ⎜⎜ 4 5 6 ⎟⎟⎟
⎜⎜ ⎟⎟
(a = {{1,2,3}, {4,5,6}, {7,8,9}}) ⎝ ⎠
7 8 9
// MatrixForm

3 3
Eigenvalues[a] � �5 + √33� , �5 − √33� , 0�
N[%] 2 2
{16.1168, −1.11684, 0.}

⎛ ⎞
⎜⎜ − −15−√33 4�6+√33�
Eigenvectors[a] ⎜⎜ 33+7 33 1 ⎟⎟⎟⎟
⎜⎜ √ 33+7√33 ⎟⎟
N[%] ⎜⎜ 15− √ 33 4�−6+√33� ⎟⎟
⎜⎜ − 1 ⎟⎟⎟
⎜⎜ −33+7√33 −33+7√33 ⎟⎟
⎜⎝ ⎠
1 −2 1
⎛ ⎞
⎜⎜ 0.283349 0.641675 1. ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ −1.28335 −0.141675 1. ⎟⎟⎟
⎜⎜ ⎟⎠

1. −2. 1.

Matlab
v =
Matlab generated eigenvectors are such that
-0.2320 -0.7858 0.4082
the sum of the squares of the eigenvector -0.5253 -0.0868 -0.8165
elements add to one. -0.8187 0.6123 0.4082
clear all; close all;
e =
A=[1 2 3;4 5 6;7 8 9]; 16.1168 0 0
0 -1.1168 0
[v,e]=eig(A) 0 0 -0.0000

62
1.23. Find the characteristic polynomial . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.23 Find the characteristic polynomial of a matrix


⎛ ⎞
⎜⎜ 1 2 3 ⎟⎟
⎜⎜ ⎟
⎜⎜ 4 5 6 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
7 8 0

Mathematica
−𝑥3 + 6𝑥2 + 72𝑥 + 27
a = {{1,2,3},{4,5,6},{7,8,0}};
CharacteristicPolynomial[a,x]

Matlab
p =
Note: Matlab generated characteristic poly-
1.0000 -6.0000 -72.0000 -27.0000
nomial coefficients are negative to what ans =
Mathematica generated. x^3 - 6 x^2 - 72 x - 27
clear all;
A=[1 2 3;4 5 6;7 8 0];

p=poly(A)
poly2str(p,'x')

63
1.24. Verify the Cayley-Hamilton theorem . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.24 Verify the Cayley-Hamilton theorem that every


matrix is zero of its characteristic polynomial
Problem, given the matrix ⎛ ⎞
⎜⎜ 1 2 ⎟⎟
⎜⎜ ⎟⎟
⎝ 3 2 ⎠

Verify that matrix is a zero of its characteristic polynomial. The Characteristic polynomial
of the matrix is found, then evaluated for the matrix. The result should be the zero matrix.
Mathematica

Remove["Global`*"]
a = {{1,2},{3,2}}; 𝑥2 − 3𝑥 − 4
n = Length[a];
p = CharacteristicPolynomial[a,x]

(-4 IdentityMatrix[n] - 3 a + ⎛ ⎞
⎜⎜ 0 0 ⎟⎟
MatrixPower[a,2])//MatrixForm ⎜⎜ ⎟⎟
⎝ 0 0 ⎠

Another way is as follows


a = {{1,2},{3,2}};
p = CharacteristicPolynomial[a,x]; ⎛ ⎞
⎜⎜ 0 0 ⎟⎟
cl = CoefficientList[p,x]; ⎜⎜ ⎟⎟
⎝ 0 0 ⎠
Sum[MatrixPower[a,j-1] cl[[j]],
{j,1,Length[cl]}]

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
ans =
clear; x^2 - 3 x - 4
A=[1 2;3 2]; ans =
p=poly(A); 0 0
poly2str(p,'x') 0 0
polyvalm(p,A)

64
1.25. How to check for stability of system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.25 How to check for stability of system represented as


a transfer function and state space
Problem: Given a system Laplace transfer function, check if it is stable, then convert to state
space and check stability again. In transfer function representation, the check is that all
poles of the transfer function (or the zeros of the denominator) have negative real part. In
state space, the check is that the matrix A is negative definite. This is done by checking
that all the eigenvalues of the matrix A have negative real part. The poles of the transfer
function are the same as the eigenvalues of the A matrix. Use
5𝑠
𝑠𝑦𝑠 =
𝑠2 + 4𝑠 + 25

1.25.1 Checking stability using transfer function poles


Mathematica

Remove["Global`*"]; {{{-2-I Sqrt[21],-2+I Sqrt


sys =TransferFunctionModel[(5s)/(s^2+4s+25),s]; [21]}}}
poles=TransferFunctionPoles[sys]

Re[#]&/@poles Out[42]= {{{-2,-2}}}

Select[%,#>=0&] Out[44]= {}

Matlab

clear all; >>


s=tf('s'); p =
sys=5*s/( s^2+4*s+25); -2.0000 + 4.5826i
-2.0000 - 4.5826i
[z,p,k]=zpkdata(sys,'v');
p

ans =
find(real(p)>=0)
Empty matrix: 0-by-1

65
1.25. How to check for stability of system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.25.2 Checking stability using state space A matrix


Mathematica

ss=StateSpaceModel[sys]; Out[49]= {{0,1},{-25,-4}}


a=ss[[1,1]]

e=Eigenvalues[a] Out[50]= {-2+I Sqrt[21],-2-I Sqrt[21]}

Re[#]&/@e Out[51]= {-2,-2}

Select[%,#>=0&] Out[52]= {}

Matlab
A =
sys=ss(sys); -4.0000 -6.2500
[A,B,C,D]=ssdata(sys); 4.0000 0
A

e =
e=eig(A) -2.0000 + 4.5826i
-2.0000 - 4.5826i

ans =
find(real(e)>=0)
Empty matrix: 0-by-1

66
1.26. Check continuous system stability in . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.26 Check continuous system stability in the Lyapunov


sense
Problem: Check the stability (in Lyapunov sense) for the state coefficient matrix
⎡ ⎤
⎢⎢ 0 1 0 ⎥⎥
⎢⎢ ⎥⎥
𝐴 = ⎢⎢⎢ 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 𝐴 when calling these functions, since the Lyapunov equation
is defined as 𝐴𝑇 𝑃 + 𝑃𝐴 = −𝑄 and this is not how the software above defines them. By simply
transposing the 𝐴 matrix when calling them, then the result will be correct.

Mathematica
⎛ ⎞
⎜⎜ 0 1 0 ⎟⎟
⎜⎜ ⎟⎟
Remove["Global`*"]; ⎜⎜ 0 0 1 ⎟⎟
⎜⎜ ⎟⎟
(mat = {{0,1,0},{0,0,1},{-1,-2,-3}}) ⎝ ⎠
−1 −2 −3

p = LyapunovSolve[Transpose@mat, ⎛ ⎞
⎜⎜ 2.3 2.1 0.5 ⎟⎟
-IdentityMatrix[Length[mat]]]; ⎜⎜ ⎟
⎜⎜ 2.1 4.6 1.3 ⎟⎟⎟
MatrixForm[N[p]] ⎜⎜ ⎟⎟
⎝ ⎠
0.5 1.3 0.6

N[Eigenvalues[p]]
{6.18272, 1.1149, 0.202375}

67
1.26. Check continuous system stability in . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear all;
p =
A=[0 1 0 2.3 2.1 0.5
0 0 1 2.1 4.6 1.3
0.5 1.3 0.6
-1 -2 -3];

p=lyap(A.',eye(length(A)))

e =
0.20238
e=eig(p)
1.1149
6.1827

Maple
⎡ ⎤
with(LinearAlgebra): ⎢⎢ 6.18272045921436 + 0.0 𝑖 ⎥⎥
⎢⎢ ⎥⎥
A:=<<0,1,0;0,0,1;-1,-2,-3>>; ⎢⎢ ⎥⎥
⎢⎢ 1.11490451203192 + 0.0 𝑖 ⎥⎥
p,s:=LyapunovSolve(A^%T,-<<1,0,0;0,1,0;0,0,1>>); ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎣ ⎦
Eigenvalues(p); 0.202375028753723 + 0.0 𝑖

68
1.27. Given a closed loop block diagram, . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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 𝑇 = 0.1 𝑠𝑒𝑐, generate the
closed loop transfer function, and that poles of the closed loop transfer function are inside
the unit circle

Gs

Ds ZOH Plant


Rs Es Ms
s1 1 Ts s Cs
T1 s5 s s1

System block diagram.


Mathematica

Remove["Global`*"]
plant = TransferFunctionModel[s/(1.0+s),s];
plantd = ToDiscreteTimeModel[
plant,
1,
z,
Method->"ZeroOrderHold"]

1. - 1. z 
 
0.367879 - 1. z 1.

d = ToDiscreteTimeModel[
TransferFunctionModel[(s+1)/(s+5.0),s],
1,
z,
Method->"ZeroOrderHold"]

0.801348 - 1. z 
 
0.00673795 - 1. z 1.

69
1.27. Given a closed loop block diagram, . . . CHAPTER 1. CONTROL SYSTEMS, . . .

sys=SystemsModelSeriesConnect[d,plantd]

(0.801348 - 1. z) (1. - 1. z) 
(0.00673795 - 1. z) (0.367879 - 1. z) 1.

loopBack=SystemsModelFeedbackConnect[sys]

1.5825 × 10 17 (-1. + 1. z) (-0.801348 + 1. z) 


3.92264 × 10 14 - 5.92834 × 10 16 z + 1.5825 × 10 17 z2 + 1.5825 × 10 17 (-1. + 1. z) (-0.801348 + 1. z) 1.

Now generate unit step response


ListPlot[OutputResponse[loopBack,
Table[1, {k, 0, 20}]],
Joined->True,
PlotRange->All,
InterpolationOrder->0,
Frame->True,
PlotStyle->{Thick,Red},
GridLines->Automatic,
GridLinesStyle->Dashed,
FrameLabel->{{"y(k)",None},
{"n","plant response"}},
RotateLabel->False]

plant response
0.5
0.4
0.3
y(k) 0.2
0.1
0.0
-0.1
5 10 15 20
n

ss=StateSpaceModel[loopBack]

70
1.27. Given a closed loop block diagram, . . . CHAPTER 1. CONTROL SYSTEMS, . . .

0 1. 0 
-0.401913 1.08798 1.
0.199717 -0.356683 0.5 1.

poles=TransferFunctionPoles[loopBack]

{0.543991 − 0.325556𝑖, 0.543991 + 0.325556𝑖}

Abs[#]&/@poles

� {0.633966, 0.633966} �

Poles are inside the unit circle, hence stable.


Matlab

clear all; close all

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)

loop =

z^2 - 1.801 z + 0.8013


------------------------
2 z^2 - 2.176 z + 0.8038

Sample time: 1 seconds


Discrete-time transfer function.

step(loop)
grid

71
1.27. Given a closed loop block diagram, . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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)

ans =
0.6340
0.6340

72
1.28. Determine the state response of a . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.28 Determine the state response of a system to only


initial conditions in state space
Problem: Given a system with 2 states, represented in state space, how to determine the
state change due some existing initial conditions, when there is no input forces?

Mathematica

Remove["Global`*"];
a = {{-0.5572,-0.7814},{0.7814, 0}};
-0.5572 -0.7814 1 
c = {{1.9691, 6.4493}}; 0.7814 0 0
sys=StateSpaceModel[ 1.9691 6.4493 0
{a,{{1},{0}},c,{{0}}}]

x0 = {1,0};
{x1,x2} = StateResponse[
{sys,x0},0,{t,0,20}];

Plot[{x1,x2},{t,0,20}, first and second state change with time

PlotRange->All, 1.0

GridLines->Automatic, 0.8

GridLinesStyle->Dashed, 0.6
Frame->True,
0.4
ImageSize->350, y(t)
0.2
AspectRatio->1,
FrameLabel->{{"y(t)",None}, 0.0

{"t", -0.2

"first and second state\ -0.4

change with time" 0 5 10 15 20

}}, t

RotateLabel->False,
PlotStyle->{Red,Blue},
BaseStyle -> 12]

73
1.28. Determine the state response of a . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear;
A = [-0.5572 -0.7814;0.7814 0]; x1 and x2 state change with time
1
B = [1;0];
C = [1.9691 6.4493]; 0.8

x0 = [1 ; 0]; 0.6

0.4
sys = ss(A,B,C,[]);

x(t)
0.2

[y,t,x]=initial(sys,x0,20); 0

plot(t,x(:,1),'r',t,x(:,2),'b'); -0.2
title('x1 and x2 state change with time');
xlabel('t (sec)');
-0.4
0 5 10 15 20
ylabel('x(t)'); t (sec)

grid
set(gcf,'Position',[10,10,320,320]);

74
1.29. Determine the response of a system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.29 Determine the response of a system to only initial


conditions in state space
Problem: Given a system represented by state space, how to determine the response 𝑦(𝑡) due
some existing initial conditions in the states. There is no input forces.

Mathematica

Remove["Global`*"]; -0.5572 -0.7814 1 


a = {{-0.5572, -0.7814}, {0.7814, 0}}; 0.7814 0 0
c = {{1.9691, 6.4493}}; 1.9691 6.4493 0
sys=StateSpaceModel[{a,{{1},{0}},c,{{0}}}]

x0 = {1,0}; (*initial state vector*)


y = OutputResponse[{sys,x0},0,{t,0,20}]; system response

Plot[y,{t,0,20}, 4

PlotRange->All,
3
GridLines->Automatic,
GridLinesStyle->Dashed, 2
y(t)
Frame->True, 1
ImageSize->300,
0
AspectRatio->1,
FrameLabel->{{"y(t)",None}, -1

{"t","system response"}}, 0 5 10 15 20

RotateLabel->False,PlotStyle->Red] t

75
1.29. Determine the response of a system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

clear all;

A = [-0.5572 -0.7814;
0.7814 0]; y(t) plant response
5
B = [1;0];
C = [1.9691 6.4493]; 4

x0 = [1 ; 0]; 3

y(t)
sys = ss(A,B,C,[]); 1

0
[y,t,x]=initial(sys,x0,20);
-1
plot(t,y);
title('y(t) plant response'); -2
0 5 10 15 20
xlabel('t (sec)'); t (sec)

ylabel('y(t)');
grid
set(gcf,'Position',...
[10,10,320,320]);

76
1.30. Determine the response of a system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.30 Determine the response of a system to step input


with nonzero initial conditions
Problem: Given a system represented by state space, how to determine the response with
nonzero initial conditions in the states and when the input is a step input?

Mathematica

Remove["Global`*"];
a = {{-0.5572, -0.7814}, {0.7814, 0}};
-0.5572 -0.7814 1 
c = {{1.9691, 6.4493}}; 0.7814 0 0
sys=StateSpaceModel[ 1.9691 6.4493 0
{a,{{1},{0}},c,{{0}}}]

x0 = {1,0};
y = OutputResponse[{sys,x0},
UnitStep[t],{t,0,20}];
system response to combined initial conditions and step input

Plot[y,{t,0,20}, 12

PlotRange->{{0,20},{0,13}}, 10
GridLines->Automatic,
GridLinesStyle->Dashed, 8

Frame->True, y(t)
6
ImageSize->300,
AspectRatio->1, 4

FrameLabel->{{"y(t)",None},
2
{"t",
"system response to initial\ 0
0 5 10 15 20
conditions and step input"}}, t
RotateLabel->False,
PlotStyle->Red]

77
1.30. Determine the response of a system . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Matlab

A = [-0.5572 -0.7814;0.7814 0];


B = [1;0]; initial conditions and step input response
12
C = [1.9691 6.4493];
x0 = [1 ; 0]; 10

sys = ss(A,B,C,[]); 8

[y1,t] = initial(sys,x0,20);

y(t)
6
y2 = step(sys,t);
4

plot(t,y1+y2,'r');
2

title(['initial conditions and step'...


0
'input response']); 0 5 10 15 20
xlabel('t *sec)'); ylabel('y(t)'); t *sec)
grid
set(gcf,'Position',[10,10,320,320]);

78
1.31. Draw the root locus from the open . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.31 Draw the root locus from the open loop transfer
function
Problem: Given 𝐿(𝑠), the open loop transfer function, draw the root locus. Let

𝑠2 + 2𝑠 + 4
𝐿(𝑠) =
𝑠(𝑠 + 4)(𝑠 + 6)(𝑠2 + 1.4𝑠 + 1)

Root locus is the locus of the closed loop dominant pole as the gain 𝑘 is varied from zero
to infinity.

Mathematica
2

Remove["Global`*"]
sys = TransferFunctionModel[ 1
k*(s^2+2 s+4)/
(s(s+4)(s+6)(s^2+1.4s+1)),s];
0
RootLocusPlot[sys,{k,0,100},
ImageSize->300,
GridLines->Automatic, -1
GridLinesStyle->Dashed,
Frame->True,
AspectRatio -> 1] -2

-8 -6 -4 -2 0

Root Locus
3
Matlab
2
Imaginary Axis (seconds-1 )

clear all; close all;


s=tf('s');
1

sys=(s^2+2*s+4)/... 0

(s*(s+4)*(s+6)*(s^2+1.4*s+1));
-1

rlocus(sys,0:100)
-2
set(gcf,'Position',[10,10,420,420]);
-3
-10 -8 -6 -4 -2 0 2
-1
Real Axis (seconds )

79
1.32. Find 𝑒𝐴𝑡 where 𝐴 is a matrix CHAPTER 1. CONTROL SYSTEMS, . . .

1.32 Find 𝑒𝐴𝑡 where 𝐴 is a matrix


Mathematica

ClearAll["Global`*"]
mat={{0,1},
{-2,-3}}
MatrixExp[mat t];
MatrixForm[%]

⎛ ⎞
⎜⎜ −𝑒−2𝑡 + 2𝑒−𝑡 −𝑒−2𝑡 + 𝑒−𝑡 ⎟⎟
⎜⎜ ⎟⎟
⎝ 2𝑒−2𝑡 − 2𝑒−𝑡 2𝑒−2𝑡 − 𝑒−𝑡 ⎠

Now verify the result by solving for 𝑒𝐴𝑡 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 |𝐴 − 𝜆𝐼|
m = mat-lambda IdentityMatrix[Length[mat]]

⎛ ⎞
⎜⎜ −𝜆 1 ⎟⎟
⎜⎜ ⎟⎟
⎝ −2 −𝜆 − 3 ⎠

Det[m]

𝜆2 + 3𝜆 + 2

sol=Solve[%==0,lambda]

Out[15]= {{lambda->-2},{lambda->-1}}

eig1=lambda/.sol[[1]]
eig2=lambda/.sol[[2]]

Out[16]= -2
Out[17]= -1

(*setup the equations to find b0,b1*)


eq1 = Exp[eig1 t]==b0+b1 eig1;
eq2 = Exp[eig2 t]==b0+b1 eig2;
sol = First@Solve[{eq1,eq2},{b0,b1}]

80
1.32. Find 𝑒𝐴𝑡 where 𝐴 is a matrix CHAPTER 1. CONTROL SYSTEMS, . . .

�b0 → 𝑒−2𝑡 �2𝑒𝑡 − 1� , b1 → 𝑒−2𝑡 �𝑒𝑡 − 1��

(*Now find e^At*)


b0=b0/.sol[[1]]

𝑒−2𝑡 �2𝑒𝑡 − 1�

b1=b1/.sol[[2]]

𝑒−2𝑡 �𝑒𝑡 − 1�

b0 IdentityMatrix[Length[mat]]+b1 mat;
Simplify[%]
MatrixForm[%]

⎛ ⎞
⎜⎜ 𝑒−2𝑡 �−1 + 2𝑒𝑡 � 𝑒−2𝑡 �−1 + 𝑒𝑡 � ⎟⎟
⎜⎜ ⎟⎟
⎝ −2𝑒−2𝑡 �−1 + 𝑒𝑡 � −𝑒−2𝑡 �−2 + 𝑒𝑡 � ⎠

The answer is the same given by Mathematica’s command MatrixExp[]


Matlab

syms t
A=[0 1;-2 -3];
expm(t*A)

ans =

[2/exp(t)-1/exp(2*t),1/exp(t)-1/exp(2*t)]
[2/exp(2*t)-2/exp(t),2/exp(2*t)-1/exp(t)]

pretty(ans)

+- -+
| 2 exp(-t)- exp(-2 t),exp(-t)-exp(-2 t) |
| |
| 2 exp(-2 t)-2 exp(-t),2 exp(-2 t)-exp(-t)|
+- -+

81
1.33. Draw root locus for a discrete system CHAPTER 1. CONTROL SYSTEMS, . . .

1.33 Draw root locus for a discrete system


Problem: Given the open loop for a continuous time system as

5𝑠 + 1
𝑠𝑦𝑠 =
𝑠2 + 2𝑠 + 3

convert to discrete time using a sampling rate and display the root locus for the discrete
system.

Mathematica

Remove["Global`*"];
sys=TransferFunctionModel[
k(5s+1)/(s^2+2s+3),s]; -19. k + 2. k z + 21. k z2 
 
11. - 26. z + 27. z2 0.5

samplePeriod=0.5; (*sec*)
sysd=ToDiscreteTimeModel[sys,samplePeriod,z]

p1 = RootLocusPlot[sysd,{k,0,100},
ImageSize->300,
GridLines->Automatic, 1.0
GridLinesStyle->Dashed,
Frame->True,
AspectRatio->1, 0.5

PlotPoints->200,
PlotStyle->PointSize[0.01]];
-1.0 -0.5 0.5 1.0

p2=ParametricPlot[{Sin[t],Cos[t]},{t,0,2Pi},
AspectRatio->1, -0.5

GridLines->Automatic,
GridLinesStyle->Dashed];
-1.0

Show[p2,p1]

82
1.33. Draw root locus for a discrete system CHAPTER 1. CONTROL SYSTEMS, . . .

Root Locus
1
Matlab 0.6:/T
0.5:/T
0.4:/T
0.8 0.1
0.7:/T 0.3:/T
0.2
0.6 0.3
clear all; close all; 0.8:/T 0.4
0.5
0.2:/T

s = tf('s');
0.4 0.6
0.7
0.9:/T 0.8 0.1:/T

sys = (5*s+1)/(s^2+2*s+3);

Imaginary Axis
0.2 0.9
1:/T
Ts = 0.5; %sample time 0
1:/T

sysd = c2d(sys,Ts,'zoh'); -0.2


0.9:/T 0.1:/T

-0.4

rlocus(sysd) -0.6
0.8:/T 0.2:/T

grid -0.8
0.7:/T 0.3:/T

0.6:/T 0.4:/T
0.5:/T
-1
-1 -0.5 0 0.5 1
Real Axis

83
1.34. Plot the response of the inverted . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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.

second system output


mg

M=20 kg
m=1 kg
system input
g=9.8 m/s^2
u M L=1 meter

First system output

Cart with inverted pendulum. One input, 2 outputs

Mathematica

Remove["Global`*"];
a = {{0, 1, 0, 0},
{0, 0, ((-m)*g)/M, 0},
{0, 0, 0, 1},
{0, 0, ((M + m)*g)/(M*L), 0}};

⎛ ⎞
⎜⎜ 0 1 0 0 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 0 0 −𝑀
𝑔𝑚
0 ⎟⎟⎟
⎜⎜ ⎟⎟
⎜⎜
⎜⎜
⎜⎜ 0 0 0 1 ⎟⎟⎟⎟
⎝ ⎟
0 ⎠
𝑔(𝑚+𝑀)
0 0 𝐿𝑀
b = {{0}, {1/M}, {0}, {-(1/(M*L))}};
MatrixForm[b]

84
1.34. Plot the response of the inverted . . . CHAPTER 1. CONTROL SYSTEMS, . . .

⎛ ⎞
⎜⎜ 0 ⎟⎟
⎜⎜ 1 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 𝑀 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 0 ⎟⎟
⎜⎜ ⎟⎟
⎝ − 1 ⎠
𝐿𝑀
c = {{1, 0, 0, 0}, {0, 0, 1, 0}};
MatrixForm[b]

⎛ ⎞
⎜⎜ 1 0 0 0 ⎟⎟
⎜⎜ ⎟⎟
⎝ 0 0 1 0 ⎠

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

It is now possible to obtain the response of the system as analytical expression or an


interpolatingFunction.
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
sys=sys/.{g->9.8,m->1,M->20,L->1};
y=Chop[OutputResponse[sys,UnitStep[t],t]]

𝑒−6.41561𝑡 (0.0238095𝑒6.41561𝑡 𝑡2 𝜃(𝑡) + 0.000115693𝑒3.2078𝑡 𝜃(𝑡) − 0.000231385𝑒6.41561𝑡 𝜃(𝑡) + 0.000115693𝑒9.62341𝑡 𝜃(𝑡))


, 𝑒−6.41561𝑡 (−0.00242954𝑒3.2078𝑡 𝜃(𝑡) + 0.00485909𝑒6.41561𝑡 𝜃(𝑡) − 0.00242954𝑒9.62341𝑡 𝜃(𝑡))

Plot[y[[1]],{t,0,3},
PlotLabel->"y(t) response",
FrameLabel->{"time (sec)","y (meter)"},
Frame->True,
PlotRange->All,
ImageSize->300,

85
1.34. Plot the response of the inverted . . . CHAPTER 1. CONTROL SYSTEMS, . . .

GridLines->Automatic,
GridLinesStyle->Dashed,
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)

Plot[ y[[2]],{t,0,3},
PlotLabel->"\[Theta](t) response",
FrameLabel->{"time (sec)","\[Theta] (radians)"},
Frame->True,
PlotRange->All,
ImageSize->300,
GridLines->Automatic,
GridLinesStyle->Dashed,
RotateLabel->False]

θ(t) response
0

-10

θ (radians)
-20

-30

0.0 0.5 1.0 1.5 2.0 2.5 3.0


time (sec)

Matlab

86
1.34. Plot the response of the inverted . . . CHAPTER 1. CONTROL SYSTEMS, . . .

clear all; close all;

m=1; M=20; L=1; g=9.8;

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');

y(t) due to step input


2

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]);

87
1.34. Plot the response of the inverted . . . CHAPTER 1. CONTROL SYSTEMS, . . .

3(t) due to step input


0

-10

Amplitude
-20

-30

-40
0 1 2 3
Time (seconds)

88
1.35. How to build and connect a closed . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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 𝑀 = 1kg,
damping coefficient 𝑐 = 1newton-seconds per meter and let the stiffness coefficient be 𝑘 =
20newton per meter.

es Fs
Yr s  +
- J s  Gs 
Ys
Fs
 1
Ys 
ms 2 csk

controller plant

Using propertional controller 𝐽(𝑠) = 𝑘𝑝 where 𝑘𝑝 = 400. First connect the system and then
show 𝑦(𝑡) for 5 seconds when the reference 𝑦𝑟 (𝑡) is a unit step function.
Mathematica

m = 1; c = 1; k = 20; kp = 400;
plant = TransferFunctionModel[1/(m s^2 + c s + k), s];
controller = TransferFunctionModel[kp, s];
sys = SystemsModelSeriesConnect[plant, controller];
sys = SystemsModelFeedbackConnect[sys];
o = OutputResponse[sys, UnitStep[t], t];
Plot[o, {t, 0, 10}, Frame -> True, PlotRange -> All,
FrameLabel -> {{"y(t)", None},
{"t (sec)", "response of closed loop"}},
BaseStyle -> 14]

89
1.35. How to build and connect a closed . . . CHAPTER 1. CONTROL SYSTEMS, . . .

response of closed loop

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');

Another way to do the above is


m=1;
c=1;
k=20;
s=tf('s');
sys3=1/(m*s^2+c*s+k);
sys2=400;
sys1=1;
sys=append(sys1,sys2,sys3);
Q=[2 1 -3;3 2 0];
input=[1];
output=[2 3];
sys=append(sys1,sys2,sys3);
sys=connect(sys,Q,input,output);
T=0:.01:10;
[Y,T,X]=step(sys,T);

90
1.35. How to build and connect a closed . . . CHAPTER 1. CONTROL SYSTEMS, . . .

response of closed loop


2

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)

91
1.36. Compare the effect on the step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.36 Compare the effect on the step response of a


standard second order system as 𝜁 changes
Problem: Given a standard second order system defined by the transfer function

𝜔𝑛2
𝐺 (𝑠) =
𝑠2 + 2𝜁𝜔𝑛 𝑠 + 𝜔𝑛2

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
𝑌 (𝑠) 𝜔𝑛2
= 2
𝑈 (𝑠) 𝑠 + 2𝜁𝜔𝑛 𝑠 + 𝜔𝑛2

Where 𝑌 (𝑠) and 𝑈 (𝑠) are the Laplace transforms of the output and input respectively.
Hence the differential equation, assuming zero initial conditions becomes

𝑦′′ (𝑡) + 2𝜁𝜔𝑛 𝑦′ (𝑡) + 𝜔𝑛2 𝑦 (𝑡) = 𝜔𝑛2 𝑢 (𝑡)

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
⎡ ⎤ ⎡ ⎤⎡ ⎤ ⎡ ⎤
⎢⎢𝑥′1 ⎥⎥ ⎢⎢ 0 1 ⎥⎥ ⎢⎢𝑥1 ⎥⎥ ⎢⎢ 0 ⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎢ ⎥ ⎢ ⎥
⎣𝑥′ ⎦ ⎣−𝜔 2 −2𝜁𝜔 ⎥⎦ ⎢⎣𝑥 ⎥⎦ + ⎢⎣𝜔 2 ⎥⎦ 𝑢 (𝑡)
2 𝑛 𝑛 2 𝑛

For a step input, 𝑢 (𝑡) = 1, we obtain

⎡ ⎤ ⎡ ⎤⎡ ⎤ ⎡ ⎤
⎢⎢𝑥′1 ⎥⎥ ⎢⎢ 0 1 ⎥⎥ ⎢⎢𝑥1 ⎥⎥ ⎢⎢ 0 ⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎢ ⎥ ⎢ ⎥
⎣𝑥′ ⎦ ⎣−𝜔 2 −2𝜁𝜔 ⎥⎦ ⎢⎣𝑥 ⎥⎦ + ⎢⎣𝜔 2 ⎥⎦
2 𝑛 𝑛 2 𝑛

Now ODE45 can be used. In Mathematica the differential equation is solved directly using
DSolve and no conversion is needed.

92
1.36. Compare the effect on the step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

solve[z_]:=Module[{sol,eq,y,t,w=1},
eq=y''[t]+2 z w y'[t]+
w^2 y[t]==w^2 UnitStep[t];
sol=First@NDSolve[{
eq,y[0]==0,y'[0]==0},y[t],{t,0,15}
];

Plot[y[t]/.sol,{t,0,15},
PlotPoints->30,
PlotRange->All,
Frame->True,
FrameLabel->{{"y(t)",None},{"time (sec)",
"step response,Subscript[\[Omega], n]=1"
<>", different \[Xi]"}},
ImageSize->400,
PlotStyle->RGBColor[2z,z/2,z/3],
LabelStyle->Directive[14]]
];

zeta = Range[0,1.4,.2];
r = Map[solve,zeta];
Show[r,GridLines->Automatic,
GridLinesStyle->Dashed]

step response, ωn =1, different ξ


2.0

1.5
y(t)

1.0

0.5

0.0
0 2 4 6 8 10 12 14
time (sec)

93
1.36. Compare the effect on the step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

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];

94
1.36. Compare the effect on the step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

step response, ! = 1 rad/sec, di,erent 1 values


2
0
.2
1.8 .4
.6
.8
1.6 1
1.2
1.4
1.4

1.2

y(t)
1

0.8

0.6

0.4

0.2

0
0 5 10 15
time sec

95
1.37. Plot the dynamic response factor 𝑅𝑑 . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.37 Plot the dynamic response factor 𝑅𝑑 of a system as


𝜔
a function of 𝑟 = 𝜔 for different damping ratios
𝑛
𝜔
Problem: Plot the standard curves showing how the dynamic response 𝑅𝑑 changes as 𝑟 = 𝜔𝑛
changes. Do this for different damping ratio 𝜉. Also plot the phase angle.
These plots are result of analysis of the response of a second order damped system to a
harmonic loading. 𝜔 is the forcing frequency and 𝜔𝑛 is the natural frequency of the system.

96
1.37. Plot the dynamic response factor 𝑅𝑑 . . . CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

Rd[r_,z_]:=1/Sqrt[(1-r^2)^2+(2 z r)^2];

phase[r_,z_]:=Module[{t},
t=ArcTan[(2z r)/(1-r^2)];
If[t<0,t=t+Pi];
180/Pi t
];

plotOneZeta[z_,f_] := Module[{r,p1,p2}, Dynamics Response vs. Frequency ratio for different ξ

p1 = Plot[f[r,z],{r,0,3},PlotRange->All, 6

5
PlotStyle->Blue];
4
0.1

p2 = Graphics[Text[z,{1.1,1.1f[1.1,z]}]];

Rd
3

Show[{p1,p2}] 2
0.3
]; 1 0.5
0.7
0.9
1.1
0

p1 = Graphics[{Red,Line[{{1,0},{1,6}}]}]; 0.0 0.5 1.0 1.5


ω
2.0 2.5 3.0

p2 = Map[plotOneZeta[#,Rd]&,Range[.1,1.2,.2]];
r=
ωn

Show[p2,p1,
FrameLabel->{{"Subscript[R, d]",None},
{"r= \[Omega]/Subscript[\[Omega], n]",
"Dynamics Response vs. Frequency\
ratio for different \[Xi]"}},
Frame->True,
GridLines->Automatic,GridLinesStyle->Dashed,
ImageSize -> 300,AspectRatio -> 1]

Phase vs. Frequency ratio for different ξ

p = Map[plotOneZeta[#,phase]&,Range[.1,1.2,.2]];
150
Show[p,FrameLabel->{{"Phase in degrees",None}, 0.1

{"r= \[Omega]/Subscript[\[Omega], n]",


Phase in degrees

0.3
0.5
0.7
0.9
1.1
100
"Phase vs. Frequency ratio for different \[Xi]"}},
Frame->True, 50

GridLines->Automatic,GridLinesStyle->Dashed,
ImageSize->300,AspectRatio->1] 0
0.0 0.5 1.0 1.5 2.0 2.5 3.0
ω
r=
ωn

97
1.38. How to find closed loop step . . . CHAPTER 1. CONTROL SYSTEMS, . . .

1.38 How to find closed loop step response to a plant


with a PID controller?
1
Find and plot the step response of the plant 𝑠2+2𝑠+1 connected to a PID controller with
𝑃 = 10, 𝐼 = 3.7, 𝐷 = 0.7. Use negative closed loopback.

Mathematica

plant= TransferFunctionModel[1/(s^2 + 2*s + 1),s];


kip = 10; ki = 3.7; kid = 0.7;
pid = TransferFunctionModel[
(kip*s + ki + kid*s^2)/s, s];
openLoop = SystemsModelSeriesConnect[
TransferFunctionModel[plant], pid]; Step response

closedLoop = SystemsModelFeedbackConnect[ 1.2

1.0

openLoop]; 0.8

input = UnitStep[t];

y(t)
0.6

output = OutputResponse[closedLoop, input, t];


0.4

0.2

0.0
0 1 2 3 4 5
Plot[{input, output}, {t, 0, 5}, PlotRange -> t (sec)

All, GridLines -> Automatic,


GridLinesStyle -> Directive[LightGray, Dashed],
Frame -> True,
FrameLabel -> {{"y(t)", None},
{"t (sec)", "Step response"}},
BaseStyle -> 12]

Matlab

close all; clear;


s = tf('s');
plant = 1/(s^2 + 2*s + 1) 1.2
step response

kip = 10; ki = 3.7; kid = 0.7; 1

thePID = pid(kip,kid,kid); 0.8

BLKSYS = append(thePID,plant);
y(t)

0.6

Q = [2 1; 1 -2]; 0.4

closedLoop = connect(BLKSYS,Q,1,2); 0.2

[y,t] = step(closedLoop);
0

plot(t(1:140),y(1:140)); 0 1 2
t (sec)
3 4 5

xlabel('t (sec)'); ylabel('y(t)');


title('step response');
grid

98
1.39. How to make Nyquist plot? CHAPTER 1. CONTROL SYSTEMS, . . .

1.39 How to make Nyquist plot?


Nyquist command takes as input the open loop transfer function (not the closed loop!) and
generates a plot, which was can look at to determine if the closed loop is stable or not. The
closed loop is assumed to be unity feedback. For example, if the open loop is 𝐺(𝑠), then we
𝐺(𝑠)
know that the closed loop transfer function is 1+𝐺(𝑠) . But we call Nyquist with 𝐺(𝑠).

Here are two examples.

1.39.1 Example 1
𝑠
Given 𝐺(𝑠) = 1−0.2𝑠
generate Nyquist plot.

1
Mathematica

NyquistPlot[s/(1 - 0.2 s), -5 -4 -3 -2 -1


NyquistGridLines -> Automatic]
-1

-2

Nyquist Diagram
2.5
2 dB 0 dB -2 dB
2

Matlab 1.5
4 dB -4 dB
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.5𝑠)
Given 𝐺(𝑠) = 𝑠(1+0.1𝑠)(1−0.25𝑠)
generate Nyquist plot.

99
1.39. How to make Nyquist plot? CHAPTER 1. CONTROL SYSTEMS, . . .

Mathematica

NyquistPlot[5(1-0.5 s)/ -1
(s(1 + 0.1 s)(1 - 0.25 s))]

-2

Matlab
2.5 s - 5
clear all; close all; ------------------------
s=tf('s'); 0.025 s^3 + 0.15 s^2 - s
sys=5*(1-0.5*s)/...
(s*(1+0.1*s)*(1-0.25*s)) 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

100
1.39. How to make Nyquist plot? CHAPTER 1. CONTROL SYSTEMS, . . .

Nyquist Diagram
0.15

0.1

0.05

Imaginary Axis
clear all; close all;
nyquist1() 0

-0.05

-0.1

-0.15
-1 -0.8 -0.6 -0.4 -0.2 0 0.2
Real Axis

101
1.39. How to make Nyquist plot? CHAPTER 1. CONTROL SYSTEMS, . . .

102
Chapter 2

Linear algebra, Linear solvers, common


operations on vectors and matrices

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 𝐴 of 3 rows, and want to find the location where 𝐴(𝑖, 𝑗) = 2 where
𝑖 is the row number and 𝑗 is the column number. Given this matrix
⎛ ⎞
⎜⎜ 1 2 3 4 ⎟⎟
⎜⎜ ⎟⎟
𝐴 = ⎜⎜⎜ 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)

I =
2
103
CHAPTER 2. LINEAR ALGEBRA, . . .

1
3
J =
1
2
4
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
mat = {{1, 2, 3, 4},
{2, 3, 1, 5},
{5, 6, 7, 2}}
Position[mat, 2]

which gives
{{1,2},
{2,1},
{3,4}}

Mathematica searched row-wise.


I found Mathematica for matrix operations takes more time to get familiar with compared to
Matlab’s, since Mathematica data structure is more general and little more complex (ragged
arrays, or list of lists is its main data structure) compared to Matlab’s. This is because
Mathematica has to also support symbolics in its commands and not just numbers
In Maple the following short cuts can be used enter vectors and matrices: For row vector:
v:=<1|2|3|4> and for column vector v:=<1,2,3,4> and for a Matrix of say 2 rows and
3 columns A:=<1,2|3,4|5,6>. Here | acts as a column separator. For transpose of matrix,
A^%T is the short cut notation.

104
2.1. Multiply matrix with a vector CHAPTER 2. LINEAR ALGEBRA, . . .

2.1 Multiply matrix with a vector


How to perform the following matrix/vector multiplication?
[ 1 2 3 ] [ 1 ]
[ 4 5 6 ] * [ 2 ]
[ 7 8 8 ] [ 3 ]

In Mathematica the dot "." is used for Matrix multiplication. In Matlab the "*" is used. In
Fortran, MATMUL is used.
Mathematica

a={{1,2,3},{4,5,6},{7,8,8}};
x={1,2,3}; Out[7]= {14,32,47}

a.x

Matlab
14
A=[1 2 3;4 5 6;7 8 9]; 32
x=[1; 2; 3]; 50
c=A*x

105
2.1. Multiply matrix with a vector CHAPTER 2. LINEAR ALGEBRA, . . .

Ada
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Numerics.Real_Arrays;
use Ada.Numerics.Real_Arrays;

procedure t1 is
A : constant real_matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));

V : constant real_vector := (1.0,2.0,3.0);


procedure Put (X : real_vector) is
begin
FOR e of X LOOP
put_line(float'image(e));
END LOOP;
end put;
begin
put(A*v);
end t1;

compile and run


>gnatmake -gnat2012 t1.adb
gcc -c -gnat2012 t1.adb
gnatbind -x t1.ali
gnatlink t1.ali
>./t1
1.40000E+01
3.20000E+01
5.00000E+01

106
2.1. Multiply matrix with a vector CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran
PROGRAM main
IMPLICIT NONE
integer, parameter :: dp = kind(1.D0)
integer, parameter :: N=3
real(kind=dp), parameter, DIMENSION(N, N) :: &
A=DBLE(reshape([ 1.0, 2.0, 3.0,&
4.0, 5.0, 6.0,&
7.0, 8.0, 9.0], shape(A), &
order=[2,1]))

real(kind=dp), parameter, DIMENSION(N, 1) :: &


x=DBLE(reshape([1.0, 2.0, 3.0], shape(x)))

real(kind=dp), DIMENSION(N, 1) :: result


integer, DIMENSION(2) :: siz

result = MATMUL(A,x)
siz = SHAPE(result)
Write(*,*) result

print *, "number of rows = ",siz(1)


print *, "number of columns = ",siz(2)

end program

compile and run


>gfortran -fcheck=all -Wall -Wconversion
-Wextra -Wconversion-extra -pedantic test.f90
>./a.out
14.000000000000000 32.000000000000000 50.000000000000000
number of rows = 3
number of columns = 1

Maple
⎡ ⎤
⎢⎢ 14 ⎥⎥
A:=Matrix([[1,2,3],[4,5,6],[7,8,9]]): ⎢⎢ ⎥
⎢⎢ 32 ⎥⎥⎥
x:=Vector([1,2,3]): #default is column vector ⎢⎢ ⎥⎥
⎣ ⎦
c:=A.x; 50

107
2.1. Multiply matrix with a vector CHAPTER 2. LINEAR ALGEBRA, . . .

Python

import numpy as np array([[14],


mat=np.array([[1,2,3],[4,5,6],[7,8,8]]) [32],
b=np.array([1,2,3]) [47]])
b.shape=(3,1)
r=dot(mat,b)

108
2.2. Insert a number at specific position . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.2 Insert a number at specific position in a vector or list


The problem is to insert a number into a vector given the index.

Mathematica

vec={1,2,3,4}; Out[11]= {1,2,99,3,4}


vec=Insert[vec,99,3];
vec

Matlab
A =
A=[1 2 3 4]; 1 2 99 3 4
A=[ A(1:2) 99 A(3:end) ]

Fortran

program f
implicit none >gfortran -std=f2008 t2.f90
REAL(4), ALLOCATABLE :: A(:) >./a.out
A=[1,2,3,4]; 1.0000000 2.0000000 99.000000
A=[A(1:2), 99.0, A(3:)] 3.0000000 4.0000000
Print *,A
end program f

Maple

v:=Vector[row]([1,2,3,4]);
v:=Vector[row]([v[1..2],99,v[3..]]);
v :=[ 1 2 99 3 4]
Using <> notation
v:=<1|2|3|4>;
v:=<v(1..2)|99|v(3..)>;

109
2.2. Insert a number at specific position . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Python
Python uses zero index.
import numpy as np Out[86]: array([ 1, 2, 99, 3,
b=np.array([1,2,3,4]) 4])
b=numpy.insert(b,2,99)
b

110
2.3. Insert a row into a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.3 Insert a row into a matrix


The problem is to insert a row into the second row position in a 2D matrix

Mathematica
{{1,2,3},
mat={{1,2,3}, {90,91,92},
{4,5,6}, {4,5,6},
{7,8,9}} {7,8,9}}
mat = Insert[mat,{90,91,92},2]

Matlab
1 2 3
A=[1 2 3; 90 91 92
4 5 6; 4 5 6
7 8 9] 7 8 9
A=[ A(1,:); [90 91 92]; A(2:end,:) ]

Maple

Using <<>> notation


A:=< <1|2|3>,
<4|5|6>,
<7|8|9>>;
[ 1 2 3
A:=< A(1..2,..),<90|91|92>, A(3,..)>; 4 5 6
90 91 92
Using Matrix/Vector 7 8 9]
A:=Matrix([ [1,2,3],[4,5,6],[7,8,9]]);
A:=Matrix([ [A[1..2,..]],
[Vector[row]([91,92,92])],
[A[3,..]
] ]);

111
2.3. Insert a row into a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

Python
import numpy as np array([[ 1, 2, 3],
mat=np.array([[1,2,3], [90, 91, 92],
[4,5,6], [ 4, 5, 6],
[7,8,9]]) [ 7, 8, 9]])
mat=numpy.insert(mat,1,[90,91,92],0)

Fortran

program t3
implicit none
integer i,nRow,nCol Compile and run
integer(4), ALLOCATABLE ::A(:,:) >gfortran -std=f2008
t3.f90
A = reshape ([1,2,3, & >./a.out
4,5,6, & before
7,8,9], [3,3], order=[2,1]) 1 2
nRow=size(A,1) 3
nCol=size(A,2) 4 5
6
print *, 'before' 7 8
do i=LBOUND(A, 1),UBOUND(A, 1) 9
after
print *,A(i,:)
1 2
end do
3
90 91
A = reshape ([A(1,:), & 92
90,91,92, & 4 7
A(2:,:)], [nRow+1,nCol] , order=[2,1]) 5
print *, 'after' 8 6
do i=LBOUND(A, 1),UBOUND(A, 1) 9
print *,A(i,:)
end do

end program t3

112
2.4. Insert a column into a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.4 Insert a column into a matrix


The problem is to insert a column into the second column position in a 2D matrix.

Mathematica

mat = {{1, 2, 3},


{4, 5, 6}, {{1,90,2,3},
{7, 8, 9}}; {4,91,5,6},
{7,92,8,9}}
mat = Insert[Transpose[mat],
{90, 91, 92}, 2];
mat = Transpose[mat]

Matlab

A=[1 2 3; 1 90 2 3
4 5 6; 4 91 5 6
7 8 9]; 7 92 8 9

A=[A(:,1) [90 91 92]' A(:,2:end) ]

113
2.4. Insert a column into a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran

program t4
implicit none
integer(4) ::i
integer(4), ALLOCATABLE ::A(:,:)
>gfortran t4.f90
A = reshape ([1,2,3, & >./a.out
4,5,6, & 1 90 2
7,8,9], [3,3], order=[2,1]) 3
4 91 5
A = reshape ([A(:,1), [90,91,92] , 6
A(:,2:)] , [3,4]) 7 92 8
9
do i=LBOUND(A, 1),UBOUND(A, 1)
print *,A(i,:)
end do

end program t4

Maple

A:=< <1|2|3>,<4|5|6>,<7|8|9>>;
A:=< A(..,1)|<90,91,92>|A(..,2..)>;
[ 1 90 2 3
Using Matrix/Vector 4 91 5 6
7 92 8 9]
A:=Matrix([ [1,2,3],[4,5,6],[7,8,9]]);
A:=Matrix([ [A[..,1],
Vector[column]([91,92,92]),
A[..,2..] ]]);

Python
import numpy as np
mat=np.array([[1,2,3], array([[ 1, 90, 2, 3],
[4,5,6], [ 4, 91, 5, 6],
[7,8,9]]) [ 7, 92, 8, 9]])

mat=numpy.insert(mat,1,[90,91,92],1)

114
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.5 Build matrix from other matrices and vectors


2.5.1 First example
⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤
⎢⎢ 1 ⎥⎥ ⎢⎢ 4 ⎥⎥ ⎢⎢ 7 ⎥⎥ ⎢⎢ 10 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
Given column vectors 𝑣1 = ⎢⎢⎢ 2 ⎥⎥⎥ and 𝑣2 = ⎢⎢⎢ 5 ⎥⎥⎥ and 𝑣3 = ⎢⎢⎢ 8 ⎥⎥⎥ and 𝑣4 = ⎢⎢⎢ 11 ⎥⎥⎥ generate the
⎢⎣ ⎥⎦ ⎢⎣ ⎥⎦ ⎢⎣ ⎥⎦ ⎢⎣ ⎥⎦
3 6 9 12
⎡ ⎤
⎢⎢ 1 4 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 2 5 ⎥⎥⎥
⎢⎢ ⎥⎥
⎡ ⎤ ⎢⎢⎢ ⎥⎥
⎥⎥
⎢⎢ 𝑣1 𝑣2 ⎥⎥ ⎢⎢ ⎢ 3 6 ⎥⎥
matrix 𝑚 = ⎢⎣⎢ ⎥
⎥⎦ = ⎢⎢ ⎢ ⎥⎥
𝑣3 𝑣4 ⎢⎢ 7 10 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 8 11 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎣ ⎥⎦
9 12
Matlab was the easiest of all to do these operations with. No surprise, as Matlab was designed
for Matrix and vector operations. But I was surprised that Maple actually had good support
for these things, using its <> notation, which makes working with matrices and vectors much
easier.
The command ArrayFlatten is essential for this in Mathematica.
Notice the need to use Transpose[{v}] in order to convert it to a column matrix. This is
needed since in Mathematica, a list can be a row or column, depending on context.

Mathematica

v1 = {1, 2, 3}; v2 = {4, 5, 6}; ⎛ ⎞


v3 = {7, 8, 9}; v4 = {10, 11, 12}; ⎜⎜ 1 4 ⎟⎟
⎜⎜ ⎟⎟
m = ArrayFlatten[ ⎜⎜ 2 5 ⎟⎟⎟
⎜⎜ ⎟⎟
{{Transpose@{v1}, Transpose@{v2}}, ⎜⎜
⎜⎜ 3 6 ⎟⎟⎟
{Transpose@{v3}, Transpose@{v4}}} ⎜⎜ ⎟⎟
⎜⎜ 7 10 ⎟⎟⎟
] ⎜⎜ ⎟⎟
⎜⎜
⎜⎜ 8 11 ⎟⎟⎟
⎜⎝ ⎟⎠
9 12

115
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

m =
Matlab 1 4
2 5
v1=[1,2,3]'; v2=[4,5,6]'; 3 6
v3=[7,8,9]'; v4=[10,11,12]'; 7 10
m=[v1 v2;v3 v4] 8 11
9 12

Maple

restart; ⎡ ⎤
v1:=<1,2,3>; #column by default ⎢⎢ 1 4 ⎥⎥
⎢⎢ ⎥⎥
v2:=<4,5,6>; ⎢⎢ ⎥⎥
⎢⎢ 2 5 ⎥⎥⎥
v3:=<7,8,9>; ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢
v4:=<10,11,12>; ⎢⎢ 3 6 ⎥⎥⎥
⎢⎢ ⎥⎥
m:=< <v1|v2>, ⎢⎢ ⎥
<v3|v4>>;
⎢⎢ 7 10 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 8 11 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎦

9 12

116
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Python
import numpy as np
v1=np.array((1,2,3));
v2=np.array((4,5,6));
v3=np.array((7,8,9));
v4=np.array((10,11,12));

r1 =np.hstack([(v1,v2)]).T Out[211]:
r2 =np.hstack([(v3,v4)]).T array([[ 1, 4],
mat = np.vstack((r1,r2)) [ 2, 5],
[ 3, 6],
Another way [ 7, 10],
v1=np.array([(1,2,3)]).T [ 8, 11],
v2=np.array([(4,5,6)]).T [ 9, 12]])
v3=np.array([(7,8,9)]).T
v4=np.array([(10,11,12)]).T

mat =np.hstack((
np.vstack((v1,v3)),
np.vstack((v2,v4)))
)

117
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran

PROGRAM main
IMPLICIT none
INTEGER :: i
INTEGER , DIMENSION(3) :: v1,v2,v3,v4
INTEGER , DIMENSION(6,2) :: m
v1 = [1,2,3]; v2=[4,5,6];
v3=[7,8,9]; v4=[10,11,12];

m(1:3,1) = v1; m(1:3,2)=v2;


m(4:,1)=v3; m(4:,2)=v4;

DO i=1,size(m,1) >gfortran -Wall foo.


PRINT *, m(i,:) f90
END DO >./a.out
1 4
END PROGRAM main 2 5
3 6
Using the RESHAPE command
7 10
PROGRAM main 8 11
IMPLICIT none 9 12
INTEGER :: i
INTEGER , DIMENSION(3) :: v1,v2,v3,v4
INTEGER , DIMENSION(6,2) :: m
v1 = [1,2,3]; v2=[4,5,6];
v3=[7,8,9]; v4=[10,11,12];

m = RESHAPE([v1,v3,v2,v4], SHAPE(m), ORDER=[1,2])

DO i=1,size(m,1)
PRINT *, m(i,:)
END DO

END PROGRAM main

118
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.5.2 second example


⎡ ⎤ ⎡ ⎤ ⎡ ⎤
⎢⎢ 1 ⎥⎥ ⎢⎢ 4 5 ⎥⎥ ⎢⎢ 10 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
Given mix of matrices and vectors, such as 𝑣1 = ⎢⎢⎢ 2 ⎥⎥⎥ and 𝑣2 = ⎢⎢⎢ 6 7 ⎥⎥⎥ and 𝑣3 = ⎢⎢⎢ 11 ⎥⎥⎥ and
⎢⎣ ⎥⎦ ⎢⎣ ⎥⎦ ⎢⎣ ⎥⎦
3 8 9 12
⎡ ⎤
⎢⎢ 13 ⎥⎥
⎢⎢ ⎥⎥
𝑣4 = ⎢⎢⎢ 14 ⎥⎥⎥ and
⎢⎣ ⎥⎦
15
⎡ ⎤
⎢⎢ 16 ⎥⎥
⎢⎢ ⎥⎥
𝑣5 = ⎢⎢⎢ 17 ⎥⎥⎥
⎢⎣ ⎥⎦
18
⎡ ⎤
⎢⎢ 1 4 5 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 2 6 7 ⎥⎥⎥
⎢⎢ ⎥⎥
⎡ ⎤ ⎢⎢⎢ ⎥⎥

⎢⎢ 𝑣1 𝑣2 ⎥⎥ ⎢⎢⎢ 3 8 9 ⎥⎥⎥
generate the matrix 6 by 3 matrix 𝑚 = ⎢⎢⎣ ⎥⎥ = ⎢⎢ ⎥⎥
𝑣3 𝑣4 𝑣5 ⎦ ⎢⎢⎢⎢ 10 13 16 ⎥⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 11 14 17 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎣ ⎦
12 15 18
Mathematica, thanks for function by Kuba at Mathematica stackexachage, this becomes
easy to do
Mathematica

myArrayFlatten = Flatten /@ Flatten[#, {{1, 3}}] &

v1 = {1, 2, 3};
v2 = {{4, 5}, {6, 7}, {8, 9}};
v3 = {10, 11, 12};
v4 = {13, 14, 15};
v5 = {16, 17, 18};

m={
{v1, v2},
{v3, v4, v5},
} // myArrayFlatten

Maple

restart;
v1:=<1,2,3>; #column by default

119
2.5. Build matrix from other matrices and . . . CHAPTER 2. LINEAR ALGEBRA, . . .

v2:=<<4|5>,
<6|7>,
<8|9>>;
v3:=<10,11,12>;
v4:=<13,14,15>;
v5:=<16,17,18>;
m:=< <v1|v2>,
<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]';

m=[v1 v2;v3 v4 v5]

Fortran

PROGRAM main
IMPLICIT none
INTEGER :: i
INTEGER , DIMENSION(3) :: v1,v3,v4,v5
INTEGER , DIMENSION(3,2) :: v2 = RESHAPE([4,6,8,5,7,9],SHAPE(v2),ORDER=[1,2])
INTEGER , DIMENSION(6,3) :: m
v1 = [1,2,3]; v3=[10,11,12];
v4 =[13,14,15]; v5=[16,17,18];
m = RESHAPE([v1,v3,v2(:,1),v4,v2(:,2),v5], SHAPE(m), ORDER=[1,2])

DO i=1,size(m,1)
PRINT *, m(i,:)
END DO

END PROGRAM main

>gfortran -Wall foo.f90


>./a.out
1 4 5
2 6 7
3 8 9
10 13 16
11 14 17
12 15 18

120
2.6. Generate a random 2D matrix from . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.6 Generate a random 2D matrix from uniform (0 to 1)


and from normal distributions

{{0.100843,0.356115,0.700317,0.657852},
Mathematica

(*from uniform over 0,1*) {0.238019,0.59598,0.523526,0.576362},


mat = RandomReal[
UniformDistribution[{0,1}],{3,4}]
{0.339828,0.32922,0.0632487,0.815892}}

{{-0.226424,1.19553,0.601433,1.28032},
(*from normal, zero mean, 1 std*)
{1.66596,0.176225,-0.619644,0.371884},
mat=RandomReal[
NormalDistribution[0,1],{3,4}] {0.895414,-0.394081,0.153507,-1.74643}}

mat =
0.6787 0.3922 0.7060
Matlab 0.0462
0.7577 0.6555 0.0318
mat=rand(3,4) 0.0971
0.7431 0.1712 0.2769
0.8235

mat =
0.3252 -1.7115 0.3192
-0.0301
mat=randn(3,4) -0.7549 -0.1022 0.3129
-0.1649
1.3703 -0.2414 -0.8649
0.6277

121
2.6. Generate a random 2D matrix from . . . CHAPTER 2. LINEAR ALGEBRA, . . .

[[0.93,0.66,0.92,0.80],
Maple

A:=ArrayTools:-RandomArray(3,4, [0.85,0.96,0.42,0.49],
distribution = uniform);

#just to round to 2 decimal points [0.04,0.79,0.14,0.96]


parse~(sprintf~("%0.2f",A));
]

Or
interface(displayprecision=5):
A:=ArrayTools:-RandomArray(3,4,
distribution = uniform);

⎡ ⎤
⎢⎢ 0.970592781760615697 0.957506835434297598 0.0975404049994095246 0.126986816293506055 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 0.157613081677548283 0.546881519204983846 0.632359246225409510 0.905791937075619225 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎣ ⎦
0.964888535199276531 0.278498218867048397 0.913375856139019393 0.814723686393178936

122
2.6. Generate a random 2D matrix from . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran
 
program t5
implicit none
INTEGER(4) ::i=0,j
REAL ::A(3,3),mean,sd,pi,temp

CALL RANDOM_SEED(i)
CALL RANDOM_NUMBER(A)

print *, 'from uniform distribution'


do i=LBOUND(A, 1),UBOUND(A, 1)
print *,A(i,:)
end do

!this block below uses the logic as explained in


!http://rosettacode.org/wiki/Random_numbers#Fortran
!
mean=0.0
sd=1.0
pi = 4.0*ATAN(1.0)

! Now convert to normal distribution


DO i = 1, SIZE(A,1)-1, 2
DO j = 1, SIZE(A,2)-1, 2
temp = sd * SQRT(-2.0*LOG(A(i,j))) * COS(2*pi*A(i+1,j+1)) + mean
A(i+1,j+1) = sd* SQRT(-2.0*LOG(A(i,j)))*SIN(2*pi*A(i+1,j+1))+mean
A(i,j) = temp
END DO
END DO

print *, 'from normal distribution'


do i=LBOUND(A, 1),UBOUND(A, 1)
print *,A(i,:)
end do

end program t5
 
>gfortran -Wall -std=f2008 t5.f90
>./a.out
from uniform distribution
0.99755955 0.74792767 7.37542510E-02
0.56682467 0.36739087 5.35517931E-03
0.96591532 0.48063689 0.34708124

from normal distribution


-4.70122509E-02 0.74792767 7.37542510E-02
0.56682467 5.17370142E-02 5.35517931E-03

123
2.6. Generate a random 2D matrix from . . . CHAPTER 2. LINEAR ALGEBRA, . . .

0.96591532 0.48063689 0.34708124

Did not find a build-in support for random numbers from normal distribution, need to look
more.

124
2.7. Generate an n by m zero matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.7 Generate an n by m zero matrix


Mathematica {{0,0,0,0},
{0,0,0,0},
mat=Table[0,{3},{4}] {0,0,0,0}}

Matlab A =
0 0 0 0
A=zeros(3,4) 0 0 0 0
0 0 0 0

Maple ⎡ ⎤
⎢⎢ 0 0 0 0 ⎥⎥
⎢⎢ ⎥
⎢⎢ 0 0 0 0 ⎥⎥⎥
LinearAlgebra:-ZeroMatrix(3,4); ⎢⎢ ⎥⎥
⎣ ⎦
0 0 0 0

125
2.7. Generate an n by m zero matrix CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran

program f
implicit none
integer i
integer, parameter :: dp = kind(1.D0)
real(kind=dp), DIMENSION(3, 4):: A

A=0

do i=LBOUND(A, 1),UBOUND(A, 1)
print *,A(i,:)
end do
end program f

tmp>gfortran -std=f2008 f.f90


tmp>./a.out
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000

Ada

with Ada.Text_IO; use Ada.


Text_IO;
with Ada.Numerics.Real_Arrays; use Ada.
Numerics.Real_Arrays;

procedure t1 is
A : Real_Matrix (1 .. 3, 1 .. 4) := (
others => (others => 0.0));
begin
null;
end t1;

126
2.8. Rotate a matrix by 90 degrees CHAPTER 2. LINEAR ALGEBRA, . . .

2.8 Rotate a matrix by 90 degrees


Mathematica

mat = {{1, 2, 3}, {{3,6,9},


{4, 5, 6}, {2,5,8},
{7, 8, 9}}; {1,4,7}}
mat = Reverse[Transpose[mat]]

Matlab

A=[1 2 3; 3 6 9
4 5 6; 2 5 8
7 8 9] 1 4 7
A=rot90(A)

Maple

A:=< <1|2|3>, [[3,2,1],


<4|5|6>, [6,5,4],
<7|8|9>>; [9,8,7]]

A:=ArrayTools:-FlipDimension(A,2);

[[3,6,9],
A:=A^%T; [2,5,8],
[1,4,7]]

127
2.8. Rotate a matrix by 90 degrees CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran

Using additional copy for the matrix


program f
implicit none
integer(4) ::i,j
integer(4), ALLOCATABLE ::A(:,:),B(:,:)

A = reshape ([1,2,3, &


4,5,6, &
7,8,9], &
[3,3], &
order=[2,1] &
)
B=A
i=0

do j=UBOUND(A, 2),LBOUND(A, 2),-1


i=i+1
B(i,:)=A(:,j)
end do

do i=LBOUND(B, 1),UBOUND(B, 1)
print *,B(i,:)
end do

end program f

mp>gfortran -std=f2008 f.f90


tmp>./a.out
3 6 9
2 5 8
1 4 7

128
2.9. Generate a diagonal matrix with given . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.9 Generate a diagonal matrix with given values on the


diagonal
Problem: generate diagonal matrix with 2, 4, 6, 8 on the diagonal.

Mathematica {{2,0,0,0},
{0,4,0,0},
DiagonalMatrix[2 Range[1, 4]] {0,0,6,0},
{0,0,0,8}}

Matlab 2 0 0 0
0 4 0 0
diag(2*(1:4)) 0 0 6 0
0 0 0 8

Maple
[[2,0,0,0],
A:=LinearAlgebra:-DiagonalMatrix([2,4,6,8]); [0,4,0,0],
#or [0,0,6,0],
A:=LinearAlgebra:-DiagonalMatrix( [0,0,0,8]]
[seq(i,i=2..8,2)]);

129
2.10. Sum elements in a matrix along the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.10 Sum elements in a matrix along the diagonal


Mathematica

mat = {{1, 2, 3},


{4, 5, 6}, Out[45]= 15
{7, 8, 9}}
Tr[mat]

Matlab

A=[1 2 3; ans =
4 5 6; 15
7 8 9]
sum(diag(A))

Maple

A:=< <1|2|3>,
<4|5|6>,
<7|8|9>>;

d:=MTM:-diag(A); 15
add(x,x in d);

Another ways
LinearAlgebra:-Diagonal(A);
Student:-LinearAlgebra:-Diagonal(A);

130
2.11. Find the product of elements in a . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.11 Find the product of elements in a matrix along the


diagonal
Mathematica

mat= {{1, 2, 3},


{4, 5, 6}, Out[49]= 45
{7, 8, 9}}
Apply[Times,Diagonal[mat]]

Matlab

A=[1 2 3;
4 5 6; ans = 45
7 8 9]
prod(diag(A))

Maple

A:=< <1|2|3>,
<4|5|6>,
<7|8|9>>; 45
d:=MTM:-diag(A);
mul(x,x in d);

131
2.12. Check if a Matrix is diagonal CHAPTER 2. LINEAR ALGEBRA, . . .

2.12 Check if a Matrix is diagonal


A diagonal matrix is one which has only zero elements off the diagonal. The Mathematica
code was contributed by Jon McLoone.

Mathematica

diagonalQ[m_List]/;ArrayDepth[m]===2&&Equal@@Dimensions[m]:=
And@@Flatten[MapIndexed[#1===0||Equal@@#2&,m,{2}]];

diagonalQ[m_]:=Return[False];
matA = {{1, 2}, Out[59]=
{2, 4}}; False
Out[60]=
matB = {{1, 0}, True
{0, 2}}; Out[61]=
False
matC = {{1, 0, 2},
{0, 2, 4}};

diagonalQ[matA]
diagonalQ[matB]
diagonalQ[matC]

Maple

A:=Matrix([[1,0],[0,2]]); true
Student:-NumericalAnalysis:-IsMatrixShape(A,'diagonal');

132
2.13. Find all positions of elements in a . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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

mat = {{1, 2,3},


{2,1,-5}, {{1,2},{1,3},{2,1},{3,1}}
{6,0,0}};

p = Position[mat, _?(#1 >= 2&)]

I =
2
Matlab 3
1
A=[1 2 3; 1
2 1 -5; J =
6 0 0] 1
[I,J]=find(A>=2) 1
2
3

Maple

A:=< <1|2|3>,
[2, 1], [3, 1], [1,
<2|1|-5>,
<6|0|0>>; 2], [1, 3]

seq(seq(`if`(A[i,j]>=2,[i,j],NULL),i=1..3),j=1..3);

133
2.14. Replicate a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.14 Replicate a matrix


Given Matrix
1 2
3 4

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 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4

In Matlab, repmat() is used. In Mathematica, a Table command is used, followed by Ar-


rayFlatten[]

Mathematica

mat = {{1,2}, {{1,2,1,2,1,2},


{3,4}} {3,4,3,4,3,4},
{1,2,1,2,1,2},
{3,4,3,4,3,4}}
r = Table[mat,{2},{3}];
ArrayFlatten[r]

ans =
1 2 1 2 1
Matlab 2
3 4 3 4 3
A=[1 2;3 4] 4
repmat(A,2,3) 1 2 1 2 1
2
3 4 3 4 3
4

Another way is to use kron() in matlab, and KroneckerProduct in Mathematica and Linear-
Algebra[KroneckerProduct] in Maple, which I think is a better way. As follows

134
2.14. Replicate a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

Mathematica

mat = {{1,2},
{3,4}} {{1,2,1,2,1,2},
{3,4,3,4,3,4},
kernel = Table[1, {2}, {3}]; {1,2,1,2,1,2},
(* {{1, 1, 1}, {3,4,3,4,3,4}}
{1, 1, 1}} *)

KroneckerProduct[kernel, mat]

Matlab
ans =
A=[1 2;3 4] 1 2 1 2 1
kernel=ones(2,3) 2
3 4 3 4 3
kernel = 4
1 1 1 1 2 1 2 1
2
1 1 1
3 4 3 4 3
4
kron(kernel,A)

Maple

A:=< <1|2>,
<3|4>>; [[1,2,1,2,1,2],
[3,4,3,4,3,4],
kern:=<<1|1|1>, [1,2,1,2,1,2],
[3,4,3,4,3,4]]
<1|1|1>>;

LinearAlgebra[KroneckerProduct](kern,A);

135
2.15. Find the location of the maximum . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.15 Find the location of the maximum value in a


matrix
Mathematica
Out[142]= {{2,2},{3,3}}
mat ={{2,4,-3},
{7,9,5},
{0,5.4,9}}

m = Max[mat]; (*this gives values *)


Position[mat,m](*this find locations*)

Matlab
r =
h = [2, 4, -3; 2
7, 9, 5; 3
0, 5.4, 9] c =
2
m = max(h(:)); 3

[r,c]=find(h==m)

136
2.15. Find the location of the maximum . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple
3,3
This below finds position of first max.
A:=< <2|4|-3>,
<7|9|5>,
<0|5.4|9>>;
v:=max(A);
member(v,A,'pos');
pos

Maple support for such operations seems to be not as strong


as Matlab. One way to find locations of all elements is by using [[2, 2], [3, 3]]
explicit loop
A:=< <2|4|-3>,
<7|9|5>,
<0|5.4|9>>;
v:=max(A);
r:=[seq(seq(`if`(A[i,j]=v,[i,j],NULL),i=1..3),j=1..3)];

137
2.16. Swap 2 columns in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.16 Swap 2 columns in a matrix


Give a matrix
1 2
3 4
5 6

How to change it so that the second column becomes the first, and the first becomes the
second? so that the result become
2 1
4 3
6 5

Mathematica

a={{1,2}, Out[29]= {{2, 1},


{3,4}, {4, 3},
{5,6}} {6, 5}}
Reverse[a,2]

Matlab

a =[1 2; 2 1
3 4; 4 3
5 6] 6 5
[a(:,2) a(:,1)]

Maple

A:=<<1|2>, [[2,1],
<3|4>, [4,3],
<5|6>>; [6,5]]
A:=<A[..,2]|A[..,1]>;

138
2.17. Join 2 matrices side-by-side and on . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.17 Join 2 matrices side-by-side and on top of each


others
Mathematica
Out[146]= {{8,5, 1},
In Mathematica, to join 2 matrices side-by-side, use
{8,10,8},
Join with '2' as the third argument. To join them one {6,0, 8}}
on top of the other, use '1' as the third argument
a = RandomInteger[10, {3, 3}]

b = RandomInteger[10, {3, 3}] {{9, 0,1},


{10,2,7},
{8, 0,8}}

(*join side-by-side as in Matlab [A B]*) {{8,5, 1, 9,0,1},


Join[a, b, 2] {8,10,8,10,2,7},
{6,0, 8, 8,0,8}}

(*join vertically as in Matlab [A;B]*) {{8, 5 , 1},


Join[a, b, 1] {8, 10, 8},
{6, 0 , 8},
{9, 0 , 1},
{10,2 , 7},
{8, 0 , 8}}

139
2.17. Join 2 matrices side-by-side and on . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab
0.5472 0.2575 0.8143 0.3500 0.6160 0.8308
A=rand(3,3) 0.1386 0.8407 0.2435 0.1966 0.4733 0.5853
B=rand(3,3) 0.1493 0.2543 0.9293 0.2511 0.3517 0.5497
[A B]

[A;B] 0.5472 0.2575 0.8143


0.1386 0.8407 0.2435
0.1493 0.2543 0.9293
0.3500 0.6160 0.8308
0.1966 0.4733 0.5853
0.2511 0.3517 0.5497

Maple

A:=ArrayTools:-RandomArray(3,3,
distribution = uniform);

B:=ArrayTools:-RandomArray(3,3,
distribution = uniform);
<A|B>; #side by side

<A,B>; #on top of each others

140
2.18. Copy the lower triangle to the upper . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.18 Copy the lower triangle to the upper triangle of a


matrix to make symmetric matrix
Question posted on the net
please help me with simple to apply function that will construct
symmetric matrix from given just a half matrix with diagonal.
Eg:

From:
1 0 0 0
2 3 0 0
4 9 5 0
2 2 3 4

To give:

1 2 4 2
2 3 9 2
4 9 5 3
2 2 3 4

Many answers were given, below is my answer, and I also show how to do it in Matlab

Mathematica

a = {{1, 0, 0, 0}, {{1, 2, 4, 2},


{2, 3, 0, 0}, {2, 3, 9, 2},
{4, 9, 5, 0}, {4, 9, 5, 3},
{2, 2, 3, 4}}; {2, 2, 3, 4}
}
Transpose[LowerTriangularize[a, -1]] + a

Matlab

a = ans =
1 0 0 0 1 2 4 2
2 3 0 0 2 3 9 2
4 9 5 0 4 9 5 3
2 2 3 4 2 2 3 4

a+tril(a,-1)'

141
2.18. Copy the lower triangle to the upper . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple

A:=< <1|0|0|0>,
<2|3|0|0>, [[1,2,4,2],
<4|9|5|0>, [2,3,9,2],
<2|2|3|4>>; [4,9,5,3],
[2,2,3,4]]
B:=ArrayTools[LowerTriangle](A,-1);
A:=A+B^%T;

142
2.19. extract values from matrix given . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.19 extract values from matrix given their index


Given a matrix A, and list of locations within the matrix, where each location is given by
𝑖, 𝑗 entry, find the value in the matrix at these locations
Example, given
A={{1,2,3},
{4,5,6},
{7,8,9}}

obtain the entries at 1, 1 and 3, 3 which will be 1 and 9 in this example.

Mathematica

mat={{1,2,3},
{4,5,6},
{7,8,9}} {1,9}

pos = { {1,1},{3,3}};
Map[ mat[[Sequence@@ # ]] & , pos ]

Another method (same really as above, but using


Part explicit) {1,9}
Map[Part[A, Sequence @@ #] &, pos]

Matlab

A=[1 2 3;
4 5 6; ans =
7 8 9]; 1 9
I=[1 3]; % setup the I,J indices
J=[1 3];
A(sub2ind(size(A),I,J))

143
2.19. extract values from matrix given . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple

A:=<<1|2|3>,
<4|5|6>, [1, 9]
<7|8|9>>;
loc:=[[1,1],[3,3]];
map(x->A[op(x)],loc);

144
2.20. Convert 𝑁 by 𝑀 matrix to a row of . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.20 Convert 𝑁 by 𝑀 matrix to a row of length 𝑁𝑀


Given
a=[1 2 3
4 5 6
7 8 9]

covert the matrix to one vector


[1 2 3 4 5 6 7 8 9]

Mathematica
{1,2,3,4,5,6,7,8,9}
a={{1,2,3},
{4,5,6},
{7,8,9}}

Flatten[a]

Matlab
1 4 7 2 5 8 3 6 9
a=[1 2 3;
4 5 6;
7 8 9]

a=a(:);
a'

145
2.20. Convert 𝑁 by 𝑀 matrix to a row of . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple
[[1,2,3,4,5,6,7,8,9]]
Maple reshapes along columns, like Matlab. To
get same result as Mathematica, we can trans-
pose the matrix first. To get same result as Mat-
lab, do not transpose.
A:=<<1|2|3>,
<4|5|6>,
<7|8|9>>;
v:=ArrayTools[Reshape](A^%T,[1,9]);

Notice the result is a row matrix and not a vector.


To get a vector
A:=<<1|2|3>,
<4|5|6>,
<7|8|9>>;
v:=ArrayTools[Reshape](A^%T,9);
v^%T;

They look the same on the screen, but using


whattype we can find the type.

146
2.21. find rows in a matrix based on values . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.21 find rows in a matrix based on values in different


columns
Example, given Matrix
1 9 0 10
5 6 7 8
3 9 2 10

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 9 0 10
3 9 2 10

Mathematica

mat={{1,9,0,10},
{5,6,7,8}, {{1},{3}}
{3,9,2,10}};

p = Position[mat[[All,{2,4}]],x_/;x==={9,10}]

{{1,9,0,10},
Extract[mat,p]
{3,9,2,10}}

Matlab

A=[1 9 0 10;
5 6 7 8; ans =
3 9 2 10]; 1 9 0 10
3 9 2 10
r=bsxfun(@eq,A(:,[2 4]),[9 10]);
ind=all(r,2);
A(ind,:)

147
2.21. find rows in a matrix based on values . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple

A:=<<1|9|0|10>,
<5|6|7|8>,
<3|9|2|10>>; [[1,9,0,10],
[3,9,2,10]]
nRow:=op([1,1],A);
<seq(`if`(A[i,2]=9 and A[i,-1]=10,A[i,..],NULL
),
i=1..nRow)>;

148
2.22. Select entries in one column based . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.22 Select entries in one column based on a condition


in another column
Given
A=[4 3
6 4 ---->
7 6 ---->
2 1
1 3
9 2
2 5 ---->
1 2
]

Select elements in the first column only which has corresponding element in the second
column greater than 3, hence the result will be
[6 7 2]

149
2.22. Select entries in one column based . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Mathematica

mat = {{4, 3},


{6, 4},
{7, 6},
{2, 1},
{1, 3}, {6, 7, 2}
{9, 2},
{2, 5},
{1, 2}};

r = Select[mat, #[[2]] > 3 &];


r[[All, 1]]

another way is to find the index using Position


and then use Extract
loc = Position[mat, {x_, y_} /; y > 3] {6, 7, 2}
r = Extract[mat, loc];
r[[All, 1]]

another way is to use Cases[]. This is the shortest


way {6, 7, 2}
Cases[mat, {x_, y_} /; y > 3 :> x]

Matlab

A=[4, 3;
6, 4;
7, 6;
2, 1; 6
1, 3; 7
9, 2; 2
2, 5;
1, 2];

A(A(:,2)>3,1)

150
2.22. Select entries in one column based . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple

A:=<<4|3>,
<6|4>,
<7|6>,
<2|1>, [[6],
<1|3>, [7],
<9|2>, [2]]
<2|5>,
<1|2>>;
nRow:=op([1,1],A);
<seq(`if`(A[i,2]>3,A[i,1],NULL),i=1..nRow)>;

151
2.23. Locate rows in a matrix with column . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.23 Locate rows in a matrix with column being a string


The problem is to select rows in a matrix based on string value in the first column. Then
sum the total in the corresponding entries in the second column. Given. For example, given

mat = {'foobar', 77;


'faabar', 81;
'foobur', 22;
'faabaa', 8;
'faabian', 88;
'foobar', 27;
'fiijii', 52};

and given list


{'foo', 'faa'}

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
'foo' 'faa'
[126] [ 177]

Mathematica

mat = {{"foobar", 77},


{"faabar", 81},
{"foobur", 22},
{"faabaa", 8},
{"faabian", 88},
{"foobar", 27},
{"fiijii", 52}};
lst = {"foo", "faa"}; {{"foo", 126}, {"faa", 177}}

foo[mat_, lst_] :=
Select[mat, StringMatchQ[lst,
StringTake[#[[1]], 3]] &];

r = Map[foo[mat, #] &, lst];

MapThread[{#1,
Total[#2[[All, 2]]]}&,{lst, r}]

152
2.23. Locate rows in a matrix with column . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab
ans =
A = {'foobar', 77; 'foo' 'faa'
'faabar', 81; [126] [177]
'foobur', 22;
'faabaa', 8;
'faabian', 88;
'foobar', 27;
'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)

But notice that in Matlab, the answer is a cellarray. To access


the numbers above ans =
r{:} 'foo' [126]
r{1}{2} ans =
r{2}{2} 'faa' [177]

ans =
126

ans =
177

153
2.24. Remove set of rows and columns . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.24 Remove set of rows and columns from a matrix at


once
Given: square matrix, and list which represents the index of rows to be removed, and it also
represents at the same time the index of the columns to be removed (it is square matrix, so
only one list is needed).
output: the square matrix, with BOTH the rows and the columns in the list removed.
Assume valid list of indices.
This is an example: remove the second and fourth rows and the second and fourth columns
from a square matrix.

I asked this question at SO, and more methods are shown there at HTML

154
2.24. Remove set of rows and columns . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Mathematica Three methods are shown.


{{0, 2, 1, 0},
method 1:
{4, 3, 3, 2},
(credit for the idea to Mike Honeychurch at stackover- {3, 4, 3, 3},
flow). It turns out it is easier to work with what we want {5, 4, 2, 0}
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
pos = {2, 4};

Start by generating list of the rows and columns to keep


by using the command Complement[], followed by using
Part[]
a = {{0, 5, 2, 3, 1, 0},
{4, 3, 2, 5, 1, 3},
{4, 1, 3, 5, 3, 2},
{4, 4, 1, 1, 1, 5},
{3, 4, 4, 5, 3, 3},
{5, 1, 4, 5, 2, 0}
};
pos = {2, 4};
keep = Complement[Range[Length[a]], pos];
a[[keep, keep]]

method 2: (due to Mr Wizard at stackoverflow)


ReplacePart[a, {{2},{4},{_, 2},{_, 4}} {{0, 2, 1, 0},
:> Sequence[]] {4, 3, 3, 2},
{3, 4, 3, 3},
{5, 4, 2, 0}
}

method 3: (me)
use Pick. This works similar to Fortran pack(). Using a Out[39]= {{0,2,1,0},
mask matrix, we set the entry in the mask to False for {4,3,3,2},
those elements we want removed. Hence this method is {3,4,3,3},
just a matter of making a mask matrix and then using it {5,4,2,0}}
in the Pick[] command.
{nRow,nCol} = Dimensions[a];
mask = Table[True,{nRow},{nCol}];
pos = {2,4};
mask[[All,pos]]=False;
mask[[pos,All]]=False;
r=Pick[a,mask]/.{}->Sequence[]
155
2.24. Remove set of rows and columns . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab
a =
a = [0, 5, 2, 3, 1, 0; 0 2 1 0
4, 3, 2, 5, 1, 3; 4 3 3 2
4, 1, 3, 5, 3, 2; 3 4 3 3
4, 4, 1, 1, 1, 5; 5 4 2 0
3, 4, 4, 5, 3, 3;
5, 1, 4, 5, 2, 0
]

list=[2 4];
a(list,:)=[];
a(:,list)=[];

156
2.25. Convert list of separated numerical . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.25 Convert list of separated numerical numbers to


strings
Problem: given a list of numbers such as
{{1, 2},
{5, 3, 7},
{4}
}

convert the above to list of strings


{"12",
"537",
"4"}

Mathematica

a={{1,2},{5,3,7},{4}}; List["12","537","4"]
Map[ToString[#]&,a,{2}];
Map[StringJoin[#]&,%]

Matlab
ans =
a={[1,2],[5,3,7],[4]}; '1 2'
r=arrayfun(@(i) ... '5 3 7'
cellstr(num2str(a{i})),1:length(a)); '4'
r'

answer below is due to Bruno Luong at Matlab newsgroup


a={[1,2],[5,3,7],[4]};
'12' '537' '4'
map='0':'9';
cellfun(@(x) map(x+1), a, 'uni', 0)

157
2.26. Obtain elements that are common . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.26 Obtain elements that are common to two vectors


Given vector or list 𝑑 = [−9, 1, 3, −3, 50, 7, 19], 𝑡 = [0, 7, 2, 50], find the common elements.
Mathematica

d = {-9,1,3,-3,50,7,19}; Out[412]= {7,50}


t = {0,7,2,50};
Intersection[d,t]

Matlab
ans =
d=[-9 1 3 -3 50 7 19]; 7 50
t =[0 7 2 50];
intersect(t,d)

158
2.27. Sort each column (on its own) in a . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.27 Sort each column (on its own) in a matrix


Given
4 2 5
2 7 9
10 1 2

Sort each column on its own, so that the result is


2 1 2
4 2 5
10 7 9

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
{{2, 1, 2},
mat={{4,2,5}, {4, 2, 5},
{2,7,9}, {10,7, 9}}
{10,1,2}};

Map[Sort[#]&,Transpose[mat]];
mat=Transpose[%]

Matlab

A=[4 2 5; 2 1 2
2 7 9; 4 2 5
10 1 2]; 10 7 9
sort(A,1)

159
2.28. Sort each row (on its own) in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.28 Sort each row (on its own) in a matrix


Given
4 2 5
2 7 9
10 1 2

Sort each row on its own, so that the result is


2 4 5
2 7 9
1 2 10

Mathematica

mat={{4, 2,5}, {{2, 4, 5},


{2, 7,9}, {2, 7, 9},
{10,1,2}}; {1, 2, 10}}
Map[Sort[#]&,mat]

Matlab

A=[4 2 5; 2 4 5
2 7 9; 2 7 9
10 1 2]; 1 2 10
sort(A,2)

160
2.29. Sort a matrix row-wise using first . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.29 Sort a matrix row-wise using first column as key


Given
4 2 5
2 7 9
10 1 2

Sort the matrix row-wise using first column as key so that the result is
2 7 9
4 2 5
10 1 2

In Matlab, the sortrows() command is used. In Mathematica the Sort[] command is now
used as is.
Mathematica

mat={{4, 2, 5}, {{2, 7, 9},


{2, 7, 9}, {4, 2, 5},
{10,1, 2}}; {10, 1, 2}}
Sort[mat]

Matlab

A=[4 2 5; 2 7 9
2 7 9; 4 2 5
10 1 2]; 10 1 2
sortrows(A)

161
2.30. Sort a matrix row-wise using non- . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.30 Sort a matrix row-wise using non-first column as


key
Given
4 2 5
2 7 9
10 1 2

Sort the matrix row-wise using the second column as key so that the result is
10 1 2
4 2 5
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

mat={{4, 2, 5}, {{10, 1, 2},


{2, 7, 9}, {4, 2, 5},
{10,1, 2}}; {2, 7, 9}}
(*sort by second element as key*)
SortBy[mat,#[[2]]&]

Matlab

A=[4 2 5; 10 1 2
2 7 9; 4 2 5
10 1 2]; 2 7 9
sortrows(A,2)

162
2.31. Replace the first nonzero element in . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.31 Replace the first nonzero element in each row in a


matrix by some value
Problem: Given a matrix, replace the first nonzero element in each row by some a specific
value. This is an example. Given matrix 𝐴 below, replace the first non-zero element in each
row by −1, then
⎛ ⎞ ⎛ ⎞
⎜⎜50 75 0 ⎟⎟ ⎜⎜−1 75 0 ⎟⎟
⎜⎜ ⎟ ⎜⎜ ⎟
⎜⎜50 0 100⎟⎟⎟ ⎜⎜−1 0 100⎟⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟⎟
⎜⎜ ⎟ ⎜⎜ ⎟
⎜⎜ 0 75 100⎟⎟⎟ ⎜⎜ 0 −1 100⎟⎟⎟
𝐴 = ⎜⎜ ⎟ will become 𝐵 = ⎜⎜ ⎟
⎜⎜75 100 0 ⎟⎟⎟ ⎜⎜−1 100 0 ⎟⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟
⎜⎜ 0 75 100⎟⎟ ⎜⎜ 0 −1 100⎟⎟⎟
⎜⎝ ⎟⎠ ⎜⎝ ⎟⎠
0 75 100 0 −1 100

163
2.31. Replace the first nonzero element in . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Mathematica

A={ {50, 75, 0},{50, 0, 100},


{0, 75, 100},{75, 100, 0},
{0, 75, 100},{0, 75, 100}};
ReplacePart[A,DeleteDuplicates[
Position[A,_?(#!=0&)],
(#1[[1]]==#2[[1]]&)]->-1]

Solution due to Bob Hanlon (from Mathematica


newsgroup)
r=Union[Position[A,_?(# !=0&)],
SameTest->(#1[[1]]==#2[[1]]&)];
ReplacePart[A,r->-1]

Solution by Fred Simons (from Mathematica news-


group)
r=Split[Position[A,_?(# !=0&),{2}], {{-1,75,0},{-1,0,100},{0,-1,100},
#1[[1]]==#2[[1]]&][[All,1]];
ReplacePart[A,r->-1] {-1,100,0},{0,-1,100},{0,-1,100}}

Solution due to Adriano Pascoletti (from Mathemat-


ica newsgroup)
r=(First /@ Split[#1,First[#1]===First[#2]&]&)
[Position[A,x_/;x!=0]]
ReplacePart[A,r->-1]

Solution due to Oliver Ruebenkoenig (from Mathe-


matica newsgroup)
r=First /@ SplitBy[ Drop[ArrayRules[
SparseArray[A]][[All,1]],-1],First]
ReplacePart[A,r->-1]

Solution due to Szabolcs Horvát (from Mathematica


newsgroup)
r=MapIndexed[{First[#2],1+LengthWhile
[#1,#==0&]}&,A]
ReplacePart[A,r->-1]

164
2.31. Replace the first nonzero element in . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

A=[50 75 0;
50 0 100;
0 75 100;
75 100 0;
0 75 100;
0 75 100]; A =
-1 75 0
[I,J] = ind2sub(size(A),find(A~=0)); -1 0 100
[b,c] = unique(I,'first'); 0 -1 100
A(sub2ind(size(A),b,J(c)))=-1 -1 100 0
0 -1 100
This solution due to Bruno Luong (from matlab news- 0 -1 100
group)
B = cumsum(A~=0,2)>0
B = [false(size(B,1),1) B]
A(logical(diff(B,1,2))) = -1

This solution due to Jos from matlab newsgroup


A((cumsum(~~A,2)==1) & (A ~= 0)) = -1

165
2.32. Perform outer product and outer . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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


Remove["Global`*"] {{a e, a f, a g},
{b e, b f, b g},
v1={a,b,c}; {c e, c f, c g}}
v2={e,f,g};
Outer[Times,v1,v2]

Outer sum {{a+e, a+f, a+g},


{b+e, b+f, b+g},
Outer[Plus,v1,v2]
{c+e, c+f, c+g}}

using numerical vectors. Outer product


{{4, 5, 6},
v1={1,2,3};
{8, 10, 12},
v2={4,5,6};
{12, 15, 18}}
Outer[Times,v1,v2]

Outer sum {{5, 6, 7},


{6, 7, 8},
Outer[Plus,v1,v2]
{7, 8, 9}}

166
2.32. Perform outer product and outer . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

Outer product ans =


v1=[1 2 3]; 4 5 6
v2=[4 5 6]; 8 10 12
12 15 18
v1'*v2

Outer sum
ans =
v1=[1 2 3]; 5 6 7
v2=[4 5 6]; 6 7 8
meshgrid(v1)+meshgrid(v2)' 7 8 9

Maple

Due to Carl Love from the Maple newsgroup


restart;

Outer:= proc(OP, L1, L2) [a*d,a*e,a*f,b*d,


local a,b; b*e, b*f, c*d, c*e, c*f
[seq](seq(OP(a,b), b in L2), a in L1) ]
end proc:

L1:=[a,b,c];
L2:=[d,e,f];
Outer(`*`,L1,L2);

[a+d, a+e, a+f, b+d,


Outer(`+`,L1,L2); b+e, b+f, c+d, c+e, c+f
]

167
2.33. Find the rank and the bases of the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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⎟⎟
⎜⎜ ⎟⎟
𝐴 = ⎜⎜⎜0 −1 −2 2⎟⎟⎟
⎜⎝ ⎟⎠
0 0 0 1

Mathematica

mat={{2,3,3,4},
{0,-1,-2,2},
{0,0,0,1}}; 3,4

{nRow,nCol} = Dimensions[mat]

Print["Rank (or dimension of the range space)=", Rank (or dimension of the
MatrixRank[mat]] range space)=3

Print["Dimension of the Null Space=", Dimension of the Null


nCol-MatrixRank[mat]] Space=1

Basis for Null Space


Print["Basis for Null Space=",NullSpace[mat]]
={{3,-4,2,0}}

168
2.33. Find the rank and the bases of the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

A=[2 3 3 4; A range space dimension=3


0 -1 -2 2; A null space dimension= 1
0 0 0 1] Basic for null space of A
=
[nRow,nCol]=size(A);

r = rank(A); ans =
fprintf('A range space dimension=%d\n',r); 1.5000 -2.0000 1.0000
fprintf('A null space dimension= %d\n',nCol-r); 0
fprintf('Basic for null space of A =');
null(A,'r')'

169
2.34. Find the singular value . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.34 Find the singular value decomposition (SVD) of a


matrix
⎡ ⎤
⎢⎢1 2 3⎥⎥
Problem: Find the SVD for the matrix ⎢⎢⎣ ⎥⎥ Notice that in Maple, the singular values
4 5 6⎦
matrix, normally called S, is returned as a column vector. So need to call DiagonalMatrix()
to format it as expected.

{{0.386318,-0.922366},
{0.922366,0.386318}}
Mathematica
{{9.50803,0.,0.},
mat = {{1,2,3},
{0.,0.77287,0.}}
{4,5,6}}

{u,s,v}=N[SingularValueDecomposition[mat]] {{0.428667,0.805964,0.408248},
{0.566307,0.112382,-0.816497},
{0.703947,-0.581199,0.408248}}

(*Reconstruct A from its components *) {{1.,2.,3.},


u.s.Transpose[v] {4.,5.,6.}}

170
2.34. Find the singular value . . . CHAPTER 2. LINEAR ALGEBRA, . . .

u =
-0.3863 -0.9224
-0.9224 0.3863
Matlab
s =
A=[1 2 3;
4 5 6]; 9.5080 0 0
[u,s,v]=svd(A); 0 0.7729 0
u
s v =
v
-0.4287 0.8060 0.4082
-0.5663 0.1124 -0.8165
-0.7039 -0.5812 0.4082

ans =
u*s*v' 1.0000 2.0000 3.0000
4.0000 5.0000 6.0000

171
2.34. Find the singular value . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple
[1 2 3 ]
restart; A := [ ]
with(LinearAlgebra): [4 5 6.]
A:=Matrix([[1,2,3],[4,5,6.]]);

[0.386317703118612
m,n:=Dimensions(A): -0.922365780077058]
u,s,v:=SingularValues(A, [
output=['U', 'S', 'Vt']): ]
u; [0.922365780077058
0.386317703118612 ]

[9.50803200069572
0 0]
s := [
]
[ 0
0.772869635673485 0]

s:=DiagonalMatrix(s,m,n); [0.428667133548626
v; 0.566306918848035
0.703946704147444 ]
v:= [0.805963908589298
0.112382414096594
-0.581199080396110]
[0.408248290463863
-0.816496580927726
0.408248290463863 ]

[9.50803200069572
0 0]
> s2:=DiagonalMatrix(SingularValues(A, s2 := [
output=['S']),m,n); ]
[ 0
0.772869635673485 0]

[1. 2. 3.]
> evalf(u.s.v); [ ]
[4. 5. 6.]

172
2.35. Solve 𝐴𝑥 = 𝑏 CHAPTER 2. LINEAR ALGEBRA, . . .

2.35 Solve 𝐴𝑥 = 𝑏
Solve for x in the following system of equations
[ 1 2 3 ][x1] [ 1 ]
[ 7 5 6 ][x2]= [ 2 ]
[ 7 8 8 ][x3] [ 3 ]

Mathematica

mat={{1,2,3},
{7,5,6}, {0,0,1/3}
{7,8,9}};
b = {1,2,3}
LinearSolve[mat,b]

Matlab

format long ans =


A=[1 2 3; 0
7 5 6; 0
7 8 9]; 0.333333333333333
b=[1;2; 3];
A\b

173
2.35. Solve 𝐴𝑥 = 𝑏 CHAPTER 2. LINEAR ALGEBRA, . . .

Fortran
 
program t2
implicit none
integer, parameter :: N=3
real(8), DIMENSION(N, N) :: &
A=DBLE(reshape([ 1.0, 2.0, 3.0,&
7.0, 5.0, 6.0,&
7.0, 8.0, 9.0], shape(A), order=[2,1]))

real(8), parameter, DIMENSION(N, 1) :: &


b=DBLE(reshape([1.0, 2.0, 3.0], shape(b)))

real(8), DIMENSION(N, 1) :: IPIV


integer :: INFO

CALL DGETRF( N, N, A, N, IPIV, INFO )


if (INFO .eq. 0 ) then
CALL DGETRS( 'N', N,1, A, N, IPIV, b , N, INFO)
if ( INFO .eq. 0 ) then
print *, 'solution is',b
else
print *, 'failed DGETRS, INFO=',INFO
end if
else
print *, 'failed DGETRF, INFO=',INFO
end if
end program
 

compile and run


$ gfortran -std=f2003 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion
t2.f90 /usr/lib/liblapack.a /usr/lib/libblas.a

$ ./a.exe
solution is
-5.28677630773884192E-018 -3.70074341541718826E-017 0.33333333333333337

174
2.36. Find all nonzero elements in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.36 Find all nonzero elements in a matrix


Given a matrix, find the locations and the values of all nonzero elements. Hence given the
matrix

⎛ ⎞
⎜⎜ 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

In Mathematica, standard Mathematica matrix opera-


tions can be used, or the matrix can be converted to
SparseArray and special named operation can be used
on it.
{{1,3},{2,1},{2,3},{3,1},{3,2}}
mat = {{0 , 0, 1},
{10, 0, 2},
{3 , 4, 0}};

sp = SparseArray[mat];
pos = sp["NonzeroPositions"]

values=sp["NonzeroValues"] {1,10,2,3,4}

Or standard list operations can be used


mat = {{0 , 0, 1},
{10, 0, 2},
{3 , 4, 0}};
{1,10,2,3,4}
(*find values not zero *)

Cases[mat,x_ /;Not[PossibleZeroQ[x]]:>x,2]

(*find the index *)


{{1,3},{2,1},{2,3},{3,1},{3,2}}
Position[mat,x_/;x!=0]

175
2.36. Find all nonzero elements in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

values =
Matlab 10
3
A=[0 0 1; 10 0 2; 3 4 0]; 4
values= nonzeros(A) 1
2

I =
2
3
3
1
%find locations 2
[I,J]=find(A) J =
1
1
2
3
3

176
2.37. evaluate f(x) on a vector of values CHAPTER 2. LINEAR ALGEBRA, . . .

2.37 evaluate f(x) on a vector of values


Given a function 𝑓(𝑥) evaluate it for each value contained in a vector. For example, given
𝑓(𝑥) = 𝑥2 evaluate it on (1, 2, 3) such that the result is (1, 4, 9).

Mathematica

Clear[f,x]
f[x_]:=x^2 {1,4,9}
v={1,2,3};
f[v]

Matlab

clear all; ans =


v=[1 2 3] 1 4 9
f=@(x) x.^2
f(v)

177
2.38. generates equally spaced N points . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.38 generates equally spaced N points between 𝑥1 and


𝑥2
Mathematica Matlab

x1=1; clear all;


x2=3; x1 = 1;
FindDivisions[{x1,x2},5] x2 = 3;
linspace(x1,x2,5)
Out[48]= {1,3/2,2,5/2,3}
ans =
N[%] 1.0000 1.5000 2.0000 2.5000
Out[49]= {1.,1.5,2.,2.5,3.} 3.0000

178
2.39. evaluate and plot a 𝑓(𝑥, 𝑦) on 2D grid . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.39 evaluate and plot a 𝑓(𝑥, 𝑦) on 2D grid of coordinates


Evaluate 𝑥 exp−𝑥 −𝑦 on 2D cartesian grid between 𝑥 = −2 ⋯ 2 and 𝑦 = −4 ⋯ 4 using ℎ = 0.4
2 2

for grid spacing.


Mathematica
f[x_,y_]:=x Exp[-x^2-y^2];
data = Table[f[x,y],{x,-2,2,.2},{y,-4,4.2}];
ListPlot3D[data,
PlotRange->All,
ColorFunction->"Rainbow",
AxesLabel->{"x","y","z"},
LabelStyle->12,
Ticks->{Range[-2,2,1],Range[-4,4,1],Automatic},
DataRange->{{-2,2},{-4,4},Automatic},
ImageSize->400]

The above can also be done using Plot3D


f[x_,y_]:=x Exp[-x^2-y^2];
Plot3D[f[x,y],{x,-2,2},{y,-4,4},
PlotRange->All,
ColorFunction->"Rainbow",
AxesLabel->{"x","y","z"},
LabelStyle->12,
ImageSize->400]

179
2.39. evaluate and plot a 𝑓(𝑥, 𝑦) on 2D grid . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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');

180
2.40. Find determinant of matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.40 Find determinant of matrix


Given a square matrix, find its determinant. In Mathematica, the Det[] command is used.
In Matlab the det() command is used.
Mathematica

mat=Table[RandomReal[],{3},{3}] -0.317792605942287
Det[mat]

Matlab

A=rand(3,3); -0.276653966272994
det(A)

181
2.41. Generate sparse matrix with 𝑛 by 𝑛 . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.41 Generate sparse matrix with 𝑛 by 𝑛 matrix repeated


on its diagonal
⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜ ⎟⎟
Given matrix ⎜⎜⎜4 5 6⎟⎟⎟, generate the following sparse matrix with this matrix on the diagonal
⎜⎝ ⎟⎠
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 ⎟⎟⎟
⎜⎜ ⎟⎟
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}]-> ⎜⎜ ⎟⎟
⎜⎜ 0 0 0 4. 5. 6. 0 0 0 ⎟⎟⎟
ConstantArray[mat,{3}]] ⎜⎜ ⎟⎟
⎜⎜
⎜⎜ 0 0 0 7. 8. 9. 0 0 0 ⎟⎟⎟
MatrixForm[sp] ⎜⎜ ⎟⎟
⎜⎜ 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. ⎠

182
2.41. Generate sparse matrix with 𝑛 by 𝑛 . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

A = [1 2 3; ans =
4 5 6; 1 0 0
7 8 9]; 0 1 0
0 0 1
Iy = speye(3);
full(Iy)

ans =
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
sp = kron(Iy,A); 0 0 0 1 2 3 0 0 0
full(sp) 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

183
2.42. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.42 Generate sparse matrix for the tridiagonal


representation of second difference operator in 1D
𝑑2 𝑢 𝑢 −2𝑢 +𝑢
The second derivative 𝑑𝑥2 is approximated by 𝑖−1 ℎ2𝑖 𝑖+1 where ℎ is the grid spacing. Generate
the 𝐴 matrix that represent this operator for 𝑛 = 4 where 𝑛 is the number of internal grid
points on the line

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 ⎟⎟⎟
numberOfInternalGridPoints = 4; ⎜⎜
⎜⎜ ⎟⎟
⎜⎜ 0 1 −2 1 0 0 0 0 0 0 0 0 ⎟⎟⎟
n = 3*internalGridPoints; ⎜⎜
⎜⎜ 0 0 1 −2 1 0 0 0 0 0 0 0 ⎟⎟⎟
⎟⎟
⎜⎜
sp = SparseArray[{Band[{1,1}]->-2, ⎜⎜
⎜⎜ 0 0 0 1 −2 1 0 0 0 0 0 0 ⎟⎟⎟⎟

⎜⎜ ⎟
Band[{1,2}]->1, ⎜⎜
⎜⎜ 0 0 0 0 1 −2 1 0 0 0 0 0 ⎟⎟⎟⎟
⎜⎜ ⎟
Band[{2,1}]->1}, ⎜⎜ 0 0 0 0 0 1 −2 1 0 0 0 0 ⎟⎟⎟⎟
⎜⎜ ⎟
⎜⎜ 0 0 0 0 0 0 1 −2 1 0 0 0 ⎟⎟⎟
{n,n}] ⎜⎜
⎜⎜
⎟⎟
⎜⎜ 0 0 0 0 0 0 0 1 −2 1 0 0 ⎟⎟⎟
Out[103]= SparseArray[<34>,{12,12}] ⎜⎜ ⎟⎟
⎜⎜ 0 0 0 0 0 0 0 0 1 −2 1 0 ⎟⎟⎟
⎜⎜ ⎟⎟
MatrixForm[sp] ⎜⎜
⎜⎜ 0 0 0 0 0 0 0 0 0 1 −2 1 ⎟⎟⎟
⎝ ⎟⎠
0 0 0 0 0 0 0 0 0 0 1 −2

184
2.42. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

ans =
-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 0 0 0 0 0 0 0
0
0 0 1 -2 1 0 0 0 0 0 0
0
Matlab 0 0 0 1 -2 1 0 0 0 0 0
0
internalGridPoints = 4; 0 0 0 0 1 -2 1 0 0 0 0
n = 3*internalGridPoints; 0
e = ones(n,1); 0 0 0 0 0 1 -2 1 0 0 0
sp = spdiags([e -2*e e], -1:1, n,n); 0
full(sp) 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
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

185
2.43. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.43 Generate sparse matrix for the Laplacian


differential operator ∇ 2 𝑢 for 2D grid
𝜕2𝑢 𝜕2𝑢
∇ 2 𝑢 = 𝑓 in 2D is defined as 2 + = 𝑓 and the Laplacian operator using second order stan-
𝜕𝑥 𝜕𝑦2
𝑢𝑖−1,𝑗 +𝑢𝑖+1,𝑗 +𝑢𝑖,𝑗−1 +𝑢𝑖,𝑗+1 −4𝑢𝑖,𝑗
dard differences results in � ℎ2
� = 𝑓𝑖,𝑗 where ℎ is the grid size. The above
is solved for 𝑥 in the form 𝐴𝑥 = 𝑓 by generating the 𝐴 matrix and taking into consideration
the boundary conditions. The follows show how to generate the sparse representation of 𝐴.
Assuminh the number of unknowns 𝑛 = 3 in one direction. Hence there are 9 unknowns to
solve for and the 𝐴 matrix will be 9 by 9.

Matlab ans =
-4 1 0 1 0 0 0 0 0
internalPoints=3; 1 -4 1 0 1 0 0 0 0
e = ones(internalPoints,1); 0 1 -4 0 0 1 0 0 0
spe = spdiags([e -2*e e], -1:1,... 1 0 0 -4 1 0 1 0 0
internalPoints,internalPoints); 0 1 0 1 -4 1 0 1 0
Iz = speye(internalPoints); 0 0 1 0 1 -4 0 0 1
sp = kron(Iz,spe)+kron(spe,Iz); 0 0 0 1 0 0 -4 1 0
full(sp) 0 0 0 0 1 0 1 -4 1
0 0 0 0 0 1 0 1 -4

186
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.44 Generate sparse matrix for the Laplacian


differential operator ∇ 2 𝑢 for 3D grid
The goal is to solve
𝜕2𝑢 𝜕2𝑢 𝜕2𝑢
+ + = −𝑓(𝑥, 𝑦, 𝑧)
𝜕𝑥2 𝜕𝑦2 𝜕𝑧2
On the unit cube. The following diagram was made to help setting up the 3D scheme to
approximate the above PDE

The discrete approximation to the Laplacian in 3D is

𝜕2𝑢 𝜕2𝑢 𝜕2𝑢 1


2
+ 2 + 2 = 2 �𝑈𝑖−1,𝑗,𝑘 + 𝑈𝑖+1,𝑗,𝑘 + 𝑈𝑖,𝑗−1,𝑘 + 𝑈𝑖,𝑗+1,𝑘 + 𝑈𝑖,𝑘,𝑘−1 + 𝑈𝑖,𝑗,𝑘+1 − 6𝑈𝑖,𝑗,𝑘 �
𝜕𝑥 𝜕𝑦 𝜕𝑧 ℎ

For the direct solver, the 𝐴 matrix needs to be formulated. From


1
�𝑈 + 𝑈𝑖+1,𝑗,𝑘 + 𝑈𝑖,𝑗−1,𝑘 + 𝑈𝑖,𝑗+1,𝑘 + 𝑈𝑖,𝑘,𝑘−1 + 𝑈𝑖,𝑗,𝑘+1 − 6𝑈𝑖,𝑗,𝑘 � = 𝑓𝑖,𝑗,𝑘
ℎ2 𝑖−1,𝑗,𝑘
Solving for 𝑈𝑖,𝑗,𝑘 results in

1
𝑈𝑖,𝑗,𝑘 = �𝑈 + 𝑈𝑖+1,𝑗,𝑘 + 𝑈𝑖,𝑗−1,𝑘 + 𝑈𝑖,𝑗+1,𝑘 + 𝑈𝑖,𝑘,𝑘−1 + 𝑈𝑖,𝑗,𝑘+1 − ℎ2 𝑓𝑖,𝑗,𝑘 �
6 𝑖−1,𝑗,𝑘
To help make the 𝐴 matrix, a small example with 𝑛 = 2, is made. The following diagram
uses the standard numbering on each node

187
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

By traversing the grid, left to right, then inwards into the paper, then upwards, the following
𝐴 matrix results

The recursive pattern involved in these 𝐴 matrices can now be seen. Each 𝐴 matrix contains
inside it a block on its diagonal which repeats 𝑛 times. Each block in turn contain inside it,
on its diagonal, smaller block, which also repeats 𝑛 times.
It is easier to see the pattern of building 𝐴 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 𝑛 = 2,

188
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

The connections are now more easily seen. Grid point 1 has connection to only points 2, 3, 5.
This means when looking at the 𝐴 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 𝑛 = 3 to better see the pattern
of 𝐴 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 𝑛2
higher than the grid point itself. 𝑛2 is the size of the grid at each surface. Hence, the general
𝐴 matrix, for the above example, can now be written as

189
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

The recursive structure can be seen. There are 𝑛 = 3 main repeating blocks on the diagonal,
and each one of them in turn has 𝑛 = 3 repeating blocks on its own diagonal. Here 𝑛 = 3,
the number of grid points along one dimension.
Now that the 𝐴 structure is understood, the A matrix can be generated.
Example 1: Using 𝑛𝑥 = 2, 𝑛𝑦 = 2, 𝑛𝑧 = 2. These are the number of grid points in the 𝑥, 𝑦, 𝑧
directions respectively.

190
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

nx=2;
ny=2;
ex=ones(nx,1);
Lx=spdiags([ex -3*ex ex],[-1 0 1],nx,nx);
ey=ones(ny,1); ans =
Ly=spdiags([ey -3*ey ey],[-1 0 1],ny,ny); -6 1 1 0 1 0 0 0
1 -6 0 1 0 1 0 0
Ix=speye(nx); 1 0 -6 1 0 0 1 0
Iy=speye(ny); 0 1 1 -6 0 0 0 1
L2=kron(Iy,Lx)+kron(Ly,Ix); 1 0 0 0 -6 1 1 0
0 1 0 0 1 -6 0 1
nz=2; 0 0 1 0 1 0 -6 1
N=nx*ny*nz; 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 𝑛𝑥 = 2, 𝑛𝑦 = 2, 𝑛𝑧 = 3.

191
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

ans =
-6 1 1 0 1 0 0 0 0 0 0
Matlab 0
1 -6 0 1 0 1 0 0 0 0 0
nx=2; 0
ny=2; 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); 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); 1 0 0 0 -6 1 1 0 1 0 0
0
Ix=speye(nx); 0 1 0 0 1 -6 0 1 0 1 0
Iy=speye(ny); 0
L2=kron(Iy,Lx)+kron(Ly,Ix); 0 0 1 0 1 0 -6 1 0 0 1
0
nz=3; 0 0 0 1 0 1 1 -6 0 0 0
N=nx*ny*nz; 1
e=ones(N,1); 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); 0 0 0 0 0 1 0 0 1 -6 0
1
A=kron(Iz,L2)+L; 0 0 0 0 0 0 1 0 1 0 -6
full(A) 1
0 0 0 0 0 0 0 1 0 1 1
-6

Example 3: Using 𝑛𝑥 = 3, 𝑛𝑦 = 3, 𝑛𝑧 = 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;

192
2.44. Generate sparse matrix for the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

full(A)

Matlab result is below.

193
2.45. Generate the adjugate matrix for . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.45 Generate the adjugate matrix for square matrix


Given square matrix such as

⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜ ⎟
⎜⎜4 5 6⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
7 8 9

find the adjugate matrix which is

⎛ ⎞
⎜⎜−3 6 −3⎟⎟
⎜⎜ ⎟
⎜⎜ 6 −12 6 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
−3 6 −3

Mathematica

<<"Combinatorica`" (*not needed in V9


*) { {-3, 6, -3},
mat = {{1,2,3},{4,5,6},{7,8,9}}; { 6, -12, 6},
cof = Table[Cofactor[mat,{i,j}], {-3, 6, -3}}
{i,3},{j,3}];
adjugate = Transpose[cof]

194
2.45. Generate the adjugate matrix for . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab Warning: Matrix is close to


singular
Will try to find function in Matlab to do this. Butor badly scaled. Results may be
for non-singular matrices only the direct method inaccurate.
of finding the inverse and then multiplying by RCOND = 1.541976e-18.
the determinant to recover the adjunct can be
used. ans =
-3.0000 6.0000 -3.0000
A=[1 2 3;4 5 6;7 8 9]
6.0000 -12.0000 6.0000
det(A)*inv(A) -3.0000 6.0000 -3.0000

The following is due to Matt J from the matlab


newsgroup
A=[1 2 3; adjunct_A =
4 5 6;
-3.0000 6.0000 -3.0000
7 8 9]
6.0000 -12.0000 6.0000
-3.0000 6.0000 -3.0000
c=poly(A);
adjunct_A=polyvalm(c(1:end-1),A)

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.
 
\begin{verbatimwrite}{toLua.txt}
!-- Find the Adjugate of a square matrix
!-- Version 6/22/2012 by Nasser M. Abbasi gfortran 4.6.3
program t44
implicit none
integer, parameter :: n=3
integer :: INFO,i,j,ii,IPIV(n-1),number_row_exchange
real (kind=kind(0.0d0)) :: A(n,n),B(n-1,n-1),C(n,n)
logical :: M(n,n)

A(1,:) = [1, 2, 3];


A(2,:) = [4, 5, 6];
A(3,:) = [7, 8, 9];

DO j=1,n
DO i=1,n

M = .true.
195
2.45. Generate the adjugate matrix for . . . CHAPTER 2. LINEAR ALGEBRA, . . .

M(:,j) = .false.
M(i,:) = .false.
B = reshape(pack(A, M),[n-1,n-1])

!-- LU decomposition in order to obtain determinant


CALL DGETRF( n-1, n-1, B, n-1, IPIV, INFO )

!-- determinant of U is the product of diagonal


C(i,j)= PRODUCT( [(B(ii,ii),ii=1,n-1)] )

!-- Adjust sign based on number of row exchanges and (-1)^(i+j)


number_row_exchange = count(IPIV /= [(ii,ii=1,n-1)])
C(i,j) = C(i,j)*(1-2*MODULO(number_row_exchange+i+j,2))

END DO
END DO
write(*,'(3F15.4)') C
end program t44
 
#compile, link and run
export LD_LIBRARY_PATH=/usr/lib/atlas-base/:/usr/lib/atlas-base/atlas/
gfortran -fcheck=all -Wall t44.f90 -L/usr/lib/atlas-base/atlas/ -lblas -llapack
>./a.out
-3.0000 6.0000 -3.0000
6.0000 -12.0000 6.0000
-3.0000 6.0000 -3.0000
!>dpkg -l|grep -E "(blas|lapack)"
!ii libblas3gf 1.2.20110419-2ubuntu1 Basic Linear Algebra Reference
implementations, shared library
!ii liblapack-dev 3.3.1-1 library of linear algebra routines
3 - static version
!ii liblapack-doc 3.3.1-1 library of linear algebra routines
3 - documentation
!ii liblapack3gf 3.3.1-1 library of linear algebra routines
3 - shared version
!ii libopenblas-base 0.1alpha2.2-3 Optimized BLAS (linear algebra)
library based on GotoBLAS2
!ii libopenblas-dev 0.1alpha2.2-3 Optimized BLAS (linear algebra)
library based on GotoBLAS2
!>

Ada
 
-- Ada implementation
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.integer_Text_Io; use Ada.integer_Text_Io;
196
2.45. Generate the adjugate matrix for . . . CHAPTER 2. LINEAR ALGEBRA, . . .

with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;


procedure t44 is
A : constant real_matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
--(( -3.0, 2.0, -5.0),
-- ( -1.0, 0.0, -2.0),
-- ( 3.0, -4.0, 1.0));
C : real_matrix(A'range(1), A'range(2));
B : real_matrix(1 .. 2, 1 .. 2);
-- Thanks goes to Dmitry A. Kazakov this function
function Exclude (A : Real_Matrix; I, J : Integer)
return Real_Matrix is
AI, AJ : Integer := A'First (1);
begin
return B : Real_Matrix (1..A'Length (1)-1, 1..A'Length (2)-1) do
AI := A'First (1);
for BI in B'Range (1) loop
if AI = I then
AI := AI + 1;
end if;
AJ := A'First (2);
for BJ in B'Range (2) loop
if AJ = J then
AJ := AJ + 1;
end if;
B (BI, BJ) := A (AI, AJ);
AJ := AJ + 1;
end loop;
AI := AI + 1;
end loop;
end return;
end Exclude;
-- Function to print a 2D matrix
procedure Put (X : Real_Matrix) is
begin
for I in X'Range (1) loop
for J in X'Range (2) loop
Put (X (I, J) ); put(" ");
end loop;
New_Line;
end loop;
end Put;
begin
FOR I in A'range(1) LOOP
FOR J in A'range(2) LOOP

197
2.45. Generate the adjugate matrix for . . . CHAPTER 2. LINEAR ALGEBRA, . . .

B := Exclude (A, I, J);


C(I,J) := float((-1)**( ((I+J) rem 2) ))*determinant(B);
END LOOP;
END LOOP;
c := transpose(c);
put(c);
end t44;
 

compile and run


-- export LD_LIBRARY_PATH=/usr/lib/atlas-base/:/usr/lib/atlas-base/atlas/
>gnatmake t44.adb
gcc-4.6 -c t44.adb
gnatbind -x t44.ali
gnatlink t44.ali

>./t44
-3.00000E+00 6.00000E+00 -3.00000E+00
6.00000E+00 -1.20000E+01 6.00000E+00
-3.00000E+00 6.00000E+00 -3.00000E+00

198
2.46. Multiply each column by values . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.46 Multiply each column by values taken from a row


Given a row of the same number of values as the number of columns in a matrix, how to
scale each column by the corresponding value in that row? This picture explains more the
problem
Multiply this value
by this column

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

Multiply this value


by this column

In Matlab, bsxfun is used.

2.46.1 Mathematica
credit for this solution goes to Bob Hanlon, Adriano Pascoletti, Kurt Tekolste, David Park,
and Peter. J. C. Moses from the Math group
r = {2,3};
mat = {{1,2},{3,4},{5,6}};
r #&/@mat

(*or*)
Map[v*#&, mat]

{{2, 6},
{6, 12},
{10, 18}}
Another way is to use Inner[] command. Credit for this solution goes to Sswziwa Mukasa
and Peter. J. C. Moses from the Math group
r={2,3};
mat={{1,2},{3,4},{5,6}};
Inner[Times,mat,r,List]

Out[66]= {{2, 6},

199
2.46. Multiply each column by values . . . CHAPTER 2. LINEAR ALGEBRA, . . .

{6, 12},
{10, 18}}

2.46.2 Matlab
r=[2 3];
A=[1 2;
3 4;
5 6]
bsxfun(@times,r,A)

ans =
2 6
6 12
10 18

2.46.3 Fortran
program t45
implicit none

integer, parameter :: nRow=3, nCol=2

character(len=*), parameter :: FMT = "(2I5)"


integer :: v(nCol),A(nRow,nCol),B(nRow,nCol),i,j;

!-- initialization of data


v = [2,3]
A(1,:) = [1,2];
A(2,:) = [3,4];
A(3,:) = [5,6];

!F2008
!do concurrent (j = 1:nCol)
! B(:,j) = v(j)*A(:,j)
!end do

do j=1,nCol
B(:,j) = v(j)*A(:,j)
end do

write(*,FMT) ( (B(i,j),j=1,nCol), i=1,nRow)

end program t45

200
2.46. Multiply each column by values . . . CHAPTER 2. LINEAR ALGEBRA, . . .

#compile and run


>gfortran -std=f2008 t45.f90
>./a.out
2 6
6 12
10 18

2.46.4 Octave
Use automatic broadcasting
r .* A

2.46.5 Maple
r:=Vector[row]([2,3]);
mat:=Matrix([[1,2],[3,4],[5,6]]);

f:=n->r(n)*mat(1..3,n);
f~([1,2]);
convert(%,Matrix)

Matrix(3, 2, [[2, 6], [6, 12], [10, 18]])

⎡ ⎤
⎢⎢ 2 6 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 6 12 ⎥⎥⎥
⎢⎢ ⎥⎥⎥
⎢⎢ ⎥⎦

10 18

201
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.47 extract submatrix from a larger matrix by


removing row/column
Given 2D matrix 𝐴 extract all submatrices by removing row/column.
⎛ ⎞
⎜⎜1 2 3⎟⎟ ⎛ ⎞
⎜⎜ ⎟⎟ ⎜⎜5 6⎟⎟
For example, given the matrix ⎜⎜⎜4 5 6⎟⎟⎟ then the submatrix for (1, 1) is⎜⎜⎝ ⎟⎟ obtained by
⎜⎝ ⎟⎠ 8 9⎠
7 8 9
removing the first row and the first column.
In Mathematica, ReplacePart can be used. In Matlab the [] operator can be used. In Fortran,
the pack() function can be used.

2.47.1 Mathematica

{{{5,6},{8,9}},
mat={{1,2,3}, {{4,6},{7,9}},
{4,5,6},
{{4,5},{7,8}},
{7,8,9}};
{{2,3},{8,9}},
{nRow, nCol} = Dimensions[mat];
Table[ReplacePart[mat,{{i},{i,_},{_,j}}
{{1,3},{7,9}},
:>Sequence[],Heads-> False], {{1,2},{7,8}},
{i,nRow},{j,nCol}]; {{2,3},{5,6}},
{{1,3},{4,6}},
r=Flatten[%,1] {{1,2},{4,5}}}

202
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.47.2 Matlab

B =
A=[1 2 3; 5 6
4 5 6; 8 9
7 8 9]
B =
4 6
for i=1:size(A,1)
for j=1:size(A,1)
7 9
B=A; B =
B(i,:)=[]; 4 5
B(:,j)=[] 7 8
end B =
end 2 3
8 9
B =
1 3
7 9
B =
1 2
7 8
B =
2 3
5 6
B =
1 3
4 6
B =
1 2
4 5

2.47.3

Fortran 
program t46
implicit none
integer, parameter:: dp=kind(0.d0), n=3
integer :: i,j,ii
real(dp) :: A(n,n) = dble(reshape([ 1.0, 2.0, 3.0, &
4.0, 5.0, 6.0, &
7.0, 8.0, 9.0], &
shape(A), &
order=[2,1]))
real(dp) :: B(n-1,n-1)
logical :: mask(n,n)

203
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

DO i=1,n
DO j=1,n
mask = .true.
mask(:,j) = .false.
mask(i,:) = .false.
!-- extract submatrix
B = reshape(pack(A, mask),[n-1,n-1])

DO ii=1,n-1
write(*,'(2F6.1)') B(ii,:)
END DO
write(*,'(/)')
END DO
END DO
end program t46
 

compile and run


>gfortran -std=f2008 -fcheck=all -Wall -Wextra -Wconversion-extra t46.f90
>./a.out
5.0 6.0
8.0 9.0

4.0 6.0
7.0 9.0

4.0 5.0
7.0 8.0

2.0 3.0
8.0 9.0

1.0 3.0
7.0 9.0

1.0 2.0
7.0 8.0

2.0 3.0
5.0 6.0

1.0 3.0
4.0 6.0

1.0 2.0
4.0 5.0
204
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.47.4

Ada 
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
procedure foo is
A : constant Real_Matrix :=
(( 1.0, 2.0, 3.0),
( 4.0, 5.0, 6.0),
( 7.0, 8.0, 9.0));
B : real_matrix(1 .. 2, 1 .. 2);
-- Thanks goes to Dmitry A. Kazakov
-- for providing this function
function Exclude (A : Real_Matrix; I, J : Integer)
return Real_Matrix is
AI, AJ : Integer := A'First (1);
begin
return B : Real_Matrix(1..A'Length(1)-1,1..A'Length(2)-1) do
AI := A'First (1);
for BI in B'Range (1) loop
if AI = I then
AI := AI + 1;
end if;
AJ := A'First (2);
for BJ in B'Range (2) loop
if AJ = J then
AJ := AJ + 1;
end if;
B (BI, BJ) := A (AI, AJ);
AJ := AJ + 1;
end loop;
AI := AI + 1;
end loop;
end return;
end Exclude;

-- Function to print a 2D matrix


procedure put(A: Real_Matrix) is
begin
for I in A'range(1) loop
for J in A'range(2) loop
put(A(I,J));
end loop;
new_line;
end loop;
end put;

begin

205
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

FOR I in A'range(1) LOOP


FOR J in A'range(2) LOOP
B := Exclude (A, I, J);
put(B);
new_line(1);
END LOOP;
END LOOP;
end foo;
 

compile and run


>gnatmake foo.adb
gcc-4.6 -c foo.adb
gnatbind -x foo.ali
gnatlink foo.ali
>./foo
>./foo
5.00000E+00 6.00000E+00
8.00000E+00 9.00000E+00

4.00000E+00 6.00000E+00
7.00000E+00 9.00000E+00

4.00000E+00 5.00000E+00
7.00000E+00 8.00000E+00

2.00000E+00 3.00000E+00
8.00000E+00 9.00000E+00

1.00000E+00 3.00000E+00
7.00000E+00 9.00000E+00

1.00000E+00 2.00000E+00
7.00000E+00 8.00000E+00

2.00000E+00 3.00000E+00
5.00000E+00 6.00000E+00

1.00000E+00 3.00000E+00
4.00000E+00 6.00000E+00

1.00000E+00 2.00000E+00
4.00000E+00 5.00000E+00

206
2.47. extract submatrix from a larger . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.47.5 Maple
del:=proc(A::Matrix,idx::list)::Matrix;
local B;
B:=LinearAlgebra:-DeleteRow(A,idx[1]);
B:=LinearAlgebra:-DeleteColumn(B,idx[2]);
return B;
end proc;

A:=Matrix([[1,2,3],[4,5,6],[7,8,9]]):
r:=map2(del,A,[indices(A,indexorder)]);

⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤
⎢⎢ 5 6 ⎥⎥ ⎢⎢ 4 6 ⎥⎥ ⎢⎢ 4 5 ⎥⎥ ⎢⎢ 2 3 ⎥⎥ ⎢⎢ 1 3 ⎥⎥ ⎢⎢ 1 2 ⎥⎥ ⎢⎢ 2 3 ⎥⎥ ⎢⎢ 1 3 ⎥⎥ ⎢⎢ 1 2 ⎥⎥
[⎢⎢⎢ ⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥ , ⎢⎢
⎥⎦ ⎢⎣
⎥⎥]
⎥⎦

8 9 7 9 7 8 8 9 7 9 7 8 5 6 4 6 4 5

207
2.48. delete one row from a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.48 delete one row from a matrix


Example, Given the folowing 2D matrix 𝐴 delete the second row
⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜⎜ ⎟⎟
⎜⎜4 5 6⎟⎟⎟
⎜⎝ ⎟⎠
7 8 9

2.48.1 Mathematica

Out[81]= {{1,2,3},
mat={{1,2,3}, {7,8,9}}
{4,5,6},
{7,8,9}};

mat[[2]]=Sequence[];
mat

or a little longer solution using Pick


Out[70]= {{1,2,3},
{nRow,nCol}=Dimensions[mat]; {7,8,9}}
mask=Table[True,{nRow},{nCol}];
mask[[2]]=False;
Pick[mat,mask]

2.48.2 Matlab

A =
A=[1 2 3;4 5 6;7 8 9]; 1 2 3
A(2,:)=[] 7 8 9

208
2.48. delete one row from a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.48.3 Maple

[1 2 3]
A:=<1,2,3; A := [ ]
4,5,6; [7 8 9]
7,8,9>;
A:=LinearAlgebra:-DeleteRow(A,2);

209
2.49. delete one column from a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.49 delete one column from a matrix


Example, Given the folowing 2D matrix 𝐴 delete say the second column
⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜⎜ ⎟⎟
⎜⎜4 5 6⎟⎟⎟
⎜⎝ ⎟⎠
7 8 9

2.49.1 Mathematica

Out[93]= {{1,3},
mat={{1,2,3}, {4,6},
{4,5,6}, {7,9}}
{7,8,9}};

mat[[All,2]]=Sequence[];
mat

or a little longer solution using Pick


Out[98]= {{1,3},
{nRow,nCol}=Dimensions[mat]; {4,6},
mask=Table[True,{nRow},{nCol}]; {7,9}}
mask[[All,2]]=False;
mat=Pick[mat,mask];
mat

2.49.2 Matlab

A =
A=[1 2 3;4 5 6;7 8 9]; 1 3
A(:,2)=[] 4 6
7 9

210
2.49. delete one column from a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.49.3 Maple

⎡ ⎤
A:=Matrix([[1,2,3],[4,5,6],[7,8,9]]); ⎢⎢ 1 3 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
A:=LinearAlgebra:-DeleteColumn(A,2); ⎢⎢ 4 6 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎣ ⎦
7 9

211
2.50. generate random matrix so that each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.50 generate random matrix so that each row adds to 1


Generate the random matrix and divide each row by its total

2.50.1 Mathematica

⎛ ⎞
mat = Table[RandomReal[],{3},{4}] ⎜⎜ 0.76862 0.917299 0.606119 0.63735 ⎟⎟
⎜⎜ ⎟
⎜⎜ 0.610077 0.208307 0.0337861 0.473017 ⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
0.388772 0.432688 0.475881 0.68523

s = Total[mat,{2}]
{1.15201, 1.99068, 3.05063}

⎛ ⎞
s = Total[mat,{2}]; ⎜⎜ 0.15919 0.0553157 0.448352 0.337142 ⎟⎟
b = mat/s ⎜⎜ ⎟⎟
⎜⎜ 0.358594 0.264968 0.123659 0.25278 ⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
0.216269 0.248665 0.278871 0.256195

Total[b,{2}] Out[24]= {1.,1.,1.}

2.50.2 Matlab

A =
0.6787 0.3922 0.7060 0.0462
0.7577 0.6555 0.0318 0.0971
0.7431 0.1712 0.2769 0.8235

A = rand(3,4) B =
s = sum(A,2); 0.3723 0.2151 0.3873 0.0253
B = bsxfun(@rdivide,A,s) 0.4913 0.4250 0.0206 0.0630
sum(B,2) 0.3689 0.0850 0.1375 0.4087

ans =
1.0000
1.0000
1.0000

212
2.51. generate random matrix so that each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.51 generate random matrix so that each column adds


to 1
Generate the random matrix and divide each column by its total

2.51.1 Mathematica
Out[31]= {{0.440393,0.945076,0.0527301,0.537288},
{0.515868,0.565691,0.800959,0.0302484},
This method due to Bob Hanlon from the {0.509004,0.143124,0.519455,0.264779}}
Math group Out[32]= {1.46526,1.65389,1.37314,0.832315}
mat = Table[RandomReal[],{3},{4}]
s = Total[mat,{1}]
b = #/s& /@ mat Out[36]= {{0.300555,0.571426,0.038401,0.645535},
Total[b,{1}] {0.352065,0.342036,0.583303,0.0363425},
{0.34738,0.0865376,0.378296,0.318123}}

Out[37]= {1.,1.,1.,1.}

Or can use Transpose


b = Transpose[Transpose[mat]/s]; {1.,1.,1.,1.}
Total[b,{1}]

Another way of doing the above, without


the need to transpose 2 times is the follow-
ing {1.,1.,1.,1.}
b=Inner[Divide,mat,s,List];
Total[b,{1}]

213
2.51. generate random matrix so that each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.51.2 Matlab

A =
0.6948 0.0344 0.7655 0.4898
0.3171 0.4387 0.7952 0.4456
0.9502 0.3816 0.1869 0.6463
A=rand(3,4)
s=sum(A,1); B =
B=bsxfun(@rdivide,A,s) 0.3541 0.0403 0.4380 0.3097
sum(B,1) 0.1616 0.5133 0.4550 0.2817
0.4843 0.4464 0.1069 0.4086

ans =
1.0000 1.0000 1.0000 1.0000

2.51.3 Maple
A:=LinearAlgebra:-RandomMatrix(3,4);

[ 9 -95 51 24]
[ ]
A := [99 -20 76 65]
[ ]
[60 -25 -44 86]

b:=MTM:-sum(A,1); #sum columns

b := [168, -140, 83, 175]


nCol:=LinearAlgebra:-ColumnDimension(A):
B:=convert([seq(A[..,i]/b[i],i=1..nCol)],Matrix);

[3 19 51 24 ]
[-- -- -- ---]
[56 28 83 175]
[ ]
[33 1 76 13]
B := [-- - -- --]
[56 7 83 35]
[ ]
[5 5 -44 86 ]
[-- -- --- ---]
[14 28 83 175]

214
2.51. generate random matrix so that each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

MTM:-sum(B,1);

[1, 1, 1, 1]

215
2.52. sum all rows in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.52 sum all rows in a matrix


Given the folowing 2D matrix 𝐴 find the sum of each row

⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜ ⎟
⎜⎜4 5 6⎟⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
7 8 9

2.52.1 Mathematica

mat={{1,2,3},
Out[2]= {6,
{4,5,6},
15,
{7,8,9}}
24}
Total[mat,{2}]

2.52.2 Matlab
ans =
A=[1 2 3;4 5 6;7 8 9]; 6
sum(A,2) 15
24

216
2.53. sum all columns in a matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.53 sum all columns in a matrix


Given the folowing 2D matrix 𝐴 find the sum of each column
⎛ ⎞
⎜⎜1 2 3⎟⎟
⎜⎜⎜ ⎟⎟
⎜⎜4 5 6⎟⎟⎟
⎜⎝ ⎟⎠
7 8 9

Mathematica Matlab

In[3]:= mat={{1,2,3}, A=[1 2 3;4 5 6;7 8 9];


{4,5,6}, sum(A,1)
{7,8,9}}
Total[mat,{1}] ans =
12 15 18
Out[4]= {12,15,18}

217
2.54. find in which columns values that . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.54 find in which columns values that are not zero


⎛ ⎞
⎜⎜ 0 39 0 ⎟⎟
⎜⎜⎜ ⎟⎟
⎜⎜55 100 0 ⎟⎟⎟
⎜⎜ ⎟⎟
given matrix ⎜⎜⎜34 0 0 ⎟⎟⎟ find the column index which contain values > 0 but do it from
⎜⎜ ⎟⎟
⎜⎜ 0 9 0 ⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
0 0 50
⎛1𝑠𝑡 row 2𝑛𝑑 row ⎞
⎜⎜ ⎟
top row to the bottom row. Hence the result should be ⎜⎝ ⏞ 2 , 1, ⏞2 ,⏞ 1,⏞ 3⎟⎟⎠ this is becuase
2,⏞
on the first row, nonzero is in second column, and on the second row, nonzero is at first
and third column, and on the third row, nonzero is at the first column, and so on.
Mathematica

mat={{0, 39, 0},


{55,100, 0},
{34,0, 0}, Out[18]= {2,1,2,1,2,3}
{0, 9, 0},
{0, 0, 50}};
Position[#,x_/;x>0]&/@mat;
Flatten[%]

Matlab

A=[0 39 0
55 100 0
34 0 0 2 1 2 1 2 3
0 9 0
0 0 50];
[I,~]=find(A'>0)
I'

218
2.54. find in which columns values that . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Maple

A:=Matrix([[0,39,0],
[55,100,0],
[34,0,0], [2,1,2,1,2,3]
[0,9,0],
[0,0,50]]):
f:=x->`if`(not evalb(A(x[1],x[2])=0),x[2],NULL):
f~([indices(A,indexorder)])

219
2.55. How to remove values from one . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.55 How to remove values from one vector that exist in


another vector
Given vector 𝑣1 = {1, 3, 4, 5, 8, 9, 20.2, 30, −44} remove from it any element that exist in 𝑣2 =
{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.

2.55.1 Mathematica

#first method
v1={1,3,4,5,8,9,20.2,30,-44};
v2={1,7,4}; {3,5,8,9,20.2,30,-44}
v1=DeleteCases[v1,Alternatives@@v2]

#second method
v1={1,3,4,5,8,9,20.2,30,-44};
v2={1,7,4}; {3,5,8,9,20.2,30,-44}
v1=DeleteCases[v1,x_/;MemberQ[v2,x]]

2.55.2 Matlab

v1=[1,3,4,5,8,9,20.2,30,-44];
v2=[1,7,4]; v1 =
3.0000 5.0000 8.0000 9.0000 20.2000 30.0000 -44.0000
v1(ismember(v1,v2))=[]

2.55.3 Fortran
program f
implicit none
REAL, ALLOCATABLE :: A(:),B(:)
A =[1.0,3.0,4.0,5.0,8.0,9.0,20.2,30.0,-44.0];
B =[1.0,7.0,4.0];
A = pack(A, A .NE. B)
Print *,A
end program f

220
2.55. How to remove values from one . . . CHAPTER 2. LINEAR ALGEBRA, . . .

>gfortran f2.f90
>./a.out
3.0000000 5.0000000 8.0000000 9.0000000 20.200001 30.000000 -44.000000

2.55.4 Maple

v1:=Array([1,3,4,5,8,9,20.2,30,-44]);
v2:=Array([1,7,4]); [3, 5, 8, 9, 20.2, 30, -44]
select[flatten](x->not(member(x,v2)),v1)

221
2.56. How to find mean of equal sized . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.56 How to find mean of equal sized segments of a


vector
Given vector 𝑉 of length 𝑚 find the mean of segments 𝑉(1 ∶ 𝑛), 𝑉(𝑛 + 1 ∶ 2𝑛), 𝑉(2𝑛 + 1 ∶ 3𝑛)...In
otherwords, equall length segments

Mathematica {0.750653,0.410073,0.401005,
0.138907,0.466247,0.568257,
len = 52; n = 4; 0.535362,0.517755,0.555368,
v = RandomReal[{0, 1}, len]; 0.705857,0.502319,0.453571,0.357949}
Mean /@ Partition[v, n]

ans =
0.3026
0.3589
0.4745
Matlab 0.6249
0.3042
N = 52; 0.5428
n = 4; 0.2387
V = rand(N,1); 0.3200
mean(reshape(V,n,N/n))' 0.6224
0.4408
0.5657
0.5469
0.5696

222
2.57. find first value in column larger than . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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

a = {{1, 5}, {2, 3}, {4, 8}, {7, 2}};


Min@Position[a, {x_, y_} /; y > 6] {{1, 5}, {2, 3}}
(* 3 *)

a[[1 ;; % - 1]]

Matlab
ans =
A = [1,5;2,3;4,8;7,2]; 1 5
A(1:find(A(:,2)>6)-1,:) 2 3

223
2.58. make copies of each value into . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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.

Mathematica

mat = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};


kernel = {{1, 1}, {1, 1}}; {{1, 1, 2, 2, 3, 3},
KroneckerProduct[mat, kernel] {1, 1, 2, 2, 3, 3},
{4, 4, 5, 5, 6, 6},
Another method that can be used in this, but I prefer the {4, 4, 5, 5, 6, 6},
kron method above: {7, 7, 8, 8, 9, 9},
{7, 7, 8, 8, 9, 9}}
mat = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
Map[ConstantArray[#, {2, 2}] &, mat, {2}]
ArrayFlatten[%, 2]

Matlab 1 1 2 2 3 3
1 1 2 2 3 3
A=[1 2 3; 4 5 6; 7 8 9] 4 4 5 5 6 6
kernel=ones(2,2) 4 4 5 5 6 6
7 7 8 8 9 9
kron(A,kernel)
7 7 8 8 9 9

224
2.59. repeat each column of matrix . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.59 repeat each column of matrix number of times


Gives a matrix, repeate each column a number of time, say 3 times, in place to produce a
matrix 3 times as wide as the original.
kron() in Matlab and KroneckerProduct in Mathematica can be used for this.
Mathematica

mat = {{1, 2, 3, 4},


{5 , 6, 7, 8}, {{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4,
{9, 10, 11, 12}} 4},
{5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
KroneckerProduct[mat, {1, 1, 1}] 8},
{9, 9, 9, 10, 10, 10, 11, 11, 11,
Another method that can be used in this, but
12, 12, 12}}
the above is better
r = Map[#*{1, 1, 1} &, mat, {2}]
Partition[Flatten[r], 12]

Matlab ans =
1 1 1 2 2 2 3 3 3 4 4
A=[1 2 3 4; 4
5 6 7 8; 5 5 5 6 6 6 7 7 7 8 8
9 10 11 12]; 8
kernel=ones(1,3); 9 9 9 10 10 10 11 11 11 12 12
kron(A,kernel) 12

225
2.60. How to apply a function to each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.60 How to apply a function to each value in a matrix?


Apply function 𝑓(𝑥, 𝑛) to ragged matrix where 𝑛 is value taken from the matrix and 𝑥 is
some other value defined somewhere else. The result of the function should replace the
same position in the matrix where 𝑛 was.
For example, given matrix
⎛ ⎞
⎜⎜ 1 2 3 ⎟⎟
⎜⎜ ⎟⎟
𝑚𝑎𝑡 = ⎜⎜⎜ 4 5 ⎟⎟
⎟⎟
⎜⎝ ⎠
7 8 9

generate the matrix

⎛ ⎞
⎜⎜ 𝑓[𝑥, 1] 𝑓[𝑥, 2] 𝑓[𝑥, 3] ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 𝑓[𝑥, 4] 𝑓[𝑥, 5] ⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
𝑓[𝑥, 7] 𝑓[𝑥, 8] 𝑓[𝑥, 9]

Mathematica

The trick is to use Map with 2 at end. Matlab


Map[f[x, #] &, mat, {2}] to do

226
2.61. How to sum all numbers in a list . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.61 How to sum all numbers in a list (vector)?


Given a vector or list 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 how to find the sum of all its elements?
Mathematica
{1,2,3,4,5,6,7,8,9,10}
list=Range[10]

Total[list]
55

Matlab

lst=1:10 55
sum(lst)

Maple
1,2,3,4,5,6,7,8,9,10
lst:=seq( i, i=1..10 );

convert([lst], `+`);
55

227
2.62. How to find maximum of each row . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.62 How to find maximum of each row of a matrix?


Given ⎛ ⎞
⎜⎜ 1 2 ⎟⎟
⎜⎜ ⎟⎟
⎝ 3 4 ⎠

Find the maximum of each row. The result should be (2, 4). (to find the min, just change
Max with Min below.
Mathematica

mat = {{1, 2}, {3, 4}} {2,4}


Map[Max , mat] (* or Max /@ mat *)

Matlab

A=[1 2;3 4]; 2 4


max(A')

228
2.63. How to find maximum of each . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.63 How to find maximum of each column of a matrix?


Given ⎛ ⎞
⎜⎜ 1 2 ⎟⎟
⎜⎜ ⎟⎟
⎝ 3 4 ⎠

Find the maximum of each column. The result should be (3, 4). (to find the min, just change
Max with Min below.
Mathematica

mat = {{1, 2}, {3, 4}}


Map[Max , Transpose[mat]] {3, 4}

(* or Max /@ Transpose@mat *)

Matlab

A=[1 2;3 4]; 3 4


max(A)

229
2.64. How to add the mean of each column . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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

mat = {{1, 2}, {3, 4}} {{3, 5}, {5, 7}}


MapThread[Plus,{Transpose@mat, Mean[mat]}]

Matlab
ans =
A=[1 2;3 4]; 3 5
bsxfun(@plus, A, mean(A)) 5 7

230
2.65. How to add the mean of each row of . . . CHAPTER 2. LINEAR ALGEBRA, . . .

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 ⎠

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
{{2.5, 3.5}, {6.5,
mat = {{1, 2}, {3, 4}}; 7.5}}
MapThread[Plus,{mat, Mean@Transpose@mat}] // N

Matlab
ans =
A=[1 2;3 4]; 2.5 6.5
bsxfun(@plus, A', mean(A')) 3.5 7.5

231
2.66. Find the different norms of a vector CHAPTER 2. LINEAR ALGEBRA, . . .

2.66 Find the different norms of a vector


Problem: Given the vector say
𝑣 = 1, 2, 4

Find its norm for 𝑝 = 1, 2, ∞


Mathematica

Remove["Global`*"];
{7,Sqrt[21],4}
v = {{1}, {2}, {4}};
p = {1, 2, Infinity};
Map[Norm[v,#]&,p]

Matlab

clear all; close all; ans =


v=[1 2 4]; 7.0000 4.5826
p=[1,2,inf]; 4.0000
arrayfun(@(i) norm(v,p(i)),1:length(p))

232
2.67. Check if a matrix is Hermite CHAPTER 2. LINEAR ALGEBRA, . . .

2.67 Check if a matrix is Hermite


Problem: Given a matrix A, check to see if it is Hermite.
A Matrix is Hermite if it is the same as the conjugate of its transpose. One way to check is
to take the difference and check that all values in the resulting difference matrix are zero.
To account for numerical values, the check is done using machine epsilon.

Mathematica

mat = {{-1,1-3*I,0},
{1+3*I,0,-6*I},
{0,6*I,1}};
Out[32]= {{True,True,True},
mat2=Conjugate[Transpose[mat]]; {True,True,True},
(diff=mat-mat2)//MatrixForm {True,True,True}}

Now check that each element in the difference matrix


is less than MachineEpsilon
Map[Abs[#]<$MachineEpsilon&,diff,{2}]

Count[%,False] Out[33]= 0

233
2.67. Check if a matrix is Hermite CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

clear all;
i=sqrt(-1); diff =
mat=[-1 1-3*i 0; 0 0 0
1+3*i 0 -6*i; 0 0 0
0 6*i 1]; 0 0 0

mat2=conj(transpose(mat));
diff = mat-mat2

r =
1 1 1
r=abs(diff)<eps('double')
1 1 1
1 1 1

all(r(:))
1

234
2.68. Obtain the LU decomposition of a . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.68 Obtain the LU decomposition of a matrix


Problem: Given a matrix 𝐴, find matrix 𝐿 and 𝑈 such that 𝐿𝑈 = 𝐴. The matrix 𝐿 will have
1 in all the diagonal elements and zeros in the upper triangle. The matrix 𝑈 will have 0 in
the lower triangle as shown in this diagram.

1 0 0

= 1 0 * 0
1 0 0

A L U
Mathematica

Remove["Global`*"]
mat = {{1, -3, 5}, {{{1,-3,5},
{2, -4, 7}, {2,2,-3},
{-1, -2, 1}}; {-1,-(5/2),-(3/2)}},
{1,2,3},1}
{lu,pivotVector,conditionNumber}=
LUDecomposition[mat]

{{1,0,0},
lower=lu*SparseArray[{i_,j_}/;j<i->1,{3,3}]+
{2,1,0},
IdentityMatrix[3]
{-1,-(5/2),1}}

{{1,-3,5},
upper=lu SparseArray[{i_,j_}/;j>=i->1,{3,3}] {0,2,-3},
{0,0,-(3/2)}}

{{1,-3,5},
lower.upper {2,-4,7},
{-1,-2,1}}

235
2.68. Obtain the LU decomposition of a . . . CHAPTER 2. LINEAR ALGEBRA, . . .

L =
1.0000 0 0
Matlab
-0.5000 1.0000 0
0.5000 0.2500 1.0000
clear all;
U =
A=[1 -3 5; 2.0000 -4.0000 7.0000
2 -4 7; 0 -4.0000 4.5000
-1 -2 1]; 0 0 0.3750
p =
[L,U,p]=lu(A) 0 1 0
0 0 1
1 0 0

ans =
2 -4 7
L*U
-1 -2 1
1 -3 5

236
2.69. Linear convolution of 2 sequences CHAPTER 2. LINEAR ALGEBRA, . . .

2.69 Linear convolution of 2 sequences


Problem: Given 2 sequences 𝑥1 [𝑛] and 𝑥2 [𝑚], determine the linear convolution of the 2
sequences. Assume 𝑥1 = [1, 2, 3, 4, 5] and 𝑥2 = [3, 4, 5].

Mathematica

Clear ["Global`*"]
x1 = {1, 2, 3, 4, 5}; {4, 13, 28, 43, 58, 49, 30}
x2 = {4, 5, 6};
ListConvolve[x2, x1, {1, -1}, 0]

Matlab

clear all; close all;


x1=[1 2 3 4 5]; 4 13 28 43 58 49 30
x2=[4 5 6];
conv(x2,x1)

237
2.70. Circular convolution of two sequences CHAPTER 2. LINEAR ALGEBRA, . . .

2.70 Circular convolution of two sequences


Problem: Given 2 sequences 𝑥1 [𝑛] and 𝑥2 [𝑚], determine the circular convolution of the 2
sequences.

2.70.1 example 1. The sequences are of equal length


Mathematica

x1 = {2, 1, 2, 1};
{14., 16., 14.,
x2 = {1, 2, 3, 4};
X1 = Chop[Fourier[x1, FourierParameters -> {1, -1} ]]; 16.}
X2 = Chop[Fourier[x2, FourierParameters -> {1, -1}]];
Re[InverseFourier[X1*X2, FourierParameters -> {1, -1}]]

Matlab

clear all; close all;


x1=[2 1 2 1]; y =
x2=[1 2 3 4]; 14 16 14 16
X1=fft(x1);
X2=fft(x2);
y=real(ifft(X1.*X2))

2.70.2 example 2. The sequences are of unequal length


Mathematica

Clear["Global`*"]
x1 = {1, 2, 3, 4, 5};
{53., 43., 28., 43.,
x2 = {4, 5, 6};
x2 = Append[x2, {0, 0}] // Flatten; 58.}
X1 = Chop[Fourier[x1, FourierParameters -> {1, -1} ]];
X2 = Chop[Fourier[x2, FourierParameters -> {1, -1}]];
Re[InverseFourier[X1*X2, FourierParameters -> {1, -1}]]

238
2.70. Circular convolution of two sequences CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

x1=[1 2 3 4 5];
x2=[4 5 6]; y =
N=max(length(x1),length(x2)); 53 43 28 43 58
X1=fft(x1,N);
X2=fft(x2,N);
y=real(ifft(X1.*X2))

239
2.71. Linear convolution of 2 sequences . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.71 Linear convolution of 2 sequences with origin at


arbitrary position
For simple case where the 2 sequences are assumed to start at n=0, then this can be done in
the time domain using the ListConvolve in Mathematica and using conv in Matlab.
The harder case is when the origin is not located at the first element in the sequence. I.e.
one or both of the sequences is not causal.
Mathematica
case 1
Convolve 2 sequences where the origin is assumed to be at the first element in each sequence.
x1={1,2,3,4,5};
x2={4,5,6};
ListConvolve[x2,x1,{1,-1},0]

{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.
(*Write down the h and take its DTFT *)
Clear[n,w]
h = 1/4DiscreteDelta[n+1] +
1/2DiscreteDelta[n]+1/4 DiscreteDelta[n-1];
hTransformed = FourierSequenceTransform[h,n,w]

1 −𝑖𝑤 2
𝑒 �1 + 𝑒𝑖𝑤 �
4

Write down the x sequence and take its DTFT


x = 1 DiscreteDelta[n]+2 DiscreteDelta[n-1]-
2 DiscreteDelta[n-2]+DiscreteDelta[n-3]+
4 DiscreteDelta[n-4]-DiscreteDelta[n-5]+
DiscreteDelta[n-6]+2 DiscreteDelta[n-7];

xTransformed = FourierSequenceTransform[x,n,w]

𝑒−7𝑖𝑤 �𝑒𝑖𝑤 − 𝑒2𝑖𝑤 + 4𝑒3𝑖𝑤 + 𝑒4𝑖𝑤 − 2𝑒5𝑖𝑤 + 2𝑒6𝑖𝑤 + 𝑒7𝑖𝑤 + 2�


240
2.71. Linear convolution of 2 sequences . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Now multiply the DTFT’s and take the inverse


z = InverseFourierSequenceTransform[
xTransformed hTransformed,w,n]

- 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
N@InverseFourierSequenceTransform[
xTransformed hTransformed hTransformed,w,n]

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

241
2.72. Visualize a 2D matrix CHAPTER 2. LINEAR ALGEBRA, . . .

2.72 Visualize a 2D matrix


Problem: Given a 2 dimensional matrix, say 𝑚 × 𝑛 , how to visualize its content?
These are some examples showing how to visualize a matrix as a 3D data, where the height
is taken as the values of the matrix entries, and the 𝑥, 𝑦 indices as the coordinates.
Mathematica
mat = Table[Table[RandomReal[{0,100}],
{20}],{10}];
ListPointPlot3D[mat,Filling->Axis
,ImageSize->300]

mat = HilbertMatrix[{20,10}];
ListPlot3D[mat,Mesh->None,InterpolationOrder->0,
ColorFunction->"SouthwestColors",
Filling->Axis,ImageSize->300]

242
2.72. Visualize a 2D matrix CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab
clear all; close all;

A = (100).*rand(20,20);
[X,Y] = meshgrid(1:20,1:20);

surfl(X,Y,A);
shading interp
colormap(gray);

figure;
A = hilb(20);
[X,Y] = meshgrid(1:20,1:20);
surfl(X,Y,A);

Maple
restart;
A := abs(LinearAlgebra[RandomMatrix](20,10,generator=0..100)):

243
2.72. Visualize a 2D matrix CHAPTER 2. LINEAR ALGEBRA, . . .

plots[matrixplot](A,heights=histogram);

A := LinearAlgebra[HilbertMatrix](20,10):
A := convert(A,listlist):
plots[listplot3d](A);

244
2.73. Find the cross correlation between . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.73 Find the cross correlation between two sequences


Problem: Given

𝐴 = [0, 0, 2, −1, 3, 7, 1, 2, −3, 0, 0]


𝐵 = [0, 0, 1, −1, 2, −2, 4, 1, −2, 5, 0, 0]

Notice that the output sequence generated by Mathematica and Matlab are reversed with
respect to each others.
Also, MATLAB uses the length 2𝑁 − 1 as the length of cross correlation sequence, which in
this example is 23 because 𝑁 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 2𝑁.

245
2.73. Find the cross correlation between . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Mathematica Matlab

Clear["Global`*"]; In MATLAB use the xcross in the signal


processing toolbox
a={0,0,2,-1,3,7,1,2,-3,0,0}; clear all; close all;
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];
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
Out[31]= {0, C'
0,
0, ans =
0,
10, 0.000000000000003
-9, 0.000000000000002
19, -0.000000000000002
36, 0
-14, 9.999999999999998
33, -9.000000000000002
0, 19.000000000000000
7, 36.000000000000000
13, -14.000000000000000
-18, 33.000000000000000
16, -0.000000000000002
-7, 6.999999999999998
5, 13.000000000000000
-3, -18.000000000000000
0, 16.000000000000004
0, -7.000000000000000
0, 4.999999999999999
0} -2.999999999999998
-0.000000000000000
0.000000000000001
0.000000000000002
-0.000000000000004
0

Maple

a:=Array([0,0,2,-1,3,7,1,2,-3,0,0]);
b:=Array([0,0,1,-1,2,-2,4,1,-2,5,0,0]);
SignalProcessing:-CrossCorrelation(a,b);

246
2.73. Find the cross correlation between . . . CHAPTER 2. LINEAR ALGEBRA, . . .

[7.0, 0.0, 33.0, −14.0, 36.0, 19.0, −9.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Not able to find out now why Maple result is different. May be definition used is different,
no time now to find out.

247
2.74. Find orthonormal vectors that span . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.74 Find orthonormal vectors that span the range of


matrix A
Problem: Given the matrix 𝐴 whose columns represents some vectors, find the set of or-
thonormal vectors that span the same space as 𝐴 and verify the result. Let
⎡ ⎤
⎢⎢0 1 1 2⎥⎥
⎢⎢ ⎥⎥
𝐴 = ⎢⎢⎢1 2 3 4⎥⎥⎥
⎢⎣ ⎥⎦
2 0 2 0

Notice that 𝐴 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}=SingularVal-
ueDecomposition[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

Remove["Global`*"];
mat = {{0, 1, 1, 2},
{1, 2, 3, 4}, 2
{2, 0, 2, 0}};
r = MatrixRank[mat]

{{0.378151, -0.308379},
{u,s,v}=SingularValueDecomposition[mat];
{0.887675, -0.146825},
orth=N[u[[All,{1,r}]]]
{0.262747, 0.939864}}

{{1.,0},
Chop[Transpose[orth].orth]
{0,1.}}

248
2.74. Find orthonormal vectors that span . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Matlab

clear all; R =
A=[0 1 1 2 -0.3782 0.3084
1 2 3 4 -0.8877 0.1468
-0.2627 -0.9399
2 0 2 0];
R=orth(A)

1.0000 0.0000
R'*R
0.0000 1.0000

249
2.75. Solve 𝐴𝑥 = 𝑏 and display the solution CHAPTER 2. LINEAR ALGEBRA, . . .

2.75 Solve 𝐴𝑥 = 𝑏 and display the solution


Problem: Solve for x given that 𝐴𝑥 = 𝑏 where
⎛ ⎞
⎜⎜ 1 2 ⎟⎟
𝐴 = ⎜⎜⎝ ⎟⎟

1 3

and ⎛ ⎞
⎜⎜ 5 ⎟⎟
𝑏 = ⎜⎜⎝ ⎟⎟⎠
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 𝑥 + 2𝑦 = 5 and 𝑥 + 3𝑦 = 8.
4.0
Mathematica

3.5
Remove["Global`*"];
ContourPlot[{x+2y==5,x+3y==8},
{x,-3,2}, 3.0

{y,1.5,4},
ContourStyle->{{Red,Thickness[0.01]},
2.5
{Blue,Thickness[0.01]}},
GridLines->Automatic,
GridLinesStyle->Dashed, 2.0

ImageSize->300]
1.5
-3 -2 -1 0 1 2

mat = {{1,2},{1,3}};
b = {5,8}; {-1,3}
x = LinearSolve[mat,b]

Matlab
x =
A = [1 2;1 3]; -1
b = [5;8]; 3
x = A\b

250
2.76. Determine if a set of linear equations . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.76 Determine if a set of linear equations 𝐴𝑥 = 𝑏 has a


solution and what type of solution
Problem: Given a general non homogeneous set of linear equations 𝐴𝑥 = 𝑏 how to test if it
has no solution (inconsistent), or one unique solution, or an infinity number of solutions?
The following algorithm summarizes all the cases
Let [A|b] be the augmented matrix, where b is appended to A.

Assume A is an M by N matrix. i.e. M equations and N unknowns.

IF rank A < rank [A|b] THEN -- system is inconsistent


-- NO exact solution exist, but can use least square approximation

x= A/b -- Matlab.
x= PseudoInverse[A].b -- Mathematica uses SVD to computer pseduoInverse

ELSE -- we must have rank A == rank[A|b] -- system is consistent


IF rank(A) == N -- we have one solution.
IF M==N -- one unique solution, can use crammer rule.
x=A/b -- Matlab. Here we get exact solution from \ operator
x=LinearSolve[A,b] -- Mathematica
ELSE -- infinite solutions, pick one.
x=A/b -- Matlab. Here we get exact solution from \ operator
x=LinearSolve[A,b] -- Mathematica
END
ELSE
-- rank A < N, i.e. rank deficient, infinite solutions. will pick one
x=A/b
x=LinearSolve[A,b]
END
END

Let the system of equations be


𝑦=𝑥−1
𝑦 = 2𝑥 + 1

So ⎛ ⎞
⎜⎜ 1 1 ⎟⎟
𝐴 = ⎜⎜⎝ ⎟⎟
−2 1 ⎠
and ⎛ ⎞
⎜⎜ 1 ⎟⎟
𝑏 = ⎜⎜⎝ ⎟⎟
−1 ⎠

Mathematica
251
2.76. Determine if a set of linear equations . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Remove["Global`*"];
ContourPlot[{y==x-1,y==2 x+1} ,
{x,-3,2},{y,-6,3},
ContourStyle->{{Red,Thickness[0.01]},
{Blue,Thickness[0.01]}},
GridLinesStyle->Dashed,
ImageSize->300]

-2

-4

-6
-3 -2 -1 0 1 2

a = {{-2,1},{-1,1}};
b = {1,-1};
{nRow, nCol} = Dimensions[a];
aRank=MatrixRank[a]

2
abRank=MatrixRank[Insert[a,b,-1]]

2
The above algorithm can now be run as follows
If[aRank<abRank,
Print["System is no consistent, no exact solution"];
x=PseudoInverse[a].b,
If[aRank==nCol,
Print["System is consistent. Exact solution."];
x=LinearSolve[a,b]
,
Print["consistent, rank deficient,infinite solutions"];
x=LinearSolve[a,b]
]
];

252
2.76. Determine if a set of linear equations . . . CHAPTER 2. LINEAR ALGEBRA, . . .

Print["Solution is x=",x];

The output of the above is


System is consistent. Exact solution.
Solution is x={-2,-3}

Matlab
A=[-2 1;-1 1];
b=[1; -1];

[nRow,nCol]=size(A);
aRank=rank(A);
abRank=rank([A b]);

fprintf('A rank=%d, [A b] rank=%d\n',aRank,abRank);


fprintf('Number of unknowns=%d\n',nCol);

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
A rank=2, [A b] rank=2
Number of unknowns=2

System is consistent. Exact solution.


solution is
x =
-2
-3

253
2.77. Given a set of linear equations . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.77 Given a set of linear equations automatically


generate the matrix 𝐴 and vector 𝑏 and solve 𝐴𝑥 = 𝑏
Problem: Given
4𝑥 + 4𝑦 + 2𝑧 = 12
5𝑥 + 6𝑦 + 3𝑧 = 7
9𝑥 + 7𝑦 + 10𝑧 = 9

Automatically convert it to the form 𝐴𝑥 = 𝑏 and solve

Mathematica

Remove["Global`*"]
eqs = {4x+3y+2z==12,
5x+6y+3z ==7, ⎛ ⎞
9x+7y+10z ==9}; ⎜⎜ 4 3 2 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 5 6 3 ⎟⎟
⎜⎜ ⎟⎟
⎝ ⎠
{b,a} = CoefficientArrays[eqs,{x,y,z}]; 9 7 10

Normal[a]//MatrixForm

Normal[b]//MatrixForm
{−12, −7, −9}

LinearSolve[a,-b]//N {6.71429,-2.85714,-3.14286}

254
2.78. Convert a matrix to row echelon . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.78 Convert a matrix to row echelon form and to


reduced row echelon form
Problem: Given a matrix A, convert it to REF and RREF. Below shows how to
convert the matrix A to RREF. To convert to REF (TODO). One reason to convert Matrix
𝐴 to its row echelon form, is to find the rank of 𝐴. If matrix 𝐴 is a 4 × 4, and when converted
to its row echelon form we find that one of the rows is all zeros, then the rank of 𝐴 will be 3
and not full rank.
Mathematica
⎛ ⎞
Remove["Global`*"] ⎜⎜ 1 1 −2 1 ⎟⎟
⎜⎜ ⎟
(mat={{1, 1, -2, 1}, ⎜⎜ 3 2 4 −4 ⎟⎟⎟
⎜⎜ ⎟⎟
{3, 2, 4, -4}, ⎝ ⎠
4 3 3 −4
{4, 3, 3, -4}})//MatrixForm

⎛ ⎞
⎜⎜ 1 0 0 2 ⎟⎟
⎜⎜ ⎟
⎜⎜ 0 1 0 −3 ⎟⎟⎟
MatrixForm[RowReduce[mat]]
⎜⎜ ⎟⎟
⎝ ⎠
0 0 1 −1

Matlab

clear all; ans =


A=[1 1 -2 1 1 0 0 2
3 2 4 -4 0 1 0 -3
0 0 1 -1
4 3 3 -4];
rref(A)

Maple
⎡ ⎤
⎢⎢ 1 0 0 2 ⎥⎥
⎢⎢ ⎥⎥
A:=Matrix([ [1,1,-2,1],[3,2,4,-4],[4,3,3,-4]]) ⎢⎢ ⎥
⎢⎢ 0 1 0 −3 ⎥⎥⎥
; ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
LinearAlgebra:-ReducedRowEchelonForm(A); ⎢⎣ ⎥
0 0 1 −1 ⎦

255
2.79. Convert 2D matrix to show the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.79 Convert 2D matrix to show the location and values


Given
⎛ ⎞
⎜⎜ 41 45 49 53 ⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 42 46 50 54 ⎟⎟⎟
𝐴 = ⎜⎜⎜ ⎟⎟
⎜⎜ 43 47 51 55 ⎟⎟⎟
⎜⎜ ⎟⎠

44 48 52 56

Generate the matrix

⎛ ⎞
⎜⎜ 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
mat = {{41, 45, 49, 53}, {42, 46, 50, 54}, {43, 47, 51, 55}, {44, 48, 52, 56}};
Flatten[MapIndexed[Flatten[{{#2[[2]], #2[[1]]}, #1}] &, Transpose@mat, {2}],1]

Another way
mat = {{41, 45, 49, 53}, {42, 46, 50, 54}, {43, 47, 51, 55}, {44, 48, 52, 56}};
{nRow, nCol} = Dimensions[mat];
idx = Flatten[Table[{i, j}, {j, nCol}, {i, nRow}], 1]; (*similar to ind2sub*)
val = Extract[mat, idx];
MapThread[Flatten[{#1, #2}] &, {idx, val}] (* similar to [I;J;A(:)']' *)

256
2.79. Convert 2D matrix to show the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

But I think the simplist is to use Table


mat = {{41, 45, 49, 53}, {42, 46, 50, 54}, {43, 47, 51, 55}, {44, 48, 52, 56}};
{nRow, nCol} = Dimensions[mat];
Table[{i, j, mat[[i, j]]}, {j, nCol}, {i, nRow}];
Flatten[%, 1]

Matlab
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
X =
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

Maple
A := Matrix([[41,45,49,53],[42,46,50,54],[43,47,51,55],[44,48,52,56]]);

⎡ ⎤
⎢⎢ 41 42 43 44 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 45 46 47 48 ⎥⎥⎥

𝐴 = ⎢⎢⎢ ⎥⎥
⎥⎥
⎢⎢
⎢⎢ 49 50 51 52 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎣ ⎥
53 54 55 56 ⎦

257
2.79. Convert 2D matrix to show the . . . CHAPTER 2. LINEAR ALGEBRA, . . .

[seq(seq([i,j,A(i,j)],j=1..4),i=1..4)]:
indx:=Matrix(%);

⎡ ⎤
⎢⎢ 1 1 41 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 1 2 45 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢
⎢⎢ 1 3 49 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 1 4 53 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 2 1 42 ⎥⎥⎥⎥
⎢⎢
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 2 2 46 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 2 3 50 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢
⎢⎢ 2 4 54 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 3 1 43 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 3 2 47 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢
⎢⎢ 3 3 51 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢
⎢⎢ 3 4 55 ⎥⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎢⎢ 4 1 44 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 4 2 48 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 4 3 52 ⎥⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
⎣ 4 4 56 ⎦

258
2.80. Find rows in matrix with zeros in . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.80 Find rows in matrix with zeros in them, and then


remove the zeros
Given 𝐴 = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}}
Find rows with zero in middle, and then remove the zeros from these found.
The result should be {{1, 9}, {5, 6}, {7, 11}}
Mathematica

Many ways to do this. See this


Remove["Global`*"]
A = {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}};
Cases[A,{x_,0,y_}:>{x,y}]

{{1, 9}, {5, 6}, {7, 11}}


Maple

restart;
A := {{1, 0, 9}, {5, 0, 6}, {4, 1, 9}, {7, 0, 11}, {8, 1, 2}};

#One way is

remove~(has,select(has,A,0),0)

#Another way is

f := x->remove(has,x,0);
f~(select(has,A,0))

{{1, 9}, {5, 6}, {7, 11}}

259
2.81. How to apply a function to two lists . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.81 How to apply a function to two lists at the same


time?
Given list 𝑎 = {1, 2, 3, 4} and list 𝑏 = {5, 6, 7, 8} how to to call function 𝑓(𝑥, 𝑦) by taking 𝑥, 𝑦
from 𝑎, 𝑏 one a time so that the result gives 𝑓(1, 5), 𝑓(2, 6), 𝑓(3, 7), 𝑓(4, 8)?

Mathematica Maple

Remove["Global`*"] restart;
a = {1, 2, 3, 4}; a:=[1,2,3,4];
b = {5, 6, 7, 8}; b:=[5,6,7,8];
MapThread[f[#1, #2] &, {a, b}] f~(a,b)

{f[1, 5], f[2, 6], f[3, 7], f[4, 8]} [f(1, 5), f(2, 6), f(3, 7), f(4, 8)]

260
2.82. How to apply a function to two lists . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.82 How to apply a function to two lists are the same


time, but with change to entries?
2.82.1 example 1
Given list 𝑎 = {1, 2, 3, 4} and list 𝑏 = {5, 6, 7, 8} how to to call function 𝑓(𝑥, 𝑦) by taking
sin(𝑥), cos(𝑦) from 𝑎, 𝑏 one a time so that the result gives

𝑓(sin(1), cos(5)), 𝑓(sin(2), cos(6)), 𝑓(sin(3), cos(7)), 𝑓(sin(4), cos(8))

Mathematica

Remove["Global`*"]
a = {1, 2, 3, 4};
b = {5, 6, 7, 8};
MapThread[f[Sin[#1],Cos[#2]] &, {a, b}]

{f[Sin[1], Cos[5]], f[Sin[2], Cos[6]], f[Sin[3], Cos[7]], f[Sin[4], Cos[8]]}


Maple

restart;
a:=[1,2,3,4];
b:=[5,6,7,8];
f~(sin~(a),cos~(b))

[f(sin(1), cos(5)), f(sin(2), cos(6)), f(sin(3), cos(7)), f(sin(4), cos(8))]

2.82.2 example 2
Given list 𝑎 = {1, 2, 3, 4} and list 𝑏 = {5, 6, 7, 8} how to to call function 𝑓(2+𝑥+𝑥2 +sin(𝑥), 2+cos(𝑦))
by taking 𝑥, 𝑦 from 𝑎, 𝑏 one a time so that the result gives

{𝑓(3 + sin(1), 5 + cos(5)), 𝑓(8 + sin(2), 6 + cos(6)), 𝑓(15 + sin(3), 7 + cos(7)), 𝑓(24 + sin(4), 8 + cos(8))}

Mathematica

Remove["Global`*"]
a = {1, 2, 3, 4};
b = {5, 6, 7, 8};
MapThread[f[2*#1 + #1^2 + Sin[#1], #2 + Cos[#2]] &, {a, b}]

{f[3+Sin[1],5+Cos[5]],f[8+Sin[2],6+Cos[6]],f[15+Sin[3],7+Cos[7]],f[24+Sin[4],8+Cos[8]]}
Maple

261
2.82. How to apply a function to two lists . . . CHAPTER 2. LINEAR ALGEBRA, . . .

In Maple, since it does not have slot numbers # to use, it is better to make a function on
the fly, which does the exact same thing.
restart;
a:=[1,2,3,4];
b:=[5,6,7,8];

f~( (x->2*x+x^2+sin(x))~(a), (x->2+cos(x)) ~(b))

[f(3 + sin(1), 2 + cos(5)), f(8 + sin(2), 2 + cos(6)), f(15 + sin(3), 2 + cos(7)), f(24 + sin(4

262
2.83. How to select all primes numbers . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.83 How to select all primes numbers from a list?


Given list of numbers from 1 to 100, select the prime numbers.
Mathematica

Remove["Global`*"]
lst = Range[1, 100];
Select[lst, PrimeQ]

{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}

Maple

restart;
lst:=[seq(i,i=1..100)];
result:=select[flatten](isprime,lst);

#or. using Array instead of list


lst:=Array(0..99,x->x+1): #generate numbers from 1 to 100
select[flatten](isprime,lst);

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

263
2.84. How to collect result inside a loop . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.84 How to collect result inside a loop when number of


interation is not known in advance?
Lets say we want to collect result obtained inside loop, but do not know in advance how
many iteration we need.
In Mathematica, Sow and Reap are used. In Maple, an Array can be used or a queue or a
table.
Mathematica

Remove["Global`*"]
result = First@Last@Reap@Do[
Sow[n],
{n, 1, 10}
];
result

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Maple

restart;
result :=Array([]):
for n from 1 to 10 do
result(n):=n;
od:
result(1..10)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

264
2.85. How flip an array around? CHAPTER 2. LINEAR ALGEBRA, . . .

2.85 How flip an array around?


Given 𝐴 = [1, 2, 3, 4, 5] change it to 𝐴 = [5, 4, 3, 2, 1]

Mathematica

a = {1, 2, 3, 4, 5}; {5, 4, 3, 2, 1}


Reverse[a]

Matlab
ans =
A=[1,2,3,4,5]; 5 4 3 2 1
flip(A)

Maple

A:=Array([1,2,3,4,5]); [5, 4, 3, 2, 1]
ArrayTools:-Reverse(A);

265
2.86. How to divide each element by its . . . CHAPTER 2. LINEAR ALGEBRA, . . .

2.86 How to divide each element by its position in a list?


Given 𝐴 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] change it to
3 5 7 11 13 17 19 23 29
[2, , , , , , , , , ]
2 3 4 5 6 7 8 9 10

2.86.1 Mathematica
A = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
MapIndexed[(#1/First[#2]) &, A]

3 5 7 11 13 17 19 23 29
�2, , , , , , , , , �
2 3 4 5 6 7 8 9 10

2.86.2 Maple
A:= [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
((x,y)->x/y)~(A,[seq(i,i=1..numelems(A))])

#or simpler might be to map the divsion operator directly

`/` ~ (A,[seq(i,i=1..numelems(A))])

3 5 7 11 13 17 19 23 29
[2, , , , , , , , , ]
2 3 4 5 6 7 8 9 10

2.86.3 Matlab
A=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
A./(1:length(A))

2.0000 1.5000 1.6667 1.7500 2.2000 2.1667 2.4286 2.3750 2.5556 2.900

266
Chapter 3

signal processing, Image processing,


graphics, random numbers

3.1 Generate and plot one pulse signal of different


width and amplitude
Problem: Generate one signal of some width and height.

267
3.1. Generate and plot one pulse signal of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Mathematica
pulse of 0.5 sec width and amplitude1
Remove["Global`*"] 2.5
f[x_,w_,h_]:=If[0<=x<w, 2.0
h*If[x-IntegerPart[x]<=0.5, 1.5

y(t)
SquareWave[x], 1.0
0.5
-SquareWave[x]
0.0
],
-0.50.00.51.01.52.02.5
-1.0
0]
w = {0.5,1,2}; (*pulse width *) t

h = {1,1.5,0.4}; (*pulse height *) pulse of 1 sec width and amplitude1.5


2.5
plots = MapThread[Plot[
2.0
f[x,#1,#2],{x,-2,2.5}, 1.5

y(t)
PlotRange->{{-1,2.5},{-0.3,2.5}}, 1.0
Frame->True, 0.5
Axes->False, 0.0
GridLines->Automatic, -0.50.00.51.01.52.02.5
-1.0
GridLinesStyle->Dashed, t
PlotStyle->{Thick,Red}, pulse of 2 sec width and amplitude0.4
FrameLabel->{{"y(t)",None}, 2.5
{"t","pulse of "<>ToString[#1]<> 2.0
" sec width and amplitude"<> 1.5

y(t)
ToString[#2]}}, 1.0
0.5
ImageSize -> 160,
0.0
AspectRatio->1]&,{w,h}];
-0.50.00.51.01.52.02.5
-1.0
t
Grid[{plots},Frame->All]

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]);
268
3.1. Generate and plot one pulse signal of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

title(sprintf...
('pulse of %2.1f sec width and amplitude=%2.1f',...
w(i),h(i)));

end

pulse of 0.5 sec width and amplitude=1.0


2
1
0

-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5


pulse of 1.0 sec width and amplitude=1.5
2
1
0

-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5


pulse of 2.0 sec width and amplitude=0.4
2
1
0

-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5

269
3.2. Generate and plot train of pulses of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.2 Generate and plot train of pulses of different width


and amplitude
Problem: Generate a pulse train of pulses of certain width and height.
pulse of 2. sec width and amplitude1
2
Mathematica
1
Remove["Global`*"]

y(t)
0
w = {0.25,0.125};
h = {1,1.5};
plots = MapThread[Plot[#2 SquareWave[#1 x], -1

{x,-10,10},
PlotRange->{All,{-2,2}}, -2
-10 -5 0 5 10
Frame->True,
t
Axes->False,
pulse of 4. sec width and amplitude1.5
PlotStyle->{Thick,Red}, 2
FrameLabel->{{"y(t)",None},
{"t","pulse of "<>ToString[1/(2*#1)]<>
1
" sec width and amplitude"<>ToString[#2]}},
ImageSize->200,

y(t)
AspectRatio->1, 0

ExclusionsStyle->Dotted]&,{w,h}];
-1
Grid[{plots},Frame->All]
-2
-10 -5 0 5 10
t

270
3.2. Generate and plot train of pulses of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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

-1
for i=1:2 -2

y = h(i)*square(2*pi*f(i)*t);
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2 2.5

pulse of 1.0 sec width and amplitude=1.5


subplot(2,1,i); 2

plot(t,y,'r','LineWidth',3); 1

grid on;
0

-1

xlim([-2 2.5]); -2

ylim([-2 2.5]);
-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

271
3.3. Find the discrete Fourier transform of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.3 Find the discrete Fourier transform of a real


sequence of numbers
𝑁−1 2𝜋
Given the sequence of numbers 𝑥(𝑛) = [1, 2, 3], Find 𝑋(𝑘) = � 𝑥(𝑚)𝑒−𝑗 𝑁 𝑚𝑘 where 𝑁 is the
𝑚=0
length of the data sequence 𝑥(𝑚) and 𝑘 = 0 ⋯ 𝑁 − 1

Mathematica
{6.,
Chop[Fourier[{1, 2, 3}, -1.5 + 0.8660254037844386*I,
FourierParameters ->{1, -1}]] -1.5 - 0.8660254037844386*I}

Matlab ans =
6.0000
fft([1,2,3])' -1.5000 - 0.8660i
-1.5000 + 0.8660i

Maple

Maple need an Array for input, not list, so have to convert


[6.+0.*I,
this is little strange
-1.5+.866025403784439*I,
lst:=[1,2,3]; -1.5-.866025403784439*I]
SignalProcessing[FFT](convert(lst,Array),
normalization=none );

272
3.3. Find the discrete Fourier transform of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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.
--
-- dtf.adb, compiled with GNAT 4.3.4 20090804 (release) 1
-- under CYGWIN 1.7.5
-- $ gnatmake dft.adb
-- gcc -c dft.adb
-- gnatbind -x dft.ali
-- gnatlink dft.ali
-- $ ./dft.exe
-- ( 6.00000E+00, 0.00000E+00)
-- (-1.50000E+00, 8.66026E-01)
-- (-1.50000E+00,-8.66025E-01)

with Ada.Text_IO; use Ada.Text_IO;


with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;

with Ada.Numerics; use Ada.Numerics;

with Ada.Numerics.Complex_Elementary_Functions;
use Ada.Numerics.Complex_Elementary_Functions;
with Ada.Complex_Text_IO; use Ada.Complex_Text_IO;

procedure dft is
N : constant := 3; -- named number, no conversion to Float needed
X : array(0 .. N-1) of Complex := (others=>(0.0,0.0));
data : constant array(0 .. N-1) of float :=(1.0,2.0,3.0);
Two_Pi_Over_N : constant := 2 * Pi / N;
-- named number, outside the loop, like in ARM 3.3.2(9)
begin
FOR k in X'range LOOP
FOR m in data'range LOOP
X(k) := X(k) + data(m)*exp(-J*Two_Pi_Over_N * float(m*k));
END LOOP;
put(X(k)); new_line;
END LOOP;
end dft;

273
3.3. Find the discrete Fourier transform of . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Fortran

Thanks to Vincent Lafage for making improvment to the Fortran code.


! dtf.f90, compiled with GCC 4.3.4
! under CYGWIN 1.7.5
! $ gfortran -Wall -Wsurprising -Wconversion dft.f90
! $ ./a.exe
! ( 6.0000000 , 0.0000000 )
! ( -1.4999999 , 0.86602557 )
! ( -1.5000005 ,-0.86602497 )
! $

PROGRAM dft

IMPLICIT NONE

INTEGER, parameter :: N = 3
COMPLEX, parameter :: J =(0.0,1.0)
REAL, parameter :: Pi = ACOS(-1.0)
INTEGER :: k,m
COMPLEX, dimension(0:N-1) :: X
REAL, dimension(0:N-1) :: data=(/1.0,2.0,3.0/)
REAL, parameter :: Two_Pi_Over_N = 2.0*Pi/real(N)

DO k = lbound(X, 1), ubound(X, 1)


X(k)=(0.0,0.0)
DO m = lbound(data, 1), ubound(data, 1)
X(k) = X(k) + complex(data(m),0.0) &
* EXP(-J*complex(Two_Pi_Over_N*real(m*k),0.0))
END DO
print *,X(k)
END DO

END PROGRAM dft

274
3.4. Generate uniform distributed random . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.4 Generate uniform distributed random numbers


3.4.1 How to generate 5 uniform distributed random numbers from
0 to 1?
Mathematica {0.817389,
0.11142,
SeedRandom[1]; 0.789526,
Table[RandomVariate[ 0.187803,
UniformDistribution[{0,1}]],{5}] 0.241361}

0.814723686393179
Matlab 0.905791937075619
0.126986816293506
rand(5,1) 0.913375856139019
0.632359246225410

Fortran

program t3
implicit none
real :: x(5)

CALL RANDOM_SEED()
CALL random_number(x)
print *,x

end program

compile and run


$ gfortran -std=f95 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion
t3.f90 /usr/lib/liblapack.a /usr/lib/libblas.a
$ ./a.exe
0.99755955 0.56682467 0.96591532 0.74792767 0.36739087

3.4.2 How to generate 5 random numbers from a to b?


Generate uniform numbers from a to b, say a=-2 and b=5

275
3.4. Generate uniform distributed random . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Mathematica {3.72173,
-1.22006,
SeedRandom[1]; 3.52668,
Table[RandomVariate[ -0.685378,
UniformDistribution[{-2,5}]],{5}] -0.310473}

-1.317217165004133
Matlab -0.050512467930661
1.828170634434887
-2 + (5+2)*rand(5,1) 4.702547848040084
4.754219746394936

Fortran
program t3_2
implicit none
integer ::i
real, parameter :: a=-1.0,b=1.0
real :: x(5)

CALL RANDOM_SEED()
DO i=1,2
CALL random_number(x)
x = a+(b-a)*x
print *,x
END DO

end program

compile and run


$ gfortran -std=f95 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion
t3_2.f90 /usr/lib/liblapack.a /usr/lib/libblas.a
$ ./a.exe
0.99511909 0.13364935 0.93183064 0.49585533 -0.26521826
-3.87262106E-02 -0.85249150 -0.98928964 -0.30583751 -0.31551242
$

3.4.3 How to generate MATRIX of random numbers from a to b?


Let 𝑎 = −2 and 𝑏 = 5, matrix of size 5 by 5
276
3.4. Generate uniform distributed random . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Mathematica
SeedRandom[1];
Table[RandomVariate[
UniformDistribution[{-2,5}]],{5},{5}]

{{3.72173,-1.22006,3.52668,-0.685378,-0.310473},
{-1.53983,1.79573,-0.381918,0.772043,2.90332},
{-0.517218,3.2406,0.959955,-0.267537,4.8402},
{3.77614,4.47693,2.04639,0.0500882,-0.543643},
{2.06332,-1.09825,0.144992,2.98408,0.734073}}

Matlab
-2 + (5+2)*rand(5,5)

ans =
3.7642 1.0712 1.4284 -0.0678 1.4885
2.8638 0.6709 1.1191 2.7579 4.7182
0.2197 3.3586 2.5242 2.5857 0.3827
4.6516 3.5664 2.9656 -0.8617 2.0969
-1.7589 -0.6919 3.2828 -1.1670 -0.4333

277
3.4. Generate uniform distributed random . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Fortran
program t3_3
implicit none
integer ::i
real, parameter :: a=-1.0,b=1.0
real :: x(5,5)

CALL RANDOM_SEED()
DO i=1,2
CALL random_number(x)
x = a+(b-a)*x
CALL write(x)
END DO

!--- internal functions below ------


contains
SUBROUTINE write(A)
implicit none
REAL, DIMENSION(:,:) :: A
integer :: i,j

WRITE(*,*)
DO i = lbound(A,1), ubound(A,1)
WRITE(*,*) (A(i,j), j = lbound(A,2), ubound(A,2))
END DO

END SUBROUTINE write

end program

compile and run


$ gfortran -std=f95 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion
t3_3.f90 /usr/lib/liblapack.a /usr/lib/libblas.a

$ ./a.exe
0.99511909 -3.87262106E-02 -0.56409657 0.32386434 0.71138477
0.13364935 -0.85249150 -0.73367929 -0.96778345 -0.19742620
0.93183064 -0.98928964 0.80104899 0.30170965 -0.58625138
0.49585533 -0.30583751 -0.22646809 0.29281759 0.93707883
-0.26521826 -0.31551242 -0.10903549 -0.35402548 0.19679904

0.34596145 0.21138644 0.22462976 0.31809497 0.45771694


-8.62354040E-02 0.43809581 0.95732045 0.10801017 -0.19508958
-0.33996975 0.79466915 0.99828446 0.95552015 0.85725522

278
3.4. Generate uniform distributed random . . . CHAPTER 3. SIGNAL PROCESSING, . . .

-0.79923415 0.31645823 -0.48640406 0.80384660 -0.70432973


0.51090658 -0.69856644 0.10173070 0.31584930 0.34905851

279
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.5 Obtain Fourier Series coefficients for a periodic


function
2𝜋
Given a continuous time function 𝑥 (𝑡) = sin( 𝑇 𝑡), find its Fourier coefficients 𝑐𝑛 , where
0

𝑥 (𝑡) = � 𝑐𝑛 𝑒𝑗𝜔0𝑛𝑡
𝑛=−∞
and 𝑇0
1 2
𝑐𝑛 = � 𝑥(𝑡)𝑒−𝑗𝜔0𝑛𝑡 𝑑𝑡
𝑇0 − 𝑇0
2
2𝜋
Where 𝑇0 is the fundamental period of 𝑥 (𝑡) and 𝜔0 = 𝑇0

Mathematica

Clear[T0, w0]
sol = FourierSeries[Sin[2 Pi/T0 t],
t, 3, FourierParameters -> {1, 2 Pi/T0}]

1 − 2𝑖𝜋𝑡 1 2𝑖𝜋𝑡
𝑖𝑒 T0 − 𝑖𝑒 T0
2 2
data = Table[{i,
FourierCoefficient[Sin[2 Pi/T0 t], t, i,
FourierParameters -> {1, 2 Pi/T0}]}, {i, -5, 5}];
head = {"n", "cn"};
Grid[Insert[data, head, 1], Frame -> All]

n cn
-5 0
-4 0
-3 0
-2 0

-1 2
0 0
1 - ⅈ2
2 0
3 0
4 0
5 0

280
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

mag = data;
mag[[All,2]] = Map[Abs[#]&,data[[All,2]]];
ListPlot[mag,AxesOrigin->{0,0},
Filling->Axis,
FillingStyle->{{Thick,Red}},
AxesLabel->{"n","|Subscript[c, n]|"}]

|cn |

0.5

0.4

0.3

0.2

0.1

n
-4 -2 2 4

phase = data;
phase[[All,2]]=Map[Arg[#]&,
data[[All,2]]]* 180/Pi;
ListPlot[phase,AxesOrigin->{0,0},
Filling->Axis,
FillingStyle->{{Thick,Red}},
AxesLabel->{"n","Phase Subscript[c, n] degrees"},
ImageSize->300]

Phase cn degrees
100

50

n
-4 -2 2 4

-50

-100

281
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

(*Find Fourier Series for Cos[w0 t] + Sin[w0 t]^2*)

T0 = 2 Pi;
w0 = (2 Pi)/T0;
f[t_] := Cos[w0 t] + Sin[w0 t]^2;
Plot[f[t], {t, -10 Pi, 10 Pi},
PlotRange -> All,
ImageSize -> 300]

1.0

0.5

-30 -20 -10 10 20 30

-0.5

-1.0

sol = FourierSeries[f[t],t,3,
FourierParameters->{1,(2 Pi)/T0}]

𝑒−𝑖𝑡 𝑒𝑖𝑡 1 −2𝑖𝑡 1 2𝑖𝑡 1


+ − 𝑒 − 𝑒 +
2 2 4 4 2
data = Table[{i,
FourierCoefficient[f[t],t,i,
FourierParameters->{1,2 Pi/T0}]},{i,-5,5}];

head = {"n","cn"};
Grid[Insert[data,head,1],Frame->All]

282
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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

mag = data;
mag[[All,2]] = Map[Abs[#]&,data[[All,2]]];
ListPlot[mag,AxesOrigin->{0,0},
Filling->Axis,
FillingStyle->{{Thick,Red}},
AxesLabel->{"n","|Subscript[c, n]|"},
ImageSize->300]

|cn |

0.5

0.4

0.3

0.2

0.1

n
-4 -2 2 4

Plot phase
phase = data;
phase[[All, 2]] = Map[Arg[#] &,

283
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

data[[All, 2]]]* 180/Pi;


ListPlot[phase, AxesOrigin -> {0, 0},
Filling -> Axis,
FillingStyle -> {{Thick, Red}},
AxesLabel -> {"n", "Phase cn degrees"}]

Phase cn degrees

150

100

50

n
-4 -2 2 4

Find Fourier series for periodic square wave


f[x_] := SquareWave[{0,1},(x+.5)/2] ;
Plot[f[x],{x,-6,6},Filling->Axis,
ImageSize->300]

1.0

0.8

0.6

0.4

0.2

-6 -4 -2 2 4 6

T0 = 2;
sol = Chop[FourierSeries[f[t],t,6,
FourierParameters->{1,(2 Pi)/T0}]]

0.5 + 0.31831𝑒−𝑖𝜋𝑡 + 0.31831𝑒𝑖𝜋𝑡 − 0.106103𝑒−3𝑖𝜋𝑡 − 0.106103𝑒3𝑖𝜋𝑡 + 0.063662𝑒−5𝑖𝜋𝑡 + 0.063662𝑒5𝑖𝜋𝑡

data = Chop[Table[{i,FourierCoefficient[f[t],t,i,
FourierParameters->{1,2 Pi/T}]},{i,-8,8}]];

head = {"n","cn"};
Grid[Insert[data,head,1],Frame->All]

284
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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

data=Table[{i,FourierCoefficient[f[t],t,i,
FourierParameters->{1,2 Pi/T}]},{i,-20,20}];
mag = data;
mag[[All,2]]=Map[Abs[#]&,data[[All,2]]];
ListPlot[mag,AxesOrigin->{0,0},
Filling->Axis,
FillingStyle->{{Thick,Red}},
PlotRange->All,
AxesLabel->{"n","|Subscript[c, n]|"},
ImageSize->300]

|cn |

0.5

0.4

0.3

0.2

0.1

n
-20 -10 10 20

Show phase
phase = data;

285
3.5. Obtain Fourier Series coefficients for . . . CHAPTER 3. SIGNAL PROCESSING, . . .

phase[[All,2]]=Map[Arg[#]&,data[[All,2]]]* 180/Pi;
ListPlot[phase,AxesOrigin->{0,0},
Filling->Axis,
FillingStyle->{{Thick,Red}},
AxesLabel->{"n","Phase cn degrees"},
ImageSize->300]

Phase cn degrees

150

100

50

n
-20 -10 10 20

286
3.6. Determine and plot the CTFT . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.6 Determine and plot the CTFT (continuous time


Fourier Transform) for continuous time function
Plot the CTFT 𝑋(𝜔) of 𝑥(𝑡) = 3 sin(𝑡). By definition

𝑋(𝜔) = � 𝑥(𝑡)𝑒−𝑖𝜔𝑡 𝑑𝑡
𝑡=−∞

Mathematica

Clear["Global`*"];
f = 3*Sin[t];
y = FourierTransform[f,t,w,FourierParameters->{1, -1}]

Out[138]= -3 I Pi DiracDelta[-1+w]+3 I Pi DiracDelta[1+w]

tab = Table[{k,y/.w->k},{k,-3,3}]
tab = tab/.DiracDelta[0]->1
tab[[All,2]]=Map[Sign[Im[#]]Abs[#]&,tab[[All,2]]]

ListPlot[tab,PlotStyle->AbsolutePointSize[5],
AxesLabel->{"frequency \[CapitalOmega] rad/sec",
"|F(\[CapitalOmega]|"},
PlotRange->{All,{-12,12}},
Filling->Axis,
FillingStyle->{{Thick,Red}}]

|F(Ω|

10

frequency Ω rad/sec
-3 -2 -1 1 2 3
-5

-10

Matlab
syms t;
F=fourier(3*sin(t))

F =
-pi*(dirac(w-1)-dirac(w+1))*3*i

Need to do the plot.


287
3.6. Determine and plot the CTFT . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Maple
restart;
transform := expand(inttrans:-fourier(3*sin(t), t, w))

gives
transform := 3*I*Pi*Dirac(w + 1) - 3*I*Pi*Dirac(w - 1)

288
3.7. Determine the DTFT (Discrete time . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.7 Determine the DTFT (Discrete time Fourier


Transform) for discrete time function
𝜋𝑛
Find DTFT 𝑋(Ω) of 𝑥[𝑛] = sin( 8
). By definition


𝑋(Ω) = � 𝑥[𝑛]𝑒−𝑖Ω𝑛
𝑛=−∞

Mathematica

Clear["Global`*"];
x[n_] := Sin[(Pi*n)/8];
X = FourierSequenceTransform[x[n], n, w, FourierParameters -> {1, 1}] //
Simplify

Which gives
(-(1/2))*I*(DiracComb[(Pi - 8*w)/(16*Pi)] - DiracComb[(Pi + 8*w)/(16*Pi)])

289
3.8. Determine the Inverse DTFT . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.8 Determine the Inverse DTFT (Discrete time Fourier


Transform)
Find 𝑥[𝑛], give its DTFT 𝑋(Ω)

1 𝜋
𝑥[𝑛] = � 𝑋(Ω)𝑒𝑖Ω𝑛 𝑑Ω
2𝜋 −𝜋

Mathematica

Clear["Global`*"];
x[n_] := Sin[(Pi*n)/8];
X = FourierSequenceTransform[x[n], n, w, FourierParameters -> {1, 1}];
InverseFourierSequenceTransform[X, w, n]

Which gives
Sin[(Pi*n)/8]

290
3.9. Use FFT to display the power . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.9 Use FFT to display the power spectrum of the


content of an audio wav file
Problem: download a wav file and display the frequency spectrum of the audio signal using
FFT. The Matlab example was based on Matheworks tech note 1702.

291
3.9. Use FFT to display the power . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Mathematica
{AudioChannels,
Remove["Global`*"]; AudioEncoding,
fname = "stereo.wav"; Data,SampledSoundList,
SetDirectory[NotebookDirectory[]]; SampleRate,Sound}
ele = Import[fname,"Elements"]

(*listen to it *)
sound = Import[fname,"Sound"];
EmitSound[sound] 22050

fs = Import[fname,"SampleRate"]

now load the samples and do power spectrum


data = Import[fname,"Data"]; Out[115]= {2,29016}
{nChannel,nSamples}=Dimensions[data]

py = Fourier[data[[1,All]],
FourierParameters->{1,-1}]; Out[117]= 14509
nUniquePts = Ceiling[(nSamples+1)/2]

py = py[[1;;nUniquePts]];
py = Abs[py];
py = py/nSamples;
py = py^2;

If[ OddQ[nSamples],
py[[2;;-1]]=2*py[[2;;-1]],
py[[2;;-2]]=2*py[[2;;-2]] Magnitude spectrum

];
4. × 10-6

3. × 10-6

f = (Range[0,nUniquePts-1] fs)/nSamples; |H(f)| 2. × 10-6

ListPlot[Transpose[{f,py}], 1. × 10-6

Joined->True,
0
FrameLabel->{{"|H(f)|",None}, 0 2000 4000 6000 8000 10 000 12 000
hz
{"hz","Magnitude spectrum"}},
ImageSize->400,
Frame->True,
RotateLabel->False,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotRange->{{0,12000},All}]
292
3.9. Use FFT to display the power . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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;

if rem(N, 2) % odd nfft excludes Nyquist point


P(2:end) = P(2:end)*2;
else
P(2:end -1) = P(2:end -1)*2;
end

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');

293
3.9. Use FFT to display the power . . . CHAPTER 3. SIGNAL PROCESSING, . . .

#10 -6 Power Spectrum of a wave file


4

3.5

2.5
|H(f)|

1.5

0.5

0
0 2000 4000 6000 8000 10000 12000
Frequency Hz

294
3.10. Plot the power spectral density of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.10 Plot the power spectral density of a signal


Problem: Given a signal

3 sin �2𝜋𝑓1 𝑡� + 4 cos �2𝜋𝑓2 𝑡� + 5 cos �2𝜋𝑓3 𝑡�

for the following frequency values (in Hz)

𝑓1 = 20, 𝑓2 = 30, 𝑓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
Clear ["Global`*"];
f1 = 20;
f2 = 30;
f3 = 100;
maxTime = 0.2;

y[t_]:=2 Sin[2 Pi f1 t]+4 Cos[2 Pi f2 t]+


5 Cos[2 Pi f3 t];

Plot[y[t],{t,0,maxTime},
Frame->True,
FrameLabel->{{"y(t)",None},
{"t (sec)","signal in time domain"}},
RotateLabel->False,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotRange->All,BaseStyle -> 12]

signal in time domain


10

y(t) 0

-5

-10

0.00 0.05 0.10 0.15 0.20


t (sec)

fs = 7.0*Max[{f1,f2,f3}];
yn = Table[y[n],{n,0,maxTime,(1/fs)}];
len = Length[yn];
py = Fourier[yn];
295
3.10. Plot the power spectral density of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

nUniquePts = Ceiling[(len+1)/2];
py = py[[1;;nUniquePts]];
py = Abs[py];
py = 2*(py^2);
py[[1]] = py[[1]]/2;
f = (Range[0,nUniquePts-1] fs)/len;

ListPlot[Transpose[{f,py}],Joined->False,
FrameLabel->{{"|H(f)|",None},
{"hz","Magnitude spectrum"}},
ImageSize->400,
Filling->Axis,
FillingStyle->{Thick,Red},
Frame->True,
RotateLabel->False,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotRange->All,BaseStyle -> 12]

Magnitude spectrum

1 × 1011

8 × 1010

6 × 1010
|H(f)|

4 × 1010

2 × 1010

0
0 50 100 150 200 250 300 350
hz

Here is the same plot as above, but using InterpolationOrder -> 0


Magnitude spectrum

1 × 1011

8 × 1010

6 × 1010
|H(f)|

4 × 1010

2 × 1010

0
0 50 100 150 200 250 300 350
hz

And using InterpolationOrder -> 2

296
3.10. Plot the power spectral density of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

Magnitude spectrum

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');

signal in time domain


10

5
Amplitude

-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);

297
3.10. Plot the power spectral density of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

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]);

#10 5 power spectral density


2.5

2
Energy content

1.5

0.5

0
0 100 200 300 400
freq (Hz)

298
3.11. Display spectrum of 2D image CHAPTER 3. SIGNAL PROCESSING, . . .

3.11 Display spectrum of 2D image


Mathematica

img=Import["ExampleData/lena.tif"];
Image[img,ImageSize->300]

ImageDimensions[img]

{150,116}

(*see how many channels*)


ImageChannels[img]

data=ImageData[img]; (*get data*)


{nRow,nCol,nChannel}=Dimensions[data]

{116,150,3}

(*look at each channel*)


Map[Image[data[[All,All,#]],ImageSize->100]&,
Range[1,nChannel]]

 , , 

(*get channel 2 to FFT but center it first*)


d = data[[All,All,2]];
299
3.11. Display spectrum of 2D image CHAPTER 3. SIGNAL PROCESSING, . . .

d = d*(-1)^Table[i+j,{i,nRow},{j,nCol}];

(*make FFT,center, view spectrum and phase*)


fw = Fourier[d,FourierParameters->{1,1}];
(*adjust for better viewing as needed*)
fudgeFactor = 100;
abs = fudgeFactor * Log[1+Abs@fw];
Labeled[Image[abs/Max[abs],
ImageSize->300],
Style["Magnitude spectrum", 18]]

Magnitude spectrum

arg = Arg@fw;
Labeled[Image[arg/Max[arg],
ImageSize->300],
Style["Phase spectrum", 18]]

Phase spectrum

Matlab

close all; clear all;


%image in same folder.
img = imread('lena.tiff','tif');
imagesc(img)

300
3.11. Display spectrum of 2D image CHAPTER 3. SIGNAL PROCESSING, . . .

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');

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

301
3.12. Obtain the statistical maximum . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.12 Obtain the statistical maximum likelihood


estimates (MLE) of probability distributions
This example uses the normal distribution and Poisson as examples. The maximum like-
lihood estimates of the population parameters is found by solving equation(s) using the
standard method of taking logs and differentiation to solve for the maximum. Mathematica
and Matlab version will be added at later time.
Maple

restart; with(Statistics):
X := RandomVariable(Normal(mu,sigma));
lik:=product(PDF(X,x[i]),i=1..n);
lik:=expand(ln(lik)) assuming positive;
eq1:=diff(lik,mu)=0;
eq2:=diff(lik,sigma)=0;
solve({eq1,eq2},{mu,sigma});
allvalues( %[2]);

302
3.12. Obtain the statistical maximum . . . CHAPTER 3. SIGNAL PROCESSING, . . .

303
3.13. Make a histogram of data sampled . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.13 Make a histogram of data sampled from some


probability distribution
This example uses the normal distribution. First random data is generated, then histogram
of the data is made.
Matlab do not have an option, (unless I missed it) to make a relative histogram (this is
where the total area is 1) but not hard to implement this.

Mathematica 0.4

0.3

data = RandomReal[NormalDistribution[],1000];
Histogram[data,30,"ProbabilityDensity",
0.2

ImageSize -> 300]] 0.1

0.0
-3 -2 -1 0 1 2 3

Matlab
0.45

data = randn(1000,1); 0.4

numberOfBins = 20; 0.35

[freq,bin] = hist(data,numberOfBins);
0.3

0.25

binWidth = (bin(end)-bin(1))/numberOfBins; 0.2

currentArea = sum(binWidth*freq); 0.15

freq = freq/currentArea; 0.1

0.05

0
bar(bin,freq) -4 -3 -2 -1 0 1 2 3 4

Maple

restart;
with(Statistics):
nSamples:=1000:
data := Sample(RandomVariable(Normal(0, 1)),
nSamples):

plots[display](Histogram(data,bincount=20,
frequencyscale=relative));

304
3.14. apply a filter on 1D numerical data . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.14 apply a filter on 1D numerical data (a vector)


Problem: suppose we want to apply say an averaging filter on a list of numbers. Say we want
to replace each value in the list by the average 3 values around each value (a smoothing
filter).
In Mathematica, ListConvolve is used, in Matlab conv() is used.

Out[66]= {1.,
Mathematica 3.33333,
6.,
data={1,2,7,9,3,4,10,12}; 6.33333,
filter=(1/3){1,1,1}; 5.33333,
data[[2;;-2]]=ListConvolve[filter,data]; 5.66667,
N[data] 8.66667,
12.}

1.0000
Matlab 3.3333
6.0000
data = [1 2 7 9 3 4 10 12]; 6.3333
filter = (1/3)*[1 1 1]; 5.3333
data(2:end-1) = conv(data,filter,'valid'); 5.6667
data' 8.6667
12.0000

305
3.15. apply an averaging Laplacian filter . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.15 apply an averaging Laplacian filter on 2D


numerical data (a matrix)
Problem: Apply a Laplacian filter on 2D data. In Mathematica, ListConvolve is used, in
Matlab conv2() is used.
Mathematica

data={{0,4,10,5,3}, {{0., 4., 10., 5.,


{4,4,1,8,5}, 3.},
{5,1,2,3,8}, {4., 2.5, 6., 3.5,
{8,6,8,8,10}, 5.},
{10,3,7,7,8}}; {5., 4.25, 3.25, 6.5,
8.},
filter= (1/4){{0,1,0}, {8., 5., 5.75, 7.,
{1,0,1}, 10.},
{0,1,0}}; {10.,3., 7., 7.,
8.}}
data[[2;;-2,2;;-2]]=ListConvolve[filter,data];
N[%]

Matlab

data=[0 4 10 5 3; data =
4,4,1,8,5; 0 4.0000 10.0000 5.0000
5,1,2,3,8; 3.0000
8,6,8,8,10; 4.0000 2.5000 6.0000 3.5000
10,3,7,7,8]; 5.0000
5.0000 4.2500 3.2500 6.5000
filter= (1/4)*[0,1,0; 8.0000
1,0,1; 8.0000 5.0000 5.7500 7.0000
0,1,0]; 10.0000
10.0000 3.0000 7.0000 7.0000
data(2:end-1,2:end-1)=... 8.0000
conv2(data,filter,'valid')

306
3.16. How to find cummulative sum CHAPTER 3. SIGNAL PROCESSING, . . .

3.16 How to find cummulative sum


10 1
compute ∑ 𝑘(𝑘+1)
𝑘=1

Mathematica
0.9090909090909091
N[Sum[1/(k*(k + 1)), {k, 10}]]

Matlab

format long
k=1:10; 0.909090909090909
s=cumsum(1./(k.*(k+1)));
s(end)

307
3.17. How to find the moving average of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.17 How to find the moving average of a 1D sequence?


Given some sequence such as 1, 2, 3, 4, 5, 6, 7 how to find the moving average for different
window sizes?
Mathematica

For window size 𝑘 = 2


v = {1, 2, 3, 4, 5, 6, 7, 8}; {1.5,2.5,3.5,4.5,5.5,6.5,7.5}
f = {1/2, 1/2};
ListConvolve[f, v] // N

For window size 𝑘 = 3


v = {1, 2, 3, 4, 5, 6, 7, 8};
{2., 3., 4., 5., 6., 7.}
f = Table[1/3, {3}];
ListConvolve[f, v] // N

Matlab

For a window size 𝑘 = 2


ans =
V=[1 2 3 4 5 6 7 8]; 1.5000 2.5000 3.5000 4.5000 5.5000 6.5000 7.5000
f=[1/2 1/2];
conv(V,f,'valid')

For window size 𝑘 = 3


V = [1 2 3 4 5 6 7 8];
ans =
k = 3;
2.0000 3.0000 4.0000 5.0000 6.0000 7.0000
f = ones(k,1)/k;
conv(V,f,'valid')

308
3.18. How to select N random values from . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.18 How to select N random values from a set of


numbers?
Given the set 𝑣1, 2, 3, 5, 6, 7, 11, 12, 20, 21 how to select say 𝑚 = 5 random numbers from it?

Mathematica

method 1
a = {1, 2, 3, 5, 6, 7, 11, 12, 20, 21};
m = 5;
b = Table[0, {m}];
Do[k = RandomInteger[{1, Length[a]}]; {6, 21, 3, 5, 11}
b[[i]] = a[[k]];
a = Delete[a, k],
{i, 1, m}
];
b

method 2 (Version 9)
{1, 6, 11, 7, 20} *)
RandomSample[a, m]

Matlab

A = [1,2,3,5,6,7,11,12,20,21];
m = 5; B =
B = zeros(m,1); 2
for i = 1:m 20
k = randi(length(A),1); 7
11
B(i) = A(k);
1
A(k) = [];
end
B

309
3.19. How to sample a sin signal and plot it? CHAPTER 3. SIGNAL PROCESSING, . . .

3.19 How to sample a sin signal and plot it?


Sample a sin signal of one second period at 8 times its frequency.
Mathematica

period = 1; (*sec*)
f = 1/period;
fs = 8*f; (*sample at 8 times*)
Ts = 1/fs; (*sampling period*)
nSamples = Round[period/Ts];
x = Array[# &, nSamples, {0, period - Ts}]; (*linspace*)
signal = {#, Sin[2 Pi f #]} & /@ x;
text = MapIndexed[Text[ToString@First[#2], #1, {2, 0}] &, signal];

Show[
ListPlot[signal, PlotStyle -> Red, Filling -> Axis, Frame -> True,
FrameLabel -> {{"f(t)", None}, {"time (sec)", "sampled sin at f2=20 hz"
}},
Epilog -> text, PlotTheme -> "Classic",
PlotRangePadding -> 0
],
Plot[Sin[2 Pi f t], {t, 0, period}, PlotTheme -> "Classic"],
BaseStyle -> 10, PlotRange -> {{0, period}, {-1.1, 1.1}}]

sampled sin at f2=20 hz

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;

310
3.19. How to sample a sin signal and plot it? CHAPTER 3. SIGNAL PROCESSING, . . .

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]);

3
1

2 4

0.5

5
0 1

-0.5

6 8

-1
7

0 0.2 0.4 0.6 0.8 1

311
3.20. How find the impulse response of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

3.20 How find the impulse response of a difference


equation?
Find the impulse response ℎ[𝑛] for the discrete system given by the difference equation
1 1
𝑦[𝑛] − 2 𝑦[𝑛 − 1] = 𝑥[𝑛] − 4 𝑥[𝑛 − 1]
analytical solution:
1. The first step is to replace 𝑦[𝑛] by ℎ[𝑛] and 𝑥[𝑛] by 𝛿[𝑛] giving
1 1
ℎ[𝑛] − ℎ[𝑛 − 1] = 𝛿[𝑛] − 𝛿[𝑛 − 1]
2 4

2. Taking the Fourier transform and assuming 𝐻(𝑒𝑖𝜔 ) is the Fourier transform of ℎ[𝑛]
results in
1 1
𝐻(𝑒𝑖𝜔 ) − 𝐻(𝑒𝑖𝜔 )𝑒−𝑖𝜔 = 1 − 𝑒−𝑖𝜔
2 4

3. Solving for 𝐻(𝑒𝑖𝜔 ) gives


1
1 − 4 𝑒−𝑖𝜔
𝐻(𝑒𝑖𝜔 ) = 1
1 − 2 𝑒−𝑖𝜔
1 1 𝑒−𝑖𝜔
= 1

1 − 2 𝑒−𝑖𝜔 4 1 − 1 𝑒−𝑖𝜔
2

4. Taking the inverse discrete Fourier transform given by


1 𝜋
ℎ[𝑛] = � 𝐻(𝑒𝑖𝜔 )𝑒𝑖𝜔
2𝜋 −𝜋
which results in
𝑛 𝑛−1
1 1 1
ℎ[𝑛] = � � 𝑢[𝑛] − � � 𝑢[𝑛 − 1]
2 4 2

Mathematica

Clear[w, n]
expr1 = -(1/4)*Exp[-I w]/(1 - (1/2)*Exp[-I w]);
expr2 = 1/(1 - (1/2)*Exp[-I w]);
sol1 = InverseFourierSequenceTransform[expr1, w, n];
sol2 = InverseFourierSequenceTransform[expr2, w, n];
sol = sol1 + sol2

−2−𝑛−1 𝑛 > 0 2−𝑛 𝑛 ≥ 0


+
0 True 0 True
312
3.20. How find the impulse response of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

And some values of ℎ[𝑛] starting from 𝑛 = 0 are


(sol /. n -> #) & /@ Range[0, 10]

1 1 1 1 1 1 1 1 1 1
�1, , , , , , , , , , �
4 8 16 32 64 128 256 512 1024 2048

313
3.20. How find the impulse response of a . . . CHAPTER 3. SIGNAL PROCESSING, . . .

314
Chapter 4

Differential, PDE solving, integration,


numerical and analytical solving of
equations

4.1 Generate direction field plot of a first order


differential equation
Problem: Given the following non autonomous differential equation, plot the line fields
which represents the solutions of the ODE.

𝑑𝑦 (𝑥)
= 𝑥2 − 𝑦
𝑑𝑥

Direction field plot (or slope plot) shows solutions for the ODE without actually solving the
ODE.
𝑑𝑦
The following are the steps to generate direction field plot for 𝑑𝑥
= 𝑓(𝑥, 𝑦)
1. generate 2 lists of numbers. The 𝑦 list and the 𝑥 list. These 2 lists are the coordinates
at which a small slop line will be plotted.
2. At each of the above coordinates (𝑦, 𝑥) evaluate 𝑓(𝑥, 𝑦).
3. Plot small line starting at the point (𝑥, 𝑦) and having slop of 𝑓(𝑥, 𝑦). 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 (𝑥, 𝑦) coordinates) then the slope 𝑓(𝑥, 𝑦)
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.

315
4.1. Generate direction field plot of a first . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica direction fields for y'(x)=x2 -y

40
f[x_,y_]:= x^2-y
ListVectorPlot[Table[{1,f[x,y]},
{x,-2,2,0.1},{y,-2,2,0.1}], 30

FrameLabel->{{"y(x)",None},
{"x",

y(x)
20

"direction fields for y'(x)=x^2-y


"} 10
},
ImageSize->350,
0
LabelStyle->Directive[14]]
0 10 20 30 40
x

direction fields for y'(x)=x2 -y

StreamPlot[{1,f[x,y]},{x,-2,2},{y
,-2,2}, 1

FrameLabel->{{"y(x)",None},
{"x","direction fields for y'(x)=x^2-
y(x)

0
y"}},
ImageSize->350,
-1
LabelStyle->Directive[14]]

-2

-2 -1 0 1 2
x

316
4.1. Generate direction field plot of a first . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Matlab

clear all; close all;

%direction fields for dy/dx=xy


f = @(X,Y) X.^2 - Y;
[X,Y] = meshgrid(-2:.4:2,-2:.4:2); dy
direction -elds for = x2 ! y
YlengthOfVector = f(X,Y); 2
dx

XlengthOfVector = ones(size( 1.5

YlengthOfVector)); 1

0.5
quiver(X,Y,XlengthOfVector,

y
YlengthOfVector);
0

-0.5
xlabel('x'); ylabel('y');
hold on; -1

-1.5

contour(X,Y,YlengthOfVector,... -2
-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

[-5 -4 -3 -2 -1 0 1 2 3 4 5]); x

title(...
'direction fields for $\frac{dy}{dx}=x
^2-y$',...
'interpreter','latex','fontsize',12)

317
4.1. Generate direction field plot of a first . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Maple

restart;
with(DEtools): with(plots):
ode1:=diff(y(x),x)=(y(x))^2-x;
dfieldplot(ode1,y(x),x=-6..10, y=-4..4,
arrows=MEDIUM,
title=`Line fields for an non-autonomous
ODE`);

restart;
with(DEtools): with(plots):
ode1:=diff(y(x),x)=(y(x))^2-x:
p1:= dfieldplot(ode1,y(x),x=-6..10, y √3Ai
(1)
(𝑥) + Bi(1) (𝑥)
=-6..6, 𝑦 (𝑥) = −
arrows=MEDIUM): √3Ai (𝑥) + Bi (𝑥)
sol:=dsolve({ode1,y(0)=0});

p2:=plot(rhs(sol),x=-6..10,
color=black,thickness=3):
display({p1,p2},
title=`Line fields and solution lines
for an non-autonomous ODE`);

318
4.2. Solve the 2-D Laplace PDE for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.2 Solve the 2-D Laplace PDE for a rectangular plate


with Dirichlet boundary conditions
Problem: Solve ∇ 2 𝑇 �𝑥, 𝑦� = 0 on the following plate, with height ℎ = 30, and width 𝑤 = 10,
and with its edges held at fixed temperature as shown, find the steady state temperature
distribution
System boundary conditions.

T=100 degrees

T=0 degrees 30 T=0 degrees

10

T=0 degrees

Plate, with sides held at the


tempretures shown. Find T(x,y),
the heat distribution anywhere
inside the plate.

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.

319
4.2. Solve the 2-D Laplace PDE for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica Matlab

n = 32; (*grid size*) n = 32;


h = 1/(n-1);(*grid spacing*) h = 1/(n-1); %grid spacing
u = Table[0.,{n},{n}]; (*init to zero u = zeros(n,n);
*) u(1,:) = 100; %B.C.
u[[1,All]] = 100; (*B.C.*)
% coordinates
Do[ (*iterate 100 times*) [X,Y] = meshgrid(0:h:1,0:h:1);
tmp=u;
For[i=2,i<=n-1,i++, for k=1:100
For[j=2,j<=n-1,j++, tmp = u;
tmp[[i,j]]=
(1/4)(u[[i-1,j]]+u[[i+1,j]]+ for i=2:n-1
u[[i,j-1]]+u[[i,j+1]]) for j=2:n-1
] tmp(i,j)=...
]; (1/4)*(u(i-1,j)+u(i+1,j)
+...
u=tmp, u(i,j-1)+u(i,j+1));
{100} end
]; end

ListPlot3D[u,PlotRange->All, u=tmp;
ImagePadding->20, end
Mesh->{n,n},
ImageSize->300, mesh(X,Y,u);
PlotLabel->"solution of Laplace PDE title('solution of Laplace PDE on 2D')
on 2D" ;
] set(gcf,'Position',[10,10,320,320]);

320
4.3. Solve homogeneous 1st order ODE, . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.3 Solve homogeneous 1st order ODE, constant


coefficients and initial conditions
Problem: Solve
𝑦′ (𝑡) = 3𝑦 (𝑡)
with initial condition 𝑦 (0) = 1 and plot the solution for 𝑡 = 0 ⋯ 2 seconds.

321
4.3. Solve homogeneous 1st order ODE, . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica Matlab

Remove["Global`*"]; function e53


sol = First@DSolve[{y'[t]==3y[t], t = 0:0.001:2; % time
y[0]==1},y[t],t]; initial_y = 1;
y = y[t]/.sol
[t,y] = ode45( @rhs, t, initial_y);
Out[26]= E^(3 t)
plot(t,y)
Plot[y,{t,0,2}, title('Solution of y''=3y , y(0)=1'
FrameLabel->{{"y(t)",None}, );
{"t","Solution of y'=3y, y(0)=1" xlabel('time');
}}, ylabel('y(t)');
Frame->True, grid on
GridLines->Automatic, set(gcf,'Position',[10,10,420,420])
GridLinesStyle->Automatic, ;
RotateLabel->False,
ImageSize->300, function dydt=rhs(t,y)
AspectRatio->1] dydt = 3*y;
end
Solution of y'=3y, y(0)=1 end
400
Solution of y'=3y , y(0)=1
500
300

400
y(t) 200

300
y(t)

100
200

0
100
0.0 0.5 1.0 1.5 2.0
t
0
0 0.5 1 1.5 2
time

322
4.4. Solve homogeneous 2nd order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.4 Solve homogeneous 2nd order ODE with constant


coefficients
Problem: Solve
𝑦′′ (𝑡) − 1.5𝑦′ (𝑡) + 5𝑦 (𝑡) = 0
with initial conditions
𝑦 (0) = 1, 𝑦′ (0) = 0
To use Matlab ode45, the second order ODE is first converted to state space formulation as
follows
Given 𝑦′′ (𝑡) − 1.5𝑦′ (𝑡) + 5𝑦 (𝑡) = 0 let

𝑥1 = 𝑦
𝑥2 = 𝑦′
= 𝑥′1

hence
𝑥′1 = 𝑥2
and

𝑥′2 = 𝑦′′
= 1.5𝑦′ − 5𝑦
= 1.5𝑥2 − 5𝑥1

Hence we can now write ⎡ ⎤ ⎡ ⎤⎡ ⎤


⎢⎢𝑥′1 ⎥⎥ ⎢⎢ 0 1 ⎥⎥ ⎢⎢𝑥1 ⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎢ ⎥
⎣𝑥′ ⎦ ⎣−5 1.5⎥⎦ ⎢⎣𝑥 ⎥⎦
2 2

Now Matlab ODE45 can be used.

323
4.4. Solve homogeneous 2nd order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica Matlab

Remove["Global`*"]; function e54


eq = y''[t]-1.5y'[t]+5y[t]==0;
ic = {y'[0]==0,y[0]== 1}; t0 = 0; %initial time
sol = First@DSolve[{eq,ic},y[t],t]; tf = 10; %final time
y = y[t]/.sol
%initial conditions [y(0) y
1. �1.𝑒0.75𝑡 cos(2.10654𝑡) − 0.356034𝑒0.75𝑡 sin(2.10654𝑡)� '(0)]
Plot[y,{t,0,10}, ic =[1 0]';
FrameLabel->{{"y(t)",None},
{"t","Solution"}}, [t,y] = ode45(@rhs, [t0 tf], ic
Frame->True, );
GridLines->Automatic,
GridLinesStyle->Automatic, plot(t,y(:,1),'r')
RotateLabel->False, title('Solution using ode45');
ImageSize->300, xlabel('time');
AspectRatio->1, ylabel('y(t)');
PlotRange->All, grid on
PlotStyle->{Thick,Red}] set(gcf,'Position'
,[10,10,320,320]);
Solution
function dydt=rhs(t,y)
dydt=[y(2) ;
500
-5*y(1)+1.5*y(2)];
end
0 end
y(t)
-500 Solution using ode45
1000

-1000 500

0
-1500
y(t)

-500
0 2 4 6 8 10
t -1000

-1500

-2000
0 2 4 6 8 10
time

324
4.5. Solve non-homogeneous 2nd order . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.5 Solve non-homogeneous 2nd order ODE, constant


coefficients
Problem: Solve
𝑦′′ (𝑡) − 1.5𝑦′ (𝑡) + 5𝑦 (𝑡) = 4 cos (𝑡)
with initial conditions
𝑦 (0) = 1, 𝑦′ (0) = 0
To use Matlab ode45, the second order ODE is converted to state space as follows
Given 𝑦′′ (𝑡) − 1.5𝑦′ (𝑡) + 5𝑦 (𝑡) = 4 cos (𝑡), let

𝑥1 = 𝑦
𝑥2 = 𝑦′
= 𝑥′1

hence
𝑥′1 = 𝑥2
and

𝑥′2 = 𝑦′′
= 1.5𝑦′ − 5𝑦 + 4 cos (𝑡)
= 1.5𝑥2 − 5𝑥1 + 4 cos (𝑡)

Hence we can now write ⎡ ⎤ ⎡ ⎤⎡ ⎤ ⎡ ⎤


⎢⎢𝑥′1 ⎥⎥ ⎢⎢ 0 1 ⎥⎥ ⎢⎢𝑥1 ⎥⎥ ⎢⎢0⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎢ ⎥ ⎢ ⎥
⎣𝑥′ ⎦ ⎣−5 1.5⎥⎦ ⎢⎣𝑥 ⎥⎦ + ⎢⎣4⎥⎦ cos (𝑡)
2 2

325
4.5. Solve non-homogeneous 2nd order . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica Matlab

Remove["Global`*"]; function e55


eq = y''[t]-15/10y'[t]+5y[t]==4 Cos[t t0 = 0; %initial time
]; tf = 10; %final time
ic = {y'[0]==0,y[0]== 1}; %initial conditions [y(0) y
sol = First@DSolve[{eq,ic},y[t],t]; '(0)]
ic =[1 0]';
1 √71𝑡 √71𝑡
5183
(−1704 sin(𝑡) sin2 � 4
� +69√71𝑒3𝑡/4 sin �
4
�+
√71𝑡 √71𝑡
[t,y] = ode45(@rhs, [t0 tf], ic
4544 cos(𝑡) cos2 � 4
� + 639𝑒3𝑡/4 cos � 4
� − );
√71𝑡 √71𝑡
1704 sin(𝑡) cos2 � 4
� + 4544 sin2 � 4
� cos(𝑡)))
plot(t,y(:,1),'r')
Plot[y,{t,0,10}, title('Solution using ode45');
FrameLabel->{{"y(t)",None}, xlabel('time');
{"t","Solution"}}, ylabel('y(t)');
Frame->True, grid on
GridLines->Automatic, set(gcf,'Position'
GridLinesStyle->Automatic, ,[10,10,320,320]);
RotateLabel->False,
ImageSize->300, function dydt=rhs(t,y)
AspectRatio->1, dydt=[y(2) ;
PlotRange->All, -5*y(1)+1.5*y(2)+4*cos
PlotStyle->{Thick,Red}] (t)];
end
Solution
end
200

Solution using ode45


200
150

150
100
100
y(t)
50
y(t)

50

0 0

-50
-50
-100
0 2 4 6 8 10 0 2 4 6 8 10
time
t

326
4.6. Solve homogeneous 2nd order ODE, . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.6 Solve homogeneous 2nd order ODE, constant


coefficients (BVP)
Problem: Solve
𝑦′′ (𝑡) + 𝑡 𝑦 (𝑡) = 0
with the boundary conditions
𝑦 (0) = 3, 𝑦 (20) = −1
For solving with Matlab, the ODE is first converted to state space as follows
Given 𝑦′′ (𝑡) + 𝑡 𝑦 (𝑡) = 0, let

𝑥1 = 𝑦
𝑥2 = 𝑦′
= 𝑥′1

Therefore
𝑥′1 = 𝑥2
And

𝑥′2 = 𝑦′′
= −𝑡 𝑦
= −𝑡 𝑥1

This results in ⎡ ⎤ ⎡ ⎤⎡ ⎤
⎢⎢𝑥′1 ⎥⎥ ⎢⎢ 0 1⎥⎥ ⎢⎢𝑥1 ⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎢ ⎥
⎣𝑥′ ⎦ ⎣−𝑡 0⎥⎦ ⎢⎣𝑥 ⎥⎦
2 2

Now bvp4c() can be used.


Mathematica

Clear[y,t];
eq = y''[t]+t y[t]==0;
ic = {y[0]==3,y[20]==-1};
sol = First@DSolve[{eq,ic},y[t],t];

y = y[t]/.sol

3 3 2 3 3 2 3 3
−√3Ai �√−1𝑡� + Bi �√−1𝑡� − 3 32/3 Γ � 3 � Bi �20√−1� Ai �√−1𝑡� + 3 32/3 Γ � 3 � Ai �20√−1� Bi �√−1𝑡�
3 3
√3Ai �20√−1� − Bi �20√−1�

327
4.6. Solve homogeneous 2nd order ODE, . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Plot[Re[y],{t,0,20},
FrameLabel->{{"y(t)",None},
{"t","Solution"}},
Frame->True,
GridLines->Automatic,
GridLinesStyle->Automatic,
RotateLabel->False,
ImageSize->300,
AspectRatio->1,
PlotRange->All,
PlotStyle->{Thick,Red},
Exclusions->None]

Solution

y(t)
0

-1

-2

0 5 10 15 20
t

328
4.6. Solve homogeneous 2nd order ODE, . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Matlab

function e56

t0 = 0; %initial time
tf = 20; %final time

solinit = bvpinit(linspace(t0,tf,5),[3 -1]);

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

329
4.7. Solve the 1-D heat partial differential . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.7 Solve the 1-D heat partial differential equation


(PDE)
The PDE is

𝜕𝑇 (𝑥, 𝑡) 𝜕 2 𝑇 (𝑥, 𝑡)
=𝑘
𝜕𝑡 𝜕𝑥2

Problem: given a bar of length 𝐿 and initial conditions 𝑇 (𝑥, 0) = sin (𝜋𝑥) and boundary
conditions 𝑇 (0, 𝑡) = 0, 𝑇 (𝐿, 𝑡) = 0, solve the above PDE and plot the solution on 3D.
Use bar length of 4 and 𝑘 = 0.5 and show the solution for 1 second.

330
4.7. Solve the 1-D heat partial differential . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica

Clear[y,x,t];
barLength = 4;
timeDuration = 1;
eq = D[y[x, t], t] == k*D[y[x, t],
x, x];
eq = eq /. k -> 0.5;
boundaryConditions = {y[0,t]==0,
y[barLength,t
]==0};
initialConditions = y[x,0]==Sin[Pi
x];
sol=First@NDSolve[{eq,
boundaryConditions,
initialConditions},
y[x,t],{x,0,barLength},{t,0,
timeDuration}];
y = y[x,t]/.sol
Plot3D[y,{x,0,barLength},{t,0,
timeDuration},
PlotPoints->30,PlotRange->All,
AxesLabel->{"x","time","T[x,t]"},
ImageSize->300]

ContourPlot[y,{x,0,barLength},
{t,0,timeDuration},PlotPoints
->15,
Contours->15,ContourLines->False,

ColorFunction->Hue,PlotRange->
All,
ImageSize->300]

331
4.7. Solve the 1-D heat partial differential . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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;

332
4.8. Show the effect of boundary/initial . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.8 Show the effect of boundary/initial conditions on


1-D heat PDE
The PDE is
𝜕𝑇 (𝑥, 𝑡) 𝜕 2 𝑇 (𝑥, 𝑡)
=𝑘
𝜕𝑡 𝜕𝑥2
Problem: given a bar of length 𝐿 , solve the above 1-D heat PDE for 4 different boundary/ini-
tial condition to show that the solution depends on these.
Mathematica
 

Clear[y,x,t,k];
SetDirectory[NotebookDirectory[]];
barLength = 4*Pi;
timeDuration = 10;
eq = D[y[x, t], t] == k*D[y[x, t], x, x];
eq = eq /. k -> 0.5;
solveHeat[eq_,bc_,ic_,y_,x_,t_,len_,timeDuration_]:=Module[{sol},
sol=First@NDSolve[{eq,bc,ic},y[x,t],{x,0,len},{t,0,timeDuration}];
Plot3D[y[x,t]/.sol,{x,0,barLength},{t,0,timeDuration},PlotPoints->30,
PlotRange->All,AxesLabel->{"x","time","y[x,t]"},ImageSize->200,
PlotLabel->bc]
];

bc={{y[0,t]==1,y[barLength,t]==1},
{y[0,t]==0,y[barLength,t]==0},{y[0,t]==1,y[barLength,t]==Exp[-t barLength
]},{y[0,t]==0,y[barLength,t]==0}
};

ic={y[x,0]== Cos[x],
y[x,0]==Sin[x],
y[x,0]==1,
y[x,0]== Cos[x]Sin[x]
};

sol=MapThread[solveHeat[eq,#1,#2,y,x,t,barLength ,timeDuration]&,{bc,ic}];
Grid[Partition[sol,2],Frame->All]
Export["images/mma_e58_1.pdf",%]
 

Each plot shows the boundary conditions used.

333
4.8. Show the effect of boundary/initial . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

334
4.9. Find particular and homogenous . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.9 Find particular and homogenous solution to


undetermined system of equations
Problem: Find the general solution to 𝐴𝑥 = 𝑏

⎡ ⎤
⎡ ⎤ ⎢⎢𝑥1 ⎥⎥ ⎡ ⎤ ⎡ ⎤ ⎡ ⎤
⎢⎢2 4 6 4⎥⎥ ⎢⎢⎢ ⎥⎥⎥ ⎢⎢𝑏1 ⎥⎥ ⎢⎢𝑏1 ⎥⎥ ⎢⎢4⎥⎥
⎢⎢ ⎥⎥ ⎢⎢𝑥2 ⎥⎥ ⎢⎢ ⎥⎥ ⎢ ⎥ ⎢ ⎥
⎢⎢2 5 7 6⎥⎥ ⎢⎢ ⎥⎥ = ⎢⎢𝑏 ⎥⎥ 𝑤ℎ𝑒𝑟𝑒 ⎢⎢⎢𝑏 ⎥⎥⎥ = ⎢⎢⎢3⎥⎥⎥
⎢⎢ ⎥⎥ ⎢⎢𝑥 ⎥⎥ ⎢⎢ 2 ⎥⎥ ⎢⎢ 2 ⎥⎥ ⎢⎢ ⎥⎥
⎣ ⎦ ⎢⎢ 3 ⎥⎥ ⎣ ⎦ ⎣ ⎦ ⎣ ⎦
2 3 5 2 ⎣ ⎦ 𝑏3 𝑏3 5
𝑥3

In Maple 11, the LinearAlgebra package was used. In Mathematica one can also get the
general solution, 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.

335
4.9. Find particular and homogenous . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica

vars = {x1,x2,x3,x4};
eqs ={2 x1+4 x2+6 x3+4 x4==4, ⎛ ⎞
2 x1+5 x2+7 x3+6 x4==3, ⎜⎜ 2 4 6 4 ⎟⎟
⎜⎜ ⎟
⎜⎜ 2 5 7 6 ⎟⎟⎟
2 x1+3 x2+5 x3+2 x4==5}; ⎜⎜ ⎟⎟
⎝ ⎠
2 3 5 2
{b,mat} = CoefficientArrays[eqs,vars];
Normal[mat]

Normal[b] Out[163]= {-4,-3,-5}

Mathematica LinearSolve gives one solution (partic-


ular solution) Out[164]= {-4,1,0,0}
particularSolution = LinearSolve[mat,b]

find the homogenous solution (nullspace) and add it ⎛ ⎞


to the above particular solution ⎜⎜ 2 −1 ⎟⎟
⎜⎜ ⎟
⎜⎜ −2 −1 ⎟⎟⎟
homogenousSolution =Transpose[NullSpace[ ⎜⎜ ⎟⎟
⎜⎜ ⎟
mat]] ⎜⎜ 0 1 ⎟⎟⎟
⎜⎝ ⎟⎠
1 0

Add the particular solution to the homogenous solu- ⎛ ⎞


tion to get the general solution ⎜⎜ −2 −5 ⎟⎟
⎜⎜ ⎟
⎜⎜ −1 0 ⎟⎟⎟
fullSolution = particularSolution+ ⎜⎜ ⎟⎟
⎜⎜ ⎟
homogenousSolution ⎜⎜ 0 1 ⎟⎟⎟
⎜⎝ ⎟⎠
1 0

To obtain the general solution right away Solve can


be used instead
sol = Flatten[Solve[eqs,vars]]

During evaluation of �x3 → −


x1

x2 3
+ 2 , x4 →
x1

x2 5
− 4�
2 2 4 4
In[167]:= Solve::svars: Equations may
not give solutions for all
"solve" variables. >>

generalSolution = vars/.sol x1 x2 3 x1 x2 5
�x1, x2, − 2
− 2
+ 2, 4
− 4
− 4�
336
4.9. Find particular and homogenous . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Matlab
Warning: Rank deficient,
rank = 2, tol = 4.033641e-15.
clear all;
A=[2 4 6 4; particularSolution =
2 5 7 6;
2 3 5 2] 0
0
b=[4 3 5]' 1.5000
particularSolution=A\b -1.2500

nullSolution =

-1 2
nullSolution=null(A,'r')
-1 -2
1 0
0 1

337
4.9. Find particular and homogenous . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Maple

restart;
⎡ ⎤
with(LinearAlgebra); ⎢⎢ 2 4 6 4 ⎥⎥
vars := x[1], x[2], x[3], x[4]; ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
sys := 2*x[1]+4*x[2]+6*x[3]+4*x[4] 𝐴 = ⎢⎢ 2 5 7 6 ⎥⎥⎥

⎢⎢ ⎥⎥
= 4, ⎢⎣ ⎥⎦
2 3 5 2
2*x[1]+5*x[2]+7*x[3]+6*x[4]
= 3,
⎡ ⎤
2*x[1]+3*x[2]+5*x[3]+2*x[4] ⎢⎢ 4 ⎥⎥
⎢⎢ ⎥⎥
= 5; ⎢⎢ ⎥⎥
𝑏 = ⎢⎢⎢ 3 ⎥⎥⎥
⎢⎢ ⎥⎥
`eqs=`, convert([sys], Vector); ⎢⎣ ⎥⎦
5
A, b := GenerateMatrix([sys], [vars
])

⎡ ⎤
⎢⎢ 4 − 𝑥3 + 2 𝑥4 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
`general solution=`, ⎢⎢ −1 − 𝑥 − 2 𝑥 ⎥⎥
⎢⎢ 3 4 ⎥⎥
LinearSolve(A, b, free = 'x') ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ 𝑥3 ⎥⎥
⎢⎢ ⎥⎥
⎢⎣ ⎥⎦
𝑥4

WARNING: Maple sometimes reorders the


result from solve() so we can get a differ-
Can solve this system to get the general so- ent ordering of the free variables as shown
lution using the solve command as follows above.
s := solve([sys], [vars]); ⎡ ⎤
r := subs(op(s), [vars]); ⎢⎢ 4 − 𝑥3 + 2 𝑥4 ⎥⎥
⎢⎢ ⎥⎥
⎢⎢ ⎥
`general solution=`, convert(%, ⎢⎢ −1 − 𝑥 − 2 𝑥 ⎥⎥⎥
⎢⎢ 3 4 ⎥
⎥⎥
Vector) ⎢⎢ ⎥
⎢⎢ ⎥⎥
⎢⎢ 𝑥3 ⎥⎥
⎢⎢ ⎥⎥
⎢⎣ ⎥⎦
𝑥4

338
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.10 Plot the constant energy levels for a nonlinear


pendulum
Problem:
Plot the constant energy levels for the nonlinear pendulum in 𝜃, 𝜃̇

Pendulum

Assume that 𝑚 = 1, 𝑔 = 9.8𝑚/𝑠2 , 𝐿 = 10𝑚


Answer:
The constant energy curves are curves in the Y-X plane where energy is constant. The Y-axis
represents 𝜃̇ , and the X-axis represents 𝜃
We assume the pendulum is given an initial force when in the initial position (𝜃 = 00 ) that
will cause it to swing anticlock wise. The pendulum will from this point obtain an energy
which will remain constant since there is no damping.
The higher the energy the pendulum posses, the larger the angle 𝜃 it will swing by will be.
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 𝐸 for the pendulum is first derived as a function of 𝜃, 𝜃̇

𝐸 = 𝑃𝐸 + 𝐾𝐸
1
= 𝑚𝑔𝐿 (1 − cos 𝜃) + 𝑚𝐿2 𝜃̇ 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.

339
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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 𝑚 = 1, 𝑔 = 9.8𝑚/𝑠2 , 𝐿 = 10𝑚
Mathematica
 
SetDirectory[NotebookDirectory[]];
energy[theta_, speed_, m_, g_, len_] := m*g*len*(1 - Cos[theta]) + (1/2)*m*
len^2*speed^2;
m = 1; g = 9.8; len = 10;
data = Table[energy[i, j, m, g, len], {j, -4, 4, 0.01}, {i, -3*Pi, 3*Pi,
Pi/20.}];
ListContourPlot[data, InterpolationOrder -> 2, Contours -> 20,
MaxPlotPoints -> 30,
DataRange -> {{-3*Pi, 3*Pi}, {-4, 4}},
FrameTicks -> {{{-4, -3, -2, 0, 1, 2, 3, 4}, None},
{{-3*Pi, -2*Pi, -Pi, 0, Pi, 2*Pi, 3*Pi}, None}},
FrameLabel -> {{"\[Theta]'(t)", None},
{"\[Theta](t)", "constant energy levels for nonlinear pendulum model"
}}, ImageSize -> 400,
LabelStyle -> 14, RotateLabel -> False]
 

Matlab

340
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

 
function HW2
%HW2 problem. MAE 200A. UCI, Fall 2005
%by Nasser Abbasi

%This MATLAB function generate the constant energy level


%curves for a nonlinear pendulum with no damping

close all; clear;


m=1; g=9.8; L=10;

%number of data points (positio vs speed) to find per curve


nPoints=40;

nEnergyLevels = 8; %number of energy levels


lowAnglesToVisit = linspace(0,pi,nEnergyLevels);
lowEnergyLevels(1:nEnergyLevels)=m*g*L*(1-cos(lowAnglesToVisit));
highAnglesToVisit = linspace(pi,2*pi,2*nEnergyLevels);
highEnergyLevels=zeros(1,2*nEnergyLevels);

initialHighEnergy=2*m*g*L;
Q=0.2;
for i=1:2*nEnergyLevels
highEnergyLevels(i) = initialHighEnergy+(Q*i*initialHighEnergy);
end

A = zeros(length(lowAnglesToVisit)+length(highAnglesToVisit),2);
A(:,1) = [lowAnglesToVisit highAnglesToVisit];
A(:,2) = [lowEnergyLevels highEnergyLevels];

[nAngles,~]=size(A);
data=zeros(nPoints,2);

for j=1:nAngles

currentAngle=A(j,1);
currentEnergyLevel =A(j,2) ;
angles=linspace(0,currentAngle,nPoints);
data(1:nPoints,1)=angles(:);

for m=1:nPoints
data(m,2)=speed(currentEnergyLevel,angles(m));
end
doPlots(data);
end
341
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

title(sprintf(['constant energy curves, nonlinear pendulum,'...


'quantum=%1.3f'],Q));
xlabel('angle (position)');
ylabel('speed');
set(gca,'xtick',[-4*pi,-3*pi,-2*pi,-pi,0,pi,2*pi,3*pi,4*pi]);
set(gca,'XTickLabel',{'-4pi','-3pi','-2pi','-pi',...
'0','pi','2pi','3pi','4pi'})

print(gcf, '-dpdf', '-r600', 'images/matlab_e77_1');

function s=speed(energy,angle)
m=1; g=9.8; L=10;
if angle<pi
s=sqrt(2/(m*L^2)*(energy-m*g*L*(1-cos(angle))));
else
s=sqrt(2/(m*L^2)*(energy-m*g*L*(1+cos(angle-pi))));
end

function doPlots(data)
plotCurves(data,0);
plotCurves(data,2*pi);
plotCurves(data,-2*pi);

function plotCurves(data,k)
plot(data(:,1)+k,data(:,2));
hold on;
plot(data(:,1)+k,-data(:,2));
plot(-data(:,1)+k,-data(:,2));
plot(-data(:,1)+k,data(:,2));
 

342
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

constant energy curves, nonlinear pendulum, quantum=0.200


5

speed 0

-1

-2

-3

-4

-5
-4pi -3pi -2pi -pi 0 pi 2pi 3pi 4pi
angle (position)

Maple

The Maple solution was contributed by Matrin Eisenberg


 
restart;
plotEnergyLevels:= proc(m::positive, g::positive, L::positive, Erange::
positive, numContours::posint)
local plotOptions, maxTheta, thetaDot, plotContour, Emax, energies,
contours;
plotOptions := args[6..-1];
maxTheta := E- arccos(max(1-E/m/g/L, -1));
thetaDot := E- theta- sqrt(max(2/m/L^2 * (E - m*g*L*(1-cos(theta))), 0))
;
plotContour := E- plot(thetaDot(E), 0..maxTheta(E), numpoints=5,
plotOptions);

# Create first quadrant of middle region of the graph.


Emax := Erange*m*g*L;
energies := {Emax * n/numContours $ n=1..numContours};
if Erange 2 then energies := energies union {2*m*g*L}; fi;
contours := map(plotContour, energies);

# Create other quadrants.


map2(rcurry, plottools[reflect], {[[0,0],[0,1]], [0,0], [[0,0],[1,0]]});

contours := contours union map(f- map(f, contours)[], %);

# Create left and right regions of the graph.


343
4.10. Plot the constant energy levels for a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

map2(rcurry, plottools[translate], {-2*Pi,2*Pi}, 0);


contours := contours union map(f- map(f, contours)[], %);

# Complete the graph.


plots[display]([%[], plot([[-2*Pi,0], [0,0], [2*Pi,0]], plotOptions,
style=point)],
view=[-3*Pi..3*Pi, -thetaDot(Emax)(0)..thetaDot(Emax)(0)],
title="Constant energy levels, undamped pendulum",
labels=["angle", "angular speed"],
xtickmarks=[seq](evalf(k*Pi)=sprintf("%a pi", k), k=-3..3));
end:
plotEnergyLevels(1, 9.8, 10, 5, 15);

;
 

344
′′′′
4.11. Solve numerically the ODE 𝑢 + 𝑢 = . . . CHAPTER 4. DIFFERENTIAL, PDE . . .


4.11 Solve numerically the ODE 𝑢 + 𝑢 = 𝑓 using point
collocation method
Problem: Give the ODE
𝑑4 𝑢 (𝑥)
+ 𝑢 (𝑥) = 𝑓
𝑑𝑥4
Solve numerically using the point collocation method. Use 5 points and 5 basis functions.
Use the Boundary conditions 𝑢 (0) = 𝑢 (1) = 𝑢′′ (0) = 𝑢′′ (1) = 0
Use the trial function
𝑁=5
𝑖
𝑔 (𝑥) = � 𝑎𝑖 (𝑥 (𝑥 − 1))
𝑖=1
Use 𝑓 = 1
𝑁=5
The solution is approximated using 𝑢 (𝑥) ≈ 𝑔 (𝑥) = � 𝑎𝑖 (𝑥 (𝑥 − 1))𝑖 .
𝑖=1

𝑁 equations are generated for 𝑁 unknowns (the unknowns being the undetermined coeffi-
cients of the basis functions). This is done by setting the error to zero at those points. The
error being
𝑑4 𝑔 (𝑥)
+ 𝑔 (𝑥) − 𝑓
𝑑𝑥4
Once 𝑔 (𝑥) (the trial function is found) the analytical solution is used to compare with the
numerical solution.
Mathematica

Clear["Global`*"];
nBasis = 5;
nPoints = 5;
a = Array[v,{nBasis}]

Out[392]= {v[1],v[2],v[3],v[4],v[5]}

trial = Sum[a[[n]] (x(x-1))^n,{n,1,nBasis}];


residual = D[trial,{x,4}]+trial-1;
mat = Flatten[Table[residual==0/.x->n/(2*nPoints-1),
{n,1,nPoints-1}]];

mat = Join[mat,{2 a[[1]]+2a[[2]]==0}];


sol = N@First@Solve[mat,a]

Out[397]= {v[1.]->-0.0412493,
v[2.]->0.0412493,
v[3.]->0.000147289,
v[4.]->-0.0000245233,
345
′′′′
4.11. Solve numerically the ODE 𝑢 + 𝑢 = . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

v[5.]->-3.28259*10^-8}

numericalSolution=Chop@
FullSimplify@Sum[sol[[n,2]](x(x-1))^n,
{n,1,nBasis}]

numericalSolutionDiff4 = D[numericalSolution,{x,4}];
numericalMoment = D[numericalSolution,{x,2}];

0.0412493𝑥 − 0.0826459𝑥3 + 0.0416667𝑥4 − 0.00034374𝑥5 − 1.51283 ∗ 10− 8𝑥6


+0.0000984213𝑥7 − 0.0000248515𝑥8 + 1.64129 ∗ 10− 7𝑥9 − 3.28259 ∗ 10− 8𝑥1 0

(*now analytical solution is obtained


using DSolve and compared to numerical solution*)
eq = u''''[x]+u[x]==1;
bc = {u[0]==0,u[1]==0,u''[0]==0,u''[1]==0};
analyticalSolution=First@DSolve[{eq,bc},u[x],x];
analyticalSolution=u[x]/.analyticalSolution;
analyticalSolution=FullSimplify[analyticalSolution]

1−(1+𝑖)𝑥 1−(1−𝑖)𝑥 1−(1+𝑖)𝑥 1−(1−𝑖)𝑥 1 1


cos � � + cos � � + cosh � � + cosh � � − 2 �cos � � + cosh � ��
√2 √2 √2 √2 √2 √2

1 1
2 �cos � � + cosh � ��
√2 √2

analyticalMoment = D[analyticalSolution,{x,2}];

1−(1+𝑖)𝑥 1−(1−𝑖)𝑥 1−(1+𝑖)𝑥 1−(1−𝑖)𝑥


−𝑖 cos � � + 𝑖 cos � � + 𝑖 cosh � � − 𝑖 cosh � �
√2 √2 √2 √2

1 1
2 �cos � � + cosh � ��
√2 √2
dispError[pt_] :=
((analyticalSolution-numericalSolution)/.x->pt)/
(analyticalSolution/.x->.5)

momentError[pt_]:=
((analyticalMoment-numericalMoment)/.x->pt)/
(analyticalMoment/.x->.5)

(*Now the percentage displacement


and moment errors are plotted*)
Plot[dispError[z],{z,0,1},
346
′′′′
4.11. Solve numerically the ODE 𝑢 + 𝑢 = . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

ImagePadding->70,
ImageSize->400,
Frame->True,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotStyle->Red,
FrameLabel->{{"error",None},
{"x","percentage displacement error"}},
LabelStyle->14]

percentage displacement error

1.5 × 10-10

1. × 10-10

5. × 10-11

0
0.0 0.2 0.4 0.6 0.8 1.0
x

Plot[momentError[z],{z,0,1},
ImagePadding->70,
ImageSize->400,
Frame->True,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotStyle->Red,
FrameLabel->{{"error",None},
{"x","percentage moment error"}},
LabelStyle->14,PlotRange->All]

percentage moment error


-10
1.5 × 10

1. × 10-10

5. × 10-11

0
0.0 0.2 0.4 0.6 0.8 1.0
x

347
′′′′
4.11. Solve numerically the ODE 𝑢 + 𝑢 = . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

(*Now the Residual error distribution


over x is plotted*)
Plot[Abs[numericalSolutionDiff4+
numericalSolution-1],{x,0,1},
ImagePadding->80,
ImageSize->400,
Frame->True,
GridLines->Automatic,
GridLinesStyle->Dashed,
PlotStyle->Red,
FrameLabel->{{"error",None},
{"x","Residual error distribution over x"}},
LabelStyle->14,
PlotRange->All]

Residual error distribution over x

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

348
′′′′
4.11. Solve numerically the ODE 𝑢 + 𝑢 = . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Maple
 
#Solve u''''+u=1 using point collocation. Zero B.C.
#written by Nasser Abbasi for fun on April 25,2006.
restart;
Digits:=15;
nBasis := 5:
nPoints := 5:
coef := [seq(a[i],i=1..nBasis)]:
g := (x,n)-coef[n]*(x*(x-1))^n: #basis function
f := x-sum(g(x,k),k=1..nBasis): #trial function
moment := x-diff(f(x),x$2):
residual := x-diff(f(x),x$4)+f(x)-1:
A := seq(subs(x=N/(2*nPoints-1),residual(x)=0),N=1..nPoints-1):
A := A,2*(coef[1]+coef[2]=0):
sol := solve([A],coef):
coef := map(rhs,sol[1]):
evalf(coef):
numericalSolution:=x-sum(coef[n]*(x*(x-1))^n ,n=1..nBasis):
`The numerical solution is `, numericalSolution(x);
numericalSolutionMoment := x-diff(numericalSolution(x),x$2):

#Now obtain exact solution from Maple


eq := diff(W(x),x$4)+W(x)=1:
bc := W(0)=0,W(1)=0,D(D(W))(0)=0,D(D(W))(1)=0:

exact := unapply(rhs(dsolve({eq,bc})),x):

exactMoment := x-diff(exact(x),x$2):

displacmentError := x-(exact(x)-numericalSolution(x))/exact(.5):
momentError := x- (exactMoment(x)-numericalSolutionMoment(x))/evalf(subs(
x=.5,exactMoment(x))):

plot(displacmentError(x),x=0..1,labels=['x',"Disp. error %"]);


plot(momentError(x),x=0..1,labels=['x',"Moment error %"]);
 

349
4.12. How to numerically solve a set of . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.12 How to numerically solve a set of non-linear


equations?
Numerically solve the following three equations for 𝑒, 𝑎, 𝑓

𝑒𝑞1 = 𝑟1 − 𝑎(𝑒 − 1)

𝑎3
𝑒𝑞2 = 𝑑𝑒𝑙𝑇 − (𝑒 ∗ sinh(𝑓) − 𝑓)
�𝜇
𝑒𝑞3 = 𝑟2 − 𝑎(𝑒 cosh(𝑓) − 1)

Mathematica
ClearAll[a, e, f]
delT = 5.215*60*60;
r1 = 200 + 6378;
r2 = 130000;
mu = 3.986*10^5; {{a->12029.39633,
eq1 = r1 - a*(e - 1) == 0; e->1.546827108,
eq2 = delT - Sqrt[a^3/mu]* f->2.721303232}}
(e*Sinh[f] - f) == 0;

eq3 = r2 - a*(e*Cosh[f]-1)==0;
sol = NSolve[{eq1, eq2, eq3},
{a, e, f}, Reals]

350
4.12. How to numerically solve a set of . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Matlab

clear all
syms a e f;
delT = 5.215*60*60;
r1 = 200+6378;
r2 = 130000; ans =
mu = 3.986*10^5; [a == 12029.4, e ==
eq1 = r1 - a*(e-1); 1.54683, f == 2.7213]
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)

sol =
a: [1x1 sym]
e: [1x1 sym]
f: [1x1 sym]

sol.a
12029.396328714435126444927089827
Another option is solve but slower
sol = solve(eq1,eq2,eq3,a,e,f);
sol.e
1.5468271075497087492979481526009

sol.f
2.7213032317471583123822097902877

351
4.13. Solve 2nd order ODE (Van Der Pol) . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.13 Solve 2nd order ODE (Van Der Pol) and generate
phase plot
Problem: Solve
𝑦′′ (𝑡) − 𝜇 �1 − 𝑦2 � 𝑦′ (𝑡) + 𝑦 (𝑡) = 0
for different values of 𝜇 to compare effect of changing 𝜇 on the solution trajectories. The
initial conditions are

𝑦 (0) = 0.1
𝑦′ (𝑡) = 0

In both Mathematica and Matlab, numerical ODE solver was used.


For Matlab, The 2nd order ODE is first converted to 2 first order ODE’s, and then solve
the coupled ODE’s using ode45. In Mathematica NDSolve was used. This does not require
the conversion.
Starting by writing the 2nd order ODE as 2 first order ODE’s
⎫ ⎫ ⎫
⎪ ′ ⎪ ′ ⎪
𝑥1 = 𝑦 ⎪⎬ 𝑥1 = 𝑦 ′ ⎪
⎬ 𝑥1 = 𝑥2 ⎪

⎪derivatives⇒ ′ ⎪ ⇒ ′ ⎪
𝑥2 = 𝑦′ ⎪ ⎪ ⎪
′′
⎭ 𝑥2 = 𝑦 ⎭ 𝑥2 = 𝜇 �1 − 𝑥21 � 𝑥2 + 𝑥1 ⎭

Below is the solution of the differential equation for different values of 𝜇 = 1

352
4.13. Solve 2nd order ODE (Van Der Pol) . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica

process[mu_]:=Module[
{sol,p1,p2,p3,data,system,z,x1,
x2,t,ode1,ode2,timeScale},
ode1 =x1'[t]==x2[t];
ode2 =x2'[t]==z(1-x1[t]^2)x2[t]-x1[t];
timeScale ={t,0,80};
sol=First@NDSolve[
{ode1,ode2/.z->mu,x1[0]==0.01,x2[0]==0},
{x1[t],x2[t]},
timeScale,Method->{"Extrapolation",
Method->"LinearlyImplicitEuler"}];
sol = {x1[t],x2[t]}/.sol;
p1 = Plot[Evaluate[sol[[1]]],
Evaluate[timeScale],
Frame->True,
FrameLabel->{"time","y(t)"},
PlotLabel->"\[Mu]="<>ToString[mu]];
p2 = Plot[Evaluate[sol[[2]]],
Evaluate[timeScale],
Frame->True,
FrameLabel->{"time","y'(t)"},
PlotLabel->"\[Mu]="<>ToString[mu],
PlotStyle->RGBColor[1,0,0]];
data = Table[{evaluate[sol[[1]]],
Evaluate[sol[[2]]]},
Evaluate[timeScale]];
p3=ListPlot[data,Joined->True,Frame->True,
PlotLabel->"\[Mu]="<>ToString[mu],
FrameLabel->{"y(t)","y'(t)"},
PlotRange->All];
{p1,p2,p3}
];
mu={0.1,.2,1,3,5,10};
r = process/@mu; Grid[r]

353
4.13. Solve 2nd order ODE (Van Der Pol) . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

μ=0.1 μ=0.1 μ=0.1


0.4 0.3
0.2 0.4
0.3
0.2 0.1 0.2
0.1

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)

μ=0.2 μ=0.2 μ=0.2


2 2 2

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)

μ=1 μ=1 μ=1


2
2 2
1 1
1

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)

μ=3 μ=3 μ=3


2 2 4
1 1 y'(t)
2
y'(t)
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)

μ=5 μ=5 μ=5


2
1.0
5
1 0.5
y'(t)
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)

μ=10 μ=10 μ=10


2 0
0.4
1 -2
0.2
-4
y'(t)
y'(t)
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

time time y(t)

354
4.13. Solve 2nd order ODE (Van Der Pol) . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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)];

355
4.13. Solve 2nd order ODE (Van Der Pol) . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

mu=0.10 mu=0.10 mu=0.10

y'(t)

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)

0 time 0 time 0 y(t)


-5 -5 -5
mu=3.00 mu=3.00 mu=3.00
50 50 100 10 0 50 100 5-5 0 5
y'(t)

y'(t)
y(t)

0 time 0 time 0 y(t)


-5 mu=5.00 -10 mu=5.00 -5 mu=5.00
50 50 100 10 0 50 100 5-10 0 10
y'(t)

y'(t)
y(t)

0 time 0 time 0 y(t)


-5 mu=10.00 -10 mu=10.00 -5 mu=10.00
50 50 100 20 0 50 100 5-10 0 10
y'(t)

y'(t)
y(t)

0 time 0 time 0 y(t)


-5 -20 -5
0 50 100 0 50 100 -20 0 20
time time y(t)

356
4.14. How to numerically solve Poisson . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.14 How to numerically solve Poisson PDE on 2D


using Jacobi iteration method?
Problem: Solve ▽2 𝑢 = 𝑓(𝑥, 𝑦) on 2D using Jacobi method. Assume 𝑓(𝑥, 𝑦) = −e−(𝑥−0.25)
2 −(𝑦−0.6)2
.
Use mesh grid norm and relative residual to stop the iterations.

357
4.14. How to numerically solve Poisson . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mathematica

n = 21; (*number of grid points*)


uNew = Table[0, {n}, {n}]; (*solution grid*)
residual = uOld = uNew;

h = 1/(n - 1); (*spacing*)


c = 0.1; (*controls the tolerance*)
epsilon = c*h^2; (*error tolerance*)

grid = N@Table[{i*h,j*h},{i,0,n-1},{j,0,n-1}];

(*the force function*)


f[x_,y_] := -Exp[-(x - 0.25)^2 - (y - 0.6)^2];

(*evaluate force on the grid*)


force = Map[f[#[[1]],#[[2]]]&,grid,{2}];
normF = Sqrt[h]*Norm[Flatten@force,2];(*force norm*)
converged = False;

k = 0; (*iteration counter*)
While[Not[converged],
k++;
For[i = 2, i < n, i++,
For[j = 2, j < n, j++,
uNew[[i, j]] = (1/4)*(uOld[[i-1,j]]+uOld[[i+1,j]]
+ uOld[[i,j-1]]+uOld[[i,j+1]]-h^2*force[[i,j]]);

residual[[i,j]] = force[[i, j]]-1/h^2*(uOld[[i-1,j]]+


uOld[[i+1,j]]+uOld[[i,j-1]]+uOld[[i,j+1]]-4*uOld[[i,j]])
]
];
uOld = uNew; (*updated at end*)
normR = Sqrt[h] Norm[Flatten@residual, 2];
If[normR/normF < epsilon, converged = True]
];

(*plot solution*)
ListPlot3D[uOld, PlotRange -> All, ImagePadding -> 30,
ImageSize -> 400, Mesh -> {n, n},
AxesLabel -> {"x", "y", "u(x,y)"},
PlotRangePadding -> 0, BaseStyle -> 12,
PlotLabel -> Row[{"Converged in ", k, " iterations",
" ,epsilon=", epsilon, " ,h=", h}]]

358
4.14. How to numerically solve Poisson . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

359
4.14. How to numerically solve Poisson . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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 );

h = 1/(n-1); % grid spacing


tol = c * h^2; % tolerance
res = zeros(n,n); % storage for residual
u = res; % storage for solution
uNew = u;
k = 0; % loop counter
[X,Y] = meshgrid(0:h:1,0:h:1); % coordinates
f = myforce(X,Y);
normf = norm( f(:),2); % find norm

%Now start the iteration solver, stop when


%relative residual < tolerance
figure;
i = 2:n-1;
j = 2:n-1; %the iterations vectorized
done = false;

while ~done
k = k+1;

uNew(i,j) = (1/4)*( u(i-1,j) + u(i+1,j) + ...


u(i,j-1) + u(i,j+1) - h^2 * f(i,j) );
res(i,j) = f(i,j) - (1/h^2)*( u(i-1,j) + ...
u(i+1,j) + u(i,j-1) + u(i,j+1) - 4*u(i,j) );

%uncomment to see it update as it runs

%mesh(X,Y,u); %hold on;


%title(sprintf('solution at iteration %d',k));
%zlim([0,.07]);
%drawnow;

if norm(res(:),2)/normf < tol


done = true;
end;

u = uNew;
end
360
mesh(X,Y,u);
title(sprintf('solution at iteration %d',k))
4.14. How to numerically solve Poisson . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

solution at iteration 655

0.08

0.06

0.04

0.02

0
1
1
0.8
0.5 0.6
0.4
0.2
0 0

361
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.15 How to solve BVP second order ODE using finite


elements with linear shape functions and using
weak form formulation?
Solve 𝑦″ (𝑥) − 3𝑦(𝑥) = −𝑥2 over 𝑥 = 0 … 1 with boundary conditions 𝑥(0) = 0 and 𝑥(1) = 0 using
piecewise linear trial functions.
solution
̂
Let the trial function be the linear function 𝑦(𝑥) = 𝑐1 𝑥+𝑐2 . The residual is 𝑅 = 𝑦̂ ″ (𝑥)−3𝑦(𝑥)+𝑥
̂ 2.

Let the test function be 𝑤(𝑥). We need to solve for each element 𝑖 the following equation

𝐼𝑖 = � 𝑤𝑖 𝑅𝑖 𝑑𝑥

Using the weak form, we apply integration by parts to obtain


𝑥𝑖+1 𝑥𝑖+1
𝑑𝑤 𝑑𝑦̂ 𝑑𝑦̂
𝐼𝑖 = � − ̂ + 𝑤(𝑥)𝑥2 𝑑𝑥 + �𝑤(𝑥) �
− 3𝑤(𝑥)𝑦(𝑥)
𝑥𝑖 𝑑𝑥 𝑑𝑥 𝑑𝑥
𝑥𝑖
=0 (96.1)

or
𝑖=𝑀
𝐼 = � 𝐼𝑖
𝑖=1
⎛ ⎞
𝑖=𝑀 𝑥𝑖+1 ⎜⎜ 𝑑𝑤 𝑑𝑦̂ 𝑥𝑖+1 ⎟
⎜⎜− 𝑑𝑦̂ ⎟
= �� ⎜⎝ ̂ + 𝑤(𝑥)𝑥2 𝑑𝑥 + �𝑤(𝑥) � ⎟⎟⎟
− 3𝑤(𝑥)𝑦(𝑥)
𝑥𝑖 𝑑𝑥 𝑑𝑥 𝑑𝑥 ⎠
𝑖=1 𝑥𝑖
=0

Where 𝑀 is the number of elements. The above is the 𝑀 equations we need to solve for the
unknowns 𝑦𝑖 at the internal nodes. In Galerkin method, the test function is 𝑤1 (𝑥) = 𝐻1 (𝑥)
̂
𝑑𝑦(𝑥)
and 𝑤2 (𝑥) = 𝐻2 (𝑥) which comes from writing 𝑤𝑖 (𝑥) = 𝑑𝑦
𝑖

̂
Rewriting the trial function 𝑦(𝑥) in terms of unknown values at nodes results in

̂
𝑦(𝑥) = 𝐻1 (𝑥)𝑦𝑖 + 𝐻2 (𝑥)𝑦𝑖+1
𝑥𝑖+1 −𝑥 𝑥−𝑥𝑖
Where 𝐻1 (𝑥) = ℎ
and 𝐻2 (𝑥) = ℎ
where ℎ is the length of each element. Hence (96.1)
becomes
⎧ ⎫ ⎧ ⎫ ⎧ ⎫ ⎧ ⎫ ⎧ ⎫

⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ 𝑥
𝑥𝑖+1
⎨𝐻1′ (𝑥)⎪
⎬ ′ ′

⎨ 𝑦𝑖

⎬ ⎪
⎨ 𝐻1 (𝑥) ⎪
⎬ ⎪
⎨ 𝑦 𝑖

⎬ ⎪
⎨ 𝐻1 (𝑥) ⎪
⎬ 2 𝑑𝑦̂ 𝑖+1
𝐼𝑖 = � −⎪
⎪ ⎪ �𝐻1 (𝑥)𝐻2 (𝑥)� ⎪ ⎪ − 3⎪ ⎪ �𝐻1 (𝑥)𝐻2 (𝑥)� ⎪ ⎪+⎪ ⎪ 𝑥 𝑑𝑥 + �𝑤(𝑥) �
𝑥𝑖 ⎩𝐻2′ (𝑥)⎪
⎭ ⎪
⎩𝑦𝑖+1 ⎪
⎭ ⎪
⎩𝐻2 (𝑥)⎪ ⎭ ⎪
⎩𝑦𝑖+1 ⎪
⎭ ⎪
⎩𝐻2 (𝑥)⎪ ⎭ 𝑑𝑥
𝑥 𝑖
(96.2)

362
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

𝑥𝑖+1 1
𝑑𝑦̂ 𝑑𝑦̂
The terms �𝑤(𝑥) 𝑑𝑥 � reduce to �𝑤(𝑥) 𝑑𝑥 � since intermediate values cancel each other leaving
𝑥𝑖 0
the two edge values over the whole domain.
−𝑥 𝑥
But 𝐻1′ (𝑥) = ℎ
and 𝐻2′ (𝑥) = ℎ . Plugging these into (96.2) and integrating gives the following
⎡ ⎤⎧ ⎪

⎪ ⎡ 1⎤ ⎪
⎧ ⎫
⎪ ⎡ ⎤ 1
1 ⎢⎢−1 1 ⎥⎥ ⎨ 𝑦𝑖 ⎪
⎢ ⎥ ⎪ ⎬ ⎢⎢ 1
⎢⎢
⎥⎥ ⎪
2⎥
⎨ 𝑦𝑖 ⎪
⎬ 1 ⎢⎢⎢3𝑥4𝑖 − 4𝑥3𝑖 𝑥𝑖+1 + 𝑥4𝑖+1 ⎥⎥⎥ 𝑑𝑦̂
𝐼𝑖 = ⎢⎣ ⎥⎦ ⎪ ⎪ − ℎ ⎣1 ⎥⎦ ⎪ ⎪ + 12ℎ ⎢⎣ 𝑥4 − 4𝑥 𝑥3 + 3𝑥4 ⎥⎦ + �𝑤(𝑥) 𝑑𝑥 �
⎪ (96.3)
ℎ 1 −1 ⎪ ⎩𝑦𝑖+1 ⎪
⎭ 1 ⎪ ⎩𝑦𝑖+1 ⎭ 𝑖 𝑖 𝑖+1 𝑖+1
2 0

The algebra above was done with Mathematica. In the following code, 𝑥1 is 𝑥𝑖 and 𝑥2 is 𝑥𝑖+1

h1 = (x2 - x)/h;
h2 = (x - x1)/h;
int1 = -{{D[h1, x]}, {D[h2, x]}}.{{D[h1, x
], D[h2, x]}}; {{-(1/h), 1/h}, {1/h, -(1/h)}}
int2 = -3 {{h1}, {h2}}.{{h1, h2}};
int3 = {{h1}, {h2}} x^2;
sol1 = Integrate[int1, {x, x1, x2}];
sol1 /. {(x1 - x2) -> -h, (x2 - x1) -> h}

sol2 = Integrate[int2, {x, x1, x2}];


{{-h, -(h/2)}, {-(h/2), -h}}
sol2 /. {(x1 - x2) -> -h, (x2 - x1) -> h}

sol3 = Integrate[int3, {x, x1, x2}]; {{(3 x1^4 - 4 x1^3 x2 + x2^4)


Simplify[%]; /(12 h)},
% /. {(x1 - x2) -> -h, (x2 - x1) -> h} {(x1^4 - 4 x1 x2^3 + 3 x2^4)
/(12 h)}}

The above equation 𝐼𝑖 is calculated for each element 𝑖, resulting in 𝑀 equations where
𝑀 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 𝑦𝑖 as a system 𝐴𝑥 = 𝑓
using direct solver. The following code illustrates the method.

363
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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];

for i = 1:M %loop over all elements


x1 = (i-1)*h;
x2 = i*h;
f_local = -1/(12*h)*[3*x1^4-4*x1^3*x2+...
x2^4;x1^4-4*x1*x2^3+3*x2^4];
f(i:i+dof-1) = f(i:i+dof-1)+f_local;
kk(i:i+dof-1,i:i+dof-1) = ...
kk(i:i+dof-1,i:i+dof-1)+k_local;
end
%fix first and last rows since these are B.C.
kk(1,:) = 0;
kk(1,1) = 1;
kk(end,:) = 0;
kk(end,end) = 1;
f(1) = 0;
f(end) = 0;
y = kk\f; %solve

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

364
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

FEM solution using to ODE using 9 elements


0.035

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.
Mathematica

Analtical solution
ClearAll[y, x]
sol= y[x]/.First@DSolve[{y''[x]-3 y[x]==-x^2,
y[0] == 0, y[1] == 0}, y[x], x];
Plot[sol, {x, 0, 1}, Frame -> True,
FrameLabel -> {{"y(x)", None},
{"x", "analytical solution"}},
GridLines -> Automatic,
GridLinesStyle -> {{Dashed, LightGray},
{Dashed, LightGray}}
]

365
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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
m = 9;
n = m + 1;
dof = 2;
kk = Table[0., {n}, {n}];
f = Table[0., {n}];
h = 1/m;
kLocal = 1/h {{-1, 1}, {1, -1}} - h {{1, 1/2}, {1/2, 1}};
Do[
x1 = (i - 1) h;
x2 = i h;
fLocal = -1/(12 h) {3 x1^4 - 4 x1^3 x2 + x2^4,
x1^4 - 4 x1 x2^3 + 3 x2^4};
f[[i ;; i + dof - 1]] += fLocal;
kk[[i ;; i + dof - 1, i ;; i + dof - 1]] +=kLocal,
{i, m}
];
kk[[1, ;;]] = 0;
kk[[1, 1]] = 1;
kk[[-1, ;;]] = 0;
kk[[-1, -1]] = 1;
f[[1]] = 0;
f[[-1]] = 0;
y = LinearSolve[kk, f];
x = Range[0, 1, h];

ListPlot[Transpose[{x, y}], Frame -> True, Joined -> True,


PlotMarkers -> Automatic, FrameLabel ->
{{"y(x)", None}, {"x",
Row[{"solution to y''(x)-3 y(x)=-x^2 using FEM, 9 elements"}]}},

366
4.15. How to solve BVP second order ODE . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

GridLines -> Automatic,


GridLinesStyle -> LightGray
]

solution to y''(x)-3 y(x)=-x^2 using FEM, 9 elements



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

367
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16 How to solve Poisson PDE in 2D using finite


elements methods using rectangular element?
Solve ∇ 2 𝑢 = 𝑓 �𝑥, 𝑦� on square using FEM. Assume 𝑢 = 0 on boundaries and solve using
𝑓 �𝑥, 𝑦� = 𝑥𝑦 and also 𝑓 �𝑥, 𝑦� = 1 and 𝑓 �𝑥, 𝑦� = 3 �cos(4𝜋𝑥) + sin(3𝜋𝑦)�
Use Galerkin method and weak form, Using a bilinear trial function. Let width of square
be 1.
Solution
Using as an example with 9 elements to illustrate the method. The program below can be
called with different number of elements.

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

The trial function is bilinear

𝑢̃ = 𝑐1 + 𝑐2 𝑥 + 𝑐3 𝑦 + 𝑐4 𝑥𝑦 (1)

Looking at one element, and using local coordinates systems with element having width 2𝑎
and height 2𝑏 gives

368
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

a, b a, b
4 3

b
x
(0,0)
Local node
a numbers, always
increase anti-
clockwise
1 2
a, b a, b

Evaluating the trial function (1) at each corner node of the above element gives

𝑢̃ 1 = 𝑐1 − 𝑎𝑐2 − 𝑏𝑐3 + 𝑎𝑏𝑐4


𝑢̃ 2 = 𝑐1 + 𝑎𝑐2 − 𝑏𝑐3 − 𝑎𝑏𝑐4
𝑢̃ 3 = 𝑐1 + 𝑎𝑐2 + 𝑏𝑦3 + 𝑎𝑏𝑐4
𝑢̃ 4 = 𝑐1 − 𝑎𝑐2 + 𝑏𝑐3 + 𝑎𝑏𝑐4

Or

⎧ ⎫ ⎛ ⎞⎧ ⎫

⎪𝑢 ̃ ⎪
⎪ ⎜ 1 −𝑎 −𝑏 𝑎𝑏 ⎟⎟ ⎪⎪ 𝑐1 ⎪


⎪ 1⎪
⎪ ⎜⎜ ⎟ ⎪
⎪ ⎪


⎪ ⎪
⎪ ⎜
⎜ ⎟
⎟ ⎪
⎪ ⎪
𝑢 ̃
⎨ 2⎬ ⎜ ⎜ 1 𝑎 −𝑏 −𝑎𝑏 ⎟
⎟ ⎨ 2⎪
𝑐 ⎬
⎪ ⎪ = ⎜
⎜⎜ ⎟
⎟⎟ ⎪ ⎪

⎪ ⎪
𝑢̃ 3 ⎪ ⎜⎜1 𝑎 𝑏 𝑎𝑏 ⎟⎟ ⎪𝑐3 ⎪
⎪ ⎪
⎪ ⎪

⎪ ⎪ ⎜ ⎟ ⎪ ⎪


⎩𝑢̃ ⎭ ⎪ ⎝ ⎠ ⎪
⎩ ⎪

4 1 −𝑎 𝑏 𝑎𝑏 𝑐4

Hence

⎧ ⎫ ⎛ ⎞−1 ⎧ ⎫
⎪ ⎪ ⎜1 −𝑎 −𝑏 𝑎𝑏 ⎟⎟ ⎪ ⎪𝑢̃ 1 ⎪
⎪𝑐1 ⎪

⎪ ⎪
⎪ ⎜⎜ ⎟⎟ ⎪ ⎪



⎪ ⎪ ⎜ ⎪ ⎪
⎨𝑐2 ⎬ ⎜⎜⎜1 𝑎 −𝑏
⎪ ⎪ ⎟
−𝑎𝑏⎟⎟ ⎨𝑢̃ 2 ⎪
⎪ ⎬

⎪ ⎪ = ⎜⎜⎜ ⎟⎟ ⎪ ⎪

⎪ 𝑐3 ⎪

⎪ ⎜1 𝑎 𝑏 ⎟
𝑎𝑏 ⎟⎟ ⎪ ⎪ 𝑢̃ 3 ⎪


⎪ ⎪ ⎜⎜⎝ ⎟⎠ ⎪

⎪ ⎪

⎩𝑐 ⎪ ⎭ 1 −𝑎 𝑏 𝑎𝑏 ⎩ ⎪
𝑢̃ 4 ⎭
4
⎛ ⎞⎧ ⎫
⎜⎜ 𝑎𝑏 𝑎𝑏 𝑎𝑏 𝑎𝑏 ⎟⎟ ⎪ ⎪𝑢̃ 1 ⎪ ⎪
⎜⎜ ⎟⎟ ⎪ ⎪




1 ⎜⎜⎜−𝑏 𝑏 ⎟
𝑏 −𝑏⎟⎟ ⎨𝑢̃ 2 ⎪⎪ ⎬
= ⎜⎜ ⎟⎟ ⎪ ⎪ (2)
4𝑎𝑏 ⎜⎜⎜−𝑎 −𝑎 𝑎 𝑎 ⎟⎟⎟ ⎪ ⎪ 𝑢̃ 3 ⎪

⎜⎝ ⎟⎠ ⎪





1 −1 1 −1 𝑢̃ 4 ⎭ ⎩

369
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

phi /. {a :> (x0 + a), b :> (y0 + b)}


Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + b}]

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

Substituting (2) back into (1) and rearranging terms results in

𝑢̃ = 𝑐1 + 𝑐2 𝑥 + 𝑐3 𝑦 + 𝑐4 𝑥𝑦
1
= ��𝑎𝑏 − 𝑏𝑥 − 𝑎𝑦 + 𝑥𝑦� 𝑢̃ 1 + �𝑎𝑏 + 𝑏𝑥 − 𝑎𝑦 − 𝑥𝑦� 𝑢̃ 2 + �𝑎𝑏 + 𝑏𝑥 + 𝑎𝑦 + 𝑥𝑦� + �𝑎𝑏 − 𝑏𝑥 + 𝑎𝑦 − 𝑥𝑦��
4𝑎𝑏

1
Since 𝑎𝑏 is the 4
of the area of element, then the above becomes

1
𝑢̃ = ��𝑎𝑏 − 𝑏𝑥 − 𝑎𝑦 + 𝑥𝑦� 𝑢̃ 1 + �𝑎𝑏 + 𝑏𝑥 − 𝑎𝑦 − 𝑥𝑦� 𝑢̃ 2 + �𝑎𝑏 + 𝑏𝑥 + 𝑎𝑦 + 𝑥𝑦� + �𝑎𝑏 − 𝑏𝑥 + 𝑎𝑦 − 𝑥𝑦��
𝐴

The above can now be written in term of what is called shape functions

̃ 𝑦) = 𝑁1 (𝑥, 𝑦)𝑢1̃ + 𝑁2 (𝑥, 𝑦)𝑢2̃ 𝑁3 (𝑥, 𝑦)𝑢3̃ + 𝑁4 (𝑥, 𝑦)𝑢4̃


𝑢(𝑥,

Where

1 1
𝑁1 = �𝑎𝑏 − 𝑏𝑥 − 𝑎𝑦 + 𝑥𝑦� = (𝑎 − 𝑥) �𝑏 − 𝑦�
𝐴 𝐴
1 1
𝑁2 = �𝑎𝑏 + 𝑏𝑥 − 𝑎𝑦 − 𝑥𝑦� = (𝑎 + 𝑥) �𝑏 − 𝑦�
𝐴 𝐴
1 1
𝑁3 = �𝑎𝑏 + 𝑏𝑥 + 𝑎𝑦 + 𝑥𝑦� = (𝑎 + 𝑥) �𝑏 + 𝑦�
𝐴 𝐴
1 1
𝑁4 = �𝑎𝑏 − 𝑏𝑥 + 𝑎𝑦 − 𝑥𝑦� = (𝑎 − 𝑥) �𝑏 + 𝑦�
𝐴 𝐴

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.
370
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

𝑥=𝑎 𝑦=𝑏
𝐼𝑖 = � � 𝑤 �∇ 2 𝑢 − 𝑓 �𝑥, 𝑦�� 𝑑𝑥𝑑𝑦 (3)
𝑥=−𝑎 𝑦=−𝑏

𝑑𝑢̃
Where 𝑤 �𝑥, 𝑦� is the test function. For Galerkin method, the test function 𝑤𝑖 = 𝑑𝑢𝑖
= 𝑁𝑖 �𝑥, 𝑦�.
Hence

⎧ ⎫ ⎧⎪ 1



⎪ 𝑁 �𝑥, 𝑦� ⎪
⎪ ⎪
⎪ (𝑎 − 𝑥) �𝑏 − 𝑦� ⎪


⎪ 1 ⎪
⎪ ⎪
⎪ 𝐴 ⎪


⎪ ⎪ ⎪ 1 ⎪
⎨𝑁2 �𝑥, 𝑦�⎬ ⎨ 𝐴 + 𝑥) − 𝑦� ⎪
⎪ ⎪ (𝑎 �𝑏 ⎬
𝑤 �𝑥, 𝑦� = ⎪
⎪ ⎪
⎪ =⎪
⎪ 1 ⎪


⎪𝑁3 �𝑥, 𝑦�⎪ ⎪ ⎪⎪ 𝐴 (𝑎 + 𝑥) �𝑏 + 𝑦�⎪⎪

⎪ ⎪
⎪ ⎪
⎪ ⎪

⎩𝑁 �𝑥, 𝑦�⎭ ⎪ ⎩ 1 (𝑎 − 𝑥) �𝑏 + 𝑦� ⎪

4 𝐴

Using weak form, integration by parts is applied to (2)

goes to zero
𝑥=𝑎 𝑦=𝑏
𝜕𝑤 𝜕𝑢̃ ���������
𝜕𝑢̃
𝐼𝑖 = � � �− − 𝑤𝑓 �𝑥, 𝑦�� 𝑑𝑥𝑑𝑦 + � 𝑤
𝜕𝑥𝑖 𝜕𝑥𝑖 𝜕𝑛
𝑥=−𝑎 𝑦=−𝑏 Γ

𝜕𝑢̃
The term ∫ 𝑤 𝜕𝑛 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), 𝑤 = 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

371
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

𝑥=𝑎 𝑦=𝑏
𝜕𝑤 𝜕𝑢̃
𝐼𝑖 = � � �− − 𝑤𝑓 �𝑥, 𝑦�� 𝑑𝑥𝑑𝑦
𝜕𝑥𝑖 𝜕𝑥𝑖
𝑥=−𝑎 𝑦=−𝑏
⎧ 𝜕𝑁1 ⎫ ⎧ 𝜕𝑁1 ⎫
⎪ ⎪ ⎧ ⎫ ⎪ ⎪ ⎪
⎪ ⎧ ⎫

⎪ ⎪
𝜕𝑥 ⎪

⎪ 𝑢 ̃ ⎪
⎪ ⎪
⎪ 𝜕𝑦 ⎪
⎪ ⎪
⎪ 𝑢̃ 1 ⎪

𝑥=𝑎 𝑦=𝑏 ⎪
⎪ ⎪
⎪ ⎪
⎪ 1 ⎪
⎪ ⎪
⎪ 𝜕𝑁2 ⎪
⎪ ⎪
⎪ ⎪


⎪ 𝜕𝑁 2⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪
⎨ 𝜕𝑥 ⎪⎬ 𝜕𝑁1 𝜕𝑁2 𝜕𝑁3
⎪ ⎪ ⎪
𝜕𝑁4 ⎨𝑢̃ 2 ⎬ ⎨ 𝜕𝑦 ⎬ 𝜕𝑁1
⎪ 𝜕𝑁2 𝜕𝑁3 𝜕𝑁4 ⎨𝑢̃ 2 ⎪
⎪ ⎬
= � � −⎪ ⎪ 𝜕𝑁3 ⎪
⎪ � 𝜕𝑥 � ⎪ ⎪ − ⎪ 𝜕𝑁3 ⎪ � 𝜕𝑦 � ⎪ ⎪
⎪ ⎪ 𝜕𝑥 𝜕𝑥 𝜕𝑥 ⎪⎪ 𝑢̃ 3 ⎪⎪ ⎪
⎪ ⎪
⎪ 𝜕𝑦 𝜕𝑦 𝜕𝑦 ⎪⎪ 𝑢̃ 3 ⎪


𝑥=−𝑎 𝑦=−𝑏 ⎪ 𝜕𝑥 ⎪⎪ ⎪
⎪ ⎪
⎪ ⎪ ⎪ ⎪
𝜕𝑦 ⎪

⎪ ⎪


⎪ ⎪ ⎪
⎩𝑢̃ ⎪ ⎭ ⎪ ⎪ ⎪
⎩𝑢̃ ⎪ ⎭
⎩ 𝜕𝑁4 ⎪
⎭ 4

⎪ 𝜕𝑁4 ⎪
⎩ ⎪
⎭ 4
𝜕𝑥 𝜕𝑦
⎧ ⎫

⎪ 𝑁 �𝑥, 𝑦� ⎪

𝑥=𝑎 𝑦=𝑏 ⎪
⎪ 1 ⎪


⎪ ⎪

𝑁
⎨ 2 �𝑥, 𝑦� ⎬
− � � ⎪ ⎪ ⎪ 𝑓 �𝑥, 𝑦� 𝑑𝑥𝑑𝑦

⎪ 𝑁 3 �𝑥, 𝑦�⎪⎪

𝑥=−𝑎 𝑦=−𝑏 ⎪ ⎪

⎩𝑁 �𝑥, 𝑦�⎪ ⎭
4

Hence

⎛ 𝜕𝑁 𝜕𝑁 𝜕𝑁1 𝜕𝑁1 𝜕𝑁1 𝜕𝑁2 𝜕𝑁1 𝜕𝑁2 𝜕𝑁1 𝜕𝑁3 𝜕𝑁1 𝜕𝑁3 𝜕𝑁1 𝜕𝑁4

𝜕𝑁1 𝜕𝑁4
⎜⎜ 1 1 + + + + ⎟⎟ ⎧ ⎫
⎜⎜⎜ 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 ⎟ ⎟⎪ ⎪𝑢̃ 1 ⎪⎪
𝑥=𝑎 𝑦=𝑏 ⎜ ⎜⎜ 𝜕𝑁2 𝜕𝑁1 𝜕𝑁2 𝜕𝑁1 𝜕𝑁2 𝜕𝑁2 𝜕𝑁2 𝜕𝑁2 𝜕𝑁2 𝜕𝑁3 𝜕𝑁2 𝜕𝑁3 𝜕𝑁2 𝜕𝑁4 𝜕𝑁2 𝜕𝑁4 ⎟⎟⎟ ⎪ ⎪




+ + + + 𝜕𝑦 𝜕𝑦 ⎟⎟ ⎪ 𝑢̃ ⎪
𝐼𝑖 = � � − ⎜⎜⎜ 𝜕𝑁
⎜ 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 ⎟⎟ ⎪ ⎬
⎨ 2
⎜ 3 𝜕𝑁1 𝜕𝑁3 𝜕𝑁1 𝜕𝑁3 𝜕𝑁2 𝜕𝑁3 𝜕𝑁2 𝜕𝑁3 𝜕𝑁3 𝜕𝑁3 𝜕𝑁3 𝜕𝑁3 𝜕𝑁4 𝜕𝑁3 𝜕𝑁4 ⎟ ⎪𝑢̃ ⎪ ⎪
𝑥=−𝑎 𝑦=−𝑏 ⎜ ⎜⎜ 𝜕𝑥 𝜕𝑥 + + + + 𝜕𝑦 𝜕𝑦 ⎟⎟⎟ ⎪ ⎪ 3⎪ ⎪
⎜⎜ 𝜕𝑁4 𝜕𝑁1 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥 ⎟⎟ ⎪
⎪ ⎪

⎝ 𝜕𝑁4 𝜕𝑁1 𝜕𝑁4 𝜕𝑁2 𝜕𝑁4 𝜕𝑁2 𝜕𝑁4 𝜕𝑁3 𝜕𝑁4 𝜕𝑁3 𝜕𝑁4 𝜕𝑁4 𝜕𝑁4 𝜕𝑁4 ⎠ ⎟ 𝑢̃ 4 ⎭

+ 𝜕𝑦 𝜕𝑦
𝜕𝑥 𝜕𝑥 𝜕𝑥 𝜕𝑥
+ 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥
+ 𝜕𝑦 𝜕𝑦 𝜕𝑥 𝜕𝑥
+ 𝜕𝑦 𝜕𝑦
⎧ ⎫
⎪ ⎪
𝑥=𝑎 𝑦=𝑏 ⎪
⎪𝑁1 �𝑥, 𝑦�⎪
⎪ ⎪


⎪ ⎪
⎨𝑁2 �𝑥, 𝑦�⎪

− � � ⎪ ⎪
⎪ ⎪ 𝑓 �𝑥, 𝑦� 𝑑𝑥𝑑𝑦

⎪𝑁3 �𝑥, 𝑦�⎪
𝑥=−𝑎 𝑦=−𝑏 ⎪ ⎪


⎩𝑁 �𝑥, 𝑦�⎪⎭
4

In the above, we have the from 𝐼𝑖 = ∫ −𝑘𝑖 {𝑢}̃ 𝑑Ω − ∫ {𝑢}̃ 𝑓𝑖 𝑑Ω, 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 Mathematica. The local stiffness matrix for element 𝑖 is

372
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

𝑥=𝑎 𝑦=𝑏
𝜕𝑤 𝜕𝑢̃
𝑘𝑖 = � � 𝑑𝑥𝑑𝑦
𝜕𝑥𝑖 𝜕𝑥𝑖
𝑥=−𝑎 𝑦=−𝑏
⎛ 𝑎2+𝑏2 𝑎 𝑏 𝑎2 +𝑏2 𝑎

𝑏
⎜⎜ − − − 3𝑏 + ⎟⎟
⎜⎜ 3𝑎𝑏 6𝑏 3𝑎 6𝑎𝑏 6𝑎 ⎟⎟
⎜⎜ 𝑎 𝑎2 +𝑏2 𝑎 +𝑏 ⎟
2 2
⎜⎜ − 𝑏 − 6𝑎𝑏 ⎟⎟⎟
𝑎 𝑏
− 3𝑏 +
= ⎜⎜⎜ 6𝑏𝑎2+𝑏3𝑎2 𝑎
3𝑎𝑏
𝑏 𝑎2 +𝑏2
6𝑎
𝑎 𝑏 ⎟

⎟⎟
⎜⎜ − − 3𝑏 + − ⎟
⎜⎜ 3𝑎 ⎟ ⎟⎟
⎜⎝ 𝑎 6𝑎𝑏 𝑏 6𝑎
𝑎2 +𝑏2 𝑎
3𝑎𝑏
𝑏
6𝑏
2
𝑎 +𝑏 2 ⎠
− 3𝑏 + 6𝑎 − 6𝑎𝑏 6𝑏
− 3𝑎 3𝑎𝑏

1 1
For example, for element of width 1 and height 1, then 𝑎 = 2 , 𝑏 = 2
and the above becomes

⎛ 2 1 1 1⎞
⎜⎜ −6 −3 − 6 ⎟⎟
⎜⎜ 31 1⎟

⎜⎜− 2
−6
1
− 3 ⎟⎟⎟

𝑘𝑖 = ⎜⎜⎜ 61 3
1⎟

− 6 ⎟⎟⎟⎟
1 2
⎜⎜− −6
⎜⎜ 3 3
⎝ 1 1 1 2 ⎟ ⎠
−6 −3 −6 3

phi /. {a :> (x0 + a), b :> (y0 + b)}


Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + 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
- 3 b + 6ba
a a
6b
- 3ba
3ab
a b a 2 +b 2 a a 2 +b 2
- 3b
+ 6a
- 6ab 6b
- 3ba
3ab

Hence

⎧ ⎫ ⎧ ⎫

⎪𝑢̃ 1 ⎪
⎪ ⎪
⎪𝑁1 �𝑥, 𝑦�⎪⎪

⎪ ⎪
⎪ ⎪
𝑥=𝑎 𝑦=𝑏 ⎪



⎪ ⎪
⎪ ⎪
⎪ ⎪

𝑢 ̃
⎨ 2⎬ 𝑁
⎨ 2 �𝑥, 𝑦� ⎬
𝐼𝑖 = −𝑘𝑖 ⎪
⎪ ⎪
⎪ − � � ⎪
⎪ ⎪ 𝑓 �𝑥, 𝑦� 𝑑𝑥𝑑𝑦

⎪ ⎪
𝑢̃ 3 ⎪ 𝑥=−𝑎 ⎪
⎪𝑁3 �𝑥, 𝑦�⎪⎪


⎪ ⎪
⎪ 𝑦=−𝑏 ⎪
⎪ ⎪
⎩𝑢̃ ⎭ ⎩𝑁 �𝑥, 𝑦�⎪ ⎭
4 4

Now the integration of the force vector is carried out.

373
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

⎧ ⎫

⎪𝑁 �𝑥, 𝑦� ⎪

𝑥=𝑎 𝑦=𝑏 ⎪
⎪ 1 ⎪


⎪ ⎪
𝑓 ⎨𝑁2 �𝑥, 𝑦�⎪ ⎬
𝐼𝑖 = � � ⎪ ⎪ ⎪ 𝑓 �𝑥, 𝑦� 𝑑𝑥𝑑𝑦
⎪𝑁3 �𝑥, 𝑦�⎪ ⎪
𝑥=−𝑎 𝑦=−𝑏 ⎪
⎪ ⎪


⎩𝑁 �𝑥, 𝑦�⎪ ⎭
4
⎧ ⎫

⎪ 1
(𝑎 − 𝑥) �𝑏 − 𝑦� ⎪⎪

⎪𝐴 ⎪

𝑥=𝑎 𝑦=𝑏 ⎪⎪ 1 ⎪


⎨𝐴 (𝑎 + 𝑥) �𝑏 − 𝑦� ⎪

= � � ⎪ ⎪ ⎪ 𝑓 �𝑥, 𝑦� 𝑑𝑥𝑑𝑦
⎪ (𝑎 + 𝑥) �𝑏 + 𝑦�⎪
1

𝑥=−𝑎 𝑦=−𝑏 ⎪
⎪ 𝐴 ⎪


⎪ ⎪
⎩ (𝑎 − 𝑥) �𝑏 + 𝑦� ⎪
1

𝐴

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 �𝑥0 , 𝑦0 � then we need
to replace 𝑎 → 𝑥0 + 𝑎 and 𝑏 → 𝑦0 + 𝑏 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.

4.16.1 Integrating the force vector


This is normally done using Gaussian quadrature method. In this example, the integral is
found off-line using Mathematica.
Evaluating the force vector requires integration over the element. This was done off-line
using Mathematica. The result is a function of the coordinate of the center of the element.
Then when running the code, this was evaluated for each element in the main loop.

4.16.1.1 𝑓 �𝑥, 𝑦� = 𝑥𝑦

For 𝑓 �𝑥, 𝑦� = 𝑥𝑦 the above gives a result as function of the center of the physical element.
⎧ ⎫

⎪ 1
((𝑥 − 𝑎) − 𝑥) �𝑦 + 𝑏 − 𝑦� ⎪


⎪𝐴 0 0 ⎪

𝑥=𝑥0 +𝑎 𝑦=𝑦0 +𝑏 ⎪ ⎪ 1 ⎪

𝑓

⎨𝐴 0((𝑥 − 𝑎) + 𝑥) �𝑦 0 + 𝑏 − 𝑦� ⎪

𝐼𝑖 = � � ⎪ ⎪ ⎪ 𝑥𝑦 𝑑𝑥𝑑𝑦
((𝑥0 − 𝑎) + 𝑥) �𝑦0 + 𝑏 + 𝑦�⎪
1

⎪ ⎪


𝑥=(𝑥0 −𝑎) 𝑦=�𝑦0 −𝑏� ⎪ 𝐴 ⎪


⎩ ((𝑥0 − 𝑎) − 𝑥) �𝑦0 + 𝑏 + 𝑦� ⎪
1

𝐴

This was done using Mathematica

374
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

⎧ ⎫

⎪ 𝑎 2 𝑏2 (𝑎 − 3𝑥 ) �𝑏 − 3𝑦 � ⎪


⎪ 0 0 ⎪


⎪ ⎪
𝑓 1 ⎨ −𝑎𝑏 �𝑎 + 3𝑎𝑥0 + 6𝑥0 � �𝑏 − 3𝑦0 � ⎪
2 2 2

𝐼𝑖 = ⎪
⎪ ⎪
9 (𝑥0 + 𝑎) �𝑦0 + 𝑏� ⎪
⎪𝑎𝑏 �𝑎 + 3𝑎𝑥0 + 6𝑥0 � �𝑏 + 3𝑏𝑦0 + 6𝑦0 �⎪
2 2 2 2 ⎪


⎪ ⎪

⎩ 2 2
−𝑎𝑏 (𝑎 − 3𝑥 ) �𝑏 + 3𝑏𝑦 + 𝑦 � 2 ⎭
0 0 0

phi /. {a :> (x0 + a), b :> (y0 + b)}


Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + b}]

4.16.2 Case 1
Case 𝑓(𝑥, 𝑦) = 3 �cos(4𝜋𝑥) + sin(3𝜋𝑦)�
This was done using Mathematica
phi /. {a :> (x0 + a), b :> (y0 + b)}
Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + b}]

{(a^2*b^2)/((a + x0)*(b + y0)),


(a*b^2*(a + 2*x0))/((a + x0)*(b + y0)),
(a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0)),
(a^2*b*(b + 2*y0))/((a + x0)*(b + y0))}

4.16.2.1 case 2

Case 𝑓 �𝑥, 𝑦� = 1
⎧ ⎫

⎪ 1
((𝑥 − 𝑎) − 𝑥) �𝑦 + 𝑏 − 𝑦� ⎪

⎪𝐴 0
⎪ 0 ⎪

𝑥=𝑥0 +𝑎 𝑦=𝑦 0 +𝑏 ⎪
⎪ 1 ⎪

𝑓

⎨ 𝐴 ((𝑥0 − 𝑎) + 𝑥) �𝑦0 + 𝑏 − 𝑦� ⎪⎬
𝐼𝑖 = � � ⎪ ⎪ ⎪ 𝑑𝑥𝑑𝑦
((𝑥0 − 𝑎) + 𝑥) �𝑦0 + 𝑏 + 𝑦�⎪
1

⎪ ⎪

𝑥=(𝑥0 −𝑎) 𝑦=�𝑦0 −𝑏� ⎪
⎪ 𝐴1 ⎪


⎩ ((𝑥0 − 𝑎) − 𝑥) �𝑦0 + 𝑏 + 𝑦� ⎪ ⎭
𝐴

This was done using Mathematica


⎧ ⎫

⎪ 𝑎2 𝑏2 ⎪


⎪ (𝑎+𝑥0 )(𝑏+𝑦0 ) ⎪


⎪ ⎪



2
𝑎𝑏 (𝑎+2𝑥0 ) ⎪

𝑓

⎨ (𝑎+𝑥0)(𝑏+𝑦0) ⎪ ⎬
𝐼𝑖 = ⎪
⎪ 𝑎𝑏(𝑎+2𝑥0 )(𝑏+2𝑦0 ) ⎪


⎪ ⎪


⎪ (𝑎+𝑥0 )(𝑏+𝑦0 ) ⎪ ⎪

⎪ 2
𝑎 𝑏(𝑏+2𝑦0 ) ⎪


⎩ (𝑎+𝑥 )(𝑏+𝑦 ) ⎪ ⎭
0 0

phi /. {a :> (x0 + a), b :> (y0 + b)}


Integrate[% , {x, x0 - a, x0 + a}, {y, y0 - b, y0 + b}]

375
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

{(a^2*b^2)/((a + x0)*(b + y0)),


(a*b^2*(a + 2*x0))/((a + x0)*(b + y0)),
(a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0)),
(a^2*b*(b + 2*y0))/((a + x0)*(b + y0))}

Now that the local 𝑘𝑖 and local 𝑓𝑖 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 (3ℎ, 3ℎ) where ℎ is the grid spacing.

376
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

y
Global node numbering

x0 y0 0, 6b 13 14 15 16 6a, 6b

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 matrix by putting zero in the row numbered 𝑖 that correspond to the edge node
𝑖, and by putting 1 in the diagonal entry (𝑖, 𝑖). 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 𝐴𝑥 = 𝑓 is then solved for 𝑥 where 𝑥 now is the
displacement or value of 𝑦 at the nodes. The following is an implementation of the above.
 
function matlab_97()
close all; clear all;

number_of_elements=[16 64 256 625];


function_string={'1','xy','3(\cos(4\pi x)+\sin(3 \pi y))'};
function_handles={@f_1,@f_xy,@f_2};

figure_image_file={'matlab_e97_1','matlab_e97_2','matlab_e97_3'};

for i=1:length(function_handles)
for j=1:length(number_of_elements)
plot_file=sprintf('%s_%d',figure_image_file{i},...
number_of_elements(j));
close all;
solve_poisson_2D_square(function_handles{i},...
function_string{i},number_of_elements(j),plot_file);
end
end
end

377
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

%----------------------------------
function k_local=getk(a,b)

k11=(a^2+b^2)/(3*a*b);
k12=a/(6*b)-b/(3*a);
k13=-(a^2+b^2)/(6*a*b);
k14=-a/(3*b)+b/(6*a);
k_local = [k11 k12 k13 k14;
k12 k11 k14 k13;
k13 k14 k11 k12;
k14 k13 k12 k11];
end
%----------------------------------------------------
%use this for f(x,y)=x*y
function f_local=f_xy(x0,y0,a,b)

f_local=1/(9*(a + x0)*(b + y0))*...


[a^2*b^2*(a-3*x0)*(b -3*y0);
-a*b^2*(a^2 + 3*a*x0 + 6*x0^2)*(b - 3*y0);
a*b*(a^2 + 3*a*x0 + 6*x0^2)*(b^2 + 3*b*y0 + 6*y0^2);
-a^2*b*(a - 3*x0)*(b^2 + 3*b*y0 + 6*y0^2)...
];
end
%----------------------------------------------------
%use this for f(x,y)=1
function f_local=f_1(x0,y0,a,b)

f_local=[(a^2*b^2)/((a + x0)*(b + y0));


(a*b^2*(a + 2*x0))/((a + x0)*(b + y0));
(a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0));
(a^2*b*(b + 2*y0))/((a + x0)*(b + y0))];

end
%----------------------------------------------------
%use this for f(x,y)= 3(cos(4 pi x)+sin(3 pi y))
function f_local=f_2(x0,y0,a,b)
f_local=[(1/(96*pi^2*(a + x0)*(b + y0)))*...
(9*b^2*cos(4*pi*(-a + x0)) -...
9*b^2*cos(4*pi*(a + x0)) + ...
8*a*(12*a*b*pi*cos(3*pi*(b - y0)) -...
9*b^2*pi*sin(4*pi*(-a + x0)) - ...
2*a*(sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0)))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(-9*b^2*cos(4*pi*(-a + x0)) + 9*b^2*cos(4*pi*(a + x0)) +...
8*(12*a*b*pi*(a + 2*x0)*cos(3*pi*(b - y0)) -...
9*b^2*pi*x0*sin(4*pi*(-a + x0)) + ...

378
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

9*a*b^2*pi*sin(4*pi*(a + x0)) +...


9*b^2*pi*x0*sin(4*pi*(a + x0)) - 2*a^2*sin(3*pi*(b - y0)) -...
4*a*x0*sin(3*pi*(b - y0)) - 2*a^2*sin(3*pi*(b + y0)) -...
4*a*x0*sin(3*pi*(b + y0))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(-9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) + ...
9*b*(b + 2*y0)*cos(4*pi*(a + x0)) -...
72*b*pi*x0*(b + 2*y0)*sin(4*pi*(-a + x0)) + ...
72*b*pi*(a + x0)*(b + 2*y0)*...
sin(4*pi*(a + x0)) + 12*(a + x0)^2*...
(6*pi*y0*cos(3*pi*(b - y0)) -...
6*pi*(b + y0)*cos(3*pi*(b + y0)) + sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0))) - 4*(-a + x0)*(a + 3*x0)*...
(6*pi*y0*cos(3*pi*(b - y0)) -...
6*pi*(b + y0)*cos(3*pi*(b + y0)) + sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) - ...
9*b*(b + 2*y0)*cos(4*pi*(a + x0)) +...
8*a*(12*a*pi*y0*cos(3*pi*(b - y0)) - ...
12*a*pi*(b + y0)*cos(3*pi*(b + y0)) -...
9*b^2*pi*sin(4*pi*(-a + x0)) - ...
18*b*pi*y0*sin(4*pi*(-a + x0)) +...
2*a*sin(3*pi*(b - y0)) + 2*a*sin(3*pi*(b + y0))))];

end
%----------------------------------------------------
function solve_poisson_2D_square(fh,rhs,M,plot_file)
%2a is width of element
%2b is height of element
%fh is function which evaluate the force vector
%rhs is string which is the f(x,y), for plotting only
%M=total number of elements
%k=local stiffness matrix
L = 1; %length of grid
N = 4; %number of nodes per element
M1 = sqrt(M); %number of elements per row
a=(L/M1)/2;
b=(L/M1)/2;
k_local=getk(a,b);
N1 = M1+1; %number of nodes per edge
dof=4;
nodes = N1^2; %total number of nodes
kk = zeros(nodes); %global stiffness vector
f = zeros(nodes,1); %global force vector
mtb = generate_coordinates_table(M1);
fmtb = generate_physical_coordinates_table(M1,a,b);

379
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

for i = 1:M
x0 = fmtb(i,1); y0 = fmtb(i,2);
%call to load different force vector, pre-computed offline
f_local=fh(x0,y0,a,b);

%assemble force vecotr and global stiffness matrix


for ii = 1:N
f(mtb(i,ii)) = f(mtb(i,ii)) + f_local(ii);
for jj = 1:N
kk(mtb(i,ii),mtb(i,jj)) = kk(mtb(i,ii),mtb(i,jj))+...
k_local(ii,jj);
end
end
end

%fix the global stiffness matrix and force vector for B.C.
edge_nodes=[1:N1 (M1+2):(M1+1):nodes-N1 ...
(2*M1+2):(M1+1):(nodes-N1) nodes-N1:nodes];
for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,:)=0;
f(z)=0;
end

for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,z)=1;
end

y=kk\f; %solve
Z=reshape(y,N1,N1);
[X,Y] = meshgrid(0:2*a:1,0:2*b:1);
h=surf(X,Y,Z);
shading interp
set(h','edgecolor','k');
set(gcf,'defaulttextinterpreter','latex');
plot_title=sprintf('$\\nabla^2 u=%s$, number of elements $%d$',rhs,M);
title(plot_title,'fontweight','bold','fontsize',14);

print(gcf, '-dpdf', '-r300', ['images/',plot_file]);


print(gcf, '-dpng', '-r300', ['images/',plot_file]);

figure;
[C,h] = contourf(X,Y,Z);
clabel(C,h)
set(gcf,'defaulttextinterpreter','latex');

380
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

title(plot_title,'fontweight','bold','fontsize',14);
colormap cool
print(gcf, '-dpdf', '-r300', ['images/',[plot_file,'_c']]);
print(gcf, '-dpng', '-r300', ['images/',[plot_file,'_c']]);

end
%----------------------------------------------------
function mtb=generate_coordinates_table(M)
%M=number_of_elements_per_row
mtb=zeros(M^2,4);
for i=1:M
for j=1:M
mtb(j+M*(i-1),:) =[j j+1 j+(M+2) j+(M+1)]+(M+1)*(i-1);
end
end
end
%----------------------------------------------------
function fmtb=generate_physical_coordinates_table(M,a,b)
%2a is width of element
%2b is height of element
%M=number_of_elements_per_row
fmtb=zeros(M^2,2);
for i=1:M
for j=1:M
fmtb(j+M*(i-1),:) = [(2*j-1)*a (2*i-1)*b];
end
end
end
 

Here is the output for the three force functions, for different number of elements.

4.16.3 𝑓(𝑥, 𝑦) = 1

381
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16.4 𝑓(𝑥, 𝑦) = 𝑥𝑦

382
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16.5 case 3
Case 3: 𝑓(𝑥, 𝑦) = 3 �cos(4𝜋𝑥) + sin(3𝜋𝑦)�

383
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16.6 Solving for reactangle grid


A small modification is now made to allow one to specify different width and height for the
domain.
 
function matlab_97_2()
close all; clear all;

%number of elements per unit length, width, height


number_of_elements=[4 1 1;
8 1 2;
16 1 4;
25 1 6];
function_string={'1','xy','3(\cos(4\pi x)+\sin(3 \pi y))'};
function_handles={@f_1,@f_xy,@f_2};

figure_image_file={'matlab_e97_rectangle_1',...
'matlab_e97_rectangle_2','matlab_e97_rectangle_3'};

384
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

for i=1:length(function_handles)
for j=1:size(number_of_elements,1)
plot_file=sprintf('%s_%d',figure_image_file{i},...
number_of_elements(j,1)*number_of_elements(j,2)*...
number_of_elements(j,3));
close all;
solve_poisson_2D_square(function_handles{i},...
function_string{i},number_of_elements(j,1),...
number_of_elements(j,2),number_of_elements(j,3),...
plot_file);
end
end
end

%----------------------------------
function k_local=getk(a,b)

k11=(a^2+b^2)/(3*a*b);
k12=a/(6*b)-b/(3*a);
k13=-(a^2+b^2)/(6*a*b);
k14=-a/(3*b)+b/(6*a);
k_local = [k11 k12 k13 k14;
k12 k11 k14 k13;
k13 k14 k11 k12;
k14 k13 k12 k11];
end
%----------------------------------------------------
%use this for f(x,y)=x*y
function f_local=f_xy(x0,y0,a,b)

f_local=1/(9*(a + x0)*(b + y0))*...


[a^2*b^2*(a-3*x0)*(b -3*y0);
-a*b^2*(a^2 + 3*a*x0 + 6*x0^2)*(b - 3*y0);
a*b*(a^2 + 3*a*x0 + 6*x0^2)*(b^2 + 3*b*y0 + 6*y0^2);
-a^2*b*(a - 3*x0)*(b^2 + 3*b*y0 + 6*y0^2)...
];
end
%----------------------------------------------------
%use this for f(x,y)=1
function f_local=f_1(x0,y0,a,b)

f_local=[(a^2*b^2)/((a + x0)*(b + y0));


(a*b^2*(a + 2*x0))/((a + x0)*(b + y0));
(a*b*(a + 2*x0)*(b + 2*y0))/((a + x0)*(b + y0));
(a^2*b*(b + 2*y0))/((a + x0)*(b + y0))];

end

385
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

%----------------------------------------------------
%use this for f(x,y)= 3(cos(4 pi x)+sin(3 pi y))
function f_local=f_2(x0,y0,a,b)
f_local=[(1/(96*pi^2*(a + x0)*(b + y0)))*...
(9*b^2*cos(4*pi*(-a + x0)) -...
9*b^2*cos(4*pi*(a + x0)) + 8*a*(12*a*b*pi*cos(3*pi*(b - y0)) -...
9*b^2*pi*sin(4*pi*(-a + x0)) - 2*a*(sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0)))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(-9*b^2*cos(4*pi*(-a + x0)) + 9*b^2*cos(4*pi*(a + x0)) +...
8*(12*a*b*pi*(a + 2*x0)*cos(3*pi*(b - y0)) -...
9*b^2*pi*x0*sin(4*pi*(-a + x0)) + ...
9*a*b^2*pi*sin(4*pi*(a + x0)) +...
9*b^2*pi*x0*sin(4*pi*(a + x0)) - 2*a^2*sin(3*pi*(b - y0)) -...
4*a*x0*sin(3*pi*(b - y0)) - 2*a^2*sin(3*pi*(b + y0)) -...
4*a*x0*sin(3*pi*(b + y0))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(-9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) + 9*b*(b + 2*y0)*...
cos(4*pi*(a + x0)) -...
72*b*pi*x0*(b + 2*y0)*sin(4*pi*(-a + x0)) + ...
72*b*pi*(a + x0)*(b + 2*y0)*...
sin(4*pi*(a + x0)) + 12*(a + x0)^2*(6*pi*y0*...
cos(3*pi*(b - y0)) -...
6*pi*(b + y0)*cos(3*pi*(b + y0)) + ...
sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0))) - 4*(-a + x0)*(a + 3*x0)*...
(6*pi*y0*cos(3*pi*(b - y0)) -...
6*pi*(b + y0)*cos(3*pi*(b + y0)) + ...
sin(3*pi*(b - y0)) +...
sin(3*pi*(b + y0))));
(1/(96*pi^2*(a + x0)*(b + y0)))*...
(9*b*(b + 2*y0)*cos(4*pi*(-a + x0)) - 9*b*(b + 2*y0)*...
cos(4*pi*(a + x0)) +...
8*a*(12*a*pi*y0*cos(3*pi*(b - y0)) - 12*a*pi*(b + y0)*...
cos(3*pi*(b + y0)) -...
9*b^2*pi*sin(4*pi*(-a + x0)) - 18*b*pi*y0*sin(4*pi*(-a + x0)) +...
2*a*sin(3*pi*(b - y0)) + 2*a*sin(3*pi*(b + y0))))];

end
%----------------------------------------------------
function solve_poisson_2D_square(fh,rhs,M,Lx,Ly,plot_file)
%fh is function which evaluate the force vector
%rhs is string which is the f(x,y), for plotting only
%M=number of element per unit length
%Lx=length in x-direction
%Ly=length in y-direction
N = 4; %number of nodes per element

386
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Mx=M*Lx;
My=M*Ly;
a=(1/M)/2;
b=a;
k_local=getk(a,b);
dof=4;

nodes = (Mx+1)*(My+1); %total number of nodes


kk = zeros(nodes); %global stiffness vector
f = zeros(nodes,1); %global force vector
mtb = generate_coordinates_table(Mx,My);
fmtb = generate_physical_coordinates_table(Mx,My,a,b);

for i = 1:(Mx*My)
x0 = fmtb(i,1); y0 = fmtb(i,2);
%call to load different force vector, pre-computed offline
f_local=fh(x0,y0,a,b);

%assemble force vecotr and global stiffness matrix


for ii = 1:N
f(mtb(i,ii)) = f(mtb(i,ii)) + f_local(ii);
for jj = 1:N
kk(mtb(i,ii),mtb(i,jj)) = kk(mtb(i,ii),mtb(i,jj))+...
k_local(ii,jj);
end
end
end

%fix the global stiffness matrix and force vector for B.C.
edge_nodes=[1:Mx+1 (Mx+2):(Mx+1):nodes-...
Mx (2*Mx+2):(Mx+1):(nodes-(Mx+1)) nodes-(Mx-1):nodes];
for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,:)=0;
f(z)=0;
end

for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,z)=1;
end

y=kk\f; %solve
Z=reshape(y,Mx+1,My+1);
[X,Y] = meshgrid(0:2*b:Ly,0:2*a:Lx);
h=surf(X,Y,Z);
shading interp

387
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

set(h','edgecolor','k');
set(gcf,'defaulttextinterpreter','latex');
plot_title=sprintf('$\\nabla^2 u=%s$, number of elements $%d$',rhs,Mx*My);
title(plot_title,'fontweight','bold','fontsize',14);

print(gcf, '-dpdf', '-r300', ['images/',plot_file]);


print(gcf, '-dpng', '-r300', ['images/',plot_file]);

figure;
[C,h] = contourf(X,Y,Z);
clabel(C,h)
set(gcf,'defaulttextinterpreter','latex');
title(plot_title,'fontweight','bold','fontsize',14);
colormap cool

print(gcf, '-dpdf', '-r300', ['images/',[plot_file,'_c']]);


print(gcf, '-dpng', '-r300', ['images/',[plot_file,'_c']]);

end
%----------------------------------------------------
function mtb=generate_coordinates_table(Mx,My)
%Mx= number of element x-wise
%My= number of element y-wise
mtb=zeros(Mx*My,4);
for i=1:My
for j=1:Mx
mtb(j+Mx*(i-1),:) =[j j+1 j+(Mx+2) j+(Mx+1)]+(Mx+1)*(i-1);
end
end
end
%----------------------------------------------------
function fmtb=generate_physical_coordinates_table(Mx,My,a,b)
%Mx= number of element x-wise
%My= number of element y-wise
%2a is width of element
%2b is height of element
fmtb=zeros(Mx*My,2);
for i=1:My
for j=1:Mx
fmtb(j+Mx*(i-1),:) = [(2*j-1)*a (2*i-1)*b];
end
end
end
 

Here is the output for the three force functions, for different number of elements.

388
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16.7 Case 4
Case 𝑓(𝑥, 𝑦) = 1.

4.16.8 Case 5
Case : 𝑓(𝑥, 𝑦) = 𝑥𝑦

389
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.16.9 case 6
Case 𝑓(𝑥, 𝑦) = 3 �cos(4𝜋𝑥) + sin(3𝜋𝑦)�.

390
4.16. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

391
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.17 How to solve Poisson PDE in 2D using finite


elements methods using triangle element?
Solve ∇ 2 𝑢 = 𝑓 �𝑥, 𝑦� on square using FEM. Assume 𝑢 = 0 on boundaries and solve using
𝑓 �𝑥, 𝑦� = 𝑥𝑦 and also 𝑓 �𝑥, 𝑦� = 1 and 𝑓 �𝑥, 𝑦� = 3 �cos(4𝜋𝑥) + sin(3𝜋𝑦)�
Use Galerkin method and weak form, Using triangle element.
Solution
Using as an example with 9 elements to illustrate the method. The program below can be
called with different number of elements.

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 3
2 2 1 2

1 2 3 4

Local node numbers Global node number

Figure 4.1: node numbering

Looking at one element


The trial function is

𝑢̃ = 𝑐1 + 𝑐2 𝑥 + 𝑐3 𝑦 (1)

Evaluating the trial function (1) at each corner node of the above element gives

𝑢̃ 1 = 𝑐1 + 𝑐2 𝑥1 + 𝑐3 𝑦1
𝑢̃ 2 = 𝑐1 + 𝑐2 𝑥2 + 𝑐3 𝑦2
𝑢̃ 3 = 𝑐1 + 𝑐2 𝑥3 + 𝑐3 𝑦3

392
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

x 3, y 3 
3

1 2
x 1, y 1  x 2, y 2 

area

1
A 2
x 1y 2  y 3   x 2y 3  y 1   x 3y 1  y 2 

Figure 4.2: element in physical coordinates

Hence

⎛ ⎞ ⎛ ⎞⎛ ⎞
⎜⎜𝑢̃ 1 ⎟⎟ ⎜⎜1 𝑥1 𝑦1 ⎟⎟ ⎜⎜𝑐1 ⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟⎜ ⎟
⎜⎜𝑢̃ ⎟⎟ = ⎜⎜1 𝑥 𝑦 ⎟⎟⎟ ⎜⎜⎜𝑐 ⎟⎟⎟
⎜⎜ ⎟⎟ ⎜⎜
2 2 2 ⎟⎟ ⎜⎜ 2 ⎟⎟
⎝ ⎠ ⎝ ⎠⎝ ⎠
𝑢̃ 3 1 𝑥3 𝑦3 𝑐3

Therefore

⎛ ⎞ ⎛ ⎞−1 ⎛ ⎞
⎜⎜𝑐1 ⎟⎟ ⎜⎜1 𝑥1 𝑦1 ⎟⎟ ⎜⎜𝑢̃ 1 ⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟ ⎜ ⎟
⎜⎜𝑐 ⎟⎟ = ⎜⎜1 𝑥 𝑦 ⎟⎟⎟ ⎜⎜⎜𝑢̃ ⎟⎟⎟
⎜⎜ 2 ⎟⎟ ⎜⎜ 2 2⎟ ⎜ 2⎟
⎟⎠ ⎜⎝ ⎟⎠
⎝ ⎠ ⎝
𝑐3 1 𝑥 3 𝑦3 𝑢̃ 3
⎛ ⎞⎛ ⎞
⎜⎜𝑥2 𝑦3 − 𝑥3 𝑦2 𝑥3 𝑦1 − 𝑥1 𝑦3 𝑥1 𝑦2 − 𝑦1 𝑥2 ⎟⎟ ⎜⎜𝑢̃ 1 ⎟⎟
1 ⎜⎜⎜ ⎟⎟ ⎜⎜ ⎟⎟
= ⎜⎜ 𝑦2 − 𝑦3 𝑦3 − 𝑦1 𝑦1 − 𝑦2 ⎟⎟⎟ ⎜⎜⎜𝑢̃ 2 ⎟⎟⎟ (2)
|𝐷| ⎜⎝ ⎟⎠ ⎜⎝ ⎟⎠
𝑥3 − 𝑥2 𝑥1 − 𝑥3 𝑥2 − 𝑥1 𝑢̃ 3

⎛ ⎞
⎜⎜1 𝑥1 𝑦1 ⎟⎟
⎜⎜ ⎟⎟
Where |𝐷| is the determinant of ⎜⎜⎜1 𝑥2 𝑦2 ⎟⎟⎟ which is |𝐷| = −𝑦1 𝑥2 +𝑥3 𝑦1 +𝑥1 𝑦2 −𝑥3 𝑦2 −𝑥1 𝑦3 +𝑥2 𝑦3 .
⎜⎝ ⎟⎠
1 𝑥3 𝑦3
1
This quantity is twice the area of the triangle 𝐴 = 2 �𝑥1 �𝑦2 − 𝑦3 � + 𝑥2 �𝑦3 − 𝑦1 � + 𝑥3 �𝑦1 − 𝑦2 ��.

393
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Substituting (2) into (1) in order to find the shape functions gives

𝑢̃ = 𝑐1 + 𝑐2 𝑥 + 𝑐3 𝑦
1
= ��𝑥2 𝑦3 − 𝑥3 𝑦2 � 𝑢̃ 1 + �𝑥3 𝑦1 − 𝑥1 𝑦3 � 𝑢̃ 2 + �𝑥1 𝑦2 − 𝑦1 𝑥2 � 𝑢̃ 3 �
2𝐴
1
+ ��𝑦2 − 𝑦3 � 𝑢̃ 1 + �𝑦3 − 𝑦1 � 𝑢̃ 2 + �𝑦1 − 𝑦2 � 𝑢̃ 3 � 𝑥
2𝐴
1
+ [(𝑥 − 𝑥2 ) 𝑢̃ 1 + (𝑥1 − 𝑥3 ) 𝑢̃ 2 + (𝑥2 − 𝑥1 ) 𝑢̃ 3 ] 𝑦
2𝐴 3

Collecting terms in 𝑢̃ 𝑖

1
𝑢̃ = 𝑢̃ 1 ��𝑥2 𝑦3 − 𝑥3 𝑦2 � + �𝑦2 − 𝑦3 � 𝑥 + (𝑥3 − 𝑥2 ) 𝑦�
2𝐴
1
+ 𝑢̃ 2 ��𝑥3 𝑦1 − 𝑥1 𝑦3 � + �𝑦3 − 𝑦1 � 𝑥 + (𝑥1 − 𝑥3 ) 𝑦�
2𝐴
1
+ 𝑢̃ 3 ��𝑥1 𝑦2 − 𝑦1 𝑥2 � + �𝑦1 − 𝑦2 � 𝑥 + (𝑥2 − 𝑥1 ) 𝑦�
2𝐴

Hence

1
𝑁1 �𝑥, 𝑦� = ��𝑥2 𝑦3 − 𝑥3 𝑦2 � + �𝑦2 − 𝑦3 � 𝑥 + (𝑥3 − 𝑥2 ) 𝑦�
2𝐴
1
𝑁2 �𝑥, 𝑦� = ��𝑥3 𝑦1 − 𝑥1 𝑦3 � + �𝑦3 − 𝑦1 � 𝑥 + (𝑥1 − 𝑥3 ) 𝑦�
2𝐴
1
𝑁3 �𝑥, 𝑦� = ��𝑥1 𝑦2 − 𝑦1 𝑥2 � + �𝑦1 − 𝑦2 � 𝑥 + (𝑥2 − 𝑥1 ) 𝑦�
2𝐴

Therefore (1) can be written as

𝑢̃ = 𝑁1 �𝑥, 𝑦� 𝑢̃ 1 + 𝑁2 �𝑥, 𝑦� 𝑢̃ 2 + 𝑁3 �𝑥, 𝑦� 𝑢̃ 3

Now that the shape functions are found, the test or weight function 𝑤 �𝑥, 𝑦� can be found.
𝜕𝑢̃
Since 𝑤𝑖 �𝑥, 𝑦� = 𝜕𝑢̃ 𝑖
for 𝑖 = 1, 2, 3, therefore this results in

⎛ ⎞ ⎛ ⎞ ⎛ ⎞
⎜⎜𝑤1 ⎟⎟ ⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟ ⎜⎜�𝑥2 𝑦3 − 𝑥3 𝑦2 � + �𝑦2 − 𝑦3 � 𝑥 + (𝑥3 − 𝑥2 ) 𝑦⎟⎟
⎜⎜ ⎟⎟ ⎜⎜ ⎟⎟ 1 ⎜⎜⎜ ⎟⎟
𝑤 �𝑥, 𝑦� = ⎜⎜⎜𝑤2 ⎟⎟⎟ = ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ = ⎜⎜�𝑥3 𝑦1 − 𝑥1 𝑦3 � + �𝑦3 − 𝑦1 � 𝑥 + (𝑥1 − 𝑥3 ) 𝑦⎟⎟⎟
⎝⎜ ⎠⎟ ⎝⎜ ⎠⎟ 2𝐴 ⎜⎝ ⎟⎠
𝑤3 𝑁3 �𝑥, 𝑦� �𝑥1 𝑦2 − 𝑦1 𝑥2 � + �𝑦1 − 𝑦2 � 𝑥 + (𝑥2 − 𝑥1 ) 𝑦

The weak form formulation now gives

394
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

⎛ ⎞
⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟
𝜕𝑁𝑖 𝜕𝑁𝑗 𝜕𝑁𝑖 𝜕𝑁𝑗 𝜕𝑢̃ ⎜⎜ ⎟⎟
𝐼𝑖 = − � 𝑑Ω − � 𝑑Ω + � 𝑤 𝑑Γ − � ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ 𝑓 �𝑥, 𝑦� 𝑑Ω
Ω
𝜕𝑥 𝜕𝑥
Ω
𝜕𝑦 𝜕𝑦
Γ
𝜕𝑛 ⎝⎜
Ω 𝑁 �𝑥, 𝑦�
⎠⎟
3

Hence
⎛ �𝑥,𝑦� ⎞
⎜⎜ 𝜕𝑁1 ⎟ ⎧ ⎫
⎜⎜ 𝜕𝑥 ⎟⎟⎟ ⎪

⎪𝑢̃ 1 ⎪⎪

⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ 𝜕𝑁 �𝑥,𝑦� ⎪
𝜕𝑁3 �𝑥,𝑦� ⎨ ⎬

𝐼𝑖 = − � ⎜⎜⎜ 2 ⎟⎟ 1 𝜕𝑁2 �𝑥,𝑦�
𝑢 ̃ 𝑑Ω
⎜⎜ 𝜕𝑥 ⎟⎟⎟ � 𝜕𝑥 𝜕𝑥 𝜕𝑥
�⎪

⎪ 2 ⎪


Ω ⎜ ⎜⎝ 𝜕𝑁3�𝑥,𝑦� ⎟⎟⎠ ⎪
⎩𝑢̃ 3 ⎪⎭
𝜕𝑥
⎛ ⎞
⎜⎜ 𝜕𝑁1�𝑥,𝑦� ⎟⎟ ⎧ ⎫
⎜⎜ 𝜕𝑦 ⎟⎟ ⎪
⎪ 𝑢̃ 1 ⎪

⎜⎜ ⎟ ⎪ ⎪
⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟⎟ 𝜕𝑁1�𝑥,𝑦� 𝜕𝑁3 �𝑥,𝑦� ⎨ ⎪
⎪ ⎬
− � ⎜⎜⎜ 2
𝜕𝑁2 �𝑥,𝑦�

⎜⎜ 𝜕𝑦 ⎟⎟⎟ � 𝜕𝑦 𝜕𝑦 𝜕𝑦
�⎪ 𝑢
⎪ 2⎪

̃ ⎪ 𝑑Ω

Ω ⎜ ⎜ ⎟ ⎪
⎩𝑢̃ 3 ⎪⎭
⎜⎝ 𝜕𝑁3�𝑥,𝑦� ⎟⎟⎠
𝜕𝑦
⎛ ⎞ ⎧ ⎫
⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟ ⎪
⎪𝑢̃ 1 ⎪⎪
⎜⎜⎜ ⎟⎟ 𝜕𝑢̃ ⎪

⎨ ⎪


+ � ⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟ ⎟ ⎪ 𝑢̃ 2 ⎪ 𝑑Γ
⎜⎝ ⎪
⎟⎠ 𝜕𝑛 ⎪ ⎪

Γ 𝑁 �𝑥, 𝑦� ⎪
⎩𝑢̃ 3 ⎭⎪
3
⎛ ⎞
⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟
⎜⎜ ⎟⎟
− � ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ 𝑓 �𝑥, 𝑦� 𝑑Ω
⎜⎝ ⎟⎠
Ω 𝑁 �𝑥, 𝑦�
3

Since 𝑤 = 0 on the boundary with Dirichlet conditions, and since there are no natural
boundary conditions, the above simplifies to

⎛ �𝑥,𝑦� ⎞
⎜⎜ 𝜕𝑁1 ⎟ ⎧ ⎫
⎜⎜ 𝜕𝑥 ⎟⎟⎟ ⎪

⎪𝑢̃ 1 ⎪⎪

⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ 𝜕𝑁 �𝑥,𝑦� ⎪
𝜕𝑁3 �𝑥,𝑦� ⎨ ⎬

𝐼𝑖 = − � ⎜⎜⎜ 2 ⎟⎟ 1 𝜕𝑁2 �𝑥,𝑦�
𝑢 ̃ 𝑑Ω
⎜⎜ 𝜕𝑥 ⎟⎟⎟ � 𝜕𝑥 𝜕𝑥 𝜕𝑥
�⎪

⎪ 2 ⎪


Ω ⎜ ⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ ⎪
⎩𝑢̃ 3 ⎭⎪
⎝ 3 ⎠
𝜕𝑥
⎛ ⎞
⎜⎜ 𝜕𝑁1�𝑥,𝑦� ⎟⎟ ⎧ ⎫ ⎛ ⎞
⎜⎜⎜ 𝜕𝑦 ⎟⎟⎟ ⎪

⎪𝑢̃ 1 ⎪

⎪ ⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟
⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ 𝜕𝑁 �𝑥,𝑦� ⎪
⎨ ⎬ ⎪ ⎜⎜ ⎟⎟
− � ⎜⎜⎜ 2 ⎟⎟ � 1 𝜕𝑁2 �𝑥,𝑦� 𝜕𝑁3 �𝑥,𝑦�
⎟ � 𝑑Ω ⎪
⎪𝑢̃ 2 ⎪
⎪ − � ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ 𝑓 �𝑥, 𝑦� 𝑑Ω
⎜⎜⎜ 𝜕𝑦 ⎟⎟⎟ 𝜕𝑦 𝜕𝑦 𝜕𝑦 ⎪ ⎪ ⎜ ⎟
Ω ⎜ ⎜⎝ 3
𝜕𝑁 �𝑥,𝑦� ⎟⎟ ⎪ ⎭ Ω ⎝𝑁3 �𝑥, 𝑦�⎠
⎩𝑢̃ 3 ⎪

𝜕𝑦

Now each integral is calculated for the triangle element. First the derivatives are found

395
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

⎛ �𝑥,𝑦� ⎞
⎜⎜ 𝜕𝑁1 ⎟ ⎛ ⎞
⎜⎜ 𝜕𝑥 ⎟⎟⎟ ⎜
⎜�𝑦2 − 𝑦 3 � ⎟⎟
⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟
⎜⎜ 2 ⎟⎟ = 1 ⎜⎜⎜⎜�𝑦 − 𝑦 �⎟⎟⎟⎟
⎜⎜ ⎟
⎜⎜ 𝜕𝑥 ⎟⎟⎟ 2𝐴 ⎜⎜⎝
3 1 ⎟
⎟⎠
⎜⎝ 𝜕𝑁3�𝑥,𝑦� ⎟⎠ �𝑦1 − 𝑦2 �
𝜕𝑥

and

⎛ ⎞
⎜⎜ 𝜕𝑁1�𝑥,𝑦� ⎟⎟ ⎛ ⎞
⎜⎜ 𝜕𝑦 ⎟⎟ ⎜⎜(𝑥3 − 𝑥2 )⎟⎟
⎜⎜ ⎟⎟
⎜⎜ 𝜕𝑁2�𝑥,𝑦� ⎟⎟ 1 ⎜⎜⎜ ⎟⎟
⎟⎟
⎜⎜ ⎟⎟ = ⎜(𝑥 − 𝑥 )
⎜⎜ 𝜕𝑦 ⎟⎟ 2𝐴 ⎜⎜⎝ 1 3 ⎟⎟

⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ (𝑥 − 𝑥 )
⎜⎝ 3 ⎟⎠ 2 1
𝜕𝑦

Hence

⎛ �𝑥,𝑦� ⎞
⎜⎜ 𝜕𝑁1 ⎟
⎜⎜ 𝜕𝑥 ⎟⎟⎟
⎜⎜ 𝜕𝑁 �𝑥,𝑦� ⎟⎟ 𝜕𝑁 �𝑥,𝑦� 𝜕𝑁𝑖 𝜕𝑁𝑗
⎜⎜ 2 ⎟⎟ � 1 𝜕𝑁2 �𝑥,𝑦� 𝜕𝑁3 �𝑥,𝑦�
�=
⎜⎜ ⎟
⎜⎜ 𝜕𝑥 ⎟⎟⎟ 𝜕𝑥 𝜕𝑥 𝜕𝑥 𝜕𝑥 𝜕𝑥
⎜⎝ 𝜕𝑁3�𝑥,𝑦� ⎟⎠
𝜕𝑥
⎛ 2 ⎞
⎜⎜ �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 �⎟⎟
1 ⎜⎜⎜⎜ ⎟⎟
2 3 2 3 3 1 2 3 1 2
2 ⎟⎟
= 2 ⎜ ⎜ �𝑦3 − 𝑦 1 � �𝑦 2 − 𝑦 3 � �𝑦 3 − 𝑦 1 � �𝑦 3 − 𝑦 1 � �𝑦1 − 𝑦 2 � ⎟⎟
(2𝐴) ⎜⎜⎝ 2
⎟⎟

�𝑦1 − 𝑦2 � �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 �

And

⎛ 𝜕𝑁 �𝑥,𝑦� ⎞
⎜⎜ 1 ⎟
⎜⎜ 𝜕𝑦 ⎟⎟⎟
⎜⎜ ⎟
⎜⎜ 𝜕𝑁2�𝑥,𝑦� ⎟⎟⎟ 𝜕𝑁1�𝑥,𝑦� 𝜕𝑁2 �𝑥,𝑦� 𝜕𝑁3 �𝑥,𝑦� 𝜕𝑁𝑖 𝜕𝑁𝑗
⎜⎜ ⎟⎟ � �=
⎜⎜⎜ 𝜕𝑦 ⎟⎟⎟ 𝜕𝑦 𝜕𝑦 𝜕𝑦 𝜕𝑦 𝜕𝑦
⎜⎝ 𝜕𝑁3�𝑥,𝑦� ⎟⎠
𝜕𝑦
⎛ ⎞
⎜⎜ (𝑥3 − 𝑥2 )2 (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 )⎟⎟
1 ⎜⎜ ⎟⎟
= ⎜⎜(𝑥 − 𝑥 ) (𝑥 − 𝑥 ) (𝑥1 − 𝑥3 )2 (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )⎟⎟⎟
⎜ 1 3 3 2
(2𝐴)2 ⎜⎝ ⎟⎠
(𝑥2 − 𝑥1 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )2

We see the above terms do not depend on 𝑥 nor on 𝑦. Hence the next integration is done
over the area of the triangle as follow
⎧ ⎫ ⎧ ⎫

⎪ 𝑢̃ 1 ⎪
⎪ ⎪
⎪ ⎪
⎪ ⎪ ⎪𝑢̃ 1 ⎪⎪
𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬ 𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬
� ⎪
⎪ 𝑢̃ 2 ⎪
⎪ 𝑑Ω = ⎪
⎪ 𝑢̃ 2 ⎪
⎪ � 𝑑Ω
𝜕𝑥 𝜕𝑥 ⎪ ⎪ ⎪
⎪ 𝜕𝑥 𝜕𝑥 ⎪ ⎪ ⎪

Ω ⎩𝑢̃ 3 ⎭ ⎩𝑢̃ 3 ⎭ Ω
396
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

But ∫ 𝑑Ω is the area of the triangle. Hence


Ω
⎧ ⎫ ⎧ ⎫

⎪ ⎪
⎪ ⎪
⎪ ⎪
𝑢
⎪ ⎪̃ 1 ⎪𝑢̃ 1 ⎪

𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬ 𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬
� ⎪
⎪ 𝑢 ̃ 2⎪⎪ 𝑑Ω = ⎪
⎪ 𝑢̃ 2⎪
⎪ 𝐴
𝜕𝑥 𝜕𝑥 ⎪ ⎪ ⎪
⎪ 𝜕𝑥 𝜕𝑥 ⎪ ⎪ ⎪

Ω ⎩𝑢̃ 3 ⎭ ⎩𝑢̃ 3 ⎭

𝜕𝑁𝑖 𝜕𝑁𝑗
Replacing 𝜕𝑥 𝜕𝑥
by the expression we found for it above, gives

⎧ ⎫ ⎛ 2 ⎞⎧ ⎫

⎪ 𝑢̃ 1 ⎪
⎪ ⎜⎜ �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � ⎟⎟ ⎪ ⎪

𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪

𝐴 ⎜⎜⎜⎜
2 3 2 3 3 1 2 3 1 2 ⎟⎟ ⎪ ⎪𝑢̃ 1 ⎪ ⎪
⎨ ⎪ ⎬ 2 ⎟⎟ ⎪⎨ ⎪ ⎬
� ⎪
⎪ 𝑢̃ 2 ⎪
⎪ 𝑑Ω = 2 ⎜⎜�𝑦3 − 𝑦1 � �𝑦2 − 𝑦3 � �𝑦3 − 𝑦1 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 �⎟⎟ ⎪ ⎪ 𝑢̃ 2 ⎪⎪
𝜕𝑥 𝜕𝑥 ⎪ ⎪
⎩𝑢̃ 3 ⎪

⎭ (2𝐴) ⎜⎜⎝ 2
⎟⎟ ⎪
⎠⎪⎩



Ω
�𝑦1 − 𝑦2 � �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 � 𝑢 ̃ 3
⎛ 2 ⎞⎧ ⎫
⎜⎜ �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 � �𝑦 − 𝑦 �
2 ⎟
⎟⎪ ⎪ 𝑢̃ 1 ⎪

⎜ 2 3 2 3 3 1 2 3 1 ⎟ ⎪ ⎪
1 ⎜⎜⎜ 2 ⎟⎟ ⎨ ⎪
⎟ ⎪ ⎬
= ⎜⎜�𝑦3 − 𝑦1 � �𝑦2 − 𝑦3 � �𝑦3 − 𝑦1 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 �⎟⎟ ⎪ ⎪ 𝑢̃ 2 ⎪
⎪ (3)
4𝐴 ⎜ ⎜ ⎟
⎟⎠ ⎪
⎪ ⎪

⎝ 2 ⎩ 𝑢̃ 3 ⎭
�𝑦1 − 𝑦2 � �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 �

Now we do the same for the second integral


⎧ ⎫ ⎧ ⎫

⎪ ⎪
⎪ ⎪
⎪ ⎪
⎪ 𝑢̃
⎪ 1⎪ ⎪ ⎪𝑢̃ 1 ⎪

𝜕𝑁𝑖 𝜕𝑁𝑗 ⎨ ⎬ 𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬
� ⎪
⎪ 𝑢 ̃ ⎪
2⎪ 𝑑Ω = ⎪
⎪𝑢 ̃ 2⎪
⎪ � 𝑑Ω
𝜕𝑦 𝜕𝑦 ⎪ ⎪ ⎪
⎪ 𝜕𝑦 𝜕𝑦 ⎪ ⎪ ⎪

Ω ⎩𝑢̃ 3 ⎭ ⎩𝑢̃ 3 ⎭ Ω

But ∫ 𝑑Ω is the area of the triangle. Hence


Ω
⎧ ⎫ ⎧ ⎫

⎪ ⎪
⎪ ⎪
⎪ ⎪
𝑢̃
⎪ 1⎪ ⎪𝑢̃ 1 ⎪

𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬ 𝜕𝑁𝑖 𝜕𝑁𝑗 ⎪
⎨ ⎪ ⎬
� ⎪
⎪ 𝑢 ̃ ⎪
2⎪ 𝑑Ω = ⎪
⎪ 𝑢̃ 2⎪
⎪ 𝐴
𝜕𝑦 𝜕𝑦 ⎪ ⎪ ⎪
⎪ 𝜕𝑦 𝜕𝑦 ⎪ ⎪ ⎪

Ω ⎩𝑢̃ 3 ⎭ ⎩𝑢̃ 3 ⎭

𝜕𝑁𝑖 𝜕𝑁𝑗
Replacing 𝜕𝑦 𝜕𝑦
by the expression we found for it above, gives

⎧ ⎫ ⎛ ⎞⎧ ⎫

⎪ ⎪
⎪ 2 ⎪
⎪ ⎪
⎪ 𝑢̃
⎪ 1⎪
⎜ (𝑥 − 𝑥 ) (𝑥 − 𝑥 ) (𝑥 − 𝑥 ) (𝑥 − 𝑥 ) (𝑥 − 𝑥 ) ⎟
1 ⎟⎪ 𝑢 ̃ 1⎪

𝐴 ⎜⎜⎜⎜
⎪ 3 2 3 2 1 3 3 2 2 ⎪ ⎪
𝜕𝑁𝑖 𝜕𝑁𝑗 ⎨ ⎬ 2

⎟⎟ ⎨ ⎬
� 𝑢
⎪ 2⎪
⎪ ̃ ⎪ 𝑑Ω = 2 ⎜
⎜(𝑥1 − 𝑥 3 ) (𝑥 3 − 𝑥 2 ) (𝑥 1 − 𝑥 3 ) (𝑥1 − 𝑥 3 ) (𝑥 2 − 𝑥 )
1 ⎟⎪⎟ ⎪𝑢 ̃ 2⎪

𝜕𝑥 𝜕𝑥 ⎪ ⎪
⎩𝑢̃ 3 ⎪

⎭ (2𝐴) ⎜⎝ 2
⎟⎠ ⎪ ⎪



Ω (𝑥2 − 𝑥1 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 ) 𝑢̃ 3 ⎭
⎛ ⎞⎧ ⎫
⎜⎜ (𝑥3 − 𝑥2 )2 (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 )⎟⎟ ⎪ ⎪
⎪ 𝑢̃ 1 ⎪


1 ⎜⎜⎜ 2

⎟⎟ ⎪
⎨ ⎪

= ⎜⎜(𝑥1 − 𝑥3 ) (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )⎟⎟ ⎪ ⎪ 𝑢 ̃ 2⎪
⎪ (4)
4𝐴 ⎜⎝ 2
⎟⎠ ⎪
⎪ ⎪

(𝑥2 − 𝑥1 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 ) ⎩𝑢̃ 3 ⎭

397
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

Adding (3) and (4) to obtain the local stiffness matrix

⎧ ⎫ ⎛ 2 ⎞⎧ ⎫

⎪ ⎪

𝑢̃ 1 ⎪ ⎜⎜ �𝑦 − 𝑦 � �𝑦2 − 𝑦3 � �𝑦3 − 𝑦1 � �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 �⎟⎟⎟ ⎪ ⎪𝑢̃ 1 ⎪ ⎪
⎪ ⎟⎟ ⎪ ⎪
1 ⎜⎜⎜⎜
2 3

⎨ ⎪ ⎬ 2 ⎪
⎨ ⎪

𝑘𝑖 ⎪𝑢 ̃ ⎪ = ⎜�𝑦 − 𝑦1 � �𝑦2 − 𝑦3 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 �⎟⎟ ⎪ ⎟ 𝑢 ̃
�𝑦3 − 𝑦1 � 2⎪



2⎪

⎪ 4𝐴 ⎜⎜⎜ 3 ⎪
⎟⎟ ⎪ ⎪

⎩𝑢̃ 3 ⎭ ⎝ 2 ⎠⎪⎩ 𝑢 ̃


𝑖
�𝑦1 − 𝑦2 � �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 � �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 � 3
⎛ ⎞⎧ ⎫
⎜⎜ (𝑥3 − 𝑥2 )2 (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 )⎟⎟ ⎪ ⎪
⎪ 𝑢̃ 1 ⎪


1 ⎜⎜ ⎜ 2 ⎟⎟ ⎨ ⎪
⎟ ⎪ ⎬
+ ⎜(𝑥 − 𝑥3 ) (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )⎟⎟ ⎪ 𝑢̃ 2 ⎪
4𝐴 ⎜⎜⎝ 1 ⎪
⎟⎠ ⎪



(𝑥2 − 𝑥1 ) (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 ) (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )2 ⎩𝑢̃ 3 ⎪ ⎭

or

⎛ 2 ⎞
⎜⎜
⎜ �𝑦2 − 𝑦3 � + (𝑥3 − 𝑥2 )2 �𝑦2 − 𝑦3 � �𝑦3 − 𝑦1 � + (𝑥3 − 𝑥2 ) (𝑥1 − 𝑥3 ) �𝑦2 − 𝑦3 � �𝑦1 − 𝑦2 � + (𝑥3 − 𝑥2 ) (𝑥2 − 𝑥1 )⎟⎟⎟
1 ⎜⎜⎜ 2 ⎟⎟
𝑘𝑖 = ⎜�𝑦 − 𝑦1 � �𝑦2 − 𝑦3 � + (𝑥1 − 𝑥3 ) (𝑥3 − 𝑥2 ) �𝑦3 − 𝑦1 � + (𝑥1 − 𝑥3 )2 �𝑦3 − 𝑦1 � �𝑦1 − 𝑦2 � + (𝑥1 − 𝑥3 ) (𝑥2 − 𝑥1 )⎟⎟⎟
4𝐴 ⎜⎜⎜ 3 ⎟⎟
⎝ 2 ⎠
�𝑦1 − 𝑦2 � �𝑦2 − 𝑦3 � + (𝑥2 − 𝑥1 ) (𝑥3 − 𝑥2 ) �𝑦1 − 𝑦2 � �𝑦3 − 𝑦1 � + (𝑥2 − 𝑥1 ) (𝑥1 − 𝑥3 ) �𝑦1 − 𝑦2 � + (𝑥2 − 𝑥1 )2

And the final integral (the force vector) depends on the nature of 𝑓 �𝑥, 𝑦�. For 𝑓 �𝑥, 𝑦� = 1 we
obtain

⎛ ⎞ ⎛ ⎞
⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟ ⎜⎜�𝑥2 𝑦3 − 𝑥3 𝑦2 � + �𝑦2 − 𝑦3 � 𝑥 + (𝑥3 − 𝑥2 ) 𝑦⎟⎟
⎜⎜ ⎟⎟ 1 ⎜⎜⎜ ⎟⎟
� ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ 𝑓 �𝑥, 𝑦� 𝑑Ω = � ⎜⎜�𝑥3 𝑦1 − 𝑥1 𝑦3 � + �𝑦3 − 𝑦1 � 𝑥 + (𝑥1 − 𝑥3 ) 𝑦⎟⎟⎟ 𝑑𝑦𝑑𝑥
⎜⎝ ⎟⎠ 2𝐴 ⎜⎝ ⎟⎠
Ω 𝑁 �𝑥, 𝑦� Ω �𝑥1 𝑦2 − 𝑦1 𝑥2 � + �𝑦1 − 𝑦2 � 𝑥 + (𝑥2 − 𝑥1 ) 𝑦
3

And for 𝑓 �𝑥, 𝑦� = 𝑥𝑦 similarly

⎛ ⎞ ⎛ ⎞
⎜⎜𝑁1 �𝑥, 𝑦�⎟⎟ ⎜⎜�𝑥2 𝑦3 − 𝑥3 𝑦2 � + �𝑦2 − 𝑦3 � 𝑥 + (𝑥3 − 𝑥2 ) 𝑦⎟⎟
⎜⎜ ⎟⎟ 1 ⎜⎜⎜ ⎟⎟
� ⎜⎜⎜𝑁2 �𝑥, 𝑦�⎟⎟⎟ 𝑓 �𝑥, 𝑦� 𝑑Ω = � ⎜⎜�𝑥3 𝑦1 − 𝑥1 𝑦3 � + �𝑦3 − 𝑦1 � 𝑥 + (𝑥1 − 𝑥3 ) 𝑦⎟⎟⎟ 𝑥𝑦𝑑𝑦𝑑𝑥
⎜⎝ ⎟⎠ 2𝐴 ⎜⎝ ⎟⎠
Ω 𝑁 �𝑥, 𝑦� Ω �𝑥1 𝑦2 − 𝑦1 𝑥2 � + �𝑦1 − 𝑦2 � 𝑥 + (𝑥2 − 𝑥1 ) 𝑦
3

And similarly for other 𝑓 �𝑥, 𝑦�. These were all integrated off-line and the resulting expression
evaluated during the run of the program. These expression are all functions of the node
coordinates �𝑥1 , 𝑦1 , 𝑥2 , 𝑦2 , 𝑥3 , 𝑦3 �. 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 functions 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
𝑥2 𝑦3 −𝑥
odd numbered triangles, the integration limits are ∫ ∫ 𝑑𝑦𝑑𝑥 while on the even numbered
𝑥1 𝑦1
𝑥1 𝑦2 −𝑥
elements the limits are ∫ ∫ 𝑑𝑦𝑑𝑥 as shown in this diagram
𝑥2 𝑦1

398
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

y
Odd numbered
triangle Even numbered
integration triangle 13 14 15 16
integration
x 3, y 3  14 16
18

3 y x 2, y 2  x 1, y 1  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

Figure 4.3: Integrating over elements

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 case 1
Case 𝑓 �𝑥, 𝑦� = 1. For odd numbered elements
Integrate[w, {x, x1, x2}, {y, y1, y2 - x}]

{{((x1 - x2)*(x2^3 + 3*x3*(y1 - y2)^2 + x1*(x2^2 + 3*(y1 - y2)*(y2 - y3) -


x2*(x3 + y2 - y3)) + x1^2*(x2 - x3 + 2*y2 - 2*y3) -
3*x2*(y1 - y2)*(y1 - y3) - x2^2*(x3 + y2 - y3)))/(12*area)},
{-((1/(12*area))*((x1 - x2)*(x1^3 - 3*x3*(y1 - y2)^2 - 3*x2*(y1 - y2)*
(x3 - y1 + y3) + x1^2*(x2 - x3 + 2*y1 - 3*y2 + y3) -
x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 - 3*(y1 - y2)*(x3 + y2 - y3) +
x2*(-x3 + 2*y1 - 3*y2 + y3)))))},
{((x1 - x2)^2*(x1^2 + x1*(x2 + 2*y1 - 2*y2) + x2*(x2 + y1 - y2)))/(12*area)}
}

For even numbered elements


Integrate[w, {x, x1, x2}, {y, y1, y2 - x}]

{{((x1 - x2)*(x2^3 + 3*x3*(y1 - y2)^2 + x1*(x2^2 + 3*(y1 - y2)*(y2 - y3) -


x2*(x3 + y2 - y3)) + x1^2*(x2 - x3 + 2*y2 - 2*y3) -
3*x2*(y1 - y2)*(y1 - y3) - x2^2*(x3 + y2 - y3)))/(12*area)},
{-((1/(12*area))*((x1 - x2)*(x1^3 - 3*x3*(y1 - y2)^2 - 3*x2*(y1 - y2)*
399
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

(x3 - y1 + y3) + x1^2*(x2 - x3 + 2*y1 - 3*y2 + y3) -


x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 - 3*(y1 - y2)*(x3 + y2 - y3) +
x2*(-x3 + 2*y1 - 3*y2 + y3)))))},
{((x1 - x2)^2*(x1^2 + x1*(x2 + 2*y1 - 2*y2) + x2*(x2 + y1 - y2)))/(12*area)}
}

4.17.2 Program output


This is an implementation of the above for 𝑓(𝑥, 𝑦) = 1. The coordinates mapping was first
carried out in order to map each elements local node numbers to the global node numbering
so we know where to add each element stiffness matrix to the global stiffness matrix. Also
we need to build the mapping of each element to the physical coordinates of its local node
number 1 to use for calculating the force vector since that depends on physical location of
each element.
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

12 12 11 8 Local node numbers Global node number

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

400
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

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

 
function matlab_98()
close all; clear all;
number_of_elements=[16*2 64*2 256*2 625*2];
function_string={'1'};
%function_handles={@f_1,@f_xy,@f_2};%something wrong with the other
%cases, need to work more on it.
function_handles={@f_1};
figure_image_file={'matlab_e98_1'};

for i=1:length(function_handles)
for j=1:length(number_of_elements)
plot_file=sprintf('%s_%d',figure_image_file{i},...
number_of_elements(j));
close all;
solve_poisson_2D_square(function_handles{i},...
function_string{i},number_of_elements(j),plot_file);
end
end
end

%----------------------------------
function k_local=getk(area,x1,y1,x2,y2,x3,y3)

k11=(y2-y3)^2+(x3-x2)^2;
k12=(y2-y3)*(y3-y1)+(x3-x2)*(x1-x3);
k13=(y2-y3)*(y1-y2)+(x3-x2)*(x2-x1);
k22=(y3-y1)^2+(x1-x3)^2;
k23=(y3-y1)*(y1-y2)+(x1-x3)*(x2-x1);
k33=(y1-y2)^2+(x2-x1)^2;
k_local = [k11 k12 k13;
k12 k22 k23;

401
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

k13 k23 k33];

k_local = k_local/(4*area);
end
%----------------------------------------------------
%use this for f(x,y)=1
function f_local=f_1(area,x1,y1,x2,y2,x3,y3,ele)

if mod(ele,2)
f_local=[(1/(12*area))*((x1 - x2)*(x2^3 + x1^2*...
(x2 - x3 + 2*y2 - 2*y3) +...
3*x3*(y1 - y3)*(y1 - 2*y2 + y3) - x2^2*(x3 - 2*y2 + 2*y3) -...
3*x2*(y1^2 + x3*y2 - x3*y3 + y2*y3 - y1*(y2 + y3)) + x1*(x2^2 -...
3*(y2 - y3)*(x3 - y1 + y3) - x2*(x3 - 2*y2 + 2*y3))));
-((1/(12*area))*((x1 - x2)*(x1^3 + x1^2*(x2 - x3 + 2*y1 - 2*y3) -...
3*x3*(y1 - y3)^2 - 3*x2*(y1 - y3)*(x3 - y1 + y3) -...
x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 + 3*x3*(-y1 + y3) -...
x2*(x3 - 2*y1 + 2*y3)))));
((x1 - x2)^2*(x1^2 + x2^2 + x1*(x2 + 2*y1 + y2 - 3*y3) +...
x2*(y1 + 2*y2 - 3*y3) + 3*(y1 - y3)*(y2 - y3)))/(12*area)];
else
f_local=[((x1 - x2)*(x2^3 + 3*x3*(y1 - y2)^2 + x1*(x2^2 +...
3*(y1 - y2)*(y2 - y3) - x2*(x3 + y2 - y3)) + x1^2*...
(x2 - x3 + 2*y2 - 2*y3) -...
3*x2*(y1 - y2)*(y1 - y3) - x2^2*(x3 + y2 - y3)))/(12*area);
-((1/(12*area))*((x1 - x2)*(x1^3 - 3*x3*(y1 - y2)^2 -...
3*x2*(y1 - y2)*(x3 - y1 + y3) + x1^2*...
(x2 - x3 + 2*y1 - 3*y2 + y3) -...
x2^2*(x3 - 2*y1 + 2*y3) + x1*(x2^2 - 3*(y1 - y2)*(x3 + y2 - y3)...
+ x2*(-x3 + 2*y1 - 3*y2 + y3)))));
((x1 - x2)^2*(x1^2 + x1*(x2 + 2*y1 - 2*y2) + ...
x2*(x2 + y1 - y2)))/(12*area)];

end

end
%----------------------------------------------------
function solve_poisson_2D_square(fh,rhs,M,plot_file)
%fh is function which evaluate the force vector
%rhs is string which is the f(x,y), for plotting only
%M=total number of elements
L = 1; %length of grid
N = 3; %number of nodes per element
h=(L/sqrt(M/2));
%area is same for each element, otherwise use
%area = 0.5*(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
area= (1/2)*h^2;

402
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

N1 = sqrt(M/2)+1; %number of nodes per edge


dof=3;
nodes = N1^2; %total number of nodes
kk = zeros(nodes); %global stiffness vector
f = zeros(nodes,1); %global force vector
mtb = generate_coordinates_table(M);
fmtb = generate_physical_coordinates_table(M,h);

for i = 1:M
x1 = fmtb(i,1); y1 = fmtb(i,2);
x2 = fmtb(i,3); y2 = fmtb(i,4);
x3 = fmtb(i,5); y3 = fmtb(i,6);
k_local=getk(area,x1,y1,x2,y2,x3,y3);
%call to load different force vector, pre-computed offline
f_local=fh(area,x1,y1,x2,y2,x3,y3,i);

for ii = 1:N %assemble force vector and global stiffness matrix


f(mtb(i,ii)) = f(mtb(i,ii)) + f_local(ii);
for jj = 1:N
kk(mtb(i,ii),mtb(i,jj)) = kk(mtb(i,ii),mtb(i,jj))+...
k_local(ii,jj);
end
end
end

%fix the global stiffness matrix and force vector for B.C.
edge_nodes=[1:N1 (N1+1):N1:nodes-N1+1 ...
(2*N1):N1:nodes nodes-N1+2:nodes-1];
for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,:)=0;
f(z)=0;
end

for i=1:length(edge_nodes)
z=edge_nodes(i);
kk(z,z)=1;
end

y=kk\f; %solve
Z=reshape(y,N1,N1);
[X,Y] = meshgrid(0:h:1,0:h:1);
h=surf(X,Y,Z);
shading interp
set(h','edgecolor','k');
set(gcf,'defaulttextinterpreter','latex');

403
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

plot_title=sprintf('$\\nabla^2 u=%s$, number of elements $%d$',rhs,M);


title(plot_title,'fontweight','bold','fontsize',14);

print(gcf, '-dpdf', '-r600', ['images/',plot_file]);


print(gcf, '-dpng', '-r300', ['images/',plot_file]);

figure;
[C,h] = contourf(X,Y,Z);
clabel(C,h)
set(gcf,'defaulttextinterpreter','latex');
title(plot_title,'fontweight','bold','fontsize',14);
colormap cool

print(gcf, '-dpdf', '-r300', ['images/',plot_file,'_c']);


print(gcf, '-dpng', '-r300', ['images/',plot_file,'_c']);

end
%----------------------------------------------------
function A=generate_coordinates_table(M)
%M=number_of_elements
A=zeros(M,3);
n=2*sqrt(M/2); %number of elements per row

for i=1:n/2
for j=1:n
ele=j+n*(i-1);
if j==1
A(ele,:)=[(n/2+1)*(i-1)+1 (n/2+1)*(i-1)+2 (n/2+1)*i+1];
else
if mod(j,2)
A(ele,:) =[A(ele-1,3) A(ele-1,3)+1 A(ele-1,1)];
else
A(ele,:) =[A(ele-1,3)+1 A(ele-1,3) A(ele-1,2)];
end
end
end
end
end
%----------------------------------------------------
function A=generate_physical_coordinates_table(M,h)
%M=number_of_elements
A=zeros(M,6);
n=2*sqrt(M/2); %number of elements per row

for i=1:n/2
for j=1:n
ele=j+n*(i-1);

404
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

if j==1
A(ele,:)=[0 (i-1)*h h (i-1)*h 0 i*h];
else
if mod(j,2)
A(ele,:) =[A(ele-1,5) A(ele-1,6) ...
A(ele-1,5)+h A(ele-1,6) A(ele-1,1) A(ele-1,2)];
else
A(ele,:) =[A(ele-1,5)+h A(ele-1,6) ...
A(ele-1,5) A(ele-1,6) A(ele-1,3) A(ele-1,4)];
end
end
end
end
end
 

Here is the output for the three force functions, for different number of elements.

4.17.3 case 2
Case 𝑓(𝑥, 𝑦) = 1

405
4.17. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

hline

406
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.18 How to solve wave equation using leapfrog method?


𝑥−0.2
Solve 𝑢𝑡𝑡 = 𝑐2 𝑢𝑥𝑥 for 0 ≥ 𝑥 ≤ 1 with initial data defined as 𝑓(𝑥) = sin �2𝜋 0.4
� over 0.2 ≥ 𝑥 ≤ 0.6
and fixed at both ends.
Mathematica
 
SetDirectory[NotebookDirectory[]];
Dynamic[p]

nPoints=100;
speed=351;
f1[x_]:= Piecewise[{{Sin[2 Pi (x-0.2)/0.4],0.2<=x<=0.6},{0,True}}];
coord = Table[j h,{j,0,nPoints-1}];
ic = f1[#]&/@ coord;
h = 1/(nPoints-1);
delT = h/speed;
nSteps=1000;
end = -1;
uNow = ic;
uLast = uNow;
uNext = uNow;

Do[
Which[
n==1,
uNext[[2;;end-1]]=(1/2)(uNow[[1;;end-2]]+uNow[[3;;end]]);
uLast=uNow;
uNow=uNext,

n>2,
uNext[[2;;(end-1)]]=uNow[[1;;(end-2)]]+uNow[[3;;end]]-uLast[[2;;(
end-1)]];
uLast=uNow;
uNow=uNext
];
(*Pause[.02];*)
p=Grid[{
{Row[{"time",Spacer[5],N[n*delT],Spacer[5],"step number",Spacer
[2],n}]},
{ListLinePlot[Transpose[{coord,uNow}],PlotRange
->{{-.1,1.1},{-1,1}},
ImageSize->400,GridLines->Automatic,GridLinesStyle->LightGray],
SpanFromLeft}
407
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

},Alignment->Center
],
{n,1,nSteps}];

Export["images/mma_100.pdf",p]
 

time 0.0287778 step number 1000


1.0

0.5

0.2 0.4 0.6 0.8 1.0

-0.5

-1.0

Matlab
 
%Nasser M. Abbasi July 8, 2014
%solve u_tt = wave_speed * u_xx using leap frog
% 0<x<1
% initial data is f(x)
% initial speed = 0;
% fixed at x=0 and x=1

close all;
nPoints = 100;
speed = 351;
f = @(x) sin(2*pi*(x-0.2)/0.4).*(x>0.2&x<=0.6)
coord = linspace(0,1,nPoints);
ic = f(coord);
h = 1/(nPoints-1);
delT = h/speed;
last = ic;
now = last;
next = now;
nSteps = 500;

for n=1:nSteps
if n==1
next(2:end-1) = 1/2*(now(1:end-2)+now(3:end));
last = now;
408
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

now = next;
else
next(2:end-1) = now(1:end-2)+now(3:end)-last(2:end-1);
last = now;
now = next;
end
plot(now,'r');
xlim([0 nPoints]);
ylim([-1 1]);
grid;
pause(.1);
drawnow;
end

print(gcf, '-dpdf', '-r600', 'images/matlab_100');


 

0.8

0.6

0.4

0.2

-0.2

-0.4

-0.6

-0.8

-1
0 20 40 60 80 100

Ada
 
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.
Elementary_Functions;

procedure foo is
nPoints : constant Integer := 100;
type grid_type is array (1 .. nPoints) of Float;
Output : File_Type;

409
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

nSteps : constant Integer := 500;


speed : constant Float := 351.0;
coord : array (1 .. nPoints) of Float;
h : constant Float := 1.0 / (Float (nPoints) - 1.0);
delT : constant Float := h / speed;
last : grid_type := (others => 0.0);
now : grid_type := last;
next : grid_type := last;

-- output one snapshot to file to plot later


procedure put_rec (rec : in grid_type) is
begin
for i in rec'Range loop
Put (Output, rec (i));
Put (Output,' ');
end loop;
end put_rec;

-- define function of initial data


function f (x : Float) return Float is
begin
if (x > 0.2 and x <= 0.6) then
return Sin (2.0 * Pi * (x - 0.2) / 0.4);
else
return 0.0;
end if;
end f;

begin
Create (File => Output, Mode => Out_File, Name => "output2.txt");

for i in 1 .. nPoints loop


coord (i) := Float (i - 1) * h;
last (i) := f (coord (i));
end loop;

now := last;
next := now;
put_rec (now);
New_Line (File => Output);

for i in 1 .. nSteps loop


if i = 1 then
for j in 2 .. nPoints - 1 loop
next (j) := (1.0 / 2.0) * (now (j - 1) + now (j + 1));
410
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

end loop;
last := now;
now := next;
put_rec (now);
New_Line (File => Output);
else
for j in 2 .. nPoints - 1 loop
next (j) := now (j - 1) + now (j + 1) - last (j);
end loop;
last := now;
now := next;
put_rec (now);
if i < nSteps then
New_Line (File => Output);
end if;
end if;

end loop;

Close (Output);
end foo;
 

The GPR file to build the above is


project One is

for Main use ("foo.adb");


for Source_Files use ("foo.adb");

package Builder is
for Executable_Suffix use ".exe";
end Builder;

package Compiler is
for Default_Switches ("ada") use ("-g", "-gnata", "-gnato", "-fstack-
check",
"-gnatE", "-fcallgraph-
info=su,da");
end Compiler;

end One;

The animation for Ada was done by reading the output and using the plot command in
Matlab to show the result.
 
close all;
411
4.18. How to solve wave equation using . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

A= dlmread('output2.txt');
[nRow,nCol]=size(A);
for i=1:2:nRow
plot(A(i,:))
ylim([-1 1]);
grid;
pause(.1);
drawnow;
end
 

412
4.19. Numerically integrate 𝑓(𝑥) on the . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.19 Numerically integrate 𝑓(𝑥) on the real line


Problem: Integrate

2 1 1 𝑥
� � (322 + 3𝑥 (98 + 𝑥 (37 + 𝑥))) − 24 � 𝑑𝑥
−2 5 100 1 + 𝑥2

The exact answer is 94/25 = 3.76


Mathematica

f[x_] := (1/5)(1/100(322+3*x(98+x(37+x)))- Out[15]= 94/25


24(x/(1+x^2)))
r = Integrate[f[x],{x,-2,2}]

N[r] Out[17]= 3.76

To compare with Matlab, replace 1 by 1.0 in the expression (or use


N)
Out[62]=
f[x_]:=(1.0/5)(1/100(322+3*x(98+x(37+x)))-
3.7600000000000007
24(x/(1+x^2)))
r = Integrate[f[x],{x,-2,2}];
InputForm[r]

Matlab

clear all; ans =


format long
f=@(x)(1/5)*(1/100*(322+3*x.*(98+x.*(37+x)))... 3.760000000000001
-24*(x/(1+x.^2)));
integral(f,-2,2)

ans =
integral(f,-2,2,'AbsTol',1e-6,'RelTol',1e-6)
3.760000000000001

413
4.20. Numerically integrate 𝑓(𝑥, 𝑦) in 2D CHAPTER 4. DIFFERENTIAL, PDE . . .

4.20 Numerically integrate 𝑓(𝑥, 𝑦) in 2D


Problem: Integrate

10 14
� � �𝑥2 + 4𝑦� 𝑑𝑥𝑑𝑦
7 11

The exact answer is 1719


Mathematica

f[x_,y_] := x^2+4 y Out[69]= 1719


r = Integrate[f[x,y],{x,11,14},{y,7,10}]

Matlab

clear all; ans =


format long 1.719000000000004e
f=@(x,y) x.^2+4*y; +03
integral2(f,11,14,7,10)

414
4.21. How to solve set of differential . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.21 How to solve set of differential equations in vector


form
Given differential equations, written in vector form, as in
⎛ ⎞ ⎛ ⎞
⎜⎜𝑦′ (𝑡)⎟⎟ ⎜⎜𝑓(𝑡, 𝑦(𝑡), 𝑥(𝑡))⎟⎟
⎜⎜ ⎟ ⎜ ⎟
⎝𝑥′ (𝑡)⎟⎠ = ⎜⎝ 𝑔(𝑡, 𝑦(𝑡), 𝑥(𝑡)) ⎟⎠

How to solve them?


Reference: mathematica.stackexchange.com/questions/76713
Maple

restart;
A:=<1,0,0>;
p:=t-> <p1(t),p2(t),p3(t)>:
q:=t-> <q1(t),q2(t),q3(t)>:
eq1:= diff~(p(t),t) = LinearAlgebra[CrossProduct](A,q(t));

⎡ d ⎤ ⎡ ⎤
⎢⎢
⎢⎢ d𝑡
p1 (𝑡) ⎥⎥ ⎢⎢
⎥⎥ ⎢⎢ 0 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ d ⎥⎥ = ⎢⎢ −q3 (𝑡) ⎥⎥
⎢⎢ p2 (𝑡) ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ d𝑡 ⎥⎥ ⎢⎢ ⎥⎥
⎢⎣ ⎥⎦ ⎣ ⎥⎥
d ⎦
p3 (𝑡) q2 (𝑡)
d𝑡
eq2:= diff~(q(t),t) = LinearAlgebra[CrossProduct](A,p(t));

⎡ d ⎤ ⎡ ⎤
⎢⎢
⎢⎢ d𝑡
q1 (𝑡) ⎥⎥ ⎢⎢
⎥⎥ ⎢⎢ 0 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ d ⎥⎥ = ⎢⎢ −p3 (𝑡) ⎥⎥
⎢⎢ q2 (𝑡) ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ d𝑡 ⎥⎥ ⎢⎢ ⎥⎥
⎢⎣ ⎥⎦ ⎣ ⎥⎥
d ⎦
q3 (𝑡) p2 (𝑡)
d𝑡
ic1:= p(0)=<0.5, 0.5, 0.3>;

⎡ ⎤ ⎡ ⎤
⎢⎢ p1 (0) ⎥⎥ ⎢⎢ 0.5 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥
⎢⎢ p2 (0) ⎥⎥ = ⎢⎢ 0.5 ⎥⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥

p3 (0) ⎦ ⎣ 0.3 ⎦
ic2:= q(0)=<0.1, 0.2, 0.3>;

415
4.21. How to solve set of differential . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

⎡ ⎤ ⎡ ⎤
⎢⎢ q1 (0) ⎥⎥ ⎢⎢ 0.1 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥ ⎢ ⎥
⎢⎢ q2 (0) ⎥⎥⎥ = ⎢⎢⎢ 0.2 ⎥⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥

q3 (0) ⎦ ⎣ 0.3 ⎦
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(𝑡) ⎥⎥ ⎢ 1/2 ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ p2 (𝑡) ⎥⎥ ⎢⎢ −3/10 sin (𝑡) + 1/2 cos (𝑡) ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ p3 (𝑡) ⎥⎥ ⎢⎢ 1/5 sin (𝑡) + 3/10 cos (𝑡) ⎥⎥
⎢⎢ ⎥⎥ = ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢
⎢⎢
q1 (𝑡) ⎥⎥ ⎢⎢
⎥⎥ ⎢⎢
1/10 ⎥⎥
⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ q2 (𝑡) ⎥⎥ ⎢⎢ 1/5 cos (𝑡) − 3/10 sin (𝑡) ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎢⎢ ⎥⎥ ⎢⎢ ⎥⎥
⎣ ⎦ ⎣ ⎦
q3 (𝑡) 3/10 cos (𝑡) + 1/2 sin (𝑡)

Mathematica

Clear[P, A, t]
A = {1, 0, 0}
P[t_] = {P1[t], P2[t], P3[t]}
Q[t_] = {Q1[t], Q2[t], Q3[t]}
sol = DSolve[{P'[t] == Cross[A, Q[t]], Q'[t] == Cross[A, P[t]],
P[0] == {0.5, 0.5, 0.3}, Q[0] == {0.1, 0.2, 0.3}},
Flatten@{P[t], Q[t]}, t]
MatrixForm@{sol}

⎛ ⎛ ⎞ ⎞
⎜⎜ ⎜⎜ P1(𝑡) → 0.5 ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ P2(𝑡) → 0.5 cos(𝑡) − 0.3 sin(𝑡) ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ Q3(𝑡) → 0.5 sin(𝑡) + 0.3 cos(𝑡) ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ P3(𝑡) → 0.2 sin(𝑡) + 0.3 cos(𝑡) ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ ⎟⎟ ⎟⎟
⎜⎜ ⎜⎜ Q2(𝑡) → 0.2 cos(𝑡) − 0.3 sin(𝑡) ⎟⎟ ⎟⎟
⎜⎝ ⎜⎝ ⎟⎠ ⎟⎠
Q1(𝑡) → 0.1

416
4.22. How to implement Runge-Kutta to . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.22 How to implement Runge-Kutta to solve


differential equations?
4.22.1 First order ODE
𝑑𝑥 1 1 1−cos(𝑡)
Solve 𝑑𝑡
= 𝑥(𝑡) sin(𝑡) with initial conditions 𝑥(0) = 10
. The exact solution is 10
𝑒
Find 𝑥(𝑡) for 5 seconds, using Δ 𝑡 = 0.001
Matlab
 
function [x,t] = nma_RK4_2( )
%solve dx/dt= x*sin(t); with x(0)=1/10 which has solution
%x(t)=1/10*exp(1-cos(t));

delT = 0.001; %time grid


t = linspace(0,5,round(5/delT)); %time
N = length(t);
x = zeros(N,1);
x(1) = 0.1; %initial conditions
for i = 1:(N-1)
k1 = delT * f( t(i) , x(i) );
k2 = delT * f( t(i)+1/2*delT , x(i)+1/2*k1 );
k3 = delT * f( t(i)+1/2*delT , x(i)+1/2*k2 );
k4 = delT * f( t(i)+delT , x(i)+k3 );
x(i+1) = x(i)+1/6*(k1+2*k2+2*k3+k4);
end

function r=f(t,x) %change RHS as needed


r=x*sin(t);
end
end
 

Now call the above function and plot the solution


[x,t]=nma_RK4_2();
plot(t,x)

417
4.22. How to implement Runge-Kutta to . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

0.8

0.7

0.6

0.5

0.4

0.3

0.2

0.1
0 1 2 3 4 5

4.22.2 second order ODE


To solve second (and higher order ODE’s), we have to first rewrite the ODE as set of first
order ODE and only then implement RK similarly to the above. There will be a 𝑘𝑖 parameters
for each first order ODE in the set. For this example, since we have two first order ode’s
(since it is second order ODE), we can call the parameters for the first oder ODE 𝑘𝑖 and for
the second order ODE 𝑧𝑖 . For higher order, we can use a matrix to keep track of the RK
parameters.
Solve 𝑥″ (𝑡) = 𝑥(𝑡) + 𝑥′ (𝑡)2 − 5𝑡𝑥′ (𝑡) with initial conditions 𝑥(0) = 2, 𝑥′ (0) = 0.01. The right hand
side is 𝑓(𝑥, 𝑥′ (𝑡), 𝑡) = 𝑥(𝑡) + 𝑥′ (𝑡)2 − 5𝑡𝑥′ (𝑡). This is non-linear second order ode.
The first step is to convert this to two first order odes. Let 𝑥 = 𝑥(𝑡) and 𝑣(𝑡) = 𝑥′ (𝑡), hence
𝑥′ (𝑡) = 𝑣(𝑡) and 𝑣′ (𝑡) = 𝑥″ (𝑡) = 𝑓(𝑥, 𝑣, 𝑡).
Matlab
 
function [x,v,t] = nma_RK4_3( )
%solve x''(t)=x - 5 t x'(t) + (x'(t))^2 with x(0)=2,x'(0)=0.01,

delT = 0.001; %time grid


t = linspace(0,5,round(5/delT)); %time
N = length(t);
x = zeros(N,1);
v = zeros(N,1);
x(1) = 2; %initial conditions
v(1) = 0.01;

for i = 1:(N-1)
k1 = delT * v(i);
z1 = delT * f( t(i) , x(i) , v(i) );

k2 = delT * (v(i) + 1/2* z1);

418
4.22. How to implement Runge-Kutta to . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

z2 = delT * f( t(i)+1/2*delT , x(i)+1/2*k1 , v(i)+1/2*z1);

k3 = delT * (v(i) + 1/2* z2);


z3 = delT * f( t(i)+1/2*delT , x(i)+1/2*k2 , v(i)+1/2*z2);

k4 = delT * (v(i) + z3);


z4 = delT * f( t(i)+delT , x(i)+k3 , v(i)+z3);

x(i+1) = x(i)+1/6*(k1+2*k2+2*k3+k4);
v(i+1) = v(i)+1/6*(z1+2*z2+2*z3+z4);
end

function r=f(t,x,v)
r=x - 5*t*v + v^2;
end
end
 

The above function is called the solution is plotted


[x,v,t]=nma_RK4_3();
plot(t,x);
plot(t,v);

Here is plot result


4

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

419
4.22. How to implement Runge-Kutta to . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

A better way to do the above, which also generalized to any number of system of equations
is to use vectored approach. Writing

[𝑥]̇ = �𝑓(𝑡, 𝑥, 𝑥′ , … )�

Where now [𝑥] is the derivative of state vector and �𝑓(𝑡, 𝑥, 𝑥′ , … )� 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.
 
function [x,t] =nma_RK4_4( )
%solve x''(t)=x - 5 t x'(t) + (x'(t))^2 with x(0)=2,x'(0)=0.01,

delT = 0.001; %time grid


t = linspace(0,5,round(5/delT)); %time
N = length(t);
x = zeros(2,N);
x(1,1) = 2; %initial conditions
x(2,1) = 0.01;

for i = 1:(N-1)
k1 = delT * f( t(i) , x(:,i));
k2 = delT * f( t(i)+1/2*delT , x(:,i)+1/2*k1);
k3 = delT * f( t(i)+1/2*delT , x(:,i)+1/2*k2);
k4 = delT * f( t(i)+delT , x(:,i)+k3);

x(:,i+1) = x(:,i)+1/6*(k1+2*k2+2*k3+k4);
end

function r=f(t,x)
r=[x(2)
x(1)-5*t*x(2)+x(2)^2];
end
end
 

The above is called as follows


[x,t]=nma_RK4_4();
plot(t,x(1,:)) %plot the position x(t) solution
plot(t,x(2,:)) %plot the velocity x'(t) solution

Same plots result as given above.

420
4.23. How to differentiate treating a . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.23 How to differentiate treating a combined


expression as single variable?
Problem: Differentiate

2𝑟 2
𝑟 𝑟
𝑒 √𝑎 + 3 � �+� �
√𝑎 √𝑎
𝑟
w.r.t to produce
√𝑎
2𝑟
𝑟
2𝑒 √𝑎 + 3 + 2
√𝑎
𝑟
In other words, we want to treat as 𝑥 in the expression
√𝑎

𝑒2𝑥 + 3𝑥 + 𝑥2

Mathematica

Clear[p, x, r, a]
p[x_] := Exp[2 x] + x^2 + 3*x;
2𝑟
v = r/Sqrt[a]; 2𝑟
+ 2𝑒 √𝑎 + 3
With[{v = x}, Inactive[D][p[v], v]]; √𝑎
Activate[%];
% /. x -> v

Maple

Credit for the Maple answer goes to an internet


post by Carl Love 2
𝑟
𝑟
2e √𝑎 +3+2
restart; √𝑎
D(x->exp(2*x)+3*x+x^2) (r/sqrt(a));

421
4.24. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

4.24 How to solve Poisson PDE in 2D with Neumann


boundary conditions using Finite Elements
Solve ▽2 𝑇 − 20𝑇 = −20 on the unit square 0 ≤ 𝑥 ≤ 1, 0 ≤ 𝑦 ≤ 1 subject to insulated boundary
conditions at 𝑥 = 0 and 𝑦 = 0 and 𝑇 = 0 at 𝑥 = 1, 𝑦 = 1.

4.24.1 Mathematica
In Mathematica 10.0, one can use Finite elements directly. Here is the code to solve the
above.
ContourPlot[r[x,y],{x,0,1},{y,0,1}]

Plotting the solution


ContourPlot[r[x,y],{x,0,1},{y,0,1}]

Now we make a contour plot


ContourPlot[r[x,y],{x,0,1},{y,0,1}]

422
4.24. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

1.0

0.8

0.6

0.4

0.2

0.0
0.0 0.2 0.4 0.6 0.8 1.0

423
4.24. How to solve Poisson PDE in 2D . . . CHAPTER 4. DIFFERENTIAL, PDE . . .

424
Chapter 5

plotting how to, ellipse, 3D

5.1 Generate a plot using x and y data


Problem: Generate 𝑥 and 𝑦 data for 𝑠𝑖𝑛(𝑥) and plot the data.

Mathematica

Remove["Global`*"];
data = Table[{x,Sin[x]}, plot of sin(x)

{x, -2Pi,2 Pi,Pi/100}]; 1.0

ListPlot[data,
Frame -> True, 0.5

GridLines->Automatic,
GridLinesStyle->Dashed,
sin(x)

0.0

ImageSize->300,
-0.5
AspectRatio->1,
PlotStyle->Red,
-1.0
FrameLabel->{{"sin(x)",None}, -6 -4 -2 0 2 4 6

{"x","plot of sin(x)"}}, x

FrameTicks->{{-2Pi,-Pi,0,Pi,2Pi},
None,Automatic,None}
]

425
5.1. Generate a plot using x and y data CHAPTER 5. PLOTTING HOW TO, . . .

Matlab

plot of sin(x)
clear all; 1

x = -2*pi:pi/100:2*pi;
plot(x,sin(x),'r'); 0.5

grid on;
title('plot of sin(x)');

sin(x)
0
xlabel('x');
ylabel('sin(x)'); -0.5
set(gca,'XTick',-2*pi:pi:2*pi)
set(gca,'XTickLabel',... -1
{'-2*pi','-pi','0','pi','2*pi'}) -2*pi -pi 0
x
pi 2*pi

set(gcf,'Position',[10,10,340,340]);

Maple

restart; with(plots);
lis := [seq(sin((1/100)*theta), theta = 1 ..
1000)];
listplot(lis, axes = box)

426
5.2. Plot the surface described by 2D function CHAPTER 5. PLOTTING HOW TO, . . .

5.2 Plot the surface described by 2D function


Problem: Plot the function
𝑓(𝑥, 𝑦) = 𝑥2 − 2𝑥𝑦 + 3𝑦 + 2

Mathematica

Remove["Global`*"];
f[x_,y_]:=x^2-2x y+3y+2;
Plot3D[f[x,y],{x,-4,4},{y,-3,3},
PlotLabel->"Plot of x^2-2x y+3y+2",
ImageSize->300]

Matlab
plot of z=x2-2(x y)+3y+2

clear all; close all; 60

x = -4:.3:4;
40
y = -3:.3:3;
[X,Y] = meshgrid(x,y); 20

Z = X.^2 - 2*(X.*Y) + 3*Y + 2; 0

surf(X,Y,Z) -20

title('plot of z=x^2-2(x y)+3y+2');


4
2 4
0 2
set(gcf,'Position',[10,10,420,420]); -2
-2
0

-4 -4

427
5.3. Find the point of intersection of 3 . . . CHAPTER 5. PLOTTING HOW TO, . . .

5.3 Find the point of intersection of 3 surfaces


Problem: Given 3 surfaces find the point where they intersect by solving the linear system
and display the solution.
Let the 3 surfaces be

𝑧 = 2𝑥 + 𝑦
𝑧 = 2𝑦
𝑧=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

Remove["Global`*"];
eq1 = z-2x-y ==0;
eq2 = z-2y ==0;
eq3 = z- 2 ==0;
p1 = ContourPlot3D[Evaluate@eq1,
{x,-5,5},{y,-5,5},{z,-10,10},
AxesLabel->{"x","y","z"},
PlotLabel->"z=2x+y",
ImageSize->250];
p2 = ContourPlot3D[Evaluate@eq2,
{x,-5,5},{y,-5,5},{z,-10,10},
AxesLabel->{"x","y","z"},
PlotLabel->"z=2x",
ImageSize->250];
p3 = ContourPlot3D[Evaluate@eq3,
{x,-5,5},{y,-5,5},{z,-10,10},
AxesLabel->{"x","y","z"},
PlotLabel->"z=2",
ImageSize->250];
Grid[{{p1,p2,p3}},Frame->All]

428
5.3. Find the point of intersection of 3 . . . CHAPTER 5. PLOTTING HOW TO, . . .

{b,a} = CoefficientArrays[{eq1,eq2,eq3},
{x,y,z}];
sol = LinearSolve[a,-b]//N

Out[301]= {0.5,1.,2.}

Show[p1,p2,p3,
Graphics3D[{PointSize[0.2],
Red,Point[sol]}],
PlotLabel->"point where surfaces meet)"]

429
5.3. Find the point of intersection of 3 . . . CHAPTER 5. PLOTTING HOW TO, . . .

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');

A=[-2 -1 1;0 -2 1;0 0 1];


b=[0;0;2];
sol=A\b

figure;
surf(X,Y,2*X + Y); hold on;
surf(X,Y,2*Y);
surf(X,Y,Z);

%now add the point of intersection


%from the solution

plot3(sol(1),sol(2),sol(3),...
'k.','MarkerSize',30)

title('solution to system of linear equations.');

sol =

0.5000
1.0000
2.0000

430
5.3. Find the point of intersection of 3 . . . CHAPTER 5. PLOTTING HOW TO, . . .

431
5.4. How to draw an ellipse? CHAPTER 5. PLOTTING HOW TO, . . .

5.4 How to draw an ellipse?


5.4.1 draw an ellipse centered at origin and given its
semi-major/minor (𝑎, 𝑏)
draw an ellipse centered at (0, 0) with 𝑎 = 2, 𝑏 = 1 being its semi-major and minor.
𝑥2 𝑥2
The ellipse equation for the above is + =1
𝑎2 𝑏2

Mathematica 1.0

0.5
a = 2;
b = 1; -2 -1 1 2

Graphics[Circle[{0, 0}, {a, b}], Axes


-> True]
-0.5

-1.0

1.5

Matlab 1

a=2; 0.5

b=1; 0

t=linspace(0,2*pi,50);
plot(a*cos(t),b*sin(t)) -0.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 (𝑥, 𝑦) and given its


semi-major/minor (𝑎, 𝑏)
draw an ellipse centered at (1, 2) with 𝑎 = 2, 𝑏 = 1 being its semi-major and minor. The ellipse
𝑥2 𝑥2
equation for the above is + =1
𝑎2 𝑏2

432
5.4. How to draw an ellipse? CHAPTER 5. PLOTTING HOW TO, . . .

Mathematica

a = 2; 3.0

b = 1; 2.5
Graphics[
{ 2.0

Circle[{1, 2}, {a, b}], 1.5


Point[{1, 2}]
}, Axes -> True -1 1 2 3

Matlab 4

3.5

close all; 3

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 (𝑎, 𝑏) and rotated at angle 𝜃
draw an ellipse centered at (0, 0) with 𝑎 = 2, 𝑏 = 1 being its semi-major and minor titlted at
angle 𝜃 = 30 degrees anti-clockwise.
𝑥2 𝑥2
The ellipse equation for the above is + = 1. After drawing it, we rotate it.
𝑎2 𝑏2

433
5.4. How to draw an ellipse? CHAPTER 5. PLOTTING HOW TO, . . .

Mathematica

a = 2;
b = 1;
Graphics[ 1.0

Rotate[
{Circle[{0, 0}, {a, b}],
0.5

Line[{{-a, 0}, {a, 0}}], -1.5 -1.0 -0.5 0.5 1.0 1.5

Line[{{0, -b}, {0, b}}]


}
-0.5

, 30 Degree -1.0

]
, Axes -> True
]

Matlab

Matlab does not have rotate function, so use the ro-


tation tranformation matrix.
close all;
a = 2; 1

b = 1; 0.5

t = linspace(0,2*pi,50);
rotateAngle = 30*pi/180; 0

mat = [cos(rotateAngle) -sin(rotateAngle) -0.5

sin(rotateAngle) cos(rotateAngle)];
-1

%2x2 times 2x50 = 2x50 -1.5 -1 -0.5 0 0.5 1 1.5

data = mat*[a*cos(t);b*sin(t)];
plot(data(1,:),data(2,:))
axis equal

434
5.5. How to plot a function on 2D using . . . CHAPTER 5. PLOTTING HOW TO, . . .

5.5 How to plot a function on 2D using coordinates of


grid locations?
Sometimes in finite difference we want to evaluate the force or the function in the RHS of
the equation 𝑓(𝑥, 𝑦) using the coordinates 𝑥, 𝑦 on a 2D grid. The grid spacing can be ℎ and
the coordinates extend from some 𝑥 value to some other 𝑥 value and from some 𝑦 value to
some other 𝑦 values. In Matlab, the coordinates are setup using meshgrid.
In Mathematica, there is really no need for meshgrid as the build-in command Map can be
used to evaluate the function at each grid point. The coodinates physical values are generated
using the Table command. Here is example evaluating and plotting 𝑓(𝑥, 𝑦) = sin(10𝑥𝑦)𝑒−𝑥𝑦
on a grid of spacing ℎ = 1/𝑁 where 𝑁 is number of elements. The grid goes from 𝑥 = −1 to
𝑥 = 1 by spacing of ℎ. Same for the 𝑦 direction.

Mathematica

Clear[x, y, z];
nElem = 10.;
h = 1/nElem
N@Range[-1, 1, h]
grid = N@Table[{i, j}, {i, -1, 1, h}, {j, -1,
1, h}];
f[x_, y_] := Sin[x*10 y] Exp[-x y];
force = Map[f[#[[1]], #[[2]]] &, grid, {2}];
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:

435
5.5. How to plot a function on 2D using . . . CHAPTER 5. PLOTTING HOW TO, . . .

meshgrid[x_List,y_List]:={ConstantArray[x,
Length[x]],
Transpose@ConstantArray[y, Length[y]]};

nElem = 10.;
h = 1/nElem;
{x, y} = meshgrid[Range[-1, 1, h], Range[-1,
1, h]];
f[x_, y_] := Sin[x*10 y] Exp[-x y];
force = f[x, y];
pts = Flatten[{x, y, force}, {2, 3}];
ListPlot3D[pts, PlotRange -> All,
AxesLabel -> Automatic, ImagePadding ->
20,
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)

436
5.6. How to make table of 𝑥, 𝑦 values and . . . CHAPTER 5. PLOTTING HOW TO, . . .

5.6 How to make table of 𝑥, 𝑦 values and plot them


Generate a list or table of (𝑥, sin(𝑥)) values and plot them.
1.0

Mathematica
0.5

lst=Table[{x, Sin[x]}, {x, -Pi, Pi, 1/10}]; -3 -2 -1 1 2 3

ListLinePlot[lst] -0.5

-1.0

Matlab

Matlab does not have a nice function like Table so one


can either make the 𝑥 variable and then use it to make
sin(𝑥) 1

0.8

or use arrayfun 0.6

0.4

close all; 0.2

x=-pi:.1:pi; 0

-0.2
plot(x,sin(x)); -0.4

-0.6

Using arrayfun -0.8

-1

A=cell2mat(arrayfun(@(x) [x;sin(x)],... -4 -3 -2 -1 0 1 2 3 4

-pi:.1:pi, 'UniformOutput',false));
plot(A(1,:),A(2,:))

437
5.7. How to make contour plot of 𝑓(𝑥, 𝑦) ? CHAPTER 5. PLOTTING HOW TO, . . .

5.7 How to make contour plot of 𝑓(𝑥, 𝑦) ?


Problem: Make contour of 𝑓(𝑥, 𝑦) = (11 − 𝑥 − 𝑦)2 + (1 + 𝑥 + 10𝑦 − 𝑥𝑦)2 over region 0 < 𝑥 < 20 and
0 < 𝑦 < 10.
Contour label placement seems to be better in Matlab. It is put in the middle of the line
automatically.

Mathematica
15

f = (11 - x - y)^2 + (1 + x + 10 y - x y)^2; 9700

ContourPlot[f, {x, 0, 20}, {y, 0, 15},


8730
7760
10 9700 6790
8730 5820
7760 4850

Contours -> 10, ContourShading -> None, 6790 3880


5820
Out[15]= 2910
4850
3880 1940

ContourLabels -> Function[{x, y, z}, 5 2910 970


1940
970

Text[z, {x, y}]], AspectRatio -> Automatic, 0

PlotRangePadding -> 2] 0 5 10 15 20

Matlab 15
Contours Labeled Using clabel(C,h)

.90 5
x = 0:0.05:20;
5
91
.54

727

62
51
22

1.2
51

y = 0:0.05:15;

.90
83

41
62
418

91
81
.2
10
[x,y] = meshgrid(x,y);

727
21
10
.6
z = (11-x-y).^2 + (1+x+10*y-x.*y).^2;

36
4
64
[C,h] =contour(x,y,z,10);
3
.6
10
21
5
clabel(C,h)
title('Contours Labeled Using clabel(C,
h)')
0
0 5 10 15 20

438
Chapter 6

Some symbolic operations

6.1 How to find all exponents of list of expressions?


Given {𝑓2 , 𝑔3 , 𝑘𝑝 , ℎ} write code to return {2, 3, 𝑝, 1} as the exponents.

Mathematica

ClearAll[f, g, k, p, h];
lst = {f^2, g^3, k^p, h}; {2, 3, p, 1}
Cases[lst, x_^n_. :> n]

Maple

unassign('f,g,k,p,h');
foo:=proc(expr)
if nops(expr)=1 then
return 1;
elif hastype(expr,`^`) then
return( op(2,expr) ); [2, 3, p, 1]
fi;
return(NULL);
end proc:

expr:=[f^2, g^3, k^p, h]:


map(foo,expr)

439
6.1. How to find all exponents of list of . . . CHAPTER 6. SOME SYMBOLIC . . .

This document was compiled using


Text Font: Baskervaldx-Reg-tlf-t1 at 12.0pt
Math Operator Font: AsanaMath:mode=base;script=math;language=dflt; at 11.1947pt
Math Letter Font: cmmi12

440

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy