[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}
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}