[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}
|
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}
|
||||||
|
Reference in New Issue
Block a user