81 PDFsam Matlab Prog
81 PDFsam Matlab Prog
81 PDFsam Matlab Prog
Complex Numbers
• The operators >, <, >=, and <= use only the real part of the operands in performing comparisons.
• The operators == and ~= test both real and imaginary parts of the operands.
Logic Statements
Use relational operators in conjunction with the logical operators A & B (AND), A | B (OR),
xor(A,B) (XOR), and ~A (NOT), to string together more complex logical statements.
For example, you can locate where negative elements occur in two arrays.
A = [2 -1; -3 10]
A =
2 -1
-3 10
B = [0 -2; -3 -1]
B =
0 -2
-3 -1
ans =
0 1
1 0
For more examples, see “Find Array Elements That Meet a Condition” on page 5-2.
See Also
eq | ge | gt | le | lt | ne
More About
• “Array vs. Matrix Operations” on page 2-20
• “Compatible Array Sizes for Basic Operations” on page 2-25
• “MATLAB Operators and Special Characters” on page 2-2
2-31
2 Program Components
Operator Precedence
You can build expressions that use any combination of arithmetic, relational, and logical operators.
Precedence levels determine the order in which MATLAB evaluates an expression. Within each
precedence level, operators have equal precedence and are evaluated from left to right. The
precedence rules for MATLAB operators are shown in this list, ordered from highest precedence level
to lowest precedence level:
1 Parentheses ()
2 Transpose (.'), power (.^), complex conjugate transpose ('), matrix power (^)
3 Power with unary minus (.^-), unary plus (.^+), or logical negation (.^~) as well as matrix
power with unary minus (^-), unary plus (^+), or logical negation (^~).
Note Although most operators work from left to right, the operators (^-), (.^-), (^+), (.^+),
(^~), and (.^~) work from second from the right to left. It is recommended that you use
parentheses to explicitly specify the intended precedence of statements containing these
operator combinations.
4 Unary plus (+), unary minus (-), logical negation (~)
5 Multiplication (.*), right division (./), left division (.\), matrix multiplication (*), matrix
right division (/), matrix left division (\)
6 Addition (+), subtraction (-)
7 Colon operator (:)
8 Less than (<), less than or equal to (<=), greater than (>), greater than or equal to (>=),
equal to (==), not equal to (~=)
9 Element-wise AND (&)
10 Element-wise OR (|)
11 Short-circuit AND (&&)
12 Short-circuit OR (||)
The same precedence rule holds true for the && and || operators.
2-32
Operator Precedence
C = (A./B).^2
C =
2.2500 81.0000 1.0000
See Also
More About
• “Array vs. Matrix Operations” on page 2-20
• “Compatible Array Sizes for Basic Operations” on page 2-25
• “Array Comparison with Relational Operators” on page 2-29
• “MATLAB Operators and Special Characters” on page 2-2
2-33
2 Program Components
Use random points picked from the peaks function in the domain [ − 3, 3] × [ − 3, 3] as the data set.
Add a small amount of noise to the data.
xy = rand(10000,2)*6-3;
z = peaks(xy(:,1),xy(:,2)) + 0.5-rand(10000,1);
A = [xy z];
plot3(A(:,1), A(:,2), A(:,3), '.')
view(-28,32)
Find points that have similar x and y coordinates using uniquetol with these options:
• Specify ByRows as true, since the rows of A contain the point coordinates.
• Specify OutputAllIndices as true to return the indices for all points that are within tolerance
of each other.
• Specify DataScale as [1 1 Inf] to use an absolute tolerance for the x and y coordinates, while
ignoring the z-coordinate.
DS = [1 1 Inf];
[C,ia] = uniquetol(A, 0.3, 'ByRows', true, ...
'OutputAllIndices', true, 'DataScale', DS);
2-34
Average Similar Data Points Using a Tolerance
Average each group of points that are within tolerance (including the z-coordinates), producing a
reduced data set that still holds the general shape of the original data.
for k = 1:length(ia)
aveA(k,:) = mean(A(ia{k},:),1);
end
hold on
plot3(aveA(:,1), aveA(:,2), aveA(:,3), '.r', 'MarkerSize', 15)
See Also
uniquetol
More About
• “Group Scattered Data Using a Tolerance” on page 2-36
2-35
2 Program Components
Create a set of random 2-D points. Then create and plot a grid of equally spaced points on top of the
random data.
x = rand(10000,2);
[a,b] = meshgrid(0:0.1:1);
gridPoints = [a(:), b(:)];
plot(x(:,1), x(:,2), '.')
hold on
plot(gridPoints(:,1), gridPoints(:,2), 'xr', 'Markersize', 6)
Use ismembertol to locate the data points in x that are within tolerance of the grid points in
gridPoints. Use these options with ismembertol:
• Specify ByRows as true, since the point coordinates are in the rows of x.
• Specify OutputAllIndices as true to return all of the indices for rows in x that are within
tolerance of the corresponding row in gridPoints.
For each grid point, plot the points in x that are within tolerance of that grid point.
2-36
Group Scattered Data Using a Tolerance
figure
hold on
for k = 1:length(LocB)
plot(x(LocB{k},1), x(LocB{k},2), '.')
end
plot(gridPoints(:,1), gridPoints(:,2), 'xr', 'Markersize', 6)
See Also
ismembertol
More About
• “Average Similar Data Points Using a Tolerance” on page 2-34
2-37
2 Program Components
Bit-Wise Operations
This topic shows how to use bit-wise operations in MATLAB® to manipulate the bits of numbers.
Operating on bits is directly supported by most modern CPUs. In many cases, manipulating the bits of
a number in this way is quicker than performing arithmetic operations like division or multiplication.
Number Representations
Any number can be represented with bits (also known as binary digits). The binary, or base 2, form of
a number contains 1s and 0s to indicate which powers of 2 are present in the number. For example,
the 8-bit binary form of 7 is
00000111
A collection of 8 bits is also called 1 byte. In binary representations, the bits are counted from the
right to the left, so the first bit in this representation is a 1. This number represents 7 because
2 1 0
2 + 2 + 2 = 7.
When you type numbers into MATLAB, it assumes the numbers are double precision (a 64-bit binary
representation). However, you can also specify single-precision numbers (32-bit binary
representation) and integers (signed or unsigned, from 8 to 64 bits). For example, the most memory
efficient way to store the number 7 is with an 8-bit unsigned integer:
a = uint8(7)
a = uint8
7
You can even specify the binary form directly using the prefix 0b followed by the binary digits (for
more information, see “Hexadecimal and Binary Values” on page 6-55). MATLAB stores the number
in an integer format with the fewest number of bits. Instead of specifying all the bits, you need to
specify only the left-most 1 and all the digits to the right of it. The bits to the left of that bit are
trivially zero. So the number 7 is:
b = 0b111
b = uint8
7
MATLAB stores negative integers using two's complement. For example, consider the 8-bit signed
integer -8. To find the two's complement bit pattern for this number:
1 Start with the bit pattern of the positive version of the number, 8: 00001000.
2 Next, flip all of the bits: 11110111.
3 Finally, add 1 to the result: 11111000.
n = 0b11111000s8
n = int8
-8
2-38
Bit-Wise Operations
MATLAB does not natively display the binary format of numbers. For that, you can use the dec2bin
function, which returns a character vector of binary digits for positive integers. Again, this function
returns only the digits that are not trivially zero.
dec2bin(b)
ans =
'111'
You can use bin2dec to switch between the two formats. For example, you can convert the binary
digits 10110101 to decimal format with the commands
data = [1 0 1 1 0 1 0 1];
dec = bin2dec(num2str(data))
dec = 181
The cast and typecast functions are also useful to switch among different data types. These
functions are similar, but they differ in how they treat the underlying storage of the number:
Because MATLAB does not display the digits of a binary number directly, you must pay attention to
data types when you work with bit-wise operations. Some functions return binary digits as a
character vector (dec2bin), some return the decimal number (bitand), and others return a vector of
the bits themselves (bitget).
MATLAB has several functions that enable you to perform logical operations on the bits of two equal-
length binary representations of numbers, known as bit masking:
• bitand — If both digits are 1, then the resulting digit is also a 1. Otherwise, the resulting digit is
0.
• bitor — If either digit is 1, then the resulting digit is also a 1. Otherwise, the resulting digit is 0.
• bitxor — If the digits are different, then the resulting digit is a 1. Otherwise, the resulting digit
is 0.
In addition to these functions, the bit-wise complement is available with bitcmp, but this is a unary
operation that flips the bits in only one number at a time.
One use of bit masking is to query the status of a particular bit. For example, if you use a bit-wise
AND operation with the binary number 00001000, you can query the status of the fourth bit. You can
then shift that bit to the first position so that MATLAB returns a 0 or 1 (the next section describes bit
shifting in more detail).
n = 0b10111001;
n4 = bitand(n,0b1000);
n4 = bitshift(n4,-3)
n4 = uint8
1
Bit-wise operations can have surprising applications. For example, consider the 8-bit binary
representation of the number n = 8:
2-39
2 Program Components
00001000
8 is a power of 2, so its binary representation contains a single 1. Now consider the number
n − 1 = 7:
00000111
By subtracting 1, all of the bits starting at the right-most 1 are flipped. As a result, when n is a power
of 2, corresponding digits of n and n − 1 are always different, and the bit-wise AND returns zero.
n = 0b1000;
bitand(n,n-1)
ans = uint8
0
0
However, when n is not a power of 2, then the right-most 1 is for the 2 bit, so n and n − 1 have all
0
the same bits except for the 2 bit. For this case, the bit-wise AND returns a nonzero number.
n = 0b101;
bitand(n,n-1)
ans = uint8
4
This operation suggests a simple function that operates on the bits of a given input number to check
whether the number is a power of 2:
function tf = isPowerOfTwo(n)
tf = n && ~bitand(n,n-1);
end
The use of the short-circuit AND operator && checks to make sure that n is not zero. If it is, then the
function does not need to calculate bitand(n,n-1) to know that the correct answer is false.
Shifting Bits
Because bit-wise logical operations compare corresponding bits in two numbers, it is useful to be able
to move the bits around to change which bits are compared. You can use bitshift to perform this
operation:
• bitshift(A,N) shifts the bits of A to the left by N digits. This is equivalent to multiplying A by
N
2 .
• bitshift(A,-N) shifts the bits of A to the right by N digits. This is equivalent to dividing A by
N
2 .
These operations are sometimes written A<<N (left shift) and A>>N (right shift), but MATLAB does not
use << and >> operators for this purpose.
When the bits of a number are shifted, some bits fall off the end of the number, and 0s or 1s are
introduced to fill in the newly created space. When you shift bits to the left, the bits are filled in on
the right; when you shift bits to the right, the bits are filled in on the left.
For example, if you shift the bits of the number 8 (binary: 1000) to the right by one digit, you get 4
(binary: 100).
2-40
Bit-Wise Operations
n = 0b1000;
bitshift(n,-1)
ans = uint8
4
Similarly, if you shift the number 15 (binary: 1111) to the left by two digits, you get 60 (binary:
111100).
n = 0b1111;
bitshift(15,2)
ans = 60
When you shift the bits of a negative number, bitshift preserves the signed bit. For example, if you
shift the signed integer -3 (binary: 11111101) to the right by 2 digits, you get -1 (binary: 11111111).
In these cases, bitshift fills in on the left with 1s rather than 0s.
n = 0b11111101s8;
bitshift(n,-2)
ans = int8
-1
Writing Bits
You can use the bitset function to change the bits in a number. For example, change the first bit of
the number 8 to a 1 (which adds 1 to the number):
bitset(8,1)
ans = 9
By default, bitset flips bits to on or 1. You can optionally use the third input argument to specify the
bit value.
bitset does not change multiple bits at once, so you need to use a for loop to change multiple bits.
Therefore, the bits you change can be either consecutive or nonconsecutive. For example, change the
first two bits of the binary number 1000:
bits = [1 2];
c = 0b1000;
for k = 1:numel(bits)
c = bitset(c,bits(k));
end
dec2bin(c)
ans =
'1011'
Another common use of bitset is to convert a vector of binary digits into decimal format. For
example, use a loop to set the individual bits of the integer 11001101.
data = [1 1 0 0 1 1 0 1];
n = length(data);
dec = 0b0u8;
for k = 1:n
dec = bitset(dec,n+1-k,data(k));
2-41
2 Program Components
end
dec
dec = uint8
205
dec2bin(dec)
ans =
'11001101'
Another use of bit shifting is to isolate consecutive sections of bits. For example, read the last four
bits in the 16-bit number 0110000010100000. Recall that the last four bits are on the left of the
binary representation.
n = 0b0110000010100000;
dec2bin(bitshift(n,-12))
ans =
'110'
To isolate consecutive bits in the middle of the number, you can combine the use of bit shifting with
logical masking. For example, to extract the 13th and 14th bits, you can shift the bits to the right by
12 and then mask the resulting four bits with 0011. Because the inputs to bitand must be the same
integer data type, you can specify 0011 as an unsigned 16-bit integer with 0b11u16. Without the -
u16 suffix, MATLAB stores the number as an unsigned 8-bit integer.
m = 0b11u16;
dec2bin(bitand(bitshift(n,-12),m))
ans =
'10'
Another way to read consecutive bits is with bitget, which reads specified bits from a number. You
can use colon notation to specify several consecutive bits to read. For example, read the last 8 bits of
n.
bitget(n,16:-1:8)
0 1 1 0 0 0 0 0 1
You can also use bitget to read bits from a number when the bits are not next to each other. For
example, read the 5th, 8th, and 14th bits from n.
2-42
Bit-Wise Operations
1 1 0
See Also
bitand | bitcmp | bitget | bitor | bitset | bitshift | bitxor
More About
• “Integers” on page 4-2
• “Perform Cyclic Redundancy Check” on page 2-44
• “Hexadecimal and Binary Values” on page 6-55
2-43
2 Program Components
1101100111011010
To obtain the check value, divide this number by the polynomial x3 + x2 + x + 1. You can represent
this polynomial with its coefficients: 1111.
The division is performed in steps, and after each step the polynomial divisor is aligned with the left-
most 1 in the number. Because the result of dividing by the four term polynomial has three bits (in
general dividing by a polynomial of length n + 1 produces a check value of length n), append the
number with 000 to calculate the remainder. At each step, the result uses the bit-wise XOR of the four
bits being operated on, and all other bits are unchanged.
1101100111011010 000
1111
----------------
0010100111011010 000
Each successive division operates on the result of the previous step, so the second division is
0010100111011010 000
1111
----------------
0001010111011010 000
The division is completed once the dividend is all zeros. The complete division, including the above
two steps, is
1101100111011010 000
1111
0010100111011010 000
1111
0001010111011010 000
1111
0000101111011010 000
1111
0000010011011010 000
1111
0000001101011010 000
1111
0000000010011010 000
1111
0000000001101010 000
1111
2-44
Perform Cyclic Redundancy Check
0000000000010010 000
1111
0000000000001100 000
1111
0000000000000011 000
11 11
0000000000000000 110
The remainder bits, 110, are the check value for this message.
In MATLAB®, you can perform this same operation to obtain the check value using bit-wise
operations. First, define variables for the message and polynomial divisor. Use unsigned 32-bit
integers so that extra bits are available for the remainder.
message = 0b1101100111011010u32;
messageLength = 16;
divisor = 0b1111u32;
divisorDegree = 3;
Next, initialize the polynomial divisor. Use dec2bin to display the bits of the result.
divisor = bitshift(divisor,messageLength-divisorDegree-1);
dec2bin(divisor)
ans =
'1111000000000000'
Now, shift the divisor and message so that they have the correct number of bits (16 bits for the
message and 3 bits for the remainder).
divisor = bitshift(divisor,divisorDegree);
remainder = bitshift(message,divisorDegree);
dec2bin(divisor)
ans =
'1111000000000000000'
dec2bin(remainder)
ans =
'1101100111011010000'
Perform the division steps of the CRC using a for loop. The for loop always advances a single bit
each step, so include a check to see if the current digit is a 1. If the current digit is a 1, then the
division step is performed; otherwise, the loop advances a bit and continues.
for k = 1:messageLength
if bitget(remainder,messageLength+divisorDegree)
remainder = bitxor(remainder,divisor);
end
remainder = bitshift(remainder,1);
end
Shift the bits of the remainder to the right to get the check value for the operation.
CRC_check_value = bitshift(remainder,-messageLength);
dec2bin(CRC_check_value)
2-45
2 Program Components
ans =
'110'
You can use the check value to verify the integrity of a message by repeating the same division
operation. However, instead of using a remainder of 000 to start, use the check value 110. If the
message is error free, then the result of the division will be zero.
Reset the remainder variable, and add the CRC check value to the remainder bits using a bit-wise OR.
Introduce an error into the message by flipping one of the bit values with bitset.
remainder = bitshift(message,divisorDegree);
remainder = bitor(remainder,CRC_check_value);
remainder = bitset(remainder,6);
dec2bin(remainder)
ans =
'1101100111011110110'
Perform the CRC division operation and then check if the result is zero.
for k = 1:messageLength
if bitget(remainder,messageLength+divisorDegree)
remainder = bitxor(remainder,divisor);
end
remainder = bitshift(remainder,1);
end
if remainder == 0
disp('Message is error free.')
else
disp('Message contains errors.')
end
References
[1] Sklar, Bernard. Digital Communications: Fundamentals and Applications. Englewood Cliffs, NJ:
Prentice Hall, 1988.
[2] Wicker, Stephen B. Error Control Systems for Digital Communication and Storage. Upper Saddle
River, NJ: Prentice Hall, 1995.
See Also
bitshift | bitxor
More About
• “Bit-Wise Operations” on page 2-38
• “Hexadecimal and Binary Values” on page 6-55
2-46
Conditional Statements
Conditional Statements
Conditional statements enable you to select at run time which block of code to execute. The simplest
conditional statement is an if statement. For example:
% If it is even, divide by 2
if rem(a, 2) == 0
disp('a is even')
b = a/2;
end
if statements can include alternate choices, using the optional keywords elseif or else. For
example:
a = randi(100, 1);
if a < 30
disp('small')
elseif a < 80
disp('medium')
else
disp('large')
end
Alternatively, when you want to test for equality against a set of known values, use a switch
statement. For example:
switch dayString
case 'Monday'
disp('Start of the work week')
case 'Tuesday'
disp('Day 2')
case 'Wednesday'
disp('Day 3')
case 'Thursday'
disp('Day 4')
case 'Friday'
disp('Last day of the work week')
otherwise
disp('Weekend!')
end
For both if and switch, MATLAB executes the code corresponding to the first true condition, and
then exits the code block. Each conditional statement requires the end keyword.
In general, when you have many possible discrete, known values, switch statements are easier to
read than if statements. However, you cannot test for inequality between switch and case values.
For example, you cannot implement this type of condition with a switch:
if yourNumber < 0
2-47
2 Program Components
disp('Negative')
elseif yourNumber > 0
disp('Positive')
else
disp('Zero')
end
See Also
end | if | return | switch
2-48
Loop Control Statements
• for statements loop a specific number of times, and keep track of each iteration with an
incrementing index variable.
x = ones(1,10);
for n = 2:6
x(n) = 2 * x(n - 1);
end
• while statements loop as long as a condition remains true.
For example, find the first integer n for which factorial(n) is a 100-digit number:
n = 1;
nFactorial = 1;
while nFactorial < 1e100
n = n + 1;
nFactorial = nFactorial * n;
end
It is a good idea to indent the loops for readability, especially when they are nested (that is, when one
loop contains another loop):
A = zeros(5,100);
for m = 1:5
for n = 1:100
A(m, n) = 1/(m + n - 1);
end
end
You can programmatically exit a loop using a break statement, or skip to the next iteration of a loop
using a continue statement. For example, count the number of lines in the help for the magic
function (that is, all comment lines until a blank line):
fid = fopen('magic.m','r');
count = 0;
while ~feof(fid)
line = fgetl(fid);
if isempty(line)
break
elseif ~strncmp(line,'%',1)
continue
end
count = count + 1;
end
fprintf('%d lines in MAGIC help\n',count);
fclose(fid);
2-49
2 Program Components
Tip If you inadvertently create an infinite loop (a loop that never ends on its own), stop execution of
the loop by pressing Ctrl+C.
See Also
break | continue | end | for | while
2-50