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&#174; 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

Reply via email to