2011-10-14 02:41:56 +08:00
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
* 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
|
|
|
|
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/**
|
2011-10-14 11:23:14 +08:00
|
|
|
* @file Argument.ccp
|
|
|
|
* @author Frank Dellaert
|
2012-06-27 02:52:27 +08:00
|
|
|
* @author Andrew Melim
|
2012-07-13 06:28:28 +08:00
|
|
|
* @author Richard Roberts
|
2011-10-14 02:41:56 +08:00
|
|
|
**/
|
|
|
|
|
2014-05-26 01:01:36 +08:00
|
|
|
#include "Argument.h"
|
2016-12-16 13:23:45 +08:00
|
|
|
#include "Class.h"
|
2014-05-26 01:01:36 +08:00
|
|
|
|
2014-11-30 04:43:48 +08:00
|
|
|
#include <boost/lexical_cast.hpp>
|
2011-10-14 02:41:56 +08:00
|
|
|
|
2014-05-26 01:01:36 +08:00
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
2011-10-14 02:41:56 +08:00
|
|
|
|
|
|
|
using namespace std;
|
2011-12-03 00:43:15 +08:00
|
|
|
using namespace wrap;
|
2011-10-14 02:41:56 +08:00
|
|
|
|
2014-11-13 19:52:41 +08:00
|
|
|
/* ************************************************************************* */
|
2014-11-14 00:28:05 +08:00
|
|
|
Argument Argument::expandTemplate(const TemplateSubstitution& ts) const {
|
2014-11-13 19:52:41 +08:00
|
|
|
Argument instArg = *this;
|
2014-11-30 07:13:29 +08:00
|
|
|
instArg.type = ts.tryToSubstitite(type);
|
2014-11-13 19:52:41 +08:00
|
|
|
return instArg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2014-11-30 04:11:13 +08:00
|
|
|
ArgumentList ArgumentList::expandTemplate(
|
|
|
|
const TemplateSubstitution& ts) const {
|
2014-11-13 19:52:41 +08:00
|
|
|
ArgumentList instArgList;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(const Argument& arg: *this) {
|
2014-11-14 00:28:05 +08:00
|
|
|
Argument instArg = arg.expandTemplate(ts);
|
2014-11-13 19:52:41 +08:00
|
|
|
instArgList.push_back(instArg);
|
|
|
|
}
|
|
|
|
return instArgList;
|
|
|
|
}
|
|
|
|
|
2012-01-10 13:06:46 +08:00
|
|
|
/* ************************************************************************* */
|
2012-01-29 03:44:33 +08:00
|
|
|
string Argument::matlabClass(const string& delim) const {
|
2012-10-02 22:40:07 +08:00
|
|
|
string result;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(const string& ns: type.namespaces())
|
2014-05-26 02:35:07 +08:00
|
|
|
result += ns + delim;
|
2014-12-01 03:12:03 +08:00
|
|
|
if (type.name() == "string" || type.name() == "unsigned char"
|
|
|
|
|| type.name() == "char")
|
2012-10-02 22:40:07 +08:00
|
|
|
return result + "char";
|
2014-12-01 03:12:03 +08:00
|
|
|
if (type.name() == "Vector" || type.name() == "Matrix")
|
2012-06-13 20:03:33 +08:00
|
|
|
return result + "double";
|
2014-12-01 03:12:03 +08:00
|
|
|
if (type.name() == "int" || type.name() == "size_t")
|
2012-06-13 20:03:33 +08:00
|
|
|
return result + "numeric";
|
2014-12-01 03:12:03 +08:00
|
|
|
if (type.name() == "bool")
|
2012-06-13 20:03:33 +08:00
|
|
|
return result + "logical";
|
2014-12-01 03:12:03 +08:00
|
|
|
return result + type.name();
|
2012-01-10 13:06:46 +08:00
|
|
|
}
|
|
|
|
|
2011-10-14 02:41:56 +08:00
|
|
|
/* ************************************************************************* */
|
2012-01-16 05:42:41 +08:00
|
|
|
void Argument::matlab_unwrap(FileWriter& file, const string& matlabName) const {
|
|
|
|
file.oss << " ";
|
2011-10-14 02:41:56 +08:00
|
|
|
|
2014-11-12 09:49:23 +08:00
|
|
|
string cppType = type.qualifiedName("::");
|
|
|
|
string matlabUniqueType = type.qualifiedName();
|
2017-03-09 04:15:37 +08:00
|
|
|
bool isNotScalar = !type.isScalar();
|
2011-12-09 04:51:15 +08:00
|
|
|
|
2017-01-19 09:49:12 +08:00
|
|
|
// We cannot handle scalar non const references
|
|
|
|
if (!isNotScalar && is_ref && !is_const) {
|
2017-01-20 09:58:59 +08:00
|
|
|
throw std::runtime_error("Cannot unwrap a scalar non-const reference");
|
2017-01-19 09:49:12 +08:00
|
|
|
}
|
2011-12-09 04:51:15 +08:00
|
|
|
|
2014-12-13 00:34:34 +08:00
|
|
|
if (is_ptr && type.category != Qualified::EIGEN)
|
2012-10-02 22:40:07 +08:00
|
|
|
// A pointer: emit an "unwrap_shared_ptr" call which returns a pointer
|
2014-05-26 02:35:07 +08:00
|
|
|
file.oss << "boost::shared_ptr<" << cppType << "> " << name
|
|
|
|
<< " = unwrap_shared_ptr< ";
|
2017-01-17 18:12:00 +08:00
|
|
|
else if (is_ref && isNotScalar && type.category != Qualified::EIGEN)
|
2012-10-02 22:40:07 +08:00
|
|
|
// A reference: emit an "unwrap_shared_ptr" call and de-reference the pointer
|
|
|
|
file.oss << cppType << "& " << name << " = *unwrap_shared_ptr< ";
|
|
|
|
else
|
2017-01-17 18:12:00 +08:00
|
|
|
// Not a pointer, or a reference to a scalar type. Therefore, emit an "unwrap" call
|
2012-10-02 22:40:07 +08:00
|
|
|
// unwrap is specified in matlab.h as a series of template specializations
|
|
|
|
// that know how to unpack the expected MATLAB object
|
|
|
|
// example: double tol = unwrap< double >(in[2]);
|
|
|
|
// example: Vector v = unwrap< Vector >(in[1]);
|
|
|
|
file.oss << cppType << " " << name << " = unwrap< ";
|
|
|
|
|
|
|
|
file.oss << cppType << " >(" << matlabName;
|
2017-01-17 18:12:00 +08:00
|
|
|
if( (is_ptr || is_ref) && isNotScalar && type.category != Qualified::EIGEN)
|
2014-05-26 02:35:07 +08:00
|
|
|
file.oss << ", \"ptr_" << matlabUniqueType << "\"";
|
2012-01-16 05:42:41 +08:00
|
|
|
file.oss << ");" << endl;
|
2011-10-14 02:41:56 +08:00
|
|
|
}
|
|
|
|
|
2014-11-30 04:11:13 +08:00
|
|
|
/* ************************************************************************* */
|
2014-11-30 04:43:48 +08:00
|
|
|
void Argument::proxy_check(FileWriter& proxyFile, const string& s) const {
|
|
|
|
proxyFile.oss << "isa(" << s << ",'" << matlabClass(".") << "')";
|
2014-12-01 03:12:03 +08:00
|
|
|
if (type.name() == "Vector")
|
2014-11-30 04:43:48 +08:00
|
|
|
proxyFile.oss << " && size(" << s << ",2)==1";
|
2014-11-30 04:11:13 +08:00
|
|
|
}
|
|
|
|
|
2016-09-09 01:33:32 +08:00
|
|
|
/* ************************************************************************* */
|
2016-12-16 13:23:45 +08:00
|
|
|
void Argument::emit_cython_pxd(
|
|
|
|
FileWriter& file, const std::string& className,
|
|
|
|
const std::vector<std::string>& templateArgs) const {
|
|
|
|
string cythonType = type.pxdClassName();
|
|
|
|
if (cythonType == "This") cythonType = className;
|
|
|
|
else if (type.isEigen())
|
|
|
|
cythonType = "const " + cythonType + "&";
|
|
|
|
else if (type.match(templateArgs))
|
|
|
|
cythonType = type.name();
|
|
|
|
|
|
|
|
// add modifier
|
|
|
|
if (!type.isEigen()) {
|
|
|
|
if (is_ptr) cythonType = "shared_ptr[" + cythonType + "]&";
|
2016-09-09 01:33:32 +08:00
|
|
|
if (is_ref) cythonType = cythonType + "&";
|
|
|
|
if (is_const) cythonType = "const " + cythonType;
|
|
|
|
}
|
|
|
|
|
|
|
|
file.oss << cythonType << " " << name;
|
|
|
|
}
|
|
|
|
|
2016-09-10 03:52:44 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
void Argument::emit_cython_pyx(FileWriter& file) const {
|
2016-11-23 01:13:33 +08:00
|
|
|
file.oss << type.pyxArgumentType() << " " << name;
|
2016-09-10 03:52:44 +08:00
|
|
|
}
|
|
|
|
|
convert numpy input params to dtype float and order 'F' automatically
using numpy.astype(...). No copy if the params are already in the correct dtype and storage order.
For a function
f(Matrix A, Matrix B),
simply wrapping it to pyx as
f(A.astype(float, order='F', copy=False), B.astype(float, order='F', copy=False))
won't work.
It produces a strange side-effect that the content of A is overwritten by B and the two inputs are the same (data address) inside the function!
This is because Cython decreases the ref count for the temporary variable resulted from A.astype(...) before generates the wrap for B.astype(...).
Hence, the A.astype temp var is probably reused for B.astype, and they were pointing to the same data address.
For that reason, we have to go a longer route and wrap it as:
A = A.astype(float, order='F', copy=False)
B = B.astype(float, order='F', copy=False)
f(A, B)
For future ref., here is a sample of the wrongly generated code that wraps the JacobianFactor constructor:
Jacobian(Key i1, Matrix A1, Key i2, Matrix A2, Vector b, noiseModel::Diagonal model)
Wrongly wrapped pyx code:
self.shared_CJacobianFactor_ = shared_ptr[CJacobianFactor](new CJacobianFactor(i1, <MatrixXd>(Map[MatrixXd](A1.astype(float, order='F',copy=False)), i2, <MatrixXd>(Map[MatrixXd](A2.astype(float, order='F', copy=False)), <VectorXd>(Map[VectorXd](b.astype(float, order='F', copy=False))), model.shared_CnoiseModel_Diagonal_))
The problematic Cython generated CPP code with a comment on the problematic line:
/////////////////////////////////////////
// WRONG VERSION
/////////////////////////////////////////
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A1), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_14 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
///////////////////////////////////////////////
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; //<------- Problematic line!!! Killing this will result in the correct result!
///////////////////////////////////////////////
__pyx_t_13 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A2), __pyx_n_s_astype); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_15 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_12));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_b), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_16 = eigency::Map<Eigen::VectorXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
try {
__pyx_t_17 = new gtsam::JacobianFactor(__pyx_v_i1, ((Eigen::MatrixXd)__pyx_t_14), __pyx_v_i2, ((Eigen::MatrixXd)__pyx_t_15), ((Eigen::VectorXd)__pyx_t_16), __pyx_v_model->shared_CnoiseModel_Diagonal_);
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__pyx_v_self->shared_CJacobianFactor_ = boost::shared_ptr<gtsam::JacobianFactor> (__pyx_t_17);
2017-03-16 01:47:11 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
std::string Argument::pyx_convertEigenTypeAndStorageOrder() const {
|
|
|
|
if (!type.isEigen())
|
|
|
|
return "";
|
|
|
|
return name + " = " + name + ".astype(float, order=\'F\', copy=False)";
|
|
|
|
}
|
|
|
|
|
2016-09-10 03:52:44 +08:00
|
|
|
/* ************************************************************************* */
|
2016-11-20 22:24:43 +08:00
|
|
|
std::string Argument::pyx_asParam() const {
|
2016-11-23 01:13:33 +08:00
|
|
|
string cythonType = type.pxdClassName();
|
2016-09-10 03:52:44 +08:00
|
|
|
string cythonVar;
|
2016-09-10 06:37:48 +08:00
|
|
|
if (type.isNonBasicType()) {
|
2016-11-23 01:13:33 +08:00
|
|
|
cythonVar = name + "." + type.shared_pxd_obj_in_pyx();
|
2016-09-10 06:37:48 +08:00
|
|
|
if (!is_ptr) cythonVar = "deref(" + cythonVar + ")";
|
|
|
|
} else if (type.isEigen()) {
|
2016-09-14 19:44:38 +08:00
|
|
|
cythonVar = "<" + cythonType + ">" + "(Map[" + cythonType + "](" + name + "))";
|
2016-09-10 03:52:44 +08:00
|
|
|
} else {
|
2016-09-10 06:37:48 +08:00
|
|
|
cythonVar = name;
|
2016-09-10 03:52:44 +08:00
|
|
|
}
|
convert numpy input params to dtype float and order 'F' automatically
using numpy.astype(...). No copy if the params are already in the correct dtype and storage order.
For a function
f(Matrix A, Matrix B),
simply wrapping it to pyx as
f(A.astype(float, order='F', copy=False), B.astype(float, order='F', copy=False))
won't work.
It produces a strange side-effect that the content of A is overwritten by B and the two inputs are the same (data address) inside the function!
This is because Cython decreases the ref count for the temporary variable resulted from A.astype(...) before generates the wrap for B.astype(...).
Hence, the A.astype temp var is probably reused for B.astype, and they were pointing to the same data address.
For that reason, we have to go a longer route and wrap it as:
A = A.astype(float, order='F', copy=False)
B = B.astype(float, order='F', copy=False)
f(A, B)
For future ref., here is a sample of the wrongly generated code that wraps the JacobianFactor constructor:
Jacobian(Key i1, Matrix A1, Key i2, Matrix A2, Vector b, noiseModel::Diagonal model)
Wrongly wrapped pyx code:
self.shared_CJacobianFactor_ = shared_ptr[CJacobianFactor](new CJacobianFactor(i1, <MatrixXd>(Map[MatrixXd](A1.astype(float, order='F',copy=False)), i2, <MatrixXd>(Map[MatrixXd](A2.astype(float, order='F', copy=False)), <VectorXd>(Map[VectorXd](b.astype(float, order='F', copy=False))), model.shared_CnoiseModel_Diagonal_))
The problematic Cython generated CPP code with a comment on the problematic line:
/////////////////////////////////////////
// WRONG VERSION
/////////////////////////////////////////
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A1), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_14 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
///////////////////////////////////////////////
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; //<------- Problematic line!!! Killing this will result in the correct result!
///////////////////////////////////////////////
__pyx_t_13 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A2), __pyx_n_s_astype); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_15 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_12));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_b), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_16 = eigency::Map<Eigen::VectorXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
try {
__pyx_t_17 = new gtsam::JacobianFactor(__pyx_v_i1, ((Eigen::MatrixXd)__pyx_t_14), __pyx_v_i2, ((Eigen::MatrixXd)__pyx_t_15), ((Eigen::VectorXd)__pyx_t_16), __pyx_v_model->shared_CnoiseModel_Diagonal_);
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__pyx_v_self->shared_CJacobianFactor_ = boost::shared_ptr<gtsam::JacobianFactor> (__pyx_t_17);
2017-03-16 01:47:11 +08:00
|
|
|
return cythonVar;
|
2016-09-10 03:52:44 +08:00
|
|
|
}
|
|
|
|
|
2011-10-14 02:41:56 +08:00
|
|
|
/* ************************************************************************* */
|
2011-12-12 05:09:07 +08:00
|
|
|
string ArgumentList::types() const {
|
2011-10-14 02:41:56 +08:00
|
|
|
string str;
|
2014-05-26 02:35:07 +08:00
|
|
|
bool first = true;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this) {
|
2014-05-26 02:35:07 +08:00
|
|
|
if (!first)
|
|
|
|
str += ",";
|
2014-12-01 03:12:03 +08:00
|
|
|
str += arg.type.name();
|
2014-05-26 02:35:07 +08:00
|
|
|
first = false;
|
2011-10-14 02:41:56 +08:00
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2011-12-12 05:09:07 +08:00
|
|
|
string ArgumentList::signature() const {
|
2011-12-16 03:39:09 +08:00
|
|
|
string sig;
|
2014-05-26 02:35:07 +08:00
|
|
|
bool cap = false;
|
2011-12-15 05:10:56 +08:00
|
|
|
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this) {
|
|
|
|
for(char ch: arg.type.name())
|
2014-05-26 02:35:07 +08:00
|
|
|
if (isupper(ch)) {
|
|
|
|
sig += ch;
|
|
|
|
//If there is a capital letter, we don't want to read it below
|
|
|
|
cap = true;
|
|
|
|
}
|
|
|
|
if (!cap)
|
2014-12-01 03:12:03 +08:00
|
|
|
sig += arg.type.name()[0];
|
2011-12-16 06:26:39 +08:00
|
|
|
//Reset to default
|
|
|
|
cap = false;
|
2011-12-15 05:10:56 +08:00
|
|
|
}
|
|
|
|
|
2011-12-16 03:39:09 +08:00
|
|
|
return sig;
|
2011-10-14 02:41:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2011-12-12 05:09:07 +08:00
|
|
|
string ArgumentList::names() const {
|
2011-10-14 02:41:56 +08:00
|
|
|
string str;
|
2014-05-26 02:35:07 +08:00
|
|
|
bool first = true;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this) {
|
2014-05-26 02:35:07 +08:00
|
|
|
if (!first)
|
|
|
|
str += ",";
|
|
|
|
str += arg.name;
|
|
|
|
first = false;
|
2011-10-14 02:41:56 +08:00
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2014-05-26 03:21:13 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
bool ArgumentList::allScalar() const {
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this)
|
2016-09-10 06:37:48 +08:00
|
|
|
if (!arg.type.isScalar())
|
2014-11-13 19:52:41 +08:00
|
|
|
return false;
|
2014-05-26 03:21:13 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-10-14 02:41:56 +08:00
|
|
|
/* ************************************************************************* */
|
2012-01-16 05:42:41 +08:00
|
|
|
void ArgumentList::matlab_unwrap(FileWriter& file, int start) const {
|
2011-10-14 02:41:56 +08:00
|
|
|
int index = start;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this) {
|
2011-10-14 02:41:56 +08:00
|
|
|
stringstream buf;
|
|
|
|
buf << "in[" << index << "]";
|
2014-05-26 02:35:07 +08:00
|
|
|
arg.matlab_unwrap(file, buf.str());
|
2011-10-14 02:41:56 +08:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2014-05-26 01:01:36 +08:00
|
|
|
void ArgumentList::emit_prototype(FileWriter& file, const string& name) const {
|
|
|
|
file.oss << name << "(";
|
2014-05-26 01:12:48 +08:00
|
|
|
bool first = true;
|
2016-05-21 09:41:18 +08:00
|
|
|
for(Argument arg: *this) {
|
2014-05-26 02:35:07 +08:00
|
|
|
if (!first)
|
|
|
|
file.oss << ", ";
|
2014-12-01 03:12:03 +08:00
|
|
|
file.oss << arg.type.name() << " " << arg.name;
|
2014-05-26 01:12:48 +08:00
|
|
|
first = false;
|
2014-05-26 01:01:36 +08:00
|
|
|
}
|
|
|
|
file.oss << ")";
|
|
|
|
}
|
2014-11-30 03:53:38 +08:00
|
|
|
|
2016-09-09 01:33:32 +08:00
|
|
|
/* ************************************************************************* */
|
2016-12-16 13:23:45 +08:00
|
|
|
void ArgumentList::emit_cython_pxd(
|
|
|
|
FileWriter& file, const std::string& className,
|
|
|
|
const std::vector<std::string>& templateArgs) const {
|
2016-09-09 01:33:32 +08:00
|
|
|
for (size_t j = 0; j<size(); ++j) {
|
2016-12-16 13:23:45 +08:00
|
|
|
at(j).emit_cython_pxd(file, className, templateArgs);
|
2016-09-09 01:33:32 +08:00
|
|
|
if (j<size()-1) file.oss << ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-10 03:52:44 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
void ArgumentList::emit_cython_pyx(FileWriter& file) const {
|
|
|
|
for (size_t j = 0; j < size(); ++j) {
|
|
|
|
at(j).emit_cython_pyx(file);
|
|
|
|
if (j < size() - 1) file.oss << ", ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
convert numpy input params to dtype float and order 'F' automatically
using numpy.astype(...). No copy if the params are already in the correct dtype and storage order.
For a function
f(Matrix A, Matrix B),
simply wrapping it to pyx as
f(A.astype(float, order='F', copy=False), B.astype(float, order='F', copy=False))
won't work.
It produces a strange side-effect that the content of A is overwritten by B and the two inputs are the same (data address) inside the function!
This is because Cython decreases the ref count for the temporary variable resulted from A.astype(...) before generates the wrap for B.astype(...).
Hence, the A.astype temp var is probably reused for B.astype, and they were pointing to the same data address.
For that reason, we have to go a longer route and wrap it as:
A = A.astype(float, order='F', copy=False)
B = B.astype(float, order='F', copy=False)
f(A, B)
For future ref., here is a sample of the wrongly generated code that wraps the JacobianFactor constructor:
Jacobian(Key i1, Matrix A1, Key i2, Matrix A2, Vector b, noiseModel::Diagonal model)
Wrongly wrapped pyx code:
self.shared_CJacobianFactor_ = shared_ptr[CJacobianFactor](new CJacobianFactor(i1, <MatrixXd>(Map[MatrixXd](A1.astype(float, order='F',copy=False)), i2, <MatrixXd>(Map[MatrixXd](A2.astype(float, order='F', copy=False)), <VectorXd>(Map[VectorXd](b.astype(float, order='F', copy=False))), model.shared_CnoiseModel_Diagonal_))
The problematic Cython generated CPP code with a comment on the problematic line:
/////////////////////////////////////////
// WRONG VERSION
/////////////////////////////////////////
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A1), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_14 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
///////////////////////////////////////////////
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; //<------- Problematic line!!! Killing this will result in the correct result!
///////////////////////////////////////////////
__pyx_t_13 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A2), __pyx_n_s_astype); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_15 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_12));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_b), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_16 = eigency::Map<Eigen::VectorXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
try {
__pyx_t_17 = new gtsam::JacobianFactor(__pyx_v_i1, ((Eigen::MatrixXd)__pyx_t_14), __pyx_v_i2, ((Eigen::MatrixXd)__pyx_t_15), ((Eigen::VectorXd)__pyx_t_16), __pyx_v_model->shared_CnoiseModel_Diagonal_);
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__pyx_v_self->shared_CJacobianFactor_ = boost::shared_ptr<gtsam::JacobianFactor> (__pyx_t_17);
2017-03-16 01:47:11 +08:00
|
|
|
/* ************************************************************************* */
|
|
|
|
std::string ArgumentList::pyx_convertEigenTypeAndStorageOrder(const std::string& indent) const {
|
2017-03-16 10:45:48 +08:00
|
|
|
string ret, conversion;
|
|
|
|
for (size_t j = 0; j < size(); ++j) {
|
|
|
|
conversion = at(j).pyx_convertEigenTypeAndStorageOrder();
|
|
|
|
if (!conversion.empty())
|
|
|
|
ret += indent + conversion + "\n";
|
|
|
|
}
|
convert numpy input params to dtype float and order 'F' automatically
using numpy.astype(...). No copy if the params are already in the correct dtype and storage order.
For a function
f(Matrix A, Matrix B),
simply wrapping it to pyx as
f(A.astype(float, order='F', copy=False), B.astype(float, order='F', copy=False))
won't work.
It produces a strange side-effect that the content of A is overwritten by B and the two inputs are the same (data address) inside the function!
This is because Cython decreases the ref count for the temporary variable resulted from A.astype(...) before generates the wrap for B.astype(...).
Hence, the A.astype temp var is probably reused for B.astype, and they were pointing to the same data address.
For that reason, we have to go a longer route and wrap it as:
A = A.astype(float, order='F', copy=False)
B = B.astype(float, order='F', copy=False)
f(A, B)
For future ref., here is a sample of the wrongly generated code that wraps the JacobianFactor constructor:
Jacobian(Key i1, Matrix A1, Key i2, Matrix A2, Vector b, noiseModel::Diagonal model)
Wrongly wrapped pyx code:
self.shared_CJacobianFactor_ = shared_ptr[CJacobianFactor](new CJacobianFactor(i1, <MatrixXd>(Map[MatrixXd](A1.astype(float, order='F',copy=False)), i2, <MatrixXd>(Map[MatrixXd](A2.astype(float, order='F', copy=False)), <VectorXd>(Map[VectorXd](b.astype(float, order='F', copy=False))), model.shared_CnoiseModel_Diagonal_))
The problematic Cython generated CPP code with a comment on the problematic line:
/////////////////////////////////////////
// WRONG VERSION
/////////////////////////////////////////
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A1), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_14 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
///////////////////////////////////////////////
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; //<------- Problematic line!!! Killing this will result in the correct result!
///////////////////////////////////////////////
__pyx_t_13 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A2), __pyx_n_s_astype); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_15 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_12));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_b), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
__pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
__Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
__pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
try {
__pyx_t_16 = eigency::Map<Eigen::VectorXd> (((PyArrayObject *)__pyx_t_13));
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
try {
__pyx_t_17 = new gtsam::JacobianFactor(__pyx_v_i1, ((Eigen::MatrixXd)__pyx_t_14), __pyx_v_i2, ((Eigen::MatrixXd)__pyx_t_15), ((Eigen::VectorXd)__pyx_t_16), __pyx_v_model->shared_CnoiseModel_Diagonal_);
} catch(...) {
__Pyx_CppExn2PyErr();
__PYX_ERR(0, 2107, __pyx_L1_error)
}
__pyx_v_self->shared_CJacobianFactor_ = boost::shared_ptr<gtsam::JacobianFactor> (__pyx_t_17);
2017-03-16 01:47:11 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-09-10 03:52:44 +08:00
|
|
|
/* ************************************************************************* */
|
2016-11-20 22:24:43 +08:00
|
|
|
std::string ArgumentList::pyx_asParams() const {
|
|
|
|
string ret;
|
2016-11-17 06:51:03 +08:00
|
|
|
for (size_t j = 0; j < size(); ++j) {
|
2016-11-20 22:24:43 +08:00
|
|
|
ret += at(j).pyx_asParam();
|
|
|
|
if (j < size() - 1) ret += ", ";
|
2016-09-10 03:52:44 +08:00
|
|
|
}
|
2016-11-20 22:24:43 +08:00
|
|
|
return ret;
|
2016-09-10 03:52:44 +08:00
|
|
|
}
|
|
|
|
|
2016-11-17 06:51:03 +08:00
|
|
|
/* ************************************************************************* */
|
2016-11-20 22:24:43 +08:00
|
|
|
std::string ArgumentList::pyx_paramsList() const {
|
|
|
|
string s;
|
2016-11-17 06:51:03 +08:00
|
|
|
for (size_t j = 0; j < size(); ++j) {
|
2016-11-20 22:24:43 +08:00
|
|
|
s += "'" + at(j).name + "'";
|
|
|
|
if (j < size() - 1) s += ", ";
|
2016-11-17 06:51:03 +08:00
|
|
|
}
|
2016-11-20 22:24:43 +08:00
|
|
|
return s;
|
2016-11-17 06:51:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************* */
|
2016-11-20 22:24:43 +08:00
|
|
|
std::string ArgumentList::pyx_castParamsToPythonType() const {
|
|
|
|
if (size() == 0)
|
2016-11-30 18:56:07 +08:00
|
|
|
return " pass\n";
|
2016-11-17 06:51:03 +08:00
|
|
|
|
|
|
|
// cast params to their correct python argument type to pass in the function call later
|
2016-11-20 22:24:43 +08:00
|
|
|
string s;
|
|
|
|
for (size_t j = 0; j < size(); ++j)
|
2016-11-30 18:56:07 +08:00
|
|
|
s += " " + at(j).name + " = <" + at(j).type.pyxArgumentType()
|
2016-11-20 22:24:43 +08:00
|
|
|
+ ">(__params['" + at(j).name + "'])\n";
|
|
|
|
return s;
|
2016-11-17 06:51:03 +08:00
|
|
|
}
|
|
|
|
|
2014-05-26 01:01:36 +08:00
|
|
|
/* ************************************************************************* */
|
2014-11-30 04:11:13 +08:00
|
|
|
void ArgumentList::proxy_check(FileWriter& proxyFile) const {
|
2014-05-26 02:35:07 +08:00
|
|
|
// Check nr of arguments
|
2014-11-13 03:51:47 +08:00
|
|
|
proxyFile.oss << "if length(varargin) == " << size();
|
2014-05-26 02:35:07 +08:00
|
|
|
if (size() > 0)
|
2014-11-13 03:51:47 +08:00
|
|
|
proxyFile.oss << " && ";
|
2014-11-12 09:49:23 +08:00
|
|
|
// ...and their type.names
|
2014-05-26 02:35:07 +08:00
|
|
|
bool first = true;
|
|
|
|
for (size_t i = 0; i < size(); i++) {
|
|
|
|
if (!first)
|
2014-11-13 03:51:47 +08:00
|
|
|
proxyFile.oss << " && ";
|
2014-11-30 04:43:48 +08:00
|
|
|
string s = "varargin{" + boost::lexical_cast<string>(i + 1) + "}";
|
|
|
|
(*this)[i].proxy_check(proxyFile, s);
|
2014-05-26 02:35:07 +08:00
|
|
|
first = false;
|
|
|
|
}
|
2014-11-13 03:51:47 +08:00
|
|
|
proxyFile.oss << "\n";
|
2014-05-26 02:35:07 +08:00
|
|
|
}
|
2014-11-30 04:11:13 +08:00
|
|
|
|
2014-05-26 02:35:07 +08:00
|
|
|
/* ************************************************************************* */
|
2012-06-27 02:52:27 +08:00
|
|
|
|