Lecture Notes Prepared By: Dr. Mahmoud Alnaanah Last Update:9. May. 2021 Page (1) Introduction ✔ Matlab stands for Matrix Laboratory. ✔ It is widely used in the scientific field and it has many powerful toolboxes to deal with many scientific area ✔ It mainly has a command line interpreter and many functions for each toolbox. ✔ It has Simulink, which is used to design systems from the different toolboxes (control, communications, etc) graphically as connected blocks. ✔ Some toolboxes: Antenna Toolbox Audio System Toolbox Communications System Toolbox Computer Vision System Toolbox Control System Toolbox DSP System Toolbox Fuzzy Logic Toolbox Image Processing Toolbox LTE System Toolbox Neural Network Toolbox Partial Differential Equation Toolbox Signal Processing Toolbox Statistics and Machine Learning Toolbox Symbolic Math Toolbox Wavelet Toolbox Page (2) Full List of Matlab Toolboxes Simulink Aerospace Blockset Aerospace Toolbox Antenna Toolbox Audio System Toolbox Automated Driving System Toolbox Bioinformatics Toolbox Communications System Toolbox Computer Vision System Toolbox Control System Toolbox Curve Fitting Toolbox DSP System Toolbox Data Acquisition Toolbox Database Toolbox Datafeed Toolbox Econometrics Toolbox Embedded Coder Filter Design HDL Coder Financial Instruments Toolbox Financial Toolbox Fixed-Point Designer Fuzzy Logic Toolbox Global Optimization Toolbox HDL Coder HDL Verifier Image Acquisition Toolbox Image Processing Toolbox Instrument Control Toolbox LTE System Toolbox MATLAB Coder MATLAB Compiler MATLAB Compiler SDK MATLAB Report Generator Mapping Toolbox Model Predictive Control Toolbox Model-Based Calibration Toolbox Neural Network Toolbox OPC Toolbox Optimization Toolbox Parallel Computing Toolbox Partial Differential Equation Toolbox Phased Array System Toolbox Polyspace Bug Finder Polyspace Code Prover Powertrain Blockset RF Blockset RF Toolbox Risk Management Toolbox Robotics System Toolbox Robust Control Toolbox Signal Processing Toolbox SimBiology SimEvents Simscape Simscape Driveline Simscape Electronics Simscape Fluids Simscape Multibody Simscape Power Systems Simulink 3D Animation Simulink Code Inspector Simulink Coder Simulink Control Design Simulink Design Optimization Simulink Design Verifier Simulink Desktop Real-Time Simulink PLC Coder Simulink Real-Time Simulink Report Generator Simulink Test Simulink Verification and Validation Spreadsheet Link Stateflow Statistics and Machine Learning Toolbox Symbolic Math Toolbox System Identification Toolbox Trading Toolbox Vehicle Network Toolbox Vision HDL Toolbox WLAN System Toolbox Wavelet Toolbox Page (3) Matlab Alternatives ✔ ✔ Matlab is a commercial software and requires payment for licensing. There are open-source alternatives such as: ▸ GNU Octave: (www.gnu.org/software/octave/) Pros: Has good compatibility with Matlab Pros: Lightweight and requires less resources and boots faster. Pros: Can be used online (https://octave-online.net/) Cons: No SimuLink. Cons: Limited number of toolboxes. ▸ Scilab (www.scilab.org) Pros: Has Xcos which is similar (but not equivalent) to SimuLink Cons: Low compatibility with Matlab ▸ Python: Pros: Widely adopted for scientific research Pros: Extendable Pros: Ability to use online with Google Colab (https://colab.research.google.com/) Cons: The syntax is different and not compatible with Matlab. Page (4) Notes ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ In general, the main idea behind Matlab is to create scalars, and matrices (with one or more dimension) and manipulate them. A vector is 1xN matrix (or row vector) or Nx1 matrix (or column vector) Any text after the percentage sign (%) is considered as a comment and will not be executed by Matlab. The colon operator ( : ) is used to create iterated matrix as follows: start:end like 1:5 gives 1,2,3,4,5 start:step:end like 1:2:10 gives 1,3,5,7,9. steps also called iterations. A comma ( , ) is used to separate elements horizontally and a semicolon ( ; ) is used to separate elements vertically. By default, Matlab stores variables and Matrices using double precision (requires 8 bytes per element) By default, Matlab shows the output of the current statement in the command window and a semicolon ( ; ) at the end of the statement will prevent that. Three dots ( ... ) at the end of a line means the completion of the statement on next line. Page (5) Getting started ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ in command window, enter the following (before the comment %) and see the results a a a a b a b = = = = = = 10 % defining a variable 2e3 % exponent in scientific notation 2e-3 % negative exponent 3 10 * a 5 % changing the value of a will not change the value of b % enter the name of the variable to display its values m1 = [0:5] % entering a row vector m1 = [0:5]; % use semicolon to prevent displaying the output m2 = [0:0.1:1] % using step m2 = 0:0.1:1 % the same without brackets m3 = [7:-1:1] % negative step m4 = [1,2,3,4] % comma to separate columns m4 = [1 2 3 4] % spaces could be used instead of commas m5 = [1;2;3;4] % semicolon to separate rows m6 = [1,2,3,4;5,6,7,8] % two rows matrix A = [1,2,3,4, ... 5,6,7] % three dots (...) are used to continue on the next line a =5 , b = 6 % comma (,)is used to separate multiple statements Page (6) ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ % the output of each statement is shown a = 5; b = 6 % semicolon (;) is used to separate multiple statements % without showing the output of the statements before it who % display variables whos m1 . m2 % display variables m1, m2 in details whos % display all variables in details clear m1 . m2 % clear m1 and m2 variables whos % list all variable clear all % clear all variables pwd % display the path of the current directory ls % display the file in the current directory ls -l % display file with details clc % clear the command window help clc % get help for clc command date % display date datetime % display date and time CLC % (gives error)Matlab is case-sensitive, therefore CLC % is not the same as clc or Clc Page (7) Array and matrix arithmetic operators ✔ MATLAB® has two different types of arithmetic operations: array operations and matrix operations. ✔ Array operations between two matrices is done element-by-element, therefore the size of the two matrices must be equal. Array operators are: Operator Purpose + Addition + Unary plus Subtraction Unary minus .* Element-wise multiplication .^ Element-wise power ./ Right array division .\ Left array division .' Array transpose Description A+B adds A and B. +A returns A. A-B subtracts B from A -A negates the elements of A. A.*B is the element-by-element product of A and B. A.^B is the matrix with elements A(i,j) to the B(i,j) power. A./B is the matrix with elements A(i,j)/B(i,j). A.\B is the matrix with elements B(i,j)/A(i,j). A.' is the array transpose of A. For complex matrices, this does not involve conjugation. Page (8) ✔ Matrix operations follow the rules of linear algebra and they are: Purpose Description * \ / ^ Matrix ✔ C = A*B is the linear algebraic product of the matrices A and B. The number of multiplication columns of A must equal the number of rows of B. Matrix left x = A\B is the solution to the equation Ax = B. Matrices A and B must have the same division Matrix right number of rows. x = B/A is the solution to the equation xA = B. Matrices A and B must have the same division number of columns. In terms of the left division operator, B/A = (A'\B')'. Matrix power Complex ' Reference Page conjugate transpose A^B is A to the power B, if B is a scalar. For other values of B, the calculation involves eigenvalues and eigenvectors. A' is the linear algebraic transpose of A. For complex matrices, this is the complex conjugate transpose. Operations between a scalar and a matrix are applied as array operation with all elements of the matrix. Page (9) Arithmetic operations ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ 5 + 2\4 + 2^4 + 5/10 % notice left and right division a = [1,2,3,4] b = a' % transpose operators a * b % algebraic matrix multiplication b * a a .* b % invalid b .* a % invalid 2 .^ a % array power operator a .^ 2 % array power operator a ^ 2 % invalid m = magic(3) % magic matrix I = eye(3) % 3x3 identity matrix c = I / m % inverse c = m \ I % inverse d = I / c % inverse e = inv(m) % another way to find the inverse a = [1:5] -a + 5 * a % operation between a scalar and a matrix Page (10) Operation Precedence ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ 8 + 3*5 (8 + 3)*5 4^2 - 12 - 8/4*2 4^2 - 12 - 8/(4*2) 3*4^2 + 5 (3*4)^2 + 5 27^(1/3) + 32^(0.2) 27^(1/3) + 32^0.2 27^1/3 + 32^0.2 Page (11) Built-in Variables ans pi eps inf NaN i and j realmin realmax Default variable name for results Value of pi Smallest incremental number Infinity Not a number e.g. 0/0 i = j = square root of -1 The smallest usable positive real number The largest usable positive real number Page (12) Built-in Functions ✔ ✔ ≫ ≫ ≫ ≫ Function are applied to the elements of the a matrix. Examples: a = pi sin(a) m = [0:pi/10:pi] cos(m) Page (13) Trigonometric Function Argument ✔ The argument of a trigonometric function must be in radian. ✔ To use argument in degrees, the argument should be converted to radians by multiplying it with (pi/180). For example, to find cos(90°) then cos(90*pi/180) should be used. ✔ The functions: cosd, sind, tand, cscd, secd, and cotd accept arguments in degrees. ✔ The functions: acosd, asind, atand, acscd, asecd, and acotd return angle in degrees. Page (14) Plotting ✔ More about plotting, see the link: ✔ https://www.mathworks.com/help/matlab/ref/plot.html ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ x = [-pi:pi/20:pi] y1 = sin(x) y2 = cos(x) plot(y1) % you can specify y-vector without x-vector plot(x,y1) % x-vector comes before y-vector plot(x,y2) % by default, new plot will erase previous one figure() % create new figure plot(x,y1,x,y2) % muliple functions, x-vector must be specified for each y-vector figure() plot(x,y1,'-gs',x,y2,'-.bo') % specifying line properties (more details in page 19) figure() plot(x,y1) hold on % do not erase previous plots plot(x,y2) grid on % turning grid on axis off % turning axis off axis on title('Example Figure') xlabel('x variable') % x-axis label Page (15) ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ylabel('sin(x) and cos(x)') % y-axis label xlim([-pi/2,pi/2]) % x axis limits ylim([-2,2]) % y axis limits xticks([-pi/2:pi/10:pi/2]) % adjusting x axis ticks values yticks([-2:.2:2]) % adjusting x axis ticks values legend('First curve','Second curve','Location','northwest') % Enables the mouse to get n points from a plot, and returns % the x and y coordinates as a vectors, which have a length n=3. [x,y] = ginput(3) gtext('text') % Enables placement of text with the mouse. % Draw a circle with radius 2 r=2 ; theta = linspace(0,2* pi); x = r*cos(theta) ; y = r*sin(theta) ; plot(x,y); axis equal Page (16) Exercises Page (17) Subplots ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ x = linspace(0,10); y1 = sin(x); subplot(2,2,1) plot(x,y1) title('Subplot 1: sin(x)') y2 = sin(2*x); subplot(2,2,2) plot(x,y2) title('Subplot 2: sin(2x)') y3 = sin(4*x); subplot(2,2,3) plot(x,y3) title('Subplot 3: sin(4x)') y4 = sin(8*x); subplot(2,2,4) plot(x,y4) title('Subplot 4: sin(8x)') Page (18) Plot Line Specifications ✔ Plot line specifications has three components: (Style Color Marker). Example ≫ plot(x,y,'-.ro') Line Style Description - Solid line -- Dashed line : Dotted line -. Dash-dot line Color Description Marker Description y yellow 'o' Circle m magenta '+' Plus sign c cyan '*' Asterisk r red '.' Point g green 'x' Cross b blue '_' Horizontal line w white '|' Vertical line k black 's' Square 'd' '>' Diamond Upward-pointing triangle Downward-pointing triangle Right-pointing triangle '<' Left-pointing triangle 'p' Pentagram 'h' Hexagram '^' 'v' Page (19) ✔ ✔ Related Properties ▸ LineWidth: Specifies the width (in points) of the line. ▸ MarkerEdgeColor: Specifies the color of the marker or the edge color for filled markers (circle, square, diamond, pentagram, hexagram, and the four triangles). ▸ MarkerFaceColor: Specifies the color of the face of filled markers. ▸ MarkerSize:Specifies the size of the marker in points (must be greater than 0). Color can be specified as [R, G, B] where R, G, B are the Red, Green, Blue components of the color and they are between 0 and 1. ≫ t = 0:pi/20:2*pi; ≫ figure ≫ plot(t,sin(2*t),'-mo',... ≫ 'LineWidth',2,... ≫ 'MarkerEdgeColor','k',... ≫ 'MarkerFaceColor',[.49 1 .63],... ≫ 'MarkerSize',10) ≫ Page (20) Equally and Logarithmically Spaced Values ✔ linspace(start,end,N) gives N equally spaced points from start to end, the same as start:(end - start)/(N-1):end ✔ logspace(start,end,N) gives N logarithmically spaced points from start^10 to end^10, the log10 of the results is the same as linspace(start,end,N) ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ x = linspace(2,7,10) x = [2:(7-2)/(10-1):7] % same results x = [0:0.3:1] % gives 0, 0.3, 0.6, 0.9 x = [0:0.7:1] % gives 0, 0.7 x = logspace(1,4,7) log10(x) % same as linspace(1,4,7) Page (21) Complex Numbers ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ z = 3+4i % entering a complex number z = 3+4j % same as before z = complex(3,4) % same as before x = real(z) % real part of z y = imag(z) % imaginary part of z R = abs(z) % absolute value of z theta = angle(z) % phase angle of z in radians w = conj(z) % complex conjugate, w=3-4i isreal(z) % test if z is real or complex z1=4*exp(j*pi/2)% entering using magnitude and angle in radian z1=4*exp(j*90*(pi/180)) % converting degrees to radian Page (22) Transpose ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ In transposition, the dimensions of a matrix are swapped A = [1,2,3,4,5] % row vector AT = A' % transpose of A Z = [1 + j, j, 2-5j] ZC = Z' % conjugate transpose, the complex part is negated ZT = Z.' % transpose without conjugating C = conj(Z) % complex conjugate C = (Z.')' % same as before Page (23) Accessing Matrix Elements ✔ Index in Matlab starts with 1, not 0. ✔ Any matrix could be considered as one column matrix with ordering as in the figure to the right ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ A = magic(4) % 4x4 magic matrix A(2,3) % element of row 2 and column 3 B = A(:,1) % elements in all rows and first columnt C = A(1:3,:) % elements of rows 1 to 3 and all columns D = A(:) % the matrix is converted to one column vector E = A(1:10) % the first 10 elements A(10) A(1:3,:) % from the first row to row 3 and all columns A(2:end,1:end-1) % end represent the last index A(end,:) % last row and all columns A([1,4],:) % rows 1 and 4 and all columns Page (24) Matrix Generation and Sizing ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ A = zeros(2,3) % 2x3 matrix filled with zeros A = ones(2,3) % 2x3 matrix filled with ones length(A) % maximum dimension of A SZ = size(A) % return the size of A SZ(1) % number of rows SZ(2) % number of columns A = magic(4) A2 = reshape(A,[2,8]) % changing the shape of A to 2x8 A3 = rot90(A) % rotate matrix 90 degree A3 = fliplr(A) % flip matrix horizontally A3 = flipud(A) % flip matrix vertically A = [1,2;3,4] R = repmat(A,[2,3]) % replicate and tile A 2x3 times A = [1,2,3] % A has only 3 elements A(7) = 20 %this will extend number of elements to 7 and fill A(4) to A(6) with 0 A (2) = [] % delete element A(2) A = magic(3) A(2,:) = [] % delete second row Page (25) Random Numbers ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ % % % % % rand % generate a pseudorandom number between 0 and 1 (uniformly distributed) rand(3) % generate 3x3 matrix of pseudorandom numbers between 0 and 1 rand([2,3]) % generate 2x3 matrix of pseudorandom numbers randn % generate a normally distributed pseudorandom number % with mean = 0 and standard deviation = 1 randn([2,3]) % 2x3 matrix of normally distributed random numbers randi([1,10]) % generate pseudorandom integer between 1 and 10 randi([1,10],[2,3]) % generate a 2x3 matrix of random integers % between 1 and 10 randperm(5) % generate randomly permuted numbers from 1 to 5 Random numbers generated in Matlab are actually pseudorandom numbers, which means they look random but they are generated using a function (generator) that will generate the same random numbers when the same seed is used. The seed is used to set the random generator internal state and it is changes every time the random generator is called, as in the following example: ≫ ≫ ≫ ≫ rand([1,10]) rand([1,10]) % different random numbers rand('seed',100); rand([1,10]) % the seed is set to 100 rand('seed',100); rand([1,10]) % the same numbers are generated Page (26) Example: plot the distribution of uniformly and normally distributed 100000 number. ≫ ≫ ≫ ≫ ≫ ≫ x1 = rand([1,100000]); % uniformly distributed random numbers. x2 = randn([1,100000]); % normally distributed random numbers. hist(x1,100) % plotting the histogram using 100 bins (The figure on the left) xlim([-1,2]) figure hist(x2,100) % plotting the histogram using 100 bins (The figure on the right) Page (27) Linear Algebra Page (28) ✔ Matrix multiplication ≫ A = [6,-2;10,3;4,7]; ≫ B = [9,8;-5,12]; ≫ A*B Page (29) ≫ I = eye(4) % 4x4 identity matrix ≫ A = magic(5) % 5x5 magic matrix ≫ det(A) % determinant of A ≫ diag(A) % vector contains the diagonal elements of A ≫ tril(A) % lower triangular part of A ≫ triu(A) % upper triangular part of A ≫ inv(A) % inverse of A, must be a square matrix ≫ eig(A) % eigenvalues of A ≫ help eig % more help about eig ≫ rank(A) % rank of A (maximum number of linearly independent ≫ % column vectors in the matrix ≫ A = [4 -2 1]; B = [1 -1 3]; ≫ cross(A,B) % cross product ≫ dot(A,B) % dot product ≫ % solve the system of linear equations: x1 – 2*x2 + x3 = 0 % 2*x2 – 8*x3 = 8 % -4*x1 + 5*x2 + 9*x3 = -9 ≫ A = [1, -2, 1;0, 2, -8;-4, 5, 9] ≫ b = [0; 8; -9] ≫ x = A\b % Ax = b => x = A\b ≫ x = linsolve(A,b) % other method Page (30) Output format ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ % The format command is used to control how the number are displayed. x = [-4/3 1.2345e-6] % -> -1.3333 0.0000 format long % display numbers in long format x % -> -1.333333333333333 0.000001234500000 format short % default format x % -> -1.3333 0.0000 format long e % long format with scientific notation x % -> -1.333333333333333e+00 1.234500000000000e-06 format short e % short format with scientific notation x % -1.3333e+00 1.2345e-06 format + % display only the sign of the number x % -> -+ format % apply the default display format (short) Page (31) Strings ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ S = 'Hello' % strings are created between single quotes S(2) % string is created as array of characters, -> 'e' S = ['Hello', 'world'] % strings in the same row are concatenated S % gives 'Helloworld' length(S) % gives 10 S = ['Hello'; 'all'] % error, string rows must have the same length S = num2str(23.123) % convert number to a string a = str2num('12.23') % convert a string to a number S = ['x = ', num2str(20.2)] % concatenating numbers and strings dec2bin(10) % converting an integer into a binary as string -> '1010' dec2bin([1,5,32]) %gives 3 rows matrix with each row as binary string dec2bin(10,8) % setting the number of bits to 8 -> '00001010' bin2dec('1101') %converting a string of bits to an integer -> 13 strfind('Hello all','ll') % search for a pattern 'll' in a string -> [3,8] Page (32) Cell arrays % cells are used to store values of different types, curl brackets are used with cells % cells are suitable to store strings with different lengths ≫ c = {[5, 10, 7], 'hello', 'all'} -> 1x3 cell array ≫ c{2} % gives the second cell in the array -> 'hello' ≫ c{2}(2) % brackets are used to access elements in the cells -> 'e' ≫ c{1}(2) % -> 10 ≫ c = {[4,5,6], 'hello'; 'all', 'world'} % -> 2x2 cell array ≫ c{2,2} % -> 'world' ≫ c{4} % the fourth cell, counting is from top to bottom ≫ c{2} % -> 'all' ≫ c{1,1}(3) % -> 6 , brackets are used to access elements of cells. Page (33) m-Files ✔ m-files are used to store a sequence of Matlab instructions, running the the m-file is equivalent to typing these instructions in the command window. ✔ m-files are also used to store functions, which are encapsulated Matlab code, that has its own input, output, and local variables. ✔ An m-files is run by typing its name (without .m) in command window, Matlab then search for the m-file in the current directory and run it. ✔ If the m-file is not found the current directory, Matlab will search in a list of directories stored in its path preferences. If the file is not found then an error message is returned. ✔ The name of the m-file should not be the same as a built-in function. ✔ Use % at the beginning of a line to comment out that line. ✔ Matlab text editor or any other text editor can be used to edit the m-file. Page (34) Example Example: write the following text in a file called my_code.m and save it in the current working directory, then run it by typing my_code % First m-file example, save it in my_code.m clear all; close all; % clearing all variables and closing all figures x = [-pi:pi/20:pi]; y = sin(x); plot(x,y) The variables created in the m-files will remain in the memory as if the code is types directly in the command windows ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ edit my_code.m % edit the code using Matlab built-in editor my_code % whos % list the variables created in the m-file mkdir code % create subfolder called code in the current directory movefile my_code.m code % move the file into the folder code my_code % -> error, because the subfolder 'code' is not in path preferences cd code; % change directory to 'code' my_code % the file now runs because the code is in the current folder cd .. ; % return to the parent directory addpath 'code' % adding subfolder 'code' to path list (only for current session). my_code % the code will run correctly path % show the list of folders where Matlab searches for m-files Page (35) Function Files ✔ ✔ ✔ ✔ Function are encapsulated code that has its own input, output, and local variables. The name of the function is the same as the name of its file (without .m) Example: Write a Matlab function called (my_prod) that returns the algebraic product of two matrices and return error message of their size is incompatible. Solution: Write the following code in an m-file called my_prod.m. % This function return the algebraic product of two matrices function [mat_out] = my_prod(mat1, mat2) %notice the structure of function declaration SZ1 = size(mat1); SZ2 = size(mat2); if SZ1(2) ~= SZ2(1) error('Incompatible Matrix size') end mat_out = mat1 * mat2; % the output matrix that will be returned; return % used to exit the function ≫ ≫ ≫ ≫ ≫ ≫ m1 = [1,2,3] m2 = [4,5,6] p = my_prod(m1,m2) % gives error message p = my_prod(m1,m2') % run the function whos % the variables created inside the function are local to the functions help my_prod % will display the comments in the beginning of the function file Page (36) Examples % write this code in a file called my_circle.m and run it function my_circle() theta = linspace(0,2*pi,100); % create theta x = cos(theta); % generate x-coordinate y = sin(theta); % generate y-coordinate plot(x,y); % plot circle axis('equal'); % set equal scale on axes title('Circle of unit radius') % title return % sum_prod function returns the summation and the product of a vector function [SUM, PROD] = sum_prod(V) SUM = sum(V); PROD = prod(V); return ≫ A = [1:5]; ≫ [S, P] = sum_prod(A) % calling the function Page (37) Input and Output ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ A = [1,2,3,4] disp (A) % Displays the contents, but not the name, of the array A. S = 'hello' disp(S) % Displays the text string S A = 12 disp(['A = ',num2str(A)]) % numbers are converted to stings if mixed with strings x = input('x = ') % Displays text and store input number in x x = input ('name = ','s') % store the input as string k = menu('Choose option','option 1','option 2') % return chosen option, 1,2,3,... eval('plot(sin(0:.1:10))') % evaluate the expression x = 0:.1:10; y = eval('sin(x)') % store the result of string evaluation in y % save this code in plot_fun.m function plot_fun() x1 = input('X1 = '); % Enter initial number, 0 for example x2 = input('X2 = '); % Enter final number, 10 for example S = input('f(x) = ','s'); % Enter 'sin(x)', 'cos(x)', 'exp(x)', etc.... x = [x1:.1:x2]; y = eval(S); plot(x,y) return Page (38) Flow control: if, for, while, .... ✔ The body of control statements (if, for, while) is indented for reading clarity % example.m ,what is the output of this code for n = 0:10 if mod(n,2) == 0 % remember to use == not = with if statement disp([num2str(n), ' is even']); else disp([num2str(n), ' is odd']); end % end of if statement end % end of for loop for k = m:s:n % fact.m , this function returns the factorial of a number function f = fact(n) if n < 0 error('Negative number.') elseif mod(n,1) ~= 0 % check if the number is integer error('Non-integer number.') else f = 1; for m = 1:n f = f*m; end end return Page (39) continue... and break... ✔ ✔ ✔ continue statement is used to skip the current iteration of a loop break statement is used to exit the loop completely Convert the following code into a function that receives a number n and returns an array of all prime numbers less than or equal n. Modify the code to check and return an error if the n is negative, zero, or a fraction. % my_prime.m, this code displays the prime numbers less than 100 for n1 = 1:100 is_prime = true; for n2 = 2:(n1-1) if mod(n1,n2) == 0 is_prime = false; break % break statement is used to exit the inner loop end end if ~is_prime continue % continue is used to skip the current iteration of the outer loop end disp ([num2str(n1), ' is a prime number']) end Page (40) while ... loop % example.m, this code displays the numbers 1, 10,100,1000,10000, 100000, 1000000 n=1; while n <= 1000000 disp(n) n = n * 10; end % feb.m, this code prints the Febonacci sequence below 40 n1 = 0; n2 = 1; while n2 < 40 disp(n2) f = n1 + n2; n1 = n2; n2 = f; end Page (41) logical Search in Matrices ✔ ≫ ≫ ≫ ≫ ≫ ✔ Logical operators (<, >,<=, >=, ==, ~=) can be used to search in matrices. A = magic(3) A > 5 % return an array with the same size of A, 1s where A > 5 and 0s elsewhere. find( A > 5) % return the index of elements where A > 5 A (A>=5) = -1*A(A>=5) % A is indexed by an array of 0s and 1s the same size as A A(find(A>0)) = 0 % 'find' could be used to index an array Write a function that clips the values of an array A between two numbers MIN, and MAX, so that where A > MAX becomes MAX and where A < MIN becomes MIN % solution function A1 = clip(A,MIN,MAX) A1 = A; A1(A1< MIN) = MIN; A1(A1 > MAX) = MAX; return Page (42) Complex Logic Statements (and, or, not) ✔ Complex logic statement can be formed using the operators: and (&) , or ( | ), not (~) ✔ Remember the presidency of the operators as shown in the table: ✔ Example: write the code that determine of a year is a leap year: function result = isleap(year) if ~mod(year,1)==0 | (year <1) error('Invalid number') elseif (mod(year, 4) == 0 & mod(year,100) ~= 0) | mod(year, 400) == 0 result = true; else result = false; end return Page (43) for loops and efficiency ✔ ✔ In GNU-Octave and older versions of Matlab, always try to perform operations on a Matrix as whole, instead of doing it on single elements using for-loop. Run the following code and compare the time used with and without for-loop. A = rand([1000,1000]); tic; % Start a stopwatch timer, toc command is used to get the timer A = A .^ 2; disp(['Time without loop = ', num2str(toc), ' seconds']) [row_num,col_num] = size(A); tic; for r =1:row_num for c = 1:col_num A(r,c) = A(r,c) .^ 2; end end disp(['Time with loop = ', num2str(toc), ' seconds']) Page (44) Debug a MATLAB Program ✔ Breakpoints are used to pause the execution of a MATLAB file so you can examine the value of variables where you think a problem could be. ✔ Click the breakpoint alley to the left of a line in the code below to add a breakpoint. ✔ Run the program using the run button ✔ The prompt in the Command Window changes to K>> indicating that MATLAB is in . The run button changes to continue button . debug mode. ✔ MATLAB pauses at the first breakpoint in the program. In the Editor, a green arrow just to the right of the breakpoint indicates the pause. The program does not execute the line where the pause occurs until it resumes running. Page (45) ✔ To view a variable while debugging, position your mouse pointer over the variable. The current value of the variable appears in a data tip. ✔ MATLAB displays the current workspace in the Function Call Stack, on the Editor tab in the Debug section. Description Continue execution of file until the line where the cursor is positioned. Also available on the context menu. Execute the current line of the file. ✔ Click the continue button to continue executing until the next breakpoint or the end of the code. Click step button Execute the current line of the file and, if the line is a call to another function, step into that function. Resume execution of file until completion or until another breakpoint is encountered. After stepping in, run the rest of the called function or local function, leave the called function, and pause. to execute only the current line of Pause debug mode. code. Exit debug mode. Toolbar Button Run to Cursor Step Step In Continue Step Out Pause Quit Debugging Page (46) Assignments ✔ Write the function sum1.m that returns the sum of even numbers less than or equal to the input n. ✔ Write the function sum2.m that accepts a matrix m and returns the summation of the positive numbers and the summation of the negative numbers in m. The outputs are sum_p, and sum_n. Use the function sum() to calculate the summation. ✔ Write the function vect.m that accepts a matrix m and returns two vectors v_p and v_n which contain the positive and negative elements in m sorted in an ascending order. Use the function sort() to sort the output vectors. ✔ Write the function factorize.m that accepts a positive integer larger than 0, and returns its prime factors (including 1). The function should return the error "Invalid number." if the number is less than 1 or is a fraction. (Do not use the built-in function factor() in your code, instead write your own code using for loop and if statement.) Page (47) More Plots ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ For more about plots, see the link: https://www.mathworks.com/help/matlab/creating_plots/types-of-matlab-plots.html x = [1:.5:10]; y = sin(x); bar(x,y) % bar plot width = 0.5; % bar width is half the interval , width > 1 produce overlapping bars bar(x,y,width) % specify bar width stem(x,y) % stem plot stem(x,y,'filled') % filled markers stairs(x,y) % stair plot ≫ x = [10,40,30,10,20,50] ≫ pie(x) % pie chart, percentage of each value to total values is shown ≫ pie3(x) % 3-D pie chart Page (48) 3D Plots ≫ ≫ ≫ ≫ ≫ mat = peaks(20) % generate 2-D matrix with mountain like values mesh(mat) % 3-D mesh surf(mat) % shaded 3-D mesh contour(mat) % contour plot bar3(mat) % 3-D bar plot % 3-D line plot ≫ t = 0:pi/10:4*pi; ≫ x = sin(t); y = cos(t); ≫ plot3(x,y,t) Page (49) Statistics % The median is the value separating the higher half from the lower half of the data % The mode is the value that appears most often in a set of data values. ≫ A = [1,1,1,2,3,10] ≫ m = mean(A) % finding the mean (i.e. average) of a vector. ≫ me = median(A) % finding median of a vector (in this case median = 1.5) ≫ md = mode(A) % finding mode of a vector (in this case mode = 1) ≫ mx = max(A) % finding the maximum value of a vector ≫ mn = min(A) % finding the minimum value of a vector. ≫ st = std(A) % standard deviation of a vector ≫ A = [1:5;6:10;11:15;11:15] ≫ m = mean(A) % find the mean value for each column in a matrix. ≫ m = mean(mean(A)) % mean of the vector means. ≫ m = mean(A(:)) % another way to find the mean value of all values in a matrix ≫ mx = max(A) % The same is applied for other operations, min, max, median, std, etc. % median, mode, and std are not linear operations, be careful when dealing with them. ≫ A = [1,2,3,4;1,2,3,4;5,5,5,5] ≫ md = mode(A) % find the mode for each column of a matrix. ≫ md = mode(mode(A)) % not the correct value for the mode of A ≫ md = mode(A(:)) % the correct value of the mode of A Page (50) Histogram % Histogram shows the data distribution (or occurrence) within defined ranges. ≫ d = [1,1,2,2,2,2,3,3,4,5,6,7,7,8:20] ≫ hist(d) % show histogram with 10 bins (default number of bins) ≫ hist(d,6) % show histogram with 6 bins ≫ M = [1:20] ≫ hist(d,M) % M determines the centers of the bins ≫ ≫ ≫ ≫ ≫ ≫ ≫ M=[1,2,3,4,5,10,15] hist(d,M) % bins width is not symmetric xticks([1:20]) title('Histogram with non-symmetric bins') % title, xlabel, etc.. can be added [freq,pos] =hist(d) % returns frequency and bar positions (no plotting) bar(pos,freq) % another way to plot the histgram [freq,pos] = hist(d,[1:20]) % centers can be set as described before. ≫ ≫ ≫ ≫ ≫ ≫ data = rand([1,100000]); hist(data,50) % show the histogram for uniformly distribution random numbers xlim([-1,2]); data = randn([1,100000]); %random numbers with mean = 0 and std = 1 hist(data,50) % show the histogram for normally distribution random numbers hist(data,50) Page (51) Example % plot a bar plot that shows the count of the elements in the following array % [1,1,1,5,5,5,5,10,10,13,15,40,40,40]; % total bars width = 1 , notice that minimum interval is between 13 and 15 = 2 % Solution d = [1,1,1,5,5,5,5,10,10,13,15,40,40,40]; du = unique(d) % returns the unique values in an array [freq,pos] = hist(d,du); width = 0.5; % bar(pos,freq,width) Page (52) Data Statistics Tool ✔ Use Data Statistics tool to get statistical information about the data in the plot. Page (53) Interpolation ✔ Interpolation is a technique for adding new data points within a range of a set of known data points. You can use interpolation to fill-in missing data, smooth existing data, make predictions, and more. ≫ x = 0:pi/4:2*pi; ≫ y = sin(x); ≫ plot(x,y,':bo') ≫ val_x = 0:pi/16:2*pi; % define x value for the interpretation ≫ val_y = interp1(x,y,val_x); % linear interpolation ≫ plot(x,y,':bo',val_x,val_y,':r.') ≫ val_y = interp1(x,y,val_x,'spline'); % spline interpolation ≫ plot(x,y,':bo',val_x,val_y,':r.') Page (54) Numerical Integration % finding the integration using % trapezoidal method. ≫ x = [0:pi/10:pi]; y = sin(x); ≫ trapz(x,y) ans: 1.9835 % reduce step to increase accuracy ≫ x = [0:pi/20:pi]; y = sin(x); ≫ trapz(x,y) ans: 1.9959 % more accurate method ≫ f = @(x) sin(x); % Anonymous function ≫ integral (f, 0, pi) % use global adaptive quadrature to find integration ans: 2.0000 % double integration ≫ f = @(x,y) sin(x .* y) ≫ integral2 (f, 0,pi,0,pi) % integral2 (function, x_min, x_max, y_min, y_max) % see also quad, quad1, integral3 Page (55) Example An accelerometer is used in aircraft, rockets, and other vehicles to estimate the vehicle’s velocity and displacement. The accelerometer integrates the acceleration signal to produce an estimate of the velocity, and it integrates the velocity estimate to produce an estimate of displacement. Suppose the vehicle starts from rest at time t = 0, and its measured acceleration is given in the following table. Time Acceleration 0 0 1 2 2 4 3 7 4 11 5 17 6 24 7 32 8 41 9 48 10 51 (a) Estimate the velocity v after 10 s. (b) Estimate the velocity at times t = 1, 2, ..., 10 s. t = 0:10; a = [0,2,4,7,11,17,24,32,41,48,51] v10 = trapz(t,a) % solution to question a v = zeros([1,11]); for k = 1:10 v(k+1)= trapz(t(k:k+1), a(k:k+1)) + v(k); end disp([t;v]) % solution to question b Page (56) Numerical Differentiation step = pi/20; % delta-x x1 = 0:step:2*pi; y1 = sin(x1); y2 = diff(y1); % return difference between y1 elements, length(y2) = length(y1)-1 y2=y2/step; % fining derivative by dividing by delta-x x2 = x1(1:end-1); % remove last element in x plot (x1,y1,x2,y2,'-.','LineWidth',3) legend('y', 'derivative of y') Page (57) Finding the Root of a Function Numerically ✔ 2 Find the root of the function f ( x)=x −e −x f = @(x) x .^ 2 - exp(-x); % anonymous function x0 = 0; % Initial value for the calculation of the root x_zero = fzero(f,x0); % claculate the root of the function numerically disp(x_zero) disp(f(x_zero)) Page (58) Functions Input and Output Arguments % % % % This function illustrates how to deal with function input and output arguments nargin, nargout: number of input and output arguments varargin, varargout: cells contain input and output arguments after the declared ones in1, in2, out1, out2: declared input and output arguments function [out1, out2, varargout] = arg_test(in1, in2, varargin) disp(['Number of input arguments: ', num2str(nargin)]) if nargin == 1 disp(in1); elseif nargin == 2 disp(in1); disp(in2); elseif nargin >= 3 disp(in1); disp(in2); for c = 3:nargin disp(varargin{c-2}); end end Page (59) disp(['Number of output arguments: ', num2str(nargout)]) if nargout == 1 out1 = 1; elseif nargout == 2 out1 = 1; out2 = 2; elseif nargout >= 3 out1 = 1; out2 = 2; for c = 3:nargout varargout{c-2} = c; end end return % end of the function ≫ % calling the function ≫ arg_test % no input or output ≫ [a,b,c,d] = arg_test(1,2,3,4,5) % different number of inputs and outputs Page (60) Structure Array ✔ A structure array is a data type that groups related data using data containers called fields. Each field can contain any type of data. Access data in a field using dot notation of the form structName.fieldName. ≫ ≫ ≫ ≫ ≫ ≫ ✔ S.name = 'ali' % creating structure for a student data S.number = 122 S.marks = [12,20,30] whos disp(S.marks) You also can create a structure array using the struct function ≫ S = struct('name', 'ali', 'number', 12, 'marks', [12,20,30]) ≫ whos ≫ disp(S.marks) Page (61) Matlab Symbolic Toolbox ✔ In general, Matlab is used for numerical analysis; however, using the Symbolic Toolbox, it is possible to perform analytical calculations such as ✔ Algebra: Manipulating expressions. ✔ Solving systems of linear equations. ✔ Solving systems of nonlinear equations. ✔ Calculus: Integration, differentiation, limits, etc. ✔ Solving differential equations. ✔ Fourier & Laplace transforms. ✔ Try the command help symbolic. Page (62) ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ✔ Introduction syms x a b c % defining symbolic variables y1 = a * x^2 + b * x + c % defining a symbolic expression y2 = sin(x) / x whos % see how symbolic variables are defined pretty(y1) % print symbolic expression with nice formatting pretty(y2) lmt = limit(y2,0) % finding the limit of a function (at x=0) y3 = (x + a)^3 expand(y3) % expanding an expression y4 = x^3-6*x^2+11*x-6 factor(y4) % factorize an expression (in this example a polynomial) pretty(factor(y4)) y5 = cos(x)^2 + sin(x)^2 simplify(y5) % Attempts to simplify an expression (not always helpful) subs(sin(pi*x),x,(a+b)/c) % substitute (a+b)/c instead of x in the given expression Finding the numerical value for an expression syms x y = x^2 + x -1 y_value = subs(y,2) % find the value of y at x = 2 Page (63) ✔ Solving (finding the root) of a function y = x^2 + x + 1 y_sol = solve(y) % solve y with respect to x double(y_sol) % convert values to double ✔ Another example syms a b c x; y = a*x^2+b*x+c; xsoln = solve(y,x); pretty(xsoln); a=2; b=-5; c=3; subs(xsoln) ✔ Differentiation syms a x; y = sin(a*x); d = diff(y,x) % first derivative of y d = diff(y,x,3) % third derivative of y a = 2 x = 2 subs(d) double(sub(d)) % evaluate the derivative at a = 2, and x = 2 Page (64) ✔ Integration syms a x; y = 1/x; y_i = int(y,x) % find integration with respect to x y_i3 = int(int(int(y))) % integrate y three times y_di = int(y,x,1,3) % find the definite integration from 1 to 3 ✔ Solving first order differential equation dy =t y dt syms y(t); ode = diff(y,t) == t*y; ySol(t) = dsolve(ode) ✔ Solving differential equation with condition. dy =t y , y (0)=2 dt syms y(t); ode = diff(y,t) == t*y; cond = y(0) == 2; ySol(t) = dsolve(ode,cond) Page (65) ✔ Nonlinear Differential Equation with Initial Condition. 2 dy ( + y) =1 , y (0)=0 dt syms y(t) ode = (diff(y,t)+y)^2 == 1; cond = y(0) == 0; ySol(t) = dsolve(ode,cond) ✔ Second-Order ODE with Initial Conditions 2 d y =cos(2 x)− y , y (0)=1 , y ' (0)=0 2 dx syms y(x) Dy = diff(y); ode = diff(y,x,2) == cos(2*x)-y; cond1 = y(0) == 1; cond2 = Dy(0) == 0; conds = [cond1 cond2]; ySol(x) = dsolve(ode,conds); ySol = simplify(ySol) Page (66) ✔ Solve System of Differential Equations dy 1 =3 y 1 +4 y 2 dt dy 2 =−4 y 1 +3 y 2 dt clear all; syms y1(t) y2(t) ode1 = diff(y1) == 3*y1 + 4*y2; ode2 = diff(y2) == -4*y1 + 3*y2; odes = [ode1; ode2] [y1Sol(t), y2Sol(t)] = dsolve(odes) output: y1Sol(t) = C2*cos(4*t)*exp(3*t) + C1*sin(4*t)*exp(3*t) y2Sol(t) = C1*cos(4*t)*exp(3*t) - C2*sin(4*t)*exp(3*t) % The constants C1 and C2 appear because no conditions are specified. Page (67) % solving with initial conditions cond1 = y1(0) == 0; cond2 = y2(0) == 1; conds = [cond1; cond2]; [y1Sol(t), y2Sol(t)] = dsolve(odes,conds) output: y1Sol(t) = sin(4*t)*exp(3*t) y2Sol(t) = cos(4*t)*exp(3*t) % Visualize the solution using fplot. fplot(y1Sol) hold on fplot(y2Sol) grid on legend('y1Sol','y2Sol','Location','best') Page (68) ✔ Fourier and inverse Fourier transform syms t w; % t and w are the variables in time and frequency respectively y(t) = exp(-abs(t)) Y(w) = fourier(y,t,w) y2(t) = ifourier(Y,w,t) ✔ another example syms t w; y(t) = exp(-t)* heaviside(t) Y(w) = fourier(y,t,w) y2(t) = ifourier(Y,w,t) Page (69) ✔ Laplace and inverse Laplace transform syms a t s; % t and s are the variables in time and frequency respectively y(t) = sin(a*t) Y(s) = laplace(y,t,s) y2(t) = ilaplace(Y,s,t) ✔ another example syms a t s; y(t) = exp(a*t) Y(s) = laplace(y,t,s) y2(t) = ilaplace(Y,s,t) Page (70) Storing and Loading Variables ✔ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ ≫ Use save() and load() commands to save and load current session variables. A = [1,2,3,4]; B = [1,2,3,4]; S = 'Hello world!' save('My_Data') % saving all variables in My_Data.mat file. clear all; % clear all variables whos % view variables load('My_Data') % load all variables in the file My_Data.mat whos save('My_Data', 'A', 'S') % save only variables A and S load('My_Data', 'A') % load only variable A Page (71) Reading/Writing Heterogeneous data to a Text Files Write a Matlab program that get input data from user for a number of students. The input data are: Name, age, first mark, and second mark. The data should be stored in the file Student.txt, then loaded from that file and displayed on the screen. std_count = input ('Number of students = '); fid = fopen('Student.txt', 'w'); % 'w' will overwrite existing file, user 'a' to append for s = 1:std_count name = input('Name = ','s'); age = input('Age = '); mark_1 = input('First mark = '); mark_2 = input('Second mark = '); fprintf(fid, '%s, %d, %.2f, %.2f\n', name, age, mark_1, mark_2); end fclose(fid); % reading the data fid = fopen('Student.txt', 'r'); % 'r' is used for reading the file data = textscan(fid,'%s %d %f %f',std_count, 'Delimiter', ','); for c=1:std_count disp(sprintf('Student name = %s. Age = %d. Mark1 = %.2f. Mark2 = %.2f\n', ... data{1,1}{c}, data{1,2}(c), data{1,3}(c), data{1,4}(c))); end fclose(fid); Page (72) Reading/Writing Homogeneous Data to a Text File ✔ Homogeneous data (i.e. of the same type) can be stored to and read from text files using dlmwrite() and dlmread() commands. Write a program that stores and read the values generated by the command (peaks(10)) in the text file Data.txt , starting from the second row and the third column. The values are separated by a comma (,). Round the stored data to 2 decimal places. Plot the mesh of the original and the stored data. A = peaks(10); dlmwrite('Data.txt',A(2:end,3:end),'delimiter',',','precision','%0.2f') B = dlmread('Data.txt'); subplot(1,2,1);mesh(A);title ('Original Data'); subplot(1,2,2);mesh(B);title ('Stored Data'); Page (73) Audio Processing Example clear all; close all; % reading a wav sound file (about 10 seconds), Fs is the sampling frequency [snd, Fs] = audioread('example.wav'); N = length(snd); snd = snd(:,1); % taking only one channel from the stereo sound % playing 7 seconds of the sound, try changing Fs with Fs/2 or Fs*2 sound(snd(1:Fs*7),Fs); SND = fftshift(fft(snd))/N; % finding frequency domain contents % plotting the sound in time domain Ts=1/Fs; % sampling period t_max = (N-1)*Ts; t=[0:Ts:t_max]; subplot(2,1,1);plot(t,snd); title ('Signal in time domain.'); % plotting the sound in frequency domain f=[-Fs/2:Fs/(N-1):Fs/2]; subplot(2,1,2);plot(f,abs(SND));title('Spectrum of the signal (frequency domain)'); Page (74) Page (75) Image Processing Example (Denoising) clear all; close all; I = imread('peppers.png'); % loading image file I_gr = rgb2gray(I); % convert the imag to gray-scale % adds Gaussian white noise with zero mean and variance 0.1 I_ng = imnoise(I_gr,'gaussian',0,0.05); % adds salt and pepper noise with 0.1 noise density I_ns = imnoise(I_gr,'salt & pepper',0.1); % Filter the image with Gaussian noise using averaging filter % the filter has 3-by-3 kernel size I_dg = uint8(filter2(fspecial('average',3),I_ng)); % Filter the image with salt and pepper using median filter % the filter has 3-by-3 kernel size I_ds = medfilt2(I_ns,[3,3]); subplot(2,3,1);imshow(I); title('The original colored image'); subplot(2,3,2);imshow(I_ng); title('Gaussian noise'); subplot(2,3,3);imshow(I_ns); title('Salt and pepper noise'); subplot(2,3,4);imshow(I_gr); title('Gray-scale image'); subplot(2,3,5);imshow(I_dg); title('Denoising using 3x3 averaging filter'); subplot(2,3,6);imshow(I_ds); title('Denoising using 3x3 median filter'); imwrite(I_ds,'denoised_median.png') % saving the image denoised using median filtering Page (76) GUI Design Using uicontrols ✔ In following sections writing a GUI (Graphical User Interface) for Matlab will be illustrated. ✔ Using GUIDE and App Designer, it is possible to make GUIs using a graphical drag and drop method, however the old fashion way of coding using uicontrols will be described for the following reasons. ▸ Having better control and understanding of the code. ▸ This method is compatible with GNU Octave also. Page (77) GUI Design Guidelines ✔ Start by making a sketch of the GUI and planning position and type of each GUI element. ✔ ✔ Write the general structure of the code that handle the different actions of the application. Use Tag property to find the figure and store the handle of any required element in UserData property of the figure. Put the different functionalities of the GUI using the action argument of the main program. Use a prefix for each type of uicontrols, such as lbl_ for static text , and txt_ for edit boxe. Use uicontrol action property for triggering certain functionality. Use set and get function set functions to interact with the uicontrols More about uicontrols: https://www.mathworks.com/help/matlab/ref/uicontrol.html ✔ ✔ ✔ ✔ ✔ Page (78) GUI example – Temperature Converter function temp_gui(action) if nargin<1 action = 'initialize'; end if strcmp (action, 'initialize') % Building the GUI % Check if the GUI is already opened fig=findobj('tag', 'temp_gui_figure'); if isempty(fig) % Defining general alignments of uicontrols in pixels ui_spc = 10; % spacing between uicontrols lbl_w = 140; % label width txt_w = 170; % edit text width btn_w = 50; % button width ui_h = 35; % height for all uicontrols % position -> [left bottom width height] % Creating the main figure fig_w = lbl_w + txt_w + btn_w + 4 * ui_spc; fig_h = 2 * ui_h + 3 * ui_spc; fig=figure('Tag','temp_gui_figure', ... 'name', 'Temperature Converter',... 'resize', 'off', ... 'ToolBar', 'none', ... % disable default toolbar 'MenuBar', 'None', ... % disable default menubar 'Position',[300,300,fig_w,fig_h]); Page (79) % Starting first row of UI elements left = ui_spc; bottom = ui_spc; lbl_c = uicontrol('parent', fig, ... 'style','text', ... 'string', 'Celsius', ... 'position', [left, bottom , lbl_w, ui_h]); left = left + lbl_w + ui_spc; bottom = bottom; txt_c = uicontrol ('parent', fig, ... 'style', 'edit', ... 'string', '0', ... 'position', [left, bottom, txt_w, ui_h]); left = left + txt_w + ui_spc; bottom = bottom; btn_c2f = uicontrol ('parent', fig, ... 'style', 'pushbutton', ... 'string', 'C -> F', ... 'position', [left, bottom, btn_w, ui_h], ... 'callback', 'temp_gui(''c2f'')'); % Starting second row of UI elements left = ui_spc; bottom = ui_h + 2 * ui_spc; lbl_f = uicontrol('parent', fig, ... 'style','text', ... 'string', 'Fahrenheit', ... 'position', [left, bottom , lbl_w, ui_h]); left = left + lbl_w + ui_spc; bottom = bottom; Page (80) txt_f = uicontrol ('parent', fig, ... 'style', 'edit', ... 'string', '32', ... 'position', [left, bottom, txt_w, ui_h]); left = left + txt_w + ui_spc; bottom = bottom; btn_f2c = uicontrol ('parent', fig, ... 'style', 'pushbutton', ... 'string', 'F -> C', ... 'position', [left, bottom, btn_w, ui_h], ... 'callback', 'temp_gui(''f2c'')'); % Adding "About" menu mnu_help = uimenu('parent',fig, ... 'label', 'Help'); mnu_help_about = uimenu('parent',mnu_help, ... 'label', 'About', ... 'callback', 'temp_gui(''about'')'); % Storing the UI handles in the figure UserData GUI = struct('txt_c', txt_c, 'txt_f',txt_f); set(fig, 'UserData', GUI); else figure(fig); end elseif strcmp (action , 'c2f') % convert c to f fig=findobj('tag', 'temp_gui_figure'); if ~isempty(fig) GUI=get(fig, 'UserData'); c = str2num(get(GUI.txt_c, 'string')); f=(9/5*c)+32; f=round(f*100)/100; % round to 2 decimal places set(GUI.txt_f,'string', num2str(f)); end Page (81) elseif strcmp (action, 'f2c') % convert f to c fig=findobj('tag', 'temp_gui_figure'); if ~isempty(fig) GUI=get(fig, 'UserData'); f = str2num(get(GUI.txt_f, 'string')); c=5/9 * (f-32); c = round(c*100)/100; % round to 2 decimal places set(GUI.txt_c,'string', num2str(c)); end elseif strcmp(action,'about') msgbox('Programmed by Mahmoud Alnaanah', 'About', 'help'); else error('Undefined action'); end return Page (82) GUI Example: Function Plotting function plot_gui(action) if nargin <1 action = 'initialize'; end if strcmp(action, 'initialize') % Building the GUI % Check if the GUI is already opened fig=findobj('tag', 'plot_gui_figure'); if isempty(fig) % Defining general alignments of uicontrols in pixels ui_spc = 10; % spacing between uicontrols ui_h = 30; % uicontrol height lbl_w = 70; % label width txt_w = 230; % text edit width btn_w = 100; % button width pnl_h = ui_h + 3 * ui_spc; % panel height pnl_w = 2 * lbl_w + 2 * txt_w + btn_w + 6 * ui_spc; % panel width ax_w = pnl_w - ui_spc; % axis width ax_h = 450; % axis height % position -> [left bottom width height] % Creating the main figure fig_w = pnl_w + 2 * ui_spc; fig_h = ax_h + pnl_h + 5 * ui_spc; Page (83) fig=figure('tag', 'plot_gui_figure', ... 'name', 'Function Plotting',... 'resize', 'off', ... 'Position',[100,100,fig_w,fig_h]); % Creating the axis left = 3 * ui_spc; bottom = 3 * ui_spc; ax_plot=axes('parent', fig, ... 'units','pixels',... 'box', 'on', ... 'position', [left, bottom, ax_w, ax_h]); % Creating the pannel left = ui_spc; bottom = bottom + ax_h + ui_spc; pnl = uipanel('Parent',fig, ... 'Title','Parameters', ... 'BackgroundColor', [0.8, 0.8 , 0.8], ... 'FontSize',10,... 'BorderType', 'line', ... 'BorderWidth', 2, ... 'units', 'pixels',... % default value of panel is 'normalized' 'Position',[left, bottom, pnl_w, pnl_h]); % Creaing UI elements inside the panel % The position is relative to the panel left = ui_spc; bottom = ui_spc; lbl_t = uicontrol('parent', pnl,... 'style', 'text',... 'position', [left, bottom, lbl_w, ui_h], ... 'string', 't = '); Page (84) left = left + lbl_w + ui_spc; bottom = bottom; txt_t = uicontrol('parent', pnl, ... 'style', 'edit', ... 'position', [left, bottom, txt_w, ui_h], ... 'string', '[0:.01:10]'); left = left + txt_w + ui_spc; bottom = bottom; lbl_f = uicontrol('parent', pnl,... 'style', 'text',... 'position', [left, bottom, lbl_w, ui_h], ... 'string', 'f(t) = '); left = left + lbl_w + ui_spc; bottom = bottom; txt_f = uicontrol('parent', pnl, ... 'style', 'edit', ... 'position', [left, bottom, txt_w, ui_h], ... 'string', 'sin(t)'); left = left + txt_w + ui_spc; bottom = bottom; btn_plot = uicontrol('parent', pnl, ... 'style', 'pushbutton', ... 'position', [left, bottom, btn_w, ui_h], ... 'string', 'Plot', ... 'callback', 'plot_gui(''plot'')'); % Adding "About" menu mnu_help = uimenu('parent',fig, ... 'label', 'Help'); Page (85) mnu_help_about = uimenu('parent',mnu_help, ... 'label', 'About', ... 'callback', 'plot_gui(''about'')'); % Storing the UI handles in the figure UserData GUI = struct('axes', ax_plot, 'txt_t' , txt_t, 'txt_f', txt_f); set(fig, 'UserData', GUI); else figure(fig); end elseif strcmp(action, 'plot'); fig=findobj('tag', 'plot_gui_figure'); if ~isempty(fig) GUI=get(fig, 'UserData'); t=eval(get(GUI.txt_t, 'string')); f=eval(get(GUI.txt_f,'string')); axes(GUI.axes); % set the current axes plot(t,f); end elseif strcmp(action, 'about'); msgbox('Programmed by Mahmoud Alnaanah', 'About', 'help'); else error('Undefined action'); end return Page (86) GUI Example (Image Manipulation) function img_gui(action) if nargin <1 action = 'initialize'; end if strcmp(action, 'initialize') % buildin the gui fig=findobj('tag', 'img_gui_figure'); if isempty(fig) fig=figure('tag', 'img_gui_figure', ... 'MenuBar','none',... 'position', [200,300, 256,256]); ax=axes('parent', fig, ... 'units','normalized',... % the size of the axes will change with the figure 'YDir','reverse',... 'XTick',[],'YTick',[],... 'position', [0,0,1,1]); % Creating image img=image('Parent',ax); mnu_file=uimenu('parent', fig, ... 'label', 'File'); mnu_file_open=uimenu('parent', mnu_file, ... 'label', 'Load Image',... 'callback','img_gui(''load_image'')'); Page (87) mnu_file_Save=uimenu('parent', mnu_file, ... 'label', 'Save Image',... 'callback','img_gui(''save_image'')'); mnu_img=uimenu('parent', fig, ... 'label', 'Image'); mnu_img_negative=uimenu('parent', mnu_img, ... 'label', 'Negative',... 'callback','img_gui(''negative'')'); mnu_img_flipH=uimenu('parent', mnu_img, ... 'label', 'Flip Horizontally',... 'callback','img_gui(''flip_h'')'); mnu_img_flipV=uimenu('parent', mnu_img, ... 'label', 'Flip Vertically',... 'callback','img_gui(''flip_v'')'); mnu_img_original=uimenu('parent', mnu_img, ... 'label', 'Original',... 'callback','img_gui(''original'')'); GUI = struct('axes', ax, 'img' , img); set(fig, 'UserData', GUI); % Adding "About" menu mnu_help = uimenu('parent',fig, ... 'label', 'Help'); mnu_help_about = uimenu('parent',mnu_help, ... 'label', 'About', ... 'callback', 'img_gui(''about'')'); img_gui('fix_default'); % fix default image img_gui('set_colormap'); img_gui('fix_axes_limits'); else figure(fig); end Page (88) elseif strcmp (action , 'load_image') [fileName,pathName]=uigetfile('*.jpg;*.jpeg;*.bmp;*.png' ,'Select image file'); if fileName ~= 0; img=imread([pathName,fileName]); fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); set(GUI.img,'CData',img); set(GUI.img,'UserData',img); img_gui('set_colormap'); img_gui('fix_axes_limits'); end elseif strcmp (action , 'save_image') [fname,pname] = uiputfile('*.jpg','Save as'); if fname ~=0 fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); imwrite(get(GUI.img,'CData'),[pname,fname],'jpg') end elseif strcmp (action , 'negative') fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=double(get(GUI.img,'CData')); img=255-img; set(GUI.img,'CData',uint8(img)); elseif strcmp (action , 'flip_h') fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=double(get(GUI.img,'CData')); img=flipdim(img,2); set(GUI.img,'CData',uint8(img)); Page (89) elseif strcmp (action , 'flip_v') fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=double(get(GUI.img,'CData')); img=flipdim(img,1); set(GUI.img,'CData',uint8(img)); elseif strcmp (action , 'original') fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=get(GUI.img,'UserData'); set(GUI.img,'CData',img); elseif strcmp (action , 'fix_default') % Fix the default image fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=double(get(GUI.img,'CData')); img = 255 * (img/max(img(:))); img = uint8(img); set(GUI.img,'CData',img); set(GUI.img,'UserData',img); elseif strcmp (action , 'set_colormap') % Set the correct color map for rgb and grayscale images fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=get(GUI.img,'CData'); if ndims(img)==3 colormap(GUI.axes,'default') else colormap(GUI.axes, gray(256)) end Page (90) elseif strcmp (action , 'fix_axes_limits') % fix the scale of the axes to match the image fig=findobj('tag', 'img_gui_figure'); GUI=get(fig,'UserData'); img=get(GUI.img,'CData'); img_sz = size(img); img_w = img_sz(2); img_h = img_sz(1); set(GUI.axes,'xlim',[1 img_w]); set(GUI.axes,'ylim',[1 img_h]); elseif strcmp(action, 'about'); msgbox('Programmed by Mahmoud Alnaanah', 'About', 'help'); else error('Undefined action'); end return Page (91) Assignment ✔ Write a code for the GUI shown on the right. ✔ When the '=' button is pressed, the value on the left is converted and shown in the text box on the right. ✔ The text box on the right is disabled. ✔ The about menu shows a message with your name. ✔ The options menu shows two sub-menus (Temperature, and Length). Temperature submenu has two sub-sub-menus ('C to F' and 'F to C'), while Length sub-menu has two subsub-menus ('Meters to Feet' and 'Feet to Meters'). ✔ Whenever a sub-sub-menu is selected, the title of the panel is changed accordingly to: 'Celsius to Fahrenheit', 'Fahrenheit to Celsius', 'Meters to Feet', 'Feet to Meters', also the value in the left text box is updated. ✔ The actions of the programs are: 'initialize', 'convert', 'set_option', and 'about'. ✔ See the screenshots in the next page for more information. Page (92) Page (93) Simulink Example: AM Modulation ✔ In this example, the continuous-time AM modulation system shown in the following figure will be simulated using Simulink. ✔ From the Matlab main window, choose New>Simulink Model. ✔ From the Simulink window, choose View> Library Browser. ✔ From the Library Browser, add the following blocks as shown in the previous figure. ▸ Simulink>Sources> Sine Wave, Constant Page (94) ▸ Simulink>Math Operations> Add, Product. ▸ DSP System Toolbox>Filtering>Filter Implementations>Analog Filter Design. ▸ Simulink>Sinks>Scope. Double click on the scope, then: Select File > Number of Input Ports > More, then set the number of ports to 4 Select View>Layout, then set the number of subplots to 4. ✔ From the vertical action bar on the left of the Simulink window, use the Area to highlight the receiver and the transmitter parts. ✔ Connect the blocks and change their names as shown in the previous figure. Press CTRL to create a connection branching from a link. ✔ Double-click on the following elements and change these properties: ▸ Input Signal: Frequency (rad/sec) = 1000*2*pi ▸ DC offset: Constant value = 2 ▸ Transmitter Carrier: Frequency (rad/sec) = 10000*2*pi ▸ Receiver Carrier: Frequency (rad/sec) = 10000*2*pi ▸ Lowpass Filter: Passband edge frequency (rad/s) = 2000*2*pi Page (95) ✔ From the toolbar From the Simulink window, choose Simulation>Model Configuration Parameters, then set Stop time to 0.01. You can also use the toolbar ✔ . Run the simulation and double-click the scope, the different waveforms will be shown as in the figure beside. ✔ From the Simulink window, Choose File>Save As, and save the model as AM_Modulation.slx Page (96) Simulink Example: PID Controller ✔ In this example, the continuous-time PID controller system shown in the following figure will be simulated using Simulink. Page (97) ✔ From the Matlab main window, choose New>Simulink Model. ✔ From the Simulink window, choose View> Library Browser. ✔ From the Library Browser, add the following blocks as shown in the previous figure. ▸ Simulink>Sources>Step ▸ Simulink>Continuous> Transfer Fcn, Integrator, Derivative, PID controller. ▸ Simulink>Math Operations> Sum, Gain. ▸ Simulink>Sinks>Scope. Double click on the scope, then: Select File > Number of Input Ports > 3 Select View>Layout, then set the number of subplots to 3. ✔ From the vertical action bar on the left of the Simulink window, use the Area to highlight the blocks as shown in the previous figure. ✔ Connect the blocks and change their names as shown in the previous figure. Press CTRL to create a connection branching from a link. ✔ Double-click on the following elements and change these properties: ▸ Input: Step time = 0 Page (98) ▸ The Sums before the PID controllers: List of signs = |+▸ The Sum within the PID controller structure: List of signs = +++ ▸ K_P: Gain = 5 ▸ K_I: Gain = 1 ▸ K_D: Gain = 0 ▸ Plant 1, 2, 3: Numerator coefficients: = [1 6 10], Denominator coefficients: [1 7 1] ▸ PID Controller: Proportional (P) = 5, Integral (I) = 1, Derivative (D) = 0 ▸ From the Simulink window, choose Simulation>Model Configuration Parameters, then set Stop time to 10. You can also use the toolbar ✔ . Run the simulation and double-click the scope, the different waveforms will be shown as in the next figure. ✔ From the Simulink window, Choose File>Save As, and save the model as PID_Controller.slx Page (99) Page (100) Simulink Example: 8-PSK Communications System ✔ In this example, the 8-PSK communications system shown in the following figure will be simulated using Simulink. ✔ From the Matlab main window, choose New>Simulink Model. ✔ From the Simulink window, choose View> Library Browser. ✔ From the Library Browser, add the following blocks as shown in the figure. ▸ Communications System Toolbox>Comm Sources>Random Data Sources> Random Integer Generator ▸ Communications System Toolbox>Utility Blocks>Integer to Bit Converter Page (101) ▸ Communications System Toolbox>Modulation>Digital Baseband Modulation>PM> M-PSK Modulator Baseband, M-PSK Demodulator Baseband ▸ Communications System Toolbox>Channels>AWGN Channel ▸ Communications System Toolbox>Comm Sinks>Error Rate Calculation, Constellation Diagram ▸ Simulink>Sinks>Display ✔ Connect the blocks and change their names as shown in the previous figure. Press CTRL to create a connection branching from a link. ✔ Double-click on the following blocks and change these properties: ▸ Error Rate Calculation: Output data = Port, Stop simulation = on ▸ Random Integer Generator: Set size = 8, Sample time = 0.1, Samples per frame = 1024 ▸ Integer to bit converter: Number of bits per integer(M) = 3 ▸ 8-PSK Modulator: M-ary number = 8, Input type = Bit ▸ AWGN Channel: Eb/No (dB) = 8, Number of bits per symbol = 3, Symbol period (s) = 0.1 (The same for the Random Integer Generator) ▸ 8-PSK Demodulator: M-ary number = 8, Output type = Bit Page (102) ▸ From the Simulink window, choose Simulation>Model Configuration Parameters, then set Stop time to 10. You can also use the toolbar ✔ . Run the simulation and and notice the constellation diagram for the signals before and after the AWGN channel. They will be as in figures below. ✔ The Display Block will show three values. The first value is the BER, the second value is the number of incorrect bits, and the third value is the total number of bits received. ✔ From the Simulink window, Choose File>Save As, and save the model as PSK8.slx. Page (103) Using bertool ✔ In the previous 8-PSK model, delete the constellation diagram and add the following block: ▸ Simulink>Sinks>To Workspace ✔ Double-click on the following blocks and set these properties: ▸ To Wrokspace: Variable name = BER, Save format = Array, Save 2-D signals as = 2D array (Concatenation along first dimension) ▸ AWGN Channel: Eb/No (dB) = EbNo ✔ The model will be as in the following figure. Save the model as PSK8_BER.slx. Page (104) ✔ In Matlab window, type the command bertool. The bertool window will appear. ✔ In the Theoretical tap, put the settings as shown in the figure below: ▸ Eb/N0 range = 1:12, Modulation type = PSK , Modulation order = 8 ✔ Press Plot to see the curve for the theoretical values of BER. Page (105) ✔ In the Monte Carlo tap, put the settings as shown in the figure below: ▸ Eb/N0 range = 1:10, BER variable name = BER ✔ Press Browse and choose the PSK8_BER.slx file. ✔ Press RUN to see the curve for the experimental values of BER that are generator using the file PSK8_BER.slx. Page (106) ✔ The curve will be as in the figure below. Page (107) The End Page (108)