# Wisenheimer Brainstorm Wiki

### Site Tools

notes:tools:matlab

# MATLAB

### Commands

format compact       % suppress extra line-feeds
format long          % show all digits after the decimal point
format short         % show only five digits after the decimal point
clc                  % clear the command window
clear v              % delete the variable v
clear v w z          % delete the variables v w z
clear                % delete all variables from the workspace
save                 % save the current workspace to the matlab.mat file
save cust x y        % save the variables 'x' and 'y' to the file cust.mat
load cust x y        % load the variables 'x' and 'y' from the file cust.mat
...                  % continuation of a command to the next line in the command window
help format          % show help information about the format command in the command window
doc format           % show documentation about the format command in a pop up window
help function        % show help for any function 'function'
help precedence      % show the operators' precedence
edit                 % open the code editor
edit myscript        % open the code editor and open the file myscript.m or create it if it does not exist
dbquit               % quit the debugger
pwd                  % the fully qualified path of the current folder (pwd = print working directory)
ls                   % = DOS dir; returns an array of chars
ls directory         % = DOS dir; the same as the function ls('directory')
cd dr                % = DOS cd; cd(dr) changes the current folder to a folder stored in the 'dr' variable
cd..                 % set the parent folder as the current folder; the same as the function cd(..)
mkdir/rmdir          % create and remove folders
quit                 % quit MatLab
cputime              % the CPU time in seconds that has been used by the MATLAB process since MATLAB started

### Built-in Functions

% initialize the random number generator
rnd(0);                  % from the beginning
rnd(start);              % from the start position in the pseudo-random sequence
rng('shuffle');          % from a random position

% rand returns real random numbers that have uniform distribution
rand                     % a random number between 0 and 1
rand(3,4)                % a 3x4 matrix of random numbers between 0.0 and 1.0
1+rand(3,4)*9            % a 3x4 matrix of random numbers between 1.0 and 10.0
fix(1+rand(3,4)*9)       % a 3x4 matrix of random integers between 1 and 10

% randi returns random integers that have uniform distribution
randi(10,3,4)            % a 3x4 matrix of random integers between 1 and 10
randi(10,5)              % a 5x5 matrix of random integers between 1 and 10
randi([5 10],2,3)        % a 2x3 matrix of random integers between 5 and 10
randi([-3,3],1,12)       % a 1x12 vector of random integers between -3 and 3

% randn returns real random numbers that have normal (Gaussian) distribution (a bell curve)
randn(5)                 % a 5x5 matrix of random numbers that range from -inf to +inf clustered around 0.0
% with standard deviation of 1
r = randn(1,1000000);    % a row vector of a million numbers distributed normally with a mean of 0.0 and StdDev=1
hist(r,100)              % show a histogram of the distribution (with 100 of bins)
% y-axis shows the number of random numbers
sqrt(2)                  % ans = 1.4142
sqrt([1 4;9 16;25 36])   % ans = 1 2
%       3 4
%       5 6
sin(pi/4.0)              % ans = 0.7071
sin(pi/2.0)              % ans = 1
sind(30)                 % ans = 0.5000; the argument is in degrees
sum([1 5 -4 2 -3])       % returns a scalar: ans = 1
sum([1 2;3 4])           % returns a 1x2 vector: ans = 4 6
max([1 2 -4 8])          % ans = 8
[maxNumber,maxIndex] = max([1 2 -4 8]) % returns two output values: maxNumber = 8 and maxIndex = 4
length(v)                % the number of elements of a vector v
s = size([1 2;9 8;0 -2]) % returns a row vector s = [3 2]
[row,col] = size([1 2;9 8;0 -2]) % returns two output values: row = 3 and col = 2
size(A,1)                % the size of the first dimension of A
size(A,2)                % the size of the second dimension of A
pause(5)                 % pause for 5 seconds
isprime(n)               % checks if the input argument n is a prime number
>> tic; sum(1:1e9); toc   % measure running time
Elapsed time is 1.987099 seconds.

### Custom Functions

% GetRand returns a 3x3 matrix of random numbers between low and high
function ret = GetRand(low, high)
ret = low + rand(3,4) * (high - low);
end

>> r = GetRand(2,5);        % r is a 3x4 matrix of random number between 2.0 and 5.0
>> r = GetRand(1,10);       % r is a 3x4 matrix of random number between 1.0 and 10.0
>> r = GetRand(-2,3);       % r is a 3x4 matrix of random number between -2.0 and 3.0
% GetRandMatrixAndSum computes the sum of all the elements of the generated random matrix.
% It returns both the random matrix and the sum.
function [A,s] = GetRandMatrixAndSum(low, high)
A = low + rand(3,4) * (high - low);
v = A(:);    % a shorcut matrix indexing: it stacks up all columns in one column vector
s = sum(v);  % the sum of all elements in the vector v
end

>> [X,sum] = GetRandMatrixAndSum(2,3)

X = 2.4018  2.1233  2.4173  2.9448
2.0760  2.1839  2.0497  2.4909
2.2399  2.2400  2.9027  2.4893

sum = 28.5594
% Corners returns elements at the corners of a given matrix in the following order:
% top-left, top-right, bottom-left, bottom-right
function [tl,tr,bl,br] = Corners(M)
tl = M(1,1);
tr = M(1,end);
bl = M(end,1);
br = M(end,end);
end
% MiniMax returns two output values:
% - mmr - a vector containing the absolute values of the difference between the max and min elements in each row
% - mmm - the difference between the max and min elements in the entire matrix
function [mmr,mmm] = MiniMax(M)
mmr = abs(max(M') - min(M'));
mmm = max(M(:)) - min(M(:));
end

% An example of usage
>> M = [66 94 75 18;4 68 40 71;85 76 66 4]
M = 66 94 75 18
4 68 40 71
85 76 66  4
>> [a,b] = MiniMax(M)
a = 76 67 81
b = 90

