@@ -437,6 +437,44 @@ namespace roboptim
437437 }
438438
439439
440+ CachedFunction::CachedFunction (boost::shared_ptr<pyFunction_t> f, size_t cache_size)
441+ : function_t (f->inputSize (), f->outputSize (), f->getName ()),
442+ pyFunction_t (f->inputSize (), f->outputSize (), f->getName ()),
443+ cached_f_ (boost::make_shared<cache_t > (f, cache_size))
444+ {
445+ }
446+
447+ CachedFunction::~CachedFunction ()
448+ {
449+ }
450+
451+ void CachedFunction::impl_compute (result_ref result,
452+ const_argument_ref argument)
453+ const
454+ {
455+ (*cached_f_) (result, argument);
456+ }
457+
458+ void CachedFunction::impl_gradient (gradient_ref gradient,
459+ const_argument_ref argument,
460+ size_type functionId)
461+ const
462+ {
463+ cached_f_->gradient (gradient, argument, functionId);
464+ }
465+
466+ void CachedFunction::impl_jacobian (jacobian_ref jacobian,
467+ const_argument_ref argument)
468+ const
469+ {
470+ cached_f_->jacobian (jacobian, argument);
471+ }
472+
473+ std::ostream& CachedFunction::print (std::ostream& o) const
474+ {
475+ return cached_f_->print (o);
476+ }
477+
440478 FunctionPool::~FunctionPool ()
441479 {
442480 }
@@ -472,6 +510,7 @@ using roboptim::core::python::DifferentiableFunction;
472510using roboptim::core::python::TwiceDifferentiableFunction;
473511using roboptim::core::python::FiniteDifferenceGradient;
474512using roboptim::core::python::FunctionPool;
513+ using roboptim::core::python::CachedFunction;
475514
476515namespace detail
477516{
@@ -1038,6 +1077,50 @@ createFDWrapper (PyObject*, PyObject* args)
10381077 return fdFunctionPy;
10391078}
10401079
1080+ static PyObject*
1081+ createCachedFunction (PyObject*, PyObject* args)
1082+ {
1083+ typedef CachedFunction cachedDifferentiableFunction_t;
1084+
1085+ Function* function = 0 ;
1086+ size_t cache_size = 10 ;
1087+
1088+ if (!PyArg_ParseTuple (args, " O&|i" , &detail::functionConverter, &function, &cache_size))
1089+ return 0 ;
1090+
1091+ if (!function)
1092+ {
1093+ PyErr_SetString
1094+ (PyExc_TypeError,
1095+ " Failed to retrieve function object" );
1096+ return 0 ;
1097+ }
1098+
1099+ PyObject* cachedFunctionPy = 0 ;
1100+
1101+ DifferentiableFunction* dfunction =
1102+ dynamic_cast <DifferentiableFunction*> (function);
1103+ if (!dfunction)
1104+ {
1105+ PyErr_SetString
1106+ (PyExc_TypeError,
1107+ " Failed to retrieve differentiable function object" );
1108+ return 0 ;
1109+ }
1110+
1111+ boost::shared_ptr<DifferentiableFunction> dfunction_ptr
1112+ = detail::to_shared_ptr<DifferentiableFunction> (dfunction, PyTuple_GetItem (args, 0 ));
1113+ assert (dfunction_ptr);
1114+
1115+ cachedDifferentiableFunction_t* cachedFunction
1116+ = new cachedDifferentiableFunction_t (dfunction_ptr, cache_size);
1117+
1118+ cachedFunctionPy = PyCapsule_New (cachedFunction, ROBOPTIM_CORE_FUNCTION_CAPSULE_NAME ,
1119+ &detail::destructor<cachedDifferentiableFunction_t>);
1120+
1121+ return cachedFunctionPy;
1122+ }
1123+
10411124static PyObject*
10421125inputSize (PyObject*, PyObject* args)
10431126{
@@ -2872,7 +2955,11 @@ static PyMethodDef RobOptimCoreMethods[] =
28722955 METH_VARARGS , " Create a FiniteDifferenceGradient with forward difference." },
28732956 {" FivePointsFiniteDifferenceGradient" ,
28742957 createFDWrapper<FiniteDifferenceGradient<fivePointsPolicy_t> >,
2875- METH_VARARGS , " Create a FiniteDifferenceGradient with the 5-points rule." },
2958+ METH_VARARGS , " Create a FiniteDifferenceGradient with the 5-point rule." },
2959+
2960+ // Filters
2961+ {" CachedFunction" , createCachedFunction, METH_VARARGS ,
2962+ " Create a cached function." },
28762963
28772964 // Print functions
28782965 {" strFunction" , print<Function>, METH_VARARGS ,
0 commit comments