diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1b65f722..bafaab2ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,6 +28,7 @@ SET(PROJECT_URL "http://github.com/roboptim/roboptim-core")
SET(HEADERS
${CMAKE_SOURCE_DIR}/include/roboptim/core.hh
+ ${CMAKE_SOURCE_DIR}/include/roboptim/core/alloc.hh
${CMAKE_SOURCE_DIR}/include/roboptim/core/cache.hh
${CMAKE_SOURCE_DIR}/include/roboptim/core/cache.hxx
${CMAKE_SOURCE_DIR}/include/roboptim/core/callback/multiplexer.hh
diff --git a/include/roboptim/core/alloc.hh b/include/roboptim/core/alloc.hh
new file mode 100644
index 000000000..d12a024b3
--- /dev/null
+++ b/include/roboptim/core/alloc.hh
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 by Félix Darricau, AIST, CNRS, EPITA
+//
+// This file is part of the roboptim.
+//
+// roboptim is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// roboptim is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with roboptim. If not, see .
+
+#ifndef ROBOPTIM_CORE_ALLOC_HH
+# define ROBOPTIM_CORE_ALLOC_HH
+
+# include
+
+# define EIGEN_RUNTIME_NO_MALLOC
+# include
+
+namespace roboptim
+{
+ ROBOPTIM_LOCAL
+ bool is_malloc_allowed_update(bool update, bool new_value);
+
+ ROBOPTIM_DLLAPI
+ bool set_is_malloc_allowed (bool allow);
+}
+
+#endif //! ROBOPTIM_CORE_ALLOC_HH
diff --git a/include/roboptim/core/decorator/finite-difference-gradient.hxx b/include/roboptim/core/decorator/finite-difference-gradient.hxx
index 2135ec4d5..efc4d34f7 100644
--- a/include/roboptim/core/decorator/finite-difference-gradient.hxx
+++ b/include/roboptim/core/decorator/finite-difference-gradient.hxx
@@ -403,7 +403,7 @@ namespace roboptim
argument_ref xEps) const
{
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
typedef Eigen::Triplet triplet_t;
@@ -431,6 +431,10 @@ namespace roboptim
}
}
jacobian.setFromTriplets (coefficients.begin (), coefficients.end ());
+
+#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+ set_is_malloc_allowed (false);
+#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
}
template
@@ -668,7 +672,7 @@ namespace roboptim
argument_ref xEps) const
{
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
typedef Eigen::Triplet triplet_t;
diff --git a/include/roboptim/core/differentiable-function.hh b/include/roboptim/core/differentiable-function.hh
index a7f99e28d..e7eac7dfd 100644
--- a/include/roboptim/core/differentiable-function.hh
+++ b/include/roboptim/core/differentiable-function.hh
@@ -150,11 +150,11 @@ namespace roboptim
assert (argument.size () == this->inputSize ());
assert (isValidJacobian (jacobian));
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
this->impl_jacobian (jacobian, argument);
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
assert (isValidJacobian (jacobian));
}
@@ -194,11 +194,11 @@ namespace roboptim
assert (argument.size () == this->inputSize ());
assert (isValidGradient (gradient));
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
this->impl_gradient (gradient, argument, functionId);
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
assert (isValidGradient (gradient));
}
diff --git a/include/roboptim/core/differentiable-function.hxx b/include/roboptim/core/differentiable-function.hxx
index 59de80667..133800eac 100644
--- a/include/roboptim/core/differentiable-function.hxx
+++ b/include/roboptim/core/differentiable-function.hxx
@@ -37,12 +37,9 @@ namespace roboptim
(jacobian_ref jacobian, const_argument_ref argument)
const
{
-#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
-#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
-
typedef Eigen::Triplet triplet_t;
std::vector coefficients;
+
for (jacobian_t::Index i = 0; i < this->outputSize (); ++i)
{
gradient_t grad = gradient (argument, i);
diff --git a/include/roboptim/core/function.hh b/include/roboptim/core/function.hh
index ab3929d12..7e2995f8b 100644
--- a/include/roboptim/core/function.hh
+++ b/include/roboptim/core/function.hh
@@ -33,7 +33,8 @@
# include
# define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
-# define EIGEN_RUNTIME_NO_MALLOC
+
+# include
# include
# include
# include
@@ -476,11 +477,11 @@ namespace roboptim
assert (argument.size () == inputSize ());
assert (isValidResult (result));
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
this->impl_compute (result, argument);
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
assert (isValidResult (result));
}
diff --git a/include/roboptim/core/n-times-derivable-function.hh b/include/roboptim/core/n-times-derivable-function.hh
index 384cf1e41..ae495d84c 100644
--- a/include/roboptim/core/n-times-derivable-function.hh
+++ b/include/roboptim/core/n-times-derivable-function.hh
@@ -213,10 +213,15 @@ namespace roboptim
size_type functionId = 0) const
{
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
derivative_t derivative (derivativeSize ());
+
+#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+ set_is_malloc_allowed (false);
+#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+
derivative.setZero ();
this->derivative (derivative, argument[0], 1);
@@ -250,12 +255,17 @@ namespace roboptim
size_type functionId = 0) const
{
# ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
# endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
assert (functionId == 0);
derivative_t derivative (derivativeSize ());
+
+#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+ set_is_malloc_allowed (false);
+#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+
derivative.setZero ();
this->derivative (derivative, argument[0], 2);
diff --git a/include/roboptim/core/numeric-quadratic-function.hxx b/include/roboptim/core/numeric-quadratic-function.hxx
index 49d2e607e..7ad8d2e21 100644
--- a/include/roboptim/core/numeric-quadratic-function.hxx
+++ b/include/roboptim/core/numeric-quadratic-function.hxx
@@ -77,10 +77,15 @@ namespace roboptim
(jacobian_ref jacobian, const_argument_ref x) const
{
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
Eigen::MatrixXd j = 2 * x.transpose () * a_;
+
+#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+ set_is_malloc_allowed (false);
+#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
+
for (size_type i = 0; i < this->inputSize (); ++i)
j.coeffRef (0, i) += b_[i];
diff --git a/include/roboptim/core/sum-of-c1-squares.hxx b/include/roboptim/core/sum-of-c1-squares.hxx
index 882aafe31..fe35c934e 100644
--- a/include/roboptim/core/sum-of-c1-squares.hxx
+++ b/include/roboptim/core/sum-of-c1-squares.hxx
@@ -62,13 +62,9 @@ namespace roboptim {
void GenericSumOfC1Squares::
impl_compute(result_ref result, const_argument_ref x) const
{
-#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
-#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
-
computeFunction (x);
value_type sumSquares = 0;
- for (size_t i = 0; i < value_.size(); i++) {
+ for (typename result_t::Index i = 0; i < value_.size(); i++) {
value_type y = value_[i];
sumSquares += y*y;
}
@@ -80,10 +76,6 @@ namespace roboptim {
impl_gradient(gradient_ref gradient, const_argument_ref x,
size_type ROBOPTIM_DEBUG_ONLY (row)) const
{
-#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
-#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
-
assert (row == 0);
computeFunction (x);
gradient.setZero ();
diff --git a/include/roboptim/core/twice-differentiable-function.hh b/include/roboptim/core/twice-differentiable-function.hh
index 73df35ccf..d0cdfa0ee 100644
--- a/include/roboptim/core/twice-differentiable-function.hh
+++ b/include/roboptim/core/twice-differentiable-function.hh
@@ -126,11 +126,11 @@ namespace roboptim
"Evaluating hessian at point: " << argument);
assert (isValidHessian (hessian));
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
this->impl_hessian (hessian, argument, functionId);
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
assert (isValidHessian (hessian));
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4f0fb575d..508f1d043 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -24,6 +24,7 @@ ADD_LIBRARY(roboptim-core SHARED
${HEADERS}
debug.hh
doc.hh
+ alloc.cc
finite-difference-gradient.cc
generic-solver.cc
indent.cc
diff --git a/src/alloc.cc b/src/alloc.cc
new file mode 100644
index 000000000..ccaa23eed
--- /dev/null
+++ b/src/alloc.cc
@@ -0,0 +1,37 @@
+// Copyright (C) 2015 by Félix Darricau, AIST, CNRS, EPITA
+//
+// This file is part of the roboptim.
+//
+// roboptim is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// roboptim is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with roboptim. If not, see .
+
+#include "roboptim/core/alloc.hh"
+
+namespace roboptim
+{
+ bool is_malloc_allowed_update(bool update = false, bool new_value = false)
+ {
+ static bool value = true;
+ if (update)
+ value = new_value;
+ return value;
+ }
+
+ /// \brief Manage the calls to Eigen::set_is_malloc_allowed.
+ bool set_is_malloc_allowed (bool allow)
+ {
+ is_malloc_allowed_update(true, allow);
+
+ return Eigen::internal::set_is_malloc_allowed(allow);
+ }
+} // end of namespace roboptim.
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 53e6cabf0..bf89ce24c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -122,6 +122,9 @@ ROBOPTIM_CORE_TEST(function-identity)
ROBOPTIM_CORE_TEST(function-sin)
ROBOPTIM_CORE_TEST(function-polynomial)
+# Sum Of C1 Squares.
+ROBOPTIM_CORE_TEST(sum-of-c1-squares)
+
# Decorators.
ROBOPTIM_CORE_TEST(decorator-cached-function)
ROBOPTIM_CORE_TEST(decorator-finite-difference-gradient)
diff --git a/tests/detail-utility.cc b/tests/detail-utility.cc
index bada6758d..fdc26b326 100644
--- a/tests/detail-utility.cc
+++ b/tests/detail-utility.cc
@@ -58,9 +58,9 @@ namespace detail
matrix_t m (2, 2);
m << 1., 2., 3., 4.;
- internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
foo (m.row (1));
- internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
BOOST_CHECK (!m.row (0).isZero ());
BOOST_CHECK (m.row (1).isZero ());
diff --git a/tests/function-pool.cc b/tests/function-pool.cc
index 72b456479..17f50d8c6 100644
--- a/tests/function-pool.cc
+++ b/tests/function-pool.cc
@@ -306,7 +306,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE (function_pool, T, functionTypes_t)
"Joint position pool");
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
// Pre-allocate memory
@@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE (function_pool, T, functionTypes_t)
fd_denseJac (pool->outputSize (), pool->inputSize ());
#ifndef ROBOPTIM_DO_NOT_CHECK_ALLOCATION
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
#endif //! ROBOPTIM_DO_NOT_CHECK_ALLOCATION
// Call the pool
diff --git a/tests/ref.cc b/tests/ref.cc
index 90f631dd4..f02003ffa 100644
--- a/tests/ref.cc
+++ b/tests/ref.cc
@@ -88,9 +88,9 @@ BOOST_AUTO_TEST_CASE (ref)
F::jacobian_ref jac_ref (jac);
F::const_argument_ref x_ref (map_x);
- Eigen::internal::set_is_malloc_allowed (false);
+ set_is_malloc_allowed (false);
f.jacobian (jac_ref, x_ref);
- Eigen::internal::set_is_malloc_allowed (true);
+ set_is_malloc_allowed (true);
(*output) << map_x << std::endl;
(*output) << f << std::endl;
diff --git a/tests/sum-of-c1-squares.cc b/tests/sum-of-c1-squares.cc
new file mode 100644
index 000000000..65f24061a
--- /dev/null
+++ b/tests/sum-of-c1-squares.cc
@@ -0,0 +1,111 @@
+// Copyright (C) 2015 by Félix Darricau, AIST, CNRS, EPITA
+//
+// This file is part of the roboptim.
+//
+// roboptim is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// roboptim is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with roboptim. If not, see .
+
+#include "shared-tests/fixture.hh"
+
+#include
+
+#include
+#include
+
+using namespace roboptim;
+
+struct F : public DifferentiableFunction
+{
+ F () : DifferentiableFunction (4, 2,
+ "x₀ * x₃ * (x₀ + x₁ + x₂) + x₃, "
+ "x₀²")
+ {
+ }
+
+ void
+ impl_compute (result_ref result, const_argument_ref x) const
+ {
+ result (0) = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[3];
+ result (1) = x[0] * x[0];
+ }
+
+ void
+ impl_gradient (gradient_ref grad, const_argument_ref x,
+ size_type functionId) const
+ {
+ switch (functionId)
+ {
+ case 0:
+ {
+ grad[0] = x[0] * x[3] + x[3] * (x[0] + x[1] + x[2]);
+ grad[1] = x[0] * x[3];
+ grad[2] = x[0] * x[3] + 1;
+ grad[3] = x[0] * (x[0] + x[1] + x[2]);
+ }
+ break;
+
+ case 1:
+ {
+ grad[0] = 2. * x[0];
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE (core, TestSuiteConfiguration)
+
+BOOST_AUTO_TEST_CASE (sum_of_c1_squares)
+{
+ boost::shared_ptr
+ output = retrievePattern ("sum-of-c1-squares");
+
+ boost::shared_ptr fptr =
+ boost::make_shared();
+
+ SumOfC1Squares fSum(fptr, "null");
+
+ SumOfC1Squares::vector_t x (4);
+ x << 1., 2., 1., 2.;
+ SumOfC1Squares::gradient_t grad (fSum.gradientSize ());
+
+ (*output) << fSum << std::endl;
+
+ BOOST_CHECK (fSum.inputSize () == 4);
+
+ BOOST_CHECK (fSum.outputSize () == 1);
+
+ BOOST_CHECK (fSum.getName () == "null");
+
+ BOOST_CHECK (fSum.isValidResult (fSum (x)));
+
+ BOOST_CHECK (fSum(x)[0] == 101);
+
+ (*output) << fSum.gradient (x) << std::endl;
+
+ fSum.gradient (grad, x);
+ (*output) << grad << std::endl;
+
+ BOOST_CHECK (fSum.gradientSize () == 4);
+
+ BOOST_CHECK (fSum.isValidGradient (fSum.gradient (x)));
+
+
+ std::cout << output->str () << std::endl;
+ BOOST_CHECK (output->match_pattern ());
+}
+
+BOOST_AUTO_TEST_SUITE_END ()
diff --git a/tests/sum-of-c1-squares.stdout b/tests/sum-of-c1-squares.stdout
new file mode 100644
index 000000000..f9901685d
--- /dev/null
+++ b/tests/sum-of-c1-squares.stdout
@@ -0,0 +1,5 @@
+null (differentiable function)
+[4](204,40,60,80)
+[4](204,40,60,80)
+4
+1