Added back the matlab interface to gtsam

release/4.3a0
Alex Cunningham 2011-10-13 18:41:56 +00:00
parent c2aee8668e
commit f4d9ca72a8
83 changed files with 3005 additions and 78 deletions

171
.cproject
View File

@ -375,14 +375,6 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>testGaussianFactor.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="all" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -409,6 +401,7 @@
</target>
<target name="tests/testBayesTree.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>tests/testBayesTree.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -416,6 +409,7 @@
</target>
<target name="testBinaryBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testBinaryBayesNet.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -463,6 +457,7 @@
</target>
<target name="testSymbolicBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSymbolicBayesNet.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -470,6 +465,7 @@
</target>
<target name="tests/testSymbolicFactor.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>tests/testSymbolicFactor.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -477,6 +473,7 @@
</target>
<target name="testSymbolicFactorGraph.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -492,11 +489,20 @@
</target>
<target name="tests/testBayesTree" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>tests/testBayesTree</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>testGaussianFactor.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -523,7 +529,6 @@
</target>
<target name="testGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testGraph.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -595,7 +600,6 @@
</target>
<target name="testInference.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testInference.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -603,7 +607,6 @@
</target>
<target name="testGaussianFactor.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testGaussianFactor.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -611,7 +614,6 @@
</target>
<target name="testJunctionTree.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testJunctionTree.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -619,7 +621,6 @@
</target>
<target name="testSymbolicBayesNet.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSymbolicBayesNet.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -627,7 +628,6 @@
</target>
<target name="testSymbolicFactorGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -721,7 +721,15 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<target name="all" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
@ -729,6 +737,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="build_wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="tests/testGeneralSFMFactor.run" path="build/gtsam/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -769,6 +785,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/gtsam/nonlinear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -825,14 +849,6 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/gtsam/inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="vSFMexample.run" path="build/examples/vSLAMexample" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -841,6 +857,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/gtsam/inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="testVSLAMGraph" path="build/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -1083,6 +1107,7 @@
</target>
<target name="testErrors.run" path="linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testErrors.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -1482,7 +1507,6 @@
</target>
<target name="testSimulated2DOriented.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSimulated2DOriented.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -1522,7 +1546,6 @@
</target>
<target name="testSimulated2D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSimulated2D.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -1530,7 +1553,6 @@
</target>
<target name="testSimulated3D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>testSimulated3D.run</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -1722,7 +1744,6 @@
</target>
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>tests/testGaussianISAM2</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
@ -1744,6 +1765,46 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>install</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>dist</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -1840,54 +1901,6 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>install</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>dist</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
@ -1928,6 +1941,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="check" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j2</buildArguments>
<buildTarget>check</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

View File

@ -16,6 +16,10 @@ include aminclude.am
# All the sub-directories that need to be built
SUBDIRS = CppUnitLite gtsam tests examples
if ENABLE_BUILD_TOOLBOX
SUBDIRS += wrap
endif
# Add these files to make sure they're in the distribution
EXTRA_DIST = autogen.sh configure.ac COPYING INSTALL LGPL LICENSE README THANKS USAGE doc

View File

@ -7,6 +7,7 @@ AM_INIT_AUTOMAKE(gtsam, 0.9.3)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_SRCDIR([CppUnitLite/Test.cpp])
AC_CONFIG_SRCDIR([wrap/wrap.cpp])
AC_CONFIG_SRCDIR([gtsam/base/DSFVector.cpp])
AC_CONFIG_SRCDIR([gtsam/geometry/Cal3_S2.cpp])
AC_CONFIG_SRCDIR([gtsam/inference/SymbolicFactorGraph.cpp])
@ -114,7 +115,26 @@ AC_CHECK_FUNCS([pow sqrt])
# Check for boost
AX_BOOST_BASE([1.40])
# ask for toolbox directory
# enable matlab toolbox generation
AC_ARG_ENABLE([build_toolbox],
[ --enable-build-toolbox Enable building of the Matlab toolbox],
[case "${enableval}" in
yes) build_toolbox=true ;;
no) build_toolbox=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-build-toolbox]) ;;
esac],[build_toolbox=false])
AM_CONDITIONAL([ENABLE_BUILD_TOOLBOX], [test x$build_toolbox = xtrue])
# Matlab toolbox: optional flag to change location of toolbox, defaults to install prefix
AC_ARG_WITH([toolbox],
[AS_HELP_STRING([--with-toolbox],
[specify the matlab toolbox directory for installation])],
[toolbox=$withval],
[toolbox=$prefix])
AC_SUBST([toolbox])
#Original version
#AC_ARG_WITH([toolbox],
# [AS_HELP_STRING([--with-toolbox],
# [specify the matlab toolbox directory for installation (mandatory)])],
@ -122,9 +142,9 @@ AX_BOOST_BASE([1.40])
# [AC_MSG_FAILURE(
# [--with-toolbox has to be specified])
# ])
#AC_SUBST([toolbox])
AC_CONFIG_FILES([CppUnitLite/Makefile \
wrap/Makefile \
gtsam/3rdparty/Makefile \
gtsam/base/Makefile \
gtsam/geometry/Makefile \

270
gtsam-broken.h Normal file
View File

@ -0,0 +1,270 @@
// These are considered to be broken and will be added back as they start working
// It's assumed that there have been interface changes that might break this
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 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;
};
// 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,Vector> matrix(const Ordering& ordering) const;
pair<GaussianConditional*,GaussianFactor*> 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,Vector> 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;
};

