0% found this document useful (0 votes)
161 views18 pages

04 Matlab and Roots III

The document discusses functions and function handles in MATLAB. It provides an example function PR that calculates pressure ratio given a Mach number. It discusses how to plot this function using function handles and the fplot command. It also provides a vectorized version of the PR function called PRv that works for vector inputs. Finally, it discusses creating your own functions like fplot and ftable to plot and tabulate other functions.

Uploaded by

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

04 Matlab and Roots III

The document discusses functions and function handles in MATLAB. It provides an example function PR that calculates pressure ratio given a Mach number. It discusses how to plot this function using function handles and the fplot command. It also provides a vectorized version of the PR function called PRv that works for vector inputs. Finally, it discusses creating your own functions like fplot and ftable to plot and tabulate other functions.

Uploaded by

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

Problem: Aircraft are typically equipped with a static port and a Pitot tube.

The
static port measures the static pressure (P) of the airflow past the aircraft and the
Pitot tube measures the stagnation pressure (Po) of this flow. If an aircraft's speed
(expressed as a Mach number) is known, the ratio of the two pressures (Po/P) can
be computed:
for M <= 1:

PR( M ) = (1 + 0.2M 2 )

for M >= 1:

PR( M ) = (1.2 M 2 )

3.5

3.5

((7 / 6)M

1 / 6)

2.5

where M is the aircraft's Mach number


Typically the situation is the other way around. The pressure ratio is known (from
the static port and Pitot tube measurements) and the Mach number must be
determined.
This is another root finding problem. We need to find M such that
PR(M) observed pressure ratio = 0
F(M) = 0

Function PR could be implemented as an anonymous function (with a little


trickiness) but a function m-file is more appropriate.
function [ ratio ] = PR( M )
%PR Given a Mach number, returns the corresponding pressure ratio
% Usage: [ ratio ] = PR( M )
% Inputs: M = Mach number
% Outputs: ratio = pressure ratio (stagnation pressure / static pressure)
if M <= 1
ratio = (1 + 0.2 * M^2)^3.5;
else
ratio = (1.2 * M^2)^3.5 * ((7/6)* M^2 - 1/6)^-2.5;
end
end

The Matlab if is logically equivalent to a C++ if. Only the details differ.
if M <= 1
% round brackets around expression allowed but not required
ratio = (1 + 0.2 * M^2)^3.5;
else
ratio = (1.2 * M^2)^3.5 * ((7/6)* M^2 - 1/6)^-2.5;
end
Relational and logical operators:
==
~=
<
>
<=
>=

is equal to
is not equal to ** different from C++ **
is less than
is greater than
is less than or equal to
is greater than or equal to

~
&&
||

NOT ** different from C++ **


AND note: & is array version
OR
note: | is array version

The script file below plots the pressure ratio for Mach numbers from 0 to 7
(world records: the X-15 rocket plane achieved Mach 6.72; SR-71 Blackbird
jet plane achieved Mach 3.3), reads in a pressure ratio, and outputs the
corresponding Mach number.
figure (1);
fplot (@PR, [0, 7]); % Note the @
xlabel ('Mach Number');
ylabel ('Pressure Ratio');
grid on;
ratio = input ('Enter pressure ratio: ');
% define function for root finding
f = @(M) PR(M) - ratio;
M = fzero (f, [0 7]);
fprintf ('The mach number is %f\n', M);

Functions like fplot expect to be given a function handle.


Anonymous functions:
The function itself is anonymous
What looks like a function name is actually the name of a function handle
>> f = @(x) x + 4;
>>fplot (f, [6 20]);

% f is a function handle
% which is exactly what fplot expects

m-file functions:
The name relates to the function itself
When a function handle is required, one must be created by using @
>>fplot (@PR, [0, 7]); % @PR creates a function handle
Built-in functions:
These are also named
>>fplot (@sin, [0, 7]); % a function handle must be created

Function PR is not vector friendly. Unlike most Matlab functions, it will not work
properly if it is given a vector of input values.
Part of the problem is the mathematical expressions, but no amount of adding
dots to them is going to improve the overall situation.
The real problem is that if M is a vector if M < 1 doesnt make much sense
Comparing a vector to a scalar produces a vector of 1s (true) and 0s (false)
>> M = [ 0.2 0.5 1 2 3 ];
>> M <= 1
ans =
1 1 1 0 0
A vector is considered to be true only if all of its element are non zero. This means
that the formula for M <= 1 will get used only if ALL of the Mach values in the
input vector are <= 1.

Suppose that we would like to create a plot of PR vs M using function plot.


Creating a collection of x values is easy enough
M = linspace (0, 7, 100); % 100 points between 0 and 7
Creating corresponding y values is a bit harder because function PR isnt vector
friendly. A loop is required
for k = 1 : length(M) % from 1 to length(M) in steps of 1
ratio(k) = PR(M(k));
end
Once x and y values exist the plotting is straightforward
figure (1)
plot (M, ratio);
xlabel ('Mach Number');
ylabel ('Pressure Ratio');
grid on;
This code takes advantage of the fact that vectors grow automatically when a value is
assigned to a previously non-existent element.

Function length returns the length of a row or column vector.


Function size returns a two element row vector containing the dimensions of a
variable (number of rows and numbers of columns).
>> A = [1 3 5 7];
>> length(A)
ans =
4
% A is 4 elements long
>> size(A)
ans =
1 4 % A has 1 row and 4 columns
>> x = 4;
>> size(x)
ans =
1 1

% remember that Matlab treats scalars as 1x1 arrays

