gtsam/wrap/Method.cpp

177 lines
6.7 KiB
C++
Raw Normal View History

/* ----------------------------------------------------------------------------
* 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
2012-07-13 06:28:28 +08:00
* @author Richard Roberts
**/
#include "Method.h"
#include "Class.h"
#include "utilities.h"
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <fstream>
using namespace std;
using namespace wrap;
/* ************************************************************************* */
bool Method::addOverload(Str name, const ArgumentList& args,
const ReturnValue& retVal, bool is_const,
boost::optional<const Qualified> instName,
bool verbose) {
bool first = MethodBase::addOverload(name, args, retVal, instName, verbose);
if (first)
is_const_ = is_const;
else if (is_const && !is_const_)
throw std::runtime_error(
"Method::addOverload now designated as const whereas before it was "
"not");
else if (!is_const && is_const_)
throw std::runtime_error(
"Method::addOverload now designated as non-const whereas before it "
"was");
return first;
}
/* ************************************************************************* */
void Method::proxy_header(FileWriter& proxyFile) const {
proxyFile.oss << " function varargout = " << matlabName()
<< "(this, varargin)\n";
}
/* ************************************************************************* */
string Method::wrapper_call(FileWriter& wrapperFile, Str cppClassName,
Str matlabUniqueName,
const ArgumentList& args) const {
// check arguments
// extra argument obj -> nargin-1 is passed !
// example: checkArguments("equals",nargout,nargin-1,2);
2014-11-30 02:34:46 +08:00
wrapperFile.oss << " checkArguments(\"" << matlabName()
<< "\",nargout,nargin-1," << args.size() << ");\n";
// get class pointer
// example: shared_ptr<Test> = unwrap_shared_ptr< Test >(in[0], "Test");
wrapperFile.oss << " Shared obj = unwrap_shared_ptr<" << cppClassName
<< ">(in[0], \"ptr_" << matlabUniqueName << "\");" << endl;
// unwrap arguments, see Argument.cpp, we start at 1 as first is obj
args.matlab_unwrap(wrapperFile, 1);
// call method and wrap result
// example: out[0]=wrap<bool>(obj->return_field(t));
string expanded = "obj->" + name_;
if (templateArgValue_)
expanded += ("<" + templateArgValue_->qualifiedName("::") + ">");
return expanded;
}
/* ************************************************************************* */
2016-09-12 06:14:19 +08:00
void Method::emit_cython_pxd(FileWriter& file, const Class& cls) const {
for (size_t i = 0; i < nrOverloads(); ++i) {
2016-11-30 18:56:07 +08:00
file.oss << " ";
returnVals_[i].emit_cython_pxd(file, cls.pxdClassName(), cls.templateArgs);
file.oss << pyRename(name_) + " \"" + name_ + "\""
<< "(";
argumentList(i).emit_cython_pxd(file, cls.pxdClassName(), cls.templateArgs);
file.oss << ")";
// if (is_const_) file.oss << " const";
file.oss << " except +";
file.oss << "\n";
}
}
/* ************************************************************************* */
void Method::emit_cython_pyx_no_overload(FileWriter& file,
const Class& cls) const {
string funcName = pyRename(name_);
// leverage python's special treatment for print
if (funcName == "print_")
2016-11-30 18:56:07 +08:00
file.oss << " def __str__(self):\n self.print_('')\n return ''\n";
// Function definition
2016-11-30 18:56:07 +08:00
file.oss << " def " << funcName;
// modify name of function instantiation as python doesn't allow overloads
// e.g. template<T={A,B,C}> funcName(...) --> funcNameA, funcNameB, funcNameC
if (templateArgValue_) file.oss << templateArgValue_->pyxClassName();
// funtion arguments
file.oss << "(self";
if (argumentList(0).size() > 0) file.oss << ", ";
argumentList(0).emit_cython_pyx(file);
file.oss << "):\n";
/// Call cython corresponding function and return
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
file.oss << argumentList(0).pyx_convertEigenTypeAndStorageOrder(" ");
string caller = "self." + cls.shared_pxd_obj_in_pyx() + ".get()";
string ret = pyx_functionCall(caller, funcName, 0);
if (!returnVals_[0].isVoid()) {
2016-11-30 18:56:07 +08:00
file.oss << " cdef " << returnVals_[0].pyx_returnType()
<< " ret = " << ret << "\n";
2016-11-30 18:56:07 +08:00
file.oss << " return " << returnVals_[0].pyx_casting("ret") << "\n";
} else {
2016-11-30 18:56:07 +08:00
file.oss << " " << ret << "\n";
}
}
/* ************************************************************************* */
void Method::emit_cython_pyx(FileWriter& file, const Class& cls) const {
string funcName = pyRename(name_);
// For template function: modify name of function instantiation as python
// doesn't allow overloads
// e.g. template<T={A,B,C}> funcName(...) --> funcNameA, funcNameB, funcNameC
string instantiatedName =
(templateArgValue_) ? funcName + templateArgValue_->pyxClassName() : funcName;
size_t N = nrOverloads();
// It's easy if there's no overload
if (N == 1) {
emit_cython_pyx_no_overload(file, cls);
return;
}
// Dealing with overloads..
2016-11-30 18:56:07 +08:00
file.oss << " def " << instantiatedName << "(self, *args, **kwargs):\n";
for (size_t i = 0; i < N; ++i) {
2016-11-30 18:56:07 +08:00
file.oss << " success, results = self." << instantiatedName << "_" << i
<< "(*args, **kwargs)\n";
2016-11-30 18:56:07 +08:00
file.oss << " if success:\n return results\n";
}
2016-11-30 18:56:07 +08:00
file.oss << " raise TypeError('Could not find the correct overload')\n";
for (size_t i = 0; i < N; ++i) {
ArgumentList args = argumentList(i);
2016-11-30 18:56:07 +08:00
file.oss << " def " + instantiatedName + "_" + to_string(i) +
"(self, *args, **kwargs):\n";
2016-11-22 06:14:30 +08:00
file.oss << pyx_resolveOverloadParams(args, false); // lazy: always return None even if it's a void function
/// Call cython corresponding function
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
file.oss << argumentList(i).pyx_convertEigenTypeAndStorageOrder(" ");
string caller = "self." + cls.shared_pxd_obj_in_pyx() + ".get()";
string ret = pyx_functionCall(caller, funcName, i);
2016-11-22 06:14:30 +08:00
if (!returnVals_[i].isVoid()) {
2016-11-30 18:56:07 +08:00
file.oss << " cdef " << returnVals_[i].pyx_returnType()
<< " ret = " << ret << "\n";
2016-11-30 18:56:07 +08:00
file.oss << " return True, " << returnVals_[i].pyx_casting("ret") << "\n";
} else {
2016-11-30 18:56:07 +08:00
file.oss << " " << ret << "\n";
file.oss << " return True, None\n";
}
}
}
/* ************************************************************************* */