>> max(M(2,:))        % the max element in the second row: ans = 71
>> max(M')            % max elements in each row as a row vector: ans = 94 71 85
>> max(M, [], 2)      % max elements in each row as a column vector: ans = 94
71
85
>> max(M')-min(M')    % ans = 76 67 81
% OneMore prompts the user to enter a number. Then, adds 1 to the number and returns the result.
function a = OneMore
x = input('Enter a number: ');
a = x + 1;
end

The IsValidDate function takes three positive integer scalar values: year, month, and day. If the input values represent a valid date, the function returns true, otherwise false.

The function verifies the rules for leap years:

• Every year divisible by 4 is a leap year.
• Except the years that are divisible by 100.
• However, years that are divisible by 400 are also leap years.

For example, the year 1900 was not a leap year, but the year 2000 was.

function isvalid = IsValidDate (y, m, d)

% Check that the inputs are scalars.
if ~(isscalar(y) && isscalar(m) && isscalar(d))
isvalid = false;
% Check that inputs are positive.
elseif ~all([y, m, d] > 0)
isvalid = false;
% Check that inputs are integers.
elseif any(rem([y, m, d], 1))
isvalid = false;
% Check that m and d are below the max possible
elseif (m > 12) || (d > 31)
isvalid = false;
else
% Vector of the number of days for each month.
D = [31 28 31 30 31 30 31 31 30 31 30 31];

leap = 0;

% The same as: if isequal(rem(y, 4), 0) && (~isequal(rem(y, 100), 0) || isequal(rem(y, 400), 0))
if m == 2
leap = ( (y/4) == fix(y/4) && ((y/100) ~= fix(y/100) || (y/400) == fix(y/400)) );
end

if d > D(m) + leap
isvalid = false;
else
isvalid = true;
end
end
>> valid = IsValidDate(2018,4,1)
valid = 1

>> valid = IsValidDate(2018,4,31)
valid = 0

>> valid = IsValidDate(1312, 2, 29)
valid = 1

>> valid = IsValidDate(2000,2,29)
valid = 1

>> valid = IsValidDate(1900,2,29)
valid = 0

The values assigned to the loop index do not have to be

• integers
• regularly spaced
• assigned in increasing order
• scalars

The loop index is assigned the columns of an array.

% SumInts adds up consecutive integers between 1 and N.
function SumInts(N)
total = 0;
for n = 1:N  % n = 1,2,3..N
total = total + n;
end
fprintf('Total: %d\n', total);
>> SumInts(5)
Total: 15

>> SumInts(10)
Total: 55

>> SumInts(100)
Total: 505
function RandomHalf
for x = rand(1,10) % x is assigned the elements of a vector of 10 random numbers
if x > 0.5
fprintf('%.3f>, ', x);
else
fprintf('%.3f<, ', x);
end
end
fprintf('\n');
>> RandomHalf
0.439<, 0.382<, 0.766>, 0.795>, 0.187<, 0.490<, 0.446<, 0.646>, 0.709>, 0.755>,
% The Fibonacci function returns a Fibonacci sequence for n.
function f = Fibonacci(n)
if ( ~isscalar(n) || n<1 || n ~= fix(n) )
error('n must be a positive integer');
end

f(1) = 1;
f(2) = 1;
for ii = 3:n
f(ii) = f(ii-2) + f(ii-1);
end
>> Fibonacci(20)
ans = Columns 1 through 12
1   1   2   3   5   8   13   21   34   55   89   144
Columns 13 through 20
233   377   610   987   1597   2584   4181   6765
% The HalfSum function adds up the elements in the upper triangular part of the input matrix.
function summa = HalfSum(M)
summa = 0;
[row col] = size(M);
for r = 1:row
for c = r:col
summa = summa + M(r,c);
end
end
>> summa = HalfSum([1 2 3; 4 5 6; 7 8 9])
ans = 26
% The ApproxSqrt function calculates an estimate of the square root of its input argument x > 0
function y = ApproxSqrt(x)
y = x;
% 0.00001 is the accuracy we want to achieve.
while abs(y^2 - x) > 0.00001*x
y = (x/y + y) / 2;
end
>> a = ApproxSqrt(2)
a = 1.414215686274510

>> a - sqrt(2)
ans = 2.123901414519125e-06

>> a = ApproxSqrt(200)
a = 14.142136001158033

>> a - sqrt(200)
ans = 3.774270815881664e-07
% The Caesar's cypher is a simple encryption algorithm. It adds a fixed value to the ASCII code of each character
% of an input string i.e., it shifts the characters of the string. Decrypting the string is achieved
% by shifting back by the same amount i.e., by subtracting the same fixed value from the characters.

% The function Caesar accepts two arguments:
% - the character vector to be encrypted.
% - the shift amount.
% The function returns the encrypted string. It works with all visible ASCII characters from the space to ~
% which have the ASCII codes 32 to 126 respectively. If the shifted code goes outside of this range, the function
% wraps the code around.

% Solution 1
function coded = Caesar(s, shift)

% 95 is the difference between the ASCII codes of the last character ~ and the first character, the space:
% 95 = double('~') - double(' ') + 1

% Remove the wrapping of the input shifting.
if abs(shift) > 95
shift = shift - fix(shift/95) * 95;
end

% Shift all the characters in the input string. Obtain a vector of numbers.
s = s + shift;

% Wrap the characters that are greater than the maximum allowed code. We need to use the mod function
% because the codes may be greater than the max code after applying shifting.
s(s > 126) = mod(s(s > 126), 126) + 32 - 1;

% Wrap the characters that are less than the minimum allowed code.
s(s < 32) = 95 + s(s < 32);

% Convert the vector of numbers back to a string.
coded = char(s);
end

% Solution 2
function coded = Caesar(s, shift)

s = double(s) + shift;
first = double(' ');
last = double('~');

coded = char(mod(s - first, last - first + 1) + first);
end

% Solution 3 - uses the circshift function
function coded = Caesar(s, shift)
v = ' ' : '~';
[~, loc] = ismember(s, v);
v2 = circshift(v, -shift);
coded = v2(loc);
end

% A handy string for testing the Caesar function:
' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~' | | | | | | | | | | 4 % SparseToMatrix creates a matrix on the basis of an input sparse matrix % represented by a cell argument. The argument contains: % - a 2-element vector representing the size of the sparse matrix % - a scalar specifying the default value of the sparse matrix % - each successive element of the cell vector is a 3-element vector % representing one element of the sparse matrix that has a value other % than the default: the row index, the column index, and the actual % value. % Example: % matrix = SparseToMatrix({[2 3], 0, [1 2 3], [2 2 -3]}) % matrix = 0 3 0 % 0 -3 0 function matrix = SparseToMatrix(cellvec) rows = cellvec{1}(1); cols = cellvec{1}(2); defautValue = cellvec{2}; M = defautValue*ones(rows,cols); for j = 3:length(cellvec) coord = cellvec{j}; x = coord(1); y = coord(2); val = coord(3); M(x,y) = val; end matrix = M; end ### Variable Number of Function Arguments We have two built-in function that help us write functions with variable number of arguments: • nargin (Number of Arguments Input) - returns the number of input arguments that the function was called with • nargout (Number of Arguments Output) - returns the number of output arguments that the function caller requested % The function MulTable returns an n-by-m multiplication table in the % output argument table. Optionally, it can return the sum of all elements % in the output argument summa. If m is not provided, it returns an n-by-n % matrix. The input arguments n and m: n >= 0, m >= 0 % Syntax: % T = MulTable(N) returns an N-by-N matrix containing the multiplication % table for the integers 1 through N. % T = MulTable(N,M) returns am N-by-M matrix. % [T SM] = MulTable(...) returns the matrix containing the multiplication % in T and the sum of all its elements in SM. function [table, summa] = MulTable(n, m) % Perform validation if nargin < 1 error('Please, provide at least one input argument.'); end % Check if the first argument n is a positive integer scalar. % The fix function rounds its argument to an integer. if ~isscalar(n) || n < 1 || n ~= fix(n) error('n needs to be a positive integer'); end % Check if the second argument m is a positive integer scalar. if (nargin == 2) && (~isscalar(m) || m < 1 || m ~= fix(m)) error('m needs to be a positive integer'); end % Check if the function was called with just one argument. % If so, set a default value for the input that is omitted. if (nargin < 2) m = n; end % Compute the multiplication table using matrix multiplication. % The resulting table is an n-by-m matrix. table = (1:n)' * (1:m); % Determine if we need to compute the sum of the matrix. If so, calculate % the sum using the sum function. The sum function computes the sums of the % columns of a matrix and returns them as a vector. Here, we use the colon % operator to create the column vector from all the elements of the % multiplication table. Then, we sum all the elements of this column % vector. if nargout == 2 summa = sum(table(:)); end >> MulTable(3,4) ans = 1 2 3 4 2 4 6 8 3 6 9 12 >> [table s] = MulTable(3,4) table = 1 2 3 4 2 4 6 8 3 6 9 12 s = 60 >> table = MulTable(5) table = 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25 >> MulTable Error using MulTable (line 10) Please, provide at least one input argument. >> MulTable(-1) Error using MulTable (line 16) n needs to be a positive integer >> MulTable(2,3.41) Error using MulTable (line 21) m needs to be a positive integer >> MulTable([1 2]) Error using MulTable (line 16) n needs to be a positive integer >> help MulTable % shows the description of the function included as a comment before the function keyword ### Colon Operator The colon operator returns a row vector. >> x = 1:3:7 % start at 1; increase by the steps of 3; stop before you go over 7 x = 1 4 7 >> 1:3:10 % start at 1; increase by the steps of 3; stop before you go over 10 ans = 1 4 7 10 >> a = 1:10 % shortcut: start at 1; increase by 1; stop before you go over 10 ans = 1 2 3 4 5 6 7 8 9 10 >> size(a) ans = 1 10 >> colon(1,10) % the same as 1:10 ans = 1 2 3 4 5 6 7 8 9 10 >> 1:2:10 % a vector of all odd numbers smaller than 10 starting at 1 ans = 1 3 5 7 9 >> 7:-3:1 % a vector with decreasing values of the elements ans = 7 4 1 >> e = [] % an empty matrix e = [] >> size(e) ans = 0 0 >> q = 7:3:1 % a 1 by 0 vector q = 1×0 empty double row vector ### Logical Indexing Create a vector containing only positive elements from another vector. >> v = [-1 2 4 -5 -6 7 -3] v = -1 2 4 -5 -6 7 -3 >> w = v(v > 0) w = 2 4 7 % v >= 0 is a logical array >> v >= 0 ans = 1×7 logical array 0 1 1 0 0 1 0 % Define a logical array on a basis of a vector. >> h = logical([1 -2 0 9.32 -2 0]) h = 1×6 logical array 1 1 0 1 1 0 >> a = 1:6 a = 1 2 3 4 5 6 % Apply the logical array h to the vector a. >> a(h) ans = 1 2 4 5 Compare each element of a vector with corresponding elements of another vector. >> v = [2 5 3 4 7 1] v = 2 5 3 4 7 1 >> w = [4 2 6 1 3 2] w = 4 2 6 1 3 2 >> b = v(v > w) b = 5 4 7 >> v > w ans = 1×6 logical array 0 1 0 1 1 0 Modify elements of an indexed vector by using the logical indexing on the left-hand side of the assignment statement. >> v = [1 -3 4 -6 7 9 -2 -5 -8 2] v = 1 -3 4 -6 7 9 -2 -5 -8 2 % Replace all negative values of v with 0s. >> v(v < 0) = 0 v = 1 0 4 0 7 9 0 0 0 2 % Replace 0s with 1, 2, 3, 4, and 5. >> v(v == 0) = 1:5 v = 1 1 4 2 7 9 3 4 5 2 % Add 10 to all elements less or equal 2. >> v(v <= 2) = v(v <= 2) + 10 v = 11 11 4 12 7 9 3 4 5 12 Logical indexing on matrices produces a column vector by stacking the columns of the resulting matrix. >> A = [1 2 3;4 5 6] A = 1 2 3 4 5 6 >> B = A(A > 2) B = 4 5 3 6 >> A = randi(10,5)-5 A = -3 1 -3 5 -1 2 -2 -1 3 1 3 3 2 0 1 2 -3 3 0 4 0 2 -4 0 3 % Set negative elements of a matrix to 88. >> A(A<0) = 88 A = 88 1 88 5 88 2 88 88 3 1 3 3 2 0 1 2 88 3 0 4 0 2 88 0 3 % Assign different values to the elements with the value 88. Note that the assignment is in column-major order. % Assigning a column vector would give the same result A(A == 88) = 101:107' >> A(A == 88) = 101:107 A =101 1 104 5 107 2 102 105 3 1 3 3 2 0 1 2 103 3 0 4 0 2 106 0 3 % If the number of elements on the right is different than the number of elements found by logical indexing % on the left we get an error. >> A(A > 100) = 101:200 Unable to perform assignment because the left and right sides have a different number of elements. % Use logical indexing on both sides of the assignment. >> A(A > 100) = A(A > 100) - 50 A = 51 1 54 5 57 2 52 55 3 1 3 3 2 0 1 2 53 3 0 4 0 2 56 0 3 • Logical indexing on the right-hand side of the assignment statement produces a subset of values. • Logical indexing on the left-hand side of the assignment statement updates a subset of values. ### Vectors >> v = [1 2 3] % a row vector 1 x 3 v = 1 2 3 >> v = [1,2,3] % the same vector as [1 2 3]; you can use a space or a comma as element separators v = 1 2 3 >> v = [1:3] % the same vector as [1 2 3] but using the colon operator v = 1 2 3 >> size(v) % the size of the vector v ans = 1 3 >> w = [1;2;3] % a column vector 3 x 1 w = 1 2 3 >> size(w) % the size of the vector w ans = 3 1 >> [1 2] + [2 3] % add two vectors ans = 3 5 >> v = [2 3 4]'; % multiply and add two column vectors >> w = [1 1 1]'; >> u = 2 * v + 3 * w u = 7 9 11 >> [1 2] * [3 4]' % calculate the dot product by multiplying a row vector by a column vector ans = 11 >> v = [1 2 2]; % calculate the vector length >> norm(v) ans = 3 >> v = [1 2 2]; % calculate the vector length; the vector length is the same as sqrt(v*v) >> sqrt(v * v') ans = 3 >> v = [1 2]; % calculate the cosine between two vectors >> w = [3 4]; >> cosine = v * w' / (norm(v) * norm(w)) cosine = 0.9839 >> i = [1 0]; % calculate an angle (in radians) between two unit-length vectors >> j = [0 1]; >> cosine = i * j'; >> angle = acos(cosine) angle = 1.5708 >> [4 -1 7 5 3] > [5 -9 6 5 -3] % compare elements of two vectors one by one ans = 0 1 1 0 1 >> [4 -1 7 5 3] <= 4 % compare elements of a vector to a scalar ans = 1 1 0 0 1 >> sum([14 9 3 14 8 3] == 14) % count elements in a vector that are equal to 14 ans = 2 >> [1 pi 0 -2] % show true/false values of some numbers ans = 1.0000 3.1416 0 -2.000 >> ~[1 pi 0 -2] ans = 0 0 1 0 >> [1 -3 0 9] & [pi 0 0 2] % use the vector logical operator AND; the && operator compares scalars ans = 1 0 0 1 >> [1 -3 0 9] | [pi 0 0 2] % use the vector logical operator OR; the || operator compares scalars ans = 1 1 0 1 >> 2 & [0 1;2 3] % use the scalar/matrix AND ans = 0 1 1 1 >> 2 | [0 1;2 3] % use the scalar/matrix OR ans = 1 1 1 1 >> 1.4 < sqrt(2) & [pi > 3 -1 > 1] ans = 1 0 ### Matrices >> A = [1 2 3; 4 5 6] % a matrix 2 x 3 A = 1 2 3 4 5 6 >> A = [1:3; 4:6] % the same matrix using the colon operator A = 1 2 3 4 5 6 >> A = [1 2; 3 4; 5 6] A = 1 2 3 4 5 6 >> B = [0 1 -1; 2.5 pi 100] % a matrix 2 x 3 B = 0 1.0000 -1.0000 2.5000 3.1416 100.0000 >> x = 5 % a scalar; 1 x 1 matrix x = 5 >> size(A) % the size of the matrix A ans = 2 3 >> size(x) % the size of the scalar x ans = 1 1 >> X = [1:4; 5:8; 9:12] % create a 3 x 4 matrix using the colon operator X = 1 2 3 4 5 6 7 8 9 10 11 12 >> X = [1 5 -2; 3 0 7] % show multiple matrices by typing X,Y X = 1 5 -2 3 0 7 >> Y = [1:3; 4:6] Y = 1 2 3 4 5 6 >> X,Y X = 1 5 -2 3 0 7 Y = 1 2 3 4 5 6 ### Updating Matrices Below, there are examples of the following operations: • Matrix indexing • Subarrays • Constructing a new matrix from subarrays >> A = [1 2 3; 4 5 6] A = 1 2 3 4 5 6 >> A(2,3) % an element in the 2nd row and the 3rd column in the matrix A ans = 6 >> A(2,3) = 88 % assign a value to the specified element A = 1 2 3 4 5 88 >> B = A(2,[1 3]) % subarray: elements in the 2nd row and the 1st and the 3rd column B = 4 88 >> B = A([2 1],2) % subarray: elements in the 2nd and 1st row and the 2nd column B = 5 2 >> B = A(2, 1:3) % subarray: the same as A(2, [1 2 3]) B = 4 5 88 >> B = A([2 1 2],[3 1 1 2]) % a new matrix constructed from subarrays of an existing matrix B = 88 4 4 5 3 1 1 2 88 4 4 5 >> A(2:-1:1, 3:-1:1) % a new matrix constructed from subarrays of an existing matrix ans = 88 5 4 3 2 1 >> A(end,2) % the last element of the 2nd column; end means the last index ans = 5 >> A(2,end) % the last element of the 2nd row ans = 88 >> A(2,end-1) % the element before the last one in the 2nd row ans = 5 >> A(1,[end,end-1]) % the last two elements of the 1st row in the reversed order ans = 3 2 % create a matrix by assigning a value to a non-existing matrix >> B(2,2) = 1 B = 0 0 0 1 % expand a matrix by assigning a value to a non-existing element index; the same as B(end+1,end+1) = 8 >> B(3,3) = 8 B = 0 0 0 0 1 0 0 0 8 % expand a matrix using the 'end' keyword >> B(end+1,1) = 11 B = 0 0 0 0 1 0 0 0 8 11 0 0 % assign 2 to the second column >> B(1:end,2) = 2 B = 0 2 0 0 2 0 0 2 8 11 2 0 % assign 3 to the elements in all the rows and in the 2nd and 3rd column >> B(1:end,2:3) = 3 B = 0 3 3 0 3 3 0 3 3 11 3 3 % the 'end' keyword with the colon operator >> A = [1:2:10] A = 1 3 5 7 9 >> A(1,1:2:end) ans = 1 5 9 >> A(1,end-1:end) ans = 7 9 % get all the elements in the first row; A(1,:) is the same as A(1,1:end); the : stands for 1:end % the entire matrix would be A(:,:), the same as just A >> A(1,:) ans = 1 3 5 7 9 % assign a matrix to a subarray; the dimensions of the matrix have to match the dimensions of the subarray >> B(1:end,2:3) = [10 20;30 40;50 60;70 80] B = 0 10 20 0 30 40 0 50 60 11 70 80 % assign the second column of A to a variable v; change each element of the last row of A to 0 >> A = [1:5; 6:10; 11:15; 16:20] A = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 >> v = A(1:end,2); v = 2 7 12 17 >> A(end,1:end) = 0 A = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 0 0 0 0 ### Combining Matrices The purpose of combining matrices is to obtain a new matrix composed of existing matrices. For example, let's say we have two matrices A and B. We can obtain a new matrix C by combining A and B: | A B | C = | B C | Put matrices side-by-side or stack matrices: >> A1 = [1 1 1; 1 1 1] A1 = 1 1 1 1 1 1 >> A2 = [2 2 2; 2 2 2] A2 = 2 2 2 2 2 2 >> A3 = [3 3 3; 3 3 3] A3 = 3 3 3 3 3 3 % put matrices A1, A2, and A3 side-by-side >> [A1 A2 A3] ans = 1 1 1 2 2 2 3 3 3 1 1 1 2 2 2 3 3 3 % stack matrices A1, A2, and A3 >> [A1;A2;A3] ans = 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 % you can only combine matrices with matching dimensions >> B1 = [1;1] B1 = 1 1 >> B2 = [2 2;2 2] B2 = 2 2 2 2 >> B3 = [3 3 3;3 3 3] B3 = 3 3 3 3 3 3 >> [B1 B2 B3] ans = 1 2 2 3 3 3 1 2 2 3 3 3 >> [B1 B2 B3 B2 B1] ans = 1 2 2 3 3 3 2 2 1 1 2 2 3 3 3 2 2 1 >> [B1;B2;B3] Error using vertcat Dimensions of arrays being concatenated are not consistent. The function Trio returns a 3n-by-m matrix T. The top third of T (n-by-m submatrix) is all 1s, the middle third is all 2s, and the bottom third is all 3s. function T = Trio(n,m) T1 = ones(n,m); T2 = 2*ones(n,m); T3 = 3*ones(n,m); T = [T1;T2;T3]; end % an example >> Trio(2,4) ans = 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 ### Matrix & Vector Transposition The transposition operator takes precedence over the colon operator. >> H = [1 2 3;4 5 6] H = 1 2 3 4 5 6 >> G = H' G = 1 4 2 5 3 6 >> v = [1;3;5;7] v = 1 3 5 7 >> v = v' v = 1 3 5 7 >> [1:2:5]' ans = 1 3 5 % you need to use the parentheses because the transposition operator takes precedence over the colon operator >> (1:2:5)' ans = 1 3 5 ### Arithmetic Examples of arithmetic operations on matrices and arrays: • Array addition (the same as matrix addition) • Array multiplication (different than matrix multiplication) • Matrix multiplication • Array division • Array exponentiation Two arrays used in the examples: >> X = [1 5 -2; 3 0 7] X = 1 5 -2 3 0 7 >> Y = [1:3; 4:6] Y = 1 2 3 4 5 6 Array and matrix addition and subtraction: >> Z = X + Y Z = 2 7 1 7 5 13 >> Z = X - Y Z = 0 3 -5 -1 -5 1 Array multiplication: • Uses the .* operator: Z = X.*Y • Different than matrix multiplication: .* multiplies each pair of elements from both arrays. • Arrays have to be of the same dimensions. • An example of usage: Calibration: each element of a given array has to be calibrated by values from another array. % Both arrays X and Y are 2 x 3. >> Z = X.*Y Z = 1 10 -6 12 0 42 % Arrays multiplication using nested loops. The same as P = A.*A [row col] = size(A); for r = 1:row for c = 1:col P(r,c) = A(r,c) * A (r,c) end end Matrix multiplication: • Uses the * operator: Z = X*Y • The X's width must be the same as the Y's height. • In other words: the number of columns in X must be the same as the number of rows in Y. Let's introduce the following symbols: • L - the height of X i.e., the number of rows in X. • M1 - the width of X i.e., the number of columns in X. • M2 - the height of Y i.e., the number of rows in Y. • N - the width of Y i.e., the number of columns in Y. Note, that M1 has to be equal to M2 in order to perform matrix multiplication: M1 = M2 = M Then, Z = X*Y has dimensions L x N: • M1 and M2 are called the inner dimensions of X and Y. • L and N are called the outer dimensions of X and Y. % The matrix A is 4 x 3 >> A = [1 2 3;4 5 6;6 1 1;0 1 3] A = 1 2 3 4 5 6 6 1 1 0 1 3 % The matrix B is 3 x 2 >> B = [2 -2;3 8;7 4] B = 2 -2 3 8 7 4 % The inner dimensions of X and Y are the same: 3 >> [size(A),size(B)] ans = 4 3 3 2 % We are able to perform matrix multiplication: the matrix C is 4 x 2 >> C = A*B C = 29 26 65 56 22 0 24 20 % We are not able to multiply B and A because their inner dimensions differ: 2 and 4 respectively. >> [size(B),size(A)] ans = 3 2 4 3 Array division: • Arrays have to be the same shape and size. • X./Y - “over” division • X.\Y - “under” division >> A = [2 4; 5 10; 9 3] A = 2 4 5 10 9 3 >> B = [1 2; 5 2; 3 3] B = 1 2 5 2 3 3 >> A./B ans = 2 2 1 5 3 1 >> B.\A % the same as A./B ans = 2 2 1 5 3 1 >> A.\B ans = 0.5000 0.5000 1.0000 0.2000 0.3333 1.0000 Array exponentiation: • Uses the .^ operator: X^N • The matrix X has to be square. >> X = [1 2;3 4] X = 1 2 3 4 >> N = [6 0.5; -1 2] N = 6.0000 0.5000 -1.0000 2.0000 >> X.^N ans = 1.0000 1.4142 0.3333 16.0000 >> X^3 % X^3 is the same as X*X*X ans = 37 54 81 118 Operations involving a scalar: >> A = [1 2 3;4 5 6] A = 1 2 3 4 5 6 >> A + 3 ans = 4 5 6 7 8 9 >> A - 1 ans = 0 1 2 3 4 5 >> 2.*A ans = 2 4 6 8 10 12 >> 2*A ans = 2 4 6 8 10 12 >> A./2 ans = 0.5000 1.0000 1.5000 2.0000 2.5000 3.0000 >> 2./A ans = 2.0000 1.0000 0.6667 0.5000 0.4000 0.3333 >> A.^2 ans = 1 4 9 16 25 36 >> 2.^A ans = 2 4 8 16 32 64 % the sum of 3^n for n=0..8: 3^0 + 3^1 + 3^2 + 3^3 + ... + 3^8 >> sum(3.^[0:8]) ans = 9841 function fh = GetPolynomial(p) function polynomial = poly(x) polynomial = sum(p .* x.^(0 : length(p)-1)); end fh = @poly; end ### Special matrices Use M = zeroes(n,m) to pre-allocate memory for a large n-by-m matrix M. >> zeros(2,3) ans = 0 0 0 0 0 0 >> zeros(2) ans = 0 0 0 0 >> ones(1,5) ans = 1 1 1 1 1 >> ones(3,1) ans = 1 1 1 >> ones(2,2) ans = 1 1 1 1 >> eye(2) ans = 1 0 0 1 >> 6*eye(5)-ones(5,5) ans = 5 -1 -1 -1 -1 -1 5 -1 -1 -1 -1 -1 5 -1 -1 -1 -1 -1 5 -1 -1 -1 -1 -1 5 >> diag([7 4 3 1]) ans = 7 0 0 0 0 4 0 0 0 0 3 0 0 0 0 1 >> pascal(4) % 4 x 4 symmetric Pascal matrix ans = 1 1 1 1 1 2 3 4 1 3 6 10 1 4 10 20 >> inv(pascal(4)) ans = 4.0000 -6.0000 4.0000 -1.0000 -6.0000 14.0000 -11.0000 3.0000 4.0000 -11.0000 10.0000 -3.0000 -1.0000 3.0000 -3.0000 1.0000 >> L = abs(pascal(4,1)) % Pascal's lower triangular ans = 1 0 0 0 1 -1 0 0 1 -2 1 0 1 -3 3 -1 >> L * L' % the same as pascal(4) ans = 1 1 1 1 1 2 3 4 1 3 6 10 1 4 10 20 >> inv(L') * inv(L) % the same as inv(pascal(4)) ans = 4 -6 4 -1 -6 14 -11 3 4 -11 10 -3 -1 3 -3 1 >> hilb(6) % the approximation of a Hilbert matrix (fractions are rounded off) ans = 1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 0.5000 0.3333 0.2500 0.2000 0.1667 0.1429 0.3333 0.2500 0.2000 0.1667 0.1429 0.1250 0.2500 0.2000 0.1667 0.1429 0.1250 0.1111 0.2000 0.1667 0.1429 0.1250 0.1111 0.1000 0.1667 0.1429 0.1250 0.1111 0.1000 0.0909 >> inv(hilb(6)) % the approximated inverse of the Hilbert matrix ans = 1.0e+06 * 0.0000 -0.0006 0.0034 -0.0076 0.0076 -0.0028 -0.0006 0.0147 -0.0882 0.2117 -0.2205 0.0832 0.0034 -0.0882 0.5645 -1.4112 1.5120 -0.5821 -0.0076 0.2117 -1.4112 3.6288 -3.9690 1.5523 0.0076 -0.2205 1.5120 -3.9690 4.4100 -1.7464 -0.0028 0.0832 -0.5821 1.5523 -1.7464 0.6985 >> invhilb(6) % the exact inverse of the Hilbert matrix ans = 36 -630 3360 -7560 7560 -2772 -630 14700 -88200 211680 -220500 83160 3360 -88200 564480 -1411200 1512000 -582120 -7560 211680 -1411200 3628800 -3969000 1552320 7560 -220500 1512000 -3969000 4410000 -1746360 -2772 83160 -582120 1552320 -1746360 698544 ### Strings and Characters There are two types that can hold strings in MATLAB: • the string type, e.g., “house” • the char type, e.g., 'house' % char type >> s = 'abracadabra' % s = 'abracadabra' >> class(s) % ans = 'char' >> size(s) % ans = 1 11 % string type >> s = "abracadabra" % s = "abracadabra" >> class(s) % ans = 'string' >> size(s) % ans = 1 1 The char type vs. the string type. >> s = 'qwerty' >> r = s(end:-1:1) % r = 'ytrewq' - reversed >> s = "qwerty" >> r = s(end:-1:1) % r = "qwerty" - not reversed >> string('There''s') % ans = "There's something" >> s = "Quote: ""yes""." % s = "Quote: "yes"." >> t = ["a";"bb";"ccc";"dddd"] test = 4×1 string array "a" "bb" "ccc" "dddd" >> t = ['a';'bb';'ccc';'dddd'] Error using vertcat Dimensions of arrays being concatenated are not consistent. % The vertcat error applies to a matrix of any type. >> t = [1;2 2;3 3 3;4 4 4 4] Error using vertcat Dimensions of arrays being concatenated are not consistent. % Append the trailing spaces to make the elements the same length. >> t2 = char(t) t2 = 4×4 char array 'a ' 'bb ' 'ccc ' 'dddd' % The char elements of a row vector are concatenated. >> s = ['a' 'bb' 'ccc' 'dddd'] s = 'abbcccdddd' % The string elements of a row vector are kept separately. >> s2 = ["a" "bb" "ccc" "dddd"] s2 = 1×4 string array "a" "bb" "ccc" "dddd" Conversion >> string(14) % ans = "14" >> string(-2.342) % ans = "-2.342" >> string(3.1e8) % ans = "310000000" >> string(pi) % ans = "3.1416" >> code = uint16(477) % code = uint16 477 >> string(code) % ans = "477" >> string(1.234567) % ans = "1.2346" >> string(false) % ans = "false" >> string([5 0 -4 8] > [0 0 0 0]) ans = 1×4 string array "true" "false" "false" "true" >> double("17"), double("-1.234567"), double("3.1e8"), double("pi") ans = 17 ans = -1.2346 ans = 310000000 ans = NaN >> int8("120") Error using int8 Conversion to int8 from string is not possible. >> format long >> double("17"), double("-1.234567"), double("3.1e8"), double("pi") ans = 17 ans = -1.234567000000000 ans = 310000000 ans = NaN >> format short >> double("17") % ans = 17 >> double('17') % ans = 49 55 >> double('ABCDE') % ans = 65 66 67 68 69 >> str2num('17') % ans = 17 % Use str2double when you don't know if the input argument is a char or a string. >> str2double('17') % ans = 17 >> str2double("17") % ans = 17 >> n = '17'; double(string(n)) % ans = 17 >> n = "17"; double(string(n)) % ans = 17 >> int8(double("17")) % ans = int8 17 % Convert the elements of a cell array using the string function. >> string({1.23, logical(345), 'hi'}) ans = 1×3 string array "1.23" "true" "hi" >> c = 'abracadabra' >> c(2:4) % ans = 'bra' % You can't use vector indexing on the string variables. >> s = "abracadabra" >> s(2:4) Index exceeds array bounds. >> extractBetween(s,2,4) % ans = "bra" >> t = 'abracadabra'; string(t(2:4)) % ans = "bra" % Extract a part of a string that comes between two substrings. % There also extractBefore and extractAfter functions. >> extractBetween("independence","in","ence") ans = "depend" % Print all visible ASCII characters. You don't need to convert an integer to a char explicitly. % You can write fprintf('%s', c) instead of fprintf('%s', char(c)) >> for c = 32:126; fprintf('%s', char(c)); end; fprintf('\n'); !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~

% Another way of printing a range of ASCII characters.
>> ' ' : '~'
ans = ' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' % Reverse a string. >> a = 'abcde' >> r = a(end:-1:1) r = 'edcba' % Strings are vectors of characters. Comparing two strings of the same length returns a vector. >> a == r ans = 1×5 logical array 0 0 1 0 0 % Convert a string to a vector of ASCII codes. >> s = 'ABRACADABRA' s = 'ABRACADABRA' >> code = int8(s) % you can use any numerical type that is large enough to hold 0-255 numbers code = 1×11 int8 row vector 65 66 82 65 67 65 68 65 66 82 65 >> encrypted = char(code + 3) encrypted = 'DEUDFDGDEUD' >> decrypted = char(encrypted - 3) decrypted = 'ABRACADABRA' % Combine characters by transposing a 2D char array. >> S = ['abc';'123'] S = 2×3 char array 'abc' '123' >> S' ans = 3×2 char array 'a1' 'b2' 'c3' % The concatenated dimensions must be the same. >> p = ['asdf';'123'] Error using vertcat Dimensions of arrays being concatenated are not consistent. >> fprintf('Text\n') Text >> fprintf('%d items at %.2f each\nTotal =$%7.2f\n', 6, 2.25, 6*2.25)
6 items at 2.25 each
Total = \$  13.50

>> fprintf('12%% of 200 is %.2f\n', 0.12*200)
12% of 200 is 24.00

>> fprintf('a backslash: \\  a single quote: ''\n')
a backslash: \  a single quote: '

% print an entire vector using just one format specifier
>> fprintf('%6.1f\n', [1 2 3 4]);
1.0
2.0
3.0
4.0

% Store a formatted string in a char vector.
>> r = 12; s = sprintf('The number %.2f\n', r);
>> s
s = 'The number 12.00'
% Find the index of the first occurrence of a substring in a given string.
ans = 3

% Find the indices of all occurrences of a substring in a given string.
ans = 1  8

% Compare two strings. Use strcmpi to perform a case-independent comparison.
>> a = 'abcd'; b = 'abcde';

>> strcmp(a, b)
ans = logical 0

>> strcmp(a, b(1:4))
ans = logical 1

% Replace characters in a string.
>> ['C:', strrep('/main/level/file.txt', '/', '\')]
ans = 'C:\main\level\file.txt'

% Convert a string to a number.
>> str2num('123.4')
ans = 123.4000

% An example of mixed-mode arithmetic (different types of operands).
>> a = '123'; double(a)
ans = 1×3 int8 row vector
49   50   51

>> a + 1
ans = 50   51   52

### Numbers

double is a default data type for all numerical values in MATLAB. It is a 64-bit value.

% Show the type of a variable.
>> x = 23
x = 23

>> class(x)
ans = 'double'

>> class(1)
ans = 'double'

% sqrt(-1) is an imaginary number but MATLAB does not distinguish it from a double
>> class(sqrt(-1))
ans = 'double'

% Print a list of variables in the current workspace. Note that the 3x4 matrix is of class 'double'.
>> whos
Name      Size            Bytes  Class     Attributes

ans       1x6                12  char
x         1x1                 8  double
z         3x4                96  double

% Check the type of a variable.
>> isa(x,'double')
ans = logical 1

% Maximums and minimums of numerical types.
>> intmax
ans = int32 2147483647
>> intmin
ans = int32 -2147483648
>> realmax
ans = 1.7977e+308
>> realmin
ans = 2.2251e-308
>> intmax('uint8')
ans = uint8 255
>> intmin('uint8')
ans = uint8 0
>> intmax('uint64')
ans = uint64 18446744073709551615
>> intmin('uint64')
ans = uint64 0
>> realmax('single')
ans = single 3.4028e+38
>> realmin('single')
ans = single 1.1755e-38

% Conversion functions.
>> x = single(98.73)
x = single 98.7300

>> n = int8(-16)
n = int8 -16

>> m = uint16(1234)
m = uint16 1234

>> whos
Name      Size            Bytes  Class     Attributes

m         1x1                 2  uint16
n         1x1                 1  int8
x         1x1                 4  single

% Conversion functions produce a number that is closest to the input value that can be represented in
% a given data type. It's called clipping.
>> k = uint8(500)
k = uint8 255

>> k = uint8(256)
k = uint8 255

>> k = uint8(-1)
k = uint8 0

>> k = 2; class(k)    % now k has the default MATLAB type 'double'
ans = 'double'

% Assign the minus infinity to a variable.
a = -inf
-1111111 > a             % ans = logical 1

### Datetime and Duration

>> d = datetime(1987,7,26);
>> fieldnames(d)
ans = 8×1 cell array
{'Format'  }
{'TimeZone'}
{'Year'    }
{'Month'   }
{'Day'     }
{'Hour'    }
{'Minute'  }
{'Second'  }

>> class(d)
ans = 'datetime'
% Relative dates
>> datetime                    % ans = datetime 11-Apr-2021 21:37:27
>> datetime("yesterday")       % ans = datetime 10-Apr-2021
>> datetime("today")           % ans = datetime 11-Apr-2021
>> datetime("tomorrow")        % ans = datetime 12-Apr-2021
>> datetime("now")             % ans = datetime 11-Apr-2021 21:42:05

% The weekday function returns two values:
% - an integer representing the day of a week
% - the name of the day of the week
>> [~,weekdayName] = weekday(datetime("now"), 'long')   % weekdayName = 'Sunday'
>> [~,weekdayName] = weekday(datetime("now"), 'short')  % weekdayName = 'Sun'

% Duration preserves units of time.
>> hours(2.5)                  % ans = duration 2.5 hr
>> days(2.5)                   % ans = duration 2.5 days
>> datetime("now") + days(7)   % ans = datetime 18-Apr-2021 21:49:51

% Creating datetimes.
>> datetime(1987,7,26)         % ans = datetime 26-Jul-1987
>> datetime(1927,11,23,17,30,45) % ans = datetime 23-Nov-1927 17:30:45

% Time zones
>> timezones                         % show the names of time zones
>> d = datetime(1927,11,23,17,30,45) % d = datetime 23-Nov-1927 17:30:45
>> d.TimeZone = "Europe/London"      % d = datetime 23-Nov-1927 17:30:45
>> d2 = d                            % d2 = datetime 23-Nov-1927 17:30:45
>> d2.TimeZone                       % ans = 'Europe/London'
>> d2.TimeZone = "America/Chicago"   % d2 = datetime 23-Nov-1927 11:30:45
>> d2.TimeZone = "Europe/Warsaw"     % d2 = datetime 23-Nov-1927 18:30:45

% Formatting
>> d.Format = 'dd-MMMM-yyyy'         % d = datetime 23-November-1927
>> d.Format = 'dd/MM/yyyy'           % d = datetime 23/11/1927
>> d.Format = 'eeee, MMMM dd, yyyy'  % d = datetime Wednesday, November 23, 1927

% Years vs. calendar years
>> d + years(100)                    % ans = datetime Monday, November 22, 2027
>> d + calyears(100)                 % ans = datetime Tuesday, November 23, 2027

% Date components - splitting the parts of the datetime.
>> year(d)                     % ans = 1927
>> day(d)                      % ans = 23
>> hour(d)                     % ans = 17
>> minute(d)                   % ans = 30
>> second(d)                   % ans = 45
>> quarter(d)                  % ans = 4 - the quarter of the year

>> d.Year, d.Month, d.Day, d.Minute
ans = 1927
ans = 11
ans = 23
ans = 30

>> [y1,m1,d1] = ymd(d)
y1 = 1927
m1 = 11
d1 = 23

>> [h1,m1,s1] = hms(d)
h1 = 17
m1 = 30
s1 = 45

>> l = duration(3,7,43)        % l = duration 03:07:43
>> l/2                         % ans = duration 01:33:51

% Add 24 hours; the basic time unit of duration is a day.
>> l+1                         % ans = duration 27:07:43
>> seconds(l)                  % ans = 11263
>> days(l)                     % ans = 0.1304

>> days(datetime(1763,5,17) - datetime(1763,2,15))
ans = 91

>> ms = days(datetime(1763,5,17) - datetime(1763,2,15))
ms = 91

>> class(ms)
ans = 'double'

>> days(1):days(3):days(19)
ans = 1×7 duration array
1 day    4 days    7 days   10 days   13 days   16 days   19 days

>> days(1):3:days(19)
ans = 1×7 duration array
1 day    4 days    7 days   10 days   13 days   16 days   19 days

>> datetime(1763,5,17):14:datetime(1763,7,17)
ans = 1×5 datetime array
17-May-1763   31-May-1763   14-Jun-1763   28-Jun-1763   12-Jul-1763

### Structs

>> account.number = 12345
>> account.balance = 7000
>> account.owner.name = 'Leon Klop'
>> account.owner.email = 'leon@burak.com'

>> class(account)                        % ans = 'struct'
>> class(account.number)                 % ans = 'double'
>> class(account.owner)                  % ans = 'struct'

>> account.owner
ans = struct with fields:
name: 'Leon Klop'
email: 'leon@burak.com'

% Turn the 'account' struct into an array of structs.
>> account(2).number = 876543
>> account(2).owner.name = 'Mania Kulpa'
>> account(2).balance                    % ans = []

% Add a new field to the first struct.
>> account(1).owner.age = 34

% The second struct does not have the new field.
>> account(2).owner.age
Dot indexing is not supported for variables of this type.

% Show both structs.
>> account(1:2).owner
ans = struct with fields:
name: 'Leon Klop'
email: 'leon@burak.com'
age: 34

ans = struct with fields:
name: 'Mania Kulpa'

>> isfield(account(1).owner, 'age')      % ans = logical 1
>> isfield(account(2).owner, 'age')      % ans = logical 0

% Remove the 'age' field from the first struct.
>> account(1).owner = rmfield(account(1).owner, 'age')
>> account(1).owner
ans = struct with fields:
name: 'Leon Klop'
email: 'leon@burak.com'

% Create a struct using fieldname/value pairs.
>> book = struct('Title','C++ for Cats','Price',23.90,'Author','Black Cat')
book = struct with fields:
Title: 'C++ for Cats'
Price: 23.9000
Author: 'Black Cat'

### Cells/Pointers

A script that creates a variable that stores multiple lines of text:

%% Create four cells. Each 'page' variable (a cell) points to a piece of text.
page{1} = 'Opabinia regalis is an extinct, stem group arthropod found ';
page{2} = 'in the Middle Cambrian Burgess Shale Lagerstätte of British ';
page{3} = 'Columbia, Canada. It flourished from 505 million years ago to ';
page{4} = '487 million years ago during the Cambrian Period of the Paleozoic Era.';

%% Print the text.
fprintf('\n');
for j = 1:length(page)
fprintf('%s\n', page{j});
end
fprintf('\n');
>> whos
Name      Size            Bytes  Class     Attributes

j         1x1                 8  double
page      1x4               950  cell

>> % Access individual elements of a page.
>> page{1}
ans = 'Opabinia regalis is an extinct, stem group arthropod found '

>> class(page)              % ans = 'cell'
>> class(page{1})           % ans = 'char'
>> size(page{1})            % ans = 1  59 - a 59-element row vector

A 2×3 array containing six pointers.

>> p = cell(2,3)
p = 2×3 cell array
{0×0 double}  {0×0 double}  {0×0 double}
{0×0 double}  {0×0 double}  {0×0 double}

>> p{1,1} = pi
>> p{2,1} = 'Hi'
>> p{1,2} = [1 2;3 4;5 6]

p = 2×3 cell array
{[3.1416]}  {3×2 double}  {0×0 double}
{'Hi'    }  {0×0 double}  {0×0 double}

>> p{1,2}
ans = 1  2
3  4
5  6

>> p{1,2}(3,2)              % ans = 6
>> p{2,1}                   % ans = 'Hi'
>> p(2,1)                   % ans = 1×1 cell array {'Hi'}

MATLAB does not allow two cells to point to the same object. It copies all the objects pointed by one cell and assign the copies to another pointer.

>> c1 = {[1 2], [10 20]}
c1 = 1×2 cell array
{1×2 double}  {1×2 double}

% Copy the objects pointed by c1 and assign them to c2.
>> c2 = c1
c2 = 1×2 cell array
{1×2 double}  {1×2 double}

>> c1{1,1}                  % ans = 1  2
>> c2{1,1}                  % ans = 1  2
>> c1{1,2}                  % ans = 10 20
>> c2{1,2}                  % ans = 10 20

>> c1{1,1} = 88
c1 = 1×2 cell array
{[88]}  {1×2 double}

>> c1{1,1}                  % ans = 88   - c1 is updated
>> c2{1,1}                  % ans = 1  2 - c2 remains the same

Get a value at the cross-section of a row and a column in an Excel spreadsheet. The first column and the first row in the spreadsheet should contain the x and y values.

function d = GetDistance(x, y)

% Get the indices of a row and a column that contain the values x and y.
row = find(ismember(r(2:end,1), x))+1;
col = find(ismember(r(1,2:end), y))+1;

if isempty(row) || isempty(col)
d = -1;
else
d = r{row, col};
end
end

### Plots & Images

plot(xs,ys,'*')          % asterisks (no lines)
plot(xs,ys,'^')          % triangles (no lines)
plot(xs,ys,'-^')         % solid lines
plot(xs,ys,'r-^')        % red solid lines
plot(xs,ys,'rs')         % red squares (no lines)
plot(xs,ys,'rs--')       % red squares with dashed lines
grid on                  % show the grid
grid                     % toggle the grid on/off
xlabel('x')              % a label on the x-axis
ylabel('y')              % a label on the y-axis
title('Changes')         % the graph's title
axis([0 12 -10 20])      % define a range for x- and y-axes
bar(xs,ys)               % bar graph
figure                   % open a new window for a figure
figure(2)                % make the figure#2 window active
pie([4 2 7 4 7])         % pie chart (percentages calculated automatically)
close(2)                 % close the second figure window (window index is 0-based)
close all                % close all figure windows
pic = imread('ja.jpg');  % assign a picture to a variable; the picture must be located in the current folder
image(pic)               % display a picture assign to the variable 'pic'
axis off                 % hide axes

Examples of plots:

% a simple plot
>> xs = [1, 3, 10];
>> ys = [2, -4.2, 12.3];
>> plot(xs,ys);

% helix
>> t = 0:pi/50:10*pi;
>> plot3(sin(t),cos(t),t);

% plot a vector of squares of the numbers from 1 to 10 (the right side of a parabola)
% note that the x-axis is from 0 to 10
>> a = (1:10).^2
a = 1  4  9  16  25  36  49  64  81 100
>> plot(a)

% plot a vector of squares of the numbers from -10 to 10 (the entire parabola) to a different figure
% note that the x-axis is from 0 to 20
>> a = (-10:10).^2
a = 100  81  64  49  36  25  16  9  4  1  0  1  4  9  16  25  36  49  64  81  100
>> figure(2)
>> plot(a)

To draw a mathematical function properly, we need to pass two vectors:

• one vector for the x-values
• another vector for y-values
>> t = -10:10
t = -10  -9  -8  -7  -6  -5  -4  -3  -2  -1  0  1  2  3  4  5  6  7  8  9  10
>> b = t.^2
b = 100  81  64  49  36  25  16  9  4  1  0  1  4  9  16  25  36  49  64  81  100
>> plot(t,b)

Draw two plots in the same figure:

>> x1 = 0 : 0.1 : 2*pi;
>> y1 = sin(x1);
>> x2 = pi/2 : 0.1 : 3*pi;
>> y2 = cos(x2);
>> plot(x1,y1,x2,y2)

Change the colors of plots:

• make the first plot red
• make the second plot dotted black

Also, and add a legend and the grid.

>> plot(x1,y1,'r',x2,y2,'k:')
>> grid
>> legend('size','cosine')

Use the hold on command to make all subsequent plots to the figure#2 to be drawn on the same axes:

>> figure(2)            % select an active figure
>> plot(x1,y1,'r')      % draw the first plot
>> hold on
>> plot(x2,y2,'k:')     % draw the second plot; this call does not erase the first plot because we used hold on

Use the hold off command to enable replacing the current plot in a figure with a new plot.

Use the command help plot to explore more line styles.

b     blue          .     point              -     solid
g     green         o     circle             :     dotted
r     red           x     x-mark             -.    dashdot
c     cyan          +     plus               --    dashed
m     magenta       *     star             (none)  no line
y     yellow        s     square
k     black         d     diamond
w     white         v     triangle (down)
^     triangle (up)
<     triangle (left)
>     triangle (right)
p     pentagram
h     hexagram

### Arrows

%% [Strang] 1.1C p.7 - crossing lines

ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
axis([-4 4 -2 3]), daspect([1 1 1])

hold on

% axis labels
text( 3.7,0.4,'\bf\fontsize{12}x');
text(-0.4,2.9,'\bf\fontsize{12}y');

% axis arrows
arrow3([3.8 0  ],[4 0],'k-',2,2);
arrow3([0   2.8],[0 3],'k-',2,2);

% two crossing lines
plot([-4,4.0],[-0.5,3.5],'k-');
plot([-1,1.5],[-2.0,3.0],'k-');

% crossing point
p = [1 2];
for r = 1:5
plot(p(1), p(2), 'bo', 'MarkerSize', r);
end

text( 1.2, 1.8,'\bf\fontsize{11}\color{blue}(1,2)');

% guide lines
plot([0 p(1)],[p(2) p(2)],'k--');
plot([p(1) p(1)],[0 p(2)],'k--');

% equations
text( 0.4, 2.8,'\fontsize{11}2x-y=0');
text( 2.4, 2.6,'\fontsize{11}-x+2y=3');

hold off

%% [Strang] 1.1C p.7 - vector addition

ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
axis([-3 4 -3 5]), daspect([1 1 1])

v = [2 -1];
w = [-2 4];
b = v + w;

hold on
arrow3([0,0],v);
arrow3([0,0],w);

arrow3([0,0],b,'b-2');

plot([v(1) b(1)],[v(2) b(2)],'k--');
plot([w(1) b(1)],[w(2) b(2)],'k--');

text( 1.6,-1.2,'\bf\fontsize{11}v');
text(-2.5, 3.6,'\bf\fontsize{11}2w');
text( 0.2, 1.0,'\bf\fontsize{11}\color{blue}v+w');

hold off

%% [Strang] 1.1B p.7

ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
axis([-5 5 -2 2]); daspect([1 1 1]);

hold on

text(4.6,0.4,'\bf\fontsize{12}x');
text(0.2,1.8,'\bf\fontsize{12}y');

arrow3([4.8 0],[5 0],'k-',2,2);
arrow3([0 1.8],[0 2],'k-',2,2);

% a) equally spaced points
% for r = 1:5
%     plot(-4:4, 0, 'bo', 'MarkerSize', r);
% end

% b) a half-line
%plot([0 5], [0 0], 'b-', 'LineWidth', 2);

% c) parallel lines
% for x = -4:4
%     plot([x x], [-2 2], 'b-', 'LineWidth', 1);
% end

