Bible of Matlab
Short Description
matlab...
Description
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
-0.6908
-0.8893
-0.9900
>> cos(r) ans = -0.4161 >> 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: >> print 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 + 3x3 − 10x2 − 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 b
a b = =
= 2x^3 + 2x^2 - 2x - 2 = 2x - 2 [2 2 -2 -2]; [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] ap = polyder(a)
(meaning a = 2x3 + 2x2 - 2x - 2)
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: (assuming that x and y have values already):
, can be achieved as follows
>> 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: that x has a value already):
, can be coded as follows (assuming
>>(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-byelement operators): z = m.^2 z= 1.0e+005 * 0.0000 0.0000 >>
0.0001 0.0108
0.0000 0.2067
0.0000 0.0000 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 318 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 3
2 4
b= 5 7
6 9
c= -1 -3
-5 9
d= -5 0 0 -10
4 3
e= 8 3 9
4 8 1
6 1 8
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 -15 -40
10 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 3
2 4
h= -1 -3 1 3 5 7
-5 9 2 4 6 9
5 7
6 9
-1 -3
-5 9
We extract all the columns in rows 2 to 4 of matrix h i = h(2:4, :) Matlab produces: i= -3 1 3
9 2 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 -3 1 3 5 7
-5 9 2 4 6 9
3 4 7 9 -3 9
Extract columns 2 and 3 from rows 3 to 6. j = [h(3:6, 2:3)] And Matlab produces: j=
2 4 6 9
7 9 -3 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 w2 = 0
0
1
-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 successive values 0, 1, 2, ..., n-1 in the above formula.
, let k take on the
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.1429 0.1250 0.1111
0.0909 0.0833 0.0769 0.0714
0.0625 0.0588 0.0556 0.0526
0.0476 0.0455 0.0435 0.0417
0.0385 0.0370 0.0357 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 2
1 0 3
4 1 -1
-2 0 -1 3 2
-1 2 1 0 1
2 1 4 1 2
1 2 0
2 -1 -2
B =
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 1 -7 ans = -1 1 -7 >>
6 -1 1
26 6 -1
6 -1 1
26 6 -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 counter counter counter counter counter >>
is is is is is is
still > 95 still > 95 still > 95 still > 95 still > 95 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 elementby-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 > A & B ans = 0 1 0 1
0 1 0 0
0 0 0 1
0 0 0 0
>>
Example: If vector x is: x= 0
1
2
3
0
0
0
and vector y is: y= 1
2
3
Then, the AND operation between x and y is: >> x & y ans = 0
1
1
0
0
>>
Logical OR A 0 0 1 1
B 0 1 0 1
A|B 0 1 1 1
A | B performs a logical OR of arrays A and B and returns an array elements set to either logical 1 (TRUE) or logical 0 (FALSE).
containing
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 1 0 1
0 1 0 1
1 0 0 1
and matrix B is:
1 0 0 1
B= 0 1 0 1
0 1 1 0
0 1 0 1
0 1 1 0
Then, the OR operation between A and B is: >> A | B ans = 0 1 0 1
0 1 1 1
1 1 0 1
1 1 1 1
>>
Example: If vector x is: x= 0
1
2
3
0
0
0
and vector y is: y= 1
2
3
Then, the OR operation between x and y is: >> x | y ans = 1
1
1
1
0
>>
XOR - Logical EXCLUSIVE OR A 0 0 1 1
B 0 1 0 1
x o r (A,B) 0 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 1 0 1
0 1 0 1
1 0 0 1
1 0 0 1
and matrix B is: B= 0 1 0 1
0 1 1 0
0 1 0 1
0 1 1 0
Then, the logical EXCLUSIVE OR between A and B is: >> xor(A,B) ans = 0 0 0 0
0 0 1 1
1 1 0 0
1 1 1 1
>>
Example: If vector x is: x= 0
1
2
and vector y is:
3
0
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 0 1
~A 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 1 0 1
0 1 0 1
1 0 0 1
1 0 0 1
Then, the NOT A is produced: >> ~A ans = 1 0 1 0
1 0 1 0
0 1 1 0
>>
Example: If vector x is:
0 1 1 0
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 -3 2
-2 2 4 -3 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: funcCount: algorithm: message:
121.00 243.00 'Nelder-Mead simplex direct search' [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: funcCount: algorithm: message:
75.00 151.00 'Nelder-Mead simplex direct search' [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.7500 1.0000
-0.5385 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')-1S-1U-1 = VS-1U' since (AB)-1 = B-1A-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-1b = VS-1U'b that would otherwise be usolvable. Example:
Let's find with Matlab the singular value decomposition of A = [ 0 -2 1
-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.9129 -0.3651
-0.8944 0.0000 0.4472
0.4082 0.4082 0.8165
S = 2.4495 0 0
0 1.0000 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 ans = 1 0
-0.0000 1.0000 -0.0000
-0.0000 -0.0000 1.0000
0 1
ans = -0.0000 -2.0000 1.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 pointmarker style.
Examples: plot(x,y) plot(x,y,'-.') plot(x) plot(x,y,'r--') plot(a,b,'k+')
plots plots plots plots plots
y vs x with a solid line y vs x with a dash-dot line the elements of x against their own index y vs x with a red dashed line 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 x m s
= = = =
-100; b = 100; a + (b-a) * rand(1, 500); (a + b)/2; 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 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
0
1
2
3
4
y= 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
>> 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 X = -2 : [x, y] = z = .5 *
paraboloid .1 : 2; Y = X; meshgrid(X, Y); (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 'Angle Side 'Side Angle 'Angle Angle 'Side Side
of a Triangle', ... Angle',... 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) s(3) a(2) a(3) s(1) s(2)
= = = = = =
input(ea) * c; input(es); input(ea) * c; pi - a(1) - a(2); s(3) * sin(a(1)) / sin(a(3)); 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 Opposite angles... a = 25.7000 33.9200
21.6700 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 2 9
3 2 3 8
4 6 1 0
5 1 7 2];
[l,u] = lu(M) l*u Matlab answer is: l = 0.2222 0.3333 0.2222 1.0000
1.0000 -0.5455 1.0000 0
0.4583 1.0000 0 0
1.0000 0 0 0
9.0000 0 0
8.0000 1.2222 0
0 1.0000 6.5455
2.0000 6.5556 3.9091
u =
0
0
0
-3.7917
ans = 2.0000 3.0000 2.0000 9.0000
3.0000 2.0000 3.0000 8.0000
4.0000 6.0000 1.0000 0
5.0000 1.0000 7.0000 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.3030 -0.2020 -0.9091
0.6359 -0.4127 0.6359 -0.1450
-0.4469 -0.8144 0.0027 0.3702
-0.5959 0.2731 0.7449 -0.1241
-9.8995 0 0 0
-9.0914 1.8295 0 0
-2.8284 0.7028 -6.6713 0
-4.5457 6.9274 -2.2896 2.2595
ans = 2.0000 3.0000 2.0000 9.0000
3.0000 2.0000 3.0000 8.0000
4.0000 6.0000 1.0000 -0.0000
5.0000 1.0000 7.0000 2.0000
r =
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 0 0 0
1 1 0 0
1 2 1 0
1 3 3 1
1 1 1 1
1 2 3 4
1 3 6 10
1 4 10 20
ans =
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.2012
-0.5304 -0.6403
0.7873 -0.1632
-0.3087 0.7231
-0.4581 -0.8638
-0.3918 0.3939
-0.5321 0.2654
-0.5946 0.1684
26.3047 0 0 0
0 2.2034 0 0
0 0 0.4538 0
0 0 0 0.0380
-0.0602 -0.2012 -0.4581 -0.8638
-0.5304 -0.6403 -0.3918 0.3939
0.7873 -0.1632 -0.5321 0.2654
-0.3087 0.7231 -0.5946 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
s =
v =
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')-1S-1U-1 = VS-1U' since (AB)-1 = B-1A-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-1b = VS-1U'b that would otherwise be usolvable. Example:
Let's find with Matlab the singular value decomposition of A = [ 0 -2 1
-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.9129 -0.3651
-0.8944 0.0000 0.4472
0.4082 0.4082 0.8165
S = 2.4495 0 0
0 1.0000 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 ans = 1 0 ans = -0.0000 -2.0000 1.0000
-0.0000 1.0000 -0.0000
-0.0000 -0.0000 1.0000
0 1 -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 xvalues 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, axis([-4 title(‘y xlabel(‘x’) ylabel(‘y’)
'bo', =
x1, 4 x^3
y1,
'ro', x2, -17 – 3x
y2, +
'ro') 23]) 3’)
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 mfile: 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:
x=5 Deriv(f, x) The result is: Expected: 32
Obtained:
Deriv(f, -3) The result is: Expected: -16
Obtained:
Gradient
2
32.0000
-16.0000
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 x = [2 1.5] Grad(f, x) Expected: [-8
0]'
-4.32]'
Obtained: [0
0]'
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 builtin '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-tocartesian 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 2 3 4 5
1234 2345 4320 4567 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 2 3 4 5
12340 23452 43203 45674 98765
and the content for 'data_sheet3.txt' is dummy line 1 dummy line 2 dummy line 3 1 2 3 4 5
123 234 432 456 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 2 3 4 5
1234 2345 4320 4567 9876
12340 23452 43203 45674 98765
123 234 432 456 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 Tag String FontAngle FontSize FontWeight HorizontalAlignment
Box 1 Box 2 text1 text2 This is a great trick! (empty) italic normal 10 8 bold bold left left
Box 3 text3 (empty) normal 8 bold 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 Tag String FontAngle FontSize FontWeight ForegroundColor
Button 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 card_deck = {'ad' 'ah' 'as' '3d' '3h' '3s' '5d' '5h' '5s' '7d' '7h' '7s' '9d' '9h' '9s' 'jd' 'jh' 'js' 'kd' 'kh' 'ks' card_nr = 52;
used 'ac' '2d' '2h' '2s' '2c' ... '3c' '4d' '4h' '4s' '4c' ... '5c' '6d' '6h' '6s' '6c' ... '7c' '8d' '8h' '8s' '8c' ... '9c' '10d' '10h' '10s' '10c' ... 'jc' 'qd' 'qh' 'qs' 'qc' ... 'kc'};
% 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 % varargin
structure with handles and user data (see GUIDATA) 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 callbackfunctions 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 Position FontSize FontWeight HorizontalAllignment String
axes1 4 6 75 22
text1 84 15 23 8 10 bold left
Choose a card Don’t forget it! Concentrate...
And now you should have something similar to this figure:
pushbutton1 83 6 22 2.5 10 bold left Continue...
The editor will open with a prepared template, where you can edit the callbackfunctions 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 fourband 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 pulldown 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 case 1e5 b_str case 1e6 b_str case 1e7 b_str case 1e8 b_str case 1e9 b_str
= [bs1 bs2 '0 K']; = [bs1 '.' bs2 ' M']; = [bs1 bs2 ' M']; = [bs1 bs2 '0 M']; = [bs1 '.' bs2 ' G']; = [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 'StaticText2'. 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.5911 0.6234 -0.5694 -0.5694
+ 0.9284i - 0.9284i + 0.3423i - 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 + 3x3 − 10x2 − 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 b
a b = =
= 2x^3 + 2x^2 - 2x - 2 = 2x - 2 [2 2 -2 -2]; [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] ap = polyder(a)
(meaning a = 2x3 + 2x2 - 2x - 2)
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 = [' disp(name_str)
' name];
'...
[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 102 + 1 x 101 + 0 x 20
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 forloop, 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 + p2xn-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
View more...
Comments