AN ENGINEER’S GUIDE TO MATLAB

Slides:



Advertisements
Similar presentations
Multidimensional Array
Advertisements

COMP 116: Introduction to Scientific Programming Lecture 37: Final Review.
M AT L AB Programming: scripts & functions. Scripts It is possible to achieve a lot simply by executing one command at a time on the command line (even.
Programming with MATLAB
Chapter 7. Even in quantitative sciences, we often encounter letters and/or words that must be processed by code You may want to write code that: Reads.
Chapter 8 and 9 Review: Logical Functions and Control Structures Introduction to MATLAB 7 Engineering 161.
EGR 106 – Week 2 – Arrays Definition, size, and terminology Construction methods Addressing and sub-arrays Some useful functions for arrays Character arrays.
An Introduction to Programming with C++ Fifth Edition Chapter 4 Chapter 4: Variables, Constants, and Arithmetic Operators.
Division Example 2x - 3y + 4z = 10 x + 6y - 3z = 4 -5x + y + 2z = 3 A*X = B where A = B = >> X = A\B X =
An Introduction to Programming with C++ Fifth Edition Chapter 4 Chapter 4: Variables, Constants, and Arithmetic Operators.
MATLAB Cell Arrays Greg Reese, Ph.D Research Computing Support Group Academic Technology Services Miami University.
Chapter 8 Arrays and Strings
JavaScript, Third Edition
Introduction to MATLAB MECH 300H Spring Starting of MATLAB.
Introduction to Array The fundamental unit of data in any MATLAB program is the array. 1. An array is a collection of data values organized into rows and.
Introduction to MATLAB ENGR 1187 MATLAB 1. Programming In The Real World Programming is a powerful tool for solving problems in every day industry settings.
Input/Output  Input/Output operations are performed using input/output functions  Common input/output functions are provided as part of C’s standard.
Chapter 4 MATLAB Programming Combining Loops and Logic Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display.
M-files While commands can be entered directly to the command window, MATLAB also allows you to put commands in text files called M- files. M-files are.
INTRO TO PROGRAMMING Chapter 2. M-files While commands can be entered directly to the command window, MATLAB also allows you to put commands in text files.
Slide deck by Dr. Greg Reese Miami University MATLAB An Introduction With Applications, 5 th Edition Dr. Amos Gilat The Ohio State University Chapter 4.
REVIEW 2 Exam History of Computers 1. CPU stands for _______________________. a. Counter productive units b. Central processing unit c. Copper.
Introduction to Unix (CA263) File Processing. Guide to UNIX Using Linux, Third Edition 2 Objectives Explain UNIX and Linux file processing Use basic file.
Copyright © 2012 Pearson Education, Inc. Publishing as Pearson Addison-Wesley C H A P T E R 2 Input, Processing, and Output.
1 Computer Programming (ECGD2102 ) Using MATLAB Instructor: Eng. Eman Al.Swaity Lecture (3): MATLAB Environment (Chapter 1)
1 Lab of COMP 406 Teaching Assistant: Pei-Yuan Zhou Contact: Lab 1: 12 Sep., 2014 Introduction of Matlab (I)
Arrays 1 Multiple values per variable. Why arrays? Can you collect one value from the user? How about two? Twenty? Two hundred? How about… I need to collect.
MEGN 536 – Computational Biomechanics MATLAB: Getting Started Prof. Anthony J. Petrella Computational Biomechanics Group.
ECE 1304 Introduction to Electrical and Computer Engineering Section 1.1 Introduction to MATLAB.
Chapter 8 Arrays and Strings
Introduction to Engineering MATLAB – 6 Script Files - 1 Agenda Script files.
Input, Output, and Processing
Arrays 1 Multiple values per variable. Why arrays? Can you collect one value from the user? How about two? Twenty? Two hundred? How about… I need to collect.
Matlab Programming for Engineers Dr. Bashir NOURI Introduction to Matlab Matlab Basics Branching Statements Loops User Defined Functions Additional Data.
10/24/20151 Chapter 2 Review: MATLAB Environment Introduction to MATLAB 7 Engineering 161.
What does C store? >>A = [1 2 3] >>B = [1 1] >>[C,D]=meshgrid(A,B) c) a) d) b)
Data TypestMyn1 Data Types The type of a variable is not set by the programmer; rather, it is decided at runtime by PHP depending on the context in which.
Chapter 3 MATLAB Fundamentals Introduction to MATLAB Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display.
Digital Image Processing Lecture4: Fundamentals. Digital Image Representation An image can be defined as a two- dimensional function, f(x,y), where x.
Chapter 1 – Matlab Overview EGR1302. Desktop Command window Current Directory window Command History window Tabs to toggle between Current Directory &
ENG College of Engineering Engineering Education Innovation Center 1 Array Accessing and Strings in MATLAB Topics Covered: 1.Array addressing. 2.
Introduction to Matlab Module #4 Page 1 Introduction to Matlab Module #4 – Programming Topics 1.Programming Basics (fprintf, standard input) 2.Relational.
ENG College of Engineering Engineering Education Innovation Center 1 More Script Files in MATLAB Script File I/O : Chapter 4 1.Global Variables.
Using Text Files in Excel File I/O Methods. Working With Text Files A file can be accessed in any of three ways: –Sequential access: By far the most common.
>> x = [ ]; y = 2*x y = Arrays x and y are one dimensional arrays called vectors. In MATLAB all variables are arrays. They allow functions.
Lecture 26: Reusable Methods: Enviable Sloth. Creating Function M-files User defined functions are stored as M- files To use them, they must be in the.
Files: By the end of this class you should be able to: Prepare for EXAM 1. create an ASCII file describe the nature of an ASCII text Use and describe string.
Programming Fundamentals. Overview of Previous Lecture Phases of C++ Environment Program statement Vs Preprocessor directive Whitespaces Comments.
MATLAB for Engineers, by Holly Moore. ISBN © 2007 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved. This material is.
C++ for Engineers and Scientists Second Edition Chapter 7 Completing the Basics.
8 Chapter Eight Server-side Scripts. 8 Chapter Objectives Create dynamic Web pages that retrieve and display database data using Active Server Pages Process.
INTRODUCTION TO MATLAB Dr. Hugh Blanton ENTC 4347.
Digital Image Processing Introduction to MATLAB. Background on MATLAB (Definition) MATLAB is a high-performance language for technical computing. The.
Introduction to Engineering MATLAB – 4 Arrays Agenda Creating arrays of numbers  Vectors: 1-D Arrays  Arrays: 2-D Arrays Array Addressing Strings & String.
Introduction to MATLAB 1.Basic functions 2.Vectors, matrices, and arithmetic 3.Flow Constructs (Loops, If, etc) 4.Create M-files 5.Plotting.
1 Lecture 4 Post-Graduate Students Advanced Programming (Introduction to MATLAB) Code: ENG 505 Dr. Basheer M. Nasef Computers & Systems Dept.
BRIAN D. HAHN AND DANIEL T. VALENTINE THIRD EDITION Essential MATLAB® for Engineers and Scientists.
CMPS 1371 Introduction to Computing for Engineers CHARACTER STRINGS.
Matlab for Engineers Matlab Environment Chapter 2.
Math 252: Math Modeling Eli Goldwyn Introduction to MATLAB.
Chapter 4: Variables, Constants, and Arithmetic Operators Introduction to Programming with C++ Fourth Edition.
ECE 1304 Introduction to Electrical and Computer Engineering
EEE 161 Applied Electromagnetics
© 2016 Pearson Education, Ltd. All rights reserved.
Other Kinds of Arrays Chapter 11
Intro to PHP & Variables
MATLAB: Structures and File I/O
String Manipulation Chapter 7 Attaway MATLAB 4E.
INTRODUCTION TO MATLAB
Text Manipulation Chapter 7 Attaway MATLAB 5E.
Presentation transcript:

AN ENGINEER’S GUIDE TO MATLAB 3rd Edition CHAPTER 3 DATA INPUT/OUTPUT Copyright © Edward B. Magrab 2009

Chapter 3 – Objectives Present the means of displaying annotated numerical results in the MATLAB command window and the means of storing and retrieving data from files. Introduce cell arrays. Copyright © Edward B. Magrab 2009

Topics Strings and Annotated Output Creating Strings Converting Numerical Values to Strings and Displaying Them Entering Data With Input Scalar, Vector, Matrix, and String Input/Output Data Files Cell Arrays Input Microsoft Excel Files Copyright © Edward B. Magrab 2009

Strings (Literals) - Collections of any combination of letters, numbers, and special characters Created, stored, and manipulated in arrays and defined similar to that for vectors and matrices Differ from an array of numerical values in that – Each character occupies one element in an array Defined by enclosing all its characters between a pair of single quotes (' … ') Typically used for – Displaying information to the command window Annotating data displayed to the command window Annotating graphs Copyright © Edward B. Magrab 2009

Examples – Let s be the string testing123. The MATLAB syntax is s = 'testing123' or s = ['testing123'] To retrieve specific characters in the string s, we can use expressions like s(7)  g s(3:6)  stin Strings can also be concatenated (added to form a longer string) as sc = ['testing123', 'testing123'] which produces the (120) string sc = testing123testing123 Copyright © Edward B. Magrab 2009