% d) half-plane
x = [0 5  5  0];
y = [2 2 -2 -2];
z = [0 0 0 0];
patch(x,y,z,'blue','FaceAlpha',0.1,'EdgeColor','none');

hold off

%% 3D Plane

daspect([1 1 1])

maxX = 2;
maxY = 2;
maxZ = 2;

% coordinate system boundaries
axis([-2*maxX 2*maxX -2*maxY 2*maxY -2*maxZ 2*maxZ])

% origin and axes
o = [0 0 0];
% ax = [maxX 0 0];
% ay = [0 maxY 0];
% az = [0 0 maxZ];

view([60,30]);
axis off, hold on, grid off

% axes
% arrow3(-ax,ax,'l-',1,2); text(ax(1)+0.3,ax(2),ax(3)+0.12,'\bf\fontsize{11}x');
% arrow3(-ay,ay,'l-',1,2); text(ay(1),ay(2),ay(3)+0.07,'\bf\fontsize{11}y');
% arrow3(-az,az,'l-',1,2); text(az(1)-0.05,az(2),az(3),'\bf\fontsize{11}z');

% vectors
v = [2,2,1];
w = [0.5,0.5,3];

% draw lines going through vectors
sv = 2;
plot3([-sv*v(1) sv*v(1)], [-sv*v(2) sv*v(2)], [-sv*v(3) sv*v(3)], 'b-');
sw = 2;
plot3([-sw*w(1) sw*w(1)], [-sw*w(2) sw*w(2)], [-sw*w(3) sw*w(3)], 'b-');