37
gtsam.h Normal file
View File

@ -0,0 +1,37 @@
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;
};

View File

@ -11,15 +11,26 @@ sources =
check_PROGRAMS =
# simulated2D example
# headers += Simulated2DValues.h
headers += simulated2DConstraints.h
sources += simulated2D.cpp smallExample.cpp
check_PROGRAMS += tests/testSimulated2D
# MATLAB Wrap headers for simulated2D
headers += Simulated2DMeasurement.h
headers += Simulated2DOdometry.h
headers += Simulated2DPointPrior.h
headers += Simulated2DPosePrior.h
headers += Simulated2DValues.h
# simulated2DOriented example
sources += simulated2DOriented.cpp
check_PROGRAMS += tests/testSimulated2DOriented
# MATLAB Wrap headers for simulated2DOriented
headers += Simulated2DOrientedOdometry.h
headers += Simulated2DOrientedPosePrior.h
headers += Simulated2DOrientedValues.h
# simulated3D example
sources += Simulated3D.cpp
check_PROGRAMS += tests/testSimulated3D

View File

@ -0,0 +1,29 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DMeasurement.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2D.h>
#include <gtsam/slam/Simulated2DValues.h>
namespace gtsam {
typedef simulated2D::Measurement Simulated2DMeasurement;
}

View File

@ -0,0 +1,29 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DOdometry.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2D.h>
#include <gtsam/slam/Simulated2DValues.h>
namespace gtsam {
typedef simulated2D::Odometry Simulated2DOdometry;
}

View File

@ -0,0 +1,29 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DOrientedOdometry.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Kai Ni
*/
#pragma once
#include <gtsam/slam/simulated2DOriented.h>
#include <gtsam/slam/Simulated2DOrientedValues.h>
namespace gtsam {
typedef simulated2DOriented::Odometry Simulated2DOrientedOdometry;
}

View File

@ -0,0 +1,30 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DOrientedPosePrior.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Kai Ni
*/
#pragma once
#include <gtsam/slam/simulated2DOriented.h>
#include <gtsam/slam/Simulated2DOrientedValues.h>
namespace gtsam {
/** Create a prior on a pose Point2 with key 'x1' etc... */
typedef simulated2DOriented::GenericPosePrior<Simulated2DOrientedValues, simulated2DOriented::PoseKey> Simulated2DOrientedPosePrior;
}

View File

@ -0,0 +1,60 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DValues.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2DOriented.h>
namespace gtsam {
class Simulated2DOrientedValues: public simulated2DOriented::Values {
public:
typedef boost::shared_ptr<Point2> sharedPoint;
typedef boost::shared_ptr<Pose2> sharedPose;
Simulated2DOrientedValues() {
}
void insertPose(const simulated2DOriented::PoseKey& i, const Pose2& p) {
insert(i, p);
}
void insertPoint(const simulated2DOriented::PointKey& j, const Point2& p) {
insert(j, p);
}
int nrPoses() const {
return this->first_.size();
}
int nrPoints() const {
return this->second_.size();
}
sharedPose pose(const simulated2DOriented::PoseKey& i) {
return sharedPose(new Pose2((*this)[i]));
}
sharedPoint point(const simulated2DOriented::PointKey& j) {
return sharedPoint(new Point2((*this)[j]));
}
};
} // namespace gtsam