sc = ['testing123'; 'testing123'] creates the (210) matrix scs = But, sc = ['testing123'; 'testing123'] creates the (210) matrix scs = testing123 Thus, scs(1,:)  testing123 scs(2,:)  testing123 Copyright © Edward B. Magrab 2009

One can find the starting locations of strings within strings using findstr(string1, string2) which searches the longer of the two strings for the occurrences of the shorter of the two strings. Let us find the occurrences of ‘123’ in the concatenated string shown in the script below sc = ['testing123', 'testing123'] Loc=findstr(sc, '123') Upon execution, we obtain sc = testing123testing123 Loc = 8 18 Copyright © Edward B. Magrab 2009

Thus, if we have the expression lab = ['first ';'last ';'middle'] then If we place a string in each row of a matrix, we have a convenient way in which to access string expressions. The requirement is that each row must contain the same number of characters. This requirement can be met by employing blanks to pad the rest of the string when the individual string expressions are of unequal length. Thus, if we have the expression lab = ['first ';'last ';'middle'] then lab(1,: )  firstb lab(2,: )  lastbb lab(3,: )  middle and b indicates a blank space. Copyright © Edward B. Magrab 2009

The padding is performed by char Thus, the above expression can be replaced by the easier-to-use expression lab = char('first','last','middle') ord = size(lab) which, when executed, displays lab = first last middle ord = 3 6 The trailing blanks can be removed with deblank Copyright © Edward B. Magrab 2009

The leading and trailing blanks can be removed with strtrim(s) where s is a string. Two strings can be compared by using L = strcmp(A, B) where A and B are strings and L = 1 (true) if A = B L = 0 (false) if A  B This function is intended to compare character data. Copyright © Edward B. Magrab 2009

Example – In the two strings defined in the script, A has two additional leading blanks and two additional trailing blanks than string B. A = ' Yes and No '; B = ' Yes and No '; C1 = strcmp(A, B) C2 = strcmp(strtrim(A), strtrim(B)) which, upon execution, gives C1 = C2 = 1 Copyright © Edward B. Magrab 2009

Converting Numerical Values to Strings and Displaying Them To convert a numerical value to a string, we use z = num2str(num) or z = num2str(num,N) where z is a string num is either a number, an array of numbers, or an expression resulting in a number or an array of numbers N is number of digits to be displayed (if omitted, N = 5) Copyright © Edward B. Magrab 2009

Example - Let a = 1000 = 3141.592653589. Then the various values of N will display the digits shown below. num2str(a,1)  3e+003 num2str(a,3)  3.14e+003 num2str(a,4)  3142 num2str(a,5)  3141.5 num2str(a,8)  3141.5927 Notice that the decimal point (.) does not count as a digit. Copyright © Edward B. Magrab 2009

Example - Let a =  /1000 = 0.003141592653589. Then the various values of N will display the digits shown below num2str(a,1)  0.003 num2str(a,3)  0.00314 num2str(a,4)  0.003142 num2str(a,5)  0.0031416 num2str(a,8)  0.0031415927 Copyright © Edward B. Magrab 2009

To convert an integer to a string, we use z = int2str(num) where num is an integer. If num is not an integer, then it is rounded to one. Copyright © Edward B. Magrab 2009

disp(['Product weight = ' num2str(num) ' kg']) A typical construct is to use num2str to concatenate the converted numerical value with some identifying text. Thus, if num is, say, the weight in kilograms, and it is to be identified as such, then to display it to the command window we use disp as follows: num = 12.567; disp(['Product weight = ' num2str(num) ' kg']) Upon execution, we obtain Product weight = 12.567 kg Note: At least one blank space on each side of num2str is required. Copyright © Edward B. Magrab 2009

Let num be a vector of the lengths of the object. Then, the script that displays a vector of values is num = [12.567, 3.458, 9.111]; disp(['Object length = ' num2str(num) ' m']) Upon execution, we obtain Object length = 12.567 3.458 9.111 m Copyright © Edward B. Magrab 2009

n = length(num); % Let MATLAB do the counting To create annotation that accompanies each value of num, we use repmat as follows. num = [12.567, 3.458, 9.111]; n = length(num); % Let MATLAB do the counting disp([repmat('Object length = ', n, 1) num2str(num') repmat(' m', n, 1)]) which, upon execution, displays Object length = 12.567 m Object length = 3.458 m Object length = 9.111 m Copyright © Edward B. Magrab 2009

fprintf(1,'%…', variables) where An alternative way to display formatted data to the MATLAB command window is with fprintf(1,'%…', variables) where ‘1’ indicates that the output goes to the command window '%….' is the format specification pertaining to variables % precedes each specific format specification, which is of the form x.yq q specifies the format x specifies the minimum number of digits to be displayed y is the number of digits to the right of the decimal point Copyright © Edward B. Magrab 2009

Example – We select q = f, which is a fixed point format, and use it to display the vector num = [12, -14, 3098.458, 0.11167]; several different ways. To display this vector on one line, we have fprintf(1,'%5.2f ', num) which results in 12.00 -14.00 3098.46 0.11 Copyright © Edward B. Magrab 2009

which, when executed, displays 12.00 -14.00 3098.46 0.11 To display these values as a column of four numbers, we use the delimiter \n as follows: num = [12 -14 3098.458 0.11167]; fprintf(1,'%5.2f\n', num) which, when executed, displays 12.00 -14.00 3098.46 0.11 Copyright © Edward B. Magrab 2009

The execution of this script results in weight = 12 kg To display each number with the appropriate number of digits, annotate each value, and print it in column form, we use num = [12, -14, 3098.458, 0.11167]; fprintf(1,'weight = %2.0f kg\npressure = %2.0f kPa\ntime = %5.3f s\nlength = %5.5f m', num) The execution of this script results in weight = 12 kg pressure = -14 kPa time = 3098.458 s length = 0.11167 m Copyright © Edward B. Magrab 2009

If this number were x = 0.00045, then the script is x = 0.00045; num2str can also employ the format specifications of fprintf by replacing the second argument N in num2str with a string format specification. Suppose that we wanted to display a very small number as 0 instead of in exponent form. If this number were x = 0.00045, then the script is x = 0.00045; disp(['x = ' num2str(x,'%2.1f')]) displays x = 0.0 Copyright © Edward B. Magrab 2009

Entering Data with input Entering a Scalar – To input a single numerical quantity, we use InputData=input('Enter temperature in degrees C: '); Upon execution, we have displayed in the command window Enter temperature in degrees C: 121.7 where the number 121.7 was entered by the user. The semicolon at the end of the expression in the script suppresses the echoing of the value entered. The variable InputData has the value of 121.7 after Enter is depressed. Copyright © Edward B. Magrab 2009

One can also modify user-entered values in the same expression. Consider the conversion of degrees to radians. Here InputData = input('Enter the starting angle in degrees: ')*pi/180; When executed, we have in the command window Enter the starting angle in degrees: 45 where the value 45 was entered by the user. However, the value of InputData is 0.7854 (= 45/180). Copyright © Edward B. Magrab 2009

Entering a String – To input a single string quantity, we append an 's' at the end of the input function InputData = input('Enter file name, including its extension: ','s'); which displays command to the window. Enter file name, including its extension: DataSet3.txt where the string DataSet3.txt was entered by the user. Notice that no single quotation marks are required. The value of InputData is the string DataSet3.txt, which is a vector of length 12. Copyright © Edward B. Magrab 2009

The square brackets are required. Entering a Vector – To input a vector of numerical values, we use InputData = input('Enter four temperatures in degrees C: '); which, upon execution, displays Enter four temperatures in degrees C: [120, 141,169, 201] where the vector of numbers [120, 141, 169, 201] was entered by the user. The square brackets are required. If a column vector was required, then the user's response would be either [120, 141, 169, 201]' or [120; 141; 169; 201] Copyright © Edward B. Magrab 2009

Entering a Matrix - To input a matrix of numerical values, we use InputData = input('Enter three temperatures in degrees C\nfor levels 1 and 2: '); which displays Enter the three temperatures in degrees C for levels 1 and 2: [67, 35, 91; 44, 51, 103] where the array [67, 35, 91; 44, 51, 103] was entered by the user. The variable InputData is a (23) array. Copyright © Edward B. Magrab 2009

Input/Output Data Files – load/save Reads data on a row-by-row basis. Each row separated by an Enter, where Enter is used instead of the semicolon. Each data value separated by either one or more blanks or by a comma. The number of columns of data in each row must be the same. For a row vector, data entered without using Enter. For a column vector, each data value followed by an Enter. Copyright © Edward B. Magrab 2009

Example – Assume that data reside in an ASCII text file DataSection33.txt in the form 11 12 13 21 22 23 31 32 33 41 42 43 The load function is load('DataSection33.txt') Copyright © Edward B. Magrab 2009

load('DataSection33.txt') y = DataSection33.^2 Let us square each element of the matrix in DataSection33.txt. The script is load('DataSection33.txt') y = DataSection33.^2 which, upon execution, results in y = 121 144 169 441 484 529 961 1024 1089 1681 1764 1849 11 12 13 21 22 23 31 32 33 41 42 43 Copyright © Edward B. Magrab 2009

FileName1 = input('Enter file name containing data If one wanted to operate on data in different files, each having a different file name, then we have to employ a different technique. Here, the user will enter the file name when requested to do so and, as before, the script will square the data residing in the file whose name is specified when the script is executed. The script is FileName1 = input('Enter file name containing data (including suffix): ','s'); load(FileName1); m = findstr(FileName1,'.'); data1 = eval(FileName1(1:m-1)); y = data1.^2 Copyright © Edward B. Magrab 2009

Since FileName1 is still unknown to the remaining expressions in the script, it must be converted to a numerical quantity. This is done by the eval function, which evaluates the string quantity appearing in its argument. Copyright © Edward B. Magrab 2009

save If one wants to save numerical values resulting from the execution of a script or function to a file, then we use save('File name', 'Variable 1', 'Variable 2', …, '-ascii') where 'File name' is a string containing the name of the file to be saved and its directory, if other that the current directory. 'Variable n' are strings containing the names of the n variables that are to be saved in the order that they appear. '-ascii' is a string indicating that the data will be saved in ascii format. Copyright © Edward B. Magrab 2009

Example – Save the square of each value in a file named DataSection33.txt as ASCII text. The script is load('DataSection33.txt') y = DataSection33.^2; save('SavedDataSection33.txt', 'y', '-ascii') Upon execution, the script creates a text file whose contents are 1.2100000e+002 1.4400000e+002 1.6900000e+002 4.4100000e+002 4.8400000e+002 5.2900000e+002 9.6100000e+002 1.0240000e+003 1.0890000e+003 1.6810000e+003 1.7640000e+003 1.8490000e+003 Copyright © Edward B. Magrab 2009

A Note About Path Name – When just the file name is given, MATLAB places the file in the current directory. In order to place the file in a specific directory, the entire path name must be given. For example, load('DataSection33.txt') % File in current directory y = DataSection33.^2; z = sqrt(Datasection33); save('c:\Matlab mfiles\Matlab results\SavedDataSection33.txt', 'y', ‘z', '-ascii') Copyright © Edward B. Magrab 2009

Execution of this script creates the file SavedDataSection331 Execution of this script creates the file SavedDataSection331.txt with the contents 1.2100000e+002 1.4400000e+002 1.6900000e+002 4.4100000e+002 4.8400000e+002 5.2900000e+002 9.6100000e+002 1.0240000e+003 1.0890000e+003 1.6810000e+003 1.7640000e+003 1.8490000e+003 3.3166248e+000 3.4641016e+000 3.6055513e+000 4.5825757e+000 4.6904158e+000 4.7958315e+000 5.5677644e+000 5.6568542e+000 5.7445626e+000 6.4031242e+000 6.4807407e+000 6.5574385e+000 y z Copyright © Edward B. Magrab 2009

Cell Arrays – Cell arrays are a special class of arrays whose elements consist of cells that themselves contain arrays. They provide a hierarchical way of storing dissimilar kinds of data. Any cell in a cell array can be accessed through matrix indexing as is done with standard vectors and matrices. Cell notation differs from standard matrix notation in that open braces ‘{’ and the closed braces ‘}’ are used instead of open ‘[’ and closed ‘]’ brackets. Copyright © Edward B. Magrab 2009

Example – Let us create four different arrays of data as shown in the following script A = ones(3,2) B = magic(3) C = char('Pressure', 'Temperature', 'Displacement') D = [6+7j, 15] Upon executing this script, we obtain Copyright © Edward B. Magrab 2009

A = 1 1 B = 8 1 6 3 5 7 4 9 2 C = Pressure Temperature Displacement 1 1 B = 8 1 6 3 5 7 4 9 2 C = Pressure Temperature Displacement D = 6.0000 + 7.0000i 15.0000 Copyright © Edward B. Magrab 2009

C = char('Pressure', 'Temperature', 'Displacement'); D = [6+7j, 15]; We now add to this script the cell assignment statement to create a (22) cell array, which is analogous to that used for standard arrays, except that we use braces as delimiters. Thus, A = ones(3,2); B = magic(3); C = char('Pressure', 'Temperature', 'Displacement'); D = [6+7j, 15]; Cel = {A, B; C, D} After executing this script, we obtain Cel = [3x2 double] [3x3 double] [3x12 char ] [1x2 double] Copyright © Edward B. Magrab 2009

To display the contents of Cel to the command window, we use Notice that we do not get what is specifically in each cell, only what the size of the data arrays in each cell are and their type. To display the contents of Cel to the command window, we use celldisp(x) Then, the program becomes A = ones(3,2); B = magic(3); C = char('Pressure', 'Temperature', 'Displacement'); D = [6+7j, 15]; Cel = {A, B; C, D}; celldisp(Cel) Copyright © Edward B. Magrab 2009

which, upon execution, gives Cel{1,1} = 1 1 1 1 Cel{2,1} = Pressure Temperature Displacement Cel{1,2} = 8 1 6 3 5 7 4 9 2 Cel{2,2} = 6.0000 + 7.0000i 15.0000 Copyright © Edward B. Magrab 2009

C = char('Pressure', 'Temperature', 'Displacement'); D = [6+7j,15]; To access each cell individually, we use the index notation used for standard array variables, except that we use braces instead of parentheses. Thus, A = ones(3,2); B = magic(3); C = char('Pressure', 'Temperature', 'Displacement'); D = [6+7j,15]; Cel = {A, B; C, D}; Cell_1_2 = Cel{1,2} which, upon execution, gives Cell_1_2 = 8 1 6 3 5 7 4 9 2 Copyright © Edward B. Magrab 2009

Words = {'application', 'apple', 'friend', 'apply', 'fiend'}; With cell arrays, the use of sort can be extended to sort words in dictionary order. Consider the following script, where we will create a cell array of five words and then sort them. Words = {'application', 'apple', 'friend', 'apply', 'fiend'}; WordSort = sort(Words)' The execution of this script gives 'apple' 'application' 'apply' 'fiend' 'friend' Copyright © Edward B. Magrab 2009

Input Microsoft Excel Files Data files created in Microsoft Excel can be read into MATLAB with the function [X, Y] = xlsread('Filename') where X will be an array containing the columns and rows of data and Y will be a cell array containing any text headers that accompany the data. The file name must contain the suffix ‘.xls’. Copyright © Edward B. Magrab 2009

Example – Consider the data generated in Excel shown below and saved in ForceDispData.xls. The script to read this file is [X, Y] = xlsread('ForceDispData.xls') X = 100.0000 0.1000 110.0000 0.2000 135.0000 0.3300 150.0000 0.4000 175.0000 0.5500 Y = [1x20 char] [] 'Force' 'Displacement' '(kPa)' '(mm)' Note: Y is a (3×2) cell array: Y{1,1}=Transducer Linearity Copyright © Edward B. Magrab 2009