% draw vectors
arrow3(o,v,'k-2',2,3); text(0,2.6,0.3,'\bf\fontsize{11}v');
arrow3(o,w,'k-2',2,3); text(-1,0.7,2.4,'\bf\fontsize{11}w');

% a plane as a rectangle
s = 2;
x = [-s*v(1) -s*v(1)  s*v(1)  s*v(1)];
y = [-s*v(2) -s*v(2)  s*v(2)  s*v(2)];
z = [-2*s*v(3)  2*s*v(3)  2*s*v(3) -2*s*v(3)];
patch(x,y,z,'black','FaceAlpha',0.1,'EdgeColor','none');

%% 3D Vectors

daspect([1 1 1])

tickSize = 0.05;
tickStep = 1.0;

maxX = 2.5;
maxY = 2.5;
maxZ = 1.5;

axis([-0.5 maxX -0.5 maxY -0.5 maxZ])

o = [0 0 0];
ax = [maxX 0 0];
ay = [0 maxY 0];
az = [0 0 maxZ];

view([110,30]);
axis off, hold on, grid off

% axes
arrow3(o,ax,'l-',1,2); text(ax(1)+0.3,ax(2),ax(3)+0.12,'\bf\fontsize{11}x');
arrow3(o,ay,'l-',1,2); text(ay(1),ay(2),ay(3)+0.07,'\bf\fontsize{11}y');
arrow3(o,az,'l-',1,2); text(az(1)-0.05,az(2),az(3),'\bf\fontsize{11}z');

