%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                          %
%   HPLOT  Reference Guide - Examples and output generated                 %
%    Last Mod. 9 July 1993 oc                                              %
%                                                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Examples of HPLOT output}
The examples are reproduced directly from the output of a PostScript metafile
and introduced into the \LaTeX{} file containing the \HPLOT{} manual.

\begin{XMPt}{HPLOT test program}
      PROGRAM HPLEXA
*
      CHARACTER*(*) HZFILE,HPFILE
+SELF,IF= IBM.
      PARAMETER (HZFILE='/HPLOT HIGZ')
+SELF,IF= IBM,IF=-PSCRIPT.
      PARAMETER (HPFILE='/HPLOT METAFILE')
+SELF,IF= IBM,IF= PSCRIPT.
      PARAMETER (HPFILE='/HPLOT PS')
+SELF,IF=-IBM.
      PARAMETER (HZFILE='hplot.higz')
+SELF,IF=-IBM,IF=-PSCRIPT.
      PARAMETER (HPFILE='hplot.metafile')
+SELF,IF=-IBM,IF= PSCRIPT.
      PARAMETER (HPFILE='hplot.ps')
+SELF.
      COMMON/PAWC/H(100000)
      LOGICAL INTRAC
*.___________________________________________
+SELF,IF=IBM,IF=X11.
      CALL INITC
+SELF,IF=APOLLO,UNIX,IBM,CRAY.
      OPEN(UNIT= 1,FILE=HZFILE,FORM='UNFORMATTED',RECL=4096,
     +     ACCESS='DIRECT',STATUS='UNKNOWN')
+SELF,IF=VAX
      OPEN(UNIT=1,FILE=HZFILE,FORM='UNFORMATTED',RECL=1024,
     +     ACCESS='DIRECT',SHARED,STATUS='UNKNOWN')
+SELF,IF=-VAX.
      OPEN(UNIT=10,FILE=HPFILE,FORM='FORMATTED',STATUS='UNKNOWN')
+SELF,IF= VAX.
      OPEN(UNIT=10,FILE=HPFILE,FORM='FORMATTED',SHARED,
     +     STATUS='UNKNOWN')
+SELF.
      IF(.NOT.INTRAC(DUMMY))THEN
         KWTYPE=0
      ELSE
         CALL IGWKTY(KWTYPE)
      ENDIF
      CALL TIMED(T0)
      CALL HLIMIT(100000)
      CALL HPLINT(KWTYPE)
      CALL HPLMAK
      IF(KWTYPE.NE.0)THEN
         CALL HPLOPT('PTO ',1)
         CALL HPLEX1
         CALL TIMED(T1)
         PRINT *, ' TIME FOR EXAMPLE 1 =',T1,'  SECONDS'
         CALL HPLEX2
         CALL TIMED(T2)
         PRINT *, ' TIME FOR EXAMPLE 2 =',T2,'  SECONDS'
         CALL HPLEX3
         CALL TIMED(T3)
         PRINT *, ' TIME FOR EXAMPLE 3 =',T3,'  SECONDS'
         CALL HPLEX4
         CALL TIMED(T4)
         PRINT *, ' TIME FOR EXAMPLE 4 =',T4,'  SECONDS'
         CALL HPLEX5
         CALL TIMED(T5)
         PRINT *, ' TIME FOR EXAMPLE 5 =',T5,'  SECONDS'
      ENDIF
      CALL HPLOPT('NPTO',1)
*
*          Open HIGZ metafile
*          and repeat previous examples
*
      PRINT *,' WRITING HIGZ PICTURE FILE'
      CALL IGZSET('Z')
      CALL IZFILE(1,'HPLOT','NA')
      CALL HPLOPT('ZFL ',1)
      CALL HPLEX6
      CALL TIMED(T6)
      PRINT *, ' TIME TO WRITE HIGZ PICTURE FILE =',T6,'  SECONDS'
*
*          Open a GKS or PostScript metafile
*          and repeat previous examples
*
      PRINT *,' WRITING METAFILE (BE PATIENT !)'
      CALL IGZSET('G')
      CALL HPLOPT('NZFL',1)
      CALL HPLCAP(-10)
      CALL HPLEX6
      CALL TIMED(T7)
      PRINT *, ' TIME TO WRITE METAFILE =',T7,'  SECONDS'
*
*          Replay some pictures from the HIGZ picture file
*
      IF(KWTYPE.NE.0)THEN
         CALL HPLCAP(0)
         CALL HPLEX7
      ENDIF
*
      CALL HPLEND
      END
\end{XMPt}

\newpage

\begin{XMPt}{Creation of some histograms (based on HBOOK examples)}
      SUBROUTINE HPLMAK
*
      COMMON/HEX2/C1,C2,XM1,XM2,XS1,XS2
      EXTERNAL HTFUN1,HTFUN2
*.___________________________________________
*
*             BOOKING
*
      C1=1.
      C2=0.5
      XM1=0.3
      XM2=0.7
      XS1=0.07
      XS2=0.12
*
      CALL HBFUN1(100,'TEST OF HRNDM1',100,0.,1.,HTFUN1)
*
      CALL HBOOK1(110,'Test of 1-DIM plots',100,0.,1.,1000.)
*
      CALL HBFUN2(200,'Test of 2-DIM plots',40,0.,1.,40,0.,1.,HTFUN2)
      CALL HSCALE(200,0.)
*
*             FILLING
*
      DO 10 I=1,5000
         X=HRNDM1(100,I)
         CALL HFILL(110,X,0.,1.)
  10  CONTINUE
*
      END
      FUNCTION HTFUN1(X)
      COMMON/HEX2/C1,C2,XM1,XM2,XS1,XS2
*
      A1=-0.5*((X-XM1)/XS1)**2
      A2=-0.5*((X-XM2)/XS2)**2
      X1=C1
      X2=C2
      IF(ABS(A1).GT.1.E-4)X1=C1*EXP(A1)
      IF(ABS(A2).GT.1.E-4)X2=C2*EXP(A2)
      HTFUN1=X1+X2
      END
      FUNCTION HTFUN2(X,Y)
      HTFUN2=HTFUN1(X)*HTFUN1(Y)
      END
\end{XMPt}

\newpage

\begin{XMPt}{Examples of basic HPLOT : 1-DIM histograms}
      SUBROUTINE HPLEX1
*
      CALL HTITLE('EXAMPLE NO = 1')
*
      CALL HPLSIZ(14.,16.,' ')
      CALL HPLOT(110,' ',' ',0)
      CALL HPLSET('HTYP',333.)
      CALL HPLOT(110,' ',' ',0)
      CALL HPLAX('GeV/C',' ')
      CALL HPLSIZ(14.5,21.4,' ')
      CALL HPLZON(1,2,1,' ')
      CALL HPLOT(110,' ',' ',0)
      CALL HPLSET('HTYP',244.)
      CALL HPLOT(110,' ',' ',0)
      CALL HPLSET('HTYP',0.)
      CALL HPLZON(1,1,1,' ')
*
      END
\end{XMPt}
\newpage
\begin{Fighere}
\begin{center}\includegraphics{hplot11.eps}\end{center}
\end{Fighere}
\begin{Fighere}
\begin{center}\includegraphics{hplot12.eps}\end{center}
\end{Fighere}
\begin{Fighere}
\begin{center}\includegraphics{hplot13.eps}\end{center}
\end{Fighere}

\newpage

\begin{XMPt}{Examples of basic HPLOT : 2-DIM histograms}
      SUBROUTINE HPLEX2
*
      CALL HTITLE('EXAMPLE NO = 2')
*
      CALL HPLSIZ(14.,14.,' ')
      CALL HPLSET('YGTI',0.3)
      CALL HPLSET('XMGL',1.)
      CALL HPLSET('YMGL',1.)
      CALL HPLSET('XMGR',1.)
      CALL HPLSET('YMGU',1.)
      CALL HPLSET('VSIZ',0.2)
      CALL HPLSET('YHTI',0.6)
      CALL IGSET('MTYP',1.)
      CALL HPLOT(200,' ',' ',0)
      CALL HPLCON(200,10,1)
      CALL HPLEGO(200,30.,30.)
      CALL HPLSUR(200,30.,30.,1)
*
      END
\end{XMPt}
\newpage
\begin{Fighere}
\begin{center}\includegraphics{hplot21.eps}\end{center}
\end{Fighere}
\begin{Fighere}
\begin{center}\includegraphics{hplot22.eps}\end{center}
\end{Fighere}
\begin{Fighere}
\begin{center}\includegraphics{hplot23.eps}\end{center}
\end{Fighere}
\begin{Fighere}
\begin{center}\includegraphics{hplot24.eps}\end{center}
\end{Fighere}

\newpage

\begin{XMPt}{Examples of HPLOT options}
      SUBROUTINE HPLEX3
*
      CALL HTITLE('EXAMPLE NO = 3')
*
      CALL HPLSIZ(14.5,20.,' ')
      CALL HPLSET('GSIZ',0.5)
      CALL HOPERA(110,'+',110,120,0.5,0.)
      CALL HOPERA(120,'+',120,130,0.5,0.)
      CALL HPLSET('PASS',5.)
      CALL HPLSET('CSHI',0.03)
      CALL HPLSET('XVAL',0.15)
      CALL HPLOPT('TIC ',1)
      CALL HPLOT(110,' ',' ',0)
      CALL HPLSET('HTYP',245.)
      CALL HPLOT(120,'S',' ',0)
      CALL HPLSET('HTYP',254.)
      CALL HPLOT(130,'S',' ',0)
      CALL HPLSOF(7.,12.,'LEP4 Very Preliminary',0.5,45.,99.,-1)
*
      END
\end{XMPt}
\newpage
\begin{Fighere}
\begin{center}\includegraphics{hplot31.eps}\end{center}
\end{Fighere}

\newpage

\begin{XMPt}{ Examples of HPLOT options}
      SUBROUTINE HPLEX4
*
      DIMENSION X(100),Y(100),EX(100),EY(100)
*
      CALL HTITLE('EXAMPLE NO = 4')
*
      CALL HCOPY(110,310,' ')
      CALL HRESET(310,' ')
      CALL HPLSET('XMGL',1.)
      CALL HPLSET('YMGL',1.)
      CALL HPLSET('XMGR',1.)
      CALL HPLSET('YMGU',1.)
      CALL HPLSET('VSIZ',0.2)
      CALL HPLSET('XVAL',0.15)
      CALL HPLSET('YGTI',0.3)
      CALL HPLSET('YHTI',0.6)
      CALL HPLSIZ(14.5,21.,' ')
      CALL HPLZON(1,2,1,' ')
      CALL HMAXIM(310,200.)
      CALL HMINIM(310,-25.)
      CALL HPLOT(310,' ',' ',0)
      CALL HREBIN(110,X,Y,EX,EY,50,1,100)
      CALL HPLERR(X,Y,EX,EY,48,' ',25,0.15)
      CALL HPLKEY(9.,18.,25,'p,K^+!,K^-!,[S,W')
*
      CALL HPLOT(310,' ',' ',0)
      CALL HREBIN(110,X,Y,EX,EY,20,1,100)
      CALL HPLERR(X,Y,EX,EY,20,' ',22,0.2)
      CALL HPLKEY(9.,8.,22,'[p^+!,p^-!,m^+!,m^-')
      CALL HDELET(120)
      CALL HDELET(130)
      CALL HDELET(310)
*
      END
\end{XMPt}
\newpage
\begin{Fighere}
\begin{center}\includegraphics{hplot41.eps}\end{center}
\end{Fighere}

\newpage

\begin{XMPt}{Examples of HPLOT options (BARS)}
      SUBROUTINE HPLEX5
*
      DIMENSION XALL(12),XFEM(12)
      DATA XALL/
     +100.,200.,300.,500.,400.,700.,600.,400.,500.,300.,200.,100./
      DATA XFEM/
     + 70.,220.,330.,480.,440.,650.,300.,100.,200.,300.,200.,300./
*
      CALL HTITLE('EXAMPLE NO = 5')