View File

@ -0,0 +1,30 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DPointPrior.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2D.h>
#include <gtsam/slam/Simulated2DValues.h>
namespace gtsam {
/** Create a prior on a landmark Point2 with key 'l1' etc... */
typedef simulated2D::GenericPrior<Simulated2DValues, simulated2D::PointKey> Simulated2DPointPrior;
}

View File

@ -0,0 +1,30 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DPosePrior.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2D.h>
#include <gtsam/slam/Simulated2DValues.h>
namespace gtsam {
/** Create a prior on a pose Point2 with key 'x1' etc... */
typedef simulated2D::GenericPrior<Simulated2DValues, simulated2D::PoseKey> Simulated2DPosePrior;
}

View File

@ -0,0 +1,59 @@
/* ----------------------------------------------------------------------------
* 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
* -------------------------------------------------------------------------- */
/*
* Simulated2DValues.h
*
* Re-created on Feb 22, 2010 for compatibility with MATLAB
* Author: Frank Dellaert
*/
#pragma once
#include <gtsam/slam/simulated2D.h>
namespace gtsam {
class Simulated2DValues: public simulated2D::Values {
public:
typedef boost::shared_ptr<Point2> sharedPoint;
Simulated2DValues() {
}
void insertPose(const simulated2D::PoseKey& i, const Point2& p) {
insert(i, p);
}
void insertPoint(const simulated2D::PointKey& j, const Point2& p) {
insert(j, p);
}
int nrPoses() const {
return this->first_.size();
}
int nrPoints() const {
return this->second_.size();
}
sharedPoint pose(const simulated2D::PoseKey& i) {
return sharedPoint(new Point2((*this)[i]));
}
sharedPoint point(const simulated2D::PointKey& j) {
return sharedPoint(new Point2((*this)[j]));
}
};
} // namespace gtsam

1
myconfigure.matlab Executable file
View File

@ -0,0 +1 @@
../configure --prefix=$HOME --with-toolbox=$HOME/borg/gtsam/toolbox --enable-build-toolbox CFLAGS="-fno-inline -g -Wall" CXXFLAGS="-fno-inline -g -Wall" LDFLAGS="-fno-inline -g -Wall" --disable-static --disable-fast-install

85
wrap/Argument.cpp Normal file
View File

@ -0,0 +1,85 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <sstream>
#include <boost/foreach.hpp>
#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++;
}
}
/* ************************************************************************* */

51
wrap/Argument.h Normal file
View File

@ -0,0 +1,51 @@
/* ----------------------------------------------------------------------------
* 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 <string>
#include <list>
// 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<Argument> {
std::list<Argument> 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++
};

85
wrap/Class.cpp Normal file
View File

@ -0,0 +1,85 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#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;
}
/* ************************************************************************* */

45
wrap/Class.h Normal file
View File