%ticks
for n = 0.0:tickStep:maxX
plot3([n,n],[0,0],[-tickSize,tickSize],'k-');
end
for n = 0.0:tickStep:maxY
plot3([0,0],[n,n],[-tickSize,tickSize],'k-');
end
for n = 0.0:tickStep:maxZ
plot3([0,0],[-tickSize,tickSize],[n,n],'k-');
end

% vectors
v = [0 2 1];
w = [2 2 0];
arrow3(o,v);
arrow3(o,w);

text(0,1.0,0.7,'\bf\fontsize{11}v');
text(1,0.7,0,'\bf\fontsize{11}w');

% coordinate guides
plot3([0 0],[v(2) v(2)],[0 v(3)],'k--');
plot3([0 0],[0 v(2)],[v(3) v(3)],'k--');

plot3([w(1) w(1)],[0 w(2)],[0 0],'k--');
plot3([0 w(1)],[w(2) w(2)],[0 0],'k--');

hold off

ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
axis([-2 5 -3 5]), daspect([1 1 1])

w = [-1 2];
v = [4 2];
s = v + w;

hold on
arrow3([0,0],w);
arrow3([0,0],v);

arrow3([0,0],s,'b-2');

plot([w(1) s(1)],[w(2) s(2)],'k--');
plot([v(1) s(1)],[v(2) s(2)],'k--');