*
      CALL HPLSET('YGTI',0.3)
      CALL HPLSIZ(14.5,21.,' ')
      CALL HPLZON(1,2,1,' ')
      CALL HBOOK1(1,'Distribution of grades (males)',12,2.,14.,0.)
      CALL HPAK(1,XALL)
      CALL HPLOPT('BAR ',1)
      CALL HPLSET('HTYP',188.)
      CALL HPLOT(1,' ',' ',0)
      CALL HRESET(1,'(Males and Females)')
      CALL HPAK(1,XALL)
      CALL HPLSET('BARO',0.)
      CALL HPLSET('BARW',0.3)
      CALL HPLOT(1,' ',' ',0)
      CALL HPLSET('HTYP',211.)
      CALL HPLSET('BARO',0.4)
      CALL HPAK(1,XFEM)
      CALL HPLOT(1,'SAME',' ',0)
      CALL HPLOPT('NBAR',1)
      CALL HDELET(1)
      CALL HPLSET('*',0.)
*
      END
\end{XMPt}
\newpage
\begin{Fighere}
\begin{center}\includegraphics{hplot51.eps}\end{center}
\end{Fighere}

\newpage

\begin{XMPt}{Examples of HPLOT using GKS metafiles or HIGZ files}
      SUBROUTINE HPLEX6
*
      CALL HPLEX1
      CALL HPLEX2
      CALL HPLEX3
      CALL HPLEX4
      CALL HPLEX5
      CALL HPLNUL
*
      END
\end{XMPt}

\begin{XMPt}{Examples of HPLOT playing back HIGZ files}
      SUBROUTINE HPLEX7
*
      CHARACTER*10 STR
      DATA ICYCLE/999/
*
      CALL RZLDIR(' ',' ')
      CALL IGSET('AURZ',0.)
      CALL IZIN('PICT1',ICYCLE)
      CALL IZPICT('PICT1','D')
      CALL IRQST(1,1,ISTAT,NCH,STR)
      CALL IZIN('PICT8',ICYCLE)
      CALL IZPICT('PICT8','D')
      CALL IRQST(1,1,ISTAT,NCH,STR)
      CALL IZIN('PICT9',ICYCLE)
      CALL IZPICT('PICT9','D')
      CALL IRQST(1,1,ISTAT,NCH,STR)
*
      END
\end{XMPt}


    \filetitle{subsasgn}{Subscripted assignment for tseries objects}{tseries/subsasgn}

	\paragraph{Syntax}\label{syntax}

\begin{verbatim}
X(Dates) = Values;
X(Dates,I,J,K,...) = Values;
\end{verbatim}

\paragraph{Input arguments}\label{input-arguments}

\begin{itemize}
\item
  \texttt{X} {[} tseries {]} - Tseries object that will be assigned new
  observations.
\item
  \texttt{Dates} {[} numeric {]} - Dates for which the new observations
  will be assigned.
\item
  \texttt{I}, \texttt{J}, \texttt{K}, \ldots{} {[} numeric {]} -
  References to 2nd and higher dimensions of the tseries object.
\item
  \texttt{Values} {[} numeric {]} - New observations that will assigned
  at specified dates.
\end{itemize}

\paragraph{Output arguments}\label{output-arguments}

\begin{itemize}
\itemsep1pt\parskip0pt\parsep0pt
\item
  \texttt{X} {[} tseries {]} - Tseries object with newly assigned
  observations.
\end{itemize}

\paragraph{Description}\label{description}

\paragraph{Example}\label{example}


\subsection{Surface-Enhanced Raman Spectroscopy of Graphene}

Plasmonics explores the interaction of metallic surfaces and light that causes density waves of electrons called plasmons. The electron density wave propagating on the metal surface is often referred to as a surface plasmon. In addition, localised surface plasmons are created by exciting a nanostructure that is smaller than the wavelength $\lambda$ of the light used for the excitation~\cite{maier2007}.

Exciting a localized surface plasmon during Raman processes can increase the intensity of the Raman signal by several orders of magnitude~\cite{maier2007}. This field enhancement is strongest for a resonance between the frequency of the incident light and the frequency of the surface plasmon $\omega_P$. Because of the influence of the surface plasmons this method is called "Surface-Enhanced Raman Spectroscopy".

\begin{figure}[!h]
  \centering
  \begin{subfigure}{0.45\textwidth}
    \includegraphics[width=\textwidth]{./images/sers-schema.png}
  \end{subfigure}
  ~
  \begin{subfigure}{0.45\textwidth}
    \includegraphics[width=\textwidth]{./images/local-enhancement-heeg.png}
  \end{subfigure}
  \caption{\textbf{(a)} A gold-nanodisk dimer with a chromium interlayer is fabricated with e-beam lithography on a SiO$_2$/Si substrate. A layer of graphene is suspended on top of the nanostructure and pulled into the gap (figure adapted from ref.~\cite{heeg}). \textbf{(b)} Local $E$-field enhancement at $\lambda = \SI{638}{nm}$ and a distance to the substrate of \SI{40}{nm}. The blue dashed line indicates the area that includes 90\% of the near field intensity according to \cite{heeg} (figure from ref.~\cite{heeg})}
  \label{fig:heeg-experiment}
\end{figure}

The experiment relevant for this work is depicted in figure~\ref{fig:heeg-experiment} (for details see ref.~\cite{heeg}). Graphene is suspended on top of two gold disks with a diameter of \SI{100}{nm} and a gap of \SI{30}{nm}. Localized surface plasmons in the gold structures enhance the Raman signal. The near-field intensity enhancement at a distance of \SI{40}{nm} to the substrate is shown in figure~\ref{fig:heeg-experiment}b. The geometry of the nanostructure is chosen to be in resonance with the laser wavelength of $\lambda = \SI{638}{nm}$. Only the component of the electric field that lies within the graphene plane is contributing to the enhancement.

\subsubsection{Electromagnetic-Enhancement Theory of SERS}

The effect of electromagnetic field enhancement actually happens twice in surface-enhanced Raman spectroscopy (SERS): The incoming- and the Raman-scattered light are both enhanced by an interaction with the localized surface plasmon. The local electromagnetic enhancement at position $\mathbf{r}$ and laser frequency $\omega_\mathrm{L}$ can be calculated as~\cite{maier2007}
\begin{equation}
  Enh_\mathrm{loc}(\mathbf{r},\omega_L)=\frac{\left|\mathbf{E}_\mathrm{loc}(\mathbf{r}, \omega_L)\right|^2}{\left|\mathbf{E}_0\right|^2}\frac{\left|\mathbf{E}_\mathrm{loc}(\mathbf{r}, \omega_L-\omega_\mathrm{ph})\right|^2}{\left|\mathbf{E}_0\right|^2}\approx\frac{\left|\mathbf{E}_\mathrm{loc}(\mathbf{r}, \omega_L)\right|^4}{\left|\mathbf{E}_0\right|^4},
  \label{eq:enhancement}
\end{equation}
where $\mathbf{E}_\mathrm{loc}$ is the local electric field amplitude, $\mathbf{E}_0$ the electric field amplitude of the reference signal and $\omega_\mathrm{ph}$ the phonon frequency. For a Raman shift that is small compared to the laser frequency, the enhancement is proportional to $\mathbf{E}^4$.


\section{Unification}

First of all we describe the data structures and algorithms of
the unification algorithm. All classes used for this algorithm
can be found in the package \texttt{de.renew.unify}.

\subsection{Motivation}

For improved usability, the inscription
language of a Petri net formalism should support some sort of tuples to
facilitate the easy retrieval of matching values. Tuples are already
a classic area in which unification algorithms have been applied,
and the unification of tokens at places with arc inscriptions
requires at least a matching algorithm. There are, however,
aspects of the simulation algorithm for which a unification
algorithm is useful in different ways.

Petri net formalisms often require the consideration of
many different transition inscriptions when firing a transition.
Mostly, these inscriptions are given without a particular order, so their
effect should not depend on the order of their evaluation.
This coincides with the characteristic of unification algorithms,
i.e., the sequence of unification is irrelevant.

For synchronous channels, no direction of the information flow
is prescribed. during the search for enabled
bindings, the values and variables on both sides must be unified,
as a simple assignment is generally not possible. First of all,
a parameter of a synchronous channel itself could be again a
tuple expression, if we want to keep the orthogonality of the
language definitions. Further, a synchronous channel might have to be
handled even before the last variable of the initiating side
is bound. This is especially important when the channel transfers
values in both directions.

The question is, whether more unifiable objects, besides tuples,
should be examined. Lists were identified as a reasonable
extension of a net formalism. Although lists can be represented
as nested tuples, for the sake of better usability this way
of implementation should not be externally visible. However,
we cannot modify the representation of tuples, as nested tuples
do not always represent a list. Hence a special category of
lists was created which allows a more suitable representation
and prohibits the visibility of their internal structure as well.
In the following, we will not deal with this class often since
nothing changes in the actual unification algorithm and all
interesting effects can already be observed with tuples.

\subsection{Unknowns}

Each variable has a value. This can be a normal Java object or
a unifiable object. When a new variable is generated, its value
is unknown at first, because the variable is completely unbound.
In order to be able to indicate a value nonetheless, special
objects have been introduced by the class
\texttt{Unknown}.

These objects become important during unification. After
two unassigned variables \texttt{x} and \texttt{y} have been unified, their
value is still unknown. The unification, however, is visible
in that both variables would return the same unknown as their value.

We note that, after the unification of \texttt{x} and \texttt{y},
it is not specified which of the two
unknowns will form the later value of \texttt{x} and \texttt{y}.
In fact, this is irrelevant for further unifications.
Outside the unification algorithm, the class \texttt{Unknown}
need not be known anyway, because variables should be
queried for their valuation only after
they have become completely bound, i.e., when no unknown is part
of their value, not even nested within a tuple.

\subsection{Backtracking}

For the implementation of a unification algorithm one can choose
one of two ways. Either unification creates a new binding list
that assigns the appropriate values to the variables, whereby the
original bindings list is preserved; or, alternatively, the old
binding information is overwritten and thus no longer available.

Here, the second way, which modifies the existing objects, has
been chosen, so that unnecessary copying can be avoided.

In a Petri net simulator, however, it is necessary to be able to
reset to the old state as required, for example when a
proposed binding of an arc variable to a token value
did not lead to an activated
transition and alternative bindings should be tried out.

Therefore all modifications that the unification algorithm executes
are noted in a central object, which belongs to the \texttt{StateRecorder}
class. For all modifying accesses to unifiable objects a recorder
must then be specified. If the special value \texttt{null} is used, then
the corresponding operation cannot be undone. Otherwise, all attributes
of the object that are supposed to be modified are stored in
the recorder. It is important to make no modification at all before
recording it first.

In order to keep the recording of the modifications as flexible as
possible, the state recorder does not prescribe a format for the information
that must be recorded. Instead, an object of the type
\texttt{StateRestorer} is transmitted. This object possesses only one method
\texttt{restore()} and stores all necessary information. For each
type of modification a subclass of \texttt{StateRestorer} is created.

Several reset points can be specified for a recorder, so that a partial
resetting is possible. Modifications are always undone in the reverse
order in which they were made.

It will be shown that almost the entire state of the Petri net
simulator is stored in unifiable objects, and that almost the
entire backtracking can be performed by this algorithm.
If information is not connected to unifiable objects, special
subclasses of \texttt{StateRestorer} can handle these cases, too.

\singlediagram{unifdata}{Unifiable objects}

\subsection{Unifiability and Java Equality}

The unifiability of Java objects was implemented on the basis of the
method \texttt{equals(Object)}.
Thus we follow the decision of the programmers of container classes,
where this way is also always chosen to access the contents
of a container. It is a procedure already embodied in the
language definition, which can be adapted sufficiently flexibly to
individual needs.

The substantial problems develop from the fact that the Java definition
of equality allows \texttt{equals(Object)} to vary over time.
In most cases the Java API follows the rule that only for
unchangeable objects equality may be coarser than identity, but
there are exceptions as for instance \texttt{java.awt.Point} or the
container classes from Java 1.2.

This is to be borne, if Java's equality concept is normally used.
It becomes a serious problem for unification, however, because a check
for equality may occur in many unexpected places.

