Commit Graph

50 Commits (e72b42b61479df736b0469f4eee0aeef2378a6d5)

Author SHA1 Message Date
Duy-Nguyen Ta 1cdc228d6a remove trailing spaces 2019-02-11 10:58:34 -05:00
dellaert 74a33ff222 Re-structured argument overloading to call a common function 2017-08-06 11:07:13 -07:00
Duy-Nguyen Ta 6bf7ea23cf 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-15 13:47:11 -04:00
Duy-Nguyen Ta f154be176f Major update to generate proper Cython pxd header files which could be included in other projects/modules
All cdef (class, functions, variables) declarations are moved to pxd. Implementations of those cdefs and normal Python def are in pyx.
See: http://cython.readthedocs.io/en/latest/src/userguide/sharing_declarations.html#sharing-extension-types
2016-12-16 00:23:45 -05:00
Duy-Nguyen Ta 74f80fea4f [refactor] more understandable function names
Clearing confusions between pxd and pyx classes and objects!
2016-11-22 12:13:33 -05:00
Duy-Nguyen Ta fbcb9041f2 big refactoring, support method/static method overloading 2016-11-20 09:24:43 -05:00
Duy-Nguyen Ta acf3c9d259 proper overloading constructors 2016-11-16 17:51:03 -05:00
Duy-Nguyen Ta 709417b36d remove unused 2016-11-14 00:00:35 -05:00
Duy-Nguyen Ta 2433cbd8e8 Remove copy constructor assumption. Manually add copy constructors. Remove dependency on default constructor (some like Optimizers and Marginals don't have the default constructor). Remove cyCreateFromValue. Ignore variable name when checking overload similarity. 2016-09-13 17:11:23 -04:00
Duy-Nguyen Ta 1b04c6713b handle "This". Wrap all geometry 2016-09-11 18:14:19 -04:00
Duy-Nguyen Ta 10f510119a pyx class methods with arguments/return type casting 2016-09-09 18:37:48 -04:00
Duy-Nguyen Ta 1e84da1cfa pyx: add constructors and fixing inheritance 2016-09-09 15:52:44 -04:00
Duy-Nguyen Ta ecde851d8c [inprogress] cython wrapper 2016-09-08 13:33:32 -04:00
dellaert f00f62d89f Much better way of handling local variables in grammar 2014-12-02 11:24:53 +01:00
dellaert e963512164 Tightened up individual Grammars 2014-12-01 20:03:26 +01:00
dellaert 7dbe9389cb Fixed ArgumentListGrammar 2014-12-01 10:38:24 +01:00
dellaert 58806b75d2 testReturnValue with prototype grammar 2014-11-30 22:33:30 +01:00
dellaert 24f5636d6a Moved to header 2014-11-30 20:25:26 +01:00
dellaert b50f42a606 Equality 2014-11-30 16:08:56 +01:00
dellaert 8d9e108acc Check Vector by checking size 2014-11-29 21:43:48 +01:00
dellaert 370f2c6763 Isolated argument check 2014-11-29 21:11:13 +01:00
dellaert 0eaabd700b Refactored emit call 2014-11-29 20:53:38 +01:00
dellaert 7a4748d3dc Simplified method/function hierarchy drastically, and renamed bottom addOverload to initializeOrCheck to reflect what it does. Also, gratuitous re-ordering of addOverload arguments. 2014-11-14 16:44:08 +01:00
dellaert e07da1c82d Added matlabName, and made data members private 2014-11-13 22:43:29 +01:00
dellaert efd544527f Stream operator for many classes 2014-11-13 21:11:29 +01:00
dellaert b451e97f6f New TemplateSubstitution object simplifies a lot 2014-11-13 17:28:05 +01:00
dellaert a5e0adb7e6 Made methods and global functions derive from Function 2014-11-13 12:52:41 +01:00
dellaert 1ea0225030 Big refactor because methods now private member of Class 2014-11-12 23:23:07 +01:00
dellaert 7d4f5a4820 Make explicit whether wrapper or proxy is written to... 2014-11-12 20:51:47 +01:00
dellaert 77935bd631 Massive edit: new Qualified type groups namespaces with name, eliminates a lot of clutter. 2014-11-12 02:49:23 +01:00
dellaert 5987f78be3 Methods to check whether arguments are scalar 2014-05-25 15:21:13 -04:00
dellaert 9d9614d185 Split up into two calls 2014-05-25 14:59:20 -04:00
dellaert 406419317f eliminated more copy/paste mess between Method and StaticMethod 2014-05-25 14:35:07 -04:00
dellaert 1002696f83 Formatting and headers 2014-05-25 13:29:06 -04:00
dellaert 80b7d91264 emit prototype method (to eliminate horrible copy/paste mess someone thought was good programming style) 2014-05-25 13:01:36 -04:00
Chris Beall 4297d24c96 changed tabs to spaces for consistent indentation in all of GTSAM 2012-10-02 14:40:07 +00:00
Richard Roberts ce12f3d255 Code cleanup and comments 2012-07-12 22:28:28 +00:00
Andrew Melim 6d776812d3 new wrap! :) 2012-06-26 18:52:27 +00:00
Frank Dellaert a1aba7d6ff Fixed argument parse error. Somehow it could parse either refs or ptrs, but noth both, and it depended on the order in which the rules were given in the argList_p. I just combined ptr and ref in one and now it works. Go figure. 2012-01-28 19:44:33 +00:00
Alex Cunningham 66a9d635b3 Unified file writing to use a custom class to allow for smart checking 2012-01-15 21:42:41 +00:00
Frank Dellaert 0c03fd010d Constructors now check argument types to allow multiple constructors in MATLAB with the same number of arguments 2012-01-10 05:06:46 +00:00
Alex Cunningham 6a0da1519a Cleanup in wrap 2011-12-11 21:09:07 +00:00
Alex Cunningham 66711e1faa Added namespace support to arguments 2011-12-08 20:51:15 +00:00
Alex Cunningham 3050dc2dde Added wrap components to "wrap" namespace, added options for installing wrap program 2011-12-02 16:43:15 +00:00
Frank Dellaert 5fd71a33eb Documentation 2011-10-14 04:43:06 +00:00
Frank Dellaert 56d1d6ae34 Fixed some Doxygen problems with global replace 2011-10-14 03:23:14 +00:00
Alex Cunningham f4d9ca72a8 Added back the matlab interface to gtsam 2011-10-13 18:41:56 +00:00
Richard Roberts 08beb34060 Moved doc and wrap to experimental 2010-10-25 21:16:20 +00:00
Kai Ni 24d499039f prepend license information on all the codes 2010-10-14 04:54:38 +00:00
Richard Roberts d80fa24a9f Fixing directory structure 2009-08-21 22:23:24 +00:00