text(-1.3,1.8,'\bf\fontsize{11}w');
text( 4.0,1.8,'\bf\fontsize{11}v');
text( 2.0,2.4,'\bf\fontsize{11}\color{blue}v+w');

hold off

### Persistent Variables

A persistent variable is a local variable which value persists across function calls.

% The Accumulate function adds a value of a single input argument.
% It returns the total of arguments entered so far.
function total = Accumulate(n)

% Declare a persistent variable. It is initialized automatically to an
% empty matrix.
persistent summa;

if isempty(summa)
% If the function is called first time, initialize the persistent variable
% to the input argument.
summa = n;
else
summa = summa + n;
end
total = summa;
>> Accumulate(3)
ans = 3

>> Accumulate(5)
ans = 8

>> Accumulate(10)
ans = 18

>> Accumulate(-11)
ans = 7

>> clear accumulate    % clears persistent variables in the Accumulate function

>> Accumulate(10)
ans = 10

>> clear Accumulate

>> Accumulate(3)
ans = 3

### Files

Text files:

% Open a text file for writing.
fid = fopen('test.txt','w+t')
... % check for errors
fprintf(fid, '%s\n', 'Hello!')
fclose(fid)

% Show the contents of a file.
>> type test.txt
Hello!

% Open a text file for reading. Always check if an error occurred.
fid = fopen('test.txt','rt')
if fid < 0
error('error')
end