Now the question arises, how unifiable objects themselves deal
with testing on equality. Tuples are very easy to handle, because
for them the equality is defined by the equality of all components.

For unknowns, however, a certain problem results, because they can still
take any value by unification, so that the outcome of a comparison with
other objects is not at all defined.

Therefore a comparison attempt on unknowns throws an exception,
which interrupts the normal program flow and is normally announced as error.
Indeed a comparison should not occur, because unknown should be used only
under the control of the Petri net simulator. To other program sections
the simulator should only pass completely bound tuples,
so that unknown should not be accessible from normal Java code.

Since backtracking operations can again introduce unknown components into
already fully unified tuples, it would be possible that an appropriate
method stores reference to a complete tuple and later, after the
backtracking, accesses the tuple again and retrieves an unknown. Since
those methods that are not invoked from within actions
should not have any side effects, this effect will only
occur in actions. In that case all, however, all tuples will first be
copied, so that they are not subject to backtracking any more.

A hash code must be assigned to each Java Object. For tuples this
is calculated using a simple polynomial derived from the hash codes of
the tuple components. For unknowns the query of the hash code throws
an exception, because an unknown should not be stored in a hashed
data structure.

\subsection{Occurrence check}

If a tuple could contain itself directly or indirectly, then one could
describe certain infinite data structures quite easily. But such things
are not easy to handle in the mathematical theory and cause problems
during the implementation, too.

With unification further problems occur. In particular,
attention would have to be paid to avoid endless loops. Also unification
is founded on the basis of term unification of predicate
logic, where infinite terms are not allowed.

Thus there is the task is to ensure cycle-freeness during the
unification: the so called occurrence check, which checks for the
occurrence of a tuple within in another tuple. The
occurrence check is sometimes not implemented in the area of
logical programming, and one leaves the behavior in the case
of recursive tuple unspecified, because a check in
that context would be very expensive. In Petri net simulators
the principal complexity is due to other algorithms, so
that an occurrence check does not slow down the simulator considerably.

\subsection{Calculations}

In the formalism of the reference nets it is possible to carry out
certain calculations only during the execution of a transition,
which is noted with the keyword action. The results of the
calculations are not known to the unification algorithm,
yet the algorithm should as far possibly be able to deal with these
calculations.

Especially, late calculations should be effectively executable
during the transition's firing. This leads to certain requirements:
\begin{itemize}
\item Cyclic dependencies shall be detected. This applies also to
complex multi-level dependencies. For example, the call
\texttt{action x=[1,a.method(x)]}
should fail before the firing of the transition,
because here \texttt{x} depends on itself
indirectly through a method invocation
and a tuple.

\item As far as possible, the result type of a later calculation should be
represented by unification algorithm, so that no preventable
type errors may occur.
\end{itemize}

A calculation is represented by special unifiable objects
of the type \texttt{Calculator}.
A calculator is unifiable only with unknowns and with itself,
but not with tuples, values or other calculators.
In particular, equality reduces to identity for calculations.

Calculator objects reference exactly another object, which can serve
as an argument for a calculation. If more arguments are required,
this can be implemented by a calculator object that references a tuple
object.

Occasionally a variable value must be of a certain type,
in order to be a valid allocation for the variable.
this is ensured by the class \texttt{TypeConstrainer}. Such an object
monitors an arbitrary value. As soon as the value is no more
an unknown, the type of the new value is
checked. This might be possible before the value is completely
bound. For example, a tuple may be type checked before all its
components are bound.

\singlediagram{tupleindex}{A tuple index}

In order to be able to provide type checking for late calculation,
all calculator objects carry the predicted type of their result.
If a \texttt{TypeConstrainer} detects as a calculation object as value, the
predicted type is used instead of the type \texttt{Calculator}.

In Fig.~\ref{fig:unifdata} we summarize the main classes involved in
the representation of unifiable data structures. You can see
how every implementation of \texttt{Referer} is assisted by an instance
of \texttt{Reference}. Similarly, every \texttt{Referable} is
augmented by a \texttt{BacklinkSet}. A backlink set collects
information about all those references that reference its owner.
A reference makes sure to insert itself into the backlink set
of its referenced object.

Using a \texttt{CalculationChecker} object a program can require that
certain variables must be bound or that they must be complete.
A value is complete if it contains no unknowns, even nested
within a multitude of unifiable objects. A complete value
is bound if it contains no calculators.

\subsection{Tuple Index}

The tuple index is a specialized data structure that allows to select
among a set of tuples some candidates that might fit a given pattern.
The given pattern is itself a possibly nested tuple, which might be
incomplete, i.e., it might contain unknown in some substructures.

The tuple index provides an upper bound for the set of matching
values based on exactly one component of the tuple or one component
of a subcomponent of the tuple. The tuple index will try all
complete subcomponents of the tuple during lookup and select the best
estimate among these. It will not, however, consider more then one
components. E.g., with the set \texttt{[0,0,0]}, \texttt{[0,1,0]},
\texttt{[0,1,1]},and \texttt{[1,0,0]} of values and
the pattern \verb:[0,0,_]:, the only matching pattern is
\texttt{[0,0,0]}, but the optimal guess based on
the second component contains \texttt{[0,0,0]} and \texttt{[1,0,0]}.


\section{Lineshape determination (new 11/2002)}

\subsection{Introduction}

This note summarizes the proposed lineshape treatment
for SP5 Monte Carlo production in {\tt EvtGen}.  Some
significant changes have been made since SP4 given
input from users during the past year.  The generater
now works in several steps:
\begin{enumerate}
\item The complete decay chain is determined according
to the branching fractions given in {\tt EvtGen/DECAY.DEC}
and the user decay file.
\item The mass of each particle in the decay chain
is determined, as described below.
\item The kinematics of each particle are determined
according to the decay model specified.
\end{enumerate}

As these are separate steps, the algorithm for
the determination of masses is not as general
is would be possible if the mass determination and
kinematic determination were combined.  This would
entail a more significant code rewrite, which we
were not able to undertake.

\subsection{Lineshapes}

\subsubsection{What is the default?}

The short answer is that it depends on the decay.  For a
particle $P$, the algorithm is as follows:

\begin{enumerate}
\item Something like 30\% of $B$ mesons are decayed
using JETSET. If $P$ is produced by JETSET, then
its lineshape is determined by JETSET.  JETSET uses
a nonrelativistic Breit-Wigner.
\item If $P$ or any of its daughters has a spin other
than 0, 1/2, 1, 3/2, or 2,
a nonrelativistic Breit Wigner is used.
\item If the decay $P \to D_1 D_2$ proceeds by
a higher partial wave than $D$ wave, a nonrelativistic
Breit Wigner is used. (in practice, this case appears
to never occur in our DECAY.DEC)
\item $G \to P P_1$ and $P \to D_1 D_2$ (ie, $P$ is
produced and decayed in a two body decay): A relativistic
Breit-Wigner is used.  The corresponding amplitude is
\begin{equation}
A(m) = {{(p_{G \to P P_1}^{L_{G \to P P_1}} )
(p_{P \to D_1 D_2}^{L_{P \to D_1 D_2}})} \over {m^2 -{m_0}^2 + im \Gamma(m)}}
({B(p_{G \to P P_1}) \over B(p^{\prime}_{G \to P P_1})})
({B(p_{P \to D_1 D_2}) \over B(p^{\prime}_{P \to D_1 D_2})})
\label{eq:ls}
\end{equation}
where $m_0$ is the nominal particle mass as specified
in {\tt PDT/pdt.table} and $p$ is the daughter
momentum in the rest frame of its parent (for the
specified decay chain). $p^{\prime}$ is the same, but for the nominal
mass of P.
$\Gamma(m)$ is
\begin{equation}
\Gamma(m) = \left( {p \over p^{\prime}} \right)^{2L_{P \to D_1 D_2}+1}
\left( m_0 \over m \right) \Gamma_0
\left[ B(p) \over B(p^{\prime}) \right].
\label{eq:gamma}
\end{equation}
Here $\Gamma_0$ is the nominal particle width has
specified in {\tt PDT/pdt.table}.  $p$ and $p^{\prime}$
are the daughter momenta in the rest frame of $P$,
if $P$ has mass $m$ or
$m_0$, respectively.  $L$ is the angular momentum
of the decay specified in its subscript, which is assumed
to be the lowest allowed given the parent and daughter spins.
$B(p)$ is the Blatt-Weisskopf form factor, which depends on
$L$:
\begin{eqnarray}
B(p) &=& 1  \nonumber \\
B(p) &=& {1 \over \sqrt{1+(Rp)^2}} \nonumber \\
B(p) &=& {1 \over \sqrt{1+{(Rp)^2 \over 3} + {(Rp)^4 \over 9}}}
\end{eqnarray}
for $L_{P \to D_1 D_2}$ equal to 0, 1, or 2. $R$ is $3~{\rm GeV}^{-1}$.
\item $G \to P P_1 P_2 X$ and $P \to D_1 D_2$ (ie, $P$ has
two daughters): Very similar to the above case, except the
birth momentum factor and form factor are removed:
\begin{equation}
A(m) = {{
(p_{P \to D_1 D_2}^{L_{P \to D_1 D_2}})} \over {m^2 -{m_0}^2 + im \Gamma(m)}}
({B(p_{P \to D_1 D_2}) \over B(p^{\prime}_{P \to D_1 D_2})})
\label{eq:ls2}
\end{equation}

\item $P \to P_1 P_2 P_3 X$ (ie, $P$ decays to more than
two daughters): A nonrelativitic Breit-Wigner is
used.

\end{enumerate}

\subsubsection{Mass cutoffs, etc}

Cutoffs are listed in {\tt PDT/pdt.table}.  The cutoff
given represents the maximum $\Delta$ allowed from the
nominal mass, but only on the low side.  That is, the
lowest allowed mass is $m - \Delta$. The highest allowed
mass is $m + 15 \Gamma$.  In the case that the cutoff
is not given, the lowest mass is ${\rm max}(0, m-15 \Gamma)$.

\subsubsection{What can be changed in user decay files?}

We have added some flexibility in how lineshapes
can be generated for signal Monte Carlo.  We hope
that this will simplify systematic studies.  The
various options are listed below.  As with other
features of user decay files, be sure to test your
changes with {\tt GeneratorsQA} before submitted your
request for a Monte Carlo sample.
\begin{itemize}
\item Lowest generated mass
\begin{verbatim}
ChangeMassMin rho0 0.7
\end{verbatim}
\item Highest generated mass
\begin{verbatim}
ChangeMassMax rho0 0.9
\end{verbatim}
\item Presence of the birth momentum factor and form factor
(${p_P}^{L_{G \to P P_1}}$ and corresponding form factor)
\begin{verbatim}
IncludeBirthFactor rho0 no
\end{verbatim}
\item Presence of the decay momenum factor and form factor
(${p_D}^{L_{P \to D_1 D_2}}$ and corresponding form factor)
\begin{verbatim}
IncludeDecayFactor rho0 no
\end{verbatim}
\item Blatt-Weisskopf factor (in $GeV^{-1}$)
\begin{verbatim}
BlattWeisskopf rho 3.0
\end{verbatim}
\item Lineshape used.  There are a few alternative
lineshapes available:
\begin{verbatim}
LSNONRELBW rho0
LSFLAT rho0
\end{verbatim}
Note that LSFLAT should be used together with the ChangeMassMin
and ChangeMassMax options.
\item Mass and width
\begin{verbatim}
Particle rho0 0.8 0.2
\end{verbatim}
\end{itemize}

Some of these are illustrated in Figures~\ref{fig:nom}
to~\ref{fig:flat} for the $\rho$ mass in the decay $B \to \rho \pi$ and $\rho
\to \pi \pi$.

\begin{figure}
\epsfig{figure=nominal.eps,width=0.9\linewidth}
\caption{The nominal $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$.}
\label{fig:nom}
\end{figure}

\begin{figure}
\epsfig{figure=masswid.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$ having included {\tt Particle rho0 0.8 0.2}
in the user decay table.}
\label{fig:masswid}
\end{figure}

