[programming] elaborate the boolean section a bit
This commit is contained in:
parent
050066a464
commit
554766acf6
@ -74,7 +74,7 @@ z =
|
||||
|
||||
Line 1 can be read like: ``Create a variable with the name \varcode{x}
|
||||
and assign the value 38''. The equality sign is the so called
|
||||
\codeterm{assignment operator}. Line 5 defines a variable \varcode{y}
|
||||
\codeterm[Operator!assignment]{assignment operator}. Line 5 defines a variable \varcode{y}
|
||||
and assigns an empty value. If not explicitly specified \matlab{}
|
||||
variables will have the \codeterm{double} (a numeric data type, see
|
||||
below) data type. In line 9, however, we create a variable \varcode{z}
|
||||
@ -809,35 +809,171 @@ ans =
|
||||
|
||||
\section{Boolean expressions}
|
||||
|
||||
Boolean expressions are instructions that can be evaluated to
|
||||
Boolean expressions are computations that are evaluated to
|
||||
\varcode{true} or \varcode{false}. In the context of programming they
|
||||
are used to test the relations between entities, i.e. are entities the
|
||||
same, greater or less than? Accordingly, programming languages define
|
||||
operators for such instructions. The following \codeterm{relational
|
||||
operators} are defined: (\code[Operator!relational!>]{>},
|
||||
\code[Operator!relational!<]{<}, \code[Operator!relational!==]{==},
|
||||
\code[Operator!relational!"~]{~}, greater than, less than, equal to,
|
||||
and not. Using so called \codeterm[Operator!logical]{logical
|
||||
operators} allows to join single Boolean expressions to more complex
|
||||
constructs (\code[Operator!logical!and1@\&]{\&},
|
||||
\code[Operator!logical!or1@{"|} {}]{|}, AND, OR). These expressions
|
||||
are important e.g. to control which parts of the code are evaluated
|
||||
under certain conditions (conditional statements,
|
||||
Section~\ref{controlstructsec}) but also for accessing only those
|
||||
elements of a vector or matrix that match a certain condition (logical
|
||||
indexing, Section~\ref{logicalindexingsec}).
|
||||
|
||||
Truth tables (\ref{logicalandor}) are used to visualize the results of
|
||||
Boolean expressions. A and B are statements that can be evaluated to
|
||||
true or false. When they are combined with a logical AND the whole
|
||||
expression is true only if both statements are true. The logical OR,
|
||||
on the other hand, requires that at least one of the statements is
|
||||
true. The exclusive OR (XOR) is true only for cases in which one of
|
||||
the statements but not both are true. There is no operator for XOR in
|
||||
\matlab{} it is realized via the function \code[xor()]{xor(A, B)}.
|
||||
|
||||
\begin{table}[tp]
|
||||
\titlecaption{Truth tables for logical AND, OR and XOR.}{}\label{logicalandor}
|
||||
same, is the value of one entity greater or less than that of the
|
||||
other? Or the truth joint conditions is evaluated. Imagine that you
|
||||
take two independent measures and want to take a certain action only
|
||||
if both exceed a certain threshold. Boolean expressions are important
|
||||
e.g. to control which parts of the code are evaluated under a certain
|
||||
condition (conditional statements, Section~\ref{controlstructsec}) but
|
||||
also for accessing only those elements of a vector or matrix that
|
||||
match a certain condition (logical indexing,
|
||||
Section~\ref{logicalindexingsec}).
|
||||
|
||||
\subsection{The \emph{logical} data type}
|
||||
Previously we have introduced data types for integer or floating point
|
||||
numbers and discussed that there are instances in which it is more
|
||||
efficient to use an integer data type rather than storing floating
|
||||
point numbers. The result of a Boolean expression can only assume two
|
||||
values (\varcode{true} or \varcode{false}). This implies that we need
|
||||
only a single bit to store this information as 0 (false) or 1 (true)
|
||||
It would be a waste of space to use more than one bit for
|
||||
it. Accordingly, \matlab{} knows a special data type
|
||||
(\codeterm{logical}) to store such information efficiently. \matlab{}
|
||||
also knows the keywords \code{true} and \code{false} which are
|
||||
synonymous for the \codeterm{logical} values 1 and
|
||||
0. Listing~\ref{logicaldatatype} exemplifies the use of the logical
|
||||
data type.
|
||||
|
||||
\begin{lstlisting}[caption={The logical data type. Please note that the actual \matlab{} output looks a little different.}, label=logicaldatatype]
|
||||
>> true
|
||||
ans = 1
|
||||
>> false
|
||||
ans = 0
|
||||
>> class(ans)
|
||||
ans = logical
|
||||
>> logical(100)
|
||||
ans = 1
|
||||
>> logical(-10)
|
||||
ans = 1
|
||||
>> logical(0)
|
||||
ans = 0
|
||||
>> logical('test')
|
||||
ans = 1 1 1 1
|
||||
>> logical([1 2 3 4 0 0 10])
|
||||
ans = 1 1 1 1 0 0 1
|
||||
\end{lstlisting}
|
||||
|
||||
\varcode{true} and \varcode{false} are reserved keywords that evaluate
|
||||
to the logical values 1 and 0, respectively. If you want to create a
|
||||
variable of the data type \textit{logical} you need to use the
|
||||
\code{logical()} function (lines 7, 9 ..., 21 in
|
||||
listing~\ref{logicaldatatype}). \textbf{Note:} converting a value to
|
||||
logical (also known as ``casting'') gives a true for any value that is
|
||||
not zero! This is also true for character values (line 19). The ASCII
|
||||
code of each character in ``test'' is non-zero value, thus, the result
|
||||
of casting it to logical is a vector of logicals. A similar thing
|
||||
happens upon casting a vector (or matrix) of numbers to logical. Each
|
||||
value is converted to logical and the result is true for all non-zero
|
||||
values (line 21).
|
||||
|
||||
Knowing how to represent true and false values in \matlab{} using the
|
||||
logical data type allows us to take a step towards more complex
|
||||
Boolean operations. As indicated above these assess the relations
|
||||
between entities and the truth value of joint expressions. Just like
|
||||
any other programming language \matlab{} defines operators for testing
|
||||
relations (relational operators table~\ref{relationaloperators}) or to
|
||||
evaluate the truth of joint expressions (logical operators
|
||||
table~\ref{logicaloperators}) which are introduced in the following
|
||||
sections.
|
||||
|
||||
\subsection{Relational operators}
|
||||
With \codeterm[Operator!relational]{relational operators} (table~\ref{relationaloperators})
|
||||
we can ask questions such as: ''Is the value of variable \code{a}
|
||||
larger than the value of \code{b}?'' or ``Is the value in \code{a}
|
||||
equal to the one stored in variable \code{b}?''.
|
||||
|
||||
\begin{table}[h!]
|
||||
\titlecaption{\label{relationaloperators}
|
||||
Relational operations, their mathematical symbols and \matlab{} operators.}{}
|
||||
\begin{tabular}{lcc}
|
||||
\hline
|
||||
\textbf{relation} & \textbf{math. symbol} & \textbf{operator} \erh \\ \hline
|
||||
equals & $=$ & \code[Operator!relational!equals@==]{==} \erb \\
|
||||
greater than & $>$ & \code[Operator!relational!less@>]{<}\varcode{$>$} \\
|
||||
less than & $>$ & \code[Operator!relational!greater@>]{\varcode{$<$}}\\
|
||||
greater or equal & $\geq$ & \code[Operator!relational!greaterequal@>=]{\varcode{$>=$}}\\
|
||||
less or equal & $\leq$ & \code[Operator!relational!lessequal@<=]{\varcode{$<=$}}\\
|
||||
unequal & $\neq$ & \code[Operator!relational!notequal@$\sim=$]{\varcode{$\sim=$}}\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
The result of such questions is then given as a logical
|
||||
value. Listing~\ref{relationaloperationslisting} shows examples using relational operators.
|
||||
\pagebreak
|
||||
\begin{lstlisting}[caption={Relational Boolean expressions.}, label=relationaloperationslisting]
|
||||
>> true == logical(1)
|
||||
ans = 1
|
||||
>> false ~= logical(1)
|
||||
ans = 1
|
||||
>> a = 10; b = 100;
|
||||
>> a > b
|
||||
ans = 0
|
||||
>> b <= a
|
||||
ans = 0
|
||||
>> a <= b
|
||||
ans = 1
|
||||
>> [2 0 0 5 0] < [1 0 3 2 0]
|
||||
ans = 0 0 1 0 0
|
||||
>> [2 0 0 5 0] == [1 0 3 2 0]
|
||||
ans = 0 1 0 0 1
|
||||
>> [2 0 0 5 0] >= [1 0 3 2 0]
|
||||
ans = 1 1 0 1 1
|
||||
\end{lstlisting}
|
||||
|
||||
Testing the relations between numbers and scalar variables is straight
|
||||
forward. When comparing vectors, the relational operator will be
|
||||
applied element-wise and compare the respective elements of the
|
||||
left-hand-side and right-hand-side vectors. Note: vectors must have
|
||||
the same length and orientation. The result of \code{[2 0 0 5 0] == [1
|
||||
0 3 2 0]'} in which the second vector is transposed to give a
|
||||
column vector is a matrix!
|
||||
|
||||
\subsection{Logical operators}
|
||||
With the relational operators we could for example test whether a
|
||||
number is greater than a certain threshold (\code{x > 0.25}). But what
|
||||
if we wanted to check whether the number falls into the range greater
|
||||
than 0.25 but less than 0.75? Numbers that fall into this range must
|
||||
satisfy the one and the other condition. With
|
||||
\codeterm[Operator!logical]{logical
|
||||
operators} (table~\ref{logicaloperators}) single Boolean expressions
|
||||
can be joined to form more complex Boolean operations.
|
||||
|
||||
\begin{table}[ht]
|
||||
\titlecaption{\label{logicaloperators}
|
||||
Logical operations, their mathematical symbols and \matlab{} operators.}{}
|
||||
\begin{tabular}{lcc}
|
||||
\hline
|
||||
\textbf{logical operation} & \textbf{math. symbol} & \textbf{operator} \erh \\ \hline
|
||||
AND & $\wedge$ & \varcode{$\&$} \erb \\
|
||||
OR & $\vee$ & \varcode{$|$}\\
|
||||
NOT/negation & $\neg$ & \varcode{$\sim$} \\
|
||||
XOR & $\dot{\vee}$ & function \varcode{xor}\\
|
||||
short-circuit AND & n.a. & \varcode{$\&\&$}\\
|
||||
short-circuit OR & n.a. & \varcode{$\|$}\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
The two most important ones are the logical \textbf{AND} and the
|
||||
logical \textbf{OR}. When connecting with a logical \textbf{AND} the
|
||||
expressions on both sides of the operator must yield true. In contrast
|
||||
for an \textbf{OR} expression to become true it is sufficient if one
|
||||
of either sides of the operator is evaluated to true. The behavior of
|
||||
the operators can be visualized using truth tables
|
||||
(table~\ref{truthtables}. A and B are statements that can be evaluated
|
||||
to true or false. The exclusive \textbf{OR (XOR)} is true only for
|
||||
cases in which one of the statements but not both are true. There is
|
||||
no operator for XOR in \matlab{} it is realized via the function
|
||||
\code[xor()]{xor(A, B)}.
|
||||
|
||||
\begin{table}[h]
|
||||
\titlecaption{Truth tables for Boolean expressions that join the
|
||||
statements \textbf{A} and \textbf{B} using the logical AND, OR, and
|
||||
XOR.}{}\label{truthtables}
|
||||
\begin{tabular}{llll}
|
||||
\multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\
|
||||
& \sffamily{\textbf{AND}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4}
|
||||
@ -860,97 +996,63 @@ the statements but not both are true. There is no operator for XOR in
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
In addition to the logical operators discussed above
|
||||
table~\ref{logicaloperators} lists also the logical \textbf{NOT} or
|
||||
negation ($\sim$). This operator is used to invert the result of a
|
||||
Boolean expression (true becomes false and vice versa). The last two
|
||||
operators (\code[Operator!logical!and2@\&\&]{\&\&} and
|
||||
\code[Operator!logical!or2@{"|}{"|} {}]{||}) do not have mathematical
|
||||
counterparts. The so called \enterm{short-circuit} operators for the
|
||||
logical OR and AND let \matlab{} stop the evaluation a Boolean
|
||||
expression as soon as it becomes clear that the whole expression will
|
||||
become true or cannot become true. For example assume that the two
|
||||
statements A and B are joined using an AND. The whole expression can
|
||||
only be true if A is already true. This implies, that there is no need
|
||||
to evaluate B if A is already false. The same applies to the OR, the
|
||||
result of an OR connection will be true as soon as A is already true
|
||||
Since the statements may be arbitrarily elaborated computations this
|
||||
can save processing time.
|
||||
|
||||
Coming back to our problem of testing that the value of a variable is
|
||||
in a given range (e.g. $0.25 < x < 0.75$). We now have all the means
|
||||
for implementing such
|
||||
expressions. Listing~\ref{logicaloperatorlisting} shows a few
|
||||
examples and respective illustrations are shown in figure~\ref{logicaloperationsfig}.
|
||||
|
||||
\begin{lstlisting}[caption={Boolean expressions.}, label=logicaloperatorlisting]
|
||||
>> x = rand(1) % create a single random number in the range [0, 1]
|
||||
x = 0.3452
|
||||
>> x > 0.25 & x < 0.75
|
||||
ans = 1
|
||||
>> x = rand(10, 1) % create 10 random numbers
|
||||
x = 0.4920, 0.9106, 0.7218, 0.8749, 0.1574, 0.0201, 0.9107, 0.8357, 0.0357, 0.4732
|
||||
>> x > 0.25 & x < 0.75
|
||||
ans = 1 0 1 0 0 0 0 0 0 1
|
||||
>> x < 0.25 | x > 0.75
|
||||
ans = 0 1 0 1 1 1 1 1 1 0
|
||||
\end{lstlisting}
|
||||
|
||||
Table~\ref{logicalrelationaloperators} shows the logical and
|
||||
relational operators available in \matlab{}. The additional
|
||||
\code[Operator!logical!and2@\&\&]{\&\&} and
|
||||
\code[Operator!logical!or2@{"|}{"|} {}]{||} operators are the so
|
||||
called `\enterm{short-circuit} operators for the logical OR and
|
||||
AND. Short-circuit means that \matlab{} stops to evaluate a Boolean
|
||||
expression as soon as it becomes clear that the whole expression
|
||||
cannot become true. For example assume that the two statements A and B
|
||||
are joined using a AND. The whole expression can only be true if A is
|
||||
already true. This means, that there is no need to evaluate B if A is
|
||||
false. Since the statements may be arbitrarily elaborated computations
|
||||
this can save processing time.
|
||||
|
||||
\begin{table}[t]
|
||||
\titlecaption{\label{logicalrelationaloperators}
|
||||
Logical (left) and relational (right) operators in \matlab.}{}
|
||||
\begin{tabular}{cc}
|
||||
\hline
|
||||
\textbf{operator} & \textbf{description} \erh \\ \hline
|
||||
\varcode{$\sim$} & logical NOT \erb \\
|
||||
\varcode{$\&$} & logical AND\\
|
||||
\varcode{$|$} & logical OR\\
|
||||
\varcode{$\&\&$} & short-circuit logical AND\\
|
||||
\varcode{$\|$} & short-circuit logical OR\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\hfill
|
||||
\begin{tabular}{cc}
|
||||
\hline
|
||||
\textbf{operator} & \textbf{description} \erh \\ \hline
|
||||
\varcode{$==$} & equals \erb \\
|
||||
\varcode{$\sim=$} & unequal\\
|
||||
\varcode{$>$} & greater than \\
|
||||
\varcode{$<$} & less than \\
|
||||
\varcode{$>=$} & greater or equal \\
|
||||
\varcode{$<=$} & less or equal \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
\begin{figure}[ht]
|
||||
\includegraphics[]{logical_operations} \titlecaption{Using Boolean
|
||||
expressions for data selection.} {\textbf{A} Distribution of
|
||||
random numbers drawn from a Gaussian distribution. \textbf{B} Red
|
||||
and orange depict the parts of the data that are
|
||||
less than zero (red) and those that are greater than zero
|
||||
(orange). \textbf{C} The red segment show those data points that
|
||||
satisfies the Boolean operation shown above using a logical
|
||||
AND. \textbf{D} example of a Boolean operation that uses the
|
||||
logical OR for selecting the highlighted
|
||||
data.}\label{logicaloperationsfig}
|
||||
\end{figure}
|
||||
|
||||
\pagebreak
|
||||
\begin{important}[Assignment and equality operators]
|
||||
The assignment operator \code[Operator!Assignment!=]{=} and the
|
||||
logical equality operator \code[Operator!logical!==]{==} are
|
||||
relational equality operator \code[Operator!relational!==]{==} are
|
||||
fundamentally different. Since they are colloquially treated equal
|
||||
they can be easily confused.
|
||||
\end{important}
|
||||
|
||||
Previously we have introduced the data types for integer or floating
|
||||
point numbers and discussed that there are instances in which it is
|
||||
more efficient to use an integer data type rather than storing floating
|
||||
point numbers. The result of a Boolean expression can only assume two
|
||||
values (true or false). This implies that we need only a single bit to
|
||||
store this information as 0 (false) or 1 (true). \matlab{} knows a
|
||||
special data type (\codeterm{logical}) to store the result of a
|
||||
Boolean expression. Every variable can be evaluated to true or false
|
||||
by converting it to the logical data type. When doing so \matlab{}
|
||||
interprets all values different form zero to be true. In
|
||||
listing~\ref{booleanexpressions} we show several examples for such
|
||||
operations. \matlab{} also knows the keywords \code{true} and
|
||||
\code{false} which are synonyms for the \codeterm{logical} values 1
|
||||
and 0.
|
||||
|
||||
\begin{lstlisting}[caption={Boolean expressions.}, label=booleanexpressions]
|
||||
>> true
|
||||
ans = 1
|
||||
>> false
|
||||
ans = 0
|
||||
>> logical(1)
|
||||
ans = 1
|
||||
>> 1 == true
|
||||
ans = 1
|
||||
>> 1 == false
|
||||
ans = 0
|
||||
>> logical('test')
|
||||
ans = 1 1 1 1
|
||||
>> logical([1 2 3 4 0 0 10])
|
||||
and = 1 1 1 1 0 0 1
|
||||
>> 1 > 2
|
||||
ans = 0
|
||||
>> 1 < 2
|
||||
ans = 1
|
||||
>> x = [2 0 0 5 0] & [1 0 3 2 0]
|
||||
x = 1 0 0 1 0
|
||||
>> ~([2 0 0 5 0] & [1 0 3 2 0])
|
||||
ans = 0 1 1 0 1
|
||||
>> [2 0 0 5 0] | [1 0 3 2 0]
|
||||
ans = 1 0 1 1 0
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\section{Logical indexing}\label{logicalindexingsec}
|
||||
With subscript or linear indexing one can select elements of a vector
|
||||
or matrix by using their index. This is fine when we know the
|
||||
@ -965,7 +1067,7 @@ understood, very intuitive.
|
||||
|
||||
The basic concept is that applying a Boolean operation on a vector
|
||||
results in a \code{logical} vector of the same size (see
|
||||
listing~\ref{booleanexpressions}). This logical vector is then used to
|
||||
listing~\ref{logicaldatatype}). This logical vector is then used to
|
||||
select only those values for which the logical vector is true. Line 14
|
||||
in listing~\ref{logicalindexing1} can be read: ``Select all those
|
||||
elements of \varcode{x} where the Boolean expression \varcode{x < 0}
|
||||
|
Reference in New Issue
Block a user