% Read a text file one line at a time. fgets returns -1 when there are no more lines to read.
line = fgets(fid);
while ischar(line)
fprintf('%s', line)
line = fgets(fid)
end
% CharCounter counts the number of the input character in a text file.
function num = CharCounter(filename, ch)
fid = fopen(filename,'rt');

if fid<0 || ~ischar(ch)
num = -1;
return
end

line = fgets(fid);
cnt = 0;
while ischar(line)
cnt = cnt + length(strfind(line, ch));
line = fgets(fid);
end

fclose(fid);

num = cnt;
end

Binary files:

% Write an array to a file together with the array's dimensions.
function WriteArrayToFile(A, filename)
fid = fopen(filename, 'w+');
if fid < 0
error('An error occurred while opening the file %s\n', filename);
end

% The number of dimensions of the array A.
dims = size(A);

% Preserve the dimensions of the array saved in a binary file.
fwrite(fid, length(dims), 'double');
fwrite(fid, dims, 'double');
fwrite(fid, A, 'double');

fclose(fid);
end

% Read an array from a file together with the array's dimensions.
fid = fopen(filename, 'r');
if fid < 0
error('An error occurred while opening the file %s\n', filename);
end

% dims and A are column vectors.
A = fread(fid, 'double'); % convert to int using 'double=>int'

% Convert the vector into a matrix. The second arg has to be
% a row vector.
A = reshape(A, dims');

fclose(fid);
end

% Read an array from a file as a column vector.
fid = fopen(filename, 'r');
if fid < 0
error('An error occurred while opening the file %s\n', filename);
end

% The second arguments is the number of elements

fclose(fid);
end

>> rng(0); D = randn(10,12);
>> WriteArrayToFile(D, 'data.dat')

% M is a column vector, not the 10x12 array.

% M is a 10x12 array.

>> whos
Name       Size            Bytes  Class     Attributes

D         10x12              960  double
M         10x12              960  double

>> isequal(D,M)
ans = logical 1

Excel files:

>> [num, txt, raw] = xlsread('data.xlsx')
>> [~, ~, raw] = xlsread('data.xlsx')
>> num = xlsread('data.xlsx', 1, 'D15') % sheet#=1 and the cell D15
>> num = xlsread('data.xlsx', 1, 'D15:E17')

>> xlswrite('data.xlsx', M, 1, 'D2:E7') % M - matrix, sheet#=1

### Recursion

function f = Factorial(n)
if ~isscalar(n) || n ~= fix(n) || n < 0
error('non-negative integer scalar input expected');
end
% base case
if n == 0
f = 1;
else
f = n * Factorial(n-1);
end
end

### Function Handles

% create a handle to the function sin
>> trig = @sin
trig = function_handle with value: @sin

% invoke the function using the handle
>> x = trig(pi/2)
x = 1

>> plot(trig(0:0.01:2*pi))

>> % assign the handle to another variable
>> hand = trig
hand = function_handle with value: @sin
>> hand(pi/2)
ans = 1
>> pih = @pi
pih = function_handle with value: @pi

>> pih()
ans = 3.1416
>> x = pih()
x = 3.1416
>> % an array of function handles; it needs to be a cell array
>> handles = {@sin @cos @plot}
handles = 1×3 cell array {@sin} {@cos} {@plot}

>> handles{2}(pi/4)
ans = 0.7071

The fplot function takes a function handle as its first argument and plots the function within limits provided as the second argument. fplot handles discontinuities much better than the plot function.

>> fplot(@sin, [0 2*pi])  % similar to plot(0:0.01:2*pi, sin(0:0.01:2*pi))
>> fplot(@tan, [0 pi])    % better representation of discontinuities

>> % an anonymous function
>> poly = @(x) 2*x.^3 - x.^2 + 2*x - 12
poly = function_handle with value: @(x)2*x.^3-x.^2+2*x-12

>> poly(1)
ans = -9

>> poly(0:5)
ans = -12    -9     4    39   108   223

>> fplot(poly, [-10,10])    % the same as plot(-10:10, poly(-10:10))

>> % The outer variable values are captured by anonymous functions.
>> c = 10;
>> f = @(x) c*x
f = function_handle with value: @(x)c*x

>> f(3)
ans = 30

>> c = 20;
>> f(3)
ans = 30

>> clear c
>> f(3)
ans = 30
% Plot an anonymous function.
>> fplot(@(x) x + sin(x), [-5,5])

>> % returning multiple values from an anonymous function
>> smax = @(A) max(A.^2)
smax = function_handle with value: @(A)max(A.^2)

>> % smax finds the maximum values of squares of the elements of the input matrix
>> % it returns a product and a sum of the input arguments as two output args
>> [mx ind] = smax([1 2; 3 4])
mx =  9 16
ind = 2  2

>> % The deal function returns one output argument for each of its input arguments.
>> xyz = @(x,y) deal(x*y, x+y)
xyz = function_handle with value: @(x,y)deal(x*y,x+y)

>> [prod, sum] = xyz(10,20)
prod = 200
sum =   30

Also, you can view source code of many built-in MATLAB functions. For example:

>> edit num2str

function s = num2str(x, f)
if nargin > 0
x = convertStringsToChars(x);
end

if nargin > 1
f = convertStringsToChars(f);
end

narginchk(1,2);
if ischar(x)
s = x;
return;
end
if isempty(x)
s = '';
return
end
if ~isnumeric(x) && ~islogical(x)
error(message('MATLAB:num2str:nonNumericInput') );
end
if isfloat(x)
x = 0+x;  % Remove negative zero
end
if issparse(x)
x = full(x);
end
...
end