diff --git a/doc/LieGroups.lyx b/doc/LieGroups.lyx deleted file mode 100644 index a2ab4c12e..000000000 --- a/doc/LieGroups.lyx +++ /dev/null @@ -1,3233 +0,0 @@ -#LyX 1.6.6.1 created this file. For more info see http://www.lyx.org/ -\lyxformat 345 -\begin_document -\begin_header -\textclass article -\use_default_options false -\begin_modules -theorems-std -\end_modules -\language english -\inputencoding auto -\font_roman times -\font_sans default -\font_typewriter default -\font_default_family rmdefault -\font_sc false -\font_osf false -\font_sf_scale 100 -\font_tt_scale 100 - -\graphics default -\paperfontsize 12 -\spacing single -\use_hyperref false -\papersize default -\use_geometry true -\use_amsmath 1 -\use_esint 0 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\leftmargin 1in -\topmargin 1in -\rightmargin 1in -\bottommargin 1in -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\author "" -\author "" -\end_header - -\begin_body - -\begin_layout Title -Lie Groups for Beginners -\end_layout - -\begin_layout Author -Frank Dellaert -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Derivatives -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\deriv}[2]{\frac{\partial#1}{\partial#2}} -{\frac{\partial#1}{\partial#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\at}[2]{#1\biggr\rvert_{#2}} -{#1\biggr\rvert_{#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Jac}[3]{ \at{\deriv{#1}{#2}} {#3} } -{\at{\deriv{#1}{#2}}{#3}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Lie Groups -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\xhat}{\hat{x}} -{\hat{x}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\yhat}{\hat{y}} -{\hat{y}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Ad}[1]{Ad_{#1}} -{Ad_{#1}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\AAdd}[1]{\mathbf{\mathop{Ad}}{}_{#1}} -{\mathbf{\mathop{Ad}}{}_{#1}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\define}{\stackrel{\Delta}{=}} -{\stackrel{\Delta}{=}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\gg}{\mathfrak{g}} -{\mathfrak{g}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Rn}{\mathbb{R}^{n}} -{\mathbb{R}^{n}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(2), 1 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rtwo}{\mathfrak{\mathbb{R}^{2}}} -{\mathfrak{\mathbb{R}^{2}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOtwo}{SO(2)} -{SO(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sotwo}{\mathfrak{so(2)}} -{\mathfrak{so(2)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\that}{\hat{\theta}} -{\hat{\theta}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\skew}[1]{[#1]_{+}} -{[#1]_{+}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(2), 3 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\SEtwo}{SE(2)} -{SE(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\setwo}{\mathfrak{se(2)}} -{\mathfrak{se(2)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Skew}[1]{[#1]_{\times}} -{[#1]_{\times}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(3), 3 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rthree}{\mathfrak{\mathbb{R}^{3}}} -{\mathfrak{\mathbb{R}^{3}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOthree}{SO(3)} -{SO(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sothree}{\mathfrak{so(3)}} -{\mathfrak{so(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\what}{\hat{\omega}} -{\hat{\omega}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(3),6 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rsix}{\mathfrak{\mathbb{R}^{6}}} -{\mathfrak{\mathbb{R}^{6}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SEthree}{SE(3)} -{SE(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sethree}{\mathfrak{se(3)}} -{\mathfrak{se(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\xihat}{\hat{\xi}} -{\hat{\xi}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Aff(2),6 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Afftwo}{Aff(2)} -{Aff(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\afftwo}{\mathfrak{aff(2)}} -{\mathfrak{aff(2)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\aa}{a} -{a} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\ahat}{\hat{a}} -{\hat{a}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status collapsed - -\begin_layout Plain Layout -SL(3),8 -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\SLthree}{SL(3)} -{SL(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\slthree}{\mathfrak{sl(3)}} -{\mathfrak{sl(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\hh}{h} -{h} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\hhat}{\hat{h}} -{\hat{h}} -\end_inset - - -\end_layout - -\begin_layout Section -Motivation: Rigid Motions in the Plane -\end_layout - -\begin_layout Standard -We will start with a small example of a robot moving in a plane, parameterized - by a -\emph on -2D pose -\emph default - -\begin_inset Formula $(x,\, y,\,\theta)$ -\end_inset - -. - When we give it a small forward velocity -\begin_inset Formula $v_{x}$ -\end_inset - -, we know that the location changes as -\begin_inset Formula \[ -\dot{x}=v_{x}\] - -\end_inset - -The solution to this trivial differential equation is, with -\begin_inset Formula $x_{0}$ -\end_inset - - the initial -\begin_inset Formula $x$ -\end_inset - --position of the robot, -\begin_inset Formula \[ -x_{t}=x_{0}+v_{x}t\] - -\end_inset - -A similar story holds for translation in the -\begin_inset Formula $y$ -\end_inset - - direction, and in fact for translations in general: -\begin_inset Formula \[ -(x_{t},\, y_{t},\,\theta_{t})=(x_{0}+v_{x}t,\, y_{0}+v_{y}t,\,\theta_{0})\] - -\end_inset - -Similarly for rotation we have -\begin_inset Formula \[ -(x_{t},\, y_{t},\,\theta_{t})=(x_{0},\, y_{0},\,\theta_{0}+\omega t)\] - -\end_inset - -where -\begin_inset Formula $\omega$ -\end_inset - - is angular velocity, measured in -\begin_inset Formula $rad/s$ -\end_inset - - in counterclockwise direction. - -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement h -wide false -sideways false -status collapsed - -\begin_layout Plain Layout -\align center -\begin_inset Graphics - filename images/circular.pdf - -\end_inset - - -\begin_inset Caption - -\begin_layout Plain Layout -Robot moving along a circular trajectory. -\end_layout - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -However, if we combine translation and rotation, the story breaks down! - We cannot write -\begin_inset Formula \[ -(x_{t},\, y_{t},\,\theta_{t})=(x_{0}+v_{x}t,\, y_{0}+v_{y}t,\,\theta_{0}+\omega t)\] - -\end_inset - -The reason is that, if we move the robot a tiny bit according to the velocity - vector -\begin_inset Formula $(v_{x},\, v_{y},\,\omega)$ -\end_inset - -, we have (to first order) -\begin_inset Formula \[ -(x_{\delta},\, y_{\delta},\,\theta_{\delta})=(x_{0}+v_{x}\delta,\, y_{0}+v_{y}\delta,\,\theta_{0}+\omega\delta)\] - -\end_inset - -but now the robot has rotated, and for the next incremental change, the - velocity vector would have to be rotated before it can be applied. - In fact, the robot will move on a -\emph on -circular -\emph default - trajectory. - -\end_layout - -\begin_layout Standard -The reason is that -\emph on -translation and rotation do not commute -\emph default -: if we rotate and then move we will end up in a different place than if - we moved first, then rotated. - In fact, someone once said (I forget who, kudos for who can track down - the exact quote): -\end_layout - -\begin_layout Quote -If rotation and translation commuted, we could do all rotations before leaving - home. -\end_layout - -\begin_layout Standard -\begin_inset Float figure -placement h -wide false -sideways false -status open - -\begin_layout Plain Layout -\align center -\begin_inset Graphics - filename images/n-steps.pdf - -\end_inset - - -\begin_inset Caption - -\begin_layout Plain Layout -\begin_inset CommandInset label -LatexCommand label -name "fig:n-step-program" - -\end_inset - -Approximating a circular trajectory with -\begin_inset Formula $n$ -\end_inset - - steps. -\end_layout - -\end_inset - - -\end_layout - -\end_inset - -To make progress, we have to be more precise about how the robot behaves. - Specifically, let us define composition of two poses -\begin_inset Formula $T_{1}$ -\end_inset - - and -\begin_inset Formula $T_{2}$ -\end_inset - - as -\begin_inset Formula \[ -T_{1}T_{2}=(x_{1},\, y_{1},\,\theta_{1})(x_{2},\, y_{2},\,\theta_{2})=(x_{1}+\cos\theta_{1}x_{2}-\sin\theta y_{2},\, y_{1}+\sin\theta_{1}x_{2}+\cos\theta_{1}y_{2},\,\theta_{1}+\theta_{2})\] - -\end_inset - -This is a bit clumsy, so we resort to a trick: embed the 2D poses in the - space of -\begin_inset Formula $3\times3$ -\end_inset - - matrices, so we can define composition as matrix multiplication: -\begin_inset Formula \[ -T_{1}T_{2}=\left[\begin{array}{cc} -R_{1} & t_{1}\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -R_{2} & t_{2}\\ -0 & 1\end{array}\right]=\left[\begin{array}{cc} -R_{1}R_{2} & R_{1}t_{2}+t_{1}\\ -0 & 1\end{array}\right]\] - -\end_inset - -where the matrices -\begin_inset Formula $R$ -\end_inset - - are 2D rotation matrices defined as -\begin_inset Formula \[ -R=\left[\begin{array}{cc} -\cos\theta & -\sin\theta\\ -\sin\theta & \cos\theta\end{array}\right]\] - -\end_inset - -Now a -\begin_inset Quotes eld -\end_inset - -tiny -\begin_inset Quotes erd -\end_inset - - motion of the robot can be written as -\begin_inset Formula \[ -T(\delta)=\left[\begin{array}{ccc} -\cos\omega\delta & -\sin\omega\delta & v_{x}\delta\\ -\sin\omega\delta & \cos\omega\delta & v_{y}\delta\\ -0 & 0 & 1\end{array}\right]\approx\left[\begin{array}{ccc} -1 & -\omega\delta & v_{x}\delta\\ -\omega\delta & 1 & v_{y}\delta\\ -0 & 0 & 1\end{array}\right]=I+\delta\left[\begin{array}{ccc} -0 & -\omega & v_{x}\\ -\omega & 0 & v_{y}\\ -0 & 0 & 0\end{array}\right]\] - -\end_inset - -Let us define the -\emph on -2D twist -\emph default - vector -\begin_inset Formula $\xi=(v,\omega)$ -\end_inset - -, and the matrix above as -\begin_inset Formula \[ -\xihat\define\left[\begin{array}{ccc} -0 & -\omega & v_{x}\\ -\omega & 0 & v_{y}\\ -0 & 0 & 0\end{array}\right]\] - -\end_inset - -If we wanted -\begin_inset Formula $t$ -\end_inset - - to be large, we could split up -\begin_inset Formula $t$ -\end_inset - - into smaller timesteps, say -\begin_inset Formula $n$ -\end_inset - - of them, and compose them as follows: -\begin_inset Formula \[ -T(t)\approx\left(I+\frac{t}{n}\xihat\right)\ldots\mbox{n times}\ldots\left(I+\frac{t}{n}\xihat\right)=\left(I+\frac{t}{n}\xihat\right)^{n}\] - -\end_inset - -The result is shown in Figure -\begin_inset CommandInset ref -LatexCommand ref -reference "fig:n-step-program" - -\end_inset - -. -\end_layout - -\begin_layout Standard -Of course, the perfect solution would be obtained if we take -\begin_inset Formula $n$ -\end_inset - - to infinity: -\begin_inset Formula \[ -T(t)=\lim_{n\rightarrow\infty}\left(I+\frac{t}{n}\xihat\right)^{n}\] - -\end_inset - -For real numbers, this series is familiar and is actually a way to compute - the exponential function: -\begin_inset Formula \[ -e^{x}=\lim_{n\rightarrow\infty}\left(1+\frac{x}{n}\right)^{n}=\sum_{k=0}^{\infty}\frac{x^{k}}{k!}\] - -\end_inset - -The series can be similarly defined for square matrices, and the final result - is that we can write the motion of a robot along a circular trajectory, - resulting from the 2D twist -\begin_inset Formula $\xi=(v,\omega)$ -\end_inset - - -\begin_inset Formula $ $ -\end_inset - - as the -\emph on -matrix exponential -\emph default - of -\begin_inset Formula $\xihat$ -\end_inset - -: -\begin_inset Formula \[ -T(t)=e^{t\xihat}\define\lim_{n\rightarrow\infty}\left(I+\frac{t}{n}\xihat\right)^{n}=\sum_{k=0}^{\infty}\frac{t^{k}}{k!}\xihat^{k}\] - -\end_inset - -We call this mapping from 2D twists matrices -\begin_inset Formula $\xihat$ -\end_inset - - to 2D rigid transformations the -\emph on -exponential map. -\end_layout - -\begin_layout Standard -The above has all elements of Lie group theory. - We call the space of 2D rigid transformations, along with the composition - operation, the -\emph on -special Euclidean group -\emph default - -\begin_inset Formula $\SEtwo$ -\end_inset - -. - It is called a Lie group because it is simultaneously a topological group - and a manifold, which implies that the multiplication and the inversion - operations are smooth. - The space of 2D twists, together with a special binary operation to be - defined below, is called the Lie algebra -\begin_inset Formula $\setwo$ -\end_inset - - associated with -\begin_inset Formula $\SEtwo$ -\end_inset - -. - Below we generalize these concepts and then introduce the most commonly - used Lie groups and their Lie algebras. -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -Basic Lie Group Concepts -\end_layout - -\begin_layout Subsection -A Manifold and a Group -\end_layout - -\begin_layout Standard -A Lie group -\begin_inset Formula $G$ -\end_inset - - is a a group and a manifold that possesses a smooth group operation. - Associated with it is a Lie Algebra -\begin_inset Formula $\gg$ -\end_inset - - which, loosely speaking, can be identified with the tangent space at the - identity and completely defines how the groups behaves around the identity. - There is a mapping from -\begin_inset Formula $\gg$ -\end_inset - - back to -\begin_inset Formula $G$ -\end_inset - -, called the exponential map -\begin_inset Formula \[ -\exp:\gg\rightarrow G\] - -\end_inset - -which is typically a many-to-one mapping. - The corresponding inverse can be define locally around the origin and hence - is a -\begin_inset Quotes eld -\end_inset - -logarithm -\begin_inset Quotes erd -\end_inset - - -\begin_inset Formula \[ -\log:G\rightarrow\gg\] - -\end_inset - -that maps elements in a neighborhood of -\begin_inset Formula $id$ -\end_inset - - in G to an element in -\begin_inset Formula $\gg$ -\end_inset - -. -\end_layout - -\begin_layout Subsection -Lie Algebra -\end_layout - -\begin_layout Standard -The Lie Algebra -\begin_inset Formula $\gg$ -\end_inset - - is called an algebra because it is endowed with a binary operation, the - Lie bracket -\begin_inset Formula $[X,Y]$ -\end_inset - -, the properties of which are closely related to the group operation of - -\begin_inset Formula $G$ -\end_inset - -. - For example, in matrix Lie groups, the Lie bracket is given by -\begin_inset Formula $[A,B]\define AB-BA$ -\end_inset - -. -\end_layout - -\begin_layout Standard -The relationship of the Lie bracket to the group operation is as follows: - for commutative Lie groups vector addition -\begin_inset Formula $X+Y$ -\end_inset - - in -\begin_inset Formula $\gg$ -\end_inset - - mimicks the group operation. - For example, if we have -\begin_inset Formula $Z=X+Y$ -\end_inset - - in -\begin_inset Formula $\gg$ -\end_inset - -, when mapped backed to -\begin_inset Formula $G$ -\end_inset - - via the exponential map we obtain -\begin_inset Formula \[ -e^{Z}=e^{X+Y}=e^{X}e^{Y}\] - -\end_inset - -However, this does -\emph on -not -\emph default - hold for non-commutative Lie groups: -\begin_inset Formula \[ -Z=\log(e^{X}e^{Y})\neq X+Y\] - -\end_inset - -Instead, -\begin_inset Formula $Z$ -\end_inset - - can be calculated using the Baker-Campbell-Hausdorff (BCH) formula -\begin_inset CommandInset citation -LatexCommand cite -key "Hall00book" - -\end_inset - - -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -http://en.wikipedia.org/wiki/Baker–Campbell–Hausdorff_formula -\end_layout - -\end_inset - -: -\begin_inset Formula \[ -Z=X+Y+[X,Y]/2+[X-Y,[X,Y]]/12-[Y,[X,[X,Y]]]/24+\ldots\] - -\end_inset - -For commutative groups the bracket is zero and we recover -\begin_inset Formula $Z=X+Y$ -\end_inset - -. - For non-commutative groups we can use the BCH formula to approximate it. -\end_layout - -\begin_layout Subsection -Exponential Coordinates -\end_layout - -\begin_layout Standard -For -\begin_inset Formula $n$ -\end_inset - --dimensional matrix Lie groups, as a vector space the Lie algebra -\begin_inset Formula $\gg$ -\end_inset - - is isomorphic to -\begin_inset Formula $\mathbb{R}^{n}$ -\end_inset - -, and we can define the hat operator -\begin_inset CommandInset citation -LatexCommand cite -after "page 41" -key "Murray94book" - -\end_inset - -, -\begin_inset Formula \[ -\hat{}:x\in\mathbb{R}^{n}\rightarrow\xhat\in\gg\] - -\end_inset - -which maps -\begin_inset Formula $n$ -\end_inset - --vectors -\begin_inset Formula $x\in\mathbb{R}^{n}$ -\end_inset - - to elements of -\begin_inset Formula $\gg$ -\end_inset - -. - In the case of matrix Lie groups, the elements -\begin_inset Formula $\xhat$ -\end_inset - - of -\begin_inset Formula $\gg$ -\end_inset - - are -\begin_inset Formula $n\times n$ -\end_inset - - matrices, and the map is given by -\begin_inset Formula \begin{equation} -\xhat=\sum_{i=1}^{n}x_{i}G^{i}\label{eq:generators}\end{equation} - -\end_inset - -where the -\begin_inset Formula $G^{i}$ -\end_inset - - are -\begin_inset Formula $n\times n$ -\end_inset - - matrices known as Lie group generators. - The meaning of the map -\begin_inset Formula $x\rightarrow\xhat$ -\end_inset - - will depend on the group -\begin_inset Formula $G$ -\end_inset - - and will generally have an intuitive interpretation. -\end_layout - -\begin_layout Subsection -Tangent Spaces and the Tangent Bundle -\end_layout - -\begin_layout Standard -The tangent space -\begin_inset Formula $T_{g}G$ -\end_inset - - at a group element -\begin_inset Formula $g\in G$ -\end_inset - - is the vector space of tangent vectors at -\begin_inset Formula $g$ -\end_inset - -. - The tangent bundle -\begin_inset Formula $TG$ -\end_inset - - is the set of all tangent vectors -\begin_inset Formula \[ -TG\define\bigcup_{g\in G}T_{g}G\] - -\end_inset - -A vector field -\begin_inset Formula $X:G\rightarrow TG$ -\end_inset - - assigns to each element -\begin_inset Formula $g$ -\end_inset - - as single tangent vector -\begin_inset Formula $x\in T_{g}G$ -\end_inset - -. -\end_layout - -\begin_layout Subsection -The Adjoint Map and Adjoint Representation -\end_layout - -\begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout -We do not fully understand this yet!!! -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -The -\emph on -adjoint map -\emph default - -\begin_inset Formula $\AAdd g$ -\end_inset - - maps a group element -\begin_inset Formula $a\in G$ -\end_inset - - to its conjugate -\begin_inset Formula $gag^{-1}$ -\end_inset - - by -\begin_inset Formula $g$ -\end_inset - -. -\end_layout - -\begin_layout Standard -Below we frequently make use of the equality -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -http://en.wikipedia.org/wiki/Exponential_map -\end_layout - -\end_inset - - -\begin_inset Formula \[ -\AAdd ge^{\xhat}=ge^{\xhat}g^{-1}=e^{\Ad g{\xhat}}\] - -\end_inset - -where -\begin_inset Formula $\Ad g:\gg\rightarrow\mathfrak{\gg}$ -\end_inset - - is a map parameterized by a group element -\begin_inset Formula $g$ -\end_inset - -, and is called the -\emph on -adjoint representation -\emph default -. - -\begin_inset Note Note -status open - -\begin_layout Plain Layout -The intuitive explanation is that a change -\begin_inset Formula $\exp\left(\xhat\right)$ -\end_inset - - defined around the orgin, but applied at the group element -\begin_inset Formula $g$ -\end_inset - -, can be written in one step by taking the adjoint -\begin_inset Formula $\Ad g{\xhat}$ -\end_inset - - of -\begin_inset Formula $\xhat$ -\end_inset - -. -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -In the case of a matrix group the adjoint can be written as -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -http://en.wikipedia.org/wiki/Adjoint_representation_of_a_Lie_group -\end_layout - -\end_inset - - -\begin_inset Formula \[ -\Ad T{\xhat}\define T\xhat T^{-1}\] - -\end_inset - -and hence we have -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -Te^{\xhat}T^{-1}=e^{T\xhat T^{-1}}\] - -\end_inset - -where both -\begin_inset Formula $T\in G$ -\end_inset - - and -\begin_inset Formula $\xhat\in\gg$ -\end_inset - - are -\begin_inset Formula $n\times n$ -\end_inset - - matrices for an -\begin_inset Formula $n$ -\end_inset - --dimensional Lie group. -\end_layout - -\begin_layout Subsection -Actions -\end_layout - -\begin_layout Standard -The (usual) action of an -\begin_inset Formula $n$ -\end_inset - --dimensional matrix group -\begin_inset Formula $G$ -\end_inset - - is matrix-vector multiplication on -\begin_inset Formula $\mathbb{R}^{n}$ -\end_inset - -, -\begin_inset Formula \[ -q=Tp\] - -\end_inset - -with -\begin_inset Formula $p,q\in\mathbb{R}^{n}$ -\end_inset - - and -\begin_inset Formula $T\in GL(n)$ -\end_inset - -. -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Rotations -\end_layout - -\begin_layout Standard -We first look at a very simple group, the 2D rotations. -\end_layout - -\begin_layout Subsection -Basics -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $\SOtwo$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(2)$ -\end_inset - - of -\begin_inset Formula $2\times2$ -\end_inset - - invertible matrices. - Its Lie algebra -\begin_inset Formula $\sotwo$ -\end_inset - - is the vector space of -\begin_inset Formula $2\times2$ -\end_inset - - skew-symmetric matrices. - Since -\begin_inset Formula $\SOtwo$ -\end_inset - - is a one-dimensional manifold, -\begin_inset Formula $\sotwo$ -\end_inset - - is isomorphic to -\begin_inset Formula $\mathbb{R}$ -\end_inset - - and we define -\begin_inset Formula \[ -\hat{}:\mathbb{R}\rightarrow\sotwo\] - -\end_inset - - -\begin_inset Formula \[ -\hat{}:\omega\rightarrow\what=\skew{\omega}\] - -\end_inset - -which maps the angle -\begin_inset Formula $\theta$ -\end_inset - - to the -\begin_inset Formula $2\times2$ -\end_inset - - skew-symmetric matrix -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula $\skew{\theta}$ -\end_inset - -: -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit - -\begin_inset Formula \[ -\skew{\theta}=\left[\begin{array}{cc} -0 & -\theta\\ -\theta & 0\end{array}\right]\] - -\end_inset - -The exponential map can be computed in closed form as -\begin_inset Formula \[ -R=e^{\skew{\omega t}}=e^{\skew{\theta}}=\left[\begin{array}{cc} -\cos\theta & -\sin\theta\\ -\sin\theta & \cos\theta\end{array}\right]\] - -\end_inset - -This can be proven -\begin_inset CommandInset citation -LatexCommand cite -key "Hall00book" - -\end_inset - - by realizing -\begin_inset Formula $\skew 1$ -\end_inset - - is diagonizable with eigenvalues -\begin_inset Formula $-i$ -\end_inset - - and -\begin_inset Formula $i$ -\end_inset - - , and eigenvectors -\begin_inset Formula $\left[\begin{array}{c} -1\\ -i\end{array}\right]$ -\end_inset - - and -\begin_inset Formula $\left[\begin{array}{c} -i\\ -1\end{array}\right]$ -\end_inset - -. - Readers familiar with projective geometry will recognize these as the circular - points when promoted to homogeneous coordinates. -\end_layout - -\begin_layout Subsection -Adjoint -\end_layout - -\begin_layout Standard -The adjoint map for -\begin_inset Formula $\sotwo$ -\end_inset - - is trivially equal to the identity, as is the case for -\emph on -all -\emph default - commutative groups: -\begin_inset Formula \begin{eqnarray*} -\Ad R\what & = & \left[\begin{array}{cc} -\cos\theta & -\sin\theta\\ -\sin\theta & \cos\theta\end{array}\right]\left[\begin{array}{cc} -0 & -\omega\\ -\omega & 0\end{array}\right]\left[\begin{array}{cc} -\cos\theta & -\sin\theta\\ -\sin\theta & \cos\theta\end{array}\right]^{T}\\ - & = & \omega\left[\begin{array}{cc} --\sin\theta & -\cos\theta\\ -\cos\theta & -\sin\theta\end{array}\right]\left[\begin{array}{cc} -\cos\theta & \sin\theta\\ --\sin\theta & \cos\theta\end{array}\right]=\left[\begin{array}{cc} -0 & -\omega\\ -\omega & 0\end{array}\right]\end{eqnarray*} - -\end_inset - -i.e., -\begin_inset Formula \[ -\Ad R\what=\what\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Actions -\end_layout - -\begin_layout Standard -In the case of -\begin_inset Formula $\SOtwo$ -\end_inset - - the vector space is -\begin_inset Formula $\Rtwo$ -\end_inset - -, and the group action corresponds to rotating a point -\begin_inset Formula \[ -q=Rp\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\theta$ -\end_inset - - would do: -\begin_inset Formula \[ -q(\text{\omega t})=Re^{\skew{\omega t}}p\] - -\end_inset - -hence the derivative is: -\begin_inset Formula \[ -\deriv{q(\omega t)}t=R\deriv{}t\left(e^{\skew{\omega t}}p\right)=R\deriv{}t\left(\skew{\omega t}p\right)=RH_{p}\] - -\end_inset - -Note that -\begin_inset Formula \begin{equation} -\skew{\theta}\left[\begin{array}{c} -x\\ -y\end{array}\right]=\theta R_{\pi/2}\left[\begin{array}{c} -x\\ -y\end{array}\right]=\theta\left[\begin{array}{c} --y\\ -x\end{array}\right]\label{eq:RestrictedCross}\end{equation} - -\end_inset - -which acts like a restricted -\begin_inset Quotes eld -\end_inset - -cross product -\begin_inset Quotes erd -\end_inset - - in the plane. -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Rigid Transformations -\end_layout - -\begin_layout Subsection -Basics -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $\SEtwo$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(3)$ -\end_inset - - of -\begin_inset Formula $3\times3$ -\end_inset - - invertible matrices of the form -\begin_inset Formula \[ -T\define\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\] - -\end_inset - -where -\begin_inset Formula $R\in\SOtwo$ -\end_inset - - is a rotation matrix and -\begin_inset Formula $t\in\Rtwo$ -\end_inset - - is a translation vector. - -\begin_inset Formula $\SEtwo$ -\end_inset - - is the -\emph on -semi-direct product -\emph default - of -\begin_inset Formula $\Rtwo$ -\end_inset - - by -\begin_inset Formula $SO(2)$ -\end_inset - -, written as -\begin_inset Formula $\SEtwo=\Rtwo\rtimes\SOtwo$ -\end_inset - -. - In particular, any element -\begin_inset Formula $T$ -\end_inset - - of -\begin_inset Formula $\SEtwo$ -\end_inset - - can be written as -\begin_inset Formula \[ -T=\left[\begin{array}{cc} -0 & t\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -R & 0\\ -0 & 1\end{array}\right]\] - -\end_inset - -and they compose as -\begin_inset Formula \[ -T_{1}T_{2}=\left[\begin{array}{cc} -R_{1} & t_{1}\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -R_{2} & t_{2}\\ -0 & 1\end{array}\right]=\left[\begin{array}{cc} -R_{1}R_{2} & R_{1}t_{2}+t_{1}\\ -0 & 1\end{array}\right]\] - -\end_inset - -Hence, an alternative way of writing down elements of -\begin_inset Formula $\SEtwo$ -\end_inset - - is as the ordered pair -\begin_inset Formula $(R,\, t)$ -\end_inset - -, with composition defined a -\begin_inset Formula \[ -(R_{1},\, t_{1})(R_{2},\, t_{2})=(R_{1}R_{2},\, R{}_{1}t_{2}+t_{1})\] - -\end_inset - - -\end_layout - -\begin_layout Standard -The corresponding Lie algebra -\begin_inset Formula $\setwo$ -\end_inset - - is the vector space of -\begin_inset Formula $3\times3$ -\end_inset - - twists -\begin_inset Formula $\xihat$ -\end_inset - - parameterized by the -\emph on -twist coordinates -\emph default - -\begin_inset Formula $\xi\in\Rthree$ -\end_inset - -, with the mapping -\begin_inset Formula \[ -\xi\define\left[\begin{array}{c} -v\\ -\omega\end{array}\right]\rightarrow\xihat\define\left[\begin{array}{cc} -\skew{\omega} & v\\ -0 & 0\end{array}\right]\] - -\end_inset - -Note we think of robots as having a pose -\begin_inset Formula $(x,y,\theta)$ -\end_inset - - and hence I reserved the first two components for translation and the last - for rotation. - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -The corresponding Lie group generators are -\begin_inset Formula \[ -G^{x}=\left[\begin{array}{ccc} -0 & 0 & 1\\ -0 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{y}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 1\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{\theta}=\left[\begin{array}{ccc} -0 & -1 & 0\\ -1 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\] - -\end_inset - - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -Applying the exponential map to a twist -\begin_inset Formula $\xi$ -\end_inset - - yields a screw motion yielding an element in -\begin_inset Formula $\SEtwo$ -\end_inset - -: -\begin_inset Formula \[ -T=e^{\xihat}=\left(e^{\skew{\omega}},(I-e^{\skew{\omega}})\frac{v^{\perp}}{\omega}\right)\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -The Adjoint Map -\end_layout - -\begin_layout Standard -The adjoint is -\begin_inset Formula \begin{eqnarray} -\Ad T{\xihat} & = & T\xihat T^{-1}\nonumber \\ - & = & \left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -\skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{cc} -R^{T} & -R^{T}t\\ -0 & 1\end{array}\right]\nonumber \\ - & = & \left[\begin{array}{cc} -\skew{\omega} & -\skew{\omega}t+Rv\\ -0 & 0\end{array}\right]\nonumber \\ - & = & \left[\begin{array}{cc} -\skew{\omega} & Rv-\omega R_{\pi/2}t\\ -0 & 0\end{array}\right]\label{eq:adjointSE2}\end{eqnarray} - -\end_inset - -From this we can express the Adjoint map in terms of plane twist coordinates: -\begin_inset Formula \[ -\left[\begin{array}{c} -v'\\ -\omega'\end{array}\right]=\left[\begin{array}{cc} -R & -R_{\pi/2}t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -v\\ -\omega\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Actions -\end_layout - -\begin_layout Standard -The action of -\begin_inset Formula $\SEtwo$ -\end_inset - - on 2D points is done by embedding the points in -\begin_inset Formula $\mathbb{R}^{3}$ -\end_inset - - by using homogeneous coordinates -\begin_inset Formula \[ -\hat{q}=\left[\begin{array}{c} -q\\ -1\end{array}\right]=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=T\hat{p}\] - -\end_inset - -Analoguous to -\begin_inset Formula $\SEthree$ -\end_inset - -, we can compute a velocity -\begin_inset Formula $\xihat\hat{p}$ -\end_inset - - in the local -\begin_inset Formula $T$ -\end_inset - - frame: -\begin_inset Formula \[ -\xihat\hat{p}=\left[\begin{array}{cc} -\skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=\left[\begin{array}{c} -\skew{\omega}p+v\\ -0\end{array}\right]\] - -\end_inset - -By only taking the top two rows, we can write this as a velocity in -\begin_inset Formula $\Rtwo$ -\end_inset - -, as the product of a -\begin_inset Formula $2\times3$ -\end_inset - - matrix -\begin_inset Formula $H_{p}$ -\end_inset - - that acts upon the exponential coordinates -\begin_inset Formula $\xi$ -\end_inset - - directly: -\begin_inset Formula \[ -\skew{\omega}p+v=v+R_{\pi/2}p\omega=\left[\begin{array}{cc} -I_{2} & R_{\pi/2}p\end{array}\right]\left[\begin{array}{c} -v\\ -\omega\end{array}\right]=H_{p}\xi\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -3D Rotations -\end_layout - -\begin_layout Subsection -Basics -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $\SOthree$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(3)$ -\end_inset - - of -\begin_inset Formula $3\times3$ -\end_inset - - invertible matrices. - Its Lie algebra -\begin_inset Formula $\sothree$ -\end_inset - - is the vector space of -\begin_inset Formula $3\times3$ -\end_inset - - skew-symmetric matrices -\begin_inset Formula $\what$ -\end_inset - -. - The exponential map can be computed in closed form using Rodrigues' formula - -\begin_inset CommandInset citation -LatexCommand cite -after "page 28" -key "Murray94book" - -\end_inset - -: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -e^{\what}=I+\what\sin\theta+\what^{2}(1\text{−}\cos\theta)\] - -\end_inset - -where -\begin_inset Formula $\what^{2}=\omega\omega^{T}-I$ -\end_inset - -, with -\begin_inset Formula $\omega\omega^{T}$ -\end_inset - - the outer product of -\begin_inset Formula $\omega$ -\end_inset - -. - Hence, a slightly more efficient variant is -\begin_inset Formula \[ -e^{\what}=\cos\theta I+\what sin\theta+\omega\omega^{T}(1\text{−}cos\theta)\] - -\end_inset - -Since -\begin_inset Formula $\SOthree$ -\end_inset - - is a three-dimensional manifold, -\begin_inset Formula $\sothree$ -\end_inset - - is isomorphic to -\begin_inset Formula $\Rthree$ -\end_inset - - and we define the map -\begin_inset Formula \[ -\hat{}:\Rthree\rightarrow\sothree\] - -\end_inset - - -\begin_inset Formula \[ -\hat{}:\omega\rightarrow\what=\Skew{\omega}\] - -\end_inset - -which maps 3-vectors -\begin_inset Formula $\omega$ -\end_inset - - to skew-symmetric matrices -\begin_inset Formula $\Skew{\omega}$ -\end_inset - - : -\begin_inset Formula \[ -\Skew{\omega}=\left[\begin{array}{ccc} -0 & -\omega_{z} & \omega_{y}\\ -\omega_{z} & 0 & -\omega_{x}\\ --\omega_{y} & \omega_{x} & 0\end{array}\right]=\omega_{x}G^{x}+\omega_{y}G^{y}+\omega_{z}G^{z}\] - -\end_inset - -where the -\begin_inset Formula $G^{i}$ -\end_inset - - are the generators for -\begin_inset Formula $\SOthree$ -\end_inset - -, -\begin_inset Formula \[ -G^{x}=\left(\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & -1\\ -0 & 1 & 0\end{array}\right)\mbox{}G^{y}=\left(\begin{array}{ccc} -0 & 0 & 1\\ -0 & 0 & 0\\ --1 & 0 & 0\end{array}\right)\mbox{ }G^{z}=\left(\begin{array}{ccc} -0 & -1 & 0\\ -1 & 0 & 0\\ -0 & 0 & 0\end{array}\right)\] - -\end_inset - -corresponding to a rotation around -\begin_inset Formula $X$ -\end_inset - -, -\begin_inset Formula $Y$ -\end_inset - -, and -\begin_inset Formula $Z$ -\end_inset - -, respectively. - The Lie bracket -\begin_inset Formula $[x,y]$ -\end_inset - - corresponds to the cross product -\begin_inset Formula $x\times y$ -\end_inset - - in -\begin_inset Formula $\Rthree$ -\end_inset - -. -\end_layout - -\begin_layout Standard -For every -\begin_inset Formula $3-$ -\end_inset - -vector -\begin_inset Formula $\omega$ -\end_inset - - there is a corresponding rotation matrix -\begin_inset Formula \[ -R=e^{\Skew{\omega}}\] - -\end_inset - -and this is defines the canonical parameterization of -\begin_inset Formula $\SOthree$ -\end_inset - -, with -\begin_inset Formula $\omega$ -\end_inset - - known as the canonical or exponential coordinates. - It is equivalent to the axis-angle representation for rotations, where - the unit vector -\begin_inset Formula $\omega/\left\Vert \omega\right\Vert $ -\end_inset - - defines the rotation axis, and its magnitude the amount of rotation -\begin_inset Formula $\theta$ -\end_inset - -. -\end_layout - -\begin_layout Subsection -The Adjoint Map -\end_layout - -\begin_layout Standard -For rotation matrices -\begin_inset Formula $R$ -\end_inset - - we can prove the following identity (see -\begin_inset CommandInset ref -LatexCommand vref -reference "proof1" - -\end_inset - -): -\begin_inset Formula \begin{equation} -R\Skew{\omega}R^{T}=\Skew{R\omega}\label{eq:property1}\end{equation} - -\end_inset - -Hence, given property -\begin_inset CommandInset ref -LatexCommand eqref -reference "eq:property1" - -\end_inset - -, the adjoint map for -\begin_inset Formula $\sothree$ -\end_inset - - simplifies to -\begin_inset Formula \[ -\Ad R{\Skew{\omega}}=R\Skew{\omega}R^{T}=\Skew{R\omega}\] - -\end_inset - -and this can be expressed in exponential coordinates simply by rotating - the axis -\begin_inset Formula $\omega$ -\end_inset - - to -\begin_inset Formula $R\omega$ -\end_inset - -. - -\end_layout - -\begin_layout Standard -As an example, to apply an axis-angle rotation -\begin_inset Formula $\omega$ -\end_inset - - to a point -\begin_inset Formula $p$ -\end_inset - - in the frame -\begin_inset Formula $R$ -\end_inset - -, we could: -\end_layout - -\begin_layout Enumerate -First transform -\begin_inset Formula $p$ -\end_inset - - back to the world frame, apply -\begin_inset Formula $\omega$ -\end_inset - -, and then rotate back: -\begin_inset Formula \[ -q=Re^{\Skew{\omega}}R^{T}\] - -\end_inset - - -\end_layout - -\begin_layout Enumerate -Immediately apply the transformed axis-angle transformation -\begin_inset Formula $\Ad R{\Skew{\omega}}=\Skew{R\omega}$ -\end_inset - -: -\begin_inset Formula \[ -q=e^{\Skew{R\omega}}p\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Actions -\end_layout - -\begin_layout Standard -In the case of -\begin_inset Formula $\SOthree$ -\end_inset - - the vector space is -\begin_inset Formula $\Rthree$ -\end_inset - -, and the group action corresponds to rotating a point -\begin_inset Formula \[ -q=Rp\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\omega$ -\end_inset - - would do: -\begin_inset Formula \[ -q(\omega)=Re^{\Skew{\omega}}p\] - -\end_inset - -hence the derivative is: -\begin_inset Formula \[ -\deriv{q(\omega)}{\omega}=R\deriv{}{\omega}\left(e^{\Skew{\omega}}p\right)=R\deriv{}{\omega}\left(\Skew{\omega}p\right)=R\Skew{-p}\] - -\end_inset - -To show the last equality note that -\begin_inset Formula \[ -\Skew{\omega}p=\omega\times p=-p\times\omega=\Skew{-p}\omega\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -3D Rigid Transformations -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $\SEthree$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(4)$ -\end_inset - - of -\begin_inset Formula $4\times4$ -\end_inset - - invertible matrices of the form -\begin_inset Formula \[ -T\define\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\] - -\end_inset - -where -\begin_inset Formula $R\in\SOthree$ -\end_inset - - is a rotation matrix and -\begin_inset Formula $t\in\Rthree$ -\end_inset - - is a translation vector. - An alternative way of writing down elements of -\begin_inset Formula $\SEthree$ -\end_inset - - is as the ordered pair -\begin_inset Formula $(R,\, t)$ -\end_inset - -, with composition defined as -\begin_inset Formula \[ -(R_{1},\, t_{1})(R_{2},\, t_{2})=(R_{1}R_{2},\, R{}_{1}t_{2}+t_{1})\] - -\end_inset - - Its Lie algebra -\begin_inset Formula $\sethree$ -\end_inset - - is the vector space of -\begin_inset Formula $4\times4$ -\end_inset - - twists -\begin_inset Formula $\xihat$ -\end_inset - - parameterized by the -\emph on -twist coordinates -\emph default - -\begin_inset Formula $\xi\in\Rsix$ -\end_inset - -, with the mapping -\begin_inset CommandInset citation -LatexCommand cite -key "Murray94book" - -\end_inset - - -\begin_inset Formula \[ -\xi\define\left[\begin{array}{c} -\omega\\ -v\end{array}\right]\rightarrow\xihat\define\left[\begin{array}{cc} -\Skew{\omega} & v\\ -0 & 0\end{array}\right]\] - -\end_inset - -Note we follow Frank Park's convention and reserve the first three components - for rotation, and the last three for translation. - Hence, with this parameterization, the generators for -\begin_inset Formula $\SEthree$ -\end_inset - - are -\begin_inset Formula \[ -G^{1}=\left(\begin{array}{cccc} -0 & 0 & 0 & 0\\ -0 & 0 & -1 & 0\\ -0 & 1 & 0 & 0\\ -0 & 0 & 0 & 0\end{array}\right)\mbox{}G^{2}=\left(\begin{array}{cccc} -0 & 0 & 1 & 0\\ -0 & 0 & 0 & 0\\ --1 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\end{array}\right)\mbox{ }G^{3}=\left(\begin{array}{cccc} -0 & -1 & 0 & 0\\ -1 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\end{array}\right)\] - -\end_inset - - -\begin_inset Formula \[ -G^{4}=\left(\begin{array}{cccc} -0 & 0 & 0 & 1\\ -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\end{array}\right)\mbox{}G^{5}=\left(\begin{array}{cccc} -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 1\\ -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\end{array}\right)\mbox{ }G^{6}=\left(\begin{array}{cccc} -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 0\\ -0 & 0 & 0 & 1\\ -0 & 0 & 0 & 0\end{array}\right)\] - -\end_inset - -Applying the exponential map to a twist -\begin_inset Formula $\xi$ -\end_inset - - yields a screw motion yielding an element in -\begin_inset Formula $\SEthree$ -\end_inset - -: -\begin_inset Formula \[ -T=\exp\xihat\] - -\end_inset - -A closed form solution for the exponential map is given in -\begin_inset CommandInset citation -LatexCommand cite -after "page 42" -key "Murray94book" - -\end_inset - -. -\end_layout - -\begin_layout Standard - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -\begin_inset Formula \[ -\exp\left(\left[\begin{array}{c} -\omega\\ -v\end{array}\right]t\right)=\left[\begin{array}{cc} -e^{\Skew{\omega}t} & (I-e^{\Skew{\omega}t})\left(\omega\times v\right)+\omega\omega^{T}vt\\ -0 & 1\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -The Adjoint Map -\end_layout - -\begin_layout Standard -The adjoint is -\begin_inset Formula \begin{eqnarray*} -\Ad T{\xihat} & = & T\xihat T^{-1}\\ - & = & \left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -\Skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{cc} -R^{T} & -R^{T}t\\ -0 & 1\end{array}\right]\\ - & = & \left[\begin{array}{cc} -\Skew{R\omega} & -\Skew{R\omega}t+Rv\\ -0 & 0\end{array}\right]\\ - & = & \left[\begin{array}{cc} -\Skew{R\omega} & t\times R\omega+Rv\\ -0 & 0\end{array}\right]\end{eqnarray*} - -\end_inset - -From this we can express the Adjoint map in terms of twist coordinates (see - also -\begin_inset CommandInset citation -LatexCommand cite -key "Murray94book" - -\end_inset - - and FP): -\begin_inset Formula \[ -\left[\begin{array}{c} -\omega'\\ -v'\end{array}\right]=\left[\begin{array}{cc} -R & 0\\ -\Skew tR & R\end{array}\right]\left[\begin{array}{c} -\omega\\ -v\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Actions -\end_layout - -\begin_layout Standard -The action of -\begin_inset Formula $\SEthree$ -\end_inset - - on 3D points is done by embedding the points in -\begin_inset Formula $\mathbb{R}^{4}$ -\end_inset - - by using homogeneous coordinates -\begin_inset Formula \[ -\hat{q}=\left[\begin{array}{c} -q\\ -1\end{array}\right]=\left[\begin{array}{c} -Rp+t\\ -1\end{array}\right]=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=T\hat{p}\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\xi$ -\end_inset - - would do: -\begin_inset Formula \[ -\hat{q}(\xi)=Te^{\xihat}\hat{p}\] - -\end_inset - -hence the derivative is -\begin_inset Formula \[ -\deriv{\hat{q}(\xi)}{\xi}=T\deriv{}{\xi}\left(\xihat\hat{p}\right)\] - -\end_inset - -where -\begin_inset Formula $\xihat\hat{p}$ -\end_inset - - corresponds to a velocity in -\begin_inset Formula $\mathbb{R}^{4}$ -\end_inset - - (in the local -\begin_inset Formula $T$ -\end_inset - - frame): -\begin_inset Formula \[ -\xihat\hat{p}=\left[\begin{array}{cc} -\Skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=\left[\begin{array}{c} -\omega\times p+v\\ -0\end{array}\right]\] - -\end_inset - -Notice how velocities are anologous to points at infinity in projective - geometry: they correspond to free vectors indicating a direction and magnitude - of change. -\end_layout - -\begin_layout Standard -By only taking the top three rows, we can write this as a velocity in -\begin_inset Formula $\Rthree$ -\end_inset - -, as the product of a -\begin_inset Formula $3\times6$ -\end_inset - - matrix -\begin_inset Formula $H_{p}$ -\end_inset - - that acts upon the exponential coordinates -\begin_inset Formula $\xi$ -\end_inset - - directly: -\begin_inset Formula \[ -\omega\times p+v=-p\times\omega+v=\left[\begin{array}{cc} --\Skew p & I_{3}\end{array}\right]\left[\begin{array}{c} -\omega\\ -v\end{array}\right]\] - -\end_inset - -The inverse action -\begin_inset Formula $T^{-1}p$ -\end_inset - - is -\begin_inset Formula \[ -\hat{q}=\left[\begin{array}{c} -q\\ -1\end{array}\right]=\left[\begin{array}{c} -R^{T}(p-t)\\ -1\end{array}\right]=\left[\begin{array}{cc} -R^{T} & -R^{T}t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=T^{-1}\hat{p}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Affine Transformations -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $Aff(2)$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(3)$ -\end_inset - - of -\begin_inset Formula $3\times3$ -\end_inset - - invertible matrices that maps the line infinity to itself, and hence preserves - paralellism. - The affine transformation matrices -\begin_inset Formula $A$ -\end_inset - - can be written as -\begin_inset CommandInset citation -LatexCommand cite -key "Mei08tro" - -\end_inset - - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula \[ -\left[\begin{array}{ccc} -m_{11} & m_{12} & t_{1}\\ -m_{21} & m_{22} & t_{2}\\ -0 & 0 & k\end{array}\right]\] - -\end_inset - -with -\begin_inset Formula $M\in GL(2)$ -\end_inset - -, -\begin_inset Formula $t\in\Rtwo$ -\end_inset - -, and -\begin_inset Formula $k$ -\end_inset - - a scalar chosen such that -\begin_inset Formula $det(A)=1$ -\end_inset - -. - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -Note that just as -\begin_inset Formula $\SEtwo$ -\end_inset - - is a semi-direct product, so too is -\begin_inset Formula $Aff(2)=\Rtwo\rtimes GL(2)$ -\end_inset - -. - In particular, any affine transformation -\begin_inset Formula $A$ -\end_inset - - can be written as -\begin_inset Formula \[ -A=\left[\begin{array}{cc} -0 & t\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -M & 0\\ -0 & k\end{array}\right]\] - -\end_inset - -and they compose as -\begin_inset Formula \[ -A_{1}A_{2}=\left[\begin{array}{cc} -M_{1} & t_{1}\\ -0 & k_{1}\end{array}\right]\left[\begin{array}{cc} -M_{2} & t_{2}\\ -0 & k_{2}\end{array}\right]=\left[\begin{array}{cc} -M_{1}M_{2} & M_{2}t_{2}+k_{2}t_{1}\\ -0 & k_{1}k_{2}\end{array}\right]\] - -\end_inset - -From this it can be gleaned that the groups -\begin_inset Formula $\SOtwo$ -\end_inset - - and -\begin_inset Formula $\SEtwo$ -\end_inset - - are both subgroups, with -\begin_inset Formula $\SOtwo\subset\SEtwo\subset\Afftwo$ -\end_inset - -. - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -By choosing the generators carefully we maintain this hierarchy among the - associated Lie algebras. - In particular, -\begin_inset Formula $\setwo$ -\end_inset - - -\begin_inset Formula \[ -G^{1}=\left[\begin{array}{ccc} -0 & 0 & 1\\ -0 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{2}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 1\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{3}=\left[\begin{array}{ccc} -0 & -1 & 0\\ -1 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\] - -\end_inset - -can be extended to the -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -Lie algebra -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula $\afftwo$ -\end_inset - - using the three additional generators -\begin_inset Formula \[ -G^{4}=\left[\begin{array}{ccc} -0 & 1 & 0\\ -1 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{5}=\left[\begin{array}{ccc} -1 & 0 & 0\\ -0 & -1 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{6}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & -1 & 0\\ -0 & 0 & 1\end{array}\right]\] - -\end_inset - - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -Hence, the Lie algebra -\begin_inset Formula $\afftwo$ -\end_inset - - is the vector space of -\begin_inset Formula $3\times3$ -\end_inset - - incremental affine transformations -\begin_inset Formula $\ahat$ -\end_inset - - parameterized by 6 parameters -\begin_inset Formula $\aa\in\mathbb{R}^{6}$ -\end_inset - -, with the mapping -\begin_inset Formula \[ -\aa\rightarrow\ahat\define\left[\begin{array}{ccc} -a_{5} & a_{4}-a_{3} & a_{1}\\ -a_{4}+a_{3} & -a_{5}-a_{6} & a_{2}\\ -0 & 0 & a_{6}\end{array}\right]\] - -\end_inset - -Note that -\begin_inset Formula $G_{5}$ -\end_inset - - and -\begin_inset Formula $G_{6}$ -\end_inset - - change the relative scale of -\begin_inset Formula $x$ -\end_inset - - and -\begin_inset Formula $y$ -\end_inset - - but without changing the determinant: -\begin_inset Formula \[ -e^{xG_{5}}=\exp\left[\begin{array}{ccc} -x & 0 & 0\\ -0 & -x & 0\\ -0 & 0 & 0\end{array}\right]=\left[\begin{array}{ccc} -e^{x} & 0 & 0\\ -0 & 1/e^{x} & 0\\ -0 & 0 & 1\end{array}\right]\] - -\end_inset - - -\begin_inset Formula \[ -e^{xG_{6}}=\exp\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & -x & 0\\ -0 & 0 & x\end{array}\right]=\left[\begin{array}{ccc} -1 & 0 & 0\\ -0 & 1/e^{x} & 0\\ -0 & 0 & e^{x}\end{array}\right]\] - -\end_inset - -It might be nicer to have the correspondence with scaling -\begin_inset Formula $x$ -\end_inset - - and -\begin_inset Formula $y$ -\end_inset - - more direct, by choosing -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula \[ -\mbox{ }G^{5}=\left[\begin{array}{ccc} -1 & 0 & 0\\ -0 & 0 & 0\\ -0 & 0 & -1\end{array}\right]\mbox{ }G^{6}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 1 & 0\\ -0 & 0 & -1\end{array}\right]\] - -\end_inset - -and hence -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit - -\begin_inset Formula \[ -e^{xG_{5}}=\exp\left[\begin{array}{ccc} -x & 0 & 0\\ -0 & 0 & 0\\ -0 & 0 & -x\end{array}\right]=\left[\begin{array}{ccc} -e^{x} & 0 & 0\\ -0 & 1 & 0\\ -0 & 0 & 1/e^{x}\end{array}\right]\] - -\end_inset - - -\begin_inset Formula \[ -e^{xG_{6}}=\exp\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & x & 0\\ -0 & 0 & -x\end{array}\right]=\left[\begin{array}{ccc} -1 & 0 & 0\\ -0 & e^{x} & 0\\ -0 & 0 & 1/e^{x}\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Section -2D Homographies -\end_layout - -\begin_layout Standard -When viewed as operations on images, represented by 2D projective space - -\begin_inset Formula $\mathcal{P}^{3}$ -\end_inset - -, 3D rotations are a special case of 2D homographies. - These are now treated, loosely based on the exposition in -\begin_inset CommandInset citation -LatexCommand cite -key "Mei06iros,Mei08tro" - -\end_inset - -. -\end_layout - -\begin_layout Subsection -Basics -\end_layout - -\begin_layout Standard -The Lie group -\begin_inset Formula $\SLthree$ -\end_inset - - is a subgroup of the general linear group -\begin_inset Formula $GL(3)$ -\end_inset - - of -\begin_inset Formula $3\times3$ -\end_inset - - invertible matrices with determinant -\begin_inset Formula $1$ -\end_inset - -. - The homographies generalize transformations of the 2D projective space, - and -\begin_inset Formula $\Afftwo\subset\SLthree$ -\end_inset - -. - -\end_layout - -\begin_layout Standard - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -We can extend -\begin_inset Formula $\afftwo$ -\end_inset - - to the Lie algebra -\begin_inset Formula $\slthree$ -\end_inset - - by adding two generators -\begin_inset Formula \[ -G^{7}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 0\\ -1 & 0 & 0\end{array}\right]\mbox{ }G^{8}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 0\\ -0 & 1 & 0\end{array}\right]\] - -\end_inset - - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -obtaining the vector space of -\begin_inset Formula $3\times3$ -\end_inset - - incremental homographies -\begin_inset Formula $\hhat$ -\end_inset - - parameterized by 8 parameters -\begin_inset Formula $\hh\in\mathbb{R}^{8}$ -\end_inset - -, with the mapping -\begin_inset Formula \[ -h\rightarrow\hhat\define\left[\begin{array}{ccc} -h_{5} & h_{4}-h_{3} & h_{1}\\ -h_{4}+h_{3} & -h_{5}-h_{6} & h_{2}\\ -h_{7} & h_{8} & h_{6}\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Tensor Notation -\end_layout - -\begin_layout Itemize -A homography between 2D projective spaces -\begin_inset Formula $A$ -\end_inset - - and -\begin_inset Formula $B$ -\end_inset - - can be written in tensor notation -\begin_inset Formula $H_{A}^{B}$ -\end_inset - - -\end_layout - -\begin_layout Itemize -Applying a homography is then a tensor contraction -\begin_inset Formula $x^{B}=H_{A}^{B}x^{A}$ -\end_inset - -, mapping points in -\begin_inset Formula $A$ -\end_inset - - to points in -\begin_inset Formula $B$ -\end_inset - -. -\end_layout - -\begin_layout Standard -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -The inverse of a homography can be found by contracting with two permutation - tensors: -\begin_inset Formula \[ -H_{B}^{A}=H_{A_{1}}^{B_{1}}H_{A_{2}}^{B_{2}}\epsilon_{B_{1}B_{2}B}\epsilon^{A_{1}A_{2}A}\] - -\end_inset - - -\end_layout - -\end_inset - - -\begin_inset Note Note -status collapsed - -\begin_layout Subsection -The Adjoint Map -\end_layout - -\begin_layout Plain Layout -The adjoint can be done using tensor notation. - Denoting an incremental homography in space -\begin_inset Formula $A$ -\end_inset - - as -\begin_inset Formula $\hhat_{A_{1}}^{A_{2}}$ -\end_inset - -, we have, for example for -\begin_inset Formula $G_{1}$ -\end_inset - - -\begin_inset Formula \begin{eqnarray*} -\hhat_{B_{1}}^{B_{2}}=\Ad{H_{A}^{B}}{\hhat_{A_{1}}^{A_{2}}} & = & H_{A_{2}}^{B_{2}}\hhat_{A_{1}}^{A_{2}}H_{B_{1}}^{A_{1}}\\ - & = & H_{A_{2}}^{B_{2}}\left[\begin{array}{ccc} -0 & 0 & 1\\ -0 & 0 & 0\\ -0 & 0 & 0\end{array}\right]H_{A_{2}}^{B_{2}}H_{A_{3}}^{B_{3}}\epsilon_{B_{1}B_{2}B_{3}}\epsilon^{A_{1}A_{2}A_{3}}\\ - & = & H_{1}^{B_{2}}H_{A_{2}}^{B_{2}}H_{A_{3}}^{B_{3}}\epsilon_{B_{1}B_{2}B_{3}}\epsilon^{3A_{2}A_{3}}\end{eqnarray*} - -\end_inset - -This does not seem to help. -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section* -Appendix: Proof of Property -\begin_inset CommandInset ref -LatexCommand ref -reference "proof1" - -\end_inset - - -\end_layout - -\begin_layout Standard -We can prove the following identity for rotation matrices -\begin_inset Formula $R$ -\end_inset - -, -\begin_inset Formula \begin{eqnarray} -R\Skew{\omega}R^{T} & = & R\Skew{\omega}\left[\begin{array}{ccc} -a_{1} & a_{2} & a_{3}\end{array}\right]\nonumber \\ - & = & R\left[\begin{array}{ccc} -\omega\times a_{1} & \omega\times a_{2} & \omega\times a_{3}\end{array}\right]\nonumber \\ - & = & \left[\begin{array}{ccc} -a_{1}(\omega\times a_{1}) & a_{1}(\omega\times a_{2}) & a_{1}(\omega\times a_{3})\\ -a_{2}(\omega\times a_{1}) & a_{2}(\omega\times a_{2}) & a_{2}(\omega\times a_{3})\\ -a_{3}(\omega\times a_{1}) & a_{3}(\omega\times a_{2}) & a_{3}(\omega\times a_{3})\end{array}\right]\nonumber \\ - & = & \left[\begin{array}{ccc} -\omega(a_{1}\times a_{1}) & \omega(a_{2}\times a_{1}) & \omega(a_{3}\times a_{1})\\ -\omega(a_{1}\times a_{2}) & \omega(a_{2}\times a_{2}) & \omega(a_{3}\times a_{2})\\ -\omega(a_{1}\times a_{3}) & \omega(a_{2}\times a_{3}) & \omega(a_{3}\times a_{3})\end{array}\right]\nonumber \\ - & = & \left[\begin{array}{ccc} -0 & -\omega a_{3} & \omega a_{2}\\ -\omega a_{3} & 0 & -\omega a_{1}\\ --\omega a_{2} & \omega a_{1} & 0\end{array}\right]\nonumber \\ - & = & \Skew{R\omega}\label{proof1}\end{eqnarray} - -\end_inset - -where -\begin_inset Formula $a_{1}$ -\end_inset - -, -\begin_inset Formula $a_{2}$ -\end_inset - -, and -\begin_inset Formula $a_{3}$ -\end_inset - - are the -\emph on -rows -\emph default - of -\begin_inset Formula $R$ -\end_inset - -. - Above we made use of the orthogonality of rotation matrices and the triple - product rule: -\begin_inset Formula \[ -a(b\times c)=b(c\times a)=c(a\times b)\] - -\end_inset - -Similarly, without proof -\begin_inset CommandInset citation -LatexCommand cite -after "Lemma 2.3" -key "Murray94book" - -\end_inset - -: -\begin_inset Formula \[ -R(a\times b)=Ra\times Rb\] - -\end_inset - - -\end_layout - -\begin_layout Section* -Appendix: Alternative Generators for -\begin_inset Formula $\slthree$ -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset CommandInset citation -LatexCommand cite -key "Mei06iros" - -\end_inset - - uses the following generators for -\begin_inset Formula $\slthree$ -\end_inset - -: -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula \[ -G^{1}=\left[\begin{array}{ccc} -0 & 0 & 1\\ -0 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{2}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 1\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{3}=\left[\begin{array}{ccc} -0 & 1 & 0\\ -0 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\] - -\end_inset - - -\begin_inset Formula \[ -G^{4}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -1 & 0 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{5}=\left[\begin{array}{ccc} -1 & 0 & 0\\ -0 & -1 & 0\\ -0 & 0 & 0\end{array}\right]\mbox{ }G^{6}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & -1 & 0\\ -0 & 0 & 1\end{array}\right]\] - -\end_inset - - -\begin_inset Formula \[ -G^{7}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 0\\ -1 & 0 & 0\end{array}\right]\mbox{ }G^{8}=\left[\begin{array}{ccc} -0 & 0 & 0\\ -0 & 0 & 0\\ -0 & 1 & 0\end{array}\right]\] - -\end_inset - - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit -We choose to use a different linear combination as the basis. -\end_layout - -\begin_layout Standard -\begin_inset CommandInset bibtex -LatexCommand bibtex -bibfiles "../../../papers/refs" -options "plain" - -\end_inset - - -\end_layout - -\end_body -\end_document diff --git a/doc/LieGroups.pdf b/doc/LieGroups.pdf deleted file mode 100644 index 1aa0c934e..000000000 Binary files a/doc/LieGroups.pdf and /dev/null differ diff --git a/doc/images/circular.pdf b/doc/images/circular.pdf deleted file mode 100644 index b0f43f649..000000000 Binary files a/doc/images/circular.pdf and /dev/null differ diff --git a/doc/images/circular.png b/doc/images/circular.png deleted file mode 100644 index 71c346a8e..000000000 Binary files a/doc/images/circular.png and /dev/null differ diff --git a/doc/images/gtsam-structure.graffle b/doc/images/gtsam-structure.graffle deleted file mode 100644 index 22eb72dc3..000000000 --- a/doc/images/gtsam-structure.graffle +++ /dev/null @@ -1,1302 +0,0 @@ - - - - - ActiveLayerIndex - 0 - ApplicationVersion - - com.omnigroup.OmniGraffle - 138.14.0.129428 - - AutoAdjust - - BackgroundGraphic - - Bounds - {{0, 0}, {559.29, 782.89}} - Class - SolidGraphic - ID - 2 - Style - - fill - - GradientColor - - w - 0.666667 - - - shadow - - Draws - NO - - stroke - - Draws - NO - - - - CanvasOrigin - {0, 0} - CanvasSize - {559.29, 782.89} - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2010-07-13 00:07:47 -0400 - Creator - Frank Dellaert - DisplayScale - 1 0/72 in = 1 0/72 in - FileType - flat - GraphDocumentVersion - 6 - GraphicsList - - - Class - LineGraphic - Head - - ID - 19 - - ID - 35 - Points - - {191.649, 522.933} - {191.649, 558.208} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 34 - - - - Bounds - {{156.649, 558.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 19 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 tests} - - - - Class - Group - Graphics - - - Class - LineGraphic - Head - - ID - 30 - - ID - 22 - Points - - {220.827, 437.595} - {201.125, 473.266} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 25 - - - - Class - LineGraphic - Head - - ID - 28 - - ID - 23 - Points - - {198.977, 245.588} - {219.976, 281.282} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 33 - - - - Class - LineGraphic - Head - - ID - 25 - - ID - 24 - Points - - {234.015, 373.654} - {229.931, 409.211} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 27 - - - - Bounds - {{193.649, 409.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 25 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 nonlinear} - - - - Class - LineGraphic - Head - - ID - 27 - - ID - 26 - Points - - {230.126, 309.655} - {233.82, 345.213} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 28 - - - - Bounds - {{200.649, 345.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 27 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 linear} - - - - Bounds - {{193.649, 281.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 28 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 inference} - - - - Class - LineGraphic - Head - - ID - 30 - - ID - 29 - Points - - {152.743, 373.628} - {188.492, 473.239} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 32 - - - - Bounds - {{158.649, 473.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 30 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 slam} - - - - Class - LineGraphic - Head - - ID - 32 - - ID - 31 - Points - - {185.872, 245.631} - {152.363, 345.234} - - Style - - stroke - - HeadArrow - FilledArrow - LineType - 1 - TailArrow - 0 - - - Tail - - ID - 33 - - - - Bounds - {{112.649, 345.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 32 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 geometry} - - - - Bounds - {{155.649, 217.708}, {70, 27.449}} - Class - ShapedGraphic - ID - 33 - Shape - Rectangle - Text - - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural - -\f0\fs24 \cf0 base} - - - - ID - 21 - - - Bounds - {{86.649, 196.433}, {210, 326}} - Class - ShapedGraphic - ID - 34 - Shape - Rectangle - Style - - Text - - Align - 0 - Text - {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320 -{\fonttbl\f0\fswiss\fcharset0 Helvetica;} -{\colortbl;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural - -\f0\fs24 \cf0 gtsam} - - TextPlacement - 0 - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 3 - KeepToScale - - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - Animate - NO - AutoLayout - 2 - LineLength - 0.4643835723400116 - circoMinDist - 18 - circoSeparation - 0.0 - layoutEngine - dot - neatoSeparation - 0.0 - twopiSeparation - 0.0 - - LinksVisible - NO - MagnetsVisible - NO - MasterSheets - - ModificationDate - 2010-07-13 00:17:24 -0400 - Modifier - Frank Dellaert - NotesVisible - NO - Orientation - 2 - OriginVisible - NO - OutlineStyle - Basic - PageBreaks - NO - PrintInfo - - NSBottomMargin - - float - 41 - - NSLeftMargin - - float - 18 - - NSPaperSize - - size - {595.29, 841.89} - - NSRightMargin - - float - 18 - - NSTopMargin - - float - 18 - - - PrintOnePage - - QuickLookPreview - - JVBERi0xLjMKJcTl8uXrp/Og0MTGCjUgMCBvYmoKPDwgL0xlbmd0aCA2IDAgUiAvRmls - dGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAGlV8tuWzcQ3d+v4NJemCZn+NzWbYF6 - 1dQCuii6cAW5kSHZjeQW6N/3DHl5TclXUoNYSOQwnPeZM8Mv6pP6ogw+3mcVE6ndSv2q - XtTt3d6q5V7Z8tkv1Y3RXhnN2RjrglzXVCR0yhAantTtz6vdcvXX29+PG7VbQy0xFdXs - kopeB5dyVuS8dj6q5Vbd/rS16vvX4kKuV71R1jlczcoTaZusH+pNmrlpbLnJ2ZWbo865 - my6WmxTCJZ2Jyk3n0yWdKR9YP+PnqJPZXNKJ5EjsiHvGz9tfVpvHt/U/q7vXzetuvV29 - 7dZLSXUKkCrJDaYkl6xRTEGK+YQC3is7PNeS3j2Ukhj1cIcK2fKPG/lC7aWSSPakzeag - HbOq2rzO+JFSP6BiwAcJPowCNjpFNteaOOJW5u8Wytbq3uD7xhqDv1xUi+1w+6PVqLha - PKnf1NWf14IyUldv10AavveP7WR7rX5Xi3v1w6LaPsSm9TVtnqOOTF5Foyhqh5zEoeSg - 87APtQmShaBJB4KSvINIh+NITamV9/ZUpKyNNdEph1hVH+tw9UeLbApxvzofox2BafJX - xjgKMrD11TGOfXO6muRPxzjVE5HVwr62X7bTUav17t8+/Jl6SX/Z5HWKRIVFAluncIbi - ewtkMuM/vUlq0+pWUCLkVlBqPekcgHHHGRULaRDhpDkA484FbRJaZoMzZDoGj7MIzHtR - +LmcHkjD9BMU3+PP8zDjr7TSZJId2oHBh51J5qCTwKMzyezQhY6GA5OdtCDSlg/QKN4L - XRDo4hj3U+8PVj33HXqI/6rARb6MDXR6H6fNXI3nidCPOx15DDHHj/hHa2+uh4qJqQEO - evxMQqNjpxgeB8QtCQUowCdpcIF1JuNPAiBFAQgptmhZzqkIo8bRepxlnRNGGqoBKmRC - ERi0kH2gCoAZ6QkAJxM8Cg0uCkvAtvg7mnQBgDTRdiaVC05n5hFzzWQn/TD0ABhrUOon - xBcQBH7SRH8TDICZWRiUtmqlFBwJDc6qOSDDI9onGoEEjzHdRekRGAhTHf1Fc2BYN1p4 - ab88jRNg1VCymwhjurM8T5hkKj+7Rpgfgjo7Gpr4RJsfxPsBMcyMQgIfSXcekqfRxgAG - C3RvPxSRnYg1SSZFPxWvNuuX1ePuWi2e6+w70Rckq4VklxFt8NC0lfVLxxziIMTIwZ/s - C2LpJZCTEKMPkYswpgXYqZBgYicsRZR1soRGAzGSdaLwM8x8lL7YF01oEGpjotibFH+N - 98LFzWQh9xBLDJ3JTnq2L0rxvr0vCoS+qS8Y6/J7X8xjoHSIR4jH68LVy+vLBxyA1mWu - He1uhPlhrOfKj94J3xBjyQqgRc5Zc/RCZ2Mv1wE5jAOygMhFXMS2DhwIuRaFiF9xYm0j - VRwkzEpjy1nysfJjkx466f+BA+BWTDoTBQf5wCT8jTYGDEPhl2oSZ4ap8mMz2UvXAYmN - 9xzdJXB+AEliJfIpyRYBOIPq8S6hiK5xmcckEcaCsdg4vGGN+77cjdo76waPORKClZlB - 2LI44hZ40OaxM2Zkz2ZEaHMySFHeF2gyOasG4ZzVSIVMjNEgRacplpmHvmgGmyw2nAv5 - kC2FyOiEFnRYn30GPnBksO5bizPMo2AMowaiiQxpA5ooI5RSKPVCzNi8I86w0OAxJt5J - thJaWMZqdCC8QhWjNAYr4qjSZxNSvGsmZQgGwwWVzaTDg854EwUizaSsAdZhBvYmVSdd - UyJbVNmh5PGEJxceO8c7VB0Q5f00j6a641UFHsvYuf16bkS01xJeWEIPou5obMryHtF+ - PScM9bnUNudpMu7byf7CKl3cLg+1FAZ5Z2PjQNGrNxj/mB+ahe+OiKIwjuSsynogJ6CB - sD2JsDzbkx+EMcqZLFKyFUBPd4ZNekb6LArqiiLvSvHNh+rbu8ne38lkF8O7yaGTFhR8 - +g8FPYzxCmVuZHN0cmVhbQplbmRvYmoKNiAwIG9iagoxNDU4CmVuZG9iagozIDAgb2Jq - Cjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgNCAwIFIgL1Jlc291cmNlcyA3IDAgUiAvQ29u - dGVudHMgNSAwIFIgL01lZGlhQm94IFswIDAgNTU5LjI5IDc4Mi44OV0KPj4KZW5kb2Jq - CjcgMCBvYmoKPDwgL1Byb2NTZXQgWyAvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAv - SW1hZ2VJIF0gL0NvbG9yU3BhY2UgPDwgL0NzMSA4IDAgUgovQ3MyIDEzIDAgUiA+PiAv - Rm9udCA8PCAvRjEuMCAxNCAwIFIgPj4gL1hPYmplY3QgPDwgL0ltMSA5IDAgUiAvSW0y - IDExIDAgUgo+PiA+PgplbmRvYmoKOSAwIG9iago8PCAvTGVuZ3RoIDEwIDAgUiAvVHlw - ZSAvWE9iamVjdCAvU3VidHlwZSAvSW1hZ2UgL1dpZHRoIDQ2NCAvSGVpZ2h0IDY5NiAv - SW50ZXJwb2xhdGUKdHJ1ZSAvQ29sb3JTcGFjZSAxNSAwIFIgL0ludGVudCAvUGVyY2Vw - dHVhbCAvU01hc2sgMTYgMCBSIC9CaXRzUGVyQ29tcG9uZW50CjggL0ZpbHRlciAvRmxh - dGVEZWNvZGUgPj4Kc3RyZWFtCngB7dCBAAAAAMOg+VNf4QCFUGHAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwY - MGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAED - BgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDA - gAEDBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAwDswyVIAAQplbmRzdHJlYW0KZW5kb2Jq - CjEwIDAgb2JqCjQyNDgKZW5kb2JqCjExIDAgb2JqCjw8IC9MZW5ndGggMTIgMCBSIC9U - eXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggMTg0IC9IZWlnaHQgMTAw - IC9JbnRlcnBvbGF0ZQp0cnVlIC9Db2xvclNwYWNlIDE1IDAgUiAvSW50ZW50IC9QZXJj - ZXB0dWFsIC9TTWFzayAxOCAwIFIgL0JpdHNQZXJDb21wb25lbnQKOCAvRmlsdGVyIC9G - bGF0ZURlY29kZSA+PgpzdHJlYW0KeAHt0IEAAAAAw6D5Ux/khVBhwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYM - GDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIAB - AwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBg - wIABAwYMGDBgwIABAwYMGDBgwIABA48DA9egAAEKZW5kc3RyZWFtCmVuZG9iagoxMiAw - IG9iagoyNjMKZW5kb2JqCjE2IDAgb2JqCjw8IC9MZW5ndGggMTcgMCBSIC9UeXBlIC9Y - T2JqZWN0IC9TdWJ0eXBlIC9JbWFnZSAvV2lkdGggNDY0IC9IZWlnaHQgNjk2IC9Db2xv - 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 - 5vWrF8uLT+Ye3J4YuzR4KmJ+YPmUp/nrskSnx5ezcj9X8fyXzj++wFvs+Zf/x8namDjz - 61vz66HyL+qav+48NmDu5693Zh49XVp++erN23/8z6ICZoG3b169XF56+mjmzq/mfg4c - 6/y6ue6LcvMLIvML3LgYebL9SyJPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5 - sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypP - NjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJ - Job7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZ - xHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSeb - GO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQT - w33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxi - uK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M - 95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonh - vvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHc - V554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7 - yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBf - eeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4r - T7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33l - ifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK88 - 8T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un - 3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE - +7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554 - H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPv - w5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ9 - 2FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wP - WypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdh - S+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5s - qTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3oct - lSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl - 8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZU - nmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bK - k00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5 - sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypP - NjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJ - Job7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZ - xHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSeb - GO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQT - w33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxi - uK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M - 95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonh - vvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHc - V554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7 - yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBf - eeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4r - T7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33l - ifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK88 - 8T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un - 3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE - +7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554 - H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPv - w5bKk00M95Un3octlSebGO4rT7wPWypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ9 - 2FJ5sonhvvLE+7Cl8mQTw33lifdhS+XJJob7yhPvw5bKk00M95Un3octlSebGO4rT7wP - WypPNjHcV554H7ZUnmxiuK888T5sqTzZxHBfeeJ92FJ5sonhvvLE+7Cl8mQTw33lifdh - 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 - rTtamhvr67ZUhyqChfmG03p7xn/saT1wzQV1GtDM7LyCkvJNoepwTd22+obGpqamZh0b - LGAgGhvqt9XVhKtDm8pLCvKyMw2n01zPjx63a1YeuPHmiZtq3dC8QFFpeUVlqGrzl+Ga - WnPqdP7xBSyHmvCXm6tClRXlpUUB62HrSTVP29Wup/E0FzQh0bEC6s/NDxQWB8s2VlRW - hkKhL3RssYChqKys2FgWLC4M5Of6VzgdiQnmen74+jR/GWq+iAxokiPF5Vnvy/Tn5uUH - CoqKS0qDwbKych0bLFBWFgyWlhQXFQTy83L9mb71HleKw/ysEvvR15D1d9vmgsbExZsb - 6nS507y+DH92jjHN3xAo0LHNAoEN+cYyJ9uf4fOmuV1Oczutp+0q1/M9qHnkJpsr6k5b - b0gzs/xGNSdXxyYL5BhJf1amwVxvNFMcyeZh+ynONWtXbmhcfOKKaKrHY0y96ek+X4aO - TRbw+dLTvcbS40ld0TSfQiucH/zw+f7/SrQCGhtnrqgRdThTXK5Ut9ujY6sF3O5UlyvF - 6TB307qc5t25bu3qnOaJa26o9VVkvUYTk5INqsPpdKbo2GYBw2FQkpOTDKa5m5bmpzmt - j6J3oobUmBrUlZOkY5MF3oMkWJZxsX+rufKZa4mui4mJibVQdWy5gKGMsa4mvJvv36LW - JV0xtf55c8z/Usc2C7wzWflPw/S/ZP/JfzH/vI5NF/hP/PTPaAEtoAW0gBbQAlpAC2gB - /gX+B05tLvoKZW5kc3RyZWFtCmVuZG9iagoxNyAwIG9iago2NTUwCmVuZG9iagoxOCAw - IG9iago8PCAvTGVuZ3RoIDE5IDAgUiAvVHlwZSAvWE9iamVjdCAvU3VidHlwZSAvSW1h - Z2UgL1dpZHRoIDE4NCAvSGVpZ2h0IDEwMCAvQ29sb3JTcGFjZQovRGV2aWNlR3JheSAv - SW50ZXJwb2xhdGUgdHJ1ZSAvQml0c1BlckNvbXBvbmVudCA4IC9GaWx0ZXIgL0ZsYXRl - RGVjb2RlID4+CnN0cmVhbQp4Ae2b+VeS6RvGrdxARBAERRQFXAAVUQrFUgwzUcxdcVwG - Qx1pMKqRkaPlkilFrpnjMu7jMuo4Wk46TXXmX/vezwuVC1Jzjt/HfuD6Jc/hxPvx6n5f - 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 - TS+So592fgU1op5G9NOgWuds1p2CDSMOM04064g+IAn1AYlGILTzcIu4NJn0VX1AdHMS - 5KgU6OP7uYDprEPi/gPql0T/kqiOnmq28wPUWdJFfddzL7wCwse665FU1fHP+s/oyPbD - wtkxPnxd+BmM/Brow78L+ivnqcMsnp89Dngc8DjgceCoA/8DzflMvgplbmRzdHJlYW0K - ZW5kb2JqCjE5IDAgb2JqCjI4MjgKZW5kb2JqCjIwIDAgb2JqCjw8IC9MZW5ndGggMjEg - MCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl - ID4+CnN0cmVhbQp4AYVUz2sTQRT+Nm6p0CIIWmsOsniQIklZq2hF1Db9EWJrDNsftkWQ - ZDNJ1m426+4mtaWI5OLRKt5F7aEH/4AeevBkL0qFWkUo3qsoYqEXLfHNbky2perAzn7z - 3jfvfW923wANctI09YAE5A3HUqIRaWx8Qmr8iACOoglBNCVV2+xOJAZBg3P5e+fYeg+B - W1bDe/t3snetmtK2mgeE/UDgR5rZKrDvF3EKWRICiDzfoSnHdAjf49jy7I85Tnl4wbUP - Kz3EWSJ8QDUtzn9NuFPNJdNAg0g4lPVxUj6c14uU1x0HaW5mxsgQvU+QprvM7qtioZxO - 9g6QvZ30fk6z3j7CIcILGa0/RriNnvWM1T/iYeGk5sSGPRwYNfT4YBW3Gqn4NcIUXxBN - J6JUcdkuDfGYrv1W8kqCcJA4ymRhgHNaSE/XTG74uocFfSbXE6/id1ZR4XmPE2fe1N3v - RdoCrzAOHQwaDJoNSFAQRQRhmLBQQIY8GjE0snI/I6sGG5N7MnUkart0YkSxQXs23D23 - UaTdPP4oInGUQ7UIkvxB/iqvyU/lefnLXLDYVveUrZuauvLgO8XlmbkaHtfTyONzTV58 - ldR2k1dHlqx5erya7Bo/7FeXMeaCNY/Ec7D78S1flcyXKYwUxeNV8+pLhHVaMTffn2x/ - Oz3iLs8utdZzrYmLN1abl2f9akj77qq8k+ZV+U9e9fH8Z83EY+IpMSZ2iuchiZfFLvGS - 2EurC+JgbccInZWGKdJtkfok1WBgmrz1L10/W3i9Rn8M9VGUGczSVIn3f8IqZDSduQ5v - +o/bx/wX5PeK558oAi9s4MiZum1Tce8QoWWlbnOuAhe/0X3wtm5ro344/ARYPKsWrVI1 - nyC8ARx2h3oe6CmY05aWzTlShyyfk7rpymJSzFDbQ1JS1yXXZUsWs5lVYul22JnTHW4c - oTlC98SnSmWT+q/xEbD9sFL5+axS2X5OGtaBl/pvwLz9RQplbmRzdHJlYW0KZW5kb2Jq - CjIxIDAgb2JqCjczNwplbmRvYmoKOCAwIG9iagpbIC9JQ0NCYXNlZCAyMCAwIFIgXQpl - bmRvYmoKMjIgMCBvYmoKPDwgL0xlbmd0aCAyMyAwIFIgL04gMSAvQWx0ZXJuYXRlIC9E - ZXZpY2VHcmF5IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AYVST0gUURz+ - zTYShIhBhXiIdwoJlSmsrKDadnVZlW1bldKiGGffuqOzM9Ob2TXFkwRdojx1D6JjdOzQ - oZuXosCsS9cgqSAIPHXo+83s6iiEb3k73/v9/X7fe0RtnabvOylBVHNDlSulp25OTYuD - HylFHdROWKYV+OlicYyx67mSv7vX1mfS2LLex7V2+/Y9tZVlYCHqLba3EPohkWYAH5mf - KGWAs8Adlq/YPgE8WA6sGvAjogMPmrkw09GcdKWyLZFT5qIoKq9iO0mu+/m5xr6LtYmD - /lyPZtaOvbPqqtFM1LT3RKG8D65EGc9fVPZsNRSnDeOcSEMaKfKu1d8rTMcRkSsQSgZS - NWS5n2pOnXXgdRi7XbqT4/j2EKU+yWCoibXpspkdhX0AdirL7BDwBejxsmIP54F7Yf9b - UcOTwCdhP2SHedatH/YXrlPge4Q9NeDOFK7F8dqKH14tAUP3VCNojHNNxNPXOXOkiO8x - 1BmY90Y5pgsxd5aqEzeAO2EfWapmCrFd+67qJe57AnfT4zvRmzkLXKAcSXKxFdkU0DwJ - WBR9i7BJDjw+zh5V4HeomMAcuYnczSj3HtURG2ejUoFWeo1Xxk/jufHF+GVsGM+Afqx2 - 13t8/+njFXXXtj48+Y163DmuvZ0bVWFWcWUL3f/HMoSP2Sc5psHToVlYa9h25A+azEyw - DCjEfwU+l/qSE1Xc1e7tuEUSzFA+LGwluktUbinU6j2DSqwcK9gAdnCSxCxaHLhTa7o5 - eHfYInpt+U1XsuuG/vr2evva8h5tyqgpKBPNs0RmlLFbo+TdeNv9ZpERnzg6vue9ilrJ - /klFED+FOVoq8hRV9FZQ1sRvZw5+G7Z+XD+l5/VB/TwJPa2f0a/ooxG+DHRJz8JzUR+j - SfCwaSHiEqCKgzPUTlRjjQPiKfHytFtkkf0PQBn9ZgplbmRzdHJlYW0KZW5kb2JqCjIz - IDAgb2JqCjcwNAplbmRvYmoKMTMgMCBvYmoKWyAvSUNDQmFzZWQgMjIgMCBSIF0KZW5k - b2JqCjI0IDAgb2JqCjw8IC9MZW5ndGggMjUgMCBSIC9OIDMgL0FsdGVybmF0ZSAvRGV2 - aWNlUkdCIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlID4+CnN0cmVhbQp4AdWWd1gTSR/HZ3fT - Cy0QWoDQe+8gvQYQkCqISkgooYQQioDYkMMTPAsqImABPRBR8CyAnAURxcIhYK8X5BBQ - z8OCqKi5Dbx4/vHef+8/7+yzM5/9zm9/Mzsz+zxfACg9bIEgHZYBIIOfIwzz82Qujoll - 4h8AHGAAMpAFMmxOtsAjNDQI/Gt5fwdAks6bppJc/xr23ztkuYnZHACgULQ7gZvNyUD5 - JMpfOQJhDgCwhAdW5AhQRkpQlheiE0S5SsLJc3xEwglz3DUbExHmhcbcAoBAYbOFyQCQ - RajOzOMko3koKAILPpfHR9kCZVdOCpuLsgBlk4yMTAnXomyQ8F2e5O+YzU74lpPNTv7G - c9+CvokO7M3LFqSzC2Yf/pdVRnouul6zRQ6tKfz04CC0paP3OJftHTjPgvTZPZvVE/mR - 4fM6PyE4ZJ6ThL5h8yzI8fyOQyPm9cIUr+B5Tsz2+ZYnlR0g2bPZ/MLcsMh5zs4L95nn - wpSI6HnmJnp/05N4vqx5nZfD+jZWWmbgtzkAb+ADgtCLCayAxezlC9ARcxLz0T0EwCtT - UCDkJafkMD3QU5dowmTxOWYmTCsLS8mW/v8Uyf82N9u3N2b/I0hJcpT/o+UvAcBdGT3L - 0/9oUej53zsEgOKtfzQDTQA0FQBoT+DkCvPm8mEkDRaQgDSQB8pAHWgDA2CKrqYdcAbu - 6OoGgBAQAWLAMsABKSADCMEKUATWgVJQDraCnaAa7AMHwCFwFBwH7eAMuAAug+tgANwG - D4EIjIIXYBK8BzMQBOEhKkSDlCENSBcyhqwgB8gV8oGCoDAoBoqHkiE+lAsVQeuhcqgC - qobqoCboF+g0dAG6Cg1C96FhaAJ6A32CEZgCy8NqsB5sDjvAHnAgHAEvhZPhLLgQLoE3 - w1VwPXwEboMvwNfh27AIfgFPIQAhI3REEzFFHBAvJASJRZIQIbIaKUMqkXqkBelEepGb - iAh5iXzE4DA0DBNjinHG+GMiMRxMFmY1ZhOmGnMI04bpwdzEDGMmMV+xVCwDa4x1wrKw - i7HJ2BXYUmwltgF7CnsJexs7in2Pw+HoOH2cPc4fF4NLxa3EbcLtwbXiunCDuBHcFB6P - V8Yb413wIXg2Pgdfit+NP4I/jx/Cj+I/EMgEDYIVwZcQS+ATigmVhMOEc4QhwhhhhihD - 1CU6EUOIXGIBcQvxILGTeIM4SpwhyZL0SS6kCFIqaR2pitRCukR6RHpLJpO1yI7kRWQe - eS25inyMfIU8TP5IkaMYUbwocZRcymZKI6WLcp/ylkql6lHdqbHUHOpmahP1IvUJ9YMU - TcpMiiXFlVojVSPVJjUk9UqaKK0r7SG9TLpQulL6hPQN6ZcyRBk9GS8ZtsxqmRqZ0zJ3 - ZaZkabKWsiGyGbKbZA/LXpUdl8PL6cn5yHHlSuQOyF2UG6EhNG2aF41DW087SLtEG5XH - yevLs+RT5cvlj8r3y08qyCnYKEQp5CvUKJxVENERuh6dRU+nb6Efp9+hf1JUU/RQTFTc - qNiiOKQ4raSq5K6UqFSm1Kp0W+mTMlPZRzlNeZtyu/JjFYyKkcoilRUqe1UuqbxUlVd1 - VuWolqkeV33AgBlGjDDGSsYBRh9jSk1dzU9NoLZb7aLaS3W6urt6qvoO9XPqExo0DVcN - nsYOjfMaz5kKTA9mOrOK2cOc1GRo+mvmatZp9mvOaOlrRWoVa7VqPdYmaTtoJ2nv0O7W - ntTR0FmoU6TTrPNAl6jroJuiu0u3V3daT18vWm+DXrveuL6SPku/UL9Z/5EB1cDNIMug - 3uCWIc7QwTDNcI/hgBFsZGuUYlRjdMMYNrYz5hnvMR40wZo4mvBN6k3umlJMPUzzTJtN - h83oZkFmxWbtZq/MdcxjzbeZ95p/tbC1SLc4aPHQUs4ywLLYstPyjZWRFceqxuqWNdXa - 13qNdYf1axtjm0SbvTb3bGm2C2032HbbfrGztxPatdhN2OvYx9vX2t91kHcIddjkcMUR - 6+jpuMbxjONHJzunHKfjTn85mzqnOR92Hl+gvyBxwcEFIy5aLmyXOheRK9M13nW/q8hN - 043tVu/21F3bneve4D7mYeiR6nHE45WnhafQ85TntJeT1yqvLm/E28+7zLvfR84n0qfa - 54mvlm+yb7PvpJ+t30q/Ln+sf6D/Nv+7LDUWh9XEmgywD1gV0BNICQwPrA58GmQUJAzq - XAgvDFi4feGjYN1gfnB7CAhhhWwPeRyqH5oV+usi3KLQRTWLnoVZhhWF9YbTwpeHHw5/ - H+EZsSXiYaRBZG5kd5R0VFxUU9R0tHd0RbRosfniVYuvx6jE8GI6YvGxUbENsVNLfJbs - XDIaZxtXGndnqf7S/KVXl6ksS192drn0cvbyE/HY+Oj4w/Gf2SHsevZUAiuhNmGS48XZ - xXnBdefu4E4kuiRWJI4luSRVJI0nuyRvT55IcUupTHnJ8+JV816n+qfuS51OC0lrTBOn - R6e3ZhAy4jNO8+X4afyeTPXM/MxBgbGgVCDKcsramTUpDBQ2ZEPZS7M7cuRRY9OXa5D7 - Q+5wnmteTd6HFVErTuTL5vPz+wqMCjYWjBX6Fv68ErOSs7K7SLNoXdHwKo9Vdauh1Qmr - u9dorylZM7rWb+2hdaR1aet+K7Yorih+tz56fWeJWsnakpEf/H5oLpUqFZbe3eC8Yd+P - mB95P/ZvtN64e+PXMm7ZtXKL8sryz5s4m679ZPlT1U/izUmb+7fYbdm7FbeVv/XONrdt - hypkKworRrYv3N62g7mjbMe7nct3Xq20qdy3i7Qrd5eoKqiqY7fO7q27P1enVN+u8axp - rWXUbqyd3sPdM7TXfW/LPrV95fs+7eftv1fnV9dWr1dfeQB3IO/As4NRB3t/dvi5qUGl - obzhSyO/UXQo7FBPk31T02HG4S3NcHNu88SRuCMDR72PdrSYttS10lvLj4Fjucee/xL/ - y53jgce7TzicaDmpe7L2FO1UWRvUVtA22Z7SLuqI6Rg8HXC6u9O589SvZr82ntE8U3NW - 4eyWc6RzJefE5wvPT3UJul5eSL4w0r28++HFxRdv9Szq6b8UeOnKZd/LF3s9es9fcbly - 5qrT1dPXHK61X7e73tZn23fqN9vfTvXb9bfdsL/RMeA40Dm4YPDckNvQhZveNy/fYt26 - fjv49uCdyDv37sbdFd3j3hu/n37/9YO8BzMP1z7CPip7LPO48gnjSf3vhr+3iuxEZ4e9 - h/uehj99OMIZefFH9h+fR0ueUZ9VjmmMNY1bjZ+Z8J0YeL7k+egLwYuZl6V/yv5Z+8rg - 1cm/3P/qm1w8Ofpa+Fr8ZtNb5beN72zedU+FTj15n/F+Zrrsg/KHQx8dPvZ+iv40NrPi - M/5z1RfDL51fA78+EmeIxQK2kD3rBRC0hpOSAHjTCAA1BgDaAACkrjk/PBuBOvhh/3n6 - N57zzLNRdgDUuQMgsXdBXQDsQls99JmBthJbiFo6eO0/N6pISnaStdUsQBQV1Jp0icVv - xADg4wH40i8Wz1SJxV8qUa/zDoDzwXM+XBItg/r7/YiFjW9QZ6bb7OvfV38DJafpNwpl - bmRzdHJlYW0KZW5kb2JqCjI1IDAgb2JqCjI2NjMKZW5kb2JqCjE1IDAgb2JqClsgL0lD - Q0Jhc2VkIDI0IDAgUiBdCmVuZG9iago0IDAgb2JqCjw8IC9UeXBlIC9QYWdlcyAvTWVk - aWFCb3ggWzAgMCA2MTIgNzkyXSAvQ291bnQgMSAvS2lkcyBbIDMgMCBSIF0gPj4KZW5k - b2JqCjI2IDAgb2JqCjw8IC9UeXBlIC9DYXRhbG9nIC9PdXRsaW5lcyAyIDAgUiAvUGFn - ZXMgNCAwIFIgL1ZlcnNpb24gLzEuNCA+PgplbmRvYmoKMiAwIG9iago8PCAvTGFzdCAy - NyAwIFIgL0ZpcnN0IDI4IDAgUiA+PgplbmRvYmoKMjggMCBvYmoKPDwgL1BhcmVudCAy - OSAwIFIgL0NvdW50IDAgL0Rlc3QgWyAzIDAgUiAvWFlaIDAgNzgyLjg5IDAgXSAvVGl0 - bGUgKENhbnZhcyAxKQo+PgplbmRvYmoKMjkgMCBvYmoKPDwgPj4KZW5kb2JqCjI3IDAg - b2JqCjw8IC9QYXJlbnQgMjkgMCBSIC9Db3VudCAwIC9EZXN0IFsgMyAwIFIgL1hZWiAw - IDc4Mi44OSAwIF0gL1RpdGxlIChDYW52YXMgMSkKPj4KZW5kb2JqCjMwIDAgb2JqCjw8 - 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 - dCAtMjMwIC9GbGFncyAzMgovRm9udEJCb3ggWy05NTEgLTQ4MSAxNDQ1IDExMjJdIC9G - b250TmFtZSAvR0lTVklCK0hlbHZldGljYSAvSXRhbGljQW5nbGUgMAovU3RlbVYgMCAv - TWF4V2lkdGggMTUwMCAvWEhlaWdodCA2MzcgL0ZvbnRGaWxlMiAzMCAwIFIgPj4KZW5k - b2JqCjMzIDAgb2JqClsgNTU2IDU1NiA1MDAgMCA1NTYgMjc4IDU1NiAwIDIyMiAwIDAg - MjIyIDgzMyA1NTYgNTU2IDAgMCAzMzMgNTAwIDI3OCAwIDAKMCAwIDUwMCBdCmVuZG9i - agoxNCAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHJ1ZVR5cGUgL0Jhc2VG - b250IC9HSVNWSUIrSGVsdmV0aWNhIC9Gb250RGVzY3JpcHRvcgozMiAwIFIgL1dpZHRo - cyAzMyAwIFIgL0ZpcnN0Q2hhciA5NyAvTGFzdENoYXIgMTIxIC9FbmNvZGluZyAvTWFj - Um9tYW5FbmNvZGluZwo+PgplbmRvYmoKMzQgMCBvYmoKKE1hYyBPUyBYIDEwLjYuNCBR - dWFydHogUERGQ29udGV4dCkKZW5kb2JqCjM1IDAgb2JqCihEOjIwMTAwNzEzMDQxODIy - WjAwJzAwJykKZW5kb2JqCjEgMCBvYmoKPDwgL1Byb2R1Y2VyIDM0IDAgUiAvQ3JlYXRp - b25EYXRlIDM1IDAgUiAvTW9kRGF0ZSAzNSAwIFIgPj4KZW5kb2JqCnhyZWYKMCAzNgow - MDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMjgyNzAgMDAwMDAgbiAKMDAwMDAyMTQwMiAw - MDAwMCBuIAowMDAwMDAxNTc0IDAwMDAwIG4gCjAwMDAwMjEyMzkgMDAwMDAgbiAKMDAw - MDAwMDAyMiAwMDAwMCBuIAowMDAwMDAxNTU0IDAwMDAwIG4gCjAwMDAwMDE2ODQgMDAw - MDAgbiAKMDAwMDAxNzUxNCAwMDAwMCBuIAowMDAwMDAxODU3IDAwMDAwIG4gCjAwMDAw - MDYzMjUgMDAwMDAgbiAKMDAwMDAwNjM0NiAwMDAwMCBuIAowMDAwMDA2ODMwIDAwMDAw - IG4gCjAwMDAwMTgzNzggMDAwMDAgbiAKMDAwMDAyODAwMSAwMDAwMCBuIAowMDAwMDIx - MjAyIDAwMDAwIG4gCjAwMDAwMDY4NTAgMDAwMDAgbiAKMDAwMDAxMzU5MiAwMDAwMCBu - IAowMDAwMDEzNjEzIDAwMDAwIG4gCjAwMDAwMTY2MzMgMDAwMDAgbiAKMDAwMDAxNjY1 - NCAwMDAwMCBuIAowMDAwMDE3NDk0IDAwMDAwIG4gCjAwMDAwMTc1NTAgMDAwMDAgbiAK - MDAwMDAxODM1OCAwMDAwMCBuIAowMDAwMDE4NDE1IDAwMDAwIG4gCjAwMDAwMjExODEg - MDAwMDAgbiAKMDAwMDAyMTMyMiAwMDAwMCBuIAowMDAwMDIxNTY4IDAwMDAwIG4gCjAw - MDAwMjE0NTAgMDAwMDAgbiAKMDAwMDAyMTU0NiAwMDAwMCBuIAowMDAwMDIxNjY0IDAw - MDAwIG4gCjAwMDAwMjc2NTUgMDAwMDAgbiAKMDAwMDAyNzY3NiAwMDAwMCBuIAowMDAw - MDI3OTAxIDAwMDAwIG4gCjAwMDAwMjgxNzYgMDAwMDAgbiAKMDAwMDAyODIyOCAwMDAw - MCBuIAp0cmFpbGVyCjw8IC9TaXplIDM2IC9Sb290IDI2IDAgUiAvSW5mbyAxIDAgUiAv - SUQgWyA8NjJjM2U5NGRkYzI0MzQ5YjFiNDQ0MjFmMDRiOTg4MzE+Cjw2MmMzZTk0ZGRj - MjQzNDliMWI0NDQyMWYwNGI5ODgzMT4gXSA+PgpzdGFydHhyZWYKMjgzNDUKJSVFT0YK - MSAwIG9iago8PC9BdXRob3IgKEZyYW5rIERlbGxhZXJ0KS9DcmVhdGlvbkRhdGUgKEQ6 - MjAxMDA3MTMwNDA3MDBaKS9DcmVhdG9yIChPbW5pR3JhZmZsZSA1LjIuMikvTW9kRGF0 - ZSAoRDoyMDEwMDcxMzA0MTcwMFopL1Byb2R1Y2VyIDM0IDAgUiA+PgplbmRvYmoKeHJl - ZgoxIDEKMDAwMDAyOTIyMyAwMDAwMCBuIAp0cmFpbGVyCjw8L0lEIFs8NjJjM2U5NGRk - YzI0MzQ5YjFiNDQ0MjFmMDRiOTg4MzE+IDw2MmMzZTk0ZGRjMjQzNDliMWI0NDQyMWYw - NGI5ODgzMT5dIC9JbmZvIDEgMCBSIC9QcmV2IDI4MzQ1IC9Sb290IDI2IDAgUiAvU2l6 - ZSAzNj4+CnN0YXJ0eHJlZgoyOTM3MwolJUVPRgo= - - QuickLookThumbnail - - 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 - IAAAAAAAACghAAAhFQAAt2JjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAy - ADYAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8AowCoAK0A - sgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+ - AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoC - AwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1 - AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAE - LQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWW - BaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0H - TwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6 - CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kL - gAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34 - DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ - 1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPl - FAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EX - ZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsU - GzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMf - Ph9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOU - I8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8o - cSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12 - Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQz - DTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjI - OQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/ - IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWa - Rd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJM - uk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2 - VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb - 5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2Pr - ZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFds - r20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWF - deF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/ - I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjO - iTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOT - TZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3S - nkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSp - N6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSc - tRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA - 7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01 - zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHa - dtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep - 6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD1 - 3vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//3BhcmEAAAAAAAMAAAAC - ZmYAAPKnAAANWQAAE9AAAArAdmNndAAAAAAAAAABAADhSAAAAAAAAQAAAADhSAAAAAAA - AQAAAADhSAAAAAAAAQAAbmRpbgAAAAAAAAA2AAChQAAAVwAAAEzAAACXAAAAJkAAABwA - AABQAAAAVAAAAoAAAAKAAAACgAAAAAAAAAAAAHNmMzIAAAAAAAEMGgAABcD///L/AAAH - YAAA/c7///uY///9lgAAA/QAAL9ObW1vZAAAAAAAABCsAACgAzA0Rky6bz8AAAAAAAAA - AAAAAAAAAAAAAA== - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UniqueID - 1 - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - ExpandedCanvases - - FitInWindow - - Frame - {{470, 267}, {700, 891}} - ListView - - OutlineWidth - 142 - RightSidebar - - Sidebar - - SidebarWidth - 138 - VisibleRegion - {{1, 1}, {558, 782}} - Zoom - 1 - ZoomValues - - - Canvas 1 - 0.0 - 1 - - - - saveQuickLookFiles - YES - - diff --git a/doc/images/gtsam-structure.pdf b/doc/images/gtsam-structure.pdf deleted file mode 100644 index 37c2ed3c1..000000000 Binary files a/doc/images/gtsam-structure.pdf and /dev/null differ diff --git a/doc/images/n-steps.pdf b/doc/images/n-steps.pdf deleted file mode 100644 index 165accc2d..000000000 Binary files a/doc/images/n-steps.pdf and /dev/null differ diff --git a/doc/images/n-steps.png b/doc/images/n-steps.png deleted file mode 100644 index 988fe5dfc..000000000 Binary files a/doc/images/n-steps.png and /dev/null differ diff --git a/doc/macros.lyx b/doc/macros.lyx deleted file mode 100644 index 1e57e1675..000000000 --- a/doc/macros.lyx +++ /dev/null @@ -1,294 +0,0 @@ -#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ -\lyxformat 345 -\begin_document -\begin_header -\textclass article -\use_default_options true -\language english -\inputencoding auto -\font_roman default -\font_sans default -\font_typewriter default -\font_default_family default -\font_sc false -\font_osf false -\font_sf_scale 100 -\font_tt_scale 100 - -\graphics default -\paperfontsize default -\use_hyperref false -\papersize default -\use_geometry false -\use_amsmath 1 -\use_esint 1 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\author "" -\author "" -\end_header - -\begin_body - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Derivatives -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\deriv}[2]{\frac{\partial#1}{\partial#2}} -{\frac{\partial#1}{\partial#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\at}[2]{#1\biggr\rvert_{#2}} -{#1\biggr\rvert_{#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Jac}[3]{ \at{\deriv{#1}{#2}} {#3} } -{\at{\deriv{#1}{#2}}{#3}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Lie Groups -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\xhat}{\hat{x}} -{\hat{x}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\yhat}{\hat{y}} -{\hat{y}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Ad}[1]{Ad_{#1}} -{Ad_{#1}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\define}{\stackrel{\Delta}{=}} -{\stackrel{\Delta}{=}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\gg}{\mathfrak{g}} -{\mathfrak{g}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Rn}{\mathbb{R}^{n}} -{\mathbb{R}^{n}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(2) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rtwo}{\mathfrak{\mathbb{R}^{2}}} -{\mathfrak{\mathbb{R}^{2}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOtwo}{SO(2)} -{SO(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sotwo}{\mathfrak{so(2)}} -{\mathfrak{so(2)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\that}{\hat{\theta}} -{\hat{\theta}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\skew}[1]{[#1]_{+}} -{[#1]_{+}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(2) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\SEtwo}{SE(2)} -{SE(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\setwo}{\mathfrak{se(2)}} -{\mathfrak{se(2)}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(3) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rthree}{\mathfrak{\mathbb{R}^{3}}} -{\mathfrak{\mathbb{R}^{3}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOthree}{SO(3)} -{SO(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sothree}{\mathfrak{so(3)}} -{\mathfrak{so(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\what}{\hat{\omega}} -{\hat{\omega}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Skew}[1]{[#1]_{\times}} -{[#1]_{\times}} -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(3) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset FormulaMacro -\newcommand{\Rsix}{\mathfrak{\mathbb{R}^{6}}} -{\mathfrak{\mathbb{R}^{6}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SEthree}{SE(3)} -{SE(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sethree}{\mathfrak{se(3)}} -{\mathfrak{se(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\xihat}{\hat{\xi}} -{\hat{\xi}} -\end_inset - - -\end_layout - -\end_body -\end_document diff --git a/doc/math.lyx b/doc/math.lyx deleted file mode 100644 index fd620bcf2..000000000 --- a/doc/math.lyx +++ /dev/null @@ -1,2225 +0,0 @@ -#LyX 1.6.5 created this file. For more info see http://www.lyx.org/ -\lyxformat 345 -\begin_document -\begin_header -\textclass article -\use_default_options false -\language english -\inputencoding auto -\font_roman times -\font_sans default -\font_typewriter default -\font_default_family rmdefault -\font_sc false -\font_osf false -\font_sf_scale 100 -\font_tt_scale 100 - -\graphics default -\paperfontsize 12 -\spacing single -\use_hyperref false -\papersize default -\use_geometry true -\use_amsmath 1 -\use_esint 0 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\leftmargin 1in -\topmargin 1in -\rightmargin 1in -\bottommargin 1in -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\author "" -\author "" -\end_header - -\begin_body - -\begin_layout Title -Geometry Derivatives and Other Hairy Math -\end_layout - -\begin_layout Author -Frank Dellaert -\end_layout - -\begin_layout Standard -\begin_inset Box Frameless -position "t" -hor_pos "c" -has_inner_box 1 -inner_pos "t" -use_parbox 0 -width "100col%" -special "none" -height "1in" -height_special "totalheight" -status collapsed - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Derivatives -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\deriv}[2]{\frac{\partial#1}{\partial#2}} -{\frac{\partial#1}{\partial#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\at}[2]{#1\biggr\rvert_{#2}} -{#1\biggr\rvert_{#2}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Jac}[3]{ \at{\deriv{#1}{#2}} {#3} } -{\at{\deriv{#1}{#2}}{#3}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -Lie Groups -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\xhat}{\hat{x}} -{\hat{x}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\yhat}{\hat{y}} -{\hat{y}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Ad}[1]{Ad_{#1}} -{Ad_{#1}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\define}{\stackrel{\Delta}{=}} -{\stackrel{\Delta}{=}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\gg}{\mathfrak{g}} -{\mathfrak{g}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Rn}{\mathbb{R}^{n}} -{\mathbb{R}^{n}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(2) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\Rtwo}{\mathfrak{\mathbb{R}^{2}}} -{\mathfrak{\mathbb{R}^{2}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOtwo}{SO(2)} -{SO(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sotwo}{\mathfrak{so(2)}} -{\mathfrak{so(2)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\that}{\hat{\theta}} -{\hat{\theta}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\skew}[1]{[#1]_{+}} -{[#1]_{+}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(2) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\SEtwo}{SE(2)} -{SE(2)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\setwo}{\mathfrak{se(2)}} -{\mathfrak{se(2)}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SO(3) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\Rthree}{\mathfrak{\mathbb{R}^{3}}} -{\mathfrak{\mathbb{R}^{3}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SOthree}{SO(3)} -{SO(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sothree}{\mathfrak{so(3)}} -{\mathfrak{so(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\what}{\hat{\omega}} -{\hat{\omega}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\Skew}[1]{[#1]_{\times}} -{[#1]_{\times}} -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset Note Comment -status open - -\begin_layout Plain Layout -SE(3) -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Plain Layout -\begin_inset FormulaMacro -\newcommand{\Rsix}{\mathfrak{\mathbb{R}^{6}}} -{\mathfrak{\mathbb{R}^{6}}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\SEthree}{SE(3)} -{SE(3)} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\sethree}{\mathfrak{se(3)}} -{\mathfrak{se(3)}} -\end_inset - - -\begin_inset FormulaMacro -\newcommand{\xihat}{\hat{\xi}} -{\hat{\xi}} -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Section -Derivatives of Lie Group Mappings -\end_layout - -\begin_layout Subsection -Homomorphisms -\end_layout - -\begin_layout Standard -The following is relevant -\begin_inset CommandInset citation -LatexCommand cite -after "page 45" -key "Hall00book" - -\end_inset - -: suppose that -\begin_inset Formula $\Phi:G\rightarrow H$ -\end_inset - - is a a mapping (Lie group homomorphism). - Then there exists a unique linear map -\begin_inset Formula $\phi:\gg\rightarrow\mathfrak{h}$ -\end_inset - - -\begin_inset Formula \[ -\phi(\xhat)\define\lim_{t\rightarrow0}\frac{d}{dt}\Phi\left(e^{t\xhat}\right)\] - -\end_inset - -such that -\end_layout - -\begin_layout Enumerate -\begin_inset Formula $\Phi\left(e^{\xhat}\right)=e^{\phi\left(\xhat\right)}$ -\end_inset - - -\end_layout - -\begin_layout Enumerate -\begin_inset Formula $\phi\left(T\xhat T^{-1}\right)=\Phi(T)\phi(\xhat)\Phi(T^{-1})$ -\end_inset - - -\end_layout - -\begin_layout Enumerate -\begin_inset Formula $\phi\left([\xhat,\yhat]\right)=\left[\phi(\xhat),\phi(\yhat)\right]$ -\end_inset - - -\end_layout - -\begin_layout Standard -In other words, the map -\begin_inset Formula $\phi$ -\end_inset - - is the derivative of -\begin_inset Formula $\Phi$ -\end_inset - - at the identity. - It suffices to compute -\begin_inset Formula $\phi$ -\end_inset - - for a basis of -\begin_inset Formula $\gg$ -\end_inset - -. - Since -\begin_inset Formula \[ -e^{-\xhat}=\left(e^{-\xhat}\right)^{-1}\] - -\end_inset - - clearly -\begin_inset Formula $\phi(\xhat)=-\xhat$ -\end_inset - - for the inverse mapping. -\end_layout - -\begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout -Let us define two mappings -\begin_inset Formula \[ -\Phi_{1}(A)=AB\mbox{ and }\Phi_{2}(B)=AB\] - -\end_inset - -Then -\begin_inset Formula \[ -\phi_{1}(\xhat)=\lim_{t\rightarrow0}\frac{d}{dt}\Phi_{1}\left(e^{t\xhat}B\right)=\] - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Subsection -Derivatives -\end_layout - -\begin_layout Standard -The derivatives for -\emph on -inverse, compose -\emph default -, and -\emph on -between -\emph default - can be derived from Lie group principles. - -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -To find the derivatives of these functions, we look for the necessary -\begin_inset Quotes eld -\end_inset - -delta -\begin_inset Quotes erd -\end_inset - - in the tangent space of the function -\emph on -output -\emph default - -\begin_inset Formula $f(g)$ -\end_inset - - that corresponds to a -\begin_inset Quotes eld -\end_inset - -delta -\begin_inset Quotes erd -\end_inset - - in the tangent space of the function -\emph on -input -\emph default - -\begin_inset Formula $g$ -\end_inset - -. - -\end_layout - -\end_inset - -Specifically, to find the derivative of a function -\begin_inset Formula $f\left(g\right)$ -\end_inset - -, we want to find the Lie algebra element -\begin_inset Formula $\yhat\in\gg$ -\end_inset - -, that will result from changing -\begin_inset Formula $g$ -\end_inset - - using -\begin_inset Formula $\xhat$ -\end_inset - -, also in exponential coordinates: -\begin_inset Formula \[ -f\left(g\right)e^{\yhat}=f\left(ge^{\xhat}\right)\] - -\end_inset - -Calculating these derivatives requires that we know the form of the function - -\begin_inset Formula $f$ -\end_inset - -. -\end_layout - -\begin_layout Standard -Starting with -\series bold -inverse -\series default -, i.e., -\begin_inset Formula $f(g)=g^{-1}$ -\end_inset - -, we have -\begin_inset Formula \begin{align} -g^{-1}e^{\yhat} & =\left(ge^{\xhat}\right)^{-1}=e^{-\xhat}g^{-1}\nonumber \\ -e^{\yhat} & =ge^{-\xhat}g^{-1}=e^{\Ad g\left(-\xhat\right)}\nonumber \\ -\yhat & =\Ad g\left(-\xhat\right)\label{eq:Dinverse}\end{align} - -\end_inset - -In other words, and this is very intuitive in hindsight, the inverse is - just negation of -\begin_inset Formula $\xhat$ -\end_inset - -, along with an adjoint to make sure it is applied in the right frame! -\end_layout - -\begin_layout Standard - -\series bold -Compose -\series default - can be derived similarly. - Let us define two functions to find the derivatives in first and second - arguments: -\begin_inset Formula \[ -f_{1}(g)=gh\mbox{ and }f_{2}(h)=gh\] - -\end_inset - - The latter is easiest, as a change -\begin_inset Formula $\xhat$ -\end_inset - - in the second argument -\begin_inset Formula $h$ -\end_inset - - simply gets applied to the result -\begin_inset Formula $gh$ -\end_inset - -: -\begin_inset Formula \begin{align} -f_{2}(h)e^{\yhat} & =f_{2}\left(he^{\xhat}\right)\nonumber \\ -ghe^{\yhat} & =ghe^{\xhat}\nonumber \\ -\yhat & =\xhat\label{eq:Dcompose2}\end{align} - -\end_inset - -The derivative for the first argument is a bit trickier: -\begin_inset Formula \begin{align} -f_{1}(g)e^{\yhat} & =f_{1}\left(ge^{\xhat}\right)\nonumber \\ -ghe^{\yhat} & =ge^{\xhat}h\nonumber \\ -e^{\yhat} & =h^{-1}e^{\xhat}h=e^{\Ad{h^{-1}}\xhat}\nonumber \\ -\yhat & =\Ad{h^{-1}}\xhat\label{eq:Dcompose1}\end{align} - -\end_inset - -In other words, to apply a change -\begin_inset Formula $\xhat$ -\end_inset - - in -\begin_inset Formula $g$ -\end_inset - - we first need to undo -\begin_inset Formula $h$ -\end_inset - -, then apply -\begin_inset Formula $\xhat$ -\end_inset - -, and then apply -\begin_inset Formula $h$ -\end_inset - - again. - All can be done in one step by simply applying -\begin_inset Formula $\Ad{h^{-1}}\xhat$ -\end_inset - -. -\end_layout - -\begin_layout Standard -Finally, let us find the derivative of -\series bold -between -\series default -, defined as -\begin_inset Formula $between(g,h)=compose(inverse(g),h)$ -\end_inset - -. - The derivative in the second argument -\begin_inset Formula $h$ -\end_inset - - is similarly trivial: -\begin_inset Formula $\yhat=\xhat$ -\end_inset - -. - The first argument goes as follows: -\begin_inset Formula \begin{align} -f_{1}(g)e^{\yhat} & =f_{1}\left(ge^{\xhat}\right)\nonumber \\ -g^{-1}he^{\yhat} & =\left(ge^{\xhat}\right)^{-1}h=e^{\left(-\xhat\right)}g^{-1}h\nonumber \\ -e^{\yhat} & =\left(h^{-1}g\right)e^{\left(-\xhat\right)}\left(h^{-1}g\right)^{-1}=e^{\Ad{\left(h^{-1}g\right)}\left(-\xhat\right)}\nonumber \\ -\yhat & =\Ad{\left(h^{-1}g\right)}\left(-\xhat\right)=\Ad{between\left(h,g\right)}\left(-\xhat\right)\label{eq:Dbetween1}\end{align} - -\end_inset - -Hence, now we undo -\begin_inset Formula $h$ -\end_inset - - and then apply the inverse -\begin_inset Formula $\left(-\xhat\right)$ -\end_inset - - in the -\begin_inset Formula $g$ -\end_inset - - frame. -\end_layout - -\begin_layout Subsection* -Numerical Derivatives -\end_layout - -\begin_layout Standard -Let's examine -\begin_inset Formula \[ -f\left(g\right)e^{\yhat}=f\left(ge^{\xhat}\right)\] - -\end_inset - -and multiply with -\begin_inset Formula $f(g)^{-1}$ -\end_inset - - on both sides then take the log (which in our case returns -\begin_inset Formula $y$ -\end_inset - -, not -\begin_inset Formula $\yhat$ -\end_inset - -): -\begin_inset Formula \[ -y(x)=\log\left[f\left(g\right)^{-1}f\left(ge^{\xhat}\right)\right]\] - -\end_inset - -Let us look at -\begin_inset Formula $x=0$ -\end_inset - -, and perturb in direction -\begin_inset Formula $i$ -\end_inset - -, -\begin_inset Formula $e_{i}=[0,0,d,0,0]$ -\end_inset - -. - Then take derivative, -\begin_inset Formula \[ -\deriv{y(d)}d\define\lim_{d->0}\frac{y(d)-y(0)}{d}=\lim_{d->0}\frac{1}{d}\log\left[f\left(g\right)^{-1}f\left(ge^{\hat{e_{i}}}\right)\right]\] - -\end_inset - -which is the basis for a numerical derivative scheme. -\end_layout - -\begin_layout Standard -Let us also look at a chain rule. - If we know the behavior at the origin -\begin_inset Formula $I$ -\end_inset - -, we can extrapolate -\begin_inset Formula \[ -f(ge^{\xhat})=f(ge^{\xhat}g^{-1}g)=f(e^{\Ad g\xhat}g)\] - -\end_inset - - -\end_layout - -\begin_layout Section -Derivatives of Actions -\begin_inset CommandInset label -LatexCommand label -name "sec:Derivatives-of-Actions" - -\end_inset - - -\end_layout - -\begin_layout Subsection -Forward Action -\end_layout - -\begin_layout Standard -The (usual) action of an -\begin_inset Formula $n$ -\end_inset - --dimensional matrix group -\begin_inset Formula $G$ -\end_inset - - is matrix-vector multiplication on -\begin_inset Formula $\mathbb{R}^{n}$ -\end_inset - -, -\begin_inset Formula \[ -q=Tp\] - -\end_inset - -with -\begin_inset Formula $p,q\in\mathbb{R}^{n}$ -\end_inset - - and -\begin_inset Formula $T\in GL(n)$ -\end_inset - -. - Let us first do away with the derivative in -\begin_inset Formula $p$ -\end_inset - -, which is easy: -\begin_inset Formula \[ -\deriv{\left(Tp\right)}p=T\] - -\end_inset - -We would now like to know what an incremental action -\begin_inset Formula $\xhat$ -\end_inset - - would do, through the exponential map -\begin_inset Formula \[ -q(x)=Te^{\xhat}p\] - -\end_inset - -with derivative -\begin_inset Formula \[ -\deriv{q(x)}x=T\deriv{}x\left(e^{\xhat}p\right)\] - -\end_inset - -Since the matrix exponential is given by the series -\begin_inset Formula \[ -e^{A}=I+A+\frac{A^{2}}{2!}+\frac{A^{3}}{3!}+\ldots\] - -\end_inset - -we have, to first order -\begin_inset Formula \[ -e^{\xhat}p=p+\xhat p+\ldots\] - -\end_inset - -and the derivative of an incremental action x for matrix Lie groups becomes -\begin_inset Formula \[ -\deriv{q(x)}x=T\deriv{\left(\xhat p\right)}x\define TH_{p}\] - -\end_inset - -where -\begin_inset Formula $H_{p}$ -\end_inset - - is an -\begin_inset Formula $n\times n$ -\end_inset - - Jacobian matrix that depends on -\begin_inset Formula $p$ -\end_inset - -. - -\begin_inset Note Note -status collapsed - -\begin_layout Plain Layout -Recalling the definition -\begin_inset CommandInset ref -LatexCommand eqref -reference "eq:generators" - -\end_inset - - of the map -\begin_inset Formula $x\rightarrow\xhat$ -\end_inset - -, we can calculate -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\begin_inset Formula $\xhat p$ -\end_inset - - -\family default -\series default -\shape default -\size default -\emph default -\bar default -\noun default -\color inherit - as (using tensor notation) -\begin_inset Formula \[ -\left(\xhat p\right)_{jk}=G_{jk}^{i}x_{i}p^{k}\] - -\end_inset - -and hence the derivative is -\begin_inset Formula \[ -\left(H_{p}\right)_{j}^{i}=G_{jk}^{i}p^{k}\] - -\end_inset - -and the final derivative becomes -\begin_inset Formula \[ -\deriv{q(x)}x=TH_{p}\] - -\end_inset - - -\end_layout - -\end_inset - - -\end_layout - -\begin_layout Subsection -Inverse Action -\end_layout - -\begin_layout Standard -When we apply the inverse transformation -\begin_inset Formula \[ -q=T^{-1}p\] - -\end_inset - -we would now like to know what an incremental action -\begin_inset Formula $\xhat$ -\end_inset - - on -\begin_inset Formula $T$ -\end_inset - - would do: -\begin_inset Formula \begin{eqnarray*} -q(x) & = & \left(Te^{\xhat}\right)^{-1}p\\ - & = & e^{-\xhat}T^{-1}p\\ - & = & e^{-\xhat}q\\ - & \approx & q-\xhat q\end{eqnarray*} - -\end_inset - -Hence -\begin_inset Formula \begin{equation} -\deriv{q(x)}x=\deriv{\left(q-\xhat q\right)}x=-\deriv{\left(\xhat q\right)}x=-H_{q}\label{eq:inverseAction}\end{equation} - -\end_inset - -where -\begin_inset Formula $H_{q}$ -\end_inset - - will be as above. -\end_layout - -\begin_layout Section -Point3 -\end_layout - -\begin_layout Standard -A cross product -\begin_inset Formula $a\times b$ -\end_inset - - can be written as a matrix multiplication -\begin_inset Formula \[ -a\times b=\Skew ab\] - -\end_inset - -where -\begin_inset Formula $\Skew a$ -\end_inset - - is a skew-symmetric matrix defined as -\begin_inset Formula \[ -\Skew{x,y,z}=\left[\begin{array}{ccc} -0 & -z & y\\ -z & 0 & -x\\ --y & x & 0\end{array}\right]\] - -\end_inset - -We also have -\begin_inset Formula \[ -a^{T}\Skew b=-(\Skew ba)^{T}=-(a\times b)^{T}\] - -\end_inset - -The derivative of a cross product -\begin_inset Formula \begin{equation} -\frac{\partial(a\times b)}{\partial a}=\Skew{-b}\label{eq:Dcross1}\end{equation} - -\end_inset - - -\begin_inset Formula \begin{equation} -\frac{\partial(a\times b)}{\partial b}=\Skew a\label{eq:Dcross2}\end{equation} - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Rotations -\end_layout - -\begin_layout Subsection -Rot2 (in gtsam) -\end_layout - -\begin_layout Standard -A rotation is stored as -\begin_inset Formula $(\cos\theta,\sin\theta)$ -\end_inset - -. - An incremental rotation is applied using the trigonometric sum rule: -\begin_inset Formula \[ -\cos\theta'=\cos\theta\cos\delta-\sin\theta\sin\delta\] - -\end_inset - - -\begin_inset Formula \[ -\sin\theta'=\sin\theta\cos\delta+\cos\theta\sin\delta\] - -\end_inset - -where -\begin_inset Formula $\delta$ -\end_inset - - is an incremental rotation angle. -\end_layout - -\begin_layout Subsection -Derivatives of Mappings -\end_layout - -\begin_layout Standard -We have the derivative of -\series bold -inverse -\series default -, -\begin_inset Formula \[ -\frac{\partial R^{T}}{\partial\theta}=-\Ad R=-1\mbox{ }\] - -\end_inset - - -\series bold -compose, -\series default - -\begin_inset Formula \[ -\frac{\partial\left(R_{1}R_{2}\right)}{\partial\theta_{1}}=\Ad{R_{2}^{T}}=1\mbox{ and }\frac{\partial\left(R_{1}R_{2}\right)}{\partial\theta_{2}}=1\] - -\end_inset - - -\series bold - -\begin_inset Formula $and$ -\end_inset - -between: -\series default - -\begin_inset Formula \[ -\frac{\partial\left(R_{1}^{T}R_{2}\right)}{\partial\theta_{1}}=-\Ad{R_{2}^{T}R_{1}}=-1\mbox{ and }\frac{\partial\left(R_{1}^{T}R_{2}\right)}{\partial\theta_{2}}=1\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Derivatives of Actions -\end_layout - -\begin_layout Standard -In the case of -\begin_inset Formula $\SOtwo$ -\end_inset - - the vector space is -\begin_inset Formula $\Rtwo$ -\end_inset - -, and the group action corresponds to rotating a point -\begin_inset Formula \[ -q=Rp\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\theta$ -\end_inset - - would do: -\begin_inset Formula \[ -q(\text{\omega t})=Re^{\skew{\omega t}}p\] - -\end_inset - -The derivative is (following the exposition in Section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:Derivatives-of-Actions" - -\end_inset - -): -\begin_inset Formula \[ -\deriv{q(\omega t)}t=R\deriv{}t\left(e^{\skew{\omega t}}p\right)=R\deriv{}t\left(\skew{\omega t}p\right)\] - -\end_inset - -Note that -\begin_inset Formula \begin{equation} -\skew{\theta}\left[\begin{array}{c} -x\\ -y\end{array}\right]=\theta R_{\pi/2}\left[\begin{array}{c} -x\\ -y\end{array}\right]=\theta\left[\begin{array}{c} --y\\ -x\end{array}\right]\label{eq:RestrictedCross}\end{equation} - -\end_inset - -which acts like a restricted -\begin_inset Quotes eld -\end_inset - -cross product -\begin_inset Quotes erd -\end_inset - - in the plane. - Hence -\begin_inset Formula \[ -\skew{\theta}p=\left[\begin{array}{c} --y\\ -x\end{array}\right]\theta=\omega R_{pi/2}pt\] - -\end_inset - -Hence, the final derivative of an action in its first argument is -\begin_inset Formula \[ -\deriv{q(\omega t)}{\omega t}=\omega RR_{pi/2}p=\omega R_{pi/2}Rp=\omega R_{pi/2}q\] - -\end_inset - - -\end_layout - -\begin_layout Standard -Really need to think of relationship -\begin_inset Formula $\omega$ -\end_inset - - and -\begin_inset Formula $t$ -\end_inset - -. - We don't have a time -\begin_inset Formula $t$ -\end_inset - - in our code. -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Rigid Transformations -\end_layout - -\begin_layout Subsection -Derivatives of Mappings -\end_layout - -\begin_layout Standard -We can just define all derivatives in terms of the above adjoint map: -\begin_inset Formula \begin{eqnarray*} -\frac{\partial T^{^{-1}}}{\partial\xi} & = & -\Ad T\end{eqnarray*} - -\end_inset - - -\begin_inset Formula \begin{eqnarray*} -\frac{\partial\left(T_{1}T_{2}\right)}{\partial\xi_{1}} & = & \Ad{T_{2}^{^{-1}}}=1\mbox{ and }\frac{\partial\left(T_{1}T_{2}\right)}{\partial\xi_{2}}=I_{3}\end{eqnarray*} - -\end_inset - - -\begin_inset Formula \begin{eqnarray*} -\frac{\partial\left(T_{1}^{-1}T_{2}\right)}{\partial\xi_{1}} & = & -\Ad{T_{2}^{^{-1}}T_{1}}=-\Ad{between(T_{2},T_{1})}\mbox{ and }\frac{\partial\left(T_{1}^{-1}T_{2}\right)}{\partial\xi_{2}}=I_{3}\end{eqnarray*} - -\end_inset - - -\end_layout - -\begin_layout Subsection -The derivatives of Actions -\end_layout - -\begin_layout Standard -The action of -\begin_inset Formula $\SEtwo$ -\end_inset - - on 2D points is done by embedding the points in -\begin_inset Formula $\mathbb{R}^{3}$ -\end_inset - - by using homogeneous coordinates -\begin_inset Formula \[ -\hat{q}=\left[\begin{array}{c} -q\\ -1\end{array}\right]=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=T\hat{p}\] - -\end_inset - -Analoguous to -\begin_inset Formula $\SEthree$ -\end_inset - -, we can compute a velocity -\begin_inset Formula $\xihat\hat{p}$ -\end_inset - - in the local -\begin_inset Formula $T$ -\end_inset - - frame: -\begin_inset Formula \[ -\xihat\hat{p}=\left[\begin{array}{cc} -\skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=\left[\begin{array}{c} -\skew{\omega}p+v\\ -0\end{array}\right]\] - -\end_inset - -By only taking the top two rows, we can write this as a velocity in -\begin_inset Formula $\Rtwo$ -\end_inset - -, as the product of a -\begin_inset Formula $2\times3$ -\end_inset - - matrix -\begin_inset Formula $H_{p}$ -\end_inset - - that acts upon the exponential coordinates -\begin_inset Formula $\xi$ -\end_inset - - directly: -\begin_inset Formula \[ -\skew{\omega}p+v=v+R_{\pi/2}p\omega=\left[\begin{array}{cc} -I_{2} & R_{\pi/2}p\end{array}\right]\left[\begin{array}{c} -v\\ -\omega\end{array}\right]=H_{p}\xi\] - -\end_inset - -Hence, the final derivative of the group action is -\begin_inset Formula \[ -\deriv{q(\xi)}{\xi}=R\left[\begin{array}{cc} -I_{2} & R_{\pi/2}p\end{array}\right]=\left[\begin{array}{cc} -R & R_{\pi/2}q\end{array}\right]\] - -\end_inset - -The derivative of the inverse action -\begin_inset Formula $\hat{q}=T^{-1}\hat{p}$ -\end_inset - - is given by -\begin_inset CommandInset ref -LatexCommand eqref -reference "eq:inverseAction" - -\end_inset - -, specialized to -\begin_inset Formula $\SEtwo$ -\end_inset - -: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\deriv{\left(T^{-1}\hat{p}\right)}{\xi}=-T^{-1}\deriv{\left(\Ad T\hat{\xi}\right)\hat{p}}{\xi}\] - -\end_inset - -where the velocity now is -\begin_inset Formula \[ -\left(\Ad T\hat{\xi}\right)\hat{p}=\left[\begin{array}{cc} -\skew{\omega} & Rv-\omega R_{\pi/2}t\\ -0 & 0\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=\left[\begin{array}{c} -Rv+R_{\pi/2}(p-t)\omega\\ -0\end{array}\right]\] - -\end_inset - -and hence -\begin_inset Formula \[ -\deriv{q(\xi)}{\xi}=-R^{T}\left[\begin{array}{cc} -R & R_{\pi/2}(p-t)\end{array}\right]=\left[\begin{array}{cc} --I_{2} & -R_{\pi/2}q\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -3D Rotations -\end_layout - -\begin_layout Subsection -Derivatives of Mappings -\end_layout - -\begin_layout Standard -Hence, we are now in a position to simply posit the derivative of -\series bold -inverse -\series default -, -\begin_inset Formula \begin{eqnarray*} -\Skew{\omega'} & = & \Ad R\left(\Skew{-\omega}\right)=\Skew{R(-\omega)}\\ -\frac{\partial R^{T}}{\partial\omega} & = & -R\end{eqnarray*} - -\end_inset - - -\series bold -compose, -\series default - -\begin_inset Formula \[ -\Skew{\omega'}=\Ad{R_{2}^{T}}\left(\Skew{\omega}\right)=\Skew{R_{2}^{T}\omega}\] - -\end_inset - - -\begin_inset Formula \[ -\frac{\partial\left(R_{1}R_{2}\right)}{\partial\omega_{1}}=R_{2}^{T}\mbox{ and }\frac{\partial\left(R_{1}R_{2}\right)}{\partial\omega_{2}}=I_{3}\] - -\end_inset - - -\series bold -between -\series default - in its first argument, -\begin_inset Formula \begin{eqnarray*} -\Skew{\omega'} & = & \Ad{R_{2}^{T}R_{1}}\left(\Skew{-\omega}\right)=\Skew{R_{2}^{T}R_{1}(-\omega)}\\ -\frac{\partial\left(R_{1}^{T}R_{2}\right)}{\partial\omega_{1}} & = & -R_{2}^{T}R_{1}=-between(R_{2},R_{1})\end{eqnarray*} - -\end_inset - -and between in its second argument, -\begin_inset Formula \begin{eqnarray*} -\frac{\partial\left(R_{1}^{T}R_{2}\right)}{\partial\omega_{2}} & = & I_{3}\end{eqnarray*} - -\end_inset - - -\end_layout - -\begin_layout Subsection -Derivatives of Actions -\end_layout - -\begin_layout Standard -In the case of -\begin_inset Formula $\SOthree$ -\end_inset - - the vector space is -\begin_inset Formula $\Rthree$ -\end_inset - -, and the group action corresponds to rotating a point -\begin_inset Formula \[ -q=Rp\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\omega$ -\end_inset - - would do: -\begin_inset Formula \[ -q(\omega)=Re^{\Skew{\omega}}p\] - -\end_inset - -hence the derivative (following the exposition in Section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:Derivatives-of-Actions" - -\end_inset - -): -\begin_inset Formula \[ -\deriv{q(\omega)}{\omega}=R\deriv{}{\omega}\left(e^{\Skew{\omega}}p\right)=R\deriv{}{\omega}\left(\Skew{\omega}p\right)=RH_{p}\] - -\end_inset - -To calculate -\begin_inset Formula $H_{p}$ -\end_inset - - we make use of -\begin_inset Formula \[ -\Skew{\omega}p=\omega\times p=-p\times\omega=\Skew{-p}\omega\] - -\end_inset - -Hence, the final derivative of an action in its first argument is -\begin_inset Formula \[ -\deriv{q(\omega)}{\omega}=RH_{p}=R\Skew{-p}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -The derivative of the inverse action is given by -\begin_inset CommandInset ref -LatexCommand ref -reference "eq:inverseAction" - -\end_inset - -, specialized to -\begin_inset Formula $\SOthree$ -\end_inset - -: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\deriv{q(\omega)}{\omega}=-R^{T}\deriv{\left(\Skew{R\omega\mbox{ }}p\right)}{\omega}=R^{T}\Skew pR=\Skew{R^{T}p}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -3D Rigid Transformations -\end_layout - -\begin_layout Subsection -Derivatives of Mappings -\end_layout - -\begin_layout Standard -Hence, as with -\begin_inset Formula $\SOthree$ -\end_inset - -, we are now in a position to simply posit the derivative of -\series bold -inverse -\series default -, -\begin_inset Formula \[ -\frac{\partial T^{-1}}{\partial\xi}=\Ad T=-\left[\begin{array}{cc} -R & 0\\ -\Skew tR & R\end{array}\right]\] - -\end_inset - -(but unit test on the above fails !!!), -\series bold -compose -\series default - in its first argument, -\begin_inset Formula \[ -\frac{\partial\left(T_{1}T_{2}\right)}{\partial\xi_{1}}=\Ad{T_{2}^{-1}}=\left[\begin{array}{cc} -R_{2}^{T} & 0\\ -\Skew{-R_{2}^{T}t_{2}}R_{2}^{T} & R_{2}^{T}\end{array}\right]=\left[\begin{array}{cc} -R_{2}^{T} & 0\\ -R_{2}^{T}\Skew{-t_{2}} & R_{2}^{T}\end{array}\right]\] - -\end_inset - -compose in its second argument, -\begin_inset Formula \[ -\frac{\partial\left(T_{1}T_{2}\right)}{\partial\xi_{2}}=I_{6}\] - -\end_inset - - -\series bold -between -\series default - in its first argument, -\begin_inset Formula \[ -\frac{\partial\left(T_{1}^{^{-1}}T_{2}\right)}{\partial\xi_{1}}=\Ad{T_{21}}=-\left[\begin{array}{cc} -R & 0\\ -\Skew tR & R\end{array}\right]\] - -\end_inset - -with -\begin_inset Formula \[ -T_{12}=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]=T_{1}^{^{-1}}T_{2}=between(T_{2},T_{1})\] - -\end_inset - -and between in its second argument, -\begin_inset Formula \begin{eqnarray*} -\frac{\partial\left(T_{1}^{^{-1}}T_{2}\right)}{\partial\xi_{1}} & = & I_{6}\end{eqnarray*} - -\end_inset - - -\end_layout - -\begin_layout Subsection -The derivatives of Actions -\end_layout - -\begin_layout Standard -The action of -\begin_inset Formula $\SEthree$ -\end_inset - - on 3D points is done by embedding the points in -\begin_inset Formula $\mathbb{R}^{4}$ -\end_inset - - by using homogeneous coordinates -\begin_inset Formula \[ -\hat{q}=\left[\begin{array}{c} -q\\ -1\end{array}\right]=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=T\hat{p}\] - -\end_inset - -We would now like to know what an incremental rotation parameterized by - -\begin_inset Formula $\xi$ -\end_inset - - would do: -\begin_inset Formula \[ -\hat{q}(\xi)=Te^{\xihat}\hat{p}\] - -\end_inset - -hence the derivative (following the exposition in Section -\begin_inset CommandInset ref -LatexCommand ref -reference "sec:Derivatives-of-Actions" - -\end_inset - -): -\begin_inset Formula \[ -\deriv{\hat{q}(\xi)}{\xi}=T\deriv{}{\xi}\left(\xihat\hat{p}\right)=TH_{p}\] - -\end_inset - -where -\begin_inset Formula $\xihat\hat{p}$ -\end_inset - - corresponds to a velocity in -\begin_inset Formula $\mathbb{R}^{4}$ -\end_inset - - (in the local -\begin_inset Formula $T$ -\end_inset - - frame): -\begin_inset Formula \[ -\xihat\hat{p}=\left[\begin{array}{cc} -\Skew{\omega} & v\\ -0 & 0\end{array}\right]\left[\begin{array}{c} -p\\ -1\end{array}\right]=\left[\begin{array}{c} -\omega\times p+v\\ -0\end{array}\right]\] - -\end_inset - -Notice how velocities are anologous to points at infinity in projective - geometry: they correspond to free vectors indicating a direction and magnitude - of change. - -\end_layout - -\begin_layout Standard -By only taking the top three rows, we can write this as a velocity in -\begin_inset Formula $\Rthree$ -\end_inset - -, as the product of a -\begin_inset Formula $3\times6$ -\end_inset - - matrix -\begin_inset Formula $H_{p}$ -\end_inset - - that acts upon the exponential coordinates -\begin_inset Formula $\xi$ -\end_inset - - directly: -\begin_inset Formula \[ -\omega\times p+v=-p\times\omega+v=\left[\begin{array}{cc} --\Skew p & I_{3}\end{array}\right]\left[\begin{array}{c} -\omega\\ -v\end{array}\right]=H_{p}\xi\] - -\end_inset - -Hence, the final derivative of the group action is -\begin_inset Formula \[ -\deriv{\hat{q}(\xi)}{\xi}=T\hat{H}_{p}=\left[\begin{array}{cc} -R & t\\ -0 & 1\end{array}\right]\left[\begin{array}{cc} -\Skew{-p} & I_{3}\\ -0 & 0\end{array}\right]\] - -\end_inset - -in homogenous coordinates. - In -\begin_inset Formula $\Rthree$ -\end_inset - - this becomes: -\begin_inset Formula \[ -\deriv{q(\xi)}{\xi}=R\left[\begin{array}{cc} --\Skew p & I_{3}\end{array}\right]\] - -\end_inset - -The derivative of the inverse action -\begin_inset Formula $T^{-1}p$ -\end_inset - - is given by formula -\begin_inset CommandInset ref -LatexCommand ref -reference "eq:inverseAction" - -\end_inset - -: -\end_layout - -\begin_layout Standard - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -\begin_inset Formula \[ -\deriv{\hat{q}(\xi)}{\xi}=-H_{q}=\left[\begin{array}{cc} -\Skew q & -I_{3}\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Subsection -Pose3 (gtsam, old-style exmap) -\end_layout - -\begin_layout Standard -In the old-style, we have -\end_layout - -\begin_layout Standard - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none -\begin_inset Formula $R'=R(I+\Omega)$ -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Formula $t'=t+dt$ -\end_inset - - -\end_layout - -\begin_layout Standard -In this case, the derivative of -\series bold -\emph on -transform_from -\series default -\emph default -, -\begin_inset Formula $Rx+t$ -\end_inset - -: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\frac{\partial(R(I+\Omega)x+t)}{\partial\omega}=\frac{\partial(R\Omega x)}{\partial\omega}=\frac{\partial(R\left(\omega\times x\right))}{\partial\omega}=R\Skew{-x}\] - -\end_inset - -and with respect to -\begin_inset Formula $dt$ -\end_inset - - is easy: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\frac{\partial(Rx+t+dt)}{\partial dt}=I\] - -\end_inset - -The derivative of -\series bold -\emph on -transform_to -\series default -\emph default -, -\begin_inset Formula $inv(R)(x-t)$ -\end_inset - - we can obtain using the chain rule: -\begin_inset Formula \[ -\frac{\partial(inv(R)(x-t))}{\partial\omega}=\frac{\partial unrot(R,(x-t))}{\partial\omega}=skew(R^{T}\left(x-t\right))\] - -\end_inset - - -\end_layout - -\begin_layout Standard -and with respect to -\begin_inset Formula $dt$ -\end_inset - - is easy: -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\frac{\partial(R^{T}(x-t-dt))}{\partial dt}=-R^{T}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Newpage pagebreak -\end_inset - - -\end_layout - -\begin_layout Section -2D Line Segments (Ocaml) -\end_layout - -\begin_layout Standard -The error between an infinite line -\begin_inset Formula $(a,b,c)$ -\end_inset - - and a 2D line segment -\begin_inset Formula $((x1,y1),(x2,y2))$ -\end_inset - - is defined in Line3.ml. -\end_layout - -\begin_layout Section -Line3vd (Ocaml) -\end_layout - -\begin_layout Standard -One representation of a line is through 2 vectors -\begin_inset Formula $(v,d)$ -\end_inset - -, where -\begin_inset Formula $v$ -\end_inset - - is the direction and the vector -\begin_inset Formula $d$ -\end_inset - - points from the orgin to the closest point on the line. -\end_layout - -\begin_layout Standard -In this representation, transforming a 3D line from a world coordinate frame - to a camera at -\begin_inset Formula $(R_{w}^{c},t^{w})$ -\end_inset - - is done by -\begin_inset Formula \[ -v^{c}=R_{w}^{c}v^{w}\] - -\end_inset - - -\begin_inset Formula \[ -d^{c}=R_{w}^{c}\left(d^{w}+(t^{w}v^{w})v^{w}-t^{w}\right)\] - -\end_inset - - -\end_layout - -\begin_layout Section -Line3 (Ocaml) -\end_layout - -\begin_layout Standard -For 3D lines, we use a parameterization due to C.J. - Taylor, using a rotation matrix -\begin_inset Formula $R$ -\end_inset - - and 2 scalars -\begin_inset Formula $a$ -\end_inset - - and -\begin_inset Formula $b$ -\end_inset - -. - The line direction -\begin_inset Formula $v$ -\end_inset - - is simply the Z-axis of the rotated frame, i.e., -\begin_inset Formula $v=R_{3}$ -\end_inset - -, while the vector -\begin_inset Formula $d$ -\end_inset - - is given by -\begin_inset Formula $d=aR_{1}+bR_{2}$ -\end_inset - -. -\end_layout - -\begin_layout Standard -Now, we will -\emph on -not -\emph default - use the incremental rotation scheme we used for rotations: because the - matrix R translates from the line coordinate frame to the world frame, - we need to apply the incremental rotation on the right-side: -\begin_inset Formula \[ -R'=R(I+\Omega)\] - -\end_inset - -Projecting a line to 2D can be done easily, as both -\begin_inset Formula $v$ -\end_inset - - and -\begin_inset Formula $d$ -\end_inset - - are also the 2D homogenous coordinates of two points on the projected line, - and hence we have -\begin_inset Formula \begin{eqnarray*} -l & = & v\times d\\ - & = & R_{3}\times\left(aR_{1}+bR_{2}\right)\\ - & = & a\left(R_{3}\times R_{1}\right)+b\left(R_{3}\times R_{2}\right)\\ - & = & aR_{2}-bR_{1}\end{eqnarray*} - -\end_inset - -This can be written as a rotation of a point, -\begin_inset Formula \[ -l=R\left(\begin{array}{c} --b\\ -a\\ -0\end{array}\right)\] - -\end_inset - -but because the incremental rotation is now done on the right, we need to - figure out the derivatives again: -\begin_inset Formula \begin{equation} -\frac{\partial(R(I+\Omega)x)}{\partial\omega}=\frac{\partial(R\Omega x)}{\partial\omega}=R\frac{\partial(\Omega x)}{\partial\omega}=R\Skew{-x}\label{eq:rotateRight}\end{equation} - -\end_inset - -and hence the derivative of the projection -\begin_inset Formula $l$ -\end_inset - - with respect to the rotation matrix -\begin_inset Formula $R$ -\end_inset - -of the 3D line is -\begin_inset Formula \begin{equation} -\frac{\partial(l)}{\partial\omega}=R\Skew{\left(\begin{array}{c} -b\\ --a\\ -0\end{array}\right)}=\left[\begin{array}{ccc} -aR_{3} & bR_{3} & -(aR_{1}+bR_{2})\end{array}\right]\end{equation} - -\end_inset - -or the -\begin_inset Formula $a,b$ -\end_inset - - scalars: -\begin_inset Formula \[ -\frac{\partial(l)}{\partial a}=R_{2}\] - -\end_inset - - -\begin_inset Formula \[ -\frac{\partial(l)}{\partial b}=-R_{1}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -Transforming a 3D line -\begin_inset Formula $(R,(a,b))$ -\end_inset - - from a world coordinate frame to a camera frame -\begin_inset Formula $(R_{w}^{c},t^{w})$ -\end_inset - - is done by -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -R'=R_{w}^{c}R\] - -\end_inset - - -\begin_inset Formula \[ -a'=a-R_{1}^{T}t^{w}\] - -\end_inset - - -\begin_inset Formula \[ -b'=b-R_{2}^{T}t^{w}\] - -\end_inset - -Again, we need to redo the derivatives, as R is incremented from the right. - The first argument is incremented from the left, but the result is incremented - on the right: -\begin_inset Formula \begin{eqnarray*} -R'(I+\Omega')=(AB)(I+\Omega') & = & (I+\Skew{S\omega})AB\\ -I+\Omega' & = & (AB)^{T}(I+\Skew{S\omega})(AB)\\ -\Omega' & = & R'^{T}\Skew{S\omega}R'\\ -\Omega' & = & \Skew{R'^{T}S\omega}\\ -\omega' & = & R'^{T}S\omega\end{eqnarray*} - -\end_inset - -For the second argument -\begin_inset Formula $R$ -\end_inset - - we now simply have: -\begin_inset Formula \begin{eqnarray*} -AB(I+\Omega') & = & AB(I+\Omega)\\ -\Omega' & = & \Omega\\ -\omega' & = & \omega\end{eqnarray*} - -\end_inset - -The scalar derivatives can be found by realizing that -\begin_inset Formula \[ -\left(\begin{array}{c} -a'\\ -b'\\ -...\end{array}\right)=\left(\begin{array}{c} -a\\ -b\\ -0\end{array}\right)-R^{T}t^{w}\] - -\end_inset - -where we don't care about the third row. - Hence -\begin_inset Formula \[ -\frac{\partial(\left(R(I+\Omega_{2})\right)^{T}t^{w})}{\partial\omega}=-\frac{\partial(\Omega_{2}R^{T}t^{w})}{\partial\omega}=-\Skew{R^{T}t^{w}}=\left[\begin{array}{ccc} -0 & R_{3}^{T}t^{w} & -R_{2}^{T}t^{w}\\ --R_{3}^{T}t^{w} & 0 & R_{1}^{T}t^{w}\\ -... & ... & 0\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Section - -\series bold -Aligning 3D Scans -\end_layout - -\begin_layout Standard -Below is the explanaition underlying Pose3.align, i.e. - aligning two point clouds using SVD. - Inspired but modified from CVOnline... -\end_layout - -\begin_layout Standard - -\emph on -Our -\emph default - model is -\begin_inset Formula \[ -p^{c}=R\left(p^{w}-t\right)\] - -\end_inset - -i.e., -\begin_inset Formula $R$ -\end_inset - - is from camera to world, and -\begin_inset Formula $t$ -\end_inset - - is the camera location in world coordinates. - The objective function is -\begin_inset Formula \begin{equation} -\frac{1}{2}\sum\left(p^{c}-R(p^{w}-t)\right)^{2}=\frac{1}{2}\sum\left(p^{c}-Rp^{w}+Rt\right)^{2}=\frac{1}{2}\sum\left(p^{c}-Rp^{w}-t'\right)^{2}\label{eq:J}\end{equation} - -\end_inset - -where -\begin_inset Formula $t'=-Rt$ -\end_inset - - is the location of the origin in the camera frame. - Taking the derivative with respect to -\begin_inset Formula $t'$ -\end_inset - - and setting to zero we have -\begin_inset Formula \[ -\sum\left(p^{c}-Rp^{w}-t'\right)=0\] - -\end_inset - -or -\begin_inset Formula \begin{equation} -t'=\frac{1}{n}\sum\left(p^{c}-Rp^{w}\right)=\bar{p}^{c}-R\bar{p}^{w}\label{eq:t}\end{equation} - -\end_inset - -here -\begin_inset Formula $\bar{p}^{c}$ -\end_inset - - and -\begin_inset Formula $\bar{p}^{w}$ -\end_inset - - are the point cloud centroids. - Substituting back into -\begin_inset CommandInset ref -LatexCommand eqref -reference "eq:J" - -\end_inset - -, we get -\begin_inset Formula \[ -\frac{1}{2}\sum\left(p^{c}-R(p^{w}-t)\right)^{2}=\frac{1}{2}\sum\left(\left(p^{c}-\bar{p}^{c}\right)-R\left(p^{w}-\bar{p}^{w}\right)\right)^{2}=\frac{1}{2}\sum\left(\hat{p}^{c}-R\hat{p}^{w}\right)^{2}\] - -\end_inset - -Now, to minimize the above it suffices to maximize (see CVOnline) -\begin_inset Formula \[ -\mathop{trace}\left(R^{T}C\right)\] - -\end_inset - -where -\begin_inset Formula $C=\sum\hat{p}^{c}\left(\hat{p}^{w}\right)^{T}$ -\end_inset - - is the correlation matrix. - Intuitively, the cloud of points is rotated to align with the principal - axes. - This can be achieved by SVD decomposition on -\begin_inset Formula $C$ -\end_inset - - -\begin_inset Formula \[ -C=USV^{T}\] - -\end_inset - -and setting -\begin_inset Formula \[ -R=UV^{T}\] - -\end_inset - -Clearly, from -\begin_inset CommandInset ref -LatexCommand eqref -reference "eq:t" - -\end_inset - - we then also recover the optimal -\begin_inset Formula $t$ -\end_inset - - as -\begin_inset Formula \[ -t=\bar{p}^{w}-R^{T}\bar{p}^{c}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset CommandInset bibtex -LatexCommand bibtex -bibfiles "/Users/dellaert/papers/refs" -options "plain" - -\end_inset - - -\end_layout - -\end_body -\end_document diff --git a/doc/math.pdf b/doc/math.pdf deleted file mode 100644 index 98e3fd758..000000000 Binary files a/doc/math.pdf and /dev/null differ diff --git a/gtsam-broken.h b/gtsam-broken.h deleted file mode 100644 index dd4ec379c..000000000 --- a/gtsam-broken.h +++ /dev/null @@ -1,144 +0,0 @@ -// These are currently broken -// Solve by parsing a namespace pose2SLAM::Values and making a Pose2SLAMValues class -// We also have to solve the shared pointer mess to avoid duplicate methods - -class GaussianFactor { - GaussianFactor(string key1, - Matrix A1, - Vector b_in, - const SharedDiagonal& model); - GaussianFactor(string key1, - Matrix A1, - string key2, - Matrix A2, - Vector b_in, - const SharedDiagonal& model); - GaussianFactor(string key1, - Matrix A1, - string key2, - Matrix A2, - string key3, - Matrix A3, - Vector b_in, - const SharedDiagonal& model); - bool involves(string key) const; - Matrix getA(string key) const; - pair matrix(const Ordering& ordering) const; - pair eliminate(string key) const; -}; - -class GaussianConditional { - GaussianConditional(string key, - Vector d, - Matrix R, - Vector sigmas); - GaussianConditional(string key, - Vector d, - Matrix R, - string name1, - Matrix S, - Vector sigmas); - GaussianConditional(string key, - Vector d, - Matrix R, - string name1, - Matrix S, - string name2, - Matrix T, - Vector sigmas); - void add(string key, Matrix S); -}; - -class GaussianFactorGraph { - GaussianConditional* eliminateOne(string key); - GaussianBayesNet* eliminate_(const Ordering& ordering); - VectorValues* optimize_(const Ordering& ordering); - pair matrix(const Ordering& ordering) const; - Matrix sparse(const Ordering& ordering) const; - VectorValues* steepestDescent_(const VectorValues& x0) const; - VectorValues* conjugateGradientDescent_(const VectorValues& x0) const; -}; - - -class Pose2Values{ - Pose2Values(); - Pose2 get(string key) const; - void insert(string name, const Pose2& val); - void print(string s) const; - void clear(); - int size(); -}; - -class Pose2Factor { - Pose2Factor(string key1, string key2, - const Pose2& measured, Matrix measurement_covariance); - void print(string name) const; - double error(const Pose2Values& c) const; - size_t size() const; - GaussianFactor* linearize(const Pose2Values& config) const; -}; - -class Pose2Graph{ - Pose2Graph(); - void print(string s) const; - GaussianFactorGraph* linearize_(const Pose2Values& config) const; - void push_back(Pose2Factor* factor); -}; - -class Ordering{ - Ordering(string key); - Ordering subtract(const Ordering& keys) const; - void unique (); - void reverse (); -}; - - -class SymbolicFactor{ - SymbolicFactor(const Ordering& keys); - void print(string s) const; -}; - - -class VectorValues { - void insert(string name, Vector val); - Vector get(string name) const; - bool contains(string name) const; -}; - -class Simulated2DPosePrior { - GaussianFactor* linearize(const Simulated2DValues& config) const; -}; - -class Simulated2DOrientedPosePrior { - GaussianFactor* linearize(const Simulated2DOrientedValues& config) const; -}; - -class Simulated2DPointPrior { - GaussianFactor* linearize(const Simulated2DValues& config) const; -}; - -class Simulated2DOdometry { - GaussianFactor* linearize(const Simulated2DValues& config) const; -}; - -class Simulated2DOrientedOdometry { - GaussianFactor* linearize(const Simulated2DOrientedValues& config) const; -}; - -class Simulated2DMeasurement { - GaussianFactor* linearize(const Simulated2DValues& config) const; -}; - -class Pose2SLAMOptimizer { - Pose2SLAMOptimizer(string dataset_name); - void print(string s) const; - void update(Vector x) const; - Vector optimize() const; - double error() const; - Matrix a1() const; - Matrix a2() const; - Vector b1() const; - Vector b2() const; -}; - - diff --git a/gtsam.h b/gtsam.h deleted file mode 100644 index 268b8b2fe..000000000 --- a/gtsam.h +++ /dev/null @@ -1,160 +0,0 @@ -class SharedGaussian { - SharedGaussian(Matrix covariance); - SharedGaussian(Vector sigmas); -}; - -class SharedDiagonal { - SharedDiagonal(Vector sigmas); -}; - -class Ordering { - Ordering(); - void print(string s) const; - bool equals(const Ordering& ord, double tol) const; - void push_back(string s); -}; - - -class VectorValues { - VectorValues(); - VectorValues(size_t nVars, size_t varDim); - void print(string s) const; - bool equals(const VectorValues& expected, double tol) const; - size_t size() const; -}; - -class GaussianFactor { - void print(string s) const; - bool equals(const GaussianFactor& lf, double tol) const; - bool empty() const; - Vector getb() const; - double error(const VectorValues& c) const; -}; - -class GaussianFactorSet { - GaussianFactorSet(); - void push_back(GaussianFactor* factor); -}; - -class GaussianConditional { - GaussianConditional(); - void print(string s) const; - bool equals(const GaussianConditional &cg, double tol) const; - Vector solve(const VectorValues& x); -}; - -class GaussianBayesNet { - GaussianBayesNet(); - void print(string s) const; - bool equals(const GaussianBayesNet& cbn, double tol) const; - void push_back(GaussianConditional* conditional); - void push_front(GaussianConditional* conditional); -}; - -class GaussianFactorGraph { - GaussianFactorGraph(); - void print(string s) const; - bool equals(const GaussianFactorGraph& lfgraph, double tol) const; - - size_t size() const; - void push_back(GaussianFactor* ptr_f); - double error(const VectorValues& c) const; - double probPrime(const VectorValues& c) const; - void combine(const GaussianFactorGraph& lfg); -}; - -class Point2 { - Point2(); - Point2(double x, double y); - void print(string s) const; - double x(); - double y(); -}; - -class Point3 { - Point3(); - Point3(double x, double y, double z); - Point3(Vector v); - void print(string s) const; - Vector vector() const; - double x(); - double y(); - double z(); -}; - -class Pose2 { - Pose2(); - Pose2(const Pose2& pose); - Pose2(double x, double y, double theta); - Pose2(double theta, const Point2& t); - Pose2(const Rot2& r, const Point2& t); - void print(string s) const; - bool equals(const Pose2& pose, double tol) const; - double x() const; - double y() const; - double theta() const; - size_t dim() const; - Pose2 expmap(const Vector& v) const; - Vector logmap(const Pose2& pose) const; - Point2 t() const; - Rot2 r() const; -}; - -class Simulated2DValues { - Simulated2DValues(); - void print(string s) const; - void insertPose(int i, const Point2& p); - void insertPoint(int j, const Point2& p); - int nrPoses() const; - int nrPoints() const; - Point2* pose(int i); - Point2* point(int j); -}; - -class Simulated2DOrientedValues { - Simulated2DOrientedValues(); - void print(string s) const; - void insertPose(int i, const Pose2& p); - void insertPoint(int j, const Point2& p); - int nrPoses() const; - int nrPoints() const; - Pose2* pose(int i); - Point2* point(int j); -}; - -class Simulated2DPosePrior { - Simulated2DPosePrior(Point2& mu, const SharedDiagonal& model, int i); - void print(string s) const; - double error(const Simulated2DValues& c) const; -}; - -class Simulated2DOrientedPosePrior { - Simulated2DOrientedPosePrior(Pose2& mu, const SharedDiagonal& model, int i); - void print(string s) const; - double error(const Simulated2DOrientedValues& c) const; -}; - -class Simulated2DPointPrior { - Simulated2DPointPrior(Point2& mu, const SharedDiagonal& model, int i); - void print(string s) const; - double error(const Simulated2DValues& c) const; -}; - -class Simulated2DOdometry { - Simulated2DOdometry(Point2& mu, const SharedDiagonal& model, int i1, int i2); - void print(string s) const; - double error(const Simulated2DValues& c) const; -}; - -class Simulated2DOrientedOdometry { - Simulated2DOrientedOdometry(Pose2& mu, const SharedDiagonal& model, int i1, int i2); - void print(string s) const; - double error(const Simulated2DOrientedValues& c) const; -}; - -class Simulated2DMeasurement { - Simulated2DMeasurement(Point2& mu, const SharedDiagonal& model, int i, int j); - void print(string s) const; - double error(const Simulated2DValues& c) const; -}; - diff --git a/wrap/.cvsignore b/wrap/.cvsignore deleted file mode 100644 index e9c87a8fc..000000000 --- a/wrap/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -Makefile -Makefile.in -wrap -.deps -.DS_Store diff --git a/wrap/Argument.cpp b/wrap/Argument.cpp deleted file mode 100644 index e44b3033c..000000000 --- a/wrap/Argument.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Argument.ccp - * Author: Frank Dellaert - **/ - -#include -#include -#include -#include - -#include "Argument.h" - -using namespace std; - -/* ************************************************************************* */ -void Argument::matlab_unwrap(ofstream& ofs, - const string& matlabName) -{ - // the templated unwrap function returns a pointer - // example: double tol = unwrap< double >(in[2]); - ofs << " "; - - if (is_ptr) - ofs << "shared_ptr<" << type << "> " << name << " = unwrap_shared_ptr< "; - else if (is_ref) - ofs << type << "& " << name << " = *unwrap_shared_ptr< "; - else - ofs << type << " " << name << " = unwrap< "; - - ofs << type << " >(" << matlabName; - if (is_ptr || is_ref) ofs << ", \"" << type << "\""; - ofs << ");" << endl; -} - -/* ************************************************************************* */ -string ArgumentList::types() { - string str; - bool first=true; - BOOST_FOREACH(Argument arg, *this) { - if (!first) str += ","; str += arg.type; first=false; - } - return str; -} - -/* ************************************************************************* */ -string ArgumentList::signature() { - string str; - BOOST_FOREACH(Argument arg, *this) - str += arg.type[0]; - return str; -} - -/* ************************************************************************* */ -string ArgumentList::names() { - string str; - bool first=true; - BOOST_FOREACH(Argument arg, *this) { - if (!first) str += ","; str += arg.name; first=false; - } - return str; -} - -/* ************************************************************************* */ -void ArgumentList::matlab_unwrap(ofstream& ofs, int start) { - int index = start; - BOOST_FOREACH(Argument arg, *this) { - stringstream buf; - buf << "in[" << index << "]"; - arg.matlab_unwrap(ofs,buf.str()); - index++; - } -} - -/* ************************************************************************* */ diff --git a/wrap/Argument.h b/wrap/Argument.h deleted file mode 100644 index 73c3ca12f..000000000 --- a/wrap/Argument.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Argument.h - * brief: arguments to constructors and methods - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -// Argument class -struct Argument { - bool is_const, is_ref, is_ptr; - std::string type; - std::string name; -Argument() : is_const(false), is_ref(false), is_ptr(false) {} - - // MATLAB code generation: - void matlab_unwrap(std::ofstream& ofs, - const std::string& matlabName); // MATLAB to C++ -}; - -// Argument list -struct ArgumentList : public std::list { - std::list args; - std::string types (); - std::string signature(); - std::string names (); - - // MATLAB code generation: - - /** - * emit code to unwrap arguments - * @param ofs output stream - * @param start initial index for input array, set to 1 for method - */ - void matlab_unwrap(std::ofstream& ofs, int start=0); // MATLAB to C++ -}; - diff --git a/wrap/Class.cpp b/wrap/Class.cpp deleted file mode 100644 index de1620733..000000000 --- a/wrap/Class.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Class.ccp - * Author: Frank Dellaert - **/ - -#include -#include - -#include - -#include "Class.h" -#include "utilities.h" - -using namespace std; - -/* ************************************************************************* */ -void Class::matlab_proxy(const string& classFile) { - // open destination classFile - ofstream ofs(classFile.c_str()); - if(!ofs) throw CantOpenFile(classFile); - if(verbose_) cerr << "generating " << classFile << endl; - - // emit class proxy code - emit_header_comment(ofs,"%"); - ofs << "classdef " << name << endl; - ofs << " properties" << endl; - ofs << " self = 0" << endl; - ofs << " end" << endl; - ofs << " methods" << endl; - ofs << " function obj = " << name << "(varargin)" << endl; - BOOST_FOREACH(Constructor c, constructors) - c.matlab_proxy_fragment(ofs,name); - ofs << " if nargin ~= 13 && obj.self == 0, error('" << name << " constructor failed'); end" << endl; - ofs << " end" << endl; - ofs << " function display(obj), obj.print(''); end" << endl; - ofs << " function disp(obj), obj.display; end" << endl; - ofs << " end" << endl; - ofs << "end" << endl; - - // close file - ofs.close(); -} - -/* ************************************************************************* */ -void Class::matlab_constructors(const string& toolboxPath,const string& nameSpace) { - BOOST_FOREACH(Constructor c, constructors) { - c.matlab_mfile (toolboxPath, name); - c.matlab_wrapper(toolboxPath, name, nameSpace); - } -} - -/* ************************************************************************* */ -void Class::matlab_methods(const string& classPath, const string& nameSpace) { - BOOST_FOREACH(Method m, methods) { - m.matlab_mfile (classPath); - m.matlab_wrapper(classPath, name, nameSpace); - } -} - -/* ************************************************************************* */ -void Class::matlab_make_fragment(ofstream& ofs, - const string& toolboxPath, - const string& mexFlags) -{ - string mex = "mex " + mexFlags + " "; - BOOST_FOREACH(Constructor c, constructors) - ofs << mex << c.matlab_wrapper_name(name) << ".cpp" << endl; - ofs << endl << "cd @" << name << endl; - BOOST_FOREACH(Method m, methods) - ofs << mex << m.name << ".cpp" << endl; - ofs << endl; -} - -/* ************************************************************************* */ diff --git a/wrap/Class.h b/wrap/Class.h deleted file mode 100644 index f00812b95..000000000 --- a/wrap/Class.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Class.h - * brief: describe the C++ class that is being wrapped - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -#include "Constructor.h" -#include "Method.h" - -// Class has name, constructors, methods -struct Class { - std::string name; - std::list constructors; - std::list methods; - bool verbose_; - - Class(bool verbose=true) : verbose_(verbose) {} - - // MATLAB code generation: - void matlab_proxy(const std::string& classFile); // proxy class - void matlab_constructors(const std::string& toolboxPath, - const std::string& nameSpace); // constructor wrappers - void matlab_methods(const std::string& classPath, - const std::string& nameSpace); // method wrappers - void matlab_make_fragment(std::ofstream& ofs, - const std::string& toolboxPath, - const std::string& mexFlags); // make fragment -}; - diff --git a/wrap/Constructor.cpp b/wrap/Constructor.cpp deleted file mode 100644 index d26e16a07..000000000 --- a/wrap/Constructor.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Constructor.ccp - * Author: Frank Dellaert - **/ - -#include -#include - -#include - -#include "utilities.h" -#include "Constructor.h" - -using namespace std; - -/* ************************************************************************* */ -string Constructor::matlab_wrapper_name(const string& className) { - string str = "new_" + className + "_" + args.signature(); - return str; -} - -/* ************************************************************************* */ -void Constructor::matlab_proxy_fragment(ofstream& ofs, const string& className) { - ofs << " if nargin == " << args.size() << ", obj.self = " - << matlab_wrapper_name(className) << "("; - bool first = true; - for(size_t i=0;i" << endl; - ofs << "#include <" << className << ".h>" << endl; - if (!nameSpace.empty()) ofs << "using namespace " << nameSpace << ";" << endl; - ofs << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])" << endl; - ofs << "{" << endl; - ofs << " checkArguments(\"" << name << "\",nargout,nargin," << args.size() << ");" << endl; - args.matlab_unwrap(ofs); // unwrap arguments - ofs << " " << className << "* self = new " << className << "(" << args.names() << ");" << endl; - ofs << " out[0] = wrap_constructed(self,\"" << className << "\");" << endl; - ofs << "}" << endl; - - // close file - ofs.close(); -} - -/* ************************************************************************* */ diff --git a/wrap/Constructor.h b/wrap/Constructor.h deleted file mode 100644 index 0a15c06d1..000000000 --- a/wrap/Constructor.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Constructor.h - * brief: class describing a constructor + code generation - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -#include "Argument.h" - -// Constructor class -struct Constructor { - ArgumentList args; - bool verbose_; - - Constructor(bool verbose=true) : verbose_(verbose) {} - - // MATLAB code generation - // toolboxPath is main toolbox directory, e.g., ../matlab - // classFile is class proxy file, e.g., ../matlab/@Point2/Point2.m - - std::string matlab_wrapper_name(const std::string& className); // wrapper name - void matlab_proxy_fragment(std::ofstream& ofs, const std::string& className); // proxy class fragment - void matlab_mfile (const std::string& toolboxPath, const std::string& className); // m-file - void matlab_wrapper(const std::string& toolboxPath, - const std::string& className, - const std::string& nameSpace); // wrapper -}; - diff --git a/wrap/Makefile.am b/wrap/Makefile.am deleted file mode 100644 index 620dab26e..000000000 --- a/wrap/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -common = utilities.cpp Argument.cpp Constructor.cpp Method.cpp Class.cpp Module.cpp - -check_PROGRAMS = testSpirit testWrap -testSpirit_SOURCES = testSpirit.cpp -testWrap_SOURCES = testWrap.cpp ${common} - -# generate local toolbox dir -interfacePath = $(top_srcdir) -moduleName = gtsam -toolboxpath = ../toolbox -nameSpace = "gtsam" -mexFlags = "${BOOST_CPPFLAGS} -I${prefix}/include -I${prefix}/include/gtsam/linear -I${prefix}/include/gtsam/nonlinear -I${prefix}/include/gtsam/base -I${prefix}/include/gtsam/geometry -I${prefix}/include/gtsam/slam -L${exec_prefix}/lib -lgtsam" -all: - ./wrap ${interfacePath} ${moduleName} ${toolboxpath} ${nameSpace} ${mexFlags} - -# install the header files -noinst_HEADERS = geometry.h utilities.h Argument.h Constructor.h Method.h Class.h Module.h wrap-matlab.h - -noinst_PROGRAMS = wrap -wrap_SOURCES = ${common} wrap.cpp -AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(top_srcdir) -DTOPSRCDIR="\"$(top_srcdir)\"" -AM_CXXFLAGS = -MMD -AM_LDFLAGS = $(BOOST_LDFLAGS) -L../CppUnitLite -lCppUnitLite - -TESTS = $(check_PROGRAMS) - -# install the headers and matlab toolbox -install-exec-hook: all - install -d ${toolbox}/gtsam && \ - cp -rf ../toolbox/* ${toolbox}/gtsam && \ - install -d ${includedir}/wrap && \ - cp -f ${srcdir}/wrap-matlab.h ${includedir}/wrap/matlab.h - -# clean local toolbox dir -clean: - @test -z "wrap" || rm -f wrap - @test -z "../toolbox" || rm -rf ../toolbox - -# rule to run an executable -%.run: % libgtsam.la - ./$^ diff --git a/wrap/Method.cpp b/wrap/Method.cpp deleted file mode 100644 index cec6391bb..000000000 --- a/wrap/Method.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Method.ccp - * Author: Frank Dellaert - **/ - -#include -#include - -#include - -#include "Method.h" -#include "utilities.h" - -using namespace std; - -/* ************************************************************************* */ -// auxiliary function to wrap an argument into a shared_ptr template -/* ************************************************************************* */ -string maybe_shared_ptr(bool add, const string& type) { - string str = add? "shared_ptr<" : ""; - str += type; - if (add) str += ">"; - return str; -} - -/* ************************************************************************* */ -string Method::return_type(bool add_ptr, pairing p) { - if (p==pair && returns_pair) { - string str = "pair< " + - maybe_shared_ptr(add_ptr && returns_ptr, returns ) + ", " + - maybe_shared_ptr(add_ptr && returns_ptr, returns2) + " >"; - return str; - } else - return maybe_shared_ptr(add_ptr && returns_ptr, (p==arg2)? returns2 : returns); -} - -/* ************************************************************************* */ -void Method::matlab_mfile(const string& classPath) { - - // open destination m-file - string wrapperFile = classPath + "/" + name + ".m"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; - - // generate code - emit_header_comment(ofs, "%"); - ofs << "% usage: obj." << name << "(" << args.names() << ")" << endl; - string returnType = returns_pair? "[first,second]" : "result"; - ofs << "function " << returnType << " = " << name << "(obj"; - if (args.size()) ofs << "," << args.names(); - ofs << ")" << endl; - ofs << " error('need to compile " << name << ".cpp');" << endl; - ofs << "end" << endl; - - // close file - ofs.close(); -} - -/* ************************************************************************* */ -void Method::matlab_wrapper(const string& classPath, - const string& className, - const string& nameSpace) -{ - // open destination wrapperFile - string wrapperFile = classPath + "/" + name + ".cpp"; - ofstream ofs(wrapperFile.c_str()); - if(!ofs) throw CantOpenFile(wrapperFile); - if(verbose_) cerr << "generating " << wrapperFile << endl; - - // generate code - - // header - emit_header_comment(ofs, "//"); - ofs << "#include \n"; - ofs << "#include <" << className << ".h>\n"; - if (!nameSpace.empty()) ofs << "using namespace " << nameSpace << ";" << endl; - - // call - ofs << "void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])\n"; - // start - ofs << "{\n"; - - // check arguments - // extra argument obj -> nargin-1 is passed ! - // example: checkArguments("equals",nargout,nargin-1,2); - ofs << " checkArguments(\"" << name << "\",nargout,nargin-1," << args.size() << ");\n"; - - // get class pointer - // example: shared_ptr = unwrap_shared_ptr< Test >(in[0], "Test"); - ofs << " shared_ptr<" << className << "> self = unwrap_shared_ptr< " << className - << " >(in[0],\"" << className << "\");" << endl; - - // unwrap arguments, see Argument.cpp - args.matlab_unwrap(ofs,1); - - // call method - // example: bool result = self->return_field(t); - ofs << " "; - if (returns!="void") - ofs << return_type(true,pair) << " result = "; - ofs << "self->" << name << "(" << args.names() << ");\n"; - - // wrap result - // example: out[0]=wrap(result); - if (returns_pair) { - if (returns_ptr) - ofs << " out[0] = wrap_shared_ptr(result.first,\"" << returns << "\");\n"; - else - ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result.first);\n"; - if (returns_ptr2) - ofs << " out[1] = wrap_shared_ptr(result.second,\"" << returns2 << "\");\n"; - else - ofs << " out[1] = wrap< " << return_type(true,arg2) << " >(result.second);\n"; - } - else if (returns_ptr) - ofs << " out[0] = wrap_shared_ptr(result,\"" << returns << "\");\n"; - else if (returns!="void") - ofs << " out[0] = wrap< " << return_type(true,arg1) << " >(result);\n"; - - // finish - ofs << "}\n"; - - // close file - ofs.close(); -} - -/* ************************************************************************* */ diff --git a/wrap/Method.h b/wrap/Method.h deleted file mode 100644 index 8666f74ac..000000000 --- a/wrap/Method.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Method.h - * brief: describes and generates code for methods - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -#include "Argument.h" - -// Method class -struct Method { - bool is_const; - ArgumentList args; - std::string returns, returns2, name; - bool returns_ptr, returns_ptr2, returns_pair; - bool verbose_; - - Method(bool verbose=true) : returns_ptr(false), returns_ptr2(false), returns_pair(false), verbose_(verbose) {} - - enum pairing {arg1, arg2, pair}; - std::string return_type(bool add_ptr, pairing p); - - // MATLAB code generation - // classPath is class directory, e.g., ../matlab/@Point2 - - void matlab_mfile (const std::string& classPath); // m-file - void matlab_wrapper(const std::string& classPath, - const std::string& className, - const std::string& nameSpace); // wrapper -}; - diff --git a/wrap/Module.cpp b/wrap/Module.cpp deleted file mode 100644 index 82977e336..000000000 --- a/wrap/Module.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Module.ccp - * Author: Frank Dellaert - **/ - -#include -#include - -//#define BOOST_SPIRIT_DEBUG -#include -#include - -#include "Module.h" -#include "utilities.h" - -using namespace std; -using namespace BOOST_SPIRIT_CLASSIC_NS; - -typedef rule Rule; - -/* ************************************************************************* */ -// We parse an interface file into a Module object. -// The grammar is defined using the boost/spirit combinatorial parser. -// For example, str_p("const") parses the string "const", and the >> -// operator creates a sequence parser. The grammar below, composed of rules -// and with start rule [class_p], doubles as the specs for our interface files. -/* ************************************************************************* */ - -Module::Module(const string& interfacePath, - const string& moduleName, bool verbose) : name(moduleName), verbose_(verbose) -{ - // these variables will be imperatively updated to gradually build [cls] - // The one with postfix 0 are used to reset the variables after parse. - Argument arg0, arg; - ArgumentList args0, args; - Constructor constructor0(verbose), constructor(verbose); - Method method0(verbose), method(verbose); - Class cls0(verbose),cls(verbose); - - //---------------------------------------------------------------------------- - // Grammar with actions that build the Class object. Actions are - // defined within the square brackets [] and are executed whenever a - // rule is successfully parsed. Define BOOST_SPIRIT_DEBUG to debug. - // The grammar is allows a very restricted C++ header: - // - No comments allowed. - // -Only types allowed are string, bool, size_t int, double, Vector, and Matrix - // as well as class names that start with an uppercase letter - // - The types unsigned int and bool should be specified as int. - // ---------------------------------------------------------------------------- - - // lexeme_d turns off white space skipping - // http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html - - Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')]; - - Rule classPtr_p = - className_p [assign_a(arg.type)] >> - ch_p('*') [assign_a(arg.is_ptr,true)]; - - Rule classRef_p = - !str_p("const") [assign_a(arg.is_const,true)] >> - className_p [assign_a(arg.type)] >> - ch_p('&') [assign_a(arg.is_ref,true)]; - - Rule basisType_p = - (str_p("string") | "bool" | "size_t" | "int" | "double"); - - Rule ublasType = - (str_p("Vector") | "Matrix")[assign_a(arg.type)] >> - !ch_p('*')[assign_a(arg.is_ptr,true)]; - - Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')]; - - Rule argument_p = - ((basisType_p[assign_a(arg.type)] | ublasType | classPtr_p | classRef_p) >> name_p[assign_a(arg.name)]) - [push_back_a(args, arg)] - [assign_a(arg,arg0)]; - - Rule argumentList_p = !argument_p >> * (',' >> argument_p); - - Rule constructor_p = - (className_p >> '(' >> argumentList_p >> ')' >> ';') - [assign_a(constructor.args,args)] - [assign_a(args,args0)] - [push_back_a(cls.constructors, constructor)] - [assign_a(constructor,constructor0)]; - - Rule returnType1_p = - basisType_p[assign_a(method.returns)] | - ((className_p | "Vector" | "Matrix")[assign_a(method.returns)] >> - !ch_p('*') [assign_a(method.returns_ptr,true)]); - - Rule returnType2_p = - basisType_p[assign_a(method.returns2)] | - ((className_p | "Vector" | "Matrix")[assign_a(method.returns2)] >> - !ch_p('*') [assign_a(method.returns_ptr2,true)]); - - Rule pair_p = - (str_p("pair") >> '<' >> returnType1_p >> ',' >> returnType2_p >> '>') - [assign_a(method.returns_pair,true)]; - - Rule void_p = str_p("void")[assign_a(method.returns)]; - - Rule returnType_p = void_p | returnType1_p | pair_p; - - Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')]; - - Rule method_p = - (returnType_p >> methodName_p[assign_a(method.name)] >> - '(' >> argumentList_p >> ')' >> - !str_p("const")[assign_a(method.is_const,true)] >> ';') - [assign_a(method.args,args)] - [assign_a(args,args0)] - [push_back_a(cls.methods, method)] - [assign_a(method,method0)]; - - Rule class_p = str_p("class") >> className_p[assign_a(cls.name)] >> '{' >> - *constructor_p >> - *method_p >> - '}' >> ";"; - - Rule module_p = +class_p - [push_back_a(classes,cls)] - [assign_a(cls,cls0)] - >> !end_p; - - //---------------------------------------------------------------------------- - // for debugging, define BOOST_SPIRIT_DEBUG -# ifdef BOOST_SPIRIT_DEBUG - BOOST_SPIRIT_DEBUG_NODE(className_p); - BOOST_SPIRIT_DEBUG_NODE(classPtr_p); - BOOST_SPIRIT_DEBUG_NODE(classRef_p); - BOOST_SPIRIT_DEBUG_NODE(basisType_p); - BOOST_SPIRIT_DEBUG_NODE(name_p); - BOOST_SPIRIT_DEBUG_NODE(argument_p); - BOOST_SPIRIT_DEBUG_NODE(argumentList_p); - BOOST_SPIRIT_DEBUG_NODE(constructor_p); - BOOST_SPIRIT_DEBUG_NODE(returnType1_p); - BOOST_SPIRIT_DEBUG_NODE(returnType2_p); - BOOST_SPIRIT_DEBUG_NODE(pair_p); - BOOST_SPIRIT_DEBUG_NODE(void_p); - BOOST_SPIRIT_DEBUG_NODE(returnType_p); - BOOST_SPIRIT_DEBUG_NODE(methodName_p); - BOOST_SPIRIT_DEBUG_NODE(method_p); - BOOST_SPIRIT_DEBUG_NODE(class_p); - BOOST_SPIRIT_DEBUG_NODE(module_p); -# endif - //---------------------------------------------------------------------------- - - // read interface file - string interfaceFile = interfacePath + "/" + moduleName + ".h"; - string contents = file_contents(interfaceFile); - - // Comment parser : does not work for some reason - rule<> comment_p = str_p("/*") >> +anychar_p >> "*/"; - rule<> skip_p = space_p; // | comment_p; - - // and parse contents - parse_info info = parse(contents.c_str(), module_p, skip_p); - if(!info.full) { - printf("parsing stopped at \n%.20s\n",info.stop); - throw ParseFailed(info.length); - } -} - -/* ************************************************************************* */ -void Module::matlab_code(const string& toolboxPath, - const string& nameSpace, - const string& mexFlags) -{ - try { - string installCmd = "install -d " + toolboxPath; - system(installCmd.c_str()); - - // create make m-file - string makeFile = toolboxPath + "/make_" + name + ".m"; - ofstream ofs(makeFile.c_str()); - if(!ofs) throw CantOpenFile(makeFile); - - if (verbose_) cerr << "generating " << makeFile << endl; - emit_header_comment(ofs,"%"); - ofs << "echo on" << endl << endl; - ofs << "toolboxpath = pwd" << endl; - ofs << "addpath(toolboxpath);" << endl << endl; - - // generate proxy classes and wrappers - BOOST_FOREACH(Class cls, classes) { - // create directory if needed - string classPath = toolboxPath + "/@" + cls.name; - string installCmd = "install -d " + classPath; - system(installCmd.c_str()); - - // create proxy class - string classFile = classPath + "/" + cls.name + ".m"; - cls.matlab_proxy(classFile); - - // create constructor and method wrappers - cls.matlab_constructors(toolboxPath,nameSpace); - cls.matlab_methods(classPath,nameSpace); - - // add lines to make m-file - ofs << "cd(toolboxpath)" << endl; - cls.matlab_make_fragment(ofs, toolboxPath, mexFlags); - } - - // finish make m-file - ofs << "cd(toolboxpath)" << endl << endl; - ofs << "echo off" << endl; - ofs.close(); - } - catch(exception &e) { - cerr << "generate_matlab_toolbox failed because " << e.what() << endl; - } - -} - -/* ************************************************************************* */ diff --git a/wrap/Module.h b/wrap/Module.h deleted file mode 100644 index 5ee1248ca..000000000 --- a/wrap/Module.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: Module.h - * brief: describes module to be wrapped - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -#include "Class.h" - -// A module has classes -struct Module { - std::string name; - std::list classes; - bool verbose_; - - /** - * constructor that parses interface file - */ - Module(const std::string& interfacePath, - const std::string& moduleName, - bool verbose=true); - - /** - * MATLAB code generation: - */ - void matlab_code(const std::string& path, - const std::string& nameSpace, - const std::string& mexFlags); -}; - diff --git a/wrap/expected/@Point2/Point2.m b/wrap/expected/@Point2/Point2.m deleted file mode 100644 index 9cdfd6fd5..000000000 --- a/wrap/expected/@Point2/Point2.m +++ /dev/null @@ -1,15 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -classdef Point2 - properties - self = 0 - end - methods - function obj = Point2(varargin) - if nargin == 0, obj.self = new_Point2_(); end - if nargin == 2, obj.self = new_Point2_dd(varargin{1},varargin{2}); end - if nargin ~= 13 && obj.self == 0, error('Point2 constructor failed'); end - end - function display(obj), obj.print(''); end - function disp(obj), obj.display; end - end -end diff --git a/wrap/expected/@Point2/dim.cpp b/wrap/expected/@Point2/dim.cpp deleted file mode 100644 index 2955d58c3..000000000 --- a/wrap/expected/@Point2/dim.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("dim",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Point2 >(in[0],"Point2"); - int result = self->dim(); - out[0] = wrap< int >(result); -} diff --git a/wrap/expected/@Point2/dim.m b/wrap/expected/@Point2/dim.m deleted file mode 100644 index 93caab12f..000000000 --- a/wrap/expected/@Point2/dim.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.dim() -function result = dim(obj) - error('need to compile dim.cpp'); -end diff --git a/wrap/expected/@Point2/x.cpp b/wrap/expected/@Point2/x.cpp deleted file mode 100644 index 5f98d17c6..000000000 --- a/wrap/expected/@Point2/x.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("x",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Point2 >(in[0],"Point2"); - double result = self->x(); - out[0] = wrap< double >(result); -} diff --git a/wrap/expected/@Point2/x.m b/wrap/expected/@Point2/x.m deleted file mode 100644 index 4dae83bf5..000000000 --- a/wrap/expected/@Point2/x.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.x() -function result = x(obj) - error('need to compile x.cpp'); -end diff --git a/wrap/expected/@Point2/y.cpp b/wrap/expected/@Point2/y.cpp deleted file mode 100644 index 835aa8a1e..000000000 --- a/wrap/expected/@Point2/y.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("y",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Point2 >(in[0],"Point2"); - double result = self->y(); - out[0] = wrap< double >(result); -} diff --git a/wrap/expected/@Point2/y.m b/wrap/expected/@Point2/y.m deleted file mode 100644 index 9e2897114..000000000 --- a/wrap/expected/@Point2/y.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.y() -function result = y(obj) - error('need to compile y.cpp'); -end diff --git a/wrap/expected/@Point3/Point3.m b/wrap/expected/@Point3/Point3.m deleted file mode 100644 index 139c7d079..000000000 --- a/wrap/expected/@Point3/Point3.m +++ /dev/null @@ -1,14 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -classdef Point3 - properties - self = 0 - end - methods - function obj = Point3(varargin) - if nargin == 3, obj.self = new_Point3_ddd(varargin{1},varargin{2},varargin{3}); end - if nargin ~= 13 && obj.self == 0, error('Point3 constructor failed'); end - end - function display(obj), obj.print(''); end - function disp(obj), obj.display; end - end -end diff --git a/wrap/expected/@Point3/norm.cpp b/wrap/expected/@Point3/norm.cpp deleted file mode 100644 index 37ad329ce..000000000 --- a/wrap/expected/@Point3/norm.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("norm",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Point3 >(in[0],"Point3"); - double result = self->norm(); - out[0] = wrap< double >(result); -} diff --git a/wrap/expected/@Point3/norm.m b/wrap/expected/@Point3/norm.m deleted file mode 100644 index 02943303f..000000000 --- a/wrap/expected/@Point3/norm.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.norm() -function result = norm(obj) - error('need to compile norm.cpp'); -end diff --git a/wrap/expected/@Test/Test.m b/wrap/expected/@Test/Test.m deleted file mode 100644 index 31e5e35b2..000000000 --- a/wrap/expected/@Test/Test.m +++ /dev/null @@ -1,14 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -classdef Test - properties - self = 0 - end - methods - function obj = Test(varargin) - if nargin == 0, obj.self = new_Test_(); end - if nargin ~= 13 && obj.self == 0, error('Test constructor failed'); end - end - function display(obj), obj.print(''); end - function disp(obj), obj.display; end - end -end diff --git a/wrap/expected/@Test/create_ptrs.cpp b/wrap/expected/@Test/create_ptrs.cpp deleted file mode 100644 index 9a7215a60..000000000 --- a/wrap/expected/@Test/create_ptrs.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("create_ptrs",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - pair< shared_ptr, shared_ptr > result = self->create_ptrs(); - out[0] = wrap_shared_ptr(result.first,"Test"); - out[1] = wrap_shared_ptr(result.second,"Test"); -} diff --git a/wrap/expected/@Test/create_ptrs.m b/wrap/expected/@Test/create_ptrs.m deleted file mode 100644 index 0fbbd9be5..000000000 --- a/wrap/expected/@Test/create_ptrs.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.create_ptrs() -function [first,second] = create_ptrs(obj) - error('need to compile create_ptrs.cpp'); -end diff --git a/wrap/expected/@Test/print.cpp b/wrap/expected/@Test/print.cpp deleted file mode 100644 index 5db55477c..000000000 --- a/wrap/expected/@Test/print.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("print",nargout,nargin-1,0); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - self->print(); -} diff --git a/wrap/expected/@Test/print.m b/wrap/expected/@Test/print.m deleted file mode 100644 index 91e8ff31a..000000000 --- a/wrap/expected/@Test/print.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.print() -function result = print(obj) - error('need to compile print.cpp'); -end diff --git a/wrap/expected/@Test/return_TestPtr.cpp b/wrap/expected/@Test/return_TestPtr.cpp deleted file mode 100644 index 0c22621a6..000000000 --- a/wrap/expected/@Test/return_TestPtr.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_TestPtr",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - shared_ptr value = unwrap_shared_ptr< Test >(in[1], "Test"); - shared_ptr result = self->return_TestPtr(value); - out[0] = wrap_shared_ptr(result,"Test"); -} diff --git a/wrap/expected/@Test/return_TestPtr.m b/wrap/expected/@Test/return_TestPtr.m deleted file mode 100644 index 0753c283b..000000000 --- a/wrap/expected/@Test/return_TestPtr.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_TestPtr(value) -function result = return_TestPtr(obj,value) - error('need to compile return_TestPtr.cpp'); -end diff --git a/wrap/expected/@Test/return_bool.cpp b/wrap/expected/@Test/return_bool.cpp deleted file mode 100644 index d05f5c3b7..000000000 --- a/wrap/expected/@Test/return_bool.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_bool",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - bool value = unwrap< bool >(in[1]); - bool result = self->return_bool(value); - out[0] = wrap< bool >(result); -} diff --git a/wrap/expected/@Test/return_bool.m b/wrap/expected/@Test/return_bool.m deleted file mode 100644 index 3ef97ad8f..000000000 --- a/wrap/expected/@Test/return_bool.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_bool(value) -function result = return_bool(obj,value) - error('need to compile return_bool.cpp'); -end diff --git a/wrap/expected/@Test/return_double.cpp b/wrap/expected/@Test/return_double.cpp deleted file mode 100644 index edbffb889..000000000 --- a/wrap/expected/@Test/return_double.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_double",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - double value = unwrap< double >(in[1]); - double result = self->return_double(value); - out[0] = wrap< double >(result); -} diff --git a/wrap/expected/@Test/return_double.m b/wrap/expected/@Test/return_double.m deleted file mode 100644 index 87e2929da..000000000 --- a/wrap/expected/@Test/return_double.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_double(value) -function result = return_double(obj,value) - error('need to compile return_double.cpp'); -end diff --git a/wrap/expected/@Test/return_field.cpp b/wrap/expected/@Test/return_field.cpp deleted file mode 100644 index 727f6faa0..000000000 --- a/wrap/expected/@Test/return_field.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_field",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Test& t = *unwrap_shared_ptr< Test >(in[1], "Test"); - bool result = self->return_field(t); - out[0] = wrap< bool >(result); -} diff --git a/wrap/expected/@Test/return_field.m b/wrap/expected/@Test/return_field.m deleted file mode 100644 index 7e63e32e2..000000000 --- a/wrap/expected/@Test/return_field.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_field(t) -function result = return_field(obj,t) - error('need to compile return_field.cpp'); -end diff --git a/wrap/expected/@Test/return_int.cpp b/wrap/expected/@Test/return_int.cpp deleted file mode 100644 index 61b53f4ce..000000000 --- a/wrap/expected/@Test/return_int.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_int",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - int value = unwrap< int >(in[1]); - int result = self->return_int(value); - out[0] = wrap< int >(result); -} diff --git a/wrap/expected/@Test/return_int.m b/wrap/expected/@Test/return_int.m deleted file mode 100644 index df5502203..000000000 --- a/wrap/expected/@Test/return_int.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_int(value) -function result = return_int(obj,value) - error('need to compile return_int.cpp'); -end diff --git a/wrap/expected/@Test/return_matrix1.cpp b/wrap/expected/@Test/return_matrix1.cpp deleted file mode 100644 index c7b12ddad..000000000 --- a/wrap/expected/@Test/return_matrix1.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_matrix1",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Matrix value = unwrap< Matrix >(in[1]); - Matrix result = self->return_matrix1(value); - out[0] = wrap< Matrix >(result); -} diff --git a/wrap/expected/@Test/return_matrix1.m b/wrap/expected/@Test/return_matrix1.m deleted file mode 100644 index bb71670db..000000000 --- a/wrap/expected/@Test/return_matrix1.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_matrix1(value) -function result = return_matrix1(obj,value) - error('need to compile return_matrix1.cpp'); -end diff --git a/wrap/expected/@Test/return_matrix2.cpp b/wrap/expected/@Test/return_matrix2.cpp deleted file mode 100644 index e41cf5f96..000000000 --- a/wrap/expected/@Test/return_matrix2.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_matrix2",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Matrix value = unwrap< Matrix >(in[1]); - Matrix result = self->return_matrix2(value); - out[0] = wrap< Matrix >(result); -} diff --git a/wrap/expected/@Test/return_matrix2.m b/wrap/expected/@Test/return_matrix2.m deleted file mode 100644 index b8b74dd03..000000000 --- a/wrap/expected/@Test/return_matrix2.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_matrix2(value) -function result = return_matrix2(obj,value) - error('need to compile return_matrix2.cpp'); -end diff --git a/wrap/expected/@Test/return_pair.cpp b/wrap/expected/@Test/return_pair.cpp deleted file mode 100644 index 0e274049e..000000000 --- a/wrap/expected/@Test/return_pair.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_pair",nargout,nargin-1,2); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Vector v = unwrap< Vector >(in[1]); - Matrix A = unwrap< Matrix >(in[2]); - pair< Vector, Matrix > result = self->return_pair(v,A); - out[0] = wrap< Vector >(result.first); - out[1] = wrap< Matrix >(result.second); -} diff --git a/wrap/expected/@Test/return_pair.m b/wrap/expected/@Test/return_pair.m deleted file mode 100644 index 35348fd9b..000000000 --- a/wrap/expected/@Test/return_pair.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_pair(v,A) -function [first,second] = return_pair(obj,v,A) - error('need to compile return_pair.cpp'); -end diff --git a/wrap/expected/@Test/return_ptrs.cpp b/wrap/expected/@Test/return_ptrs.cpp deleted file mode 100644 index 4ad4c4fd4..000000000 --- a/wrap/expected/@Test/return_ptrs.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_ptrs",nargout,nargin-1,2); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - shared_ptr p1 = unwrap_shared_ptr< Test >(in[1], "Test"); - shared_ptr p2 = unwrap_shared_ptr< Test >(in[2], "Test"); - pair< shared_ptr, shared_ptr > result = self->return_ptrs(p1,p2); - out[0] = wrap_shared_ptr(result.first,"Test"); - out[1] = wrap_shared_ptr(result.second,"Test"); -} diff --git a/wrap/expected/@Test/return_ptrs.m b/wrap/expected/@Test/return_ptrs.m deleted file mode 100644 index ba1a16659..000000000 --- a/wrap/expected/@Test/return_ptrs.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_ptrs(p1,p2) -function [first,second] = return_ptrs(obj,p1,p2) - error('need to compile return_ptrs.cpp'); -end diff --git a/wrap/expected/@Test/return_size_t.cpp b/wrap/expected/@Test/return_size_t.cpp deleted file mode 100644 index ce5a1a9e4..000000000 --- a/wrap/expected/@Test/return_size_t.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_size_t",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - size_t value = unwrap< size_t >(in[1]); - size_t result = self->return_size_t(value); - out[0] = wrap< size_t >(result); -} diff --git a/wrap/expected/@Test/return_size_t.m b/wrap/expected/@Test/return_size_t.m deleted file mode 100644 index ad4500fd1..000000000 --- a/wrap/expected/@Test/return_size_t.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_size_t(value) -function result = return_size_t(obj,value) - error('need to compile return_size_t.cpp'); -end diff --git a/wrap/expected/@Test/return_string.cpp b/wrap/expected/@Test/return_string.cpp deleted file mode 100644 index d09e8fb31..000000000 --- a/wrap/expected/@Test/return_string.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_string",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - string value = unwrap< string >(in[1]); - string result = self->return_string(value); - out[0] = wrap< string >(result); -} diff --git a/wrap/expected/@Test/return_string.m b/wrap/expected/@Test/return_string.m deleted file mode 100644 index 28a02b0d1..000000000 --- a/wrap/expected/@Test/return_string.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_string(value) -function result = return_string(obj,value) - error('need to compile return_string.cpp'); -end diff --git a/wrap/expected/@Test/return_vector1.cpp b/wrap/expected/@Test/return_vector1.cpp deleted file mode 100644 index 079ebff09..000000000 --- a/wrap/expected/@Test/return_vector1.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_vector1",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Vector value = unwrap< Vector >(in[1]); - Vector result = self->return_vector1(value); - out[0] = wrap< Vector >(result); -} diff --git a/wrap/expected/@Test/return_vector1.m b/wrap/expected/@Test/return_vector1.m deleted file mode 100644 index 266017c86..000000000 --- a/wrap/expected/@Test/return_vector1.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_vector1(value) -function result = return_vector1(obj,value) - error('need to compile return_vector1.cpp'); -end diff --git a/wrap/expected/@Test/return_vector2.cpp b/wrap/expected/@Test/return_vector2.cpp deleted file mode 100644 index 693d3d06b..000000000 --- a/wrap/expected/@Test/return_vector2.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("return_vector2",nargout,nargin-1,1); - shared_ptr self = unwrap_shared_ptr< Test >(in[0],"Test"); - Vector value = unwrap< Vector >(in[1]); - Vector result = self->return_vector2(value); - out[0] = wrap< Vector >(result); -} diff --git a/wrap/expected/@Test/return_vector2.m b/wrap/expected/@Test/return_vector2.m deleted file mode 100644 index f237ce228..000000000 --- a/wrap/expected/@Test/return_vector2.m +++ /dev/null @@ -1,5 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -% usage: obj.return_vector2(value) -function result = return_vector2(obj,value) - error('need to compile return_vector2.cpp'); -end diff --git a/wrap/expected/make_geometry.m b/wrap/expected/make_geometry.m deleted file mode 100644 index a266b2d6d..000000000 --- a/wrap/expected/make_geometry.m +++ /dev/null @@ -1,44 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -echo on - -toolboxpath = pwd -addpath(toolboxpath); - -cd(toolboxpath) -mex -O5 new_Point2_.cpp -mex -O5 new_Point2_dd.cpp - -cd @Point2 -mex -O5 x.cpp -mex -O5 y.cpp -mex -O5 dim.cpp - -cd(toolboxpath) -mex -O5 new_Point3_ddd.cpp - -cd @Point3 -mex -O5 norm.cpp - -cd(toolboxpath) -mex -O5 new_Test_.cpp - -cd @Test -mex -O5 return_bool.cpp -mex -O5 return_size_t.cpp -mex -O5 return_int.cpp -mex -O5 return_double.cpp -mex -O5 return_string.cpp -mex -O5 return_vector1.cpp -mex -O5 return_matrix1.cpp -mex -O5 return_vector2.cpp -mex -O5 return_matrix2.cpp -mex -O5 return_pair.cpp -mex -O5 return_field.cpp -mex -O5 return_TestPtr.cpp -mex -O5 create_ptrs.cpp -mex -O5 return_ptrs.cpp -mex -O5 print.cpp - -cd(toolboxpath) - -echo off diff --git a/wrap/expected/new_Point2_.cpp b/wrap/expected/new_Point2_.cpp deleted file mode 100644 index 6a78d318d..000000000 --- a/wrap/expected/new_Point2_.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("new_Point2_",nargout,nargin,0); - Point2* self = new Point2(); - out[0] = wrap_constructed(self,"Point2"); -} diff --git a/wrap/expected/new_Point2_.m b/wrap/expected/new_Point2_.m deleted file mode 100644 index b5cab71ab..000000000 --- a/wrap/expected/new_Point2_.m +++ /dev/null @@ -1,4 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -function result = new_Point2_(obj) - error('need to compile new_Point2_.cpp'); -end diff --git a/wrap/expected/new_Point2_dd.cpp b/wrap/expected/new_Point2_dd.cpp deleted file mode 100644 index 15a8a190d..000000000 --- a/wrap/expected/new_Point2_dd.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("new_Point2_dd",nargout,nargin,2); - double x = unwrap< double >(in[0]); - double y = unwrap< double >(in[1]); - Point2* self = new Point2(x,y); - out[0] = wrap_constructed(self,"Point2"); -} diff --git a/wrap/expected/new_Point2_dd.m b/wrap/expected/new_Point2_dd.m deleted file mode 100644 index bdd42b766..000000000 --- a/wrap/expected/new_Point2_dd.m +++ /dev/null @@ -1,4 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -function result = new_Point2_dd(obj,x,y) - error('need to compile new_Point2_dd.cpp'); -end diff --git a/wrap/expected/new_Point3_ddd.cpp b/wrap/expected/new_Point3_ddd.cpp deleted file mode 100644 index 82c95bdc6..000000000 --- a/wrap/expected/new_Point3_ddd.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("new_Point3_ddd",nargout,nargin,3); - double x = unwrap< double >(in[0]); - double y = unwrap< double >(in[1]); - double z = unwrap< double >(in[2]); - Point3* self = new Point3(x,y,z); - out[0] = wrap_constructed(self,"Point3"); -} diff --git a/wrap/expected/new_Point3_ddd.m b/wrap/expected/new_Point3_ddd.m deleted file mode 100644 index 229b9658c..000000000 --- a/wrap/expected/new_Point3_ddd.m +++ /dev/null @@ -1,4 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -function result = new_Point3_ddd(obj,x,y,z) - error('need to compile new_Point3_ddd.cpp'); -end diff --git a/wrap/expected/new_Test_.cpp b/wrap/expected/new_Test_.cpp deleted file mode 100644 index ab2171762..000000000 --- a/wrap/expected/new_Test_.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// automatically generated by wrap on 2010-Feb-23 -#include -#include -void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) -{ - checkArguments("new_Test_",nargout,nargin,0); - Test* self = new Test(); - out[0] = wrap_constructed(self,"Test"); -} diff --git a/wrap/expected/new_Test_.m b/wrap/expected/new_Test_.m deleted file mode 100644 index 1aae9b6f5..000000000 --- a/wrap/expected/new_Test_.m +++ /dev/null @@ -1,4 +0,0 @@ -% automatically generated by wrap on 2010-Feb-23 -function result = new_Test_(obj) - error('need to compile new_Test_.cpp'); -end diff --git a/wrap/geometry.h b/wrap/geometry.h deleted file mode 100644 index 9b1d80b00..000000000 --- a/wrap/geometry.h +++ /dev/null @@ -1,39 +0,0 @@ - -class Point2 { - Point2(); - Point2(double x, double y); - double x(); - double y(); - int dim() const; -}; - -class Point3 { - Point3(double x, double y, double z); - double norm() const; -}; - -class Test { - Test(); - - bool return_bool (bool value); - size_t return_size_t (size_t value); - int return_int (int value); - double return_double (double value); - - string return_string (string value); - Vector return_vector1(Vector value); - Matrix return_matrix1(Matrix value); - Vector return_vector2(Vector value); - Matrix return_matrix2(Matrix value); - - pair return_pair (Vector v, Matrix A); - - bool return_field(const Test& t) const; - - Test* return_TestPtr(Test* value); - - pair create_ptrs (); - pair return_ptrs (Test* p1, Test* p2); - - void print(); -}; diff --git a/wrap/hello.cpp b/wrap/hello.cpp deleted file mode 100644 index a140afd11..000000000 --- a/wrap/hello.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -// example for wrapping python with boost -// from http://www.boost.org/doc/libs/1_37_0/libs/python/doc/tutorial/doc/html/index.html - -char const* greet() -{ - return "hello, world"; -} - -#include - -BOOST_PYTHON_MODULE(hello_ext) -{ - using namespace boost::python; - def("greet", greet); -} diff --git a/wrap/testSpirit.cpp b/wrap/testSpirit.cpp deleted file mode 100644 index 120e5561f..000000000 --- a/wrap/testSpirit.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * Unit test for Boost's awesome Spirit parser - * Author: Frank Dellaert - **/ - -#include -#include -#include - -using namespace std; -using namespace BOOST_SPIRIT_CLASSIC_NS; - -typedef rule Rule; - -/* ************************************************************************* */ -// lexeme_d turns off white space skipping -// http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/doc/directives.html -Rule name_p = lexeme_d[alpha_p >> *(alnum_p | '_')]; -Rule className_p = lexeme_d[upper_p >> *(alnum_p | '_')]; -Rule methodName_p = lexeme_d[lower_p >> *(alnum_p | '_')]; - -Rule basisType_p = (str_p("string") | "bool" | "size_t" | "int" | "double" | "Vector" | "Matrix"); - -/* ************************************************************************* */ -TEST( spirit, real ) { - // check if we can parse 8.99 as a real - CHECK(parse("8.99", real_p, space_p).full); - // make sure parsing fails on this one - CHECK(!parse("zztop", real_p, space_p).full); -} - -/* ************************************************************************* */ -TEST( spirit, string ) { - // check if we can parse a string - CHECK(parse("double", str_p("double"), space_p).full); -} - -/* ************************************************************************* */ -TEST( spirit, sequence ) { - // check that we skip white space - CHECK(parse("int int", str_p("int") >> *str_p("int"), space_p).full); - CHECK(parse("int --- - -- -", str_p("int") >> *ch_p('-'), space_p).full); - CHECK(parse("const \t string", str_p("const") >> str_p("string"), space_p).full); - - // not that (see spirit FAQ) the vanilla rule<> does not deal with whitespace - rule<>vanilla_p = str_p("const") >> str_p("string"); - CHECK(!parse("const \t string", vanilla_p, space_p).full); - - // to fix it, we need to use - rulephrase_level_p = str_p("const") >> str_p("string"); - CHECK(parse("const \t string", phrase_level_p, space_p).full); -} - -/* ************************************************************************* */ -// parser for interface files - -// const string reference reference -Rule constStringRef_p = - str_p("const") >> "string" >> '&'; - -// class reference -Rule classRef_p = className_p >> '&'; - -// const class reference -Rule constClassRef_p = str_p("const") >> classRef_p; - -// method parsers -Rule constMethod_p = basisType_p >> methodName_p >> '(' >> ')' >> "const" >> ';'; - -/* ************************************************************************* */ -TEST( spirit, basisType_p ) { - CHECK(!parse("Point3", basisType_p, space_p).full); - CHECK(parse("string", basisType_p, space_p).full); -} - -/* ************************************************************************* */ -TEST( spirit, className_p ) { - CHECK(parse("Point3", className_p, space_p).full); -} - -/* ************************************************************************* */ -TEST( spirit, classRef_p ) { - CHECK(parse("Point3 &", classRef_p, space_p).full); - CHECK(parse("Point3&", classRef_p, space_p).full); -} - -/* ************************************************************************* */ -TEST( spirit, constMethod_p ) { - CHECK(parse("double norm() const;", constMethod_p, space_p).full); -} - -/* ************************************************************************* */ -int main() { TestResult tr; return TestRegistry::runAllTests(tr); } -/* ************************************************************************* */ diff --git a/wrap/testWrap.cpp b/wrap/testWrap.cpp deleted file mode 100644 index 6e9f84d59..000000000 --- a/wrap/testWrap.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * Unit test for wrap.c - * Author: Frank Dellaert - **/ - -#include -#include -#include -#include - -#include "utilities.h" -#include "Module.h" - -using namespace std; -static bool verbose = false; -#ifdef TOPSRCDIR -static string topdir = TOPSRCDIR; -#else -static string topdir = ".."; -#endif - -/* ************************************************************************* */ -TEST( wrap, ArgumentList ) { - ArgumentList args; - Argument arg; arg.type = "double"; arg.name = "x"; - args.push_back(arg); - args.push_back(arg); - args.push_back(arg); - CHECK(args.signature()=="ddd"); - CHECK(args.types()=="double,double,double"); - CHECK(args.names()=="x,x,x"); -} - -/* ************************************************************************* */ -TEST( wrap, check_exception ) { - THROWS_EXCEPTION(Module("/notarealpath", "geometry",verbose)); - CHECK_EXCEPTION(Module("/alsonotarealpath", "geometry",verbose), CantOpenFile); -} - -/* ************************************************************************* */ -TEST( wrap, parse ) { - string path = topdir + "/wrap"; - - Module module(path.c_str(), "geometry",verbose); - CHECK(module.classes.size()==3); - - // check second class, Point3 - Class cls = *(++module.classes.begin()); - CHECK(cls.name=="Point3"); - CHECK(cls.constructors.size()==1); - CHECK(cls.methods.size()==1); - - // first constructor takes 3 doubles - Constructor c1 = cls.constructors.front(); - CHECK(c1.args.size()==3); - - // check first double argument - Argument a1 = c1.args.front(); - CHECK(!a1.is_const); - CHECK(a1.type=="double"); - CHECK(!a1.is_ref); - CHECK(a1.name=="x"); - - // check method - Method m1 = cls.methods.front(); - CHECK(m1.returns=="double"); - CHECK(m1.name=="norm"); - CHECK(m1.args.size()==0); - CHECK(m1.is_const); -} - -/* ************************************************************************* */ -TEST( wrap, matlab_code ) { - // Parse into class object - string path = topdir + "/wrap"; - Module module(path,"geometry",verbose); - - // emit MATLAB code - // make_geometry will not compile, use make testwrap to generate real make - module.matlab_code("actual", "", "-O5"); - - CHECK(files_equal(path + "/expected/@Point2/Point2.m" , "actual/@Point2/Point2.m" )); - CHECK(files_equal(path + "/expected/@Point2/x.cpp" , "actual/@Point2/x.cpp" )); - - CHECK(files_equal(path + "/expected/@Point3/Point3.m" , "actual/@Point3/Point3.m" )); - CHECK(files_equal(path + "/expected/new_Point3_ddd.m" , "actual/new_Point3_ddd.m" )); - CHECK(files_equal(path + "/expected/new_Point3_ddd.cpp", "actual/new_Point3_ddd.cpp")); - CHECK(files_equal(path + "/expected/@Point3/norm.m" , "actual/@Point3/norm.m" )); - CHECK(files_equal(path + "/expected/@Point3/norm.cpp" , "actual/@Point3/norm.cpp" )); - - CHECK(files_equal(path + "/expected/new_Test_.cpp" , "actual/new_Test_.cpp" )); - CHECK(files_equal(path + "/expected/@Test/Test.m" , "actual/@Test/Test.m" )); - CHECK(files_equal(path + "/expected/@Test/return_string.cpp" , "actual/@Test/return_string.cpp" )); - CHECK(files_equal(path + "/expected/@Test/return_pair.cpp" , "actual/@Test/return_pair.cpp" )); - CHECK(files_equal(path + "/expected/@Test/return_field.cpp" , "actual/@Test/return_field.cpp" )); - CHECK(files_equal(path + "/expected/@Test/return_TestPtr.cpp", "actual/@Test/return_TestPtr.cpp")); - CHECK(files_equal(path + "/expected/@Test/return_ptrs.cpp" , "actual/@Test/return_ptrs.cpp" )); - CHECK(files_equal(path + "/expected/@Test/print.m" , "actual/@Test/print.m" )); - CHECK(files_equal(path + "/expected/@Test/print.cpp" , "actual/@Test/print.cpp" )); - - CHECK(files_equal(path + "/expected/make_geometry.m" , "actual/make_geometry.m" )); -} - -/* ************************************************************************* */ -int main() { TestResult tr; return TestRegistry::runAllTests(tr); } -/* ************************************************************************* */ diff --git a/wrap/utilities.cpp b/wrap/utilities.cpp deleted file mode 100644 index f7376390f..000000000 --- a/wrap/utilities.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: utilities.ccp - * Author: Frank Dellaert - **/ - -#include -#include - -#include - -#include "utilities.h" - -using namespace std; -using namespace boost::gregorian; - -/* ************************************************************************* */ -string file_contents(const string& filename, bool skipheader) { - ifstream ifs(filename.c_str()); - if(!ifs) throw CantOpenFile(filename); - - // read file into stringstream - stringstream ss; - if (skipheader) ifs.ignore(256,'\n'); - ss << ifs.rdbuf(); - ifs.close(); - - // return string - return ss.str(); -} - -/* ************************************************************************* */ -bool files_equal(const string& expected, const string& actual, bool skipheader) { - try { - string expected_contents = file_contents(expected, skipheader); - string actual_contents = file_contents(actual, skipheader); - bool equal = actual_contents == expected_contents; - if (!equal) { - stringstream command; - command << "diff " << actual << " " << expected << endl; - system(command.str().c_str()); - } - return equal; - } - catch (const string& reason) { - cerr << "expection: " << reason << endl; - return false; - } - return true; -} - -/* ************************************************************************* */ -void emit_header_comment(ofstream& ofs, const string& delimiter) { - date today = day_clock::local_day(); - ofs << delimiter << " automatically generated by wrap on " << today << endl; -} - -/* ************************************************************************* */ diff --git a/wrap/utilities.h b/wrap/utilities.h deleted file mode 100644 index e75c44025..000000000 --- a/wrap/utilities.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: utilities.ccp - * Author: Frank Dellaert - **/ - -#pragma once - -#include -#include - -class CantOpenFile : public std::exception { - private: - std::string filename_; - public: - CantOpenFile(const std::string& filename) : filename_(filename) {} - ~CantOpenFile() throw() {} - virtual const char* what() const throw() { - return ("Can't open file " + filename_).c_str(); - } -}; - -class ParseFailed : public std::exception { - private: - int length_; - public: - ParseFailed(int length) : length_(length) {} - ~ParseFailed() throw() {} - virtual const char* what() const throw() { - std::stringstream buf; - buf << "Parse failed at character " << (length_+1); - return buf.str().c_str(); - } -}; - -/** - * read contents of a file into a std::string - */ -std::string file_contents(const std::string& filename, bool skipheader=false); - -/** - * Check whether two files are equal - * By default, skips the first line of actual so header is not generated - */ -bool files_equal(const std::string& expected, const std::string& actual, bool skipheader=true); - -/** - * emit a header at the top of generated files - */ -void emit_header_comment(std::ofstream& ofs, const std::string& delimiter); diff --git a/wrap/wrap-matlab.h b/wrap/wrap-matlab.h deleted file mode 100644 index 6889daaa6..000000000 --- a/wrap/wrap-matlab.h +++ /dev/null @@ -1,438 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -// header file to be included in MATLAB wrappers -// Copyright (c) 2008 Frank Dellaert, All Rights reserved -// wrapping and unwrapping is done using specialized templates, see -// http://www.cplusplus.com/doc/tutorial/templates.html - -extern "C" { -#include -} - -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost; // not usual, but for conciseness of generated code - -// start GTSAM Specifics ///////////////////////////////////////////////// -typedef numeric::ublas::vector Vector; -typedef numeric::ublas::matrix Matrix; -// to make keys be constructed from strings: -#define GTSAM_MAGIC_KEY -// to enable Matrix and Vector constructor for SharedGaussian: -#define GTSAM_MAGIC_GAUSSIAN -// end GTSAM Specifics ///////////////////////////////////////////////// - -#ifdef __LP64__ -// 64-bit Mac -#define mxUINT32OR64_CLASS mxUINT64_CLASS -#else -#define mxUINT32OR64_CLASS mxUINT32_CLASS -#endif - -//***************************************************************************** -// Utilities -//***************************************************************************** - -void error(const char* str) { - mexErrMsgIdAndTxt("wrap:error", str); -} - -mxArray *scalar(mxClassID classid) { - mwSize dims[1]; dims[0]=1; - return mxCreateNumericArray(1, dims, classid, mxREAL); -} - -void checkScalar(const mxArray* array, const char* str) { - int m = mxGetM(array), n = mxGetN(array); - if (m!=1 || n!=1) - mexErrMsgIdAndTxt("wrap: not a scalar in ", str); -} - -//***************************************************************************** -// Check arguments -//***************************************************************************** - -void checkArguments(const string& name, int nargout, int nargin, int expected) { - stringstream err; - err << name << " expects " << expected << " arguments, not " << nargin; - if (nargin!=expected) - error(err.str().c_str()); -} - -//***************************************************************************** -// wrapping C++ basis types in MATLAB arrays -//***************************************************************************** - -// default wrapping throws an error: only basis types are allowed in wrap -template -mxArray* wrap(Class& value) { - error("wrap internal error: attempted wrap of invalid type"); -} - -// specialization to string -// wraps into a character array -template<> -mxArray* wrap(string& value) { - return mxCreateString(value.c_str()); -} - -// specialization to bool -template<> -mxArray* wrap(bool& value) { - mxArray *result = scalar(mxUINT32OR64_CLASS); - *(bool*)mxGetData(result) = value; - return result; -} - -// specialization to size_t -template<> -mxArray* wrap(size_t& value) { - mxArray *result = scalar(mxUINT32OR64_CLASS); - *(size_t*)mxGetData(result) = value; - return result; -} - -// specialization to int -template<> -mxArray* wrap(int& value) { - mxArray *result = scalar(mxUINT32OR64_CLASS); - *(int*)mxGetData(result) = value; - return result; -} - -// specialization to double -> just double -template<> -mxArray* wrap(double& value) { - return mxCreateDoubleScalar(value); -} - -// wrap a const BOOST vector into a double vector -mxArray* wrap_Vector(const Vector& v) { - int m = v.size(); - mxArray *result = mxCreateDoubleMatrix(m, 1, mxREAL); - double *data = mxGetPr(result); - for (int i=0;i double vector -template<> -mxArray* wrap(Vector& v) { - return wrap_Vector(v); -} - -// const version -template<> -mxArray* wrap(const Vector& v) { - return wrap_Vector(v); -} - -// wrap a const BOOST MATRIX into a double matrix -mxArray* wrap_Matrix(const Matrix& A) { - int m = A.size1(), n = A.size2(); - mxArray *result = mxCreateDoubleMatrix(m, n, mxREAL); - double *data = mxGetPr(result); - // converts from column-major to row-major - for (int j=0;j double matrix -template<> -mxArray* wrap(Matrix& A) { - return wrap_Matrix(A); -} - -// const version -template<> -mxArray* wrap(const Matrix& A) { - return wrap_Matrix(A); -} - -//***************************************************************************** -// unwrapping MATLAB arrays into C++ basis types -//***************************************************************************** - -// default unwrapping throws an error -// as wrap only supports passing a reference or one of the basic types -template -T unwrap(const mxArray* array) { - error("wrap internal error: attempted unwrap of invalid type"); -} - -// specialization to string -// expects a character array -// Warning: relies on mxChar==char -template<> -string unwrap(const mxArray* array) { - char *data = mxArrayToString(array); - if (data==NULL) error("unwrap: not a character array"); - string str(data); - mxFree(data); - return str; -} - -// specialization to bool -template<> -bool unwrap(const mxArray* array) { - checkScalar(array,"unwrap"); - return mxGetScalar(array) != 0.0; -} - -// specialization to size_t -template<> -size_t unwrap(const mxArray* array) { - checkScalar(array,"unwrap"); - return (size_t)mxGetScalar(array); -} - -// specialization to int -template<> -int unwrap(const mxArray* array) { - checkScalar(array,"unwrap"); - return (int)mxGetScalar(array); -} - -// specialization to double -template<> -double unwrap(const mxArray* array) { - checkScalar(array,"unwrap"); - return (double)mxGetScalar(array); -} - -// specialization to BOOST vector -template<> -Vector unwrap< Vector >(const mxArray* array) { - int m = mxGetM(array), n = mxGetN(array); - if (mxIsDouble(array)==false || n!=1) error("unwrap: not a vector"); - double* data = (double*)mxGetData(array); - Vector v(m); - copy(data,data+m,v.begin()); - return v; -} - -// specialization to BOOST matrix -template<> -Matrix unwrap< Matrix >(const mxArray* array) { - if (mxIsDouble(array)==false) error("unwrap: not a matrix"); - int m = mxGetM(array), n = mxGetN(array); - double* data = (double*)mxGetData(array); - Matrix A(m,n); - // converts from row-major to column-major - for (int j=0;j class Collector; - -template -class ObjectHandle { -private: - ObjectHandle* signature; // use 'this' as a unique object signature - const std::type_info* type; // type checking information - shared_ptr t; // object pointer - -public: - // Constructor for free-store allocated objects. - // Creates shared pointer, will delete if is last one to hold pointer - ObjectHandle(T* ptr) : - type(&typeid(T)), t(shared_ptr (ptr)) { - signature = this; - Collector::register_handle(this); - } - - // Constructor for shared pointers - // Creates shared pointer, will delete if is last one to hold pointer - ObjectHandle(shared_ptr ptr) : - type(&typeid(T)), t(ptr) { - signature = this; - } - - ~ObjectHandle() { - // object is in shared_ptr, will be automatically deleted - signature = 0; // destroy signature - } - - // Get the actual object contained by handle - shared_ptr get_object() const { - return t; - } - - // Print the mexhandle for debugging - void print(const char* str) { - mexPrintf("mexhandle %s:\n", str); - mexPrintf(" signature = %d:\n", signature); - mexPrintf(" pointer = %d:\n", t.get()); - } - - // Convert ObjectHandle to a mxArray handle (to pass back from mex-function). - // Create a numeric array as handle for an ObjectHandle. - // We ASSUME we can store object pointer in the mxUINT32 element of mxArray. - mxArray* to_mex_handle() { - mxArray* handle = mxCreateNumericMatrix(1, 1, mxUINT32OR64_CLASS, mxREAL); - *reinterpret_cast**> (mxGetPr(handle)) = this; - return handle; - } - - string type_name() const { - return type->name(); - } - - // Convert mxArray (passed to mex-function) to an ObjectHandle. - // Import a handle from MatLab as a mxArray of UINT32. Check that - // it is actually a pointer to an ObjectHandle. - static ObjectHandle* from_mex_handle(const mxArray* handle) { - if (mxGetClassID(handle) != mxUINT32OR64_CLASS || mxIsComplex(handle) - || mxGetM(handle) != 1 || mxGetN(handle) != 1) error( - "Parameter is not an ObjectHandle type."); - - // We *assume* we can store ObjectHandle pointer in the mxUINT32 of handle - ObjectHandle* obj = *reinterpret_cast (mxGetPr(handle)); - - if (!obj) // gross check to see we don't have an invalid pointer - error("Parameter is NULL. It does not represent an ObjectHandle object."); - // TODO: change this for max-min check for pointer values - - if (obj->signature != obj) // check memory has correct signature - error("Parameter does not represent an ObjectHandle object."); - - /* - if (*(obj->type) != typeid(T)) { // check type - mexPrintf("Given: <%s>, Required: <%s>.\n", obj->type_name(), typeid(T).name()); - error("Given ObjectHandle does not represent the correct type."); - } - */ - - return obj; - } - - friend class Collector ; // allow Collector access to signature -}; - -// --------------------------------------------------------- -// ------------------ Garbage Collection ------------------- -// --------------------------------------------------------- - -// Garbage collection singleton (one collector object for each type T). -// Ensures that registered handles are deleted when the dll is released (they -// may also be deleted previously without problem). -// The Collector provides protection against resource leaks in the case -// where 'clear all' is called in MatLab. (This is because MatLab will call -// the destructors of statically allocated objects but not free-store allocated -// objects.) -template -class Collector { - typedef ObjectHandle Handle; - typedef std::list< Handle* > ObjList; - typedef typename ObjList::iterator iterator; - ObjList objlist; -public: - ~Collector() { - for (iterator i= objlist.begin(); i!=objlist.end(); ++i) { - if ((*i)->signature == *i) // check for valid signature - delete *i; - } - } - - static void register_handle (Handle* obj) { - static Collector singleton; - singleton.objlist.push_back(obj); - } - -private: // prevent construction - Collector() {} - Collector(const Collector&); -}; - -//***************************************************************************** -// wrapping C++ objects in a MATLAB proxy class -//***************************************************************************** - -/* - For every C++ class Class, a matlab proxy class @Class/Class.m object - is created. Its constructor will check which of the C++ constructors - needs to be called, based on nr of arguments. It then calls the - corresponding mex function new_Class_signature, which will create a - C++ object using new, and pass the pointer to wrap_constructed - (below). This creates a mexhandle and returns it to the proxy class - constructor, which assigns it to self. Matlab owns this handle now. -*/ -template -mxArray* wrap_constructed(Class* pointer, const char *classname) { - ObjectHandle* handle = new ObjectHandle(pointer); - return handle->to_mex_handle(); -} - -/* - [create_object] creates a MATLAB proxy class object with a mexhandle - in the self property. Matlab does not allow the creation of matlab - objects from within mex files, hence we resort to an ugly trick: we - invoke the proxy class constructor by calling MATLAB, and pass 13 - dummy arguments to let the constructor know we want an object without - the self property initialized. We then assign the mexhandle to self. -*/ -// TODO: think about memory -mxArray* create_object(const char *classname, mxArray* h) { - mxArray *result; - mxArray* dummy[13] = {h,h,h,h,h, h,h,h,h,h, h,h,h}; - mexCallMATLAB(1,&result,13,dummy,classname); - mxSetProperty(result, 0, "self", h); - return result; -} - -/* - When the user calls a method that returns a shared pointer, we create - an ObjectHandle from the shared_pointer and return it as a proxy - class to matlab. -*/ -template -mxArray* wrap_shared_ptr(shared_ptr< Class > shared_ptr, const char *classname) { - ObjectHandle* handle = new ObjectHandle(shared_ptr); - return create_object(classname,handle->to_mex_handle()); -} - -//***************************************************************************** -// unwrapping a MATLAB proxy class to a C++ object reference -//***************************************************************************** - -/* - Besides the basis types, the only other argument type allowed is a - shared pointer to a C++ object. In this case, matlab needs to pass a - proxy class object to the mex function. [unwrap_shared_ptr] extracts - the ObjectHandle from the self property, and returns a shared pointer - to the object. -*/ -template -shared_ptr unwrap_shared_ptr(const mxArray* obj, const string& className) { - bool isClass = mxIsClass(obj, className.c_str()); - if (!isClass) { - mexPrintf("Expected %s, got %s\n", className.c_str(), mxGetClassName(obj)); - error("Argument has wrong type."); - } - mxArray* mxh = mxGetProperty(obj,0,"self"); - if (mxh==NULL) error("unwrap_reference: invalid wrap object"); - ObjectHandle* handle = ObjectHandle::from_mex_handle(mxh); - return handle->get_object(); -} - -//***************************************************************************** diff --git a/wrap/wrap.cpp b/wrap/wrap.cpp deleted file mode 100644 index 1a52da6bd..000000000 --- a/wrap/wrap.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* ---------------------------------------------------------------------------- - - * GTSAM Copyright 2010, Georgia Tech Research Corporation, - * Atlanta, Georgia 30332-0415 - * All Rights Reserved - * Authors: Frank Dellaert, et al. (see THANKS for the full author list) - - * See LICENSE for the license information - - * -------------------------------------------------------------------------- */ - -/** - * file: wrap.ccp - * brief: wraps functions - * Author: Frank Dellaert - **/ - -#include -#include - -#include "Module.h" - -using namespace std; - -/* ************************************************************************* */ -/** - * main function to wrap a module - */ -void generate_matlab_toolbox(const string& interfacePath, - const string& moduleName, - const string& toolboxPath, - const string& nameSpace, - const string& mexFlags) -{ - // Parse into class object - Module module(interfacePath, moduleName, false); - - // emit MATLAB code - module.matlab_code(toolboxPath,nameSpace,mexFlags); -} - -/* ************************************************************************* */ - -int main(int argc, const char* argv[]) { - if (argc<5 || argc>6) { - cerr << "wrap parses an interface file and produces a MATLAB toolbox" << endl; - cerr << "usage: wrap interfacePath moduleName toolboxPath" << endl; - cerr << " interfacePath : *absolute* path to directory of module interface file" << endl; - cerr << " moduleName : the name of the module, interface file must be called moduleName.h" << endl; - cerr << " toolboxPath : the directory in which to generate the wrappers" << endl; - cerr << " nameSpace : namespace to use, pass empty string if none" << endl; - cerr << " [mexFlags] : extra flags for the mex command" << endl; - } - else - generate_matlab_toolbox(argv[1],argv[2],argv[3],argv[4],argc==5 ? " " : argv[5]); -} - -/* ************************************************************************* */