@ -0,0 +1,45 @@
/* ----------------------------------------------------------------------------
* 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 <string>
#include <list>
#include "Constructor.h"
#include "Method.h"
// Class has name, constructors, methods
struct Class {
std::string name;
std::list<Constructor> constructors;
std::list<Method> 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
};

100
wrap/Constructor.cpp Normal file
View File

@ -0,0 +1,100 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#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<args.size();i++) {
if (!first) ofs << ",";
ofs << "varargin{" << i+1 << "}";
first=false;
}
ofs << "); end" << endl;
}
/* ************************************************************************* */
void Constructor::matlab_mfile(const string& toolboxPath, const string& className) {
string name = matlab_wrapper_name(className);
// open destination m-file
string wrapperFile = toolboxPath + "/" + 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 << "function result = " << 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 Constructor::matlab_wrapper(const string& toolboxPath,
const string& className,
const string& nameSpace)
{
string name = matlab_wrapper_name(className);
// open destination wrapperFile
string wrapperFile = toolboxPath + "/" + name + ".cpp";
ofstream ofs(wrapperFile.c_str());
if(!ofs) throw CantOpenFile(wrapperFile);
if(verbose_) cerr << "generating " << wrapperFile << endl;
// generate code
emit_header_comment(ofs, "//");
ofs << "#include <wrap/matlab.h>" << 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();
}
/* ************************************************************************* */

43
wrap/Constructor.h Normal file
View File

@ -0,0 +1,43 @@
/* ----------------------------------------------------------------------------
* 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 <string>
#include <list>
#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
};

70
wrap/Makefile.am Normal file
View File

@ -0,0 +1,70 @@
#----------------------------------------------------------------------------------------------------
# GTSAM Matlab wrap toolset
#----------------------------------------------------------------------------------------------------
# use nostdinc to turn off -I. and -I.., we do not need them because
# header files are qualified so they can be included in external projects.
AUTOMAKE_OPTIONS = nostdinc
AM_DEFAULT_SOURCE_EXT = .cpp
headers =
sources =
check_PROGRAMS =
# disable all of matlab toolbox build by default
if ENABLE_BUILD_TOOLBOX
# Build a library from the core sources
sources += utilities.cpp Argument.cpp Constructor.cpp Method.cpp Class.cpp Module.cpp
check_PROGRAMS += tests/testSpirit tests/testWrap
noinst_PROGRAMS = wrap
#----------------------------------------------------------------------------------------------------
# Create a libtool library that is not installed
# It will be packaged in the toplevel libgtsam.la as specfied in ../Makefile.am
# The headers are installed in $(includedir)/gtsam:
#----------------------------------------------------------------------------------------------------
headers += $(sources:.cpp=.h) matlab.h
wrapdir = $(pkgincludedir)/wrap
wrap_HEADERS = $(headers)
noinst_LTLIBRARIES = libwrap.la
libwrap_la_SOURCES = $(sources)
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(top_srcdir) -DTOPSRCDIR="\"$(top_srcdir)\""
AM_LDFLAGS = $(BOOST_LDFLAGS)
#----------------------------------------------------------------------------------------------------
# rules to build local programs
#----------------------------------------------------------------------------------------------------
TESTS = $(check_PROGRAMS)
AM_LDFLAGS += $(boost_serialization)
LDADD = libwrap.la ../CppUnitLite/libCppUnitLite.a
# rule to run an executable
%.run: % $(LDADD)
./$^
# rule to run executable with valgrind
%.valgrind: % $(LDADD)
valgrind ./$^
# 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/wrap -I${prefix}/include/gtsam/slam -L${exec_prefix}/lib -lgtsam"
all:
./wrap ${interfacePath} ${moduleName} ${toolboxpath} ${nameSpace} ${mexFlags}
# install the headers and matlab toolbox
install-exec-hook: all
install -d ${toolbox}/gtsam && \
cp -rf ../toolbox/* ${toolbox}/gtsam
# clean local toolbox dir
clean:
@test -z "wrap" || rm -f wrap
@test -z "../toolbox" || rm -rf ../toolbox
endif
#----------------------------------------------------------------------------------------------------

139
wrap/Method.cpp Normal file
View File

@ -0,0 +1,139 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#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 <wrap/matlab.h>\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<Test> = 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<bool>(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();
}
/* ************************************************************************* */

46
wrap/Method.h Normal file
View File

@ -0,0 +1,46 @@
/* ----------------------------------------------------------------------------
* 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 <string>
#include <list>
#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
};

228
wrap/Module.cpp Normal file
View File

@ -0,0 +1,228 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/classic_core.hpp>
#include <boost/foreach.hpp>
#include "Module.h"
#include "utilities.h"
using namespace std;
using namespace BOOST_SPIRIT_CLASSIC_NS;
typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> 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<const char*> 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;
}
}
/* ************************************************************************* */

45
wrap/Module.h Normal file
View File

@ -0,0 +1,45 @@
/* ----------------------------------------------------------------------------
* 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 <string>
#include <list>
#include "Class.h"
// A module has classes
struct Module {
std::string name;
std::list<Class> 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);
};

39
wrap/geometry.h Normal file
View File

@ -0,0 +1,39 @@
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<Vector,Matrix> return_pair (Vector v, Matrix A);
bool return_field(const Test& t) const;
Test* return_TestPtr(Test* value);
pair<Test*,Test*> create_ptrs ();
pair<Test*,Test*> return_ptrs (Test* p1, Test* p2);
void print();
};

438
wrap/matlab.h Normal file
View File

@ -0,0 +1,438 @@
/* ----------------------------------------------------------------------------
* 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 <mex.h>
}
#include <list>
#include <string>
#include <sstream>
#include <gtsam/3rdparty/Eigen/Eigen/Core>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost; // not usual, but for conciseness of generated code
// start GTSAM Specifics /////////////////////////////////////////////////
typedef Eigen::VectorXd Vector; // NOTE: outside of gtsam namespace
typedef Eigen::MatrixXd 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 <typename Class>
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>(string& value) {
return mxCreateString(value.c_str());
}
// specialization to bool
template<>
mxArray* wrap<bool>(bool& value) {
mxArray *result = scalar(mxUINT32OR64_CLASS);
*(bool*)mxGetData(result) = value;
return result;
}
// specialization to size_t
template<>
mxArray* wrap<size_t>(size_t& value) {
mxArray *result = scalar(mxUINT32OR64_CLASS);
*(size_t*)mxGetData(result) = value;
return result;
}
// specialization to int
template<>
mxArray* wrap<int>(int& value) {
mxArray *result = scalar(mxUINT32OR64_CLASS);
*(int*)mxGetData(result) = value;
return result;
}
// specialization to double -> just double
template<>
mxArray* wrap<double>(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<m;i++) data[i]=v(i);
return result;
}
// specialization to BOOST vector -> double vector
template<>
mxArray* wrap<Vector >(Vector& v) {
return wrap_Vector(v);
}
// const version
template<>
mxArray* wrap<const Vector >(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<n;j++) for (int i=0;i<m;i++,data++) *data = A(i,j);
return result;
}
// specialization to BOOST MATRIX -> double matrix
template<>
mxArray* wrap<Matrix >(Matrix& A) {
return wrap_Matrix(A);
}
// const version
template<>
mxArray* wrap<const Matrix >(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 <typename T>
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<string>(const mxArray* array) {
char *data = mxArrayToString(array);
if (data==NULL) error("unwrap<string>: not a character array");
string str(data);
mxFree(data);
return str;
}
// specialization to bool
template<>
bool unwrap<bool>(const mxArray* array) {
checkScalar(array,"unwrap<bool>");
return mxGetScalar(array) != 0.0;
}
// specialization to size_t
template<>
size_t unwrap<size_t>(const mxArray* array) {
checkScalar(array,"unwrap<size_t>");
return (size_t)mxGetScalar(array);
}
// specialization to int
template<>
int unwrap<int>(const mxArray* array) {
checkScalar(array,"unwrap<int>");
return (int)mxGetScalar(array);
}
// specialization to double
template<>
double unwrap<double>(const mxArray* array) {
checkScalar(array,"unwrap<double>");
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<vector>: 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<matrix>: 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<n;j++) for (int i=0;i<m;i++,data++) A(i,j) = *data;
return A;
}
//*****************************************************************************
// Shared Pointer Handle
// inspired by mexhandle, but using shared_ptr
//*****************************************************************************
template<typename T> class Collector;
template<typename T>
class ObjectHandle {
private:
ObjectHandle* signature; // use 'this' as a unique object signature
const std::type_info* type; // type checking information
shared_ptr<T> 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<T> (ptr)) {
signature = this;
Collector<T>::register_handle(this);
}
// Constructor for shared pointers
// Creates shared pointer, will delete if is last one to hold pointer
ObjectHandle(shared_ptr<T> 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<T> 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<T> 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<ObjectHandle<T>**> (mxGetPr(handle)) = this;
return handle;
}
string type_name() const {
return type->name();
}
// Convert mxArray (passed to mex-function) to an ObjectHandle<T>.
// Import a handle from MatLab as a mxArray of UINT32. Check that
// it is actually a pointer to an ObjectHandle<T>.
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<T> pointer in the mxUINT32 of handle
ObjectHandle* obj = *reinterpret_cast<ObjectHandle**> (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<T> ; // 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 <typename T>
class Collector {
typedef ObjectHandle<T> 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 <typename Class>
mxArray* wrap_constructed(Class* pointer, const char *classname) {
ObjectHandle<Class>* handle = new ObjectHandle<Class>(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 <typename Class>
mxArray* wrap_shared_ptr(shared_ptr< Class > shared_ptr, const char *classname) {
ObjectHandle<Class>* handle = new ObjectHandle<Class>(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 <typename Class>
shared_ptr<Class> 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<Class>* handle = ObjectHandle<Class>::from_mex_handle(mxh);
return handle->get_object();
}
//*****************************************************************************

View File

@ -0,0 +1,15 @@
% 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

View File

@ -0,0 +1,10 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point2.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("dim",nargout,nargin-1,0);
shared_ptr<Point2> self = unwrap_shared_ptr< Point2 >(in[0],"Point2");
int result = self->dim();
out[0] = wrap< int >(result);
}

View File

@ -0,0 +1,5 @@
% automatically generated by wrap on 2010-Feb-23
% usage: obj.dim()
function result = dim(obj)
error('need to compile dim.cpp');
end

View File

@ -0,0 +1,10 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point2.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("x",nargout,nargin-1,0);
shared_ptr<Point2> self = unwrap_shared_ptr< Point2 >(in[0],"Point2");
double result = self->x();
out[0] = wrap< double >(result);
}

View File

@ -0,0 +1,5 @@
% automatically generated by wrap on 2010-Feb-23
% usage: obj.x()
function result = x(obj)
error('need to compile x.cpp');
end

View File

@ -0,0 +1,10 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point2.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("y",nargout,nargin-1,0);
shared_ptr<Point2> self = unwrap_shared_ptr< Point2 >(in[0],"Point2");
double result = self->y();
out[0] = wrap< double >(result);
}

View File

@ -0,0 +1,5 @@
% automatically generated by wrap on 2010-Feb-23
% usage: obj.y()
function result = y(obj)
error('need to compile y.cpp');
end

View File

@ -0,0 +1,14 @@
% 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

View File

@ -0,0 +1,10 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point3.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("norm",nargout,nargin-1,0);
shared_ptr<Point3> self = unwrap_shared_ptr< Point3 >(in[0],"Point3");
double result = self->norm();
out[0] = wrap< double >(result);
}

View File

@ -0,0 +1,5 @@
% automatically generated by wrap on 2010-Feb-23
% usage: obj.norm()
function result = norm(obj)
error('need to compile norm.cpp');
end

View File

@ -0,0 +1,14 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("create_ptrs",nargout,nargin-1,0);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
pair< shared_ptr<Test>, shared_ptr<Test> > result = self->create_ptrs();
out[0] = wrap_shared_ptr(result.first,"Test");
out[1] = wrap_shared_ptr(result.second,"Test");
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("print",nargout,nargin-1,0);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
self->print();
}

View File

@ -0,0 +1,5 @@
% automatically generated by wrap on 2010-Feb-23
% usage: obj.print()
function result = print(obj)
error('need to compile print.cpp');
end

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_TestPtr",nargout,nargin-1,1);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
shared_ptr<Test> value = unwrap_shared_ptr< Test >(in[1], "Test");
shared_ptr<Test> result = self->return_TestPtr(value);
out[0] = wrap_shared_ptr(result,"Test");
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_bool",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_double",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_field",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_int",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_matrix1",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_matrix2",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,13 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_pair",nargout,nargin-1,2);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,13 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_ptrs",nargout,nargin-1,2);
shared_ptr<Test> self = unwrap_shared_ptr< Test >(in[0],"Test");
shared_ptr<Test> p1 = unwrap_shared_ptr< Test >(in[1], "Test");
shared_ptr<Test> p2 = unwrap_shared_ptr< Test >(in[2], "Test");
pair< shared_ptr<Test>, shared_ptr<Test> > result = self->return_ptrs(p1,p2);
out[0] = wrap_shared_ptr(result.first,"Test");
out[1] = wrap_shared_ptr(result.second,"Test");
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_size_t",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_string",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_vector1",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[])
{
checkArguments("return_vector2",nargout,nargin-1,1);
shared_ptr<Test> 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);
}

View File

@ -0,0 +1,5 @@
% 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

View File

@ -0,0 +1,44 @@
% 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

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point2.h>
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");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2010-Feb-23
function result = new_Point2_(obj)
error('need to compile new_Point2_.cpp');
end

View File

@ -0,0 +1,11 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point2.h>
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");
}

View File

@ -0,0 +1,4 @@
% 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

View File

@ -0,0 +1,12 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Point3.h>
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");
}

View File

@ -0,0 +1,4 @@
% 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

View File

@ -0,0 +1,9 @@
// automatically generated by wrap on 2010-Feb-23
#include <wrap/matlab.h>
#include <Test.h>
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");
}

View File

@ -0,0 +1,4 @@
% automatically generated by wrap on 2010-Feb-23
function result = new_Test_(obj)
error('need to compile new_Test_.cpp');
end

105
wrap/tests/testSpirit.cpp Normal file
View File

@ -0,0 +1,105 @@
/* ----------------------------------------------------------------------------
* 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 <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_push_back_actor.hpp>
#include <CppUnitLite/TestHarness.h>
using namespace std;
using namespace BOOST_SPIRIT_CLASSIC_NS;
typedef rule<BOOST_SPIRIT_CLASSIC_NS::phrase_scanner_t> 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 <phrase_scanner_t>
rule<phrase_scanner_t>phrase_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); }
/* ************************************************************************* */

116
wrap/tests/testWrap.cpp Normal file
View File

@ -0,0 +1,116 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <sstream>
#include <CppUnitLite/TestHarness.h>
#include <wrap/utilities.h>
#include <wrap/Module.h>
using namespace std;
static bool verbose = false;
#ifdef TOPSRCDIR
static string topdir = TOPSRCDIR;
#else
static string topdir = "penguin";
#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");
EXPECT(args.types()=="double,double,double");
EXPECT(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);
EXPECT(module.classes.size()==3);
// check second class, Point3
Class cls = *(++module.classes.begin());
EXPECT(cls.name=="Point3");
EXPECT(cls.constructors.size()==1);
EXPECT(cls.methods.size()==1);
// first constructor takes 3 doubles
Constructor c1 = cls.constructors.front();
EXPECT(c1.args.size()==3);
// check first double argument
Argument a1 = c1.args.front();
EXPECT(!a1.is_const);
EXPECT(a1.type=="double");
EXPECT(!a1.is_ref);
EXPECT(a1.name=="x");
// check method
Method m1 = cls.methods.front();
EXPECT(m1.returns=="double");
EXPECT(m1.name=="norm");
EXPECT(m1.args.size()==0);
EXPECT(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");
EXPECT(files_equal(path + "/tests/expected/@Point2/Point2.m" , "actual/@Point2/Point2.m" ));
EXPECT(files_equal(path + "/tests/expected/@Point2/x.cpp" , "actual/@Point2/x.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Point3/Point3.m" , "actual/@Point3/Point3.m" ));
EXPECT(files_equal(path + "/tests/expected/new_Point3_ddd.m" , "actual/new_Point3_ddd.m" ));
EXPECT(files_equal(path + "/tests/expected/new_Point3_ddd.cpp", "actual/new_Point3_ddd.cpp"));
EXPECT(files_equal(path + "/tests/expected/@Point3/norm.m" , "actual/@Point3/norm.m" ));
EXPECT(files_equal(path + "/tests/expected/@Point3/norm.cpp" , "actual/@Point3/norm.cpp" ));
EXPECT(files_equal(path + "/tests/expected/new_Test_.cpp" , "actual/new_Test_.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/Test.m" , "actual/@Test/Test.m" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_string.cpp" , "actual/@Test/return_string.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_pair.cpp" , "actual/@Test/return_pair.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_field.cpp" , "actual/@Test/return_field.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/return_TestPtr.cpp", "actual/@Test/return_TestPtr.cpp"));
EXPECT(files_equal(path + "/tests/expected/@Test/return_ptrs.cpp" , "actual/@Test/return_ptrs.cpp" ));
EXPECT(files_equal(path + "/tests/expected/@Test/print.m" , "actual/@Test/print.m" ));
EXPECT(files_equal(path + "/tests/expected/@Test/print.cpp" , "actual/@Test/print.cpp" ));
EXPECT(files_equal(path + "/tests/expected/make_geometry.m" , "actual/make_geometry.m" ));
}
/* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
/* ************************************************************************* */

68
wrap/utilities.cpp Normal file
View File

@ -0,0 +1,68 @@
/* ----------------------------------------------------------------------------
* 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 <iostream>
#include <fstream>
#include <boost/date_time/gregorian/gregorian.hpp>
#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;
}
/* ************************************************************************* */

60
wrap/utilities.h Normal file
View File

@ -0,0 +1,60 @@
/* ----------------------------------------------------------------------------
* 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 <exception>
#include <sstream>
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);

58
wrap/wrap.cpp Normal file
View File

@ -0,0 +1,58 @@
/* ----------------------------------------------------------------------------
* 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 <stdio.h>
#include <iostream>
#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]);
}
/* ************************************************************************* */