Upload
gkreugineraj
View
418
Download
8
Embed Size (px)
DESCRIPTION
matlab
Citation preview
Tutorial Lesson: Using MATLAB (a minimum session)
You'll log on or invoke MATLAB, do a few trivial calculations and log off.
Launch MATLAB. You can start it from your Start Menu, as any other Windows-based
program. You see now something similar to this Figure:
The History Window is where you see all the already typed commands. You can
scroll through this list.
The Workspace Window is where you can see the current variables.
The Comand Window is your main action window. You can type your commands
here.
At the top of the window, you can see your current directory. You can change it to
start a new project.
Once the command window is on screen, you are ready to carry out this first lesson.
Some commands and their output are shown below.
Enter 5+2 and hit the enter key. Note that the result of an unassigned expression is
saved in the default variable 'ans'.
>> 5+2
ans =
7
>>
The '>>' sign means that MATLAB is ready and waiting for your input.
You can also assign the value of an expression to a variable.
>> z=4
z =
4
>>
A semicolon (at the end of your command) suppresses screen output for that
instruction. MATLAB remembers your variables, though. You can recall the value of x
by simply typing x
>> x=4;
>> x
x =
4
>>
MATLAB knows trigonometry. Here is the cosine of 6 (default angles are in
radians).
>> a=cos(6)
a =
0.9602
>>
The floating point output display is controlled by the 'format' command. Here are
two examples.
>> format long
>> a
a =
0.96017028665037
>> format short
>> a
a =
0.9602
>>
Well done!
Close MATLAB (log off).
You can also quit by selecting 'Exit MATLAB' from the file menu.
Tutorial Lesson: Vector Algebra (Algebra with many numbers, all at once...)
You'll learn to create arrays and vectors, and how to perform algebra and
trigonometric operations on them. This is called Vector Algebra.
An array is an arbitrary list of numbers or expressions arranged in horizontal
rows and vertical columns. When an array has only one row or column, it is called
a vector. An array with m rows and n columns is a called a matrix of size m x n.
Launch MATLAB and reproduce the following information. You type only what you see
right after the '>>' sign. MATLAB confirms what you enter, or gives an answer.
Let x be a row vector with 3 elements (spaces determine different columns). Start
your vectors with '[' and end them with ']'.
>> x=[3 4 5]
x =
3 4 5
>>
Let y be a column vector with 3 elements (use the ';' sign to separate each row).
MATLAB confirms this column vector.
>> y=[3; 4; 5]
y =
3
4
5
>>
You can add or subtract vectors of the same size:
>> x+x
ans =
6 8 10
>> y+y
ans =
6
8
10
>>
You cannot add/subtract a row to/from a column (Matlab indicates the error). For
example:
>> x+y
??? Error using ==> plus
Matrix dimensions must agree.
You can multiply or divide element-by-element of same-sized vectors
(using the '.*' or './' operators) and assign the result to a different variable vector:
>> x.*x
ans =
9 16 25
>> y./y
ans =
1
1
1
>> a=[1 2 3].*x
a =
3 8 15
>> b=x./[7 6 5]
b =
0.4286 0.6667 1.0000
>>
Multiplying (or dividing) a vector with (or by) a scalar does not need any special
operator (you can use just '*' or '/'):
>> c=3*x
c =
9 12 15
>> d=y/2
d =
1.5000
2.0000
2.5000
>>
The instruction 'linspace' creates a vector with some elements linearly spaced
between your initial and final specified numbers, for example:
r = linspace(initial_number, final_number, number_of_elements)
>> r=linspace(2,6,5)
r =
2 3 4 5 6
>>
or
>> r=linspace(2,3,4)
r =
2.0000 2.3333 2.6667 3.0000
>>
Trigonometric functions (sin, cos, tan...) and math functions (sqrt, log, exp...)
operate on vectors element-by-element (angles are in radians).
>> sqrt(r)
ans =
1.4142 1.5275 1.6330 1.7321
>> cos(r)
ans =
-0.4161 -0.6908 -0.8893 -0.9900
>>
Well done!
So far, so good?
Experimenting with numbers, vectors and matrices is good for you and it does not
hurt!
Go on!
Tutorial Lesson: a Matlab Plot (creating and printing figures)
You'll learn to make simple MATLAB plots and print them out.
This lesson teaches you the most basic graphic commands.
If you end an instruction with ';', you will not see the output for that instruction.
MATLAB keeps the resuls in memory until you let the results out.
Follow this example, step-by-step.
In the command window, you first create a variable named 'angle' and assign 360
values, from 0 to 2*pi (the constant 'pi' is already defined in MATLAB):
>> angle = linspace(0,2*pi,360);
Now, create appropriate horizontal and vertical values for those angles:
>> x=cos(angle);
>> y=sin(angle);
Then, draw those (x,y) created coordinates:
>> plot(x,y)
Set the scales of the two axes to be the same:
>> axis('equal')
Put a title on the figure:
>> title('Pretty Circle')
Label the x-axis and the y-axis with something explanatory:
>> ylabel('y')
>> xlabel('x')
Gridding the plot is always optional but valuable:
>> grid on
You now see the figure:
The 'print' command sends the current plot to the printer connected to your
computer:
The arguments of the axis, title, xlabel, and ylabel commands are text strings.
Text strings are entered within single quotes (').
Do you like your plot? Interesting and funny, isn't it?
Tutorial Lesson: Matlab Code (Creating, Saving, and Executing a Script File)
You'll learn to create Script files (MATLAB code) and execute them.
A Script File is a user-created file with a sequence of MATLAB commands in it.
You're actually creating MATLAB code, here. The file must be saved with a '.m'
extension, thereby, making it an m-file.
The code is executed by typing its file name (without the '.m' extension') at the
command prompt.
Now you'll write a script file to draw the unit circle of Tutorial Lesson 3.
You are esentially going to write the same commands in a file, save it, name it, and
execute it within MATLAB.
Follow these directions:
Create a new file. On PCs, select 'New' -> 'M-File' from the File menu, or use the
related icons.
A new edit window appears.
Type the following lines into this window. Lines starting with a '%' sign are
interpreted as comments and are ignored by MATLAB, but are very useful for you,
because then you can explain the meaning of the instructions.
% CIRCLE - A script file to draw a pretty circle
angle = linspace(0, 2*pi, 360);
x = cos(angle);
y = sin(angle);
plot(x,y)
axis('equal')
ylabel('y')
xlabel('x')
title('Pretty Circle')
grid on
Write and save the file under the name 'prettycircle.m'.
On PCs select 'Save As...' from the File menu. A dialog box appears. Type the name
of the document as prettycircle.m. Make sure the file is being saved in the folder
you want it to be in (the current working folder / directory of MATLAB).
Click on the 'Save' icon to save the file.
Now go back to the MATLAB command window and type the following command to
execute the script file.
>>prettycircle
And you achieve the same 2D plot that you achieved in Tutorial Lesson 3, but the
difference is that you saved all the instructions in a file that can be accessed and run
by other m-files! It's like having a custom-made code!
You're doing great!
Tutorial Lesson: Matlab Programs (create and execute Function Files)
You'll learn to write and execute Matlab programs. Also, you'll learn the
difference between a script file and a function file.
A function file is also an M-file, just like a script file, but it has a
function definition line on the top, that defines the input and output explicitly. You
are about to create a MATLAB program!
You'll write a function file to draw a circle of a specified radius, with the radius
being the input of the function. You can either write the function file from scratch
or modify the script file of this Tutorial Lesson.
Open the script file prettycircle.m (created and saved before).
On PCs, select 'Open' -> 'M-File' from the File menu. Make sure you're in the
correct directory.
Navigate and select the file prettycircle.m from the 'Open' dialog box. Double click
to open the file. The contents of the program should appear in an edit window.
Edit the file prettycircle.m from Tutorial 4 to look like the following:
function [x, y] = prettycirclefn(r)
% CIRCLE - A script file to draw a pretty circle
% Input: r = specified radius
% Output: [x, y] = the x and y coordinates
angle = linspace(0, 2*pi, 360);
x = r * cos(angle);
y = r * sin(angle);
plot(x,y)
axis('equal')
ylabel('y')
xlabel('x')
title(['Radius r =',num2str(r)])
grid on
Now, write and save the file under the name prettycirclefn.m as follows:
On PCs, select 'Save As...' from the 'File' menu. A dialog box appears.
Type the name of the document as prettycirclefn. Make sure the file is saved in the
folder you want (the current working folder/directory of MATLAB). Click on the 'Save'
icon to save the file.
In the command window write the following:
>> prettycirclefn(5);
and you get the following figure (see the title):
Then, try the following:
>> radius=3;
>> prettycirclefn(radius);
>>
and now you get a circle with radius = 3
Notice that a function file must begin with a function definition line. In this case is
function [x, y] = prettycirclefn(r), where you define the input variables and the
output ones.
The argument of the 'title' command in this function file is a combination of
a fixed part that never changes (the string 'Radius r= '), and a variable part that
depends on the argumments passed on to the function, and that converts a number
into a string (instruction 'num2str').
You can generate now a circle with an arbitrary radius, and that radius can be
assigned to a variable that is used by your MATLAB program or function!
Great!
Polynomials
Polynomials are used so commonly in algebra, geometry and math in general that Matlab
has special commands to deal with them. The polynomial 2x4 + 3x
3 − 10x
2 − 11x + 22 is
represented in Matlab by the array [2, 3, -10, -11, 22] (coefficients of the polynomial
starting with the highest power and ending with the constant term). If any power is
missing from the polynomial its coefficient must appear in the array as a zero.
Here are some examples of the things that Matlab can do with polynomials. I suggest you
experiment with the code…
Roots of a Polynomial
% Find roots of polynomial p = [1, 2, -13, -14, 24];
r = roots(p)
% Plot the same polynomial (range -5 to 5) to see its roots x = -5 : 0.1 : 5;
f = polyval(p,x);
plot(x,f)
grid on
Find the polynomial from the roots
If you know that the roots of a polynomial are -4, 3, -2, and 1, then you can find the
polynomial (coefficients) this way:
r = [-4 3 -2 1];
p = poly(r)
Multiply Polynomials
The command conv multiplies two polynomial coefficient arrays and returns the
coefficient array of their product:
a = [1 2 1];
b = [2 -2];
c = conv(a,b)
Look (and try) carefully this result and make sure it’s correct.
Divide Polynomials
Matlab can do it with the command deconv, giving you the quotient and the remainder
(as in synthetic division). For example:
% a = 2x^3 + 2x^2 - 2x - 2
% b = 2x - 2 a = [2 2 -2 -2];
b = [2 -2];
% now divide b into a finding the quotient and remainder [q, r] = deconv(a,b)
You find quotient q = [1 2 1] (q = x2 + 2x + 1), and remainder r = [0 0 0 0] (r = 0),
meaning that the division is exact, as expected from the example in the multiplication
section…
First Derivative
Matlab can take a polynomial array and return the array of its derivative:
a = [2 2 -2 -2] (meaning a = 2x3 + 2x
2 - 2x - 2)
ap = polyder(a)
The result is ap = [6 4 -2] (meaning ap = 6x2 + 4x - 2)
Fitting Data to a Polynomial
If you have some data in the form of arrays (x, y), Matlab can do a least-squares fit of a
polynomial of any order you choose to this data. In this example we will let the data be
the cosine function between 0 and pi (in 0.01 steps) and we’ll fit a polynomial of order 4
to it. Then we’ll plot the two functions on the same figure to see how good we’re doing.
clear; clc; close all
x = 0 : 0.01 : pi; % make a cosine function with 2% random error on it f = cos(x) + 0.02 * rand(1, length(x));
% fit to the data p = polyfit(x, f, 4);
% evaluate the fit g = polyval(p,x);
% plot data and fit together plot(x, f,'r:', x, g,'b-.')
legend('noisy data', 'fit')
grid on
Got it?
Examples: Basic Matlab Codes
Here you can find examples on different types of arithmetic, exponential,
trigonometry and complex number operations handled easily with MATLAB
codes.
To code this formula: , you can write the following instruction in the Matlab
command window (or within an m-file):
>> 5^3/(2^4+1)
ans =
7.3529
>>
To compute this formula: , you can always break down the
commands and simplify the code (a final value can be achieved in several ways).
>>numerator = 3 * (sqrt(4) - 2)
numerator =
0
>>denominator = (sqrt(3) + 1)^2
denominator =
7.4641
>>total = numerator/denominator – 5
total =
-5
>>
The following expression: , can be achieved as follows
(assuming that x and y have values already):
>> exp(4) + log10(x) - pi^y
The basic MATLAB trigonometric functions are 'sin', 'cos', 'tan', 'cot', 'sec', and
'csc'. The inverses, are calculated with 'asin', 'atan', etc. The inverse function
'atan2' takes two arguments, y and x, and gives the four-quadrant inverse tangent.
Angles are in radians, by default.
The following expression: , can be coded as follows (assuming
that x has a value already):
>>(sin(pi/2))^2 + tan(3*pi*x).
MATLAB recognizes the letters i and j as the imaginary number. A complex
number 4 + 5i may be input as 4+5i or 4+5*i in MATLAB. The first case is always
interpreted as a complex number, whereas the latter case is taken as complex only if
i has not been assigned any local value.
Can you verify in MATLAB this equation (Euler's Formula)?
You can do it as an exercise!
Examples: Simple Vector Algebra
On this page we expose how simple it is to work with vector algebra, within
Matlab.
Reproduce this example in MATLAB:
x = [2 4 6 8];
y = 2*x + 3
y =
7 11 15 19
Row vector y can represent a straight line by doubling the x value (just as a slope
= 2) and adding a constant. Something like y = mx + c. It's easy to perform
algebraic operations on vectors since you apply the operations to the whole vector,
not to each element alone.
Now, let's create two row vectors (v and w), each with 5 linearly spaced elements
(that's easy with function 'linspace':
v = linspace(3, 30, 5)
w = linspace(4, 400, 5)
Obtain a row vector containing the sine of each element in v:
x = sin(v)
Multiply these elements by thir correspondig element in w:
y = x .* w
And obtain MATLAB's response:
y =
0.5645 -32.9105 -143.7806 -286.4733 -395.2126
>>
Did you obtain the same? Results don't appear on screen if you end the command
with the ';' sign.
y = x .* w;
You can create an array (or matrix) by combining two or more vectors:
m = [x; y]
The first row of m above is x, the second row is y.
m =
0.1411 -0.3195 -0.7118 -0.9517 -0.9880
0.5645 -32.9105 -143.7806 -286.4733 -395.2126
>>
You can refer to each element of m by using subscripts. For example, m(1,2) = -
0.3195 (first row, second column);
m(2,1) = 0.5645 (second row, first column).
You can manipulate single elements of a matrix, and replace them on the same
matrix:
m(1,2) = m(1,2)+3
m(2,4) = 0
m(2,5) = m(1,2)+m(2,1)+m(2,5)
m =
0.1411 2.6805 -0.7118 -0.9517 -0.9880
0.5645 -32.9105 -143.7806 0 -391.9677
>>
Or you can perform algebraic operations on the whole matrix (using element-by-
element operators):
z = m.^2
z =
1.0e+005 *
0.0000 0.0001 0.0000 0.0000 0.0000
0.0000 0.0108 0.2067 0 1.5364
>>
MATLAB automatically presents a coefficient before the matrix, to simplify the
notation. In this case .
Examples: MATLAB Plots
In this group of examples, we are going to create several MATLAB plots.
2D Cosine Plot
y=cos(x), for
You can type this in an 'm-file':
% Simple script to plot a cosine
% vector x takes only 10 values
x = linspace(0, 2*pi, 10);
y = cos(x);
plot(x,y)
xlabel('x')
ylabel('cos(x)')
title('Plotting a cosine')
grid on
The result is:
If we use 100 points rather than 10, and evaluate two cycles instead of one (like
this):
x = linspace(0, 4*pi, 100);
We obtain a different curve:
Now, a variation with line-syles and colors (type 'help plot' to see the options for
line-types and colors):
clear; clc; close all;
% Simple script to plot a cosine
% vector x takes only 10 values
x = linspace(0, 4*pi, 100);
y = cos(x);
plot(x,y, 'ro')
xlabel('x (radians)')
ylabel('cos(x)')
title('Plotting a cosine')
grid on
Space curve
Use the command plot3(x,y,z) to plot the helix:
If x(t)=sin(t), y(t)=cos(t), z(t)=(t) for every t in ,
then, you can type this code in an 'm-file' or in the command window:
% Another way to assign values to a vector
t = 0 : pi/50 : 10*pi;
plot3(sin(t),cos(t),t);
You can use the 'help plot3' command to find out more details.
Examples: MATLAB programming - Script Files -
In this example, we are going to program the plotting of two concentric
circles and mark the center point with a black square. We use polar
coordinates in this case (for a variation).
We can open a new edit window and type the following program (script). As
already mentioned, lines starting with a '%' sign are comments, and are ignored by
MATLAB but are very useful to the viewer.
% The initial instructions clear the screen, all
% of the variables, and close any figure
clc; clear; close all
% CIRCLE - A script file to draw a pretty circle
% We first generate a 90-element vector to be used as an angle
angle = linspace(0, 2*pi, 90);
% Then, we create another 90-element vector containing only value 2
r2 = linspace(2, 2, 90);
% Next, we plot a red circle using the 'polar' function
polar(angle, r2, 'ro')
title('One more Circle')
% We avoid deletion of the figure
hold on
% Now, we create another 90-element vector for radius 1
r1 = linspace(1, 1, 90);
polar(angle, r1, 'bx')
% Finaly, we mark the center with a black square
polar(0, 0, 'ks')
We save the script and run it with the 'run' icon (within the Editor):
Or we can run it from the Command Window by typing the name of the script.
We now get:
EXAMPLES: a custom-made Matlab function
Even though Matlab has plenty of useful functions, in this example we're
going to develop a custom-made Matlab function. We'll have one input value
and two output values, to transform a given number in both Celsius and
Farenheit degrees.
A function file ('m-file') must begin with a function definition line. In this line we
define the name of the function, the input and the output variables.
Type this example in the editor window, and assign it the name 'temperature'
('File' -> 'New' -> 'M-File'):
% This function is named 'temperature.m'.
% It has one input value 'x' and two outputs, 'c' and 'f'.
% If 'x' is a Celsius number, output variable 'f'
% contains its equivalent in Fahrenheit degrees.
% If 'x' is a Fahrenheit number, output variable 'c'
% contains its equivalent in Celsius degrees.
% Both results are given at once in the output vector [c f]
function [c f] = temperature(x)
f = 9*x/5 + 32;
c = (x - 32) * 5/9;
Then, you can run the Matlab function from the command window, like this:
>> [cent fahr] = temperature(32)
cent =
0
fahr =
89.6000
>> [c f]=temperature(-41)
c =
-40.5556
f =
-41.8000
The receiving variables ([cent fahr] or [c f]) in the command window (or in
another function or script that calls 'temperature') may have different names than
those assigned within your just created function.
Matlab Examples - matrix manipulation
In this page we study and experiment with matrix manipulation and boolean algebra.
These Matlab examples create some simple matrices and then combine them to form
new ones of higher dimensions. We also extract data from certain rows or columns to
form matrices of lower dimensions.
Let's follow these Matlab examples of commands or functions in a script.
Example:
a = [1 2; 3 4]
b = [5 6
7 9]
c = [-1 -5; -3 9]
d = [-5 0 4; 0 -10 3]
e = [8 6 4
3 1 8
9 8 1]
Note that a new row can be defined with a semicolon ';' as in a, c or d, or with actual
new rows, as in b or e.
You can see that Matlab arranges and formats the data as follows:
a =
1 2
3 4
b =
5 6
7 9
c =
-1 -5
-3 9
d =
-5 0 4
0 -10 3
e =
8 6 4
3 1 8
9 8 1
Now, we are going to test some properties relative to the boolean algebra...
We can use the double equal sign '==' to test if some numbers are the same. If they
are, Matlab answers with a '1' (true); if they are not the same, Matlab answers with
a '0' (false). See these interactive examples:
Is matrix addition commutative?
a + b == b + a
Matlab compares all of the elements and answers:
ans =
1 1
1 1
Yes, all of the elements in a+b are the same than the elements in b+a.
Is matrix addition associative?
(a + b) + c == a + (b+c)
Matlab compares all of the elements and answers:
ans =
1 1
1 1
Yes, all all of the elements in (a + b) + c are the same than the elements in a +
(b+c).
Is multiplication with a matrix distributive?
a*(b+c) == a*b + a*c
ans =
1 1
1 1
Yes, indeed. Obviously, the matrices have to have appropriate dimensions, otherwise
the operations are not possible.
Are matrix products commutative?
a*d == d*a
No, not in general.
a*d =
-5 -20 10
-15 -40 24
d*a ... is not possible, since dimensions are not appropriate for a multiplication
between these matrices, and Matlab launches an error:
??? Error using ==> mtimes
Inner matrix dimensions must agree.
Now, we combine matrices to form new ones:
g = [a b c]
h = [c' a' b']'
Matlab produces:
g =
1 2 5 6 -1 -5
3 4 7 9 -3 9
h =
-1 -5
-3 9
1 2
3 4
5 6
7 9
We extract all the columns in rows 2 to 4 of matrix h
i = h(2:4, :)
Matlab produces:
i =
-3 9
1 2
3 4
We extract all the elements of row 2 in g (like this g(2, :)), transpose them (with an
apostrophe, like this g(2, :)') and join them to what we already have in h. As an
example, we put all the elements again in h to increase its size:
h = [h g(2, :)']
Matlab produces:
h =
-1 -5 3
-3 9 4
1 2 7
3 4 9
5 6 -3
7 9 9
Extract columns 2 and 3 from rows 3 to 6.
j = [h(3:6, 2:3)]
And Matlab produces:
j =
2 7
4 9
6 -3
9 9
So far so good?
Try it on your own!
Dot Product (also known as Inner or Scalar Product)
The dot product is a scalar number and so it is also known as the scalar or inner
product. In a real vector space, the scalar product between two vectors
is computed in the following way:
Besides, there is another way to define the inner product, if you know the angle
between the two vectors:
We can conclude that if the inner product of two vectors is zero, the vectors are
orthogonal.
In Matlab, the appropriate built-in function to determine the inner product is
'dot(u,v)'.
For example, let's say that we have vectors u and v, where
u = [1 0] and v = [2 2]. We can plot them easily with the 'compass' function in
Matlab, like this:
x = [1 2]
y = [0 2]
compass(x,y)
x represents the horizontal coordinates for each vector, and y represents their
vertical coordinates. The instruction 'compass(x,y)' draws a graph that displays the
vectors with components (x, y) as arrows going out from the origin, and in this case
it produces:
We can see that the angle between the two vectors is 45 degrees; then, we can
calculate the scalar product in three different ways (in Matlab code):
a = u * v'
b = norm(u, 2) * norm(v, 2) * cos(pi/4)
c = dot(u, v)
Code that produces these results:
a = 2
b = 2.0000
c = 2
Note that the angle has to be expressed in radians, and that the instruction
'norm(vector, 2)' calculates the Euclidian norm of a vector (there are more types
of norms for vectors, but we are not going to discuss them here).
Cross Product
In this example, we are going to write a function to find the cross product of two
given vectors u and v.
If u = [u1 u2 u3] and v = [v1 v2 v3], we know that the cross product w is defined
as w = [(u2v3 – u3v2) (u3v1 - u1v3) (u1v2 - u2v1)].
We can check the function by taking cross products of unit vectors i = [1 0 0], j = [0
1 0], and k = [0 0 1]
First, we create the function in an m-file as follows:
function w = crossprod(u,v)
% We're assuming that both u and v are 3D vectors.
% Naturally, w = [w(1) w(2) w(3)]
w(1) = u(2)*v(3) - u(3)*v(2);
w(2) = u(3)*v(1) - u(1)*v(3);
w(3) = u(1)*v(2) - u(2)*v(1);
Then, we can call the function from any script, as follows in this example:
% Clear screen, clear previous variables and closes all figures
clc; close all; clear
% Supress empty lines in the output
format compact
% Define unit vectors
i = [1 0 0];
j = [0 1 0];
k = [0 0 1];
% Call the previously created function
w1 = crossprod(i,j)
w2 = crossprod(i,k)
disp('*** compare with results by Matlab ***')
w3 = cross(i,j)
w4 = cross(i,k)
And Matlab displays:
w1 =
0 0 1
w2 =
0 -1 0
*** compare with results by Matlab ***
w3 =
0 0 1
w4 =
0 -1 0
>>
Complex Numbers
The unit of imaginary numbers is and is generally designated by the letter i
(or j). Many laws which are true for real numbers are true for imaginary numbers as
well. Thus .
Matlab recognizes the letters i and j as the imaginary number . A complex
number 3 + 10i may be input as 3 + 10i or 3 + 10*i in Matlab (make sure not to use
i as a variable).
In the complex number a + bi, a is called the real part (in Matlab, real(3+5i) = 3)
and b is the coefficient of the imaginary part (in Matlab, imag(4-9i) = -9). When a
= 0, the number is called a pure imaginary. If b = 0, the number is only the real
number a. Thus, complex numbers include all real numbers and all pure imaginary
numbers.
The conjugate of a complex a + bi is a - bi. In Matlab, conj(2 - 8i) = 2 + 8i.
To add (or subtract) two numbers, add (or subtract) the real parts and the
imaginary parts separately. For example:
(a+bi) + (c-di) = (a+c)+(b-d)i
In Matlab, it's very easy to do it:
>> a = 3-5i
a =
3.0000 - 5.0000i
>> b = -9+3i
b =
-9.0000 + 3.0000i
>> a + b
ans =
-6.0000 - 2.0000i
>> a - b
ans =
12.0000 - 8.0000i
To multiply two numbers, treat them as ordinary binomials and replace i2 by -1. To
divide two complex nrs., multiply the numerator and denominator of the fraction by
the conjugate of the denominator, replacing again i2 by -1.
Don't worry, in Matlab it's still very easy (assuming same a and b as above):
>> a*b
ans =
-12.0000 +54.0000i
>> a/b
ans =
-0.4667 + 0.4000i
Employing rectangular coordinate axes, the complex nr. a+bi is represented by
the point whose coordinates are (a,b).
We can plot complex nrs. this easy.
To plot numbers (3+2i), (-2+5i) and (-1-1i), we can write the following code in
Matlab:
% Enter each coordinate (x,y) separated by commas
% Each point is marked by a blue circle ('bo')
plot(3,2,'bo', -2,5,'bo', -1,-1,'bo')
% You can define the limits of the plot [xmin xmax ymin ymax]
axis([-3 4 -2 6])
% Add some labels to explain the plot
xlabel('x (real axis)')
ylabel('y (imaginary axis)')
% Activate the grid
grid on
And you get:
Polar Form of Complex Nrs.
In the figure below, .
Then .
Then x + yi is the rectangular form and is the polar form
of the same complex nr. The distance is always positive and is called
the absolute value or modulus of the complex number. The is called theangle
argument or amplitude of the complex number.
In Matlab, we can effortlessly know the modulus and angle (in radians) of any
number, by using the 'abs' and 'angle' instructions. For example:
a = 3-4i
magnitude = abs(a)
ang = angle(a)
a =
3.0000 - 4.0000i
magnitude =
5
ang =
-0.9273
De Moivre's Theorem
The nth power of is
This relation is known as the De Moivre's theorem and is true for any real value of
the exponent. If the exponent is 1/n, then
.
It's a good idea if you make up some exercises to test the validity of the theorem.
Roots of Complex Numbers in Polar Form
If k is any integer, .
Then,
Any number (real or complex) has n distinct nth roots, except zero. To obtain the
n nth roots of the complex number x + yi, or , let k take on the
successive values 0, 1, 2, ..., n-1 in the above formula.
Again, it's a good idea if you create some exercises in Matlab to test the validity of
this affirmation.
Future Value
This program is an example of a financial application in Matlab. It calculates the future
value of an investment when interest is a factor. It is necessary to provide the amount of
the initial investment, the nominal interest rate, the number of compounding periods
per year and the number of years of the investment.
Assuming that there are no additional deposits and no withdrawals, the future value is
based on the folowing formula:
where:
t = total value after y years (future value)
y = number of years
p = initial investment
i = nominal interest rate
n = number of compounding period per year
We can achieve this task very easily with Matlab. First, we create a function to request
the user to enter the data. Then, we perform the mathematical operations and deliver the
result.
This is the function that requests the user to enter the necessary information:
function [ii, nir, ncppy, ny] = enter_values
ii = input('Enter initial investment: ');
nir = input('Enter nominal interest rate: ');
ncppy = input('Enter number of compounding periods per
year: ');
ny = input('Enter number of years: ');
This is the function that performs the operations:
function t = future_value(ii, nir, ncppy, ny)
% Convert from percent to decimal
ni = nir / (100 * ncppy);
% Calculate future value by formula
t = ii*(1 + ni)^(ncppy * ny);
% Round off to nearest cent
t = floor(t * 100 + 0.5)/100;
And finally, this is the Matlab code (script) that handles the above:
% Instruction ‘format bank’ delivers fixed format for dollars and cents
% Instruction ‘format compact’ suppresses extra line-feeds
clear; clc; format compact
format bank
[ii, nir, ncppy, ny] = enter_values;
t = future_value(ii, nir, ncppy, ny)
This is a sample run:
Enter initial investment: 6800
Enter nominal interest rate: 9.5
Enter number of compounding periods per year: 4
Enter number of years: 10
with the result:
t =
17388.64
We can also test of the function, like this:
ii = 6800;
nir = 9.5;
ncppy = 4;
ny = 10;
t = future_value(ii, nir, ncppy, ny)
with exactly the same result, as expected
t =
17388.64
iteration (for loop)
The MATLAB iteration structure (for loop) repeats a group of statements a fixed,
predetermined number of times. A matching end delineates the statements.
The general format is:
for variable = expression
statement
...
end
Example:
c = 5;
% Preallocate matrix, fill it with zeros
a = zeros(c, c);
for m = 1 : c
for n = 1 : c
a(m, n) = 1/(m + n * 5);
end
end
a
The result is:
a =
0.1667 0.0909 0.0625 0.0476 0.0385
0.1429 0.0833 0.0588 0.0455 0.0370
0.1250 0.0769 0.0556 0.0435 0.0357
0.1111 0.0714 0.0526 0.0417 0.0345
0.1000 0.0667 0.0500 0.0400 0.0333
The semicolon terminating the inner statement suppresses repeated printing,
and the a after the loop displays the final result.
It is a good idea to indent the loops for readability, especially when they are nested.
Matrix Multiplication
If A is a matrix of dimension m x r, and B is a matrix of dimension r x n, you can
find the product AB of dimension m x n by doing the following:
1. To find the element in row i and column j of matrix AB, you take row i of matrix A
and column j of matrix B.
2. You multiply the corresponding elements of that row and that column and add up
all the products.
In this example, we show a code in Matlab that performs a matrix multiplication
step-by-step. The algorithm displays all the elements being considered for the
multiplication and shows how the resulting matrix is being formed in each step.
Obviously, Matlab can do it with just one operation, but we want to show every step
of the process, as well as an example of how nested iterations work in Matlab.
Example:
% Clear screen, clear previous variables and closes all figures
clc; close all; clear
% Avoid empty lines
format compact
% Define matrices, for example these
A = [2 1 4 1 2; 1 0 1 2 -1; 2 3 -1 0 -2]
B = [-2 -1 2; 0 2 1; -1 1 4; 3 0 1; 2 1 2]
% The size of each matrix is considered for these calculations
[r1 c1] = size(A);
[r2 c2] = size(B);
% prevent unappropriate matrix size
if c1 ~= r2
disp ('*** not able to multiply matrices ***')
end
% Main code
% Vary each row of matrix A
for i = 1 : r1
% Vary each column of matrix B
for j = 1 : c2
% Reset every new element of the final result
s = 0;
% Vary each column of matrix A and row of matrix B
for k = 1 : c1
% Display every element to take into account
A(i,k)
B(k,j)
% Prepare the addition in the iteration
s = s + A(i,k) * B(k,j);
end
% Assign the total of the appropriate element
% to the final matrix
C(i,j) = s
end
end
% Compare our result with a multiplication by Matlab
A*B
Matlab displays the following results:
A = 2 1 4 1 2
1 0 1 2 -1
2 3 -1 0 -2
B =
-2 -1 2
0 2 1
-1 1 4
3 0 1
2 1 2
then, the command window shows all the elements being considered and how the
product AB (C) is being formed, and finalizes with our result and the multiplication
achieved by Matlab itself.
C =
-1 6 26
1 -1 6
-7 1 -1
ans =
-1 6 26
1 -1 6
-7 1 -1
>>
Control Structures (while statement loop)
Among the control structures, there is the while... end loop which repeats a group
of statements an indefinite number of times under control of a logical condition.
Syntax:
while expression
statements
...
end
Example:
counter = 100;
while (counter > 95)
disp ('counter is still > 95')
counter = counter -1;
end
disp('counter is no longer > 95')
Matlab response is:
counter is still > 95
counter is still > 95
counter is still > 95
counter is still > 95
counter is still > 95
counter is no longer > 95
>>
The cautions involving matrix comparisons that are discussed in the section on the if
statement also apply to the while statement.
if statement
The if statement evaluates a logical expression and executes a group of
statements when the expression is true.
The optional elseif and else keywords provide for the execution of alternate groups
of statements.
An end keyword, which matches the if, terminates the last group of statements.
The groups of statements are delineated by the four keywords (no braces or
brackets are involved).
The general form of the statement is:
if expression1
statements1
...
elseif expression2
statements2
...
else
statements3
...
end
It is important to understand how relational operators and if statements work with
matrices.
When you want to check for equality between two variables, you might use if A ==
B ...
This '==' code is fine, and it does what you expect when A and B are scalars.
But when A and B are matrices, A == B does not test if they are equal, it tests
where they are equal; the result is another matrix of 0’s and 1’s showing element-
by-element equality.
In fact, if A and B are not the same size, then A == B is an error.
The proper way to check for equality between two variables is to use the
isequal function:
if isequal(A,B) ...
Here's an example code:
if m == n
a(m,n) = 3;
elseif abs(m-n) == 3
a(m,n) = 1;
else
a(m,n) = 0;
end
If m equals n, then a(m,n) becomes 3, and the routine continues after the end.
If not, the routine tests if abs(m-n) equals 3. If it does, then a(m,n) becomes 1, and
the routine continues after the end.
In any other case a(m,n) becomes 0, and the routine continues after the end.
Several functions are helpful for reducing the results of matrix comparisons to scalar
conditions for use with if, including:
isequal
isempty
all
any
break statement
The break statement lets you exit early from a for or while loop. In nested
loops, break exits from the innermost loop only.
Example 1:
for i = length(x)
% check for positive y
if y(x) > 0
% terminate loop execution
break
end
% follow your code
a = a + y(x);
...
end
Example 2:
x = sin(sqrt(variable));
while 1
n = input('Enter number of loops: ')
if n <= 0
% terminate loop execution
break
end
for i = 1 : n
% follow your code
x = x + 20;
...
end
end
Matrix Inversion
This program performs the matrix inversion of a square matrix step-by-step. The
inversion is performed by a modified Gauss-Jordan elimination method. We start
with an arbitrary square matrix and a same-size identity matrix (all the elements
along its diagonal are 1).
We perform operations on the rows of the input matrix in order to transform it and
obtain an identity matrix, and perform exactly the same operations on the
accompanying identity matrix in order to obtain the inverse one. If we find a row
full of zeros during this process, then we can conclude that the matrix is singular,
and so cannot be inverted.
We expose a very naive method, just as was performed in the old-Basic- style.
Naturally, Matlab has appropriate and fast instructions to perform matrix inversions,
but we want to explain the Gauss-Jordan concept and show how nested loops and
control flow work.
First, we develop a function like this (let's assume we save it as 'mat_inv2.m'):
function b = mat_inv2(a)
% Find dimensions of input matrix
[r,c] = size(a);
% If input matrix is not square, stop function
if r ~= c
disp('Only Square Matrices, please')
b = [];
return
end
% Target identity matrix to be transformed into the output
% inverse matrix
b = eye(r);
%The following code actually performs the matrix inversion
for j = 1 : r
for i = j : r
if a(i,j) ~= 0
for k = 1 : r
s = a(j,k); a(j,k) = a(i,k); a(i,k) = s;
s = b(j,k); b(j,k) = b(i,k); b(i,k) = s;
end
t = 1/a(j,j);
for k = 1 : r
a(j,k) = t * a(j,k);
b(j,k) = t * b(j,k);
end
for L = 1 : r
if L ~= j
t = -a(L,j);
for k = 1 : r
a(L,k) = a(L,k) + t * a(j,k);
b(L,k) = b(L,k) + t * b(j,k);
end
end
end
end
break
end
% Display warning if a row full of zeros is found
if a(i,j) == 0
disp('Warning: Singular Matrix')
b = 'error';
return
end
end
% Show the evolution of the input matrix, so that we can
% confirm that it became an identity matrix.
a
And then, we can call it or test it from any other script or from the command
window, like this:
% Input matrix a = [3 5 -1 -4
1 4 -.7 -3
0 -2 0 1
-2 6 0 .3];
% Call the function to find its inverse
b = mat_inv2(a)
% Compare with a result generated by Matlab
c = inv(a)
Matlab produces this response:
First, we see how the original matrix transformet into an identity matrix:
a =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Then, our function show its result:
b =
0.6544 -0.9348 -0.1912 0.0142
0.1983 -0.2833 -0.1034 0.1558
0.3683 -1.9547 -4.2635 -0.4249
0.3966 -0.5666 0.7932 0.3116
Finally, this is the inversion produced by a direct instruction from Matlab (inv(a)):
c =
0.6544 -0.9348 -0.1912 0.0142
0.1983 -0.2833 -0.1034 0.1558
0.3683 -1.9547 -4.2635 -0.4249
0.3966 -0.5666 0.7932 0.3116
Another example:
% Input matrix
a = [1 1
1 1];
% Call the function to find its inverse
b = mat_inv2(a)
% Compare with a result generated by Matlab
c = inv(a)
And Matlab display is:
Warning: Singular Matrix
b =
error
Warning: Matrix is singular to working precision.
> In test_mat_inv at 42
c =
Inf Inf
Inf Inf
In this case, our algorithm found a singular matrix, so an inverse cannot be
calculated. This agrees with what Matlab found with its own built-in function.
Switch Statement
The switch statement in Matlab executes groups of instructions or statements based
on the value of a variable or expression.
The keywords case and otherwise delineate the groups. Only the first matching
case is executed. There must always be an end to match the switch.
The syntax is:
switch switch_expr
case case_expr
statement
...
case {case_expr1,case_expr2,case_expr3,...}
statement
...
otherwise
statement
...
end
MATLAB switch does not fall through. If the first case statement is true, the other
case statements do not execute. So, break statements are not required.
Example:
To execute a certain block of code based on what the string 'color' is set to:
color = 'rose';
switch lower(color)
case {'red', 'light red', 'rose'}
disp('color is red')
case 'blue'
disp('color is blue')
case 'white'
disp('color is white')
otherwise
disp('Unknown color.')
end
Matlab answer is:
color is red
>>
Boolean Operator
In Matlab, there are four logical (aka boolean) operators:
Boolean operator: Meaning:
& logical AND
| logical OR
~ logical NOT (complement)
xor exclusive OR
These operators produce vectors or matrices of the same size as the operands, with 1
when the condition is true, and 0 when the condition is false.
Given array x = [0 7 3 5] and array y = [2 8 7 0], these are some possible operations:
Operation: Result: n = x & y n = [0 1 1 0]
m = ~(y | x) m = [0 0 0 0]
p = xor(x, y) p = [1 0 0 1]
Since the output of the logical or boolean operations is a vector or matrix with only 0 or 1
values, the output can be used as the index of a matrix to extract appropriate elements.
For example, to see the elements of x that satisfy both the conditions (x<y) and (x<4),
you can type x((x<y)&(x<4)).
Operation: Result: x<y ans = [1 1 1 0]
x<4 ans = [1 0 0 0]
q = x((x<y)&(x<4)) q = [0 3]
Additionally to these boolean operators, there are several useful built-in logical functions,
such as:
any true if any element of a vector is true
all true if all elements of a vector are true
exist true if the argument exists
isempty true for an empty matrix
isinf true for all infinite elements of a matrix
isnan true for all elements of a matrix that ara not-a-number
find finds indices of non-zero elements of a matrix
Relational Operators
There are six relational operators in Matlab:
Relational operator: Meaning:
< less than
<= less than or equal
> greater than
>= greater than or equal
== equal (possibility, not assignation)
~= not equal
These operations result in a vector of matrix of the same size as the operands, with 1
when the relation is true, and 0 when it’s false.
Given arrays x = [0 7 3 5] and y = [2 8 7 0], these are some possible relational
operations:
Operation: Result: k = x<y k = [1 1 1 0]
k = x <= y k = [1 1 1 0]
k = x == y k = [0 0 0 0]
Although these operations are usually used in conditional statements such as if-else to
branch out to different cases, they can be used to do very complex matrix manipulation.
For example x = y(y > 0.45) finds all the elements of vector y such that yi > 0.45 and
stores them in vector x. These operations can be combined with boolean operators, too.
Axioms - Laws of Boolean Algebra
Boolean algebra is the algebra of propositions.
Propositions are denoted by letters, such as A, B, x or y, etc.
In the following axioms and theorems (laws of boolean algebra), the '+' or 'V'
signs represent a logical OR (or conjunction), the '.' or '^' signs represent a
logical AND (or disjunction), and '¬' or '~' represent a logical NOT ( or
negation).
Every proposition has two possible values: 1 (or T) when the proposition is true and
0 (or F) when the proposition is false.
The negation of A is written as ¬A (or ~A) and read as 'not A'. If A is true then ¬A
is false. Conversely, if A is false then ¬A is true.
Descript. OR form AND form Other way to express it:
Axiom x+0 = x x.1 = x A V F = A
A ^ T = A
Commutative x+y = y+x x.y = y.x A V B = B V A
A ^ B = B ^ A
Distributive x.(y+z) =
(x.y)+(x.z)
x+y.z =
(x+y).(x+z)
A ^ (B V C) = (A ^ B) V (A ^ C)
A V B ^ C = (A V B) ^ (A V C)
Axiom x+¬x = 1 x.¬x = 0 A V ¬A = T
A ^ ¬A = F
Theorem x+x = x x.x = x A V A = A
A ^ A = A
Theorem x+1 = 1 x.0 = 0 A V T = T
A ^ F = F
Theorem ¬¬x = x ¬(¬A) = A
Associativity x+(y+z) =
(x+y)+z
x.(y.z) =
(x.y).z
A V (B V C) = (A V B) V C
A ^ (B ^ C) = (A ^ B) ^ C
Absorption x+x.y = x x.(x+y) = x A V A ^ B = A
A ^ (A V B) = A
DeMorgan's
laws
x+y =
¬(¬x.¬y)
x.y =
¬(¬x+¬y)
A V B = ¬(¬A ^ ¬B)
A ^ B = ¬(¬A V ¬B)
Using logical gates, the commutative property for a logical AND is:
The commutative property for a logical OR, is:
Using electronic gates, the distributive property is:
The De Morgan's laws can transform logical ORs into logical ANDs (negations are
necessary) and can electronically be described this way:
Or
De Morgan Laws
In Boolean Algebra, there are some very important laws which are called the De
Morgan's laws (the spelling can change from author to author).
These laws teach us how to interchange NOT with AND or OR logical operators.
Using gates (commonly used in Digital Electronics), they can be expressed in two
forms:
the OR form:
the AND form:
In Matlab, these laws can be demonstrated very easily.
Let's create a script file like this:
% Let x and y be column vectors
x = [0 0 1 1]'
y = [0 1 0 1]'
% We can demonstrate the OR form of the law
% with these two lines
x_or_y = x|y
DeMorg1 = not(not(x)& not(y))
% We can demonstrate the AND form of the law
% with these two lines
x_and_y = x&y
DeMorg2 = not(not(x) | not(y))
When we run it, we get this output:
x =
0
0
1
1
y =
0
1
0
1
x_or_y =
0
1
1
1
DeMorg1 =
0
1
1
1
x_and_y =
DeMorg2 =
0
0
0
1
0
0
0
1
Which demonstrates the De Morgan's laws.
Logical AND
A B A & B
0 0 0
0 1 0
1 0 0
1 1 1
A & B performs a logical AND of arrays A and B and returns an array containing
elements set to either logical 1 (TRUE) or logical 0 (FALSE).
An element of the output array is set to 1 if both input arrays contain a non-zero
element at that same array location. Otherwise, that element is set to 0. A and B
must have the same dimensions unless one is a scalar.
Example:
If matrix A is:
A =
0 0 1 1
1 1 0 0
0 0 0 0
1 1 1 1
and matrix B is:
B =
0 0 0 0
1 1 1 1
0 1 0 1
1 0 1 0
Then, the AND operation between A and B is:
>> A & B
ans =
0 0 0 0
1 1 0 0
0 0 0 0
1 0 1 0
>>
Example:
If vector x is:
x =
0 1 2 3 0
and vector y is:
y =
1 2 3 0 0
Then, the AND operation between x and y is:
>> x & y
ans =
0 1 1 0 0
>>
Logical OR
A B A | B
0 0 0
0 1 1
1 0 1
1 1 1
A | B performs a logical OR of arrays A and B and returns an array containing
elements set to either logical 1 (TRUE) or logical 0 (FALSE).
An element of the output array is set to 1 if either input array contains a non-zero
element at that same array location. Otherwise, that element is set to 0. A and B
must have the same dimensions unless one is a scalar.
Example:
If matrix A is:
A =
0 0 1 1
1 1 0 0
0 0 0 0
1 1 1 1
and matrix B is:
B =
0 0 0 0
1 1 1 1
0 1 0 1
1 0 1 0
Then, the OR operation between A and B is:
>> A | B
ans =
0 0 1 1
1 1 1 1
0 1 0 1
1 1 1 1
>>
Example:
If vector x is:
x =
0 1 2 3 0
and vector y is:
y =
1 2 3 0 0
Then, the OR operation between x and y is:
>> x | y
ans =
1 1 1 1 0
>>
XOR - Logical EXCLUSIVE OR
A B x o r (A,B)
0 0 0
0 1 1
1 0 1
1 1 0
For the logical exclusive OR, XOR(A,B), the result is logical 1 (TRUE) where either
A or B, but not both, is nonzero. The result is logical 0 (FALSE) where A and B are
both zero or nonzero.
A and B must have the same dimensions (or one can be a scalar).
This is the common symbol for the 'Exclusive OR'
Example:
If matrix A is:
A =
0 0 1 1
1 1 0 0
0 0 0 0
1 1 1 1
and matrix B is:
B =
0 0 0 0
1 1 1 1
0 1 0 1
1 0 1 0
Then, the logical EXCLUSIVE OR between A and B is:
>> xor(A,B)
ans =
0 0 1 1
0 0 1 1
0 1 0 1
0 1 0 1
>>
Example:
If vector x is:
x =
0 1 2 3 0
and vector y is:
y =
1 2 3 0 0
Then, the logical exclusive OR between x and y is:
ans =
1 0 0 1 0
>>
Logical NOT
A ~A
0 1
1 0
In MATLAB, ~A performs a logical NOT of input array A, and returns an array
containing elements set to either logical 1 (TRUE) or logical 0 (FALSE).
An element of the output array is set to 1 if A contains a zero value element at that
same array location. Otherwise, that element is set to 0.
Example:
If matrix A is:
A =
0 0 1 1
1 1 0 0
0 0 0 0
1 1 1 1
Then, the NOT A is produced:
>> ~A
ans =
1 1 0 0
0 0 1 1
1 1 1 1
0 0 0 0
>>
Example:
If vector x is:
x =
0 1 2 -3 0
Then, the NOT x is produced:
>> ~x
ans =
1 0 0 0 1
>>
Determinants in Matlab
The symbol
which consists of the four numbers a1, b1, a2, b2 arranged in two rows and two columns is
called a determinant of second order or of order two. The four numbers are called its
elements. By definition,
Thus . Here, the elements 2 and 3 are in the first row, and
the elements 4 and 1 are in the second row. Elements 2 and 4 are in column one, and
elements 3 and 1 are column two.
The method of solution of linear equations by determinants is called the Cramer’s
Rule. A system of two linear equations in two unknowns may be solved using a second
order det. Given the system of equations
a1x + b1y = c1
a2x + b2y = c2
it is possible to obtain
These values for x and y may be written in terms of second order dets, as follows:
Example:
Solve the system of equations
2x + 3y = 16
4x + y = -3
The denominator for both x and y is .
Then , and .
In Matlab, a determinant can be calculated with the built-in function 'det()'.
Using the same numbers as in the example above,
if A = [2 3; 4 1], then det(A) = -10;
if B = [16 3; -3 1], then x = det(A)/det(B) = -2.5;
if C = [2 16; 4 -3], then y = det(C)/det(A) = 7
Naturally, you can use the function det() to find determinants of higher order.
Simultaneous Equations
- Linear Algebra -
Solving a system of simultaneous equations is easy in Matlab. It is, maybe, the most
used operation in science and engineering, too. Solving a set of equations in linear
algebra on a computer is nowadays as basic as doing arithmetic additions using a
calculator. Let's see how easy Matlab makes this task.
We'll solve the set of linear equations given below. To solve these equations, no prior
knowledge of matrix algebra or linear methods is required. The first two steps described
below are really basic for most people who know a just little bit of linear algebra.
Consider the following set of equations for our example.
-6x = 2y - 2z + 15
4y - 3z = 3x + 13
2x + 4y - 7z = -9
First, rearrange the equations. Write each equation with all unknown quantities on the left-hand side and all known
quantities on the right side. Thus, for the equations given, rearrange them such that all
terms involving x, y and z are on the left side of the equal sign.
-6x - 2y + 2z = 15
-3x + 4y - 3z = 13
2x + 4y - 7z = -9
Second, write the equations in a matrix form. To write the equations in the matrix form Ax = b, where x is the vector of unknowns, you
have to arrange the unknowns in vector x, the coefficients of the unknowns in matrix A
and the constants on the rigth hand of the equations in vector b. In this particualar
example, the unknown column vector is
x = [x y z]'
the coefficient matrix is
A = [-6 -2 2
-3 4 -3
2 4 -7]
and the known constant column vector is
b = [15 13 -9]'
Note than the columns of A are simply the coefficients of each unknown from all the
three expressed equations. The apostrophe at the end of vectors x and b means that
those vectors are column vectors, not row ones (it is Matlab notation).
Third, solve the simultaneous equations in Matlab. Enter the matrix A and vector b, and solve for vector x with the instruction 'x = A\b' (note
that the '\' sign is different from the ordinary division '/' sign).
The Matlab answer is:
A =
-6 -2 2
-3 4 -3
2 4 -7
b =
15
13
-9
x =
-2.7273
2.7727
2.0909
>>
You can test the result by performing the substitution and multiplying Ax to get b, like
this:
A*x
And the Matlab answer is:
ans =
15.0000
13.0000
-9.0000
>>
which corresponds to b, indeed.
Cramer's Rule
The method of solution of linear equations by determinants is called Cramer's Rule.
This rule for linear equations in 3 unknowns is a method of solving by determinants the
following equations for x, y, z
a1x + b1y + c1z = d1
a2x + b2y + c2z = d2
a3x + b3y + c3z = d3
If we analytically solve the equations above, we obtain
If
is the determinant of coefficients of x, y, z and is
assumed not equal to zero, then we may re-write the values as
The solution involving determinants is easy to remember if you keep in mind these
simple ideas:
The denominators are given by the determinant in which the elements are the coefficients of x, y and z, arranged as in the original given equations.
The numerator in the solution for any variable is the same as the determinant
of the coefficients ∆ with the exception that the column of coefficients of the
unknown to be determined is replaced by the column of constants on the right side of the original equations.
That is, for the first variable, you substitute the first column of the determinant with
the constants on the right; for the second variable, you substitute the second column
with the constants on the rigth, and so on...
Example:
Solve this system using Cramer’s Rule
2x + 4y – 2z = -6
6x + 2y + 2z = 8
2x – 2y + 4z = 12
For x, take the determinant above and replace the first column by the constants on the
right of the system. Then, divide this by the determinant:
For y, replace the second column by the constants on the right of the system. Then, divide
it by the determinant:
For z, replace the third column by the constants on the right of the system. Then, divide it
by the determinant:
You just solved ths system!
In Matlab, it’s even easier. You can solve the system with just one instruction.
Let D be the matrix of just the coefficients of the variables:
D = [2 4 -2;
6 2 2;
2 -2 4];
Let b be the column vector of the constants on the rigth of the system :
b = [-6 8 12]'; % the apostrophe is used to transpose a vector
Find the column vector of the unknowns by 'left dividing' D by b (use the backslash),
like this:
variables = D\b
And Matlab response is:
variables =
1.0000
-1.0000
2.0000
Linear Algebra and its Applications
- Circuit Analyisis -
One important linear algebra application is the resolution of electrical circuits.
We can describe this type of circuits with linear equations, and then we can solve the
linear system using Matlab.
For example, let's examine the following electrical circuit (resistors are in ohms,
currents in amperes, and voltages are in volts):
We can describe the circuit with the following system of linear equations:
7 - 1(i1 - i2) - 6 - 2(i1 - i3) = 0
-1(i2 - i1) - 2(i2) - 3(i2 - i3) = 0
6 - 3(i3 - i2) - 1(i3) - 2(i3 - i1) = 0
Simplifying and rearranging the equations, we obtain:
-3i1 + i2 + 2i3 = -1
i1 - 6i2 + 3i3 = 0
2i1 + 3i2 - 6i3 = -6
This system can be described with matrices in the form Ax = b, where A is the
matrix of the coefficients of the currents, x is the vector of unknown currents, and b
is the vector of constants on the right of the equalities.
One possible Matlab code to solve this is:
A = [-3 1 2
1 -6 3
2 3 -6];
b = [-1 0 -6]';
i = A\b
The Matlab answer is:
i =
3.0000
2.0000
3.0000
>>
This means that i1 = 3, i2 = 2, and i3 = 3.
Linear Programming - (as an optimization problem)
Matlab is well suited to handle the so called linear programming problems. These
are problems in which you have a quantity, depending linearly on several variables,
that you want to maximize or minimize subject to several constraints that are
expressed as linear inequalities with the same variables.
Sometimes the number of variables and the number of constraints are high, or the
constraints in the linear inequalities or the expression for the quantity to be
optimized may be numerically complicated.
We will illustrate the method of linear programming by means of a simple example
giving a numerical solution. Matlab has some special functions such as 'simlp' or
'linprog' to tackle down this type of problems, but these built-in functions are not
always available since they belong to special toolboxes (Simulink or Optimization
toolboxes). Therefore, we are going to formulate the problem as an optimization
issue, and we'll use the instruction 'fminsearch', which is an always available
instruction.
Let's suppose that a merry farmer has 75 roods (4 roods = 1 acre) on which to plant
two crops: wheat and corn. To produce these crops, it costs the farmer (for seed,
water, fertilizer, etc. ) $120 per rood for the wheat, and $210 per rood for the corn.
The farmer has $15,000 available for expenses, but after the harvest the farmer
must store the crops while awaiting favorable or good market conditions. The farmer
has storage space for 4,000 bushels. Each rood yields an average of 110 bushels of
wheat or 30 bushels of corn. If the net profit per bushel of wheat (after all the
expenses) is $1.30 and for corn is $2.00, how should the merry farmer plant the 75
roods to maximize profit?
We begin by formulating the linear programming problem mathematically. We
express the objective (profit) and the constraints. Let x denote the number of
roods allotted to wheat and y the number of roods allotted to corn. Then the
expression to be maximized is clearly
P = (110)(1.3)x + (30)(2)y = 143x + 60y
There are some constraint inequalities, specified by the limits on expenses, storage
and roodage. They are:
and naturally:
As we mentioned before, we are going to formulate this as an optimization
problem using the 'fminsearch' built-in function.
In Matlab, the instruction works as follows:
X = FMINSEARCH(FUN,X0,OPTIONS) minimizes with the default optimization
parameters replaced by values in the structure OPTIONS, created with the OPTIMSET
function. FMINSEARCH uses these options: Display, TolX, TolFun, MaxFunEvals,
MaxIter, FunValCheck, and OutputFcn.
This is one possible approach for our objective function, which is saved as an m-file
(in this case 'OF_P.m'):
function OFValue = OF_P(x)
% Here we embed the constraints or inequalities.
% If the constraints are not met, we penalize the optimization by
% giving an arbitrary high value to the objective function.
if 120 * x(1) + 210 * x(2) > 15000 |...
110 * x(1) + 30 * x(2) > 4000 |...
x(1) + x(2) > 75 | ...
x(1) < 0 |...
x(2) < 0
OFValue = 10;
return
end
% fminsearch tries to minimize the function, so we invert its sign
P = 143 * x(1) + 60 * x(2);
OFValue = -P;
Then, we can call it from another script, which includes the 'fminsearch' function
calling the objective function file (in 'OF_P'):
clear; clc;
format bank
% We have to start with a 'seed' for the search
x = [1 10]';
% We can perform the optimization with different number of
% iterations or tolerances
options = optimset('MaxFunEvals', 2000, 'TolX', 1e-2);
[x_opt, FunVal, EF, output] = fminsearch('OF_P', x, options)
% Finally, we display the profit using the found solution
P = 143 * x_opt(1) + 60 * x_opt(2)
And the Matlab response is:
x_opt =
21.87
53.12
FunVal =
-6315.62
EF =
1.00
output =
iterations: 121.00
funcCount: 243.00
algorithm: 'Nelder-Mead simplex direct search'
message: [1x196 char]
P =
6315.62
>>
This means that the farmer should consider 21.87 roods for wheat, 53.12 roods for
corn, and his profit would be $6,315.62.
It is important to notice that this is a numerical approximation, which means that
if we start with another 'seed' or use other parameters in the 'options' set, we can
get to another result. The number found is a possible solution, but there's no
guarantee that it is the best one, according to tolerances or to number of
iterations or evaluations desired.
For example, we can use the seed 'x = [10 10]' instead (without moving any other
instruction), and the Matlab answer now is:
x_opt =
32.31
14.88
FunVal =
-5512.50
EF =
1.00
output =
iterations: 75.00
funcCount: 151.00
algorithm: 'Nelder-Mead simplex direct search'
message: [1x196 char]
P =
5512.50
Now, the 'best' profit found is only $5,512.50. So, it is a good idea to try with several
'seeds' and different parameters in the 'options' set to compare with and select the
best solution. Most of the times the solutions will be very close (at least for linear programming problems).
LU Factorization
In Matlab there are several built-in functions provided for matrix factorization (also
called decomposition).
The name of the built-in function for a Lower-Upper decomposition is 'lu'. To get the
LU factorization of a square matrix A, type the command
'[L, U] = lu(A)'.
Matlab returns a lower triangular matrix L and an upper triangular matrix U such
that L*U = A.
Suppose that
A= [ 1 2 -3
-3 -4 13
2 1 -5]
We can verify that if
L = [ 1 0 0
-3 1 0
2 -1.5 1]
and
U = [1 2 -3
0 2 4
0 0 7]
Then, A = L*U
The decomposition of the matrix A is an illustration of an important and well known
theorem. If A is a nonsingular matrix that can be transformed into an upper
diagonal form U by the application or row addition operations, then there exists a
lower triangular matrix L such that A = LU.
Row addition operations can be represented by a product of elementary matrices. If
n such operations are required, the matrix U is related to the matrix A in the
following way:
U = En En-1 ... E2 E1 A
The lower triangular matrix L is found from
L = E1-1
E2-1
... En-1
L will have ones on the diagonal. The off-diagonal elements are zeros above the
diagonal, while the elements below the diagonal are the multipliers required to
perform Gaussian elimination on the matrix A. The element lij
is equal to the multiplier used to eliminate the (i, j) position.
Example:
In Matlab, let's find the LU decomposition of the matrix
A = [-2 1 -3; 6 -1 8; 8 3 -7]
Write this instruction in the command window or within a script:
[L, U] = lu(A)
And the Matlab answer is:
L =
-0.2500 -0.5385 1.0000
0.7500 1.0000 0
1.0000 0 0
U =
8.0000 3.0000 -7.0000
0 -3.2500 13.2500
0 0 2.3846
We can test the answer, by typing
L*U
And, finnally, the Matlab answer is:
ans =
-2.0000 1.0000 -3.0000
6.0000 -1.0000 8.0000
8.0000 3.0000 -7.0000
>>
Showing that A = L*U, indeed.
Singular Value Decomposition (SVD)
Let's suppose that a matrix A is singular. Then, let A be a real m x n matrix of rank r,
with . The Singular Value Decomposition (svd) of A is
A = U S V'
(the apostrophe after a matrix or vector means its transpose) where U is an orthogonal m
x n matrix, S is an r x r diagonal matrix, and V is an n x n square orthogonal matrix.
Since U and V are orthogonal, then
UU' = I and VV' = I
That is, the transpose of each matrix is equal to its inverse. The elements along the
diagonal of S, labelled , are called the singular values of A. There are r such singular
values and they satisfy
If the matrix A is square, then we can use the singular value decomposition to find the
inverse, which is is
A-1
= (USV')-1
= (V')-1
S-1
U-1
= VS-1
U'
since (AB)-1
= B-1
A-1
, UU' = I, and VV' = I.
If A is a square matrix then
And so,
If an SVD of a matrix A can be calculated, so can be its inverse. Therefore, we can find a
solution to a system
Ax = b x = A-1
b = VS-1
U'b
that would otherwise be usolvable.
Example:
Let's find with Matlab the singular value decomposition of
A = [ 0 -1
-2 1
1 0]
We simply type:
[U,S,V] = svd(A)
and the above operation produces a diagonal matrix S, of the same dimension as A and
with nonnegative diagonal elements in decreasing order, and unitary matrices U and V so
that A = U*S*V'.
The Matlab answer is:
U =
-0.1826 -0.8944 0.4082
0.9129 0.0000 0.4082
-0.3651 0.4472 0.8165
S =
2.4495 0
0 1.0000
0 0
V =
-0.8944 0.4472
0.4472 0.8944
>>
We can confirm the values of UU', VV' and USV, by executing these instructions in
Matlab
U*U'
V*V'
U*S*V
The confirming responses are:
ans =
1.0000 -0.0000 -0.0000
-0.0000 1.0000 -0.0000
-0.0000 -0.0000 1.0000
ans =
1 0
0 1
ans =
-0.0000 -1.0000
-2.0000 1.0000
1.0000 0.0000
>>
2D Plots
Matlab includes fancy tools for visualization. Basic 2D plots, good 3D graphics, and
even animation possibilities are available in an easy environment.
The most basic and useful command for producing simple 2D plots is:
plot(xvalues, yvalues, 'style')
xvalues is the value of the horizontal points to be plotted.
yvalues is the value of the function to be plotted.
xvalues and yvalues have to have the same length.
'style' is an optional argument that specifies the color, line style and point-
marker style.
Examples:
plot(x,y) plots y vs x with a solid line
plot(x,y,'-.') plots y vs x with a dash-dot line
plot(x) plots the elements of x against their own index
plot(x,y,'r--') plots y vs x with a red dashed line
plot(a,b,'k+') plots b vs a with black plus signs
You may annotate your plots with 'xlabel', 'ylabel' and 'title'. Other useful functions
are 'legend', 'axis', 'grid' and 'hold'.
Here's an example that integrates all of the above functions.
% Clears variables, command window, and closes all figures
clear, clc,close all
% Defines value of x and two functions
x = 0: .1 : 2*pi;
y1 = cos(x);
y2 = sin(x);
% Plots two functions with different style, and wider lines
plot(x,y1,'b', x, y2, 'r-.', 'linewidth', 2)
% Activates the grid
grid on
% Defines limits for x and y axes, and sets title, labels and legends
axis([0 2*pi -1.5 1.5])
title('2D plots', 'fontsize', 12)
xlabel('angle')
ylabel('f1(x), f2(x)')
legend('cos(x)', 'sin(x)')
% Keeps figure on screen, in order to add a third function
hold on
% Defines another function
y3 = 0.5 * x;
% Plots over the previous figure
plot(x, y3, 'm')
And the result is:
Matlab Plotting - Horizontal Lines and Vertical lines
We are going to create a simple Matlab function to add horizontal lines (and vertical
ones) to any given Matlab-created plot.
For example, let's say that we need to add some indications or annotations to a plot,
and we need to display and indicate some upper or lower limits.
The proposed Matlab function will have 5 input parameters:
Initial value (where the horizontal line will start)
Final value (where the line will end)
Y value (vertical position of the line with respect to the plot)
Direction (to indicate the direction of the annotation: 1 going upwards, or -1
going downwards, like an arrow)
Vertical range (to display aesthetically proportioned lines)
We plan the usage of our function like this (its name will be 'plot_limit'):
Usage: L = [L_min L_max y d r];
plot_limit(L);
where
L_min = starting point
L_max = ending point
y = y value of horizontal line
d = direction (1 or -1)
r = y range
So, we need to know in advance where we want to put our line (sure!).
We define our horizontal and vertical values. We arbitrarily define 300 horizontal
points and use a linewidth = 1.5. The instruction 'hold on' keeps the current figure,
instead of overwriting it. This Matlab code displays just a horizontal line.
a = linspace(L_min, L_max, 300);
b = linspace(y, y, 300);
plot(a,b,'k-','linewidth',1.5)
hold on
Then, we add some tiny vertical lines on each side of the horizontal one. If direction
'd' is 1, the vertical lines are below the horizontal line (going 'up'). If direction 'd' is -
1, the vertical lines are above the horizontal one (going 'down'). We take the vertical
range into account, in 'r', to display a vertical line of just 3% of the total 'height' of
the current figure. You can try different values to suit your needs, obviously. We find
the initial or final points of the vertical lines with an 'if-statement'.
This is the code to achieve it.
% Initial vertical line
a = linspace(L_min, L_min, 10);
if d == 1
b = linspace(y-r*.03, y, 10);
else
b = linspace(y, y+r*.03, 10);
end
plot(a,b,'k-','linewidth',1.5)
hold on
% Final vertical line
a = linspace(L_max, L_max, 10);
if d == 1
b = linspace(y-r*.03, y, 10);
else
b = linspace(y, y+r*.03, 10);
end
plot(a,b,'k-','linewidth',1.5)
Now, we'll test our function with this script.
clear; clc; close all
x = 0 : 2*pi/360 : 2*pi;
y = sin(x);
plot(x,y)
grid on
xlabel('angle')
ylabel('sin(x)')
title('Plot showing horizontal and vertical lines')
hold on
plot_limit([0.8, 2.5, 0.4, 1, 2])
plot_limit([4, 5.4, -0.6, -1, 2])
The result is:
The first line starts at 0.8, ends at 2.5, and has a vertical value of 0.4. The vertical
lines simulate an up-arrow (d = 1).
The second line starts at 4, ends at 5.4, and has a vertical value of -0.6. Direction
goes down (d = -1).
Pie Plots
pie(x) draws pie plots of the data in the vector x. The values in x are normalized
via x/sum(x) to determine the area of each slice of pie.
If sum(x) is less or equal to 1, the values in x directly specify the area of the
pie slices. Only a partial pie will be drawn if sum(x) is less than < 1.
The '%' sign indicates that there is a comment in that line and Matlab does not do
anything with it. It is as if it were inexistent, and it exists only for explanatory
purposes.
Example:
% Clears variables, command window, and closes all figures
clc; clear; close all
% These are the names of the slices
names = char('Region 1', 'Region 2', 'Distr. 3', 'Distr. 4');
% These are the numbers to be plotted
data = [1200, 500, 300, 120];
pie(data)
% gtext('string') displays the graph window, puts up a
% cross-hair, and waits for a mouse button or keyboard
% key to be pressed.
for i=1:4
gtext(names(i,:));
end
title('Sales', 'fontsize', 15)
The result is:
hist - Histograms in Matlab
The hist instruction in Matlab, without output arguments, produces a histogram
bar plot of the results. The bar edges on the first and last bins may extend to cover
the min and max of the data unless a matrix of data is supplied.
Example:
This Matlab code creates a histogram with 3 bars. The first bar has two '1' values,
the second bar has three '2' values, and the third bar has one '3' values.
y = [1 1 2 2 2 3]
hist(y)
The horizontal axis has the different values in the vector to be plotted.
The vertical axis has the number of those values in the vector.
Example:
This Matlab code generates a histogram of 15 randomly distributed numbers
between 0 and 1.
a = randn(15,1)
hist(a)
a =
-0.8468
-0.2463
0.6630
-0.8542
-1.2013
-0.1199
-0.0653
0.4853
-0.5955
-0.1497
-0.4348
-0.0793
1.5352
-0.6065
-1.3474
>>
Note that each column includes a range of values, otherwise the histogram
would contain 15 bars.
Comet Plot
comet(a) displays an animated comet plot of the vector a.
comet(a, b) displays an animated comet plot of vector b vs. a.
comet(a, b, p) uses a comet of length p*length(b). Default is p = 0.10.
Example:
If you want to plot the following function:
, for the range , you can write this script in Matlab:
% Clears variables, command window, and closes all figures
clc; clear; close all
% Generates 300 linearly spaced points from 0 to 8*pi
x = linspace(0, 8*pi, 300);
% Creates the formula to be plotted
% (it's a multiplication between vector 'x' and vector 'cos(x)')
y = x .* cos(x);
% Plot it!
comet(x, y, .6)
An the result is...
It is much better to see it on your own screen, because it moves like a ribbon!
You can experiment with different p values to see the length of the comet
changing...
Matlab Plot - stem
In this example, we study the 'stem' instruction to plot Matlab functions.
It draws vertical lines (with a little circle at the tip) proportional to the value of the
function at that particular horizontal value. 'stem' does not join the circles with a
line, and it is very helpful to stress the fact that the function is, in fact, not
continuous but discrete.
Let's assume that we want to plot the following elegant exponential and sinusoidal
function:
Example:
We can develop a script like this:
% Avoid superimposed operations and close previous figs.
clc; clear; close all
% First, we define 51 values of our independant variable
x = 0 : 2*pi/50 : 2*pi;
% Second, we define the function to be ploted
y = exp(-x/3) .* sin(x);
% Third, we use the 'stem' function to plot discrete values
stem(x,y)
% We can add title and labels (as strings in arguments)
title('Demonstration of the -stem- function')
xlabel('angle x')
ylabel('f(x)')
And we get the following plot:
If we define our independant variable using less points, as in
x = 0 : 2*pi/20 : 2*pi;
we get the following visual change:
loglog - (logarithmic plot)
In this example we are going to demonstrate how to use the 'loglog' function
included in Matlab to produce non-linear plots. This term referrs to the fact that
the plot is logarithmically scaled in both axes. There are other functions such as
'semilogx' and 'semilogy' which have one axis in linear scale and the other axis in
logarithmic scale.
Example:
clear; clc; close all
% Define your independent variable
t = 0 : 2*pi/360 : 2*pi;
% Define values along your x-axis
x = exp(t);
% Define values along your y-axis
y = 50 + exp(3*t);
% Plot your function with a wider line and grid the figure
loglog(x, y, 'LineWidth', 2)
grid
% Use a title for the figure
title('Demonstration of logarithmic plots')
% Label your x-axis with a double line.
% Note the special characters
xlabel([{'e^{t}'}; {'0 \leq t \leq 2\pi'}])
% Label your y-axis
ylabel('50 + e^{3t}')
The produced figure is:
Polar Plots (with a little help from Matlab)
Matlab provides functions that plot data in the polar coordinates using magnitudes and
angles. In this article we’ll discuss and show the Matlab built-in commands 'compass',
'polar' and 'rose'.
The Compass Function
The compass function takes its inputs in Cartesian format, but outputs polar plots. In
the compass function each arrow’s length corresponds to the magnitude of a data element
and its pointing direction indicates the angle of the complex data. This function creates
arrows that go out from the origin of the axes in a polar coordinate system. To illustrate
this function, we’ll create a set of arrows that increase in size from arrow to arrow in a
counter-clockwise manner.
t = 1 : 5;
r = t .* exp(i * t * 36 * (pi/180));
compass(r)
This code produces:
The Polar Function
The polar function creates polar plots from angle and magnitude data.
It takes the forms polar(theta,rho), where theta corresponds to the angle (in radians) and
rho corresponds to the magnitude. The variables theta and rho must be identically sized
vectors.
As an example, we create a cardioid with the following code:
t = 0 : 2*pi/100 : 2*pi;
r = 1 - sin(t);
polar(t, r)
Here’s the result:
Here’s another polar chart:
t = 0 : 2*pi/100 : 2*pi;
r = sqrt(abs(sin(3*t)));
polar(t,r)
The Rose Function
With rose you can create angle histograms that are drawn in polar coordinates. By using
rose(angle_data), the function will determine how many of the angles (in radians) fall
within a given angular bin. By default there are 20 evenly spaced bins between 0 and 2pi.
The number of bins can be changed by using rose(angle_vector, nr_of_bins), where the
variable nr_of_bins is a scalar specifying the number of bins that should be spaced
between 0 and 2pi. You can also specify the centers of the bins by passing a vector,
bin_centers, to the rose function, like this: rose(angle_vector, bin_centers).
The following code produces a rose plot of data which is normally distributed in angle
about 90º.
angle_vector = angle(exp(i*randn(1, 500))) + pi/2;
rose(angle_vector)
This is the result of the angle histogram created with rose:
Gaussian distribution – how to plot it in Matlab
In statistics and probability theory, the Gaussian distribution is a continuous
distribution that gives a good description of data that cluster around a mean. The
graph or plot of the associated probability density has a peak at the mean, and is
known as the Gaussian function or bell curve.
The probability density function (pdf) in this case can be defined as:
where
The formula above can me coded in Matlab easily, like this:
function f = gauss_distribution(x, mu, s)
p1 = -.5 * ((x - mu)/s) .^ 2;
p2 = (s * sqrt(2*pi));
f = exp(p1) ./ p2;
Now, let’s use it in an example.
We produce 500 random numbers between -100 and 100, with mean m = 0 and standard
deviation s = 30. The code is:
a = -100; b = 100;
x = a + (b-a) * rand(1, 500);
m = (a + b)/2;
s = 30;
Then, we plot this information using our bell curve:
f = gauss_distribution(x, m, s);
plot(x,f,'.')
grid on
title('Bell Curve')
xlabel('Randomly produced numbers')
ylabel('Gauss Distribution')
The produced shape is:
An important property of this bell-shaped curve is that the values less than one standard
deviation from the mean (between green lines below) represent approximately 68.2% of
the area under the curve, while two standard deviations from the mean (between red lines
below) take about 95.4%, and three standard deviations account for about 99.7% of the
area.
Simple Animation in Matlab
If we have some data representing a system or a function at several time intervals, we
may want to take advantage of Matlab’s simple animation capabilities. We're going to
expose the basic method or algorithm for animations.
In this example we’re going to work with just three special instructions. The idea is to
store every figure as a frame of the ‘movie’, with each frame stored as a column vector of
a matrix, an then play all the frames on the screen.
moviein(nr_frames): we initialize the matrix that will keep the frames, with the number
of frames to be generated.
getframe: with this instruction we keep the information of a given figure and ‘load’ a
temporary matrix with information.
movie(matrix, times, FPS): this is used to play the movie after its generation. Parameter
‘matrix’ is the saved data, ‘times’ the number of times that the movie will be played back,
and ‘FPS’ means ‘frames per second’ (the default is 12).
Let’s try this simple animation example:
% Define number of frames
nr_fr = 10;
% Initialize matrix using 'moviein'
frames = moviein(nr_fr);
% Generate frames with any plotting function.
% We use a cosine with variable frequency.
t = 0 : .01 : 6;
f = 1;
for i = 1 : nr_fr
f = f * 1.25; w = 2 * pi * f;
y = cos(w*t);
plot(t, y);
title('Recording movie...')
% Get every frame with 'getframe' and load the
appropriate % matrix.
frames(:, i) = getframe;
end
% Save the matrix so that this movie can be loaded later
save frames
This is the first frame of the recording:
Now you can play back the movie:
% Play the movie once, 2 FPS.
title('Movie being played back...')
movie(frames, 1, 2)
This is the last frame of the animation:
Done!
3D Plot – Part 1
From '3D Plot Part 1' to 3D Main
Matlab provides many powerful instructions for the visualization of 3D data. The
instructions provided include tools to plot wire-frame objects, 3D plots, curves,
surfaces... and can automatically generate contours, display volumetric data,
interpolate shading colors and even display non-Matlab made images. Here are
some commonly used functions (there are many more):
plot3
stem3
pie3
comet3
contour3
mesh
meshc
surf
surfc
sphere
ellipsoid
cylinder
Among these instructions, plot3 and comet3 are the 3D matches of plot and comet
commands mentioned in the 2D plot section.
The general syntax for the plot3 command is
plot3(x, y, z, 'style')
This command draws a 3D curve with the specified line style. The argument list can
be repeated to make overlay plots, just the same way as with the plot command in
2D.
We have to make some necessary comments before any example can be introduced.
Plots in 3D may be annotated with instructions already mentioned for 2D plots:
xlabel, ylabel, title, legend, grid, etc., plus the addition of zlabel. The grid
command in 3D makes the appearance of the plots better, especially for curves in
space.
View
The viewing angle of the observer is specified by the command view(azimuth,
elevation), where
azimuth (in degrees): specifies the horizontal rotation from the y-axis,
measured positive counterclockwise (default value is -37.5 degrees).
elevation (in degrees): specifies the vertical angle measured positive above
the xy-plane (default value is 30 degrees).
By specifying appropriate values of azimuth and elevation, one can plot projections
of 3D objects on different 2D planes. For example, the command 'view(90,0)'
places the viewer toward the positive x-axis, looking straigth on the yz-plane, and
thus produces a 2D projection of the object on the yz-plane. 'view(0, 90)' shows
the figure on a 2D xy-plane.
The following script generates data, plots the curves and obtains different views.
Example:
% clears variables, command window and closes all previous figures
clear; clc; close all
% generates an angle vector with 101 values
a = 0: 3*pi/100 : 3*pi;
% calculates x, y, and z
x = cos(a);
y = sin(a);
z = a;
% divides the figure window into 4 subwindows (2x2)
% plots on the 1st. one
subplot(2,2,1)
plot3(x,y,z)
grid on
title('A helix - 3D view')
xlabel('x = cos(a)')
ylabel('y = sin(a)')
zlabel('z = a')
% plots on the 2nd. subwindow
subplot(2,2,2)
plot3(x,y,z)
axis('square')
% rotates the figure to show only the xy-plane
view(0,90)
grid on
title('A helix, xy-plane')
xlabel('x = cos(a)')
ylabel('y = sin(a)')
zlabel('z = a')
% plots on the 3rd. subwindow
subplot(2,2,3)
plot3(x,y,z)
% rotates the figure to show only the xz-plane
view(0,0)
grid on
title('A helix, xz-plane')
xlabel('x = cos(a)')
ylabel('y = sin(a)')
zlabel('z = a')
% plots on the 4th. subwindow
subplot(2,2,4)
plot3(x,y,z)
% rotates the figure to show only the yz-plane
view(-90,0)
grid on
title('A helix, yz-plane')
xlabel('x = cos(a)')
ylabel('y = sin(a)')
zlabel('z = a')
And the result is:
3D plot – Part 2
The 3D plot functions intended for plotting meshes and surfaces 'mesh' and 'surf',
and their several variants 'meshc', 'meshz', 'surfc', and 'surfl', take multiple
optional input arguments, the most simple form being 'mesh(z)' or 'surf(z)', where
z represents a matrix.
Usually, tridimensional curves are represented by the values of z-coordinates
samples on a grid of (x,y) values. Thus, to create a surface or 3D plot we first
need to generate a grid of (x,y) coordinates and find the height (z-coordinate) of the
surface at each of the grid points. Matlab provides the function 'meshgrid' to create
a grid of points over a specified range.
Meshgrid
Suppose that you want to plot the function z = x2 – 10y + 2 over the domain 0 ≤ x
≤ 4 and 0 ≤ y ≤ 4. To do so, we first take several points in the domain, say 25
points, as shown in this Fig.:
We can create two matrices x and y, each of size 5 x 5, and write the xy-coordinates
of each point in these matrices. We can then evaluate z with the command z = x.^2
– 10*y + 2.
However, creating the two matrices x and y is much easier with the meshgrid
command.
% creates vectors x and y, from 0 to 4
vx = 0 : 4
vy = vx
% creates meshgrid to be used in 3D plot
[x,y] = meshgrid(vx,vy)
The commands shown above generate the 25 points shown in the figure. All we need
to do is generate two vectors, vx and vy, to define the region of interest and
distribution or density of our grid points. Also, the two vectors need not be either
same sized or linearly spaced. It is very important to understand the use of
meshgrid.
Matlab response is as follows:
vx =
0 1 2 3 4
vy =
0 1 2 3 4
x =
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
y =
0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
>>
See the columns of x and the rows of y. When a surface is plotted with the
'mesh(z)' command (where z is a matrix), the tickmarks on the x and y axes do
not indicate the domain of z but the row and column indices of the z-matrix.
Typing 'mesh(x,y,z)' or 'surf(x,y,z)' (where x and y are vectors used by 'meshgrid'
to create a grid), result in the surface plot of z, with x and y values shown along the
respective axes.
The folowing script could be an example of how tho use the 'meshgrid', 'plot3',
'meshc', and 'surfc' commands.
We'll 3D plot the following surface:
with this script:
% clears command window, clears variables and closes figures
clc; clear; close all
% defines vectors x and y
vx = -4 : 0.2: 4;
vy = -3 : 0.2: 3;
% calculates the necessary grid
[x,y] = meshgrid(vx, vy);
% calculates z and avoids a null denominator adding 'eps'
% (eps is the least possible number in Matlab)
z = x .* y .* (x.^2 - y.^2) ./ (x.^2 + y.^2 + eps);
% generates the first figure using 'plot3'
figure
plot3(x,y,z)
grid on
% generates the second figure using 'meshc' to include the
% contour in the figure, and rotates the figure with 'view'
figure
meshc(x,y,z)
view(-37, 15)
% generates the third 3D figure using 'surfc' to include the
% contour in the image, and also rotates the figure with 'view'
figure
surfc(x,y,z)
view(-47, 25)
And the generated results are:
Do you like it?
Use the instruction 'rotate3d on' to manipulate the view angle of your plot. Include
it in your script or type it in the command window to change the view with your
mouse over the figure...
3D plot – Part 3
In this part, we demonstrate the use of the function 'sphere'. We are going to draw
a unit sphere centered at the origin and generated by matrices x, y and z, of size 31
x 31 each.
Just as an excercise, we also add a line going from the center of the sphere to one of
the corners in the figure (within the 3D plot).
Example:
% cleans the workspace
clc; clear; close all
% returns the coordinates of a sphere in three
% matrices that are (n+1)-by-(n+1) in size
[x, y, z] = sphere(30);
plot3(x,y,z)
% keeps the proportions in place and writes appropriate info.
axis('square')
title('Transparent Sphere')
xlabel('x axis')
ylabel('y axis')
zlabel('z axis')
% keeps the above sphere in order to superimpose a line
hold on
% the line goes from (-1, 1, 1) to (0, 0, 0)
a = -1 : .1 : 0;
b = 1 : -.1 : 0;
c = b;
plot3(a, b, c)
% draws the sphere in another format and in another figure
% see what happens if we don't use the axis('square') instruction
figure
mesh(x,y,z)
hold on
plot3(a, b, c)
And the resulting figures are:
3D plot – Part 4
In this example we make a summarization of the use of the following 3D plot
instructions:
• meshgrid
• figure
• contour3
• mesh
• surfc
• surfl
It is better if you've already read Parts 1 to 3. We're plotting exactly the same 3D
data (a function depending on two variables) using several instructions, so the
visualization is pretty different from each other.
Example:
% cleans the memory workspace
clc; clear; close all;
% defines the range of axes x and y
vx = -3 : 0.1 : 3;
vy = vx;
% generates the powerful grid
[x, y] = meshgrid(vx, vy);
% defines the function to be plotted
z = -10 ./ (3 + x.^2 + y.^2);
% opens figure 1 and plots the function using only contours
figure(1)
contour3(x,y,z)
% opens figure 2 and draws the function using a mesh
figure(2)
mesh(x,y,z)
% opens figure 3 and draws the function using surface with contours
figure(3)
surfc(x,y,z)
% opens figure 4 and draws the function using a enlightened surface
figure(4)
surfl(x,y,z)
shading interp
colormap hot
The resulting 3D graphics are:
3D Pie Charts
In Matlab, the expression 'pie3(V)' draws a 3D pie chart using the data in V. Each
element in V is represented as a slice (with a %) in the plot.
Example 1:
p = [3.3 2.6 .69 .4 .3];
pie3(p)
title('Interesting Chart')
results in:
In the expression 'pie3(V, explode, labels)', 'explode' specifies whether to
separate a slice from the center of the plot. V(i,j) is apart from the center of the pie
plot if explode(i,j) is nonzero. 'explode' must be the same size as V. 'labels'
specifies text labels for the slices. The number of labels must equal the number of
elements in V.
Example 2:
d = [1 2 3 2.5];
pie3(d, [1 0 1 0],...
{'Label 1', 'Label 2', 'Label 3', 'Label 4'})
title('Pie Chart showing explosions...')
results in:
3D Simple Animation
In this short article we’re going to experiment with simple animation in 3D. In the first
experiment, we are going to work with a sphere and are going to rotate our view angle
without changing any size. In the second experiment, we’re going to draw a paraboloid,
change its size and rotate. These basic techniques are the foundation of 3D animation
with Matlab.
1. Working with a sphere
In this experiment we’re going to draw a sphere and make sure that the axis box keeps its
proportions correctly. Then, we’re going to rotate our view angle, i.e., the azimuth and
elevation. We are neither moving the sphere itself nor resizing it, we’re just changing our
perspective (angle).
Instruction ‘drawnow’ is used to update the current figure. It ‘flushes the event queue’
and forces Matlab to update the screen.
The code that accomplishes this is the following:
clear; clc; close all
% Draw a sphere
sphere
% Make the current axis box square in size
axis('square')
% Define title and labels for reference
title('Rotation of a sphere...')
xlabel('x'); ylabel('y'); zlabel('z')
% Modify azimuth (horizontal rotation) and update drawing
for az = -50 : .2 : 30
view(az, 40)
drawnow
end
% Modify elevation (vertical rotation) and update drawing
for el = 40 : -.2 : -30
view(30, el)
drawnow
end
So we start with this figure:
and after the two soft rotations we end with an image like this:
2. Working with a paraboloid
In our second experiment, we’re going to work with a paraboloid. We first draw it and
make sure that the axes have the correct fixed sizes for our purposes. We stretch the
figure little-by-little and actually see the change in dimensions. We just update the ‘z’
values within a loop using the function ‘set’ (used to modify the handle graphics
properties). Finally, we rotate the azimuth of the figure to achive another view of the
box. That’s how we achieve this simple animation in 3D.
The code is the following:
clear; clc; close all
% Define paraboloid
X = -2 : .1 : 2; Y = X;
[x, y] = meshgrid(X, Y);
z = .5 * (x.^2 + y.^2);
% Draw 3D figure, keep track of its handle
h = surf(x,y,z);
% Keep axes constant
axis([-2 2 -2 2 0 20])
% Define title and labels for reference
xlabel('x'); ylabel('y'); zlabel('z')
% Stretch paraboloid and show updates
for i = 1 : .1 : 5;
set(h, 'xdata', x, 'ydata', y, 'zdata', i*z)
drawnow
end
% Modify azimuth (horizontal rotation) and update drawing
for az = -37.5 : .5 : 30
view(az, 30)
drawnow
end
We start with this view:
And we end up with this one:
Done!
These are our first experiments with 3D animations.
Quadratic Equations
We are going to create now a Matlab program that calculates the quadratic roots (roots
of quadratic equations). The equation must be in the following form:
ax2 + bx + c = 0, where a, b, and c are real coefficients.
The formula used to calculate the roots is:
Naturally, we have to deliver two x-values.
The m-file that we might use to accomplish this task is very simple:
function x = rqe(a,b,c)
x(1) = (-b + sqrt(b^2 - 4 * a * c))/(2*a);
x(2) = (-b - sqrt(b^2 - 4 * a * c))/(2*a);
We enter the coefficients as parameters when we call the function. We assign to variables
x(1) and x(2) the calculated values using the formula, and the returning result x is a vector
containing x(1) and x(2).
We could use the following Matlab code instead, to return two separate variables:
function [x,y] = rqe2(a,b,c)
x = (-b + sqrt(b^2 - 4 * a * c))/(2*a);
y = (-b - sqrt(b^2 - 4 * a * c))/(2*a);
If we want to compute the roots of the following expression:
2x2 + x - 1 = 0
We can call our function (first code) like this:
x = rqe(2,1,-1)
and we get from Matlab:
x =
0.5000 -1.0000
We can call our second function (second code above) like this:
[m, n] = rqe2(2, 1, -1)
and we get from Matlab:
m =
0.5000
n =
-1
Polygon Area
This program calculates the area of a polygon, using Matlab . You must supply the
x and y coordinates of all vertices. Coordinates must be entered in order of
successive vertices.
The formula used to calculate the area is
area = [(x1+x2)(y1-y2)+(x2+x3)(y2-y3)+ ... +(xn+x1)(yn-y1)]/2
where n is the number of vertices.
Let's assume that we have our vertices in two different vectors, for example
x = [0 1 4 5 7 9 12 14 13 15 15 13 5 4 0];
y = [4 7 8 10 11 10 9 8 4 4 1 0 1 2 4];
Note that the first and last vertices are the same, to close the polygon area. We can
plot this polygon in Matlab very easily.
If we use the instruction 'plot(x, y, '-o')', we obtain the following figure (just to
visualize what we are doing):
If we use the instruction 'area(x,y)', we obtain the following figure (to learn another
way to plot vectors):
Now, we prepare a function with the vertices in input vectors x and y. The output
scalar variable is p_area.
function p_area = area_calc(x,y)
% Get the number of vertices
n = length(x);
% Initialize the area
p_area = 0;
% Apply the formula
for i = 1 : n-1
p_area = p_area + (x(i) + x(i+1)) * (y(i) - y(i+1));
end
p_area = abs(p_area)/2;
We can call the function with a simple line, like this:
a1 = area_calc(x,y)
And we obtain from Matlab:
a1 =
108
It's important to mention that we can save all the code above, since Matlab includes
the built-in function 'polyarea', that we can call in this manner:
a2 = polyarea(x,y)
which produces the same result.
a2 =
108
Another example? Let's execute this code...
x=[0 0 3 3];
y=[0 1 1 0];
a1 = area_calc(x,y)
a2 = polyarea(x,y)
And the result is...
a1 =
3
a2 =
3
... as expected.
Trigonometry (finding parts of a triangle)
This program calculates three unknown parts of a triangle when three parts are
given (basic trigonometry is used). At least one part given must be the length of a
side. We show in this code four possibilities for data entry:
Angle, side, angle
Side, angle, side
Angle, angle, side Side, side, side
Data must be entered in the order it appears in a triangle, either clockwise or
counterclockwise.
We are going to start our Matlab coding with a simple menu for the options
opt = menu('Parts of a Triangle', ...
'Angle Side Angle',...
'Side Angle Side',...
'Angle Angle Side',...
'Side Side Side');
This code launches a menu window with four buttons, one for each option according
to the problem in our trigonometry.
Note that the first string in the menu is used to write any message that we want at
the top. Note also that we can separate long lines of code with the '...' ending.
The value of the option (in this case an integer from 1 to 4) is kept in the 'opt'
variable.
This nice window appears
Then, we can define some useful constants
% Define useful constants
c = pi/180;
ea = 'Enter angle (in degrees): ';
es = 'Enter side: ';
The 'c' value is used as a converter from radians to degrees. All trigonometric
functions in Matlab work in radians by default.
The last strings are used to ask for information from the keyboard. Instead of writing
'input('Enter angle (in degrees): ')' many times along the code, we can define
the string 'ea' and write 'input(ea)', achieving exactly the same result. If we change
the string in the definition, we don't have to change all the other lines that contain
this string.
Then, we use the 'switch statement' to develop all of the options that solve this
problem in trigonometry, case by case.
% Develop all the different cases
switch opt
% Ask for 'angle side angle'
case 1
a(1) = input(ea) * c;
s(3) = input(es);
a(2) = input(ea) * c;
a(3) = pi - a(1) - a(2);
s(1) = s(3) * sin(a(1)) / sin(a(3));
s(2) = s(3) * sin(a(2)) / sin(a(3));
...
If the user choses button 1 in the menu, the code will ask to enter three things from
the keyboard, so this is actually an interactive code. It asks for an angle, then for a
side, and finally for another angle of the triangle under study. Then, the code solves
the problem according to basic trigonometric rules, skips all the other cases and goes
to the final of the program, where the results are displayed...
if min(a) < 0 error('Angles of a triangle cannote be less than zero...')
end
% Show results
disp(' ')
disp('Sides...')
s
disp('Opposite angles...')
a = a/c
The complete code, including the four cases, is as follows:
% Clear memory, clear screen and save empty lines clc; clear;
format compact
% Display menu window
opt = menu('Parts of a Triangle', ...
'Angle Side Angle',...
'Side Angle Side',...
'Angle Angle Side',...
'Side Side Side');
% Define useful constants
c = pi/180;
ea = 'Enter angle (in degrees): ';
es = 'Enter side: ';
% Develop all the different cases
switch opt
% Ask for 'angle side angle'
case 1
a(1) = input(ea) * c;
s(3) = input(es);
a(2) = input(ea) * c;
a(3) = pi - a(1) - a(2);
s(1) = s(3) * sin(a(1)) / sin(a(3));
s(2) = s(3) * sin(a(2)) / sin(a(3));
% Ask for 'side angle side'
case 2
s(3) = input(es);
a(1) = input(ea) * c;
s(2) = input(es);
s(1) = sqrt(s(3)^2+s(2)^2-2*s(3)*s(2)*cos(a(1)));
a(2) = sin(a(1)) * s(2) / s(1);
a(2) = asin(a(2));
a(3) = pi - a(1) - a(2);
% Ask for 'angle angle side'
case 3
a(3) = input(ea) * c;
a(2) = input(ea) * c;
s(3) = input(es);
a(1) = pi - a(2) - a(3);
s(1) = s(3) * sin(a(1)) / sin(a(3));
s(2) = s(3) * sin(a(2)) / sin(a(3));
% Ask for 'side side side'
case 4
s(1) = input(es);
s(2) = input(es);
s(3) = input(es);
a(1) = (s(2)^2 + s(3)^2 - s(1)^2)/(2 * s(2) * s(3));
a(1) = acos(a(1));
a(2) = sin(a(1)) * s(2) / s(1);
a(2) = asin(a(2));
a(3) = pi - a(1) - a(2);
end
if min(a) < 0
error('Angles of a triangle cannote be less than zero...')
end
% Show results
disp(' ')
disp('Sides...')
s
disp('Opposite angles...')
a = a/c
We try it like this: choose the first button on the menu, and answer...
Enter angle (in degrees): 25.7
Enter side: 21.67
Enter angle (in degrees): 33.92
Then, Matlab response is:
Sides...
s =
10.8931 14.0173 21.6700
Opposite angles...
a =
25.7000 33.9200 120.3800
Note that there is one option missing in the menu. The option of 'side side angle' is
not included in the code... Try to develop it yourself. If you can do it then you know
that your Matlab knowledge is becoming great!!!
Good luck!
Matrix decomposition
Matlab includes several functions for matrix decomposition or factorization.
LU decomposition: the name of the built-in function is 'lu'. To get the LU
factorization of a square matrix M, type the command [L,U] = lu(M).
Matlab returns a lower triangular matrix L and an upper triangular matrix U
such that L*U = M.
Example:
Type
M = [2 3 4 5
3 2 6 1
2 3 1 7
9 8 0 2];
[l,u] = lu(M)
l*u
Matlab answer is:
l =
0.2222 1.0000 0.4583 1.0000
0.3333 -0.5455 1.0000 0
0.2222 1.0000 0 0
1.0000 0 0 0
u =
9.0000 8.0000 0 2.0000
0 1.2222 1.0000 6.5556
0 0 6.5455 3.9091
0 0 0 -3.7917
ans =
2.0000 3.0000 4.0000 5.0000
3.0000 2.0000 6.0000 1.0000
2.0000 3.0000 1.0000 7.0000
9.0000 8.0000 0 2.0000
See another example for LU factorization
QR factorization: the name of the appropriate built-in function for this purpose is
'qr'. Typing the command [Q,R] = qr(M) returns an orthogonal matrix Q and an
upper triangular matrix R such that Q*R = M.
Example (assuming the same matrix M as above):
Type
[q,r] = qr(M)
q*r
and the fast Matlab answer is:
q =
-0.2020 0.6359 -0.4469 -0.5959
-0.3030 -0.4127 -0.8144 0.2731
-0.2020 0.6359 0.0027 0.7449
-0.9091 -0.1450 0.3702 -0.1241
r =
-9.8995 -9.0914 -2.8284 -4.5457
0 1.8295 0.7028 6.9274
0 0 -6.6713 -2.2896
0 0 0 2.2595
ans =
2.0000 3.0000 4.0000 5.0000
3.0000 2.0000 6.0000 1.0000
2.0000 3.0000 1.0000 7.0000
9.0000 8.0000 -0.0000 2.0000
Cholesky decomposition: if you have a positive definite matrix A, you can
factorize the matrix with the built-in function 'chol'. The command R = chol(A);
produces an upper triangular matrix R such that R'*R = A for a positive definite
A.
This is a brief reminder of what a positive definite matrix is:
An n by n matrix M is positive definite if
xT
Mx > 0 for all x <> 0 and
xT
Mx = 0 implies x = 0
If matrix M is symmetric, diagonally dominant, and has positive diagonal elements,
then M is positive definite
If matrix M is positive definite, then M is diagonally dominant and has positive
diagonal elements.
Example:
Type
M = [1 1 1 1
1 2 3 4
1 3 6 10
1 4 10 20];
r = chol(M)
r'*r
and Matlab answer is:
r =
1 1 1 1
0 1 2 3
0 0 1 3
0 0 0 1
ans =
1 1 1 1
1 2 3 4
1 3 6 10
1 4 10 20
Singular value decomposition (svd): the name of the built-in function is svd.
Typing [U,S,V] = svd(M); produces a diagonal matrix S, of the same dimension as
M and with nonnegative diagonal elements in decreasing order, and unitary matrices
U and V so that M = U*S*V'.
Example (considering the same matrix M as above):
Type
[u,s,v] = svd(M)
u*s*v'
and you get:
u =
-0.0602 -0.5304 0.7873 -0.3087
-0.2012 -0.6403 -0.1632 0.7231
-0.4581 -0.3918 -0.5321 -0.5946
-0.8638 0.3939 0.2654 0.1684
s =
26.3047 0 0 0
0 2.2034 0 0
0 0 0.4538 0
0 0 0 0.0380
v =
-0.0602 -0.5304 0.7873 -0.3087
-0.2012 -0.6403 -0.1632 0.7231
-0.4581 -0.3918 -0.5321 -0.5946
-0.8638 0.3939 0.2654 0.1684
ans =
1.0000 1.0000 1.0000 1.0000
1.0000 2.0000 3.0000 4.0000
1.0000 3.0000 6.0000 10.0000
1.0000 4.0000 10.0000 20.0000
Singular Value Decomposition (SVD)
Let's suppose that a matrix A is singular. Then, let A be a real m x n matrix of rank r,
with . The Singular Value Decomposition (svd) of A is
A = U S V'
(the apostrophe after a matrix or vector means its transpose) where U is an orthogonal m
x n matrix, S is an r x r diagonal matrix, and V is an n x n square orthogonal matrix.
Since U and V are orthogonal, then
UU' = I and VV' = I
That is, the transpose of each matrix is equal to its inverse. The elements along the
diagonal of S, labelled , are called the singular values of A. There are r such singular
values and they satisfy
If the matrix A is square, then we can use the singular value decomposition to find the
inverse, which is is
A-1
= (USV')-1
= (V')-1
S-1
U-1
= VS-1
U'
since (AB)-1
= B-1
A-1
, UU' = I, and VV' = I.
If A is a square matrix then
And so,
If an SVD of a matrix A can be calculated, so can be its inverse. Therefore, we can find a
solution to a system
Ax = b x = A-1
b = VS-1
U'b
that would otherwise be usolvable.
Example:
Let's find with Matlab the singular value decomposition of
A = [ 0 -1
-2 1
1 0]
We simply type:
[U,S,V] = svd(A)
and the above operation produces a diagonal matrix S, of the same dimension as A and
with nonnegative diagonal elements in decreasing order, and unitary matrices U and V so
that A = U*S*V'.
The Matlab answer is:
U =
-0.1826 -0.8944 0.4082
0.9129 0.0000 0.4082
-0.3651 0.4472 0.8165
S =
2.4495 0
0 1.0000
0 0
V =
-0.8944 0.4472
0.4472 0.8944
>>
We can confirm the values of UU', VV' and USV, by executing these instructions in
Matlab
U*U'
V*V'
U*S*V
The confirming responses are:
ans =
1.0000 -0.0000 -0.0000
-0.0000 1.0000 -0.0000
-0.0000 -0.0000 1.0000
ans =
1 0
0 1
ans =
-0.0000 -1.0000
-2.0000 1.0000
1.0000 0.0000
>>
Geometric mean and geometric deviation
This program computes the geometric mean and geometric deviation of a set of
data. We obtain the results in two ways, using iterations and available vectorized
operations in Matlab.
The geom. mean is given by this formula
this means that it is the nth-root of the product of all the elements being considered.
n is the number of elements in the set.
The geom. deviation is given by this formula
where q is a sum including the natural logarithms of the elements in the set.
We can use iterations to calculate what we need. In Matlab, this is not the most
efficient way to do it, but we can implement the same algorithm in other
languages...
function [gm, gd] = geo_mean_dev(x)
% Take into account the number of elements in the vector
n = length(x);
% Initialize some variables
gm = 1;
q = 0;
% Iterate through all of the elements
for i = 1 : n
d = x(i);
% Compute mean
gm = gm * d^(1/n);
% Accumulate intermediate term for deviation
q = q + log(d)^2;
end
% Compute deviation
gd = abs(exp(sqrt(q/(n-1)-(n/(n-1)*(log(gm))^2))));
We can test our function as follows (from the command window or from another
script):
x = [3 5 8 3 7 2];
[gm1, gd1]= geo_mean_dev(x)
Matlab response is
gm1 =
4.1407
gd1 =
1.7237
We can also use the vectorized form to make it easier and faster...
(note that the 'log' function performs the natural logarithm of a number, while the
'log10' function performs the log in base 10)
n = length(x);
% The 'prod' function gets the multiplication of all the elements
gm2 = prod(x)^(1/n)
% The 'sum' function gets the sum of the vector
q = sum(log(x).^2);
% and now we can imlement the last formula
gd2 = exp(sqrt(q/(n-1)-(n/(n-1)*log(gm2)^2)))
Again, Matlab response is
gm2 =
4.1407
gd2 =
1.7237
Interpolation
This page shows the most usual and general interpolation concept. This code
calculates the y-coordinates of points on a line given their x-coordinates. It is
necessary to know coordinates of two points on the same line.
The point is interpolated using the following formula:
We can develop then the following Matlab function. Input parameters are the two
known coordinates and the desired x-value to interpolate. Note that with this formula
we can also extrapolate a coordinate on the same line.
function y = interpolate(x1, y1, x2, y2, x)
% Calculate corresponding y-coordinate
y = y1 + (y2-y1)/(x2-x1) * (x-x1);
Let's assume that our known coordinates are (60, 15.56) and (90, 32.22), and our x-
values to be interpolated are 73 and 85.6.
Now, we can use the above function, for example calling it like this:
y = interpolate(60, 15.56, 90, 32.22, 73)
y = interpolate(60, 15.56, 90, 32.22, 85.6)
Matlab response is:
y =
22.7793
y =
29.7765
Fortunately, Matlab has also several built-in function to interpolate values with
different methods ('interp1', 'interp2', 'interp3', and 'interpn').
'interp1' is called one dimensional interpolation because vector y depends on a
single variable vector x. The calling syntax is
ynew = interp1(x, y, xnew, method)
The parameter 'method' can be 'nearest', 'linear', 'cubic' or 'spline'. The default
method is 'linear' (type help interp1 on the Matlab command window to see more
details).
We can use this function (instead of our own developed function above), like this:
x = [60 90];
y = [15.56 32.22];
xnew = 73;
ynew = interp1(x, y, xnew)
xnew = 85.6;
ynew = interp1(x, y, xnew)
And Matlab response is:
ynew =
22.7793
ynew =
29.7765
Lagrange Interpolation (curvilinear interpolation)
The computations in this small article show the Lagrange interpolation. The code
computes y-coordinates of points on a curve given their x-coordinates. You must enter
coordinates of known points on the curve, no two having the same abscissa.
This is the simple function:
function y0 = lagrange_interp(x, y, x0)
% x is the vector of abscissas.
% y is the matching vector of ordinates.
% x0 represents the target to be interpolated
% y0 represents the solution from the Lagrange
interpolation
y0 = 0;
n = length(x);
for j = 1 : n
t = 1;
for i = 1 : n
if i~=j
t = t * (x0-x(i))/(x(j)-x(i));
end
end
y0 = y0 + t*y(j);
end
Example 1
Consider the curve y = x3 - 3x + 3. We now that points
x = [-3 -2 -1 0 1 2 3];
y = [-15 1 5 3 1 5 21];
are on the curve. What are the values of y when x = -1.65 and 0.2?
x1 = -1.65;
y1 = lagrange_interp(x,y,x1)
x2 = .2;
y2 = lagrange_interp(x,y,x2)
The result are: y1 = 3.4579
y2 = 2.4080
Let’s plot our approach:
plot(x, y, 'bo', x1, y1, 'ro', x2, y2, 'ro')
axis([-4 4 -17 23])
title(‘y = x^3 – 3x + 3’)
xlabel(‘x’)
ylabel(‘y’)
Example 2
Given the following points from a sine curve, what are the y-values for x = -2,47 and
1.5?
x = [-5 -4 -3 -2 -1 0 1 2 3 4 5];
y = [.958 .757 -.141 -.909 -.841 0 .841 .909 .141 -.757 -
.959];
x3 = -2.47;
y3 = lagrange_interp(x,y,x3)
x4 = 1.5;
y4 = lagrange_interp(x,y,x4)
The results are:
y3 = -0.6218
y4 = 0.9972
And our plot is:
plot (x, y, 'bo', x3, y3, 'ro', x4, y4, 'ro')
title('sin(x)')
xlabel('x')
ylabel('y')
Not bad, right?
Linear Regression
This program fits a straight line to a given set of coordinates using the method of
least squares ( linear regression ). The coefficients of the line, coefficient of
determination, coefficient of correlation and standard error of estimate are
calculated. Once the line has been fitted, you may predict values of y for given
values of x.
We develop the following Matlab code (note that Matlab has its own built-in functions
to make linear regression easier for all of us, but we'd like to show a step-by-step
way to do it, to understand the inner concepts):
function [y0, a, b, r2, r, k2] = lin_reg(x, y, x0)
% Number of known points
n = length(x);
% Initialization
j = 0; k = 0; l = 0; m = 0; r2 = 0;
% Accumulate intermediate sums
j = sum(x);
k = sum(y);
l = sum(x.^2);
m = sum(y.^2);
r2 = sum(x.*y);
% Compute curve coefficients
b = (n*r2 - k*j)/(n*l - j^2);
a = (k - b*j)/n;
% Compute regression analysis
j = b*(r2 - j*k/n);
m = m - k^2/n;
k = m - j;
% Coefficient of determination
r2 = j/m;
% Coefficient of correlation
r = sqrt(r2);
% Std. error of estimate
k2 = sqrt(k/(n-2));
% Interpolation value
y0 = a + b*x0;
If we have the following data available (where every yi has its correspondent xi):
x = [71 73 64 65 61 70 65 72 63 67 64];
y = [160 183 154 168 159 180 145 210 132 168 141];
we can call the function above in this manner (to obtain interpolated values for x =
70 and x = 72):
[y0, a, b, r2, r, k2] = lin_reg(x, y, 70)
[y0] = lin_reg(x, y, 72)
And Matlab response is:
y0 =
176.5139
a =
-106.7917
b =
4.0472
r2 =
0.5563
r =
0.7458
k2 =
15.4135
y0 =
184.6083
We can use the 'polyfit' and 'polyval' instructions in Matlab for this purpose, like
this:
a = polyfit(x,y,1)
y0 = polyval(a,70)
y0 = polyval(a,72)
Fitting a straight line through the data means thet we want to find the polynomial
coefficients of a first order polynomial such that a1xi + a0 gives the best
approximation for yi. We find the coefficients with 'polyfit' and evaluate any xi with
'polyval'.
Matlab result is
a =
4.0472 -106.7917
y0 =
176.5139
y0 =
184.6083
confirming our previous results.
Numerical Derivative
We are going to develop a Matlab function to calculate the numerical derivative of
any unidimensional scalar function fun(x) at a point x0. The function is going to have
the following functionality:
Usage: D = Deriv(fun, x0)
fun: name of the unidimensional scalar function
(string)
x0: point of interest (scalar)
D: derivative of fun at x0 (scalar)
As you may remember, the very well known way to analytically derivate any function
is:
This roughly means that we have to find the value of the function in two very close
values (one of them is the point of interest), get the difference of those values and
divide it by the displacement of the independent variable. In other words,
First step:
Find , where is a very small value compared to x.
Second step:
Obtain the difference .
Third step:
Divide the result above by .
The result is the numerical derivative of your function.
We can implement this algorithm very easily in Matlab, in this way:
function D = Deriv(fun, x0)
% |delta| is relative to |x0| delta = x0 / 1000;
if x0 == 0
% avoids delta = 0 (**arbitrary value**)
delta = 1e-12;
end
f1 = feval ( fun, x0 + delta );
f2 = feval ( fun, x0 - delta );
D = (f1 - f2) / (2 * delta);
Note, that we are really evaluating
which should be the same as explained above, since the displacement is almost zero. You
can try both options.
Function 'feval' evaluates a given function (the string in the parameter fun) in a specific
value (number in second parameter of 'feval').
Now, let's try our derivative function. We create a function in a separate m-file:
function y = inverse(x)
y = 1/x;
And we can call it like this:
Deriv('inverse', 1)
The result is:
Expected: -1 Obtained: -1.0000
Deriv('inverse', 5)
The result is:
Expected: -0.04 Obtained: -0.0400
We can save another totally arbitrary (unidimensional scalar) function in a different m-
file:
function y = myfun(x)
y = 3*x^2 + 2*x;
And we can perform the derivative in several ways...
f = 'myfun'
x = 0
Deriv(f, x)
The result is:
Expected: 2 Obtained: 2
x = 5
Deriv(f, x)
The result is:
Expected: 32 Obtained: 32.0000
Deriv(f, -3)
The result is:
Expected: -16 Obtained: -16.0000
Gradient
We are going to include the concepts in our Derivative function created before, to
develop a Matlab function to calculate the gradient of a multidimensional scalar
function. The function is going to have the following functionality:
% Usage: g = Grad(fun, x0)
% fun: name of the multidimensional scalar function
% (string). This function takes a vector argument of
% length n and returns a scalar.
% x0: point of interest (vector of length n)
% g: column vector containing the gradient of fun at x0. The
% size(g) = size(x)
function g = Grad(fun, x0)
% |delta(i)| is relative to |x0(i)|
delta = x0 / 1000;
for i = 1 : length(x0)
if x0(i) == 0
% avoids delta(i) = 0 (**arbitrary value**)
delta(i) = 1e-12;
end
% recovers original x0
u = x0;
u(i) = x0(i) + delta(i);
% fun(x0(i-1), x0(i)+delta(i), x0(i+1), ...)
f1 = feval ( fun, u );
u(i) = x0(i) - delta(i);
% fun(x0(i-1), x0(i)-delta(i), x0(i+1), ...)
f2 = feval ( fun, u );
% partial derivatives in column vector
g(i,1) = (f1 - f2) / (2 * delta(i));
end
We can try this algorithm, creating a function bowl (which includes two variables) in
an separate m-file, as follows:
function y = bowl(x)
y = (x(1)-6)^2 + (x(2)-4.5)^4 / 25;
Then, we can test it from the command window:
x = [0 0]
f = 'bowl'
Grad(f, x)
Expected: [-12 -14.58]' Obtained: [-12.0011 -14.5803]'
x = [1 1]
Grad(f, x)
Expected: [-10 -6.86]' Obtained: [-10.0000 -6.8600]'
x = [6 4.5]
Grad(f, x)
Expected: [0 0]' Obtained: [0 0]'
x = [2 1.5]
Grad(f, x)
Expected: [-8 -4.32]' Obtained: [-8.0000 -4.3200]'
Now, another test with a different multivariable function:
function y = semirosen(x)
y = 100 * ( x(2) - x(1)^2 ) + ( 1 - x(1) )^2 ;
x = [0 0]
f = 'semirosen'
Grad(f, x)
Expected: [-2 100]' Obtained: [-2.0001 100.0000]'
x = [1 1]
Grad(f, x)
Expected: [-200 100]' Obtained: [-200.0000 100.0000]'
x = [9 15]
Grad(f, x)
Expected: [-1784 100]' Obtained: 1.0e+003 *[-1.7840 0.1000]'
Trapezoidal Rule
This code approximates the definite integral of a function. The integral is calculated
using the trapezoidal rule. Parameters of the function are the limits of
integration and the number of intervals within the limits.
The function to be integrated is another parameter and must be defined before
running this program. For example, if we want to integrate the function f(x) = y =
x3, we can define it, in Matlab, like this:
function y = fun_for_integration(x)
y = x^3;
And then, we can create the integration function, like this:
function y = trap2(lower_lim, upper_lim, interv, fun)
% initialize the result
y = 0;
% 'step' is related to the size of each interval
step = (upper_lim - lower_lim) / interv;
% add up the area of each trapezoid
for j = lower_lim : step : upper_lim
y = y + feval(fun,j);
end
% compute integral
y = (y - (feval(fun, lower_lim) + feval(fun, upper_lim))/2) * step;
Now, we can call our integration function from another Matlab script or from the
command window, for example
z1 = trap2(0, 2, 10, 'fun_for_integration')
z2 = trap2(0, 2, 100, 'fun_for_integration')
z3 = trap2(0, 2, 1000, 'fun_for_integration')
and we get the Matlab results
z1 =
4.0400
z2 =
4.0004
z3 =
4.0000
Note that this is a numerical integration, and so we have to be very aware of the
possible inaccuracies of the method. The first two parameters given to the function
are the lower and upper limits, respectively. The third parameter is related to the
size of each interval: the higher the number the better accuracy in the evaluation we
can reach. The fourth parameter is the name of the function to be integrated (the
instruction 'feval' is in charge of evaluating that function in the main body of the
code).
Now, the best part is that Matlab has its own function to do the integration using the
trapezoidal rule ('trapz'), so we can save all of our programming thinking for other
things...
However, the built-in 'trapz' function, works a little different. We first define our
interval and desired step in a variable vector x, and define the value of the
corresponding function in a variable vector y.
For example, we want to evaluate the same function as above, within the interval
[0 2], in 0.1 increments, so we use x = 0 : .1 : 2. If we want a finer tunning of the
integration function, we can set the step in our independent variable. Then we can
call the Matlab function like this (three different cases)
x = 0 : .1 : 2;
y = x.^3;
z4 = trapz(x, y)
x = 0 : .01 : 2;
y = x.^3;
z5 = trapz(x, y)
x = 0 : .001 : 2;
y = x.^3;
z6 = trapz(x, y)
and we get the Matlab response, with different approximations
z4 =
4.0100
z5 =
4.0001
z6 =
4.0000
Simpson's Rule
This code approximates the definite integral of a function. The integral is
calculated using Simpson's rule.
You must supply the limits of integration, the increment between points within
the limits, and the function of the curve to be integrated.
For example, if we want to integrate the function f(x) = y = x3, we can define it, in
Matlab, like this:
function y = fun_for_integration(x)
y = x^3;
And then, we can create the actual integration function, like this:
function y = simpson2(lower_lim, upper_lim, incr, fun)
% Check that the provided increment has sense for our purpose
if (upper_lim - lower_lim)/incr ~= floor((upper_lim - lower_lim)/incr)
disp('Warning: increment must divide interval into equal subintervals')
disp('Please change the increment')
y = 'error';
return
end
% Evaluate the function in the lower and upper limits
y1 = feval(fun, lower_lim);
y2 = feval(fun, upper_lim);
% Initialize the intervals
c = 0;
d = 0;
% Loop for each subinterval
for i = 1 : (upper_lim - lower_lim)/incr - 0.5;
% Calculate the function at each subinterval
y = feval(fun, lower_lim + i*incr);
% Interval even or odd?
if i/2 == floor(i/2)
% Sum all even-interval function values
d = d + y;
continue
else
% Sum all odd-interval function values
c = c + y;
continue
end
end
% Calculate integral
y = incr/3 * (y1 + 4*c + 2*d + y2);
Now, we can call our integration function from another Matlab script or from the
command window, for example
z1 = simpson2(0, 2, .01, 'fun_for_integration')
z2 = simpson2(0, 2, .2, 'fun_for_integration')
and we get the Matlab results, which in this case are the same
z1 =
4.0000
z2 =
4
Note that this is a numerical integration, and so we have to be very aware of the
inaccuracies of the Simpson's Rule method. The first two parameters given to the
function are the lower and upper limits, respectively. The third parameter is related
to the size of each interval. The fourth parameter is the name of the function to be
integrated (the instruction 'feval' is in charge of evaluating that function in the main
body of the integration code).
Now, the best part is that Matlab has its own function to do the integration using the
Simpson's rule ('quad'), so we can save all of our programming efforts for other
things...
However, the built-in 'quad' function, works a little different. It integrates a specified
function over specified limits, based on adaptive Simpson's rule. This adaptive
rule attempts to improve accuracy by adaptively selecting the size of the subintervals
(instead of keeping it constant) within the limits of integration while evaluating the
sums that make up the integral.
You can call this 'quad' function, like this
z = quad('fun_for_integration', 0,2)
and Matlab response is
z =
4
Now, let's integrate another function. Let's work on this:
First, we define the function to be integrated in Matlab, in this way
function y = fun_for_integration2(x)
y = exp(-x.^2);
Then, we can call the 'quad' function from another script or try it from the Matlab
command window, like this
z = quad('fun_for_integration2', 0.5, 1.5)
The Matlab result is
z =
0.3949
Prime Factors
This program lists the prime factors (PFs) of an integer. It will test neither 0 nor 1.
It is well known that PFs of a positive integer are the primes that divide into that
integer exactly, without leaving a remainder. The process of finding these numbers
is called integer factorization, or prime factorization.
Here’s the full Matlab script:
% Clears variables and screen clear; clc
% Asks user for input z = input('Enter your positive number: ');
% Loops to test all integers (2 through z) as PFs for i = 2 : z
s = 0;
% Is z/i an integer? Is the remainder 0? while z/i == floor(z/i)
z = z/i;
s = s + 1;
end
% A PF is found and displayed if s > 0
str = [num2str(i) '^' num2str(s)];
disp(str)
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits if z == 1
break end end
end
Example 1:
What are the prime factors of 49?
Run the code above and enter your number…
Enter your positive number: 90
Matlab answer is
2^1
3^2
5^1
This means that 90 = 2 x 32 x 5
Example 2:
Enter your positive number: 390
2^1
3^1
5^1
13^1
This means that 390 = 2 x 3 x 5 x 13
Matlab has at least 3 built-in functions related to PFs.
a) 'factor(x)' returns a vector containing the PFs of x. For example:
factor(390), results in
ans =
2 3 5 13
b) 'primes(x)' is a row vector of the primes less than or equal to x. For example:
primes(10), results in
ans =
2 3 5 7
c) 'isprime(x)' is true for prime numbers. For example:
isprime(10) results in
ans =
0
Euclidean Algorithm
This program calculates the Greatest Common Denominator (GCD) of two integers. It
is based on the Euclidean algorithm for finding the GCD.
Basic Algorithm - Flow chart
This is the full Matlab program that follows the flow-chart above, without using the built-
in 'gcd' instruction.
% Clears screen and deletes all the variables in the workspace
clear; clc
% Asks the user for input and takes only positive numbers into account
a = input('First number: ');
b = input('Second number: ');
a = abs(a);
b = abs(b);
% This is the real trick, normally performed a number of times
r = a - b*floor(a/b);
% Repeats the operation until updates of a equal updates of b
while r ~= 0
a = b;
b = r;
r = a - b*floor(a/b);
end
% Displays the result
GCD = b
Example 1:
Find the greatest common denominator of 18 and 50.
Run the algorithm above and enter data:
First number: 18
Second number: 50
GCD =
2
The built-in Matlab command 'gcd' also works on vectors. For example:
a = [50 150 20]
b = [18 115 5]
>> gcd(a,b)
ans =
2 5 5
Coordinate conversion: polar-to- cartesian and cartesian-to-polar
This couple of Matlab functions convert the coordinates of a point given in Cartesian
coordinates to polar coordinates, and vice versa.
When we use the polar-to-cartesian function, we enter a magnitude and an angle in
degrees as parameters. The function returns a real number (x) and a complex number
(y value).
When we use the cartesian-to-polar function, we enter a complex value as parameter.
The function returns a magnitude, an angle in radians and an equivalent angle in
degrees.
The formulas for the conversions are:
where:
x = abscissa
y = ordinate
r = magnitude
angle
These are the functions:
function [x,y]= polar2cart (mag, ang_in_deg)
x = mag * cos(ang_in_deg*pi/180);
y = j * mag * sin(ang_in_deg*pi/180);
function [r, ar, ad] = cart2polar(x)
r = abs(x);
ar = angle(x);
ad = ar*180/pi;
And now we test them:
% Clear memory and screen. Avoid double-blank lines
clear; clc; format compact
[x, y] = polar2cart(2, 30.5)
[r, ar, ad] = cart2polar(7 + 18i)
[r, ar, ad] = cart2polar(0 - 46.8i)
The results are:
x = 1.7233
y = 0 + 1.0151i
r = 19.3132
ar = 1.1999
ad = 68.7495
r = 46.8000
ar = -1.5708
ad = -90
Data Analysis - reading text files and processing them with Matlab
In this article, we're going to read text files with Matlab, perform data analysis or
processing, and finally we are going to write out our results to another text file. The
procedure is easily adaptable to many situations.
Let's assume that we have 3 text files (it could be hundreds). They all have to have
the same format, and have to have a basic file name, with numbered tag endings
(otherwise it is harder to automate the reading process).
For example, we have files 'data_sheet1.txt', 'data_sheet2.txt' and 'data_sheet3.txt'.
So, the basic file name is 'data_sheet'; then, the numbered tag is 1, 2 or 3,
respectively, and they all end with the '.txt' extension.
Let the content for each file be something simple, for example, for 'data_sheet1.txt'
the hypothetical content is:
dummy line 1
dummy line 2
dummy line 3
1 1234
2 2345
3 4320
4 4567
5 9876
This file has four text lines (three dummy lines and one blank line) at the beginning,
and then the real data in two columns.
In our case, the content for 'data_sheet2.txt' is:
dummy line 1
dummy line 2
dummy line 3
1 12340
2 23452
3 43203
4 45674
5 98765
and the content for 'data_sheet3.txt' is
dummy line 1
dummy line 2
dummy line 3
1 123
2 234
3 432
4 456
5 987
Note that all the three files have four text lines at the beginning and all of them have
the relevant data in the same format, with the same number of elements (two
columns and five rows). The number of columns or rows is not relevant for our
purpose, but the files have to keep the same format or structure.
We are going to use Matlab functions 'fopen', 'textscan' and 'num2str' to read data
from all those '.txt' files (it's a good idea if you investigate those three functions a
little bit, but I'll give you the recipe).
We are not interested in the four text lines at the beginning of the files, and we want
to read the first column of the first file (which is the same for all the files, let's say
for identification purposes) and the second column of each of the files, so, we want
to end with something like
1 1234 12340 123
2 2345 23452 234
3 4320 43203 432
4 4567 45674 456
5 9876 98765 987
In this way, we now have the information in one matrix, and we can do data analysis
thereafter.
This is the function that I propose to read the files. You have two input parameters
(the base file name and the number of files to read) and one output (one cell array
with your relevant data). Fair, isn't it?
To automatically change the name of the file we use an array in this form:
[BaseFile num2str(i) '.txt']
This array concatenates the string BaseFile name (input parameter) with a counting
number (by changing the iteration counter into a string), and then concatenates the
'.txt' extension.
For the first file, the idea can be replaced by:
[BaseFile '1' '.txt'], or better [BaseFile '1.txt']
The full code would be:
function R = get_data(BaseFile, n) % Open the first file d(1) = fopen([BaseFile '1.txt']); % Read the first two columns, skip the first 4 headerlines R = textscan(d(1), '%f %f', 'headerLines', 4); % Close the file, you don't need it any longer fclose(d(1));
for i = 2 : n
% Open consecutively each of the remaining files d(i) = fopen([BaseFile num2str(i) '.txt']);
% Skip the first column of the new file (an '*' to do this) %
and keep on building the array R = [R textscan(d(i), '%*f %f', 'headerLines', 4)]; % Close the file fclose(d(i)); end
You end with your data in cell array R. Instruction 'textscan' produces a cell array
(not an ordinary array) so you have to alter this (only if necessary).
How are you going to use the above function to read text files and process data from
Matlab?
This is one suggestion. You may process it the way you want...
% Reset your memory and clear your screen clear; clc
% Provide base file name and number of files to be read BaseFile = 'data_sheet';
n = 3;
% Use the developed function to read data R = get_data(BaseFile, n);
% Transform your cell array into an ordinary matrix my_data = R{1}; for i = 2 : n+1
my_data = [my_data R{i}]; end
% Show your data my_data
At this point 'my_data' is a matrix that has the information as you need it (exactly as
shown before).
You can study it, or plot it or perform data analysis of any kind...
% Calculate the average of all of the columns and show my_average = mean(my_data) % Calculate the standard deviation for each column my_std = std(my_data) % Calculate the maximum my_max = max(my_data) % Calculate the minimum my_min = min(my_data)
% Arrange your information to be saved my_results = [my_average' my_std' my_max' my_min']
% Save your my_results matrix in file 'data.txt' save data.txt -ascii my_results
Done! Now, you have a text file with your data analysis or processed information.
Matlab GUI - Basics (Hello World!)
We are going to develop a simple Matlab GUI. We’ll use the Matlab GUIDE
(Graphical User Interface Development Environment) which is pretty handy...
This article is a super-fast introduction, but very convenient because with some
ingenuity you can learn it in 10 minutes... or so.
Let’s start the ride! On the command window type
>> guide
This will open the ‘Quick Start’ window, where you can study or review their
examples, too! For the moment, please follow me and select the fist option: ‘Blank
GUI (Default)’.
Then, an untitled figure will pop-up. You have some components on the left menu,
which you can drag onto your interface.
In this example we are going to use only two ‘push buttons’ and one ‘static text’.
Drag and drop a ‘static text’ onto your Matlab GUI. You can reduce or increase the
size of your interface window by dragging its low-rigth corner, as it’s done in other
drawing programs.
Double click on this ‘static text’ and a ‘Property Inspector’ window will appear.
Scroll down and look for the ‘String’ property and delete what's in there. For the
moment we want it to be blank.
Then, make the ‘Tag’ property to be ‘output_line’. You can use whatever name you
want, but ‘output_line’ seems good to me... (hehehe)
Your windows must look similar to what I’m showing here:
Then, drag-and-drop a ‘push button’ onto your interface. Modify its ‘String’
property to read ‘Launch Message’. Let its ‘Tag’ property intact. You could change
this tag... it’s the name or identifier of the object as it’s going to be recognized in the
rest of the code.
Your windows must look similar to what I’m showing here:
Drag-and-drop another ‘push button’. Modify its ‘String’ property to read ‘Clear
Message’ and leave its ‘Tag’ as it is. You’ll produce these results.
Now, rigth-click on the ‘Launch Message’ button and choose ‘View Callbacks’ ->
‘Callback’
You’ll be asked to save your figure. A good name (only my suggestion) is
hello_world.fig... use the name that you like.
You’ll be taken to the Matlab code (in the editor window) that will drive your
interface. Matlab has automatically created functions related to your components.
You have to make the final touches... For the moment, don’t care about the many
lines automatically created. Just focus on what we need to do.
The ‘Callback’ functions are the instructions that will be executed when the user
pushes the buttons or does something with the components that you have included
in your Matlab GUI. In this case, you’ll see something like this code.
% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MAT
% handles structure with handles and user data (see GUIDATA)
A ‘set’ instruction sets the properties of the elements that you indicate. Do you
remember that you have a ‘static text’ with the tag (identifier) ‘output_line’? We
are going to modify it when the user pushes the button with the string ‘Launch
Message’. This is accomplished with the instruction
set(handles.output_line,'String','Hello World!!')
The first parameter is the object (component) that you’re going to modify. It
starts with ‘handles.’. The second argument is the object’s property that you’re
going to modify, and in this case is the ‘String’ property. The third argument is
the value that you want to assign to the property.
So, the result is that when the user presses the ‘Launch Message’ button, a
message reading ‘Hello World!!’ will appear in the ‘output line’ (officialy named
‘handles.output_line’). Add this single line to the code, so that it looks like this:
% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MAT
% handles structure with handles and user data (see GUIDATA) set(handles.output_line,'String','Hello World!!')
We’ll do something similar to the ‘callback’ corresponding to the ‘Clear Message’
button. So change this original code...
% --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) % hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MAT
% handles structure with handles and user data (see GUIDATA)
into this...
% --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) % hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MAT
% handles structure with handles and user data (see GUIDATA) set(handles.output_line,'String','')
The result is that when the user presses the ‘Clear Message’ button, a blank
message will appear in the ‘output line’ (officialy named ‘handles.output_line’).
Magic is about to happen!
Now, run your interface by clicking the ‘run’ icon at the top of the editor window...
and... presto! a ‘hello_world’ window has appeared! It’s your first Matlab GUI!
Try, it! Press the ‘Launch Message’ button... and an interesting message appears...
then, press the ‘Clear Message’ button...
Well done! You did it!
So, let’s summarize:
You can drag-and-drop your components onto your graphic interface to start
your Matlab GUI.
Matlab will automatically create callback-functions, related to the buttons or other components that you include.
The ‘set’ instruction assigns values to properties of the elements that you want to modify. The general format is:
set(handles.tag_of_your_component, 'Property', value)
Matlab GUI – Callback function
In this article we’re going to build-up a simple adder. Our adder (by means of relevant
callback function) is going to have two ‘edit text’ components, two ‘static text’
components, and one ‘push button’ element.
I strongly recommend you to review the first article of this series, if you haven’t done so.
I explain there how to add elements to your interface, and how to use the built-in function
‘set’.
Let’s start... Open your guide (graphical interface environment) by typing on the
command window:
>> guide
Choose the default option (blank GUI).
Add (drag) two ‘edit text’ boxes (which will be your inputs), two ‘static text’ boxes (one
will be just an equal sign and the other will be the output), and add a ‘push button’
(which will be the ‘+’ sign, as in a calculator).
Resize your elements, figure and window as necessary (by dragging their anchors on the
corners). You must end-up having something similar to this:
Now, double-click on each element, look and modify their properties as indicated on this
table:
Component HorizontalAlignment String Tag
Top Edit Text right 0 edit1
Bottom Edit Text right 0 edit2
Left Static Text center = text1
Rigth Static Text right 0 result
Push-button center + pushbutton1
You must now have something similar to this (save it with any name, for example:
adder.fig):
Before we develop the code for this interface, we must mention that there are three very
important instructions when working with GUIs: ‘get’, ‘guidata’, and ‘set’.
The ‘get’ instruction, gets the string value from an input component. For example, if we
want to get the number that the user inputs in ‘edit1’, we can do it like this (preceed the
identifier tag with ‘handles.’):
get(handles.edit1, 'String')
However, this instruction gets a string, not a number; thus, if we need to numerically
manipulate that value, we have to transform it into a number first. For example,
something typical is:
num = str2double(get(handles.edit1,'String'));
Now, our variable ‘num’ does contain a number (double), and we can manipulate it.
Finally, we must update the value of the component and keep that variable in our
memory-workspace (using the ‘guidata’ instruction) to be used in other callback
functions. We can achieve it by doing this:
handles.edit1 = num;
guidata(hObject,handles)
Generally speaking, we need to finish every callback function with
guidata(hObject,handles)
in order to maintain in memory the values of the variables.
The ‘set’ instruction sets the properties of the element that you indicate. The property
‘Tag’ is the identifier to use for this purpose. Do you remember that you have one ‘static
text’ with the tag (identifier) ‘result’? We are going to modify it when the user pushes
the button with the string ‘+’. This is to be accomplished with the instruction
set(handles.output_line,'String',value)
where ‘value’ contains the addition edit1 + edit2
We have to take care about two more things:
What if the user doesn’t enter numbers in the edit boxes?
Do we need an initialization procedure to make sure everything is in order
before the user uses our GUI?
To modify the Matlab code for the components displayed in your interface, right-click on
any of them and choose ‘View Callbacks’ -> ‘Callback’. You will be taken to the
corresponding m-file (there are many automatically written lines, just add the new ones).
We can test for the input value from the user. Let’s check the code for the callback
function related to ‘edit1’:
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version
of MLB
% handles structure with handles and user data (see
GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as
text
% str2double(get(hObject,'String')) returns contents
of
% edit1 as a double
num = str2double(get(hObject,'String'));
if isnan(num)
num = 0;
set(hObject,'String',num);
errordlg('Input must be a number', 'Error')
end
handles.edit1 = num;
guidata(hObject,handles)
In this callback function, we first read the input from the user and transform it to a
number (since we are within the edit1_Callback, using get(handles.edit1,’String’) is the
same as using get(hObject,'String')).
Then, we use the ‘isnan’ (for IS Not A Number) to launch an error message if the value
is not a number, and set the value to 0, too. Finally, we keep the corresponding numerical
value in the variable ‘edit1’ (officially recognized by Matlab as ‘handles.edit1’).
We can do the same thing for the 'edit2' callback function (you only need to add the last 8
lines):
function edit2_Callback(hObject, eventdata, handles)
% hObject handle to edit2 (see GCBO)
% eventdata reserved - to be defined in a future version
of MLB
% handles structure with handles and user data (see
GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as
text
% str2double(get(hObject,'String')) returns contents
of
% edit2 as a double
num = str2double(get(hObject,'String'));
if isnan(num)
num = 0;
set(hObject,'String',num);
errordlg('Input must be a number', 'Error')
end
handles.edit2 = num;
guidata(hObject,handles)
And, since the values are kept in memory due to the 'guidata' instruction used in both
callback functions (in variables handles.edit1 and handles.edit2), we can easily code the
section for the push-button, like this (you have to add only the last two lines):
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version
of MLB
% handles structure with handles and user data (see
GUIDATA)
addition = handles.edit1 + handles.edit2;
set(handles.result, 'String', addition);
Bingo! We’re almost done!
We need to consider the initialization part. What if the user press the ‘+’ button without
entering any data? Will everything work fine?
Unfortunately not. ‘edit1’ and ‘edit2’ don’t have zero values, they display a ‘0’ string
(not a number). So, if the user press the ‘+’ button without entering any data, your GUI
will display a number, but nothing to do with the expected numerical 0 value.
To tackle this down, we just add some lines in the section code that runs just before
‘adder’ (your m-file, remember?) is made visible (most of the lines are written by Matlab
automatically, you just add three lines), like this:
% --- Executes just before adder is made visible.
function adder_OpeningFcn(hObject, eventdata, handles,
varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version
of MLB
% handles structure with handles and user data (see
GUIDATA)
% varargin command line arguments to adder (see
VARARGIN)
% Choose default command line output for adder
handles.output = hObject;
num = 0;
handles.edit1 = num;
handles.edit2 = num;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes adder wait for user response (see UIRESUME)
% uiwait(handles.figure1);
Done! Run your GUI by clicking on the ‘run’ icon at the top of your editor window...
Matlab GUI - Magic Trick!
We are going to develop a Matlab GUI that performs a magic trick! We’re going to
work on an interface to read your mind! Don’t be scared... it’s safe (as far as I know...).
It’s an old trick that has been around for at least 40 years (maybe more), but this is my
version with Matlab.
It’s the choose-a-card type trick...
Effect: the user sees 21 shuffled cards (absolutely random), arranged along 3 columns.
He/she chooses a card but tells nobody... the card is only in his/her mind. The happy
user indicates the column where the chosen card is, and does this two more times. Every
time the cards are randomly rearranged. After a complicated artificially-inteligent
algorithm, and using the most advanced artificial neural networks (??), our program
guesses the chosen card... Is computerized ESP possible? (Download the code here!)
I strongly suggest you read the first and second articles in this series, where I explain in
detail how to create a Matlab GUI, and how to use the three most important instructions
for GUIs (set, get and guidata). In this article, I’m going to elaborate on how to use the
‘axes’ and ‘radio’ buttons, as well as the associated callback-functions.
First, type ‘guide’ on your command window. Select the default option (blank gui).
You can see on the left several buttons that you can drag-and-drop onto your gui
‘canvas’ or layout area.
Add an ‘axes’ button and double-click on it to inspect and modify its properties. Set its
position to [x y width heigth] = [10 22 8 2.5]. Try to reproduce this figure:
Click once on ‘axes1’ and copy-paste (Ctl-C, Ctl-V) this element six more times
(vertically). You can align the objects by clicking on the ‘Align Objects’ icon, on the top
menu.
Select all of the 7 ‘axes’ and copy-paste two more times (horizontally). You have now 21
axes on a 7x3 matrix. Add then a ‘Static box’ to the right of your ‘canvas’, and you get
something similar to this figure:
Add more elements (and modify their properties) until you match the figure below:
You have 22 ‘axes’, 3 ‘Static boxes’, 3 ‘Radio buttons’, and 1 ‘Push button’, right?
You can modify their sizes by dragging the ‘anchors’ on the corners.
For the 3 ‘Static boxes’, update their properties like this:
Property Box 1 Box 2 Box 3
Tag text1 text2 text3
String This is a great trick! (empty) (empty)
FontAngle italic normal normal
FontSize 10 8 8
FontWeight bold bold bold
HorizontalAlignment left left right
For the 3 ‘Radio buttons’, just erase their ‘String’ property and reduce their sizes to fit
each column.
For the ‘Push button’, update its properties like this:
Property Button
Tag
String
FontAngle
FontSize
FontWeight
ForegroundColor
pushbutton1
Do it again, please!
italic
8
bold
blue
Save the Matlab GUI (I used the name ‘trick1.fig’), and Matlab will produce a template
for your figure (named ‘trick1.m’), with appropriate names and comments or suggestions
to get the values of the elements on it.
For our trick, we’ll need 5 functions that will be handled from our main module
(‘trick1.m’). These functions will be:
initialize_trick: to shuffle the cards, show them for the first time and
perform a reset
showcards: to display 21 out of 52 cards available
display_instructions: to display instructions on the ‘Static text’ boxes to let
the user know what’s going on and what’s next
go_on: to keep the trick going once the user selects the column of his/her
card
rearrange: to pick-up the cards, rearrange and deal them again on the 7x3 matrix
This is the implementation of the function named ‘initialize_trick.m’. These names are
going to be associated with a jpg file.
% Copyright 2009 by www.matrixlab-examples.com function initialize_trick() global ha cards
% Define the 52 cards to be used card_deck = {'ad' 'ah' 'as' 'ac' '2d' '2h' '2s' '2c' ... '3d' '3h' '3s' '3c' '4d' '4h' '4s' '4c' ... '5d' '5h' '5s' '5c' '6d' '6h' '6s' '6c' ... '7d' '7h' '7s' '7c' '8d' '8h' '8s' '8c' ... '9d' '9h' '9s' '9c' '10d' '10h' '10s' '10c' ... 'jd' 'jh' 'js' 'jc' 'qd' 'qh' 'qs' 'qc' ... 'kd' 'kh' 'ks' 'kc'};
card_nr = 52;
% Select 21 random cards from the deck (7 x 3 matrix) for i = 1 : 7
for j = 1 : 3
% Select one random card from the remaining deck r = ceil(card_nr .* rand);
cards{i,j} = card_deck{r};
% Delete that card from the deck card_deck(r) = [];
% Reduce the card account in the remaining deck card_nr = card_nr - 1;
end
end
% Display cards and first instructions showcards;
display_instructions(1);
% Make sure to delete the last guess str = '';
set(ha(24),'String',str);
% Hide button set(ha(25),'Visible','off');
% Make the radio-buttons available set(ha(26),'Visible','on')
set(ha(27),'Visible','on')
set(ha(28),'Visible','on')
This is the implementation of the function named ‘showcards.m’. Here we actually
associate a jpg file (a card) with its corresponding place on the matrix. We show a plain
gray image on the ‘axes22’ position.
% Copyright 2009 by www.matrixlab-examples.com
function showcards()
global ha cards
% Take one .jpg file for each 'axes' (21 cards to deal).
for i = 1 : 21
axes(ha(i));
[bg] = imread(strcat(cards{i},'.jpg'));
image(bg);
axis off;
end
% Delete the guess
axes(ha(22));
[bg] = imread('gray.jpg');
image(bg);
axis off;
This is the implementation of the function named ‘display_instructions
.m’. It launches instructions on the ‘text2’ Static-box, according to the evolution of the
trick.
% Copyright 2009 by www.matrixlab-examples.com
function display_instructions(i)
global ha
% Display instructions according to evolution of trick
switch i
case 1
str = {'Step 1: ';
'';
'Think of a card and select its column
below...'};
set(ha(23),'String',str);
case 2
str = {'Step 2: ';
'';
'Hard to guess...';
'';
'Could you please select its column
again?'};
set(ha(23),'String',str);
case 3
str = {'I cannot see it clearly... ';
'';
'Please concentrate and select its column only once
more...'};
set(ha(23),'String',str);
case 4
str = '';
set(ha(23),'String',str);
str = {'Ah! Got it! ';
'Your card is: '};
set(ha(24),'String',str);
end
This is the implementation of the function named ‘go_on.m’. It’s executed each time the
user clicks on a radio button to choose a column. After three clicks, the selection is
revealed!
% Copyright 2009 by www.matrixlab-examples.com function go_on(hObject,handles,c) global ha cards
% Take into account the number of choices by the user handles.t = handles.t + 1; % Reset the current radio-button set(hObject,'Value',0);
% Display the cards in a new order. rearrange(c); if handles.t < 4
showcards();
display_instructions(handles.t); else % Perform the trick! display_instructions(4);
axes(ha(22));
[bg] = imread(strcat(cards{4,2},'.jpg'));
image(bg);
axis off;
% Make the pushbutton appear set(ha(25),'Visible','on')
% Make the radio-buttons disappear set(ha(26),'Visible','off')
set(ha(27),'Visible','off')
set(ha(28),'Visible','off') end
guidata(hObject,handles);
This is the implementation of the function named ‘rearrange.m’. It takes the three
columns of cards, each time the column with the selected card is put in second place. The
other two columns are irrelevant for this trick.
% Copyright 2009 by www.matrixlab-examples.com
function rearrange(c)
global cards
% Take the cards and the column of the selected card
% is kept as second column
switch c
case 1
cards_aux = {cards{:,3} cards{:,1} cards{:,2}};
case 2
cards_aux = {cards{:,3} cards{:,2} cards{:,1}};
otherwise
cards_aux = {cards{:,2} cards{:,3} cards{:,1}};
end
% Deal the cards with the new order
k = 1;
for i = 1 : 7
for j = 1 : 3
cards{i,j} = cards_aux{k};
k = k + 1;
end
end
This is the main wrapper (‘trick1.m’). I deleted some of the comments automatically
written by the Matlab GUI -DE (Development Environment), to simplify the
explanation.
% Copyright 2009 by www.matrixlab-examples.com function varargout = trick1(varargin) % Begin initialization code - DO NOT EDIT gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @trick1_OpeningFcn, ... 'gui_OutputFcn', @trick1_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1}); end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT
% --- Executes just before trick1 is made visible. function trick1_OpeningFcn(hObject, eventdata, handles,varargin) % This function has no output args, see OutputFcn.
% hObject handle to figure
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to trick1 (see VARARGIN)
% Choose default command line output for trick1 handles.output = hObject; global ha
clc
ha(1) = handles.axes1; ha(8) = handles.axes8; ha(15) = handles.axes15;
ha(2) = handles.axes2; ha(9) = handles.axes9; ha(16) = handles.axes16;
ha(3) = handles.axes3; ha(10) = handles.axes10; ha(17) = handles.axes17;
ha(4) = handles.axes4; ha(11) = handles.axes11; ha(18) = handles.axes18;
ha(5) = handles.axes5; ha(12) = handles.axes12; ha(19) = handles.axes19;
ha(6) = handles.axes6; ha(13) = handles.axes13; ha(20) = handles.axes20;
ha(7) = handles.axes7; ha(14) = handles.axes14; ha(21) = handles.axes21;
ha(22) = handles.axes22;
ha(23) = handles.text2;
ha(24) = handles.text3;
ha(25) = handles.pushbutton1;
ha(26) = handles.radiobutton1;
ha(27) = handles.radiobutton2;
ha(28) = handles.radiobutton3;
initialize_trick;
handles.t = 1;
% Update handles structure guidata(hObject, handles);
% UIWAIT makes trick1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --Outputs from this function are returned to the command line. function varargout = trick1_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes on button press in radiobutton1. function radiobutton1_Callback(hObject, eventdata, handles) % hObject handle to radiobutton1 (see GCBO) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of radiobutton1 global ha
go_on(hObject,handles,1);
% --- Executes on button press in radiobutton2. function radiobutton2_Callback(hObject, eventdata, handles) global ha
go_on(hObject,handles,2);
% --- Executes on button press in radiobutton3. function radiobutton3_Callback(hObject, eventdata, handles) global ha
go_on(hObject,handles,3);
% --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO)
% handles structure with handles and user data (see GUIDATA) global ha
initialize_trick;
handles.t = 1;
% Update handles structure guidata(hObject, handles);
To run the program and see the Matlab GUI, save all these files with their respective
names, put them into a single directory, go to that directory with Matlab and just
type ‘trick1’ on your command window.
Here's a sample run.
Let's say that we choose the ace of spades, so we click on the right radio button.
The cards are reshuffled and we now click on the central radio button...
We concentrate once more, to send clearer thoughts through our mental interface... click
on the right column again and...
Nice trick, isn't it?
I wrote it for you...
Enjoy!
Card Trick with Matlab GUIs
In this article we’re going to develop another computerized card trick using callback-
functions in Matlab GUIs. I strongly suggest you read the first and second articles in this
series, to know how to start and how to use the very important three instructions ‘get’,
‘set’ and ‘guidata’.
On your command window type ‘guide’ (without the quotes). Choose the ‘Blank GUI’
option. You’ll see a menu on your left:
Drag-and-drop an ‘axes’ button, a ‘static text’ button and a ‘push button’ to your
layout-area so that you get something similar to this figure:
To modify the properties of each element on your layout-area, you must double-click
on each. You can modify properties such as size and position, font, font weight and
allignment.
Set these properties (you can experiment with others) and save your figure with the name
‘trick2.fig’:
Tag axes1 text1 pushbutton1
Position 4 6 75 22 84 15 23 8 83 6 22 2.5
FontSize 10 10
FontWeight bold bold
HorizontalAllignment left left
String
Choose a card
Don’t forget it!
Concentrate...
Continue...
And now you should have something similar to this figure:
The editor will open with a prepared template, where you can edit the callback-
functions for each element involved in the card trick.
For the opening function, you can complete it as follows (there are some comments
included by Matlab, you just have to add the missing lines):
% --- Executes just before trick2 is made visible.
function trick2_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to trick2 (see VARARGIN)
% Choose default command line output for trick2
handles.output = hObject;
clc
axes(handles.axes1);
bg = imread('trick2_001.jpg');
image(bg);
axis off;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes trick2 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
For the callback associated with the push-button, complete it like this:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA) str = {'I see it clearly... ';
'';
'';
'I have made your card vanish!!'};
set(handles.text1,'String',str);
axes(handles.axes1);
bg = imread('trick2_002.jpg');
image(bg);
axis off;
set(handles.pushbutton1,'Visible','off')
If you download the images and files that I’ve included, and you run the trick2.m file
with Matlab, you’ll get this result:
And after clicking the button, you get this figure:
Done!
Resistor Code with Matlab GUI
In this article we're going to decipher the colored Resistor Code with a Matlab
GUI. The intention is to be able to use pull-down menus to decode the colors of four-
band resistors.
Download files (right-click and save)
Use the following table and explanation to distinguish a color band's value and how
to use it.
Black = 0
Brown = 1
Red = 2
Orange = 3
Yellow = 4
Green = 5
Blue = 6
Violet = 7
Gray = 8
White = 9
Gold = +/-
5%
Silver = +/-
10%
Find one of the four-band resistors. Hold the resistor with the gold or silver band to
the right. The first two bands from the left show the value. If they are red and red,
the value is 22. The third band shows the number of zeros after the value. If it is
yellow, then the number of zeros is 4.
So the above resistor is 220000, or 220 K ohms (for easier reading).
The 'K' multiplier means 1,000 (kilo-ohms); the 'M' multiplier means 1,000,000
(mega-ohms).
The gold band indicates that the resistors are of 5% tolerance. A silver band
indicates a 10% tolerance.
An orange-red-brown-gold code equals a 320 +/-5% resistor.
Now with Matlab...
If this is your first GUI, I suggest you read these two initial articles,
Matlab GUI intro
Callback functions
and then come-back and continue with this new project.
If you're ready, then type on the command window
> guide
and a GUI window appears. Choose 'Blank GUI' and you'll get something like this
figure:
Use the buttons on the left to drag-and-drop 4 'pop-up' menus, 4 'axes', and 3
'static-text' boxes.
'Static-text1' is used to give the message below the menus. It's 'String' property is
'Select one color from each pull-down menu'. You can make it a bold font
(double-click on each menu and choose the different properties).
'Static-text2' is used to display the resistor value. It starts with a '0' (zero) in its
string property. 'Static-text3' just displays the word 'ohms'.
Arrange the elements and change their properties to achieve something like this:
Include these values in the 'String' property of the first 3 pop-up menus
(double-click on each menu and choose the 'String' property):
For the 4th menu, you have to write ' 5% gold' and '10% silver' in its 'String'
property.
Save the figure as resistor_code.fig. A template code is automatically created with
the name 'resitor_code.m'. We're going to modify it and we're going to create other
functions to make it work...
We'll create some Matlab functions and then we'll link them to this initial template.
First, a function to initialize the GUI axes. I suggest the following code:
% Initialize resistor code (bands)
% Show 0 ohm +/- 5% function init_bands(handles)
axes(handles.axes1);
image(imread('black.jpg'));
axis off;
axes(handles.axes2);
image(imread('black.jpg'));
axis off;
axes(handles.axes3);
image(imread('black.jpg'));
axis off;
axes(handles.axes4);
image(imread('gold.jpg'));
axis off;
This will display a 0-value with a 5% tolerance code in the GUI (colors for the 4
bands are black - black - black - gold).
Now, to update the colors when the values are entered using the pull-down menus, I
suggest the following code:
function update_color(ax, val, handles) % Select the appropriate color to update switch ax
case 1
axes(handles.axes1);
case 2
axes(handles.axes2);
case 3
axes(handles.axes3);
case 4
axes(handles.axes4); end
% Choose the correct image to display color = val(5 : length(val));
image(imread([color '.jpg']));
axis off;
The input parameters of this function are 'ax' (includes the correct band number),
'val' (includes the selected option), and 'handles' (all the handles to the objects in
our created figure). We have to choose the correct image to display. The name of the
image is included in the 'val' parameter. You have to have .jpg images for each
color.
Then, to update the total value of the resistor (values are entered using the pull-
down menus, too) I suggest the following code:
function update_value(handles)
b = handles.b;
b_ttl = (b(1) + b(2)) * b(3);
if b_ttl < 1000
b_str = num2str(b_ttl); end
% Format the number to make it more readable
% Consider to format only values >= 1000 k ohms bs1 = num2str(b(1)/10);
bs2 = num2str(b(2)); switch b(3)
case 1e2
b_str = [bs1 '.' bs2 ' K'];
case 1e3
b_str = [bs1 bs2 ' K'];
case 1e4
b_str = [bs1 bs2 '0 K'];
case 1e5
b_str = [bs1 '.' bs2 ' M'];
case 1e6
b_str = [bs1 bs2 ' M'];
case 1e7
b_str = [bs1 bs2 '0 M'];
case 1e8
b_str = [bs1 '.' bs2 ' G'];
case 1e9
b_str = [bs1 bs2 ' G']; end
% Actual display of the value in the 'static text' set(handles.text2, 'String', b_str);
This function reads the total value of the resistor bands and formats it to make it
more readable. It displays the number as a string, not as a number, and adds
appropriate multipliers (such as 'K' or 'M'). The resulting string is displayed in 'Static-
Text2'.
Please note that not all the combinations are real standard resistor values.
This is a portion of the script that appears in the 'resistor_code.m' file (the template
created by Matlab). We have to fill in the necessary code to achieve what we need.
Instructions contents = get(hObject,'String'), and
contents{get(hObject,'Value')} are the key Matlab functions to read data from a
pull down menu.
This code is for pop-up menu1. We read the menu, then we call our previous
function to update the color of the corresponding image, we update the value of the
resistor and finally save current data in the handles. This has to be adapted for the
other three menus and axes.
% - Executes on selection change in popupmenu1. function popupmenu1_Callback(hObject, eventdata, handles) % Hints:
% contents = get(hObject,'String') returns menu1 contents as
% cell array
% contents{get(hObject,'Value')} returns selected item from
% menu1 contents = get(hObject,'String');
v = contents{get(hObject,'Value')};
% Update color of appropriate band update_color(1, v, handles);
% Update resistor value handles.b(1) = str2num(v(1)) * 10; update_value(handles);
% Save data guidata(hObject, handles);
This is a sample run:
The full code for the main routine is:
function varargout = resistor_code(varargin) % RESISTOR_CODE M-file for resistor_code.fig
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Last Modified by GUIDE v2.5 09-Jan-2010 19:48:33
% Begin initialization code - DO NOT EDIT gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @resistor_code_OpeningFcn, ... 'gui_OutputFcn', @resistor_code_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1}); end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT
% --- Executes just before resistor_code is made visible. function resistor_code_OpeningFcn(hObject, eventdata, handles,
varargin) % This function has no output args, see OutputFcn.
% hObject handle to figure
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to resistor_code (see VARARGIN)
% Choose default command line output for resistor_code clc
handles.output = hObject;
% Initialize color of bands init_bands(handles); % Initialize and save resistor value b(1) = 0;
b(2) = 0;
b(3) = 1;
handles.b = b;
% Update handles structure guidata(hObject, handles);
% --- Outputs from this function are returned to the command line. function varargout = resistor_code_OutputFcn(hObject, eventdata,
handles)
varargout{1} = handles.output;
% --- Executes on selection change in popupmenu1. function popupmenu1_Callback(hObject, eventdata, handles) % Hints:
% contents = get(hObject,'String') returns menu1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from menu1 contents = get(hObject,'String');
v = contents{get(hObject,'Value')};
% Update color of appropriate band update_color(1, v, handles);
% Update resistor value handles.b(1) = str2num(v(1)) * 10;
update_value(handles);
% Save data guidata(hObject, handles);
% - Executes during object creation, after setting all properties. function popupmenu1_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), ... get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white'); end
% --- Executes on selection change in popupmenu2. function popupmenu2_Callback(hObject, eventdata, handles) % Hints:
% contents = get(hObject,'String') returns menu1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from menu1 contents = get(hObject,'String');
v = contents{get(hObject,'Value')};
% Update color of appropriate band update_color(2, v, handles);
% Update resistor value handles.b(2) = str2num(v(1));
update_value(handles);
% Save data guidata(hObject, handles);
% --- Executes during object creation, after setting all properties. function popupmenu2_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), ... get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white'); end
% --- Executes on selection change in popupmenu3. function popupmenu3_Callback(hObject, eventdata, handles) % Hints:
% contents = get(hObject,'String') returns menu1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from menu1 contents = get(hObject,'String');
v = contents{get(hObject,'Value')};
% Update color of appropriate band update_color(3, v, handles);
% Update resistor value handles.b(3) = 10^(str2num(v(1)));
update_value(handles);
% Save data guidata(hObject, handles);
% --- Executes during object creation, after setting all properties. function popupmenu3_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), ... get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white'); end
% --- Executes on selection change in popupmenu4. function popupmenu4_Callback(hObject, eventdata, handles) % Hints:
% contents = get(hObject,'String') returns menu1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from menu1 contents = get(hObject,'String');
% Update color of appropriate band update_color(4, contents{get(hObject,'Value')}, handles);
% Save data guidata(hObject, handles);
% --- Executes during object creation, after setting all properties. function popupmenu4_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), ... get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white'); end
Polynomial Roots - 'Zero finding' in Matlab
To find polynomial roots (aka 'zero finding' process), Matlab has a specific
command, namely 'roots'.
If you type on the command window:
>> help roots
the Matlab online help will display:
ROOTS Find polynomial roots.
ROOTS(C) computes the roots of the polynomial whose
coefficients are the elements of the vector C. If C has N+1
components, the polynomial is C(1)*X^N + ... + C(N)*X + C(N+1).
This means that the coefficients of the polynomial are placed in a vector C and the
built-in function returns the corresponding roots or zeros. It is simple to use, but
care is needed when entering the coefficients of the polynomial.
For example, find the roots of the equation
f(x) = 3x5 − 2x4 + x3 + 2x2 − 1
You can use the simple Matlab code:
c = [3 -2 1 2 0 -1];
roots(c)
And Matlab will deliver the following five zeros (x-values that produce a function f(x)
= 0):
ans =
0.5911 + 0.9284i
0.5911 - 0.9284i
0.6234
-0.5694 + 0.3423i
-0.5694 - 0.3423i
There’s a couple of things to note from this example:
The polynomial’s coefficients are listed starting with the one corresponding to the
largest power. It is important that zero-coefficients are included in the sequence
where necessary. A polynomial of order p has p + 1 coefficients, this is, a quadratic
has three coefficients and a polynomial of degree p will have p roots.
As long as the coefficients of the polynomial are real, the roots will be real or occur
in complex conjugate pairs.
Built-in Command fzero The Matlab command 'fzero' is powerful. It actually chooses which internal method
should be used to solve a given problem, and can be used for non-polynomical
functions.
Let us try the form of the command
options = optimset('disp','iter');
fzero('func', 3, options)
The command uses many different forms but here we are looking for a root of the
function defined in 'func.m' near the value x = 3 and the options are set to 'display
iterations'.
For example, determine the zero of the function f(x) = 3x − 2x2 sin(x), closest to
x = 2.
A fast plot of the function (for exploration purposes) results in:
So we need to set up the code:
function mf = myfunction(x)
mf = 3*x – 2*x.ˆ2.*sin(x);
and later we may use the inline command fzero like this (no input vector is needed)
>> fzero('myfunction', 2)
The Matlab answer is:
ans =
1.5034
Polynomials
Polynomials are used so commonly in algebra, geometry and math in general that Matlab
has special commands to deal with them. The polynomial 2x4 + 3x
3 − 10x
2 − 11x + 22 is
represented in Matlab by the array [2, 3, -10, -11, 22] (coefficients of the polynomial
starting with the highest power and ending with the constant term). If any power is
missing from the polynomial its coefficient must appear in the array as a zero.
Here are some examples of the things that Matlab can do with polynomials. I suggest you
experiment with the code…
Roots of a Polynomial
% Find roots of polynomial p = [1, 2, -13, -14, 24];
r = roots(p)
% Plot the same polynomial (range -5 to 5) to see its roots x = -5 : 0.1 : 5;
f = polyval(p,x);
plot(x,f)
grid on
Find the polynomial from the roots
If you know that the roots of a polynomial are -4, 3, -2, and 1, then you can find the
polynomial (coefficients) this way:
r = [-4 3 -2 1];
p = poly(r)
Multiply Polynomials
The command conv multiplies two polynomial coefficient arrays and returns the
coefficient array of their product:
a = [1 2 1];
b = [2 -2];
c = conv(a,b)
Look (and try) carefully this result and make sure it’s correct.
Divide Polynomials
Matlab can do it with the command deconv, giving you the quotient and the remainder
(as in synthetic division). For example:
% a = 2x^3 + 2x^2 - 2x - 2
% b = 2x - 2 a = [2 2 -2 -2];
b = [2 -2];
% now divide b into a finding the quotient and remainder [q, r] = deconv(a,b)
You find quotient q = [1 2 1] (q = x2 + 2x + 1), and remainder r = [0 0 0 0] (r = 0),
meaning that the division is exact, as expected from the example in the multiplication
section…
First Derivative
Matlab can take a polynomial array and return the array of its derivative:
a = [2 2 -2 -2] (meaning a = 2x3 + 2x
2 - 2x - 2)
ap = polyder(a)
The result is ap = [6 4 -2] (meaning ap = 6x2 + 4x - 2)
Fitting Data to a Polynomial
If you have some data in the form of arrays (x, y), Matlab can do a least-squares fit of a
polynomial of any order you choose to this data. In this example we will let the data be
the cosine function between 0 and pi (in 0.01 steps) and we’ll fit a polynomial of order 4
to it. Then we’ll plot the two functions on the same figure to see how good we’re doing.
clear; clc; close all
x = 0 : 0.01 : pi; % make a cosine function with 2% random error on it f = cos(x) + 0.02 * rand(1, length(x));
% fit to the data p = polyfit(x, f, 4);
% evaluate the fit g = polyval(p,x);
% plot data and fit together plot(x, f,'r:', x, g,'b-.')
legend('noisy data', 'fit')
grid on
Got it?
Check Writer – how to manipulate strings in Matlab
This Matlab program is a ‘check writer’. You must provide a numerical date, payee of
the check, and amount to be written (any number between 1.00 and 999,999.99
dollars). The program translates the date and amount to words, and prints providing
some spacing within the check (easily modifiable).
You should regard the listing as a sample of a check-writing code. The algorithm for
translating numbers into words (or working with strings) is general and may be easily
adapted to other programming languages.
There are five sections to convert numbers into words in this Matlab program.
Processing the thousands
Processing the hundreds
Processing the tens
Processing cents Main code that accesses and controls the other four sections
We use cell arrays to handle the necessary strings, and the process consists in finding the
correct index of an initial given ‘dictionary’.
The Matlab function to work with the first three digits (thousands) is as follows. The
string (named ‘words’) is updated after each digit is evaluated.
function [words, h, u] = thousands(amount)
global number
words = [];
% Find if there are thousands
t = floor(amount/1000);
if (t == 0)
h = 0;
u = 0;
return
end
% Find the hundreds
h = floor(amount/100000);
if h > 0
words = [number{h} ' HUNDRED'];
end
% Find the last two digits
u = floor(amount/1000) - h*100;
if (0 < u) & (u < 21)
words = [words ' ' number{u}];
else
words = [words tens(u, [])];
end
% End string with word 'thousand'
words = [words ' THOUSAND'];
The 'check writer' function to work with the three digits previous to the decimal
point (hundreds) is as follows. Again, the string (named ‘words’) is updated after
each digit is evaluated and the Matlab algorithm flows in a similar way than before.
function words = hundreds(amount, words, h, u)
global number
% Find if there are hundreds
hu = floor(amount - h*1e5 - u*1e3);
if (hu == 0)
words = [words];
return
end
% Find the hundreds
h = floor(hu/100);
if h > 0
words = [words ' ' number{h} ' HUNDRED'];
end
% Find the last two digits
u = hu - h*100;
if (0 < u) & (u < 21)
words = [words ' ' number{u}];
else
words = [words tens(u, [])];
end
The section to translate the last two digits of each group of three elements is given below.
Note that the index to locate the correct number in the given dictionary (defined in the
control section, below) works only for numbers beyond the first 20 elements in the list,
due to the way that English syntax works. For the first 20 elements, it 's not necessary to
go through this script.
function words = tens(u, words)
global number
% Work with the last two digits of the group of three
if u == 0
words = [words];
return
end
% Find the correct index of the appropriate multiple of 10
words = [words ' ' number{floor((u - 20)/10 + 20)}];
units = u - floor(u/10)*10;
if units == 0
return
end
% Add a dash and the appropriate number if there are units
words = [words '-' number{units}];
Now, this is the function to add the remaining cents to the almost ready final string. It
converts numbers into strings using command 'num2str'.
function words = cents(amount, words)
c = amount*100 - floor(amount)*100;
if c < 10
cents = ['0' num2str(c)];
else
cents = num2str(c);
end
words = [words ' AND ' cents '/100'];
The control module that accesses the previous four routines for our check writer is as
follows (name it check_writer.m, so you can run it from the command window):
clc; clear
global number
month = {'January', 'February', 'March', 'April', 'May',...
'June', 'July', 'August','September', 'October',...
'November', 'December'};
number = {'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE',...
'SIX', 'SEVEN', 'EIGHT', 'NINE', 'TEN',...
'ELEVEN', 'TWELVE', 'THIRTEEN', 'FOURTEEN',
'FIFTEEN',...
'SIXTEEN', 'SEVENTEEN', 'EIGHTEEN', 'NINETEEN',...
'TWENTY', 'THIRTY', 'FORTY', 'FIFTY',...
'SIXTY', 'SEVENTY', 'EIGHTY', 'NINETY'};
disp('Check Writer -----')
disp(' ')
dat = input('Enter date (MMDDYY): ', 's');
m = str2num(dat(1:2));
name = input('Name of payee: ', 's');
a = input('Amount of check (include two decimals): ', 's');
amount = str2num(a);
if (amount < 1)|(amount > 999999.99)
disp('Sorry, amount is out of range...')
return
end
x = input('Prepare printer... ', 's');
disp(' ')
dat_str = [' '...
month{m} ' ' dat(3:4) ', ' '20' dat(5:6)];
disp(dat_str)
amount_str = ['
'...
'$' a];
disp(amount_str)
name_str = [' ' name];
disp(name_str)
[words, h, u] = thousands(amount);
words = [hundreds(amount, words, h, u)];
words = [cents(amount, words) ' DOLLARS'];
disp(words)
Now, let’s try our code:
Check Writer -----
Enter date (MMDDYY): 122309
Name of payee: Heavenly Bank of Algorithmland
Amount of check (include two decimals): 23999.00
Prepare printer...
December 23,
2009
$23999.00
Heavenly Bank of Algorithmland
TWENTY-THREE THOUSAND NINE HUNDRED NINETY-NINE AND 00/100
DOLLARS
Another run:
Check Writer -----
Enter date (MMDDYY): 010110
Name of payee: Matrixlab-Examples.com
Amount of check (include two decimals): 734100.15
Prepare printer...
January 01, 2010
$734100.15
Matrixlab-Examples.com
SEVEN HUNDRED THIRTY-FOUR THOUSAND ONE HUNDRED AND 15/100
DOLLARS
Fibonacci Numbers in Matlab
The first two Fibonacci numbers are 0 and 1, and each remaining number is the
sum of the previous two. Some sources neglect the initial 0, and instead
beginning the sequence with the first two 1s. The Fibonnacci numbers are also
known as the Fibonacci series.
Two consecutive numbers in this series are in a 'Golden Ratio'.
In mathematics and arts, two quantities are in the golden ratio if the ratio of the sum
of the quantities to the larger quantity equals the ratio of the larger quantity to the
smaller one. The golden ratio is an irrational constant, approximately 1.618033988.
The command 'num2string' changes a number into a string, so that it can be
included in another string. The command 'num2str(golden_ratio, 10)' shows the
number 'golden_ratio' with 9 digits after the decimal point.
The simple code is here:
%Clear screen and memory
clear; clc; format compact
% Initialize the first two values
f(1) = 1;
f(2) = 1;
% Create the first 30 Fibonacci numbers
for i = 3 : 30
% Perform the sum of terms accordingly
f(i) = f(i-1) + f(i-2);
% Calculate and display the ratio of 2 consecutive elements of the series
golden_ratio = f(i)/f(i-1);
str = [num2str(f(i)) ' ' num2str(f(i-1)) ' ' num2str(golden_ratio, 10)];
disp(str)
end
The results in Matlab are:
2 1 2
3 2 1.5
5 3 1.666666667
8 5 1.6
13 8 1.625
21 13 1.615384615
34 21 1.619047619
55 34 1.617647059
89 55 1.618181818
144 89 1.617977528
233 144 1.618055556
377 233 1.618025751
610 377 1.618037135
987 610 1.618032787
1597 987 1.618034448
2584 1597 1.618033813
4181 2584 1.618034056
6765 4181 1.618033963
10946 6765 1.618033999
17711 10946 1.618033985
28657 17711 1.61803399
46368 28657 1.618033988
75025 46368 1.618033989
121393 75025 1.618033989
196418 121393 1.618033989
317811 196418 1.618033989
514229 317811 1.618033989
832040 514229 1.618033989
You can see that, in fact, the quotient of two consecutive numbers reaches the 'golden
ratio' after just a few numbers in the series.
Binary to decimal - Four ways to convert formats in Matlab
In this article we're going to present four variations of a binary to decimal
conversion in Matlab; that is, we're going to convert binary numbers (numbers with
only symbols '0' and '1') to decimal numbers (numbers with 10 different symbols,
from '0' to '9').
As you may know, a number expressed in decimal format (the common way to
express a number, also called base 10) consists of additions of digits raised to the
different powers of 10. For example:
1528 (base 10) means 1 x 103 + 5 x 102 + 2 x 101 + 8 x 100
Following the same reasoning, a binary number (called to be in base 2) consists of
additions of binary digits raised to the different powers of 2. For example:
1010 (base 2) means 1 x 23 + 0 x 10
2 + 1 x 10
1 + 0 x 2
0
1st. Method: using the bin2dec function.
The 'bin2dec' built-in function converts a binary number string to a decimal number.
Example:
bin_nr = '110101';
dec = bin2dec(bin_nr)
The result is dec = 53.
2nd. Method: using a for-loop. In the event that we cannot use the bin2dec function for any reason, we have to
elaborate an alternative. In this case, we just follow the logic explained above: every
digit found in the input string is obtained with every iteration and it is converted into
a real number (in this case the input is a string, not a number, that's why we use the
instruction 'str2num').
bin_nr = '110101';
dec = 0;
for i = 1 : length(bin_nr)
dec = dec + str2num(bin_nr(i)) * 2^(length(bin_nr) -
i);
end dec
As expected, the result is also dec = 53.
3rd. Method: using a while-loop.
Now, we make a small change in the logic to work with a while-loop instead of a for-
loop, just for a variation. The idea is the same, but we have to add an index to keep
track of the appropriate power of the digit to be considered. This binary to decimal
conversion also includes input from the user:
bin_nr = input('Enter your binary number: ', 's');
dec = 0;
i = 1;
while i < length(bin_nr) + 1
dec = dec + str2num(bin_nr(i)) * 2^(length(bin_nr) -
i);
i = i + 1;
end
dec
4rd. Method: using 'polyval'. As seen in the articles about polynomials and curve fitting (see Table of Contents),
the 'polyval' function with arguments (p, x) returns the value of a polynomial of
degree n evaluated at x. The input argument p is a vector of length n+1 whose
elements are the coefficients in descending powers of the polynomial to be
evaluated. This is exactly what we need if the input is in vector form. In other words,
the expected result is:
y = p1xn + p2x
n-1 + ... + pnx + pn+1
And that's achieved this way:
bin_nr = [1 1 0 1 0 1];
dec = polyval(bin_nr, 2)
Decimal to binary conversion: two methods to do it with Matlab
In this article we're going to present two methods of a decimal to binary
conversion in Matlab; that is, we're going to convert decimal numbers (numbers
with 10 different symbols, from '0' to '9', or in base 10) into binary numbers
(numbers with only symbols '0' and '1', or in base 2).
First, let's understand how this works if we do it manually. Later we can automate
the process.
Let's say that we need to convert the number 10 (decimal number) into a binary
number.
We divide 10 by 2: the quotient is 5 and the remainder is 0 (q = 5, r = 0). The first
digit for our binary number will be this remainder. This value will be the least
significant bit (LSB) in our final value (bin = '0', so far).
We divide the previous quotient (5) by 2: the new quotient is 2 and the remainder is
1 (q = 2, r = 1). Our second digit for the binary result will be this reminder (bin =
'10', so far).
We divide the previous quotient (2) by 2: the new quotient is 1 and the remainder is
0 (q = 1, r = 0). We keep this remainder and include it in the binary partial result
(bin = '010', so far).
Since the latest quotient was less than 2, we know that we have finished our
conversion. We take the last quotient and include it in our final binary result, and
this is going to be the most significant bit (MSB) (bin = '1010', final).
1st. method: with Matlab help We can get the decimal to binary conversion using the Matlab command 'dec2bin'.
For example:
dec_nr = 10;
bin = dec2bin(dec_nr);
Matlab's answer is
bin = 1010
Note that the result is a string in Matlab, not a number.
2nd. method: our own code To automate the process explained above, we need to explain first the commands
'floor', 'rem', 'num2str' and 'fliplr'.
'floor': rounds towards minus infinity.
'rem': remainder after a division.
'num2str': converts numbers to strings.
'fliplr': flips matrix in left/right direction.
The proposed code is this:
dec_nr = 10;
i = 1;
q = floor(dec_nr/2);
r = rem(dec_nr, 2);
bin(i) = num2str(r(i));
while 2 <= q
dec_nr = q;
i = i + 1;
q = floor(dec_nr/2);
r = rem(dec_nr, 2);
bin(i) = num2str(r);
end
bin(i + 1) = num2str(q);
bin = fliplr(bin)
The while-loop goes on until the quotient is less than 2. q is the quotient, r is the
remainder and we keep all the remainders in variable (string) 'bin'. The last bit in our
number is the MSB and it's the last quotient obtained, the one that was less than 2.
Since the binary digits (bits) are obtained from LSB to MSB, we have to flip the array in
the last step, so that we can see the appropriate order.
Binary to hexadecimal numbers: two solutions in Matlab
To convert a value from binary to hexadecimal, we first need to know what a
hexadecimal number is.
A major numbering system used in digital systems is the hexadecimal system, also
named base 16. In this system, the numbers are counted from 0 to 9 and, since in base 16
we need 16 different symbols, decimal numbers 10 through 15 are represented by letters
A through F, respectively. So we go from 0 to F.
The following table shows the meaning of all the symbols in the hex (for short)
numbering system.
To convert a value from binary to hexadecimal, you merely translate each 4-bit binary
group to its hexadecimal equivalent. For example, the binary number 0011 1111 0111
1010 translates into the hex 3F7A equivalent.
Solution 1.
In Matlab, we can go from binary to decimal, and then, from decimal to hexadecimal.
We can embed one instruction into the other, like this:
hex_str = dec2hex(bin2dec(bin_str))
It’s important to remember that both binary numbers and hexadecimal ones are treated
as strings in Matlab.
So, we can use this concept, like this:
bin_str = '10001011110101'
hex_str = dec2hex(bin2dec(bin_str))
Matlab’s answer is:
hex_str = 22F5
Solution 2.
Now, let’s say that we want to explore how the binary groups are separated to form
the hex symbols and we want to manipulate our own strings (binary and
hexadecimal).
We can develop a function to translate the table shown before. Our proposed method uses
a switch-case structure.
% Binary to Hexadecimal conversion
function h = b2h(b)
switch b
case {'0', '00', '000', '0000'}
h = '0';
case {'1', '01', '001', '0001'}
h = '1';
case {'10', '010', '0010'}
h = '2';
case {'11', '011', '0011'}
h = '3';
case {'100', '0100'}
h = '4';
case {'101', '0101'}
h = '5';
case {'110', '0110'}
h = '6';
case {'111', '0111'}
h = '7';
case '1000'
h = '8';
case '1001'
h = '9';
case '1010'
h = 'A';
case '1011'
h = 'B';
case '1100'
h = 'C';
case '1101'
h = 'D';
case '1110'
h = 'E';
case '1111'
h = 'F';
end
Now, we have to call the function for every 4-bit group of binary numbers. One possible
solution to separate the binary number into 4-bit groups is shown here:
bin_str = input('Enter binary number: ', 's');
i = length(bin_str);
n = ceil(i/4);
for g = n : -1 : 1
if i > 4
hex_str(g) = b2h(bin_str(i-3 : i));
i = i - 4;
else
hex_str(g) = b2h(bin_str(1 : i));
end
end
hex_str
Let’s try it.
Enter binary number: 101010
hex_str = 2A
Enter binary number: 110001011110101
hex_str = 62F5
Hex to binary: two solutions in Matlab
To convert a value from hex to binary, we first need to know what a hexadecimal
number is.
A major numbering system used in digital systems is the hex system, also known
as base 16. In this system, the numbers are counted from 0 to F. In base 16 we need 16
different symbols, decimal numbers 10 through 15 are represented by letters A through F,
respectively. The binary system (base 2) has only two symbols, '0' and '1'.
The following table shows the meaning of all the symbols in the hexadecimal numbering
system and their conversion to decimal or binary equivalents.
To convert a value from hex to binary, you merely translate each hex symbol to the
equivalent 4-bit binary group. For example, the hex number A5A5 translates into the
binary 1010010110100101 equivalent.
Solution 1.
In Matlab, we can go from decimal to binary, and then, from binary to hexadecimal.
We can embed one instruction into the other, like this:
bin_str = dec2bin(hex2dec(hex_str))
So, we can use this concept, like this:
hex_str = 'AF5'
bin_str = dec2bin(hex2dec(hex_str))
Matlab’s answer is:
bin_str = 101011110101
It’s important to remember that both binary numbers and hexadecimal ones are
treated as strings in Matlab.
Solution 2. Now, let’s say that we want to explore how the hex characters are separated to form
the binary symbols and how we can manipulate our own strings (binary and
hexadecimal).
We can develop a function to translate the table shown before. Our proposed method uses
a switch-case structure.
% Hex to binary conversion
function b = h2b(h)
switch h
case {'0'}
b = '0000';
case {'1'}
b = '0001';
case {'2'}
b = '0010';
case {'3'}
b = '0011';
case {'4'}
b = '0100';
case {'5'}
b = '0101';
case {'6'}
b = '0110';
case {'7'}
b = '0111';
case {'8'}
b = '1000';
case {'9'}
b = '1001';
case {'A', 'a'}
b = '1010';
case {'B', 'b'}
b = '1011';
case {'C', 'c'}
b = '1100';
case {'D', 'd'}
b = '1101';
case {'E', 'e'}
b = '1110';
case {'F', 'f'}
b = '1111';
end
Now, we have to call the function for every hex character in the string, to convert each to
a 4-bit binary number. One possible solution to separate the hex characters into 4-bit
groups is shown here:
hex_str = input('Enter hexadecimal number: ', 's');
n = length(hex_str);
bin_str = '';
for h = 1 : n
bin_str = [bin_str h2b(hex_str(h))];
end
bin_str
Let’s try this routine.
Enter hexadecimal number: af50
bin_str = 1010111101010000
Enter hexadecimal number: 15A7
bin_str = 1010110100111
WinSpice and Matlab working together
In this article, a Matlab routine to drive the WinSpice circuit simulator is
presented. This method can be easily adapted to simulate and drive any circuit
entered in this SPICE version. The performance of the Matlab driver is illustrated by
simulating a typical amplifier circuit using some resistors, capacitors and a transistor.
In this example we're using Matlab ver. 7.0.1 and WinSpice3 ver. 1.04.07.
For more information about Matlab, visit www.mathworks.com.
For more information about WinSpice, visit www.winspice.com.
SPICE stands for Simulation Program with Integrated Circuit Emphasis
Interchanging information between Matlab and WinSpice allows the
implementation of mathematical or optimization algorithms and graphical possibilities
not included in the circuit simulator environment itself. The approach developed here
is very flexible and utilizes the inherent capability of this SPICE simulator to execute
text files and print data to external .csv (comma separated values) files.
First, the circuit in Spice is defined (.cir file). This circuit is simulated and tested
within the WinSpice environment before any attempt is made to interact with Matlab.
Second, we prepare the output of the simulator by writing necessary data to an
external file, that is, we include 'write' commands in the .cir file, so that the results
are saved as external (.csv) text files available to Matlab.
Third, we now generate a new version of the .cir file using Matlab capabilities for
manipulating cell-arrays (string matrices), we then insert a Matlab statement to run
the Spice simulator from the command line with the .cir filename as a parameter.
After the simulation, we can read the results in the .csv files, process them and act
accordingly.
First Step:
We create, test and simulate this circuit in WinSpice:
We use these values:
R1 = 10k ohms, R2 = 5k ohms, R3 = 1k ohm,
R4 = 50 ohms, R5 = 1k ohm, R6 = 3k ohms
C1 = C2 = C3 = 10 uF
Q1 = transistor 2N2222
V1(ac) = 0.1V amplitude @ 1k Hz
V2(dc) = 30 V
The .cir file (text file) needed is:
--- Simple amplifier with Transistor ----
V1 Vin 0 dc 0 ac 1 sin(0 0.1 1e3)
V2 Vcc 0 dc 30
R1 Vcc b 10e3
R2 b 0 5e3
R3 Vcc c 1ek
R4 e Vr 50
R5 Vr 0 1e3
R6 Vout 0 3e3
C1 c Vout 10e-6
C2 Vr 0 10e-6
C3 b Vin 10e-6
Q1 c b e Q2N2222
.MODEL Q2N2222 NPN
+(IS=3.108E-15 XTI=3 EG=1.11 VAF=131.5 BF=217.5
+ NE=1.541 ISE=190.7E-15 IKF=1.296 XTB=1.5 BR=6.18
+ NC=2 ISC=0 IKR=0 RC=1 CJC=14.57E-12 VJC=.75
+ MJC=.3333 FC=.5 CJE=26.08E-12 VJE=.75 MJE=.3333
+ TR=51.35E-9 TF=451E-12 ITF=.1 VTF=10 XTF=2)
.control
AC DEC 10 10 10MEGHZ
plot vdb(Vout)
TRAN 10E-6 5E-3
plot v(Vout)
.endc
.end
The AC and Transient analysis deliver these results:
Second Step:
We include appropriate 'write' commands in the .cir file, so that the results are
saved as .csv files available to Matlab.
The control block changes into:
.control
AC DEC 10 10 10MEGHZ
write f_ac_out.csv vdb(Vout)
TRAN 10E-6 5E-3
write f_tran_out.csv v(Vout)
quit
.endc
.end
Third Step:
We now create a function (to be run by Matlab) that can reproduce the above .cir file
(simulation of the amplifier), modify relevant parameters with the command
'num2str' (which changes numbers into strings), and launch the circuit simulator.
This is the full code that accomplishes it:
function [Rac Rtran] = spice_amp(x)
% Create the file .cir to be run by WinSpice3.
% Built-in function 'num2str' is used to modify parameters
% wherever it is convenient.
b{1} = ['-------------Simple amplifier with Transistor----------- '];
b{2} = [' '];
b{3} = [' '];
b{4} = ['V1 Vin 0 dc 0 ac 1 sin(0 0.1 1e3) '];
b{5} = ['V2 Vcc 0 dc 30 '];
b{6} = [' '];
b{7} = ['R1 Vcc b 10e3 '];
b{8} = ['R2 b 0 5e3 '];
b{9} = ['R3 Vcc c ' num2str(x(1))];
b{10} = ['R4 e Vr ' num2str(x(2))];
b{11} = ['R5 Vr 0 1e3 '];
b{12} = ['R6 Vout 0 3e3 '];
b{13} = [' '];
b{14} = ['C1 c Vout 10e-6 '];
b{15} = ['C2 Vr 0 10e-6 '];
b{16} = ['C3 b Vin 10e-6 '];
b{17} = [' '];
b{18} = ['Q1 c b e Q2N2222 '];
b{19} = [' '];
b{20} = ['.MODEL Q2N2222 NPN '];
b{21} = ['+(IS=3.108E-15 XTI=3 EG=1.11 VAF=131.5 BF=217.5 '];
b{22} = ['+ NE=1.541 ISE=190.7E-15 IKF=1.296 XTB=1.5 BR=6.18 '];
b{23} = ['+ NC=2 ISC=0 IKR=0 RC=1 CJC=14.57E-12 VJC=.75 '];
b{24} = ['+ MJC=.3333 FC=.5 CJE=26.08E-12 VJE=.75 MJE=.3333 '];
b{25} = ['+ TR=51.35E-9 TF=451E-12 ITF=.1 VTF=10 XTF=2) '];
b{26} = [' '];
b{27} = ['.control '];
b{28} = ['AC DEC 10 10 10MEGHZ '];
b{29} = ['write amp_ac_out.csv vdb(Vout) '];
b{30} = [' '];
b{31} = ['TRAN 10E-6 5E-3 '];
b{32} = ['write amp_tran_out.csv v(Vout) '];
b{33} = ['quit '];
b{34} = ['.endc '];
b{35} = ['.end '];
b{36} = [' '];
% Save file .cir line-by-line
[r,c] = size(b);
fp = fopen('amplifier.cir', 'w+');
for i = 1 : c
fprintf(fp, '%s\n', b{i});
end
fclose(fp);
% Run WinSpice
% Make sure wspice3.exe and .cir files are available in this directory
! wspice3 amplifier.cir
% Read data saved in .csv files
% (assuming name termination _ac_out.csv and _tran_out.csv)
[Rac Rtran] = getWSpicedata('amp');
This is an important portion of additional code to read the .csv files.
function [Rac Rtran] = getWSpicedata(WSpiceBaseFile)
% Read csv files generated by a 'write' in a 'WSpiceBaseFile' (.cir file)
% Rac{1} = Frequency Points
% Rac{2} = AC response
% Rtran{1} = Time Points
% Rtran{2} = Tran response
ac = fopen([WSpiceBaseFile '_ac_out.csv']);
Rac = textscan(ac, '%f %*f %f %*f', 'delimiter',',','headerLines', 1);
tran = fopen([WSpiceBaseFile '_tran_out.csv']);
Rtran = textscan(tran, '%f %f', 'delimiter',',','headerLines', 1);
fclose('all');
Now, we're ready to perform some simulations driving WinSpice from Matlab.
clear; clc; close all
% We try some initial resistors
R3 = 1e3;
R4 = 50;
x = [R3 R4];
% Matlab launches the simulator including our parameters
[Ra Rt] = spice_amplifier(x);
figure
semilogx(Ra{1},Ra{2})
grid on
figure
plot(Rt{1},Rt{2})
grid on
% We try another gain modifying one of the resistors
R3 = 500;
x = [R3 R4];
[Ra Rt] = spice_amplifier(x);
figure
semilogx(Ra{1},Ra{2})
grid on
figure
plot(Rt{1},Rt{2})
grid on
For R3 = 1k and R4 = 50, the obtained results are:
For R3 = 500 and R4 = 50, the obtained results are:
We can now use WinSpice as if it was another built-in Matlab function!
This means that we can work through circuit optimization using Matlab...
We can try some numbers in our design, we can see the results and use
Matlab to modify relevant values in the circuit, in iterations.
Very powerful, isn't it?
Circuit Simulator (WinSpice and Matlab, improved interface)
In this article, an improved Matlab routine to drive the WinSpice circuit
simulator is presented. This method can also be easily adapted to simulate and
drive any circuit entered in SPICE. The concept of the Matlab driver is illustrated by
simulating a very simple RC low-pass filter. In this example we're using Matlab ver.
7.0.1 and WinSpice3 ver. 1.04.07.
A first approach to the driver was presented here.
For more information about Matlab, visit www.mathworks.com.
For more information about WinSpice, visit www.winspice.com.
SPICE stands for Simulation Program with Integrated Circuit Emphasis
Interchanging information between Matlab and WinSpice allows the
implementation of optimization algorithms and graphical possibilities not included in
the circuit simulator environment itself. The approach developed now is very flexible
and utilizes the inherent capability of this SPICE simulator to include other circuit
text files with parameters, and print data to external .csv (comma separated values)
files.
First, the circuit in Spice is defined (.cir file). This circuit is simulated and tested
within the WinSpice environment before any attempt is made to interact with Matlab.
We separate the components of interest and include them in a different .cir file
(using the .include directive in the main file).
Second, we prepare the output of the simulator by writing necessary data to an
external file, that is, we include 'write' commands in the main .cir file, so that the
results are saved as external (.csv) text files available to Matlab.
Third, we now generate a version of the .cir file that includes parameters using
Matlab capabilities for manipulating strings. We then run the circuit simulator from
the command line.
After the simulation, we can read the results in the .csv files, process them and act
accordingly.
First Step:
We create, test and simulate this simple RC circuit in WinSpice:
We initially use these values:
R = 10k ohms, C = 1 nF
The main .cir file (which is also a text file) is:
---- RC - LP filter ----
V1 Vin 0 dc 0 ac 1
.include param.cir
R vin out {RES1}
C out 0 {CAP1}
.control
AC DEC 10 10 1MEGHZ
plot vdb(out)
.endc
.end
The actual parameters are located in a separate file named 'param.cir', which in this
case only contains one line:
.param RES1=10e3 CAP1=1e-009
As expected, the AC analysis delivers this result (the cutoff frequency is about 16
KHz):
Second Step:
We include appropriate 'write' commands in the main .cir file, so that the results are
saved as .csv files available to Matlab.
The control block changes into:
.control
AC DEC 10 10 1MEGHZ
write RC_LP_filter_ac_out.csv vdb(out)
quit
.endc
.end
Third Step:
We now create a function (to be run by Matlab) that can reproduce the
secondary .cir file (including the parameters), modify relevant parameters with the
command 'num2str' (which changes numbers into strings), and launch the circuit
simulator. This is the full code that accomplishes it:
function [Rac] = WS_RC_low_pass(x)
% Create and save the file 'param.cir' to be included in
% another file to be run by WinSpice3.
% The built-in function 'num2str' is used to modify
parameters
% wherever it is convenient.
p = ['.param RES1=' num2str(x(1)) ' CAP1=' num2str(x(2))];
dlmwrite('param.cir', p, 'delimiter','');
% Run WinSpice
% Make sure wspice3.exe and .cir files are available
% in this directory
! wspice3 RC_LP_filter.cir
% Read data saved in .csv files
% (assuming name termination _ac_out.csv)
[Rac] = getWSpicedata2('RC_LP_filter');
Compare the simplicity of this code against the previously developed code.
We eliminated the need to re-build the complete '.cir' file with Matlab, and we
concentrate only on the relevant parameters.
There is an important portion of additional code to read the .csv files.
function [Rac] = getWSpicedata2(WSpiceBaseFile)
% Read csv files generated by a 'write' in a 'WSpiceBaseFile' (.cir file)
% Rac{1} = Frequency Points
% Rac{2} = AC response
ac = fopen([WSpiceBaseFile '_ac_out.csv']);
Rac = textscan(ac, '%f %*f %f %*f', 'delimiter',',','headerLines', 1);
fclose('all');
Now, we're ready to perform some simulations driving WinSpice from Matlab.
clear; clc; close all
% We try some initial components
R1 = 10e3;
C1 = 1e-9;
x = [R1 C1];
[Ra] = WS_RC_low_pass(x);
figure(1)
semilogx(Ra{1},Ra{2})
grid on
% We try another cutoff frequency by modifying the resistor
R1 = 1e3;
x = [R1 C1];
[Ra] = WS_RC_low_pass(x);
figure(2)
semilogx(Ra{1},Ra{2})
grid on
For R1 = 10k and C1 = 1 nF, the obtained result is:
For R1 = 1k and C1 = 1 nF, the obtained result is:
As before, we can now use WinSpice as if it was another built-in Matlab function!
This means that we can work through circuit optimization using functions such as
'fminbnd' or 'fminsearch'...
We can try some numbers in our design, we can see the results and use Matlab to
modify relevant values in the circuit, iteratively...
Mathematical Optimization
Matlab includes at least two standard functions intended for numerical or
mathematical optimization. These instructions are ‘fminbnd’ (for one single
variable) and ‘fminsearch’ (for one or more variables).
Built-in function ‘fminbnd’ tries to find a minimum of a function of one variable
within a fixed interval. Built-in function ‘fminsearch’ finds the minimum of a scalar
function of several variables, starting at an initial estimate. This can be also
considered as unconstrained nonlinear optimization. Both functions obtain a local
minimum, not a global one.
Since we can explore and express a function in terms of a predefined error,
minimizing this error function equals optimizing the function.
Let’s work with this expression:
It can be defined in this way:
function y = xcos2(x)
y = x*cos(2*x);
and it can be easily plotted like this:
ezplot('x*cos(2*x)')
axis([-6 6 -6 5])
grid on
We can implement a minimization method in the range [-5, 0], like this (the fminbnd
algorithm is based on golden section search and parabolic interpolation):
options = optimset('Display','iter','TolX',0.001);
[xc, FunVal, EF, output] = fminbnd(‘xcos2’, -5, 0, options)
Matlab displays the following answer. We get the number of times that the function was
evaluated, the point of evaluation and the function value at each iterate.
Func-count x f(x) Procedure
1 -3.09017 -3.07384 initial
2 -1.90983 1.48735 golden
3 -3.81966 -0.813651 golden
4 -3.02998 -2.95481 parabolic
5 -3.21391 -3.18035 parabolic
6 -3.22291 -3.18038 parabolic
7 -3.21865 -3.1805 parabolic
8 -3.21832 -3.1805 parabolic
9 -3.21899 -3.1805 parabolic
Optimization terminated:
the current x satisfies the termination criteria using
OPTIONS.TolX of 1.000000e-003
xc = -3.2187
FunVal = -3.1805
EF = 1
output =
iterations: 8
funcCount: 9
algorithm: 'golden section search, parabolic
interpolation'
message: [1x112 char]
The value xc = -3.2187 is the best value found after our mathematical optimization. If we
change the ‘TolX’ parameter of the options included in the optimization function
(fminbnd), we get a different amount of function evaluations and, naturally, a slightly
different minimum value. We must be aware that changes in tolerances naturally affect
our results.
options = optimset('Display','iter','TolX',0.1);
Func-count x f(x) Procedure
1 -3.09017 -3.07384 initial
2 -1.90983 1.48735 golden
3 -3.81966 -0.813651 golden
4 -3.02998 -2.95481 parabolic
5 -3.21391 -3.18035 parabolic
6 -3.24725 -3.17502 parabolic
7 -3.18058 -3.17092 parabolic
Optimization terminated:
the current x satisfies the termination criteria using
OPTIONS.TolX of 1.000000e-001
xc = -3.2139
FunVal = -3.1804
EF = 1
output =
iterations: 6
funcCount: 7
algorithm: 'golden section search, parabolic
interpolation'
message: [1x112 char]
If we now change the range of exploration to [0, 6], we find another minimum:
Func-count x f(x) Procedure
1 3.81966 0.813651 initial
2 6.18034 6.05006 golden
3 2.36068 0.0211764 golden
4 2.47085 0.561649 parabolic
5 1.45898 -1.42265 golden
6 1.66467 -1.63542 parabolic
7 1.69841 -1.64339 parabolic
8 1.73174 -1.6428 parabolic
Optimization terminated:
the current x satisfies the termination criteria using
OPTIONS.TolX of 1.000000e-001
xc = 1.6984
FunVal = -1.6434
EF = 1
output =
iterations: 7
funcCount: 8
algorithm: 'golden section search, parabolic
interpolation'
message: [1x112 char]
Now, let’s explore the same function with fminsearch. We’re going to run different
starting points, with this code:
fun = 'xcos2';
options = optimset('Display','iter','TolX',0.1);
i = 1;
for sx = -5 : .1 : 5
[xc, FunVal, EF, output] = fminsearch(fun, sx,
options);
x(i) = sx;
xo(i) = xc;
oi(i) = output.iterations;
of(i) = output.funcCount;
i = i+1;
end
We get these graphics:
These graphics say that if we start with x = -3, the minimum found after our
mathematical optimization is y = -3.22, it takes 6 iterations to reach that value, and 12
function evaluations are needed to reach that minimum. If we start with x = 4, the
minimum found is 4.8, it takes 9 iterations, and 18 function evaluations to reach that
minimum.
We must be very aware that different initial conditions and tolerances lead us to
different results. Mathematical optimization is not straigthforward most of the times.
Permutations and Combinations
This algorithm (program in Matlab) calculates the number of permutations and
combinations of N objects taken D at a time.
The full Matlab code is:
% Clears variables and screen clear; clc
% Asks user for input n = input('Total number of objects: ');
d = input('Size of subgroup: ');
% Computes and displays permut. according to basic formulas p = 1;
for i = n - d + 1 : n
p = p*i; end
str1 = [num2str(p) ' permutations'];
disp(str1)
% Computes and displays combin. according to basic formulas str2 = [num2str(p/factorial(d)) ' combinations'];
disp(str2)
Example 1:
How many permut. and combin. can be made of the 26 letters of the alphabet,
taking five at a time?
We run the code above and enter:
Total number of objects: 26
Size of subgroup: 5
The answer is:
7893600 permutations
65780 combinations
Example 2:
How many different ways can 12 computers be repaired if the workshop can only
support 2 at a time?
We run the Matlab m-file above and enter:
Total number of objects: 12
Size of subgroup: 2
The answer (with no doubt) is:
132 permutations
66 combinations
Normal Distribution
This algorithm (program in Matlab) calculates the probability and frequency of given
values on a standard normal distribution curve (Gauss’ bell).
You have to enter the mean, the standard deviation and the value of interest. No special
toolboxes or strange instructions are used.
Standard Normal distribution
The shaded area represents the probability of ‘x’, and its frequency is ‘y’.
The normal probability is approximated using the following formula:
probability = 1 – r(a1t + a2t2 + a3t
3) + eps
where:
a1 = 0.4361836
a2 = -0.1201676
a3 = 0.9372980
t = 1/(1 + 0.33267x)
eps < 10-5
This is the Matlab code to accomplish the task,
% Clears screen and deletes all the variables in the workspace
clc; clear;
% Asks the user for input
m = input('Mean: ');
s = input('Std. Dev: ');
y = input('x = ');
% Calculates the frequency (y coordinate)
y = abs((y - m)/s);
r = exp(-y^2/2)/sqrt(2*pi);
str = ['Frequency: ' num2str(r)];
disp(str)
z = y;
% Approximates probability (area under curve)
y = 1/(1 + 0.33267*abs(y));
a1 = 0.4361836;
a2 = -0.1201676;
a3 = 0.9372980;
t = 1 - r*(a1*y + a2*y^2 + a3*y^3);
if z < 0
t = 1 - t;
end
str = ['Probability: ' num2str(t)];
disp(str)
Example 1:
The mean instructions per millisecond (IPMS) of a certain type of modern computers is
150. The standard deviation is 15 IPMS. If the IPMS are normally distributed, what is the
probability that a computer executes between 150 and 180 instructions per millisecond?
Easy. Run the Matlab code above and enter...
Mean: 150
Std. Dev: 15
x = 180
The handy Matlab response is
Frequency: 0.053991
Probability: 0.97724
Example 2:
What if we need to know the probability of an execution of 130 and 150 instructions per
milliseconds for the same type of modern computers?
Don’t worry, Matlab is here...
Mean: 150
Std. Dev: 15
x = 130
Again, the handy response is
Frequency: 0.16401
Probability: 0.9088
Binomial Distribution
When a binomial distribution of events is being considered, we can use this
algorithm to calculate the probability of obtaining a given number of successes in a
given number of Bernoulli trials. It is necessary to provide the probability of succes
on a single trial. We don't use any special toolbox or instruction here.
First, we can clear the current Matlab workspace and also the screen, to keep things
clean...
clear; clc;
Then, we ask the user to enter the three required numbers... We use the 'input'
function in Matlab for this purpose,
n = input('Number of trials: ');
x = input('Exact number of successes: ');
p = input('Probability of success: ');
Now, this is the main algorithm to solve the problem,
m1 = log(factorial(n));
m2 = log(factorial(x));
m3 = log(factorial(n-x));
r = exp(m1 - m2 - m3 + x*log(p) + (n-x)*log(1-p));
Finally, we display the answer (the instruction 'num2str' transforms a number into a
string),
str = ['Probability of ' num2str(x) ' successes in ' ...
num2str(n) ' trials: ' num2str(r)];
disp(str)
See the example running...
What is the probability of getting three heads in five tosses of a fair coin?
Number of trials: 5
Exact number of successes: 3
Probability of success: .5
And the Matlab response is
Probability of 3 successes in 5 trials: 0.3125
What is the probability that in five rolls of a fair die, a number 1 appears
twice?
Number of trials: 5
Exact number of successes: 2
Probability of success: 1/6
And the response is
Probability of 2 successes in 5 trials: 0.16075
Poisson Distribution
Using the Poisson distribution, this program calculates the probability of an
event occurring a given number of times. You must know the expected frequency
of the event. No special instruction or toolboxes is used, so you can adapt the code
to any other programming language...
This is the code in Matlab:
% Clears screen and deletes all the variables in the
workspace
clc; clear;
% Asks the user for input
f = input('Calculated Frequency: ');
x = input('Test Frequency: ');
% Computes probability
a = log(factorial(x));
a = exp(-f + x*log(f) - a);
% Displays result
str = ['Probability of ' num2str(x) ' occurrences = '
num2str(a)];
disp(str)
The instruction 'num2str' (number-to-string) transforms a number into a string, to be
used along with the rest of the output message, launched by instruction 'disp'.
Example 1:
Some programs are downloaded into 2000 computers. The probability of any one
computer getting infected by a virus is 0.001 (nothing to do with reality, ok?) Thus we
can expect 2 computers will suffer a bad reaction (0.001 x 2000 = 2). What is the
probability that 4 computers will get infected?
We launch our code above and enter known data as input:
Calculated Frequency: 2
Test Frequency: 4
Matlab answer is
Probability of 4 occurrences = 0.090224
Example 2:
What is the probability that only one computer will get infected?
We re-launch our code and enter data:
Calculated Frequency: 2
Test Frequency: 1
Matlab answer is
Probability of 1 occurrences = 0.27067
F-distribution
This algorithm (program in Matlab) calculates percentile values for given values on
an F-distribution curve. You must provide the value of F, the degrees of
freedom in the numerator and the degrees of freedom in the denominator.
This Matlab code does not use any special toolbox, it uses only standard built-in
functions.
The F-distribution curve
The area of the shaded region represents the percentile. The tail-end value (the area
of the unshaded region) is also calculated.
The F-distribution function is approximated using the following formula:
where,
a1 = 0.196854
a2 = 0.115194
a3 = 0.000344
a4 = 0.019527
d1 = degrees of freedom in numerator
d2 = degrees of freedom in denominator
This is the Matlab script to perform the task:
clc; clear
% Asks the user for the relevant input f = input ('Enter F-value: ');
d1 = input('Enter degrees of freedom in numerator: ');
d2 = input('Enter degrees of freedom in denominator: ');
x = 1;
% Computes using inverse for small F-values if f < 1
s = d2;
t = d1;
z = 1/f; else s = d1;
t = d2;
z = f; end j = 2/(9*s);
k = 2/(9*t);
% Uses approximation formulas y = abs((1 - k)*z^(1/3) - 1 + j)/sqrt(k*z^(2/3) + j); if t < 4
y = y*(1 + 0.08*y^4/t^3); end
a1 = 0.196854;
a2 = 0.115194;
a3 = 0.000344;
a4 = 0.019527;
x = 0.5/(1 + y*(a1 + y*(a2 + y*(a3 + y*a4))))^4;
x = floor(x*10000 + 0.5)/10000;
% Adjusts if inverse was computed if f < 1
x = 1 - x; end
% Displays results str1 = ['Percentile = ' num2str(1-x)];
str2 = ['Tail end value = ' num2str(x)];
disp(str1)
disp(str2)
Example 1:
What is the percentile on an F-distribution curve when the F-value is 0.474 and the
degrees of freedom are 1 and 18?
We run the code above and enter the data:
Enter F-value: .474
Enter degrees of freedom in numerator: 1
Enter degrees of freedom in denominator: 18
Matlab response is:
Percentile = 0.4937
Tail end value = 0.5063
Example 2:
What is the percentile the F-value is 23.7 and the degrees of freedom are 3 and 6?
We run the code above and enter the data:
Enter F-value: 23.7
Enter degrees of freedom in numerator: 3
Enter degrees of freedom in denominator: 6
Matlab response is:
Percentile = 0.9984
Tail end value = 0.0016
Student's t distribution
This algorithm (Matlab program) calculates right-tail values for points on a t
distribution curve. You must provide the value of t and the degrees of freedom.
Student's t-distribution curve
The shaded area represents the right-tail value for t.
The right-tail value is approximated using the following formula:
where
a1 = 0.196854
a2 = 0.115194
a3 = 0.000344
a4 = 0.019527
d = degrees of freedom
The Matlab program is:
% Clears screen and deletes all the variables in the
workspace
clc; clear;
% Asks the user for input
t = input('T-value: ');
d = input('Degrees of freedom: ');
x = 1;
y = 1;
t = t^2;
% Computes using inverse for small T-values
if t < 1
s = d;
r = y;
z = 1/t;
else
s = y;
r = d;
z = t;
end
j = 2/(9*s);
k = 2/(9*r);
% Computes using approximation formulas
l = abs((1 - k)*z^(1/3) - 1 + j)/sqrt(k*z^(2/3) + j);
if r < 4
l = l*(1 + 0.08*l^4/r^3);
end
a1 = 0.196854;
a2 = 0.115194;
a3 = 0.000344;
a4 = 0.019527;
x = 0.25/(1 + l*(a1 + l*(a2 + l*(a3 + l*a4))))^4;
x = floor(x*10000 + 0.5)/10000;
% Adjusts if inverse was calculated
if t < 1
x = 1 - x;
end
% Displays result
str = ['Rigth tail value: ' num2str(x)];
disp(str)
Example 1:
What is the right-tail value when the t-value is 2.921 and there are 16 degrees of
freedom?
We run the code above and enter data:
T-value: 2.921
Degrees of freedom: 16
Matlab answer is
Rigth tail value: 0.0049
Example 2:
T-value is 11.178, with 5 degrees of freedom. What’s the tail value?
Running the program and entering appropriate data, we get:
T-value: 11.178
Degrees of freedom: 5
Rigth tail value: 0.0002
Chi-square distribution
This program calculates the tail-end and percentile values for points on a Chi-square
(X2) distribution curve. You must provide the value of X
2 and the degrees of freedom.
No special instruction or Matlab toolbox is used.
Chi-square distribution curve
The unshaded area represents the tail-end value of X2. The shaded area represents the
percentile.
The X2 distribution function is calculated using the following formulas:
with v odd,
with v even,
where
v = degrees of freedom
Since the summation in the calculation of Z cannot actually extend to infinity, we stop
summation when the next term is less than a chosen level of precision. Our precision is
limited to approx. 1×10-7
.
The Matlab program to accomplish this, is:
% Clears screen and variables in workspace clc; clear
% Asks the user for the relevant input v = input('Degrees of freedom: ');
w = input('Chi-square: ');
% Calculates the denominator product r = 1; for i = v : -2 : 2
r = r*i; end % Calculates the numerator product k = w^(floor((v+1)/2))*exp(-w/2)/r;
% If degrees of freedom are odd, then uses the pi factor if floor(v/2) == v/2
j = 1; else j = sqrt(2/(w*pi)); end l = 1;
m = 1;
v = v + 2;
m = m*w/v;
% Summation factor while m >= 1e-7
l = l + m;
v = v + 2;
m = m*w/v; end
% Displays results str = ['Tail end value: ' num2str(1-j*k*l)];
disp(str)
str = ['Percentile: ' num2str(j*k*l)];
disp(str)
Example:
A X2 statistic for a given study was computed to be 2.571108 with one degree of freedom.
What are the tail-end and percentile values?
Running the Matlab program above, we enter and get:
Degrees of freedom: 1
Chi-square: 2.571108
Tail-end value: 0.10883
Percentile: 0.89117
Random Numbers and Simulations
We’ll use Matlab to generate random numbers so that we can discuss its
statistical capabilities and explore some simulations, too. We’ll start with a
definition of some statistical quantities.
In these sections we consider a set of data which we’ll refer to as xi where i = 1 to
N. We’ll not make any assumptions about the data in terms of its source or its form.
Averages The mean is given by adding up all the data and dividing by the number of objects in
the set. This is written as:
There’s a Matlab command which does exactly this: ‘mean(x)’.
There’s another related command, which is ‘median(x)’ and it’s the value in the ‘middle’
of a vector when the data has been sorted. If there’s an odd number of pieces of data this
is well defined, however if the number is even then the mean of the data at each end of
the central interval is given, for example the median of [1 2 3 4] is (2+3)/2 = 2.5 whereas
the median of [1 3 5] is 3. Note that the median can equal the mean but it is not
necessarily so.
This short code
x = [4 0 5 3 2 1 3 5 9 3 7 5 6 8 2 0];
mn = mean(x)
md = median(x)
results in
mn = 3.9375
md = 3.5000
Other Statistical Measures
In the previous section we have discussed averages of a set of data but there are more
measures available, for instance these two distributions have the same mean but are
obviously different in form:
The first curve is narrower than the second and this is quantified using the variance,
which is given by
We can interpret this value as the ‘mean’ of the sum of the squares of the distance
from the mean. There’s the Matlab command ‘var(x)’ to calculate this number.
Another related measure is the standard deviation, which is the square root of the
variance, ‘std(x)’. This also is a measure of the width of the distribution and has the
advantage that it has the same units as the data.
There are other measures, some of which are called ‘higher-order moments’
(mean is first and variance is second): the skewness is the third, and the
kurtosis is the fourth.
Random Numbers and Distributions
In order to generate random numbers we can use various commands available
in Matlab. We won’t worry about how this is done or the technical aspects of the seeding.
We’re going to start with the simple command ‘rand’ which returns a random number
between zero and one.
If we rolled a die a large number of times, and we used the above formulas to calculate
the mean and variance, we’d expect to obtain a mean = 3.5 and a variance = 2.916. Let’s
try it with Matlab.
This is a simple dice program:
function n = roll_d()
n = ceil(rand*6 + eps);
We can use it like this:
% Roll the die and keep the values in d
for i = 1 : 1000
d(i) = roll_d;
end
% Find how many appearences of each possible value
for i = 1 : 6
v(i) = length(find(d==i));
end
% Display results
disp(['Mean = ' num2str(mean(d))])
disp(['Variance = ' num2str(var(d))])
bar(v)
The results are:
Mean = 3.508
Variance = 2.7827
Obviously, every time that we run the program we’ll get different results, since we are
dealing with random numbers, but the results are similar to what we expected.
We can use this process for other ‘chance games’, for example tossing a coin:
function r = toss()
p = ['heads'; 'tails'];
i = ceil(rand*2 + eps);
r = p(i,:);
This can then be called just using 'toss' which generates either 'heads' or 'tails'.
Normal Distribution
A normal distribution has two parameters associated with it: the mean and the variance.
The command ‘randn’ generates random numbers which have a mean of zero and a
variance of unity.
By typing
x = randn(1, 1000);
hist(x,12)
we set up an array and produce the plot
These lines on the command window
mn = mean(x)
v = var(x)
produce, in our case
mn = 0.0016
v = 0.9908
which are values very close to what was expected.
There are many problems which require simulation, largely due to that it's not viable to
actually run the real or physical tests. These cases cover things from experiments on
aircrafts or cars (which are too dangerous or expensive) to population studies and
economic strategies.