Having vectors grow one element at a time is not very efficient. It is much
better create a vector of the required size and then fill in the values. This is
called preallocation.
M = linspace (0, 7, 100); % 100 points between 0 and 7
ratio = ones(size(M)); % preallocate vector for efficiency
for k = 1 : length(M) % from 1 to length(M) in steps of 1
ratio(k) = PR(M(k));
end
Function ones creates an array full of ones. It accepts a two element row
vector containing the dimensions (# of rows, # of columns) of the array.
>> ones([2 3])
ans =
1
1
1
1

1
1

Function zeros (note that Americans dont spell properly) is analogous but
creates an array of zeroes.

Function PRv does the same job as PR did but works properly when
the input value is a vector.
function [ ratio ] = PRv( M )
%PRv Given a Mach number, returns the corresponding pressure ratio
%
Vector friendly version of PR
% Usage: [ ratio ] = PRv( M )
% Inputs: M = Mach number (may be a vector of Mach numbers)
% Outputs: ratio = pressure ratio (stagnation pressure / static pressure)
ratio = ones(size(M)); % preallocate for efficiency
for k = 1:length(M)
if M(k) <= 1
ratio(k) = (1 + 0.2 * M(k)^2)^3.5;
else
ratio(k) = (1.2 * M(k)^2)^3.5 * ((7/6)* M(k)^2 - 1/6)^-2.5;
end
end
end

The Matlab for loop is actually


for var = array
...
end
The loop is executed once for each value in the array.
val1:val2 creates an array of values from val1 to val2 in steps of 1:
>> A = 1:4
A=1 2 3

A step size may be specified:


>> A = 1:3:10
A = 1 4 7 10
The series stops at the last value that does not exceed the upper limit:
>> A = 1:3:9
A=1 4 7

Summary of ways of creating vectors:


>> v1 = [2 3 4 5 6]
% the values may be separated with commas if desired
v1 =
2 3 4 5 6
>> v2 = linspace (2, 6, 5) % 5 evenly spaced values between 2 and 6
v2 =
2 3 4 5 6
>> v3 = 2 : 6
% from 2 to 6 in steps of 1 (the default)
v3 =
2 3 4 5 6
>> v4 = 1 : 2 : 7
% from 1 to 7 in steps of 2
v4 =
1 3 5 7
>> v5 = ones([1 5])
% row vector of ones
v5 =
1 1 1 1 1
>> v6 = zeros([1 5])
% row vector of zeroes
v6 =
0 0 0 0 0
>> v7 = ones(size(v5))
% size specified using function size
v7 =
1 1 1 1 1

It might be nice to have a function that converts pressure ratios to Mach numbers
function [ M ] = PR2Mach( ratio )
%PR2Mach Given a pressure ratio, returns the corresponding Mach number
% Usage: [ M ] = PR2Mach( ratio )
% Inputs: ratio = pressure ratio (stagnation pressure / static pressure)
% Outputs: M = Mach number
if ratio < PR(0) || ratio > PR(7)
error 'Pressure ratio is not reasonable.'; % abort function execution
end
% define function for root finding
f = @(M) PR(M) - ratio;
% find root
M = fzero (f, [0 7]);
end
Testing: What should PR2Mach(PR(2)) produce?

Matlab also has while loops and breaks (just like C++).
The script (InteractivePR.m) below uses an infinite loop to read in pressure
ratios and output Mach numbers until a ratio that is less than 1 is entered.

while true % true is 1, false is 0


ratio = input ('Enter pressure ratio: ');
if ratio < 1; break; end % could be return instead of break
fprintf ('The mach number is %f\n', PR2Mach(ratio));
end

Function inputs may be functions. If fplot was not part of Matlab, we


could easily create something very similar.
function [ ] = DIYfplot( f, range )
%DIYfplot Do it yourself version of fplot. Plots a function over a range.
% Usage: DIYfplot( f, range )
% Inputs: f = function to be plotted (need not be able to handle vectors)
%
range = two element vector containing start and end of range
% No outputs (like a C++ void function)
n = 100; % number of points
x = linspace (range(1), range(2), n); % generate x values
% generate y values
y = zeros ([1 n]); % preallocate for efficiency
for k = 1 : n
y(k) = f(x(k));
end
plot (x, y);
end

Just like the built-in fplot, our version can be used to plot file functions, built-in
functions, and anonymous functions.
In the first two cases an @ is required (see previous slides).
>> DIYfplot( @PR, [0 7])
>> grid on
>> xlabel ('Mach number');
>> ylabel ('Pressure Ratio');

>> DIYfplot( @sin, [0 4*pi])

>> f = @(x) x^3 + 2* x^2 + 7;


>> DIYfplot( f, [-5 5])
Note: We could also create our own version of fzero and will soon be doing
exactly this.

Another potentially useful function is shown below. It produces a table of


function values.
function [ ] = ftable( f, vector )
%ftable Produces table of function values.
% Usage: ftable( f, vector )
% Inputs: f = function to be tabulated
%
vector = vector of values for the independent variable
% No Outputs (like a C++ void function)
fprintf (' Independent

Dependent\n');

% Note: this loop can be simplified


for k = 1 : length(vector)
x = vector(k);
y = f(x);
fprintf ('%12f%16f\n', x, y);
end
end

Sample usage:
>> ftable (@PR, 1:0.5:6)
Independent
1.000000
1.500000
2.000000
2.500000
3.000000
3.500000
4.000000
4.500000
5.000000
5.500000
6.000000

Dependent
1.892929
3.413275
5.640441
8.526136
12.060965
16.242001
21.068081
26.538665
32.653474
39.412352
46.815206

Improved Loop:
The loop in the function can be reduced to:
for x = vector
fprintf ('%12f%16f\n', x, f(x));
end

You might also like