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 <thomas.moul...@gmail.com> 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 <thomas.moul...@gmail.com> diff --git a/ChangeLog b/ChangeLog index ddc5f38..b57ca11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-03-01 Thomas Moulard <thomas.moul...@gmail.com> + + 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 <thomas.moul...@gmail.com> 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 roboptim-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/roboptim-commit