This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "roboptim-core".
The branch, master has been updated
via e487dc074102f28f3209cacb12b40ef8d5633981 (commit)
from a9e3d16f4c0d3dfa2f6c9e65825f0d0c449893a9 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e487dc074102f28f3209cacb12b40ef8d5633981
Author: Thomas Moulard <[email protected]>
Date: Mon Mar 1 16:10:58 2010 +0100
Implement function caching.
* include/Makefile.am: Distribute new header and source.
* include/roboptim/core/cached-function.hh: New.
* include/roboptim/core/cached-function.hxx: New.
* tests/Makefile.am: Compile new test case.
* tests/cached-function.cc: New.
* tests/cached-function.stdout: New.
* tests/testsuite.at: Add new test case.
Signed-off-by: Thomas Moulard <[email protected]>
diff --git a/ChangeLog b/ChangeLog
index ddc5f38..b57ca11 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-03-01 Thomas Moulard <[email protected]>
+
+ Implement function caching.
+ * include/Makefile.am: Distribute new header and source.
+ * include/roboptim/core/cached-function.hh: New.
+ * include/roboptim/core/cached-function.hxx: New.
+ * tests/Makefile.am: Compile new test case.
+ * tests/cached-function.cc: New.
+ * tests/cached-function.stdout: New.
+ * tests/testsuite.at: Add new test case.
+
2010-02-26 Thomas Moulard <[email protected]>
Fix parameter code.
diff --git a/include/Makefile.am b/include/Makefile.am
index c78b902..d6b0b98 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,6 +2,8 @@ include $(top_srcdir)/build-aux/init.mk
# --- Distribute and install headers.
nobase_include_HEADERS = \
+ roboptim/core/cached-function.hh \
+ roboptim/core/cached-function.hxx \
roboptim/core/constant-function.hh \
roboptim/core/debug.hh \
roboptim/core/derivable-function.hh \
diff --git a/include/roboptim/core/cached-function.hh
b/include/roboptim/core/cached-function.hh
new file mode 100644
index 0000000..e37f17c
--- /dev/null
+++ b/include/roboptim/core/cached-function.hh
@@ -0,0 +1,115 @@
+// Copyright (C) 2010 by Thomas Moulard, AIST, CNRS, INRIA.
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef ROBOPTIM_CORE_CACHED_FUNCTION_HH
+# define ROBOPTIM_CORE_CACHED_FUNCTION_HH
+# include <roboptim/core/sys.hh>
+# include <roboptim/core/debug.hh>
+
+# include <map>
+
+# include <roboptim/core/n-times-derivable-function.hh>
+
+
+#include <roboptim/core/io.hh>
+
+namespace roboptim
+{
+ /// \addtogroup roboptim_meta_function
+ /// @{
+
+ struct ltvector
+ {
+ bool operator()(const Function::vector_t& v1,
+ const Function::vector_t& v2) const
+ {
+ Function::vector_t::const_iterator it1 = v1.begin ();
+ Function::vector_t::const_iterator it2 = v2.begin ();
+
+ while (it1 != v1.end () && it2 != v2.end ())
+ {
+ if (*it1 < *it2)
+ return true;
+ ++it1, ++it2;
+ }
+ return it1 != v1.end () && it2 == v2.end ();
+ }
+ };
+
+ template <typename T>
+ class ROBOPTIM_DLLAPI CachedFunction : public T
+ {
+ public:
+ /// \brief Import value type.
+ typedef typename DerivableFunction::value_type value_type;
+ /// \brief Import size type.
+ typedef typename DerivableFunction::size_type size_type;
+ /// \brief Import vector type.
+ typedef typename DerivableFunction::vector_t vector_t;
+ /// \brief Import result type.
+ typedef typename DerivableFunction::result_t result_t;
+ /// \brief Import argument type.
+ typedef typename DerivableFunction::argument_t argument_t;
+ /// \brief Import gradient type.
+ typedef typename DerivableFunction::gradient_t gradient_t;
+ /// \brief Import hessian type.
+ typedef typename TwiceDerivableFunction::hessian_t hessian_t;
+ /// \brief Import jacobian type.
+ typedef typename DerivableFunction::jacobian_t jacobian_t;
+ /// \brief Import interval type.
+ typedef typename DerivableFunction::interval_t interval_t;
+
+
+ typedef std::map<Function::vector_t, Function::vector_t, ltvector>
+ functionCache_t;
+
+ explicit CachedFunction (const T& fct) throw ();
+ ~CachedFunction () throw ();
+
+ void reset () throw ();
+
+ protected:
+ virtual void impl_compute (result_t& result, const argument_t& argument)
+ const throw ();
+
+
+ virtual void impl_gradient (gradient_t& gradient,
+ const argument_t& argument,
+ size_type functionId = 0)
+ const throw ();
+
+ virtual void impl_hessian (hessian_t& hessian,
+ const argument_t& argument,
+ size_type functionId = 0) const throw ();
+
+ virtual void impl_derivative (gradient_t& derivative,
+ double argument,
+ size_type order = 1) const throw ();
+
+ private:
+ const T& function_;
+ mutable std::vector<functionCache_t> cache_;
+ mutable std::vector<functionCache_t> gradientCache_;
+ mutable std::vector<functionCache_t> hessianCache_;
+ };
+
+ /// @}
+
+} // end of namespace roboptim
+
+# include <roboptim/core/cached-function.hxx>
+#endif //! ROBOPTIM_CORE_CACHED_FUNCTION_HH
diff --git a/include/roboptim/core/cached-function.hxx
b/include/roboptim/core/cached-function.hxx
new file mode 100644
index 0000000..c5f8c0c
--- /dev/null
+++ b/include/roboptim/core/cached-function.hxx
@@ -0,0 +1,221 @@
+// Copyright (C) 2010 by Thomas Moulard, AIST, CNRS, INRIA.
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef ROBOPTIM_CORE_CACHED_FUNCTION_HXX
+# define ROBOPTIM_CORE_CACHED_FUNCTION_HXX
+# include <boost/format.hpp>
+
+namespace roboptim
+{
+ namespace
+ {
+ template <typename T>
+ std::string cachedFunctionName (const T& fct);
+
+ template <typename T>
+ std::string cachedFunctionName (const T& fct)
+ {
+ boost::format fmt ("%1% (cached)");
+ fmt % fct.getName ();
+ return fmt.str ();
+ }
+
+ template <typename T>
+ struct derivativeSize;
+
+ template <>
+ struct derivativeSize<Function>
+ {
+ static const unsigned int value = 0;
+ };
+
+ template <>
+ struct derivativeSize<DerivableFunction>
+ {
+ static const unsigned int value = 1;
+ };
+
+ template <>
+ struct derivativeSize<TwiceDerivableFunction>
+ {
+ static const unsigned int value = 2;
+ };
+
+ template <unsigned N>
+ struct derivativeSize<NTimesDerivableFunction<N> >
+ {
+ static const unsigned int value = 3;
+ };
+
+ } // end of anonymous namespace.
+
+ template <typename T>
+ CachedFunction<T>::CachedFunction (const T& fct) throw ()
+ : T (fct.inputSize (), fct.outputSize (), cachedFunctionName (fct)),
+ function_ (fct),
+ cache_ (derivativeSize<T>::value),
+ gradientCache_ (fct.outputSize ()),
+ hessianCache_ (fct.outputSize ())
+ {
+ }
+
+ template <typename T>
+ CachedFunction<T>::~CachedFunction () throw ()
+ {
+ }
+
+ template <typename T>
+ void
+ CachedFunction<T>::reset () throw ()
+ {
+ cache_.clear ();
+ gradientCache_.clear ();
+ hessianCache_.clear ();
+ }
+
+
+ template <typename T>
+ void
+ CachedFunction<T>::impl_compute (result_t& result,
+ const argument_t& argument)
+ const throw ()
+ {
+ functionCache_t::const_iterator it = cache_[0].find (argument);
+ if (it != cache_[0].end ())
+ {
+ std::cout << "cached" << std::endl;
+ result = it->second;
+ return;
+ }
+ std::cout << "not cached" << std::endl;
+ function_ (result, argument);
+ cache_[0][argument] = result;
+ }
+
+
+ template <>
+ void
+ CachedFunction<Function>::impl_gradient (gradient_t&, const argument_t&,
size_type)
+ const throw ()
+ {
+ assert (0);
+ }
+
+ template <typename T>
+ void
+ CachedFunction<T>::impl_gradient (gradient_t& gradient,
+ const argument_t& argument,
+ size_type functionId)
+ const throw ()
+ {
+ functionCache_t::const_iterator it =
+ gradientCache_[functionId].find (argument);
+ if (it != gradientCache_[functionId].end ())
+ {
+ gradient = it->second;
+ return;
+ }
+ function_.gradient (gradient, argument, functionId);
+ gradientCache_[functionId][argument] = gradient;
+ }
+
+
+
+
+ template <>
+ void
+ CachedFunction<Function>::impl_hessian
+ (hessian_t&, const argument_t&, size_type) const throw ()
+ {
+ assert (0);
+ }
+
+ template <>
+ void
+ CachedFunction<DerivableFunction>::impl_hessian
+ (hessian_t&, const argument_t&, size_type) const throw ()
+ {
+ assert (0);
+ }
+
+
+
+ template <typename T>
+ void
+ CachedFunction<T>::impl_hessian (hessian_t& hessian,
+ const argument_t& argument,
+ size_type functionId)
+ const throw ()
+ {
+ functionCache_t::const_iterator it =
+ hessianCache_[functionId].find (argument);
+ if (it != hessianCache_[functionId].end ())
+ {
+ hessian = it->second;
+ return;
+ }
+ function_.hessian (hessian, argument, functionId);
+ hessianCache_[functionId][argument] = hessian;
+ }
+
+
+ template <>
+ void
+ CachedFunction<Function>::impl_derivative
+ (gradient_t&, double, size_type) const throw ()
+ {
+ assert (0);
+ }
+
+ template <>
+ void
+ CachedFunction<DerivableFunction>::impl_derivative
+ (gradient_t&, double, size_type) const throw ()
+ {
+ assert (0);
+ }
+
+ template <>
+ void
+ CachedFunction<TwiceDerivableFunction>::impl_derivative
+ (gradient_t&, double, size_type) const throw ()
+ {
+ assert (0);
+ }
+
+ template <typename T>
+ void
+ CachedFunction<T>::impl_derivative (gradient_t& derivative,
+ double argument,
+ size_type order)
+ const throw ()
+ {
+ vector_t x (1);
+ x[0] = argument;
+ functionCache_t::const_iterator it = cache_[order].find (x);
+ if (it != cache_[order].end ())
+ {
+ derivative = it->second;
+ return;
+ }
+ function_.derivative (derivative, x, order);
+ cache_[order][x] = derivative;
+ }
+
+} // end of namespace roboptim
+
+#endif //! ROBOPTIM_CORE_CACHED_FUNCTION_HXX
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2f14961..96a6157 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -97,6 +97,11 @@ derivable_parametrized_function_SOURCES =
derivable-parametrized-function.cc \
$(COMMON_SOURCES)
derivable_parametrized_function_LDADD = $(top_builddir)/src/libroboptim-core.la
+# cached-function
+check_PROGRAMS += cached-function
+cached_function_SOURCES = cached-function.cc $(COMMON_SOURCES)
+cached_function_LDADD = $(top_builddir)/src/libroboptim-core.la
+
# plugin
check_PROGRAMS += plugin
plugin_SOURCES = plugin.cc $(COMMON_SOURCES)
@@ -153,6 +158,7 @@ generate-reference:
# Distribute reference files.
EXTRA_DIST += \
+ cached-function.stdout \
constant-function.stdout \
derivable-function.stdout \
finite-difference-gradient.stdout \
diff --git a/tests/cached-function.cc b/tests/cached-function.cc
new file mode 100644
index 0000000..c984487
--- /dev/null
+++ b/tests/cached-function.cc
@@ -0,0 +1,71 @@
+// Copyright (C) 2009 by Thomas Moulard, AIST, CNRS, INRIA.
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#include "common.hh"
+
+#include <iostream>
+
+#include <roboptim/core/cached-function.hh>
+#include <roboptim/core/io.hh>
+#include <roboptim/core/derivable-function.hh>
+#include <roboptim/core/util.hh>
+
+using namespace roboptim;
+
+struct F : public DerivableFunction
+{
+ F () : DerivableFunction (1, 1, "2 * x")
+ {}
+
+ void impl_compute (result_t& res, const argument_t& argument) const throw ()
+ {
+ res.clear ();
+ res[0] = 2. * argument[0];
+ }
+
+ void impl_gradient (gradient_t& grad, const argument_t& argument,
+ size_type) const throw ()
+ {
+ grad.clear ();
+ grad[0] = 2.;
+ }
+};
+
+int run_test ()
+{
+ F f;
+
+ CachedFunction<DerivableFunction> cachedF (f);
+
+ std::cout << cachedF << ":" << std::endl
+ << std::endl;
+
+ Function::vector_t x (1);
+ for (double i = 0.; i < 10.; i += 0.5)
+ {
+ x[0] = i;
+ std::cout << cachedF (x) << std::endl;
+ std::cout << cachedF (x) << std::endl;
+ assert (f (x)[0] == cachedF (x)[0]);
+
+ std::cout << cachedF.gradient (x) << std::endl;
+ std::cout << cachedF.gradient (x) << std::endl;
+ }
+ return 0;
+}
+
+GENERATE_TEST ()
diff --git a/tests/cached-function.stdout b/tests/cached-function.stdout
new file mode 100644
index 0000000..9b20194
--- /dev/null
+++ b/tests/cached-function.stdout
@@ -0,0 +1,142 @@
+2 * x (cached) (derivable function):
+
+not cached
+[1](0)
+cached
+[1](0)
+cached
+[1](2)
+[1](2)
+not cached
+[1](1)
+cached
+[1](1)
+cached
+[1](2)
+[1](2)
+not cached
+[1](2)
+cached
+[1](2)
+cached
+[1](2)
+[1](2)
+not cached
+[1](3)
+cached
+[1](3)
+cached
+[1](2)
+[1](2)
+not cached
+[1](4)
+cached
+[1](4)
+cached
+[1](2)
+[1](2)
+not cached
+[1](5)
+cached
+[1](5)
+cached
+[1](2)
+[1](2)
+not cached
+[1](6)
+cached
+[1](6)
+cached
+[1](2)
+[1](2)
+not cached
+[1](7)
+cached
+[1](7)
+cached
+[1](2)
+[1](2)
+not cached
+[1](8)
+cached
+[1](8)
+cached
+[1](2)
+[1](2)
+not cached
+[1](9)
+cached
+[1](9)
+cached
+[1](2)
+[1](2)
+not cached
+[1](10)
+cached
+[1](10)
+cached
+[1](2)
+[1](2)
+not cached
+[1](11)
+cached
+[1](11)
+cached
+[1](2)
+[1](2)
+not cached
+[1](12)
+cached
+[1](12)
+cached
+[1](2)
+[1](2)
+not cached
+[1](13)
+cached
+[1](13)
+cached
+[1](2)
+[1](2)
+not cached
+[1](14)
+cached
+[1](14)
+cached
+[1](2)
+[1](2)
+not cached
+[1](15)
+cached
+[1](15)
+cached
+[1](2)
+[1](2)
+not cached
+[1](16)
+cached
+[1](16)
+cached
+[1](2)
+[1](2)
+not cached
+[1](17)
+cached
+[1](17)
+cached
+[1](2)
+[1](2)
+not cached
+[1](18)
+cached
+[1](18)
+cached
+[1](2)
+[1](2)
+not cached
+[1](19)
+cached
+[1](19)
+cached
+[1](2)
+[1](2)
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 69413b3..7acb59c 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -47,6 +47,7 @@ CHECK_STDOUT([constant-function], [Check constant function
class.])
CHECK_STDOUT([parametrized-function], [Check parametrized function class.])
CHECK_STDOUT([derivable-parametrized-function],
[Check derivable parametrized function class.])
+CHECK_STDOUT([cached-function], [Check cached-function class.])
AT_BANNER([Problems])
CHECK_STDOUT([problem-cc], [Check problem copy constructor.])
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 11 +
include/Makefile.am | 2 +
include/roboptim/core/cached-function.hh | 115 +++++++++++
include/roboptim/core/cached-function.hxx | 221 ++++++++++++++++++++++
tests/Makefile.am | 6 +
tests/{linear-function.cc => cached-function.cc} | 52 ++---
tests/cached-function.stdout | 142 ++++++++++++++
tests/testsuite.at | 1 +
8 files changed, 519 insertions(+), 31 deletions(-)
create mode 100644 include/roboptim/core/cached-function.hh
create mode 100644 include/roboptim/core/cached-function.hxx
copy tests/{linear-function.cc => cached-function.cc} (60%)
create mode 100644 tests/cached-function.stdout
hooks/post-receive
--
roboptim-core
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
roboptim-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/roboptim-commit