[programming] elaborate the boolean section a bit

This commit is contained in:
Jan Grewe 2019-11-06 12:10:21 +01:00
parent 050066a464
commit 554766acf6

View File

@ -74,7 +74,7 @@ z =
Line 1 can be read like: ``Create a variable with the name \varcode{x} 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 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{} and assigns an empty value. If not explicitly specified \matlab{}
variables will have the \codeterm{double} (a numeric data type, see variables will have the \codeterm{double} (a numeric data type, see
below) data type. In line 9, however, we create a variable \varcode{z} below) data type. In line 9, however, we create a variable \varcode{z}
@ -809,35 +809,171 @@ ans =
\section{Boolean expressions} \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 \varcode{true} or \varcode{false}. In the context of programming they
are used to test the relations between entities, i.e. are entities the are used to test the relations between entities, i.e. are entities the
same, greater or less than? Accordingly, programming languages define same, is the value of one entity greater or less than that of the
operators for such instructions. The following \codeterm{relational other? Or the truth joint conditions is evaluated. Imagine that you
operators} are defined: (\code[Operator!relational!>]{>}, take two independent measures and want to take a certain action only
\code[Operator!relational!<]{<}, \code[Operator!relational!==]{==}, if both exceed a certain threshold. Boolean expressions are important
\code[Operator!relational!"~]{~}, greater than, less than, equal to, e.g. to control which parts of the code are evaluated under a certain
and not. Using so called \codeterm[Operator!logical]{logical condition (conditional statements, Section~\ref{controlstructsec}) but
operators} allows to join single Boolean expressions to more complex also for accessing only those elements of a vector or matrix that
constructs (\code[Operator!logical!and1@\&]{\&}, match a certain condition (logical indexing,
\code[Operator!logical!or1@{"|} {}]{|}, AND, OR). These expressions Section~\ref{logicalindexingsec}).
are important e.g. to control which parts of the code are evaluated
under certain conditions (conditional statements, \subsection{The \emph{logical} data type}
Section~\ref{controlstructsec}) but also for accessing only those Previously we have introduced data types for integer or floating point
elements of a vector or matrix that match a certain condition (logical numbers and discussed that there are instances in which it is more
indexing, Section~\ref{logicalindexingsec}). efficient to use an integer data type rather than storing floating
point numbers. The result of a Boolean expression can only assume two
Truth tables (\ref{logicalandor}) are used to visualize the results of values (\varcode{true} or \varcode{false}). This implies that we need
Boolean expressions. A and B are statements that can be evaluated to only a single bit to store this information as 0 (false) or 1 (true)
true or false. When they are combined with a logical AND the whole It would be a waste of space to use more than one bit for
expression is true only if both statements are true. The logical OR, it. Accordingly, \matlab{} knows a special data type
on the other hand, requires that at least one of the statements is (\codeterm{logical}) to store such information efficiently. \matlab{}
true. The exclusive OR (XOR) is true only for cases in which one of also knows the keywords \code{true} and \code{false} which are
the statements but not both are true. There is no operator for XOR in synonymous for the \codeterm{logical} values 1 and
\matlab{} it is realized via the function \code[xor()]{xor(A, B)}. 0. Listing~\ref{logicaldatatype} exemplifies the use of the logical
data type.
\begin{table}[tp]
\titlecaption{Truth tables for logical AND, OR and XOR.}{}\label{logicalandor} \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} \begin{tabular}{llll}
\multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\ \multicolumn{2}{l}{\multirow{2}{*}{}} & \multicolumn{2}{c}{\textbf{B}} \\
& \sffamily{\textbf{AND}} & \multicolumn{1}{|c}{true} & false \\ \cline{2-4} & \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{tabular}
\end{table} \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 \begin{figure}[ht]
relational operators available in \matlab{}. The additional \includegraphics[]{logical_operations} \titlecaption{Using Boolean
\code[Operator!logical!and2@\&\&]{\&\&} and expressions for data selection.} {\textbf{A} Distribution of
\code[Operator!logical!or2@{"|}{"|} {}]{||} operators are the so random numbers drawn from a Gaussian distribution. \textbf{B} Red
called `\enterm{short-circuit} operators for the logical OR and and orange depict the parts of the data that are
AND. Short-circuit means that \matlab{} stops to evaluate a Boolean less than zero (red) and those that are greater than zero
expression as soon as it becomes clear that the whole expression (orange). \textbf{C} The red segment show those data points that
cannot become true. For example assume that the two statements A and B satisfies the Boolean operation shown above using a logical
are joined using a AND. The whole expression can only be true if A is AND. \textbf{D} example of a Boolean operation that uses the
already true. This means, that there is no need to evaluate B if A is logical OR for selecting the highlighted
false. Since the statements may be arbitrarily elaborated computations data.}\label{logicaloperationsfig}
this can save processing time. \end{figure}
\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}
\pagebreak
\begin{important}[Assignment and equality operators] \begin{important}[Assignment and equality operators]
The assignment operator \code[Operator!Assignment!=]{=} and the 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 fundamentally different. Since they are colloquially treated equal
they can be easily confused. they can be easily confused.
\end{important} \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} \section{Logical indexing}\label{logicalindexingsec}
With subscript or linear indexing one can select elements of a vector 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 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 The basic concept is that applying a Boolean operation on a vector
results in a \code{logical} vector of the same size (see 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 select only those values for which the logical vector is true. Line 14
in listing~\ref{logicalindexing1} can be read: ``Select all those in listing~\ref{logicalindexing1} can be read: ``Select all those
elements of \varcode{x} where the Boolean expression \varcode{x < 0} elements of \varcode{x} where the Boolean expression \varcode{x < 0}