\begin{figure}
\epsfig{figure=min7.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$ having included {\tt ChangeMassMin rho0 0.7}
in the user decay table.}
\label{fig:min}
\end{figure}

\begin{figure}
\epsfig{figure=max9.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$ having included {\tt ChangeMassMax 0.9}
in the user decay table.}
\label{fig:max}
\end{figure}

\begin{figure}
\epsfig{figure=nodecayp.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$, $\rho \to \pi \pi$ using {\tt IncludeDecayFactor rho0 no}
in the user decay table.}
\label{fig:decayfactor}
\end{figure}

\begin{figure}
\epsfig{figure=nobirthp.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$, $\rho \to \pi \pi$ using {\tt IncludeBirthFactor rho0 no}
in the user decay table.}
\label{fig:birthfactor}
\end{figure}

\begin{figure}
\epsfig{figure=nonrel.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$ having included {\tt LSNONRELBW rho0}
in the user decay table.}
\label{fig:massnonrel}
\end{figure}

\begin{figure}
\epsfig{figure=flat.eps,width=0.9\linewidth}
\caption{The $\rho$ mass distribution in
$B \to \rho \pi$ and $\rho \to \pi \pi$ having included {\tt LSFLAT rho}
in the user decay table.}
\label{fig:flat}
\end{figure}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  basic formatting macros:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  sizing and bars

\def\st{\scriptstyle}
\def\sst{\scriptscriptstyle}

\def\overbar#1{\overline{#1}}
\let\littlebar=\bar
\let\bar=\overbar

\def\subscr#1{{\mbox{\scriptsize #1}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  text-mode macros:

\def\etal{{\it et al.}}
\def\ie{{\it i.e.}}
\def\eg{{\it e.g.}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  expectation values:

\def\VEV#1{\left\langle{ #1} \right\rangle}
\def\bra#1{\left\langle{ #1} \right|}
\def\ket#1{\left| {#1} \right\rangle}
\def\vev#1{\langle #1 \rangle}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% relation symbols

\def\lsim{\mathrel{\raise.3ex\hbox{$<$\kern-.75em\lower1ex\hbox{$\sim$}}}}
\def\gsim{\mathrel{\raise.3ex\hbox{$>$\kern-.75em\lower1ex\hbox{$\sim$}}}}

\def\Im{{\rm Im}}
\def\Re{{\rm Re}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  caligraphic letters (for matrix elements, luminosity, etc.)

\def\D{{\cal D}}
\def\L{{\cal L}}
\def\M{{\cal M}}
\def\O{{\cal O}}
\def\W{{\cal W}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  matrix operations and fractions:

\def\One{{\bf 1}}
\def\hc{{\mbox{\rm h.c.}}}
\def\tr{{\mbox{\rm tr}}}
\def\half{\frac{1}{2}}
\def\thalf{\frac{3}{2}}
\def\third{\frac{1}{3}}
\def\tthird{\frac{2}{3}}

\def\del{\partial}
\def\Dslash{\not{\hbox{\kern-4pt $D$}}}
\def\dslash{\not{\hbox{\kern-2pt $\del$}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  high-energy physics terminology:

\def\Pl{{\mbox{\scriptsize Pl}}}
\def\eff{{\mbox{\scriptsize eff}}}
\def\CM{{\mbox{\scriptsize CM}}}
\def\GUT{{\mbox{\scriptsize GUT}}}
\def\BR{\mbox{\rm BR}}
\def\ee{e^+e^-}
\def\sstw{\sin^2\theta_w}
\def\cstw{\cos^2\theta_w}
\def\mz{m_Z}
\def\gz{\Gamma_Z}
\def\mw{m_W}
\def\mt{m_t}
\def\gt{\Gamma_t}
\def\mh{m_h}
\def\gmu{G_\mu}
\def\GF{G_F}
\def\alphas{\alpha_s}
\def\msb{{\bar{\scriptsize M \kern -1pt S}}}
\def\lmsb{\Lambda_{\msb}}
\def\drb{{\bar{\scriptsize D \kern -1pt R}}}
\def\ELER{e^-_Le^+_R}
\def\EREL{e^-_Re^+_L}
\def\ELEL{e^-_Le^+_L}
\def\ERER{e^-_Re^+_R}
\def\eps{\epsilon}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% spinor products

\def\spa#1#2{\langle #1 #2 \rangle}
\def\spb#1#2{[ #1 #2 ]}
\def\apb#1#2#3{\langle #1 #2 #3 ]}
\def\bpa#1#2#3{[ #1 #2 #3 \rangle}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%  supersymmetry:

\def\ch#1{\widetilde\chi^+_{#1}}
\def\chm#1{\widetilde\chi^-_{#1}}
\def\neu#1{\widetilde\chi^0_{#1}}
\def\s#1{\widetilde{#1}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5

\makeatletter
\def\section{\@startsection{section}{0}{\z@}{5.5ex plus .5ex minus
 1.5ex}{2.3ex plus .2ex}{\large\bf}}
\def\subsection{\@startsection{subsection}{1}{\z@}{3.5ex plus .5ex minus
 1.5ex}{1.3ex plus .2ex}{\normalsize\bf}}
\def\subsubsection{\@startsection{subsubsection}{2}{\z@}{-3.5ex plus
-1ex minus  -.2ex}{2.3ex plus .2ex}{\normalsize\sl}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% small size table and figure captions %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand{\@makecaption}[2]{%
   \vskip 10pt
   \setbox\@tempboxa\hbox{\small #1: #2}
   \ifdim \wd\@tempboxa >\hsize     % IF longer than one line:
       \small #1: #2\par          %   THEN set as ordinary paragraph.
     \else                        %   ELSE  center.
       \hbox to\hsize{\hfil\box\@tempboxa\hfil}
   \fi}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% macros to collapse citation numbers to ranges %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \citenum emits the plain citation number without ornament
% \citea puts it's argument into the ornamentation for citations
% thus \cite{foo} is equivalent to \citea{\citenum{foo}}
 \def\citenum#1{{\def\@cite##1##2{##1}\cite{#1}}}
%\def\citea#1{\@cite{#1}{}}

% Collapse citation numbers to ranges.  Non-numeric and undefined labels
% are handled.  No sorting is done.  E.g., 1,3,2,3,4,5,foo,1,2,3,?,4,5
% gives 1,3,2-5,foo,1-3,?,4,5
\newcount\@tempcntc
\def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi
  \@tempcnta\z@\@tempcntb\m@ne\def\@citea{}\@cite{\@for\@citeb:=#2\do
    {\@ifundefined
       {b@\@citeb}{\@citeo\@tempcntb\m@ne\@citea\def\@citea{,}{\bf ?}\@warning
       {Citation `\@citeb' on page \thepage \space undefined}}%
    {\setbox\z@\hbox{\global\@tempcntc0\csname b@\@citeb\endcsname\relax}%
     \ifnum\@tempcntc=\z@ \@citeo\@tempcntb\m@ne
       \@citea\def\@citea{,}\hbox{\csname b@\@citeb\endcsname}%
     \else
      \advance\@tempcntb\@ne
      \ifnum\@tempcntb=\@tempcntc
      \else\advance\@tempcntb\m@ne\@citeo
      \@tempcnta\@tempcntc\@tempcntb\@tempcntc\fi\fi}}\@citeo}{#1}}
\def\@citeo{\ifnum\@tempcnta>\@tempcntb\else\@citea\def\@citea{,}%
  \ifnum\@tempcnta=\@tempcntb\the\@tempcnta\else
  {\advance\@tempcnta\@ne\ifnum\@tempcnta=\@tempcntb \else\def\@citea{--}\fi
    \advance\@tempcnta\m@ne\the\@tempcnta\@citea\the\@tempcntb}\fi\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatother


%!TEX root = main.tex

\section{Conclusions}
\label{sec:conclusions}
In this paper, we focused on the problem of
maximizing a driver's individual earnings on ride-hailing platforms like Uber or Lyft.
Our work confirms the power of strategic driving behavior %, by simulating
%key points in the strategy space optimized against
using data-driven projections
of ridership in the NYC area.  Our first key takeaway is that a naive driver,
armed with no data, and driving a 9-5 random walk schedule, is leaving
roughly a 50\% pay raise on the table by not driving more strategically.
%in terms of time and location.
In contrast, a data-savvy driver armed with
good historical data can build a forecast and optimal contingency driving plans
with relatively little computational overhead using
our dynamic programming algorithms, that have provable resilience to input
uncertainty.  Our experimental results yield insights into the
structure of highly-optimized schedules, including relatively frequent relocation,
working at specific peak periods, and taking advantage of
surges when the time is ripe.

An obvious limitation of our work is that it is tailored to the setting when the
methods are employed by self-interested individuals.  If a
significant percentage of the labor supply employs sophisticated optimization methods
for driving, one would need to consider different strategies that achieve equilibria
or other global objectives. %, as opposed to the simple
%greedy approach we invoke here.
Indeed, in the long run, as drivers for ride-hailing
platforms like Uber and Lyft are put out of work by fleets of autonomous vehicles,
the formulation and solution of new sets of optimization problems along those lines
are likely to become relevant as well.


\subsection{The Lucas islands model}


\section{Feature detection and description}

\ifCpp
\cvCppFunc{FAST}
Detects corners using FAST algorithm by E. Rosten (''Machine learning for high-speed corner detection'', 2006).
\fi

\cvdefCpp{
void FAST( const Mat\& image, vector<KeyPoint>\& keypoints,
           int threshold, bool nonmaxSupression=true );

}

\begin{description}
\cvarg{image}{The image. Keypoints (corners) will be detected on this.}
\cvarg{keypoints}{Keypoints detected on the image.}
\cvarg{threshold}{Threshold on difference between intensity of center pixel and
	pixels on circle around this pixel. See description of the algorithm.}
\cvarg{nonmaxSupression}{If it is true then non-maximum supression will be applied to detected corners (keypoints). }
\end{description}

\ifCPy
\ifPy
\cvclass{CvSURFPoint}
A SURF keypoint, represented as a tuple \texttt{((x, y), laplacian, size, dir, hessian)}.

\begin{description}
\cvarg{x}{x-coordinate of the feature within the image}
\cvarg{y}{y-coordinate of the feature within the image}
\cvarg{laplacian}{-1, 0 or +1. sign of the laplacian at the point.  Can be used to speedup feature comparison since features with laplacians of different signs can not match}
\cvarg{size}{size of the feature}
\cvarg{dir}{orientation of the feature: 0..360 degrees}
\cvarg{hessian}{value of the hessian (can be used to approximately estimate the feature strengths; see also params.hessianThreshold)}
\end{description}
\fi

\cvCPyFunc{ExtractSURF}
Extracts Speeded Up Robust Features from an image.

\cvdefC{
void cvExtractSURF( \par const CvArr* image,\par const CvArr* mask,\par CvSeq** keypoints,\par CvSeq** descriptors,\par CvMemStorage* storage,\par CvSURFParams params );
}
\cvdefPy{ExtractSURF(image,mask,storage,params)-> (keypoints,descriptors)}

\begin{description}
\cvarg{image}{The input 8-bit grayscale image}
\cvarg{mask}{The optional input 8-bit mask. The features are only found in the areas that contain more than 50\% of non-zero mask pixels}
\ifC
\cvarg{keypoints}{The output parameter; double pointer to the sequence of keypoints. The sequence of CvSURFPoint structures is as follows:}
\begin{lstlisting}
 typedef struct CvSURFPoint
 {
    CvPoint2D32f pt; // position of the feature within the image
    int laplacian;   // -1, 0 or +1. sign of the laplacian at the point.
                     // can be used to speedup feature comparison
                     // (normally features with laplacians of different
             // signs can not match)
    int size;        // size of the feature
    float dir;       // orientation of the feature: 0..360 degrees
    float hessian;   // value of the hessian (can be used to
             // approximately estimate the feature strengths;
                     // see also params.hessianThreshold)
 }
 CvSURFPoint;
\end{lstlisting}
\cvarg{descriptors}{The optional output parameter; double pointer to the sequence of descriptors. Depending on the params.extended value, each element of the sequence will be either a 64-element or a 128-element floating-point (\texttt{CV\_32F}) vector. If the parameter is NULL, the descriptors are not computed}
\else
\cvarg{keypoints}{sequence of keypoints.}
\cvarg{descriptors}{sequence of descriptors.  Each SURF descriptor is a list of floats, of length 64 or 128.}
\fi
\cvarg{storage}{Memory storage where keypoints and descriptors will be stored}
\ifC
\cvarg{params}{Various algorithm parameters put to the structure CvSURFParams:}
\begin{lstlisting}
 typedef struct CvSURFParams
 {
    int extended; // 0 means basic descriptors (64 elements each),
                  // 1 means extended descriptors (128 elements each)
    double hessianThreshold; // only features with keypoint.hessian
          // larger than that are extracted.
                  // good default value is ~300-500 (can depend on the
          // average local contrast and sharpness of the image).
                  // user can further filter out some features based on
          // their hessian values and other characteristics.
    int nOctaves; // the number of octaves to be used for extraction.
                  // With each next octave the feature size is doubled
          // (3 by default)
    int nOctaveLayers; // The number of layers within each octave
          // (4 by default)
 }
 CvSURFParams;

 CvSURFParams cvSURFParams(double hessianThreshold, int extended=0);
          // returns default parameters
\end{lstlisting}
\else
\cvarg{params}{Various algorithm parameters in a tuple \texttt{(extended, hessianThreshold, nOctaves, nOctaveLayers)}:
\begin{description}
\cvarg{extended}{0 means basic descriptors (64 elements each), 1 means extended descriptors (128 elements each)}
\cvarg{hessianThreshold}{only features with hessian larger than that are extracted.  good default value is ~300-500 (can depend on the average local contrast and sharpness of the image).  user can further filter out some features based on their hessian values and other characteristics.}
\cvarg{nOctaves}{the number of octaves to be used for extraction.  With each next octave the feature size is doubled (3 by default)}
\cvarg{nOctaveLayers}{The number of layers within each octave (4 by default)}
\end{description}}
\fi
\end{description}

The function cvExtractSURF finds robust features in the image, as
described in \cite{Bay06}. For each feature it returns its location, size,
orientation and optionally the descriptor, basic or extended. The function
can be used for object tracking and localization, image stitching etc.

\ifC
See the
\texttt{find\_obj.cpp} demo in OpenCV samples directory.
\else
To extract strong SURF features from an image

\begin{lstlisting}
>>> import cv
>>> im = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
>>> (keypoints, descriptors) = cv.ExtractSURF(im, None, cv.CreateMemStorage(), (0, 30000, 3, 1))
>>> print len(keypoints), len(descriptors)
6 6
>>> for ((x, y), laplacian, size, dir, hessian) in keypoints:
...     print "x=\%d y=\%d laplacian=\%d size=\%d dir=\%f hessian=\%f" \% (x, y, laplacian, size, dir, hessian)
x=30 y=27 laplacian=-1 size=31 dir=69.778503 hessian=36979.789062
x=296 y=197 laplacian=1 size=33 dir=111.081039 hessian=31514.349609
x=296 y=266 laplacian=1 size=32 dir=107.092300 hessian=31477.908203
x=254 y=284 laplacian=1 size=31 dir=279.137360 hessian=34169.800781
x=498 y=525 laplacian=-1 size=33 dir=278.006592 hessian=31002.759766
x=777 y=281 laplacian=1 size=70 dir=167.940964 hessian=35538.363281
\end{lstlisting}

\fi

\cvCPyFunc{GetStarKeypoints}
Retrieves keypoints using the StarDetector algorithm.

\cvdefC{
CvSeq* cvGetStarKeypoints( \par const CvArr* image,\par CvMemStorage* storage,\par CvStarDetectorParams params=cvStarDetectorParams() );
}
\cvdefPy{GetStarKeypoints(image,storage,params)-> keypoints}

\begin{description}
\cvarg{image}{The input 8-bit grayscale image}
\cvarg{storage}{Memory storage where the keypoints will be stored}
\ifC
\cvarg{params}{Various algorithm parameters given to the structure CvStarDetectorParams:}
\begin{lstlisting}
 typedef struct CvStarDetectorParams
 {
    int maxSize; // maximal size of the features detected. The following
                 // values of the parameter are supported:
                 // 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
    int responseThreshold; // threshold for the approximatd laplacian,
                           // used to eliminate weak features
    int lineThresholdProjected; // another threshold for laplacian to
                // eliminate edges
    int lineThresholdBinarized; // another threshold for the feature
                // scale to eliminate edges
    int suppressNonmaxSize; // linear size of a pixel neighborhood
                // for non-maxima suppression
 }
 CvStarDetectorParams;
\end{lstlisting}
\else
\cvarg{params}{Various algorithm parameters in a tuple \texttt{(maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize)}:
\begin{description}
\cvarg{maxSize}{maximal size of the features detected. The following values of the parameter are supported: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128}
\cvarg{responseThreshold}{threshold for the approximatd laplacian, used to eliminate weak features}
\cvarg{lineThresholdProjected}{another threshold for laplacian to eliminate edges}
\cvarg{lineThresholdBinarized}{another threshold for the feature scale to eliminate edges}
\cvarg{suppressNonmaxSize}{linear size of a pixel neighborhood for non-maxima suppression}
\end{description}
}
\fi
\end{description}

The function GetStarKeypoints extracts keypoints that are local
scale-space extremas. The scale-space is constructed by computing
approximate values of laplacians with different sigma's at each
pixel. Instead of using pyramids, a popular approach to save computing
time, all of the laplacians are computed at each pixel of the original
high-resolution image. But each approximate laplacian value is computed
in O(1) time regardless of the sigma, thanks to the use of integral
images. The algorithm is based on the paper
Agrawal08
, but instead
of a square, hexagon or octagon it uses an 8-end star shape, hence the name,
consisting of overlapping upright and tilted squares.

\ifC
Each computed feature is represented by the following structure:

\begin{lstlisting}
typedef struct CvStarKeypoint
{
    CvPoint pt; // coordinates of the feature
    int size; // feature size, see CvStarDetectorParams::maxSize
    float response; // the approximated laplacian value at that point.
}
CvStarKeypoint;

inline CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response);
\end{lstlisting}
\else
Each keypoint is represented by a tuple \texttt{((x, y), size, response)}:
\begin{description}
\cvarg{x, y}{Screen coordinates of the keypoint}
\cvarg{size}{feature size, up to \texttt{maxSize}}
\cvarg{response}{approximated laplacian value for the keypoint}
\end{description}
\fi

\ifC
Below is the small usage sample:

\begin{lstlisting}
#include "cv.h"
#include "highgui.h"

int main(int argc, char** argv)
{
    const char* filename = argc > 1 ? argv[1] : "lena.jpg";
    IplImage* img = cvLoadImage( filename, 0 ), *cimg;
    CvMemStorage* storage = cvCreateMemStorage(0);
    CvSeq* keypoints = 0;
    int i;

    if( !img )
        return 0;
    cvNamedWindow( "image", 1 );
    cvShowImage( "image", img );
    cvNamedWindow( "features", 1 );
    cimg = cvCreateImage( cvGetSize(img), 8, 3 );
    cvCvtColor( img, cimg, CV_GRAY2BGR );

    keypoints = cvGetStarKeypoints( img, storage, cvStarDetectorParams(45) );

    for( i = 0; i < (keypoints ? keypoints->total : 0); i++ )
    {
        CvStarKeypoint kpt = *(CvStarKeypoint*)cvGetSeqElem(keypoints, i);
        int r = kpt.size/2;
        cvCircle( cimg, kpt.pt, r, CV_RGB(0,255,0));
        cvLine( cimg, cvPoint(kpt.pt.x + r, kpt.pt.y + r),
            cvPoint(kpt.pt.x - r, kpt.pt.y - r), CV_RGB(0,255,0));
        cvLine( cimg, cvPoint(kpt.pt.x - r, kpt.pt.y + r),
            cvPoint(kpt.pt.x + r, kpt.pt.y - r), CV_RGB(0,255,0));
    }
    cvShowImage( "features", cimg );
    cvWaitKey();
}
\end{lstlisting}
\fi

\fi
\ifCpp

\cvclass{MSER}
Maximally-Stable Extremal Region Extractor

\begin{lstlisting}
class MSER : public CvMSERParams
{
public:
    // default constructor
    MSER();
    // constructor that initializes all the algorithm parameters
    MSER( int _delta, int _min_area, int _max_area,
          float _max_variation, float _min_diversity,
          int _max_evolution, double _area_threshold,
          double _min_margin, int _edge_blur_size );
    // runs the extractor on the specified image; returns the MSERs,
    // each encoded as a contour (vector<Point>, see findContours)
    // the optional mask marks the area where MSERs are searched for
    void operator()( const Mat& image, vector<vector<Point> >& msers, const Mat& mask ) const;
};
\end{lstlisting}

The class encapsulates all the parameters of MSER (see \url{http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions}) extraction algorithm.

\cvclass{StarDetector}
Implements Star keypoint detector

\begin{lstlisting}
class StarDetector : CvStarDetectorParams
{
public:
    // default constructor
    StarDetector();
    // the full constructor initialized all the algorithm parameters:
    // maxSize - maximum size of the features. The following
    //      values of the parameter are supported:
    //      4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
    // responseThreshold - threshold for the approximated laplacian,
    //      used to eliminate weak features. The larger it is,
    //      the less features will be retrieved
    // lineThresholdProjected - another threshold for the laplacian to
    //      eliminate edges
    // lineThresholdBinarized - another threshold for the feature
    //      size to eliminate edges.
    // The larger the 2 threshold, the more points you get.
    StarDetector(int maxSize, int responseThreshold,
                 int lineThresholdProjected,
                 int lineThresholdBinarized,
                 int suppressNonmaxSize);

    // finds keypoints in an image
    void operator()(const Mat& image, vector<KeyPoint>& keypoints) const;
};
\end{lstlisting}

The class implements a modified version of CenSurE keypoint detector described in
\cite{Agrawal08}

\cvclass{SIFT}
Class for extracting keypoints and computing descriptors using approach named Scale Invariant Feature Transform (SIFT).

\begin{lstlisting}
class CV_EXPORTS SIFT
{
public:
    struct CommonParams
    {
        static const int DEFAULT_NOCTAVES = 4;
        static const int DEFAULT_NOCTAVE_LAYERS = 3;
        static const int DEFAULT_FIRST_OCTAVE = -1;
        enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };

        CommonParams();
        CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave,
					  int _angleMode );
        int nOctaves, nOctaveLayers, firstOctave;
        int angleMode;
    };

    struct DetectorParams
    {
        static double GET_DEFAULT_THRESHOLD()
          { return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
        static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }

        DetectorParams();
        DetectorParams( double _threshold, double _edgeThreshold );
        double threshold, edgeThreshold;
    };

    struct DescriptorParams
    {
        static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
        static const bool DEFAULT_IS_NORMALIZE = true;
        static const int DESCRIPTOR_SIZE = 128;

        DescriptorParams();
        DescriptorParams( double _magnification, bool _isNormalize,
						  bool _recalculateAngles );
        double magnification;
        bool isNormalize;
        bool recalculateAngles;
    };

    SIFT();
    //! sift-detector constructor
    SIFT( double _threshold, double _edgeThreshold,
          int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
          int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
          int _angleMode=CommonParams::FIRST_ANGLE );
    //! sift-descriptor constructor
    SIFT( double _magnification, bool _isNormalize=true,
          bool _recalculateAngles = true,
          int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
          int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
          int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
          int _angleMode=CommonParams::FIRST_ANGLE );
    SIFT( const CommonParams& _commParams,
          const DetectorParams& _detectorParams = DetectorParams(),
          const DescriptorParams& _descriptorParams = DescriptorParams() );

    //! returns the descriptor size in floats (128)
    int descriptorSize() const { return DescriptorParams::DESCRIPTOR_SIZE; }
    //! finds the keypoints using SIFT algorithm
    void operator()(const Mat& img, const Mat& mask,
                    vector<KeyPoint>& keypoints) const;
    //! finds the keypoints and computes descriptors for them using SIFT algorithm.
    //! Optionally it can compute descriptors for the user-provided keypoints
    void operator()(const Mat& img, const Mat& mask,
                    vector<KeyPoint>& keypoints,
                    Mat& descriptors,
                    bool useProvidedKeypoints=false) const;

    CommonParams getCommonParams () const { return commParams; }
    DetectorParams getDetectorParams () const { return detectorParams; }
    DescriptorParams getDescriptorParams () const { return descriptorParams; }
protected:
    ...
};
\end{lstlisting}

\cvclass{SURF}
Class for extracting Speeded Up Robust Features from an image.

\begin{lstlisting}
class SURF : public CvSURFParams
{
public:
    // default constructor
    SURF();
    // constructor that initializes all the algorithm parameters
    SURF(double _hessianThreshold, int _nOctaves=4,
         int _nOctaveLayers=2, bool _extended=false);
    // returns the number of elements in each descriptor (64 or 128)
    int descriptorSize() const;
    // detects keypoints using fast multi-scale Hessian detector
    void operator()(const Mat& img, const Mat& mask,
                    vector<KeyPoint>& keypoints) const;
    // detects keypoints and computes the SURF descriptors for them;
    // output vector "descriptors" stores elements of descriptors and has size
    // equal descriptorSize()*keypoints.size() as each descriptor is
    // descriptorSize() elements of this vector.
    void operator()(const Mat& img, const Mat& mask,
                    vector<KeyPoint>& keypoints,
                    vector<float>& descriptors,
                    bool useProvidedKeypoints=false) const;
};
\end{lstlisting}

The class \texttt{SURF} implements Speeded Up Robust Features descriptor \cite{Bay06}.
There is fast multi-scale Hessian keypoint detector that can be used to find the keypoints
(which is the default option), but the descriptors can be also computed for the user-specified keypoints.
The function can be used for object tracking and localization, image stitching etc. See the
\texttt{find\_obj.cpp} demo in OpenCV samples directory.

\cvclass{RandomizedTree}
The class contains base structure for \texttt{RTreeClassifier}

\begin{lstlisting}
class CV_EXPORTS RandomizedTree
{
public:
	friend class RTreeClassifier;

	RandomizedTree();
	~RandomizedTree();

	void train(std::vector<BaseKeypoint> const& base_set,
		 cv::RNG &rng, int depth, int views,
		 size_t reduced_num_dim, int num_quant_bits);
	void train(std::vector<BaseKeypoint> const& base_set,
		 cv::RNG &rng, PatchGenerator &make_patch, int depth,
		 int views, size_t reduced_num_dim, int num_quant_bits);

	// following two funcs are EXPERIMENTAL
	//(do not use unless you know exactly what you do)
	static void quantizeVector(float *vec, int dim, int N, float bnds[2],
		 int clamp_mode=0);
	static void quantizeVector(float *src, int dim, int N, float bnds[2],
		 uchar *dst);

	// patch_data must be a 32x32 array (no row padding)
	float* getPosterior(uchar* patch_data);
	const float* getPosterior(uchar* patch_data) const;
	uchar* getPosterior2(uchar* patch_data);

	void read(const char* file_name, int num_quant_bits);
	void read(std::istream &is, int num_quant_bits);
	void write(const char* file_name) const;
	void write(std::ostream &os) const;

	int classes() { return classes_; }
	int depth() { return depth_; }

	void discardFloatPosteriors() { freePosteriors(1); }

	inline void applyQuantization(int num_quant_bits)
		 { makePosteriors2(num_quant_bits); }

private:
	int classes_;
	int depth_;
	int num_leaves_;
	std::vector<RTreeNode> nodes_;
	float **posteriors_;        // 16-bytes aligned posteriors
	uchar **posteriors2_;     // 16-bytes aligned posteriors
	std::vector<int> leaf_counts_;

	void createNodes(int num_nodes, cv::RNG &rng);
	void allocPosteriorsAligned(int num_leaves, int num_classes);
	void freePosteriors(int which);
		 // which: 1=posteriors_, 2=posteriors2_, 3=both
	void init(int classes, int depth, cv::RNG &rng);
	void addExample(int class_id, uchar* patch_data);
	void finalize(size_t reduced_num_dim, int num_quant_bits);
	int getIndex(uchar* patch_data) const;
	inline float* getPosteriorByIndex(int index);
	inline uchar* getPosteriorByIndex2(int index);
	inline const float* getPosteriorByIndex(int index) const;
	void convertPosteriorsToChar();
	void makePosteriors2(int num_quant_bits);
	void compressLeaves(size_t reduced_num_dim);
	void estimateQuantPercForPosteriors(float perc[2]);
};
\end{lstlisting}

\cvCppFunc{RandomizedTree::train}
Trains a randomized tree using input set of keypoints

\cvdefCpp{
void train(std::vector<BaseKeypoint> const\& base\_set, cv::RNG \&rng,
			PatchGenerator \&make\_patch, int depth, int views, size\_t reduced\_num\_dim,
			int num\_quant\_bits);
			}
\cvdefCpp{
void train(std::vector<BaseKeypoint> const\& base\_set, cv::RNG \&rng,
			PatchGenerator \&make\_patch, int depth, int views, size\_t reduced\_num\_dim,
			int num\_quant\_bits);
			}
\begin{description}
\cvarg{base\_set} {Vector of \texttt{BaseKeypoint} type. Contains keypoints from the image are used for training}
\cvarg{rng} {Random numbers generator is used for training}
\cvarg{make\_patch} {Patch generator is used for training}
\cvarg{depth} {Maximum tree depth}
%\cvarg{views} {}
\cvarg{reduced\_num\_dim} {Number of dimensions are used in compressed signature}
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
\end{description}

\cvCppFunc{RandomizedTree::read}
Reads pre-saved randomized tree from file or stream
\cvdefCpp{read(const char* file\_name, int num\_quant\_bits)}
\cvdefCpp{read(std::istream \&is, int num\_quant\_bits)}
\begin{description}
\cvarg{file\_name}{Filename of file contains randomized tree data}
\cvarg{is}{Input stream associated with file contains randomized tree data}
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
\end{description}

\cvCppFunc{RandomizedTree::write}
Writes current randomized tree to a file or stream
\cvdefCpp{void write(const char* file\_name) const;}
\cvdefCpp{void write(std::ostream \&os) const;}
\begin{description}
\cvarg{file\_name}{Filename of file where randomized tree data will be stored}
\cvarg{is}{Output stream associated with file where randomized tree data will be stored}
\end{description}

\cvCppFunc{RandomizedTree::applyQuantization}
Applies quantization to the current randomized tree
\cvdefCpp{void applyQuantization(int num\_quant\_bits)}
\begin{description}
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
\end{description}

\cvclass{RTreeNode}
The class contains base structure for \texttt{RandomizedTree}

\begin{lstlisting}
struct RTreeNode
{
	short offset1, offset2;

	RTreeNode() {}

	RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
		: offset1(y1*PATCH_SIZE + x1),
		offset2(y2*PATCH_SIZE + x2)
	{}

	//! Left child on 0, right child on 1
	inline bool operator() (uchar* patch_data) const
	{
		return patch_data[offset1] > patch_data[offset2];
	}
};
\end{lstlisting}

\cvclass{RTreeClassifier}
The class contains \texttt{RTreeClassifier}. It represents calonder descriptor which was originally introduced by Michael Calonder

\begin{lstlisting}
class CV_EXPORTS RTreeClassifier
{
public:
	static const int DEFAULT_TREES = 48;
	static const size_t DEFAULT_NUM_QUANT_BITS = 4;

	RTreeClassifier();

	void train(std::vector<BaseKeypoint> const& base_set,
		cv::RNG &rng,
		int num_trees = RTreeClassifier::DEFAULT_TREES,
		int depth = DEFAULT_DEPTH,
		int views = DEFAULT_VIEWS,
		size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
		int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
			 bool print_status = true);
	void train(std::vector<BaseKeypoint> const& base_set,
		cv::RNG &rng,
		PatchGenerator &make_patch,
		int num_trees = RTreeClassifier::DEFAULT_TREES,
		int depth = DEFAULT_DEPTH,
		int views = DEFAULT_VIEWS,
		size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
		int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
		 bool print_status = true);

	// sig must point to a memory block of at least
	//classes()*sizeof(float|uchar) bytes
	void getSignature(IplImage *patch, uchar *sig);
	void getSignature(IplImage *patch, float *sig);
	void getSparseSignature(IplImage *patch, float *sig,
		 float thresh);

	static int countNonZeroElements(float *vec, int n, double tol=1e-10);
	static inline void safeSignatureAlloc(uchar **sig, int num_sig=1,
			int sig_len=176);
	static inline uchar* safeSignatureAlloc(int num_sig=1,
			 int sig_len=176);

	inline int classes() { return classes_; }
	inline int original_num_classes()
		 { return original_num_classes_; }

	void setQuantization(int num_quant_bits);
	void discardFloatPosteriors();

	void read(const char* file_name);
	void read(std::istream &is);
	void write(const char* file_name) const;
	void write(std::ostream &os) const;

	std::vector<RandomizedTree> trees_;

private:
	int classes_;
	int num_quant_bits_;
	uchar **posteriors_;
	ushort *ptemp_;
	int original_num_classes_;
	bool keep_floats_;
};
\end{lstlisting}

\cvCppFunc{RTreeClassifier::train}
Trains a randomized tree classificator using input set of keypoints
\cvdefCpp{
		void train(std::vector<BaseKeypoint> const\& base\_set,
			cv::RNG \&rng,
			int num\_trees = RTreeClassifier::DEFAULT\_TREES,
			int depth = DEFAULT\_DEPTH,
			int views = DEFAULT\_VIEWS,
			size\_t reduced\_num\_dim = DEFAULT\_REDUCED\_NUM\_DIM,
			int num\_quant\_bits = DEFAULT\_NUM\_QUANT\_BITS, bool print\_status = true);
			}
\cvdefCpp{
		void train(std::vector<BaseKeypoint> const\& base\_set,
			cv::RNG \&rng,
			PatchGenerator \&make\_patch,
			int num\_trees = RTreeClassifier::DEFAULT\_TREES,
			int depth = DEFAULT\_DEPTH,
			int views = DEFAULT\_VIEWS,
			size\_t reduced\_num\_dim = DEFAULT\_REDUCED\_NUM\_DIM,
			int num\_quant\_bits = DEFAULT\_NUM\_QUANT\_BITS, bool print\_status = true);
}
\begin{description}
\cvarg{base\_set} {Vector of \texttt{BaseKeypoint} type. Contains keypoints from the image are used for training}
\cvarg{rng} {Random numbers generator is used for training}
\cvarg{make\_patch} {Patch generator is used for training}
\cvarg{num\_trees} {Number of randomized trees used in RTreeClassificator}
\cvarg{depth} {Maximum tree depth}
%\cvarg{views} {}
\cvarg{reduced\_num\_dim} {Number of dimensions are used in compressed signature}
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
\cvarg{print\_status} {Print current status of training on the console}
\end{description}

\cvCppFunc{RTreeClassifier::getSignature}
Returns signature for image patch
\cvdefCpp{
void getSignature(IplImage *patch, uchar *sig)
}
\cvdefCpp{
void getSignature(IplImage *patch, float *sig)
}
\begin{description}
\cvarg{patch} {Image patch to calculate signature for}
\cvarg{sig} {Output signature (array dimension is \texttt{reduced\_num\_dim)}}
\end{description}

\cvCppFunc{RTreeClassifier::getSparseSignature}
The function is simular to \texttt{getSignature} but uses the threshold for removing all signature elements less than the threshold. So that the signature is compressed
\cvdefCpp{
	void getSparseSignature(IplImage *patch, float *sig,
		 float thresh);
}
\begin{description}
\cvarg{patch} {Image patch to calculate signature for}
\cvarg{sig} {Output signature (array dimension is \texttt{reduced\_num\_dim)}}
\cvarg{tresh} {The threshold that is used for compressing the signature}
\end{description}

\cvCppFunc{RTreeClassifier::countNonZeroElements}
The function returns the number of non-zero elements in the input array.
\cvdefCpp{
static int countNonZeroElements(float *vec, int n, double tol=1e-10);
}
\begin{description}
\cvarg{vec}{Input vector contains float elements}
\cvarg{n}{Input vector size}
\cvarg{tol} {The threshold used for elements counting. We take all elements are less than \texttt{tol} as zero elements}
\end{description}

\cvCppFunc{RTreeClassifier::read}
Reads pre-saved RTreeClassifier from file or stream
\cvdefCpp{read(const char* file\_name)}
\cvdefCpp{read(std::istream \&is)}
\begin{description}
\cvarg{file\_name}{Filename of file contains randomized tree data}
\cvarg{is}{Input stream associated with file contains randomized tree data}
\end{description}

\cvCppFunc{RTreeClassifier::write}
Writes current RTreeClassifier to a file or stream
\cvdefCpp{void write(const char* file\_name) const;}
\cvdefCpp{void write(std::ostream \&os) const;}
\begin{description}
\cvarg{file\_name}{Filename of file where randomized tree data will be stored}
\cvarg{is}{Output stream associated with file where randomized tree data will be stored}
\end{description}

\cvCppFunc{RTreeClassifier::setQuantization}
Applies quantization to the current randomized tree
\cvdefCpp{void setQuantization(int num\_quant\_bits)}
\begin{description}
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
\end{description}

Below there is an example of \texttt{RTreeClassifier} usage for feature matching. There are test and train images and we extract features from both with SURF. Output is $best\_corr$ and $best\_corr\_idx$ arrays which keep the best probabilities and corresponding features indexes for every train feature.
% ===== Example. Using RTreeClassifier for features matching =====
\begin{lstlisting}
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
CvSURFParams params = cvSURFParams(500, 1);
cvExtractSURF( test_image, 0, &imageKeypoints, &imageDescriptors,
		 storage, params );
cvExtractSURF( train_image, 0, &objectKeypoints, &objectDescriptors,
		 storage, params );

cv::RTreeClassifier detector;
int patch_width = cv::PATCH_SIZE;
iint patch_height = cv::PATCH_SIZE;
vector<cv::BaseKeypoint> base_set;
int i=0;
CvSURFPoint* point;
for (i=0;i<(n_points > 0 ? n_points : objectKeypoints->total);i++)
{
	point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,i);
	base_set.push_back(
		cv::BaseKeypoint(point->pt.x,point->pt.y,train_image));
}

	//Detector training
 cv::RNG rng( cvGetTickCount() );
cv::PatchGenerator gen(0,255,2,false,0.7,1.3,-CV_PI/3,CV_PI/3,
			-CV_PI/3,CV_PI/3);

printf("RTree Classifier training...\n");
detector.train(base_set,rng,gen,24,cv::DEFAULT_DEPTH,2000,
	(int)base_set.size(), detector.DEFAULT_NUM_QUANT_BITS);
printf("Done\n");

float* signature = new float[detector.original_num_classes()];
float* best_corr;
int* best_corr_idx;
if (imageKeypoints->total > 0)
{
	best_corr = new float[imageKeypoints->total];
	best_corr_idx = new int[imageKeypoints->total];
}

for(i=0; i < imageKeypoints->total; i++)
{
	point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,i);
	int part_idx = -1;
	float prob = 0.0f;

	CvRect roi = cvRect((int)(point->pt.x) - patch_width/2,
		(int)(point->pt.y) - patch_height/2,
		 patch_width, patch_height);
	cvSetImageROI(test_image, roi);
	roi = cvGetImageROI(test_image);
	if(roi.width != patch_width || roi.height != patch_height)
	{
		best_corr_idx[i] = part_idx;
		best_corr[i] = prob;
	}
	else
	{
		cvSetImageROI(test_image, roi);
		IplImage* roi_image =
			 cvCreateImage(cvSize(roi.width, roi.height),
			 test_image->depth, test_image->nChannels);
		cvCopy(test_image,roi_image);

		detector.getSignature(roi_image, signature);
		for (int j = 0; j< detector.original_num_classes();j++)
		{
			if (prob < signature[j])
			{
				part_idx = j;
				prob = signature[j];
			}
		}

		best_corr_idx[i] = part_idx;
		best_corr[i] = prob;

		if (roi_image)
			cvReleaseImage(&roi_image);
	}
	cvResetImageROI(test_image);
}

\end{lstlisting}
\fi


\section{Method}
\begin{figure}
	% \advance\leftskip-1cm
	\centering
	\includegraphics[width=1\columnwidth]{img/chapter4/pipeline.pdf}
	%  \vspace{-3em}
	\caption{The overall architecture of my proposed PCCD model. It contains three major modules mentioned in the right part of the figure. Each training instance is a mutual user triplet $\langle u_i,u_j,u_k \rangle$. Compared with the sparse graph, the main graph involves raw user community as part of model input.}

	\label{fig:c4_pipeline}
	%  \vspace{-1em}
\end{figure}
\subsection{Task Overview} \label{sc:to}

As aforementioned, conventional methods suffer from graph sparseness problem. In this study, I propose a Pairwise Cross-graph Community Detection (PCCD) model that particularly aims at detecting user pairwise community closeness in sparse graphs by involving cross-graph techniques.

Particularly, a well connected graph is called ``main graph" in this paper, corresponding to the targeted sparse graph. In general, as users may visit multiple cyber domains within a short time period, these mutual users co-occurred in both the main and sparse graph are taken as the bridge to connect the two graphs. Therefore, the relevant information from the main graph can be propagated to the sparse graph to support its user community detection.

Specifically, my proposed model (showed in Figure \ref{fig:c4_pipeline}) is trained on mutual user triplets to learn three types of pairwise community relationship including ``\textit{similar}'', ``\textit{closer}'' and ``\textit{farther}''. The goal of this study can be reformulated as the following pairwise learning task: Given a sparse graph $S$ and a main graph $M$ where $N^C$ denotes their mutual user collection, for a mutual user triplet $\langle u_i,u_j,u_k \rangle  \in N^C$ (\textbf{Model Input}),  I aim to predict the relationship of its pairwise community closeness in graph $S$ (\textbf{Model Output}). In this paper, ``\textit{similar}'' relationship means that $u_j$ and $u_k$ are either in the same community or different communities with $u_i$. ``\textit{closer}'' relationship means that $u_j$ and $u_i$ are in the same community, while $u_k$ and $u_i$ are in different communities. ``\textit{farther}'' relationship means that $u_j$ and $u_i$ are in different communities, while $u_k$ and $u_i$ are in the same community.

For a mutual user triplet, my proposed model detects communities firstly on separate graphs to obtain all user raw community representations (Section \ref{sc:rcr}). Their propagative representations are learned through a community-level and a node-level filter (Section \ref{sc:upr}). Both representations are jointly utilized for predicting user community affiliation in each graph via a Community Recurrent Unit (Section \ref{sc:cru}). In the end, I integrate the community affiliation distributions to identify the pairwise community relationship of the triplet (Section \ref{sc:pcd}). Particular training strategies are introduced in the end (Section \ref{sc:mt}).

Note that even though my model is only trained on mutual users, it is still functional to detect pairwise community closeness on those users solely appeared in either the main or sparse graph. Further experiments in Section \ref{sc:ua} will verify its effectiveness on different types of users.

\subsection{Raw Community Representation} \label{sc:rcr}

As the user behavior is enriched in the main graph $M$, detecting user communities in it would offer auxiliary community features to potentially enhance my model performance. Therefore, I decide to involve user communities in the main graph as a part of model input. The same information from the sparse graph is intentionally omitted because its sparse graph structure is not able to offer reliable community partition results.

Considering all possible community detection methods listed in Section \ref{sc:baseline}, Infomap is empirically selected to detect user communities in the main graph $M$. Infomap method simulates a random walker wandering on the graph for $m$ steps and indexes his random walk path via a two-level codebook. Its final goal aims to generate a community partition with the minimum random walk description length, which is calculated as follows:

\begin{equation}
\textit{$L(\pi)$} = \sum_{i}^{m}q_{\curvearrowright}^{i}H(\mathcal{Q})+\sum_{i=1}^{m} \textit{$p_{\circlearrowright}^{i}$}H(\textit{$\mathcal{P}^{i}$})
\end{equation}
where \textit{$L(\pi)$} is the description length for a random walker under current community partition $\pi$. $q_{\curvearrowright}^{i}$ and $p_{\circlearrowright}^{i}$ are the jumping rates between communities and within the $i_{th}$ community in each step. $H(\mathcal{Q})$ is the frequency-weighted average length of codewords in the global index codebook and $H(\mathcal{P}^{i})$ is frequency-weighted average length of codewords in the $i_{th}$ community codebook.

In the end, given a user $u_i$, I obtain its one-hot community representation $v_{c,i}^M$ in the main graph $M$, which is regarded as part of user representations for the model input.

\subsection{User Propagative Representation}\label{sc:upr}

\begin{figure}
	% \advance\leftskip-1cm
	\centering
	\includegraphics[width=\columnwidth]{img/chapter4/propagation.pdf}
	% 	\vspace{-1em}
	\caption{The two-level filter to support user propagative representation estimation in the main graph $M$. Sparse graph $S$ does not contain the community-level filter ( wrapped in the red rectangle).}
	\label{fig:propagation}
	% 	\vspace{-1.5em}
\end{figure}

To better convey the mutual user insights in both main and sparse graph, their representations are learned from both direct transformation and weighted information propagation. The optimization processes are similar in the main and sparse graph. In the beginning, a user $u_i$ can be represented as a multi-hot embedding $p_{i}^{M}$ in the main graph $M$ (left part in Figure \ref{fig:propagation}) and $p_{i}^{S}$ in the sparse graph $S$. Each dimension in the embedding refers to a unique object with which the user connects in the related graph.

The direct transformation from user multi-hot embedding learns a dense vector via one hidden layer so as to retrieve the compressed  information from user connected objects directly, which is calculated as follows:

\begin{equation}
v_{e,i}^{G} = {\rm tanh}(W_e^Gp_i^G + b_e^G)
\end{equation}

where $G \in \{M, S\}$ denotes either the main or the sparse graph. $W_e^G$ and $b_e^G$ denote the weight matrix and bias respectively. $v_{e,i}^{G}$ is the learned direct transformation representation for user $u_i$.

On the other hand, from information propagation perspective, each object carries information, which can be propagated to its connected users as a type of representation. However, as such information are noisy and heterogeneous, not all of them are equally important to users. Therefore, a filtering module is proposed to automatically select appropriate information to propagate from both community level and node level.  The overall flow of the filtering module is illustrated in Figure \ref{fig:propagation}.

\textbf{Community-Level Filter:} As the raw detected communities in the sparse graph is not reliable because of graph sparseness, I only apply the community-level filter in the main graph $M$. According to the raw community partition $\pi$ calculated in Section \ref{sc:rcr}, each object node $n_i$ is assigned to a community $\pi(n_i)$. The community-level filter propagate object information in a coarser manner by considering its community importance weight $w_{\pi(n_i)}$. Throughout this filter, I aim to learn a weight vector $w$ where each dimension of $w$ denotes the importance score of a related community.

\textbf{Node-Level Filter:} Node-level filter assesses the propagated information with a fine resolution. In the main graph $M$ ( a user-object bipartite graph), I aim to learn object representations $H^M = \{h_1^M,...,h_n^M\}$ where $h_n^M$ denotes the $n_{th}$ object representation. Similarly, $H^S$ denotes the object representations in the sparse graph $S$. The weight of the $j_{th}$ object node decides the amount of its information propagating to its connected user nodes, which is calculated in an attentive means:

\begin{equation} \label{eq:np}
a_{j}^{G} = (u_p^{G})^{\intercal} {\rm tanh}(W^{G}_p h_{j}^{G} +b_p^{G})
\end{equation}

where $G \in\{M,S\}$ denotes either the main or the sparse graph. $u^{G}_p$ denotes the project vector in the related graph to calculate object attentive weights. $W_p^{G}$ and $b_p^{G}$ denote the corresponding weights and bias, respectively.

I combine the community-level and node-level weights together to quantify the information propagation in the main graph $M$. While only the node-level weights is considered in the sparse graph $S$. Normalized by the ${\rm softmax}(\cdot)$ function, the related representation of  user $u_i$ in both graphs are calculated as follows:
\begin{equation}\label{eq:pv}
\begin{aligned}
& v_{p,i}^{M} = \sum_{n_j \in \mathcal{N}^{M}(u_i)} {\rm softmax}(a_{j}^{M} w_{\pi(n_j)})  h_{j}^{M} \\
& v_{p,i}^{S} = \sum_{n_j \in \mathcal{N}^{S}(u_i)}{\rm softmax}(a_{j}^{S}) h_{j}^{S}
\end{aligned}
\end{equation}

Both $v_{p,i}^{M}$ and $v_{p,i}^{S}$ are the weighted sum of the neighbour object representations. $\mathcal{N}^{S}(n_i)$ and $\mathcal{N}^{M}(n_i)$ denote user connected objects in both graphs.

Finally, given a user $u_i$, its raw community representation, direct transformation representation and two-level filtered representation construct its propagative representation in the main graph $M$. While its direct transformation representation and node-level filtered representation construct its propagative representation in the sparse graph $S$. To avoid gradient vanishing, a ${\rm batch\_norm(\cdot)}$ function is applied on top of the concatenated representations in both graph:
\begin{equation} \label{eq:nv}
\begin{aligned}
& v_{i}^{M} = {\rm batch\_norm}([v_{c,i}^{M},v_{e,i}^{M},v_{p,i}^{M}]) \\
& v_{i}^{S} = {\rm batch\_norm}( [v_{e,i}^{S},v_{p,i}^{S}])
\end{aligned}
\end{equation}

\subsection{Community Recurrent Unit}\label{sc:cru}

After previous steps, each user of the mutual user triplet $\langle u_{i},u_{j},u_{k}\rangle$ is associated with a propagative representation. In this section, its corresponding community affiliation scores $c_{i}^{G}$ are further calculated in related graphs $G \in\{M,S\}$ through a designed Community Recurrent Unit (CRU), which is showed in Figure \ref{fig:cru}. The CRU contains an affiliation gate to calculate the user affiliation score for each community and an update gate to update community self representations. Within this unit, a community memory $D^{G} = \{d_1^G,...,d_K^G\}$ is designated to store $K$ community representations. Particularly, community representation is required to be with the same dimension as user propagative representation in both graphs.
\textbf{Community Affiliation Gate:} The affiliation gate helps to generate the affiliation score of a user $u_i$ towards each community in both graphs, which forms a $K$-dimensional vector $c_{i}^{G} = \{c_{i,1}^{G},...,c_{i,K}^{G}\}$ where $G \in \{M, S\}$ . The user $u_i$'s affiliation score $c_{i,j}^G$ towards the $j_{th}$ community in the graph $G$ is calculated as follows:

\begin{equation}\label{eq:dg}
c_{i,j}^G = {\rm  \sigma}((u_{c}^{G})^{\intercal}({\rm  tanh}(v_{i}^{G})*d_j^G))
\end{equation}

The dot product between transformed user propagative representation ${\rm  tanh}(v_{i}^{G})$ and the $j_{th}$ community representation $ d_j^G$ indicates their potential correlation, which further  turns to a scalar affiliation score $c_{i,j}^G$ between 0 to 1 with the help of a projection vector $u_{c}^{G}$ and normalization function $\sigma(\cdot)$.

\begin{figure}
	% 	\advance\leftskip-2cm
	\centering
	\includegraphics[width=1.2\columnwidth]{img/chapter4/cru.pdf}
	% 	\vspace{-1em}
	\caption{The flow of Community Recurrent Unit in the main graph $M$. The left part refers to the community affiliation gate and the right part is the community update gate.}
	\label{fig:cru}
	% 	\vspace{-1.5em}
\end{figure}

\textbf{Community Update Gate: } \label{sc:cug} When calculating $u_i$'s community affiliation, its information can help to update community representations in return. The updated representation is relied on both previous step community representation and current user propagative representation. Therefore, to better embrace the two representations, I use a delicate RNN variant, where the update process is calculated as follows:

\begin{equation}\label{eq:up}
\begin{aligned}
&  s^G = \sigma(W_s^G[v_i^{G},d_j^{G}] + b_s^G) \\
& z^G = {\rm tanh}(W_z^Gv_i^G+b_z^G)\\
& d_j^{G*} = (1-s^G)*d_j^{G} + s^G*z^G
\end{aligned}
\end{equation}

where $G \in \{M,S\}$. $s^G$ denotes the update rate and $z^G$ is transformed user information to be updated in current community.  $d_j^{G*}$ denotes the updated representation of the $j_{th}$ community in graph $G$, which is the weighted sum on previous community and current user representations. $W_s^G$ and $W_z^G,$ denote related weight matrices, while $b_s^G$ and $b_z^G,$ denote related biases.

\textbf{Community Constraint: }
To obtain the communities with less overlapping information in graph $G \in \{M,S\}$, the community representations ideally should be independent with each other. In my model, cosine similarity ${\rm cos}(\cdot)$ is taken as the criteria to measure the community similarity where higher score indicates stronger correlation. The averaged cosine similarities of all possible community representation pairs is calculated as a community loss to minimize:

\begin{equation}\label{eq:cc}
\mathcal{L}_{c}^{G} = \frac{1}{2K^2}\sum_{i,j}{\rm cos}(d_i^{G},d_j^{G})
\end{equation}
where $K$ is the number of communities in each graph.

\subsection{Pairwise Community Detection}\label{sc:pcd}

Similar to RankNet \cite{burges2010ranknet}, given a mutual user triplet  $\langle u_i,u_j,u_k \rangle$, as three types of pairwise label are considered including ``\textit{closer}'', ``\textit{similar}'' and ``\textit{farther}'', label $y_{i,j,k}$  is calculated as follows:
\begin{equation}\label{eq:y}
y_{i,j,k} = \frac{1}{2}(1+S_{jk})
\end{equation}
In terms of the community closeness for $u_i$, if $u_j$ is closer than $u_k$, $S_{jk} = 1$; if $u_j$ is farther than $u_k$, $S_{jk} = -1$; if $u_j$ and $u_k$ are similar, $S_{jk} = 0$. In this way, I convert the pairwise ranking task to a regression task.

To optimize this task, first of all, I calculate the correlation representation $r^{G}_{ij}$ between $u_j$ and $u_i$ in single graph $G \in \{M,S\}$:

\begin{equation}\label{eq:gr}
r^{G}_{ij} = W^{G}_{r}(c_{i}^{G} - c_{j}^{G}) +  b^{G}_{r}
\end{equation}

where $ W^{G}_{r}$ and $ b^{G}_{r}$ are related weight and bias, respectively.

To construct the information from both graphs, I concatenate the correlation representations from both graphs:
\begin{equation} \label{eq:cr}
r_{ij} = {\rm tanh}([r^{S}_{ij},r^{M}_{ij}])
\end{equation}
Similarly, the cross-graph correlation representation  between $u_i$ and $u_k$ is calculated as $r_{ik}$.

After that, I predict the community relationship between $u_j$ and $u_k$ towards $u_i$ as follows:
\begin{equation} \label{eq:yp}
\hat{y}_{i,j,k} = \sigma(W_{o}(r_{ij} - r_{ik}) +  b_{o})
\end{equation}

where $W_{o}$ and $b_{o}$ are the related weight and bias. $\sigma(\cdot)$ denotes the sigmoid activation function. In the end, the final loss $\mathcal{L}_{total}$ is the weighted sum of the optimization loss calculated via cross entropy and the community constraint losses where  $\mathcal{L}_{c}^S$ is for the sparse graph and $\mathcal{L}_{c}^M$ is for the main graph:
\begin{equation}\label{eq:loss}
\mathcal{L}_{total} = \underbrace{-y_{i,j,k}log\hat{y}_{i,j,k}-(1-y_{i,j,k})log(1-\hat{y}_{i,j,k})}_{optimization} + \underbrace{\alpha(\mathcal{L}_{c}^S + \mathcal{L}_{c}^M)}_{constraint}
\end{equation}

\subsection{Training Strategy}\label{sc:mt}

Although my model is trained solely on mutual user triplets, it is also able to detect pairwise community closeness among users only appeared in either sparse graph or main graph. Two training tricks are particularly employed in my model to improve model robustness, including shared weights and masked training.

First, as my model should be insensitive to the sequence of input user triplet, the weight matrices, biases and project vectors in both Section \ref{sc:upr} and Section \ref{sc:cru} should be shared among the three users. Moreover, in  Section \ref{sc:cru}, the community memory $D^G$ where $G \in \{M,S\}$ is updated by taking the average of the three updated community representations (calculated in Eq. \ref{eq:up}) from input triplets.

Second, to alleviate the negative effects of excessive connections in main graph $M$, I employ a masked training strategy by randomly remove a small ratio $\rho$ of connected objects from users in the main graph during each training batch. $\rho = 0$ means users remain their original multi-hot embeddings while $\rho = 1$ means users lose all their connections on objects.


\section{Introduction}

All that cryptography concerns are the \textit{privacy} and the \textit{integrity}
of data, no matter where the data are being processed. During the past decades,
numerous cryptographic schemes are proposed to realize this two goals. However,
most of these schemes discount their application scenarios. An typical example is
that, as pointed out by Ray \etal \cite{beaulieu2015simon}, an RFID authentication
protocol may require only 64-bits secrecy, while AES providing at least 128-bits
is certainly a waste of chip space.

Recently, \textit{pervasive computing} and its applications enable us to do our daily
activity more efficiently. The applications of pervasive computing are built from highly
constrained devices, such as sensor networks and chip cards \cite{hansmann2013pervasive}.
These systems highly emphasize on the energy consumption of the operations that taken,
as well as the computation resource usage \cite{satyanarayanan2001pervasive}. Obviously,
the secure assurance should also be bound to such constrains. Given the fact that
existing block cipher standard (\ie, AES) is unsuitable for these constrained
environments, the need for \textit{lightweight cryptography} attracts more attentions.

ARX (originally termed as AXR \cite{weinmann2009axr}) describes a family of lightweight
cryptographic schemes, which claim their lightness and universality in terms of limited
lightweight operations. In particular, an instance of ARX cipher consists of only three
kinds of operations (or \textit{primitives}): modular addition, circular bit-shifting
(the rotation) and bitwise xor. These primitives can be efficiently supported by
individual machine instructions, with each of them runs typically in one clock cycle.
The simplicity enables their uses on most constrained computing environments, especially
on those energy-aware systems, \eg, wireless sensor networks \cite{perrig2004security}.

The property of efficiency is not only necessary for hardware support, but also for
software implementation. Actually, an efficient encryption scheme is also essential for
those IO-intensive applications over a secure channel. For example, efficient encryption
and authentication improve the throughput of a popular website that transmits data
over TLS protocol. ARX cipher can also accelerate software level security-services,
because its operations can be easily implemented by almost all high-level programming
languages.

Despite the efficiency concerns, ARX should be provably secure under well-known attacks
towards a cryptosystem. Showing that each primitive runs in constant time, ARX is robust
against timing side-channels \cite{beaulieu2015simon}. An ARX cipher gets its
nonlinearity solely from modular addition, while the other two operations provide only
linear components. Given such inherited limitation, ARX ciphers could be vulnerable
under rotational cryptanalysis \cite{khovratovich2010rotational}. Excepting these
well-known results, the security analysis on ARX ciphers is still a challenging problem
\cite{mouha2011arx}.

This article explores the ARX cipher family on several aspects. Specifically, Section
\ref{sec:definition} gives the formal definition of an ARX cipher, in terms of the
operations, the notations, and their properties. Section \ref{sec:expressiveness}
discusses the expressiveness of ARX ciphers, particularly, it's shown that any permutation
on $\mathbb{Z}_{2^n}$ can be solely represented by ARX operations. Section \ref{sec:instances}
introduces two instances of ARX cipher, with their constructions and applications.
Section \ref{sec:conclusion} concludes this article.