aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorastrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675>2010-06-03 15:30:28 +0000
committerastrojhgu <astrojhgu@ed2142bd-67ad-457f-ba7c-d818d4011675>2010-06-03 15:30:28 +0000
commit492fc9d5677bad71986ff437c62f17a28d7b5996 (patch)
tree60de9622d28c37d9fac377e486b58bb6bee7d30a
parent55d6b3a31607ba104f58585f2135ed24eb528611 (diff)
downloadopt-utilities-492fc9d5677bad71986ff437c62f17a28d7b5996.tar.bz2
git-svn-id: file:///home/svn/opt_utilities@117 ed2142bd-67ad-457f-ba7c-d818d4011675
-rw-r--r--math/num_diff.hpp115
-rw-r--r--math/vector_operation.hpp18
2 files changed, 133 insertions, 0 deletions
diff --git a/math/num_diff.hpp b/math/num_diff.hpp
new file mode 100644
index 0000000..27a1674
--- /dev/null
+++ b/math/num_diff.hpp
@@ -0,0 +1,115 @@
+/**
+ \file num_diff.hpp
+ */
+
+
+#ifndef NUMDIFF_HPP
+#define NUMDIFF_HPP
+#define OPT_HEADER
+#include <core/optimizer.hpp>
+#include <core/opt_traits.hpp>
+#include <algorithm>
+#include <limits>
+#include <cmath>
+
+namespace opt_utilities
+{
+
+ /**
+ \brief differentiable function
+ \tparam rT the return type
+ \tparam the parameter type
+ */
+ template <typename rT,typename pT>
+ class dfunc_obj
+ :public func_obj<rT,pT>
+ {
+ private:
+ virtual pT do_diff(const pT& p)=0;
+
+ public:
+ /**
+ calculate the differentiation
+ \param p the self-var
+ \return the gradient at p
+ */
+ pT diff(const pT& p)
+ {
+ return do_diff(p);
+ }
+ };
+
+
+ /**
+ When trying to diff an object function, when it is not differentiable,
+ this exception will be thrown.
+ */
+ class underivable
+ :public opt_exception
+ {
+ public:
+ underivable()
+ :opt_exception("underivable")
+ {}
+ };
+
+ /**
+ calculate the numerical differential of a func_obj
+ */
+ template <typename rT,typename pT>
+ pT numdiff(func_obj<rT,pT>& f,const pT& p)
+ {
+ rT ep=std::sqrt(std::numeric_limits<rT>::epsilon());
+
+ pT result;
+ resize(result,get_size(p));
+ pT p2;
+ resize(p2,get_size(p));
+ pT p1;
+ resize(p1,get_size(p));
+
+ for(size_t i=0;i<get_size(p);++i)
+ {
+ set_element(p2,i,get_element(p,i));
+ set_element(p1,i,get_element(p,i));
+ }
+ for(size_t i=0;i<get_size(p);++i)
+ {
+ typename element_type_trait<pT>::element_type h=
+ std::max(get_element(p,i),rT(1))*ep;
+
+ set_element(p2,i,get_element(p,i)+h);
+ set_element(p1,i,get_element(p,i)-h);
+
+ rT v2=f(p2);
+ rT v1=f(p1);
+ set_element(result,i,
+ (v2-v1)/h/2
+ );
+ set_element(p2,i,get_element(p,i));
+ set_element(p1,i,get_element(p,i));
+ }
+ return result;
+ }
+
+
+ /**
+ Help function to calculate the gradient of an objection function
+ func_obj, whether it is differentiable or not. If it is differentiable,
+ the gradient will be calculated by calling the diff member in the func_obj,
+ or a numerical calculation will be performed.
+ */
+ template <typename rT,typename pT>
+ pT diff(func_obj<rT,pT>& f,const pT& p)
+ {
+ dfunc_obj<rT,pT>* pdf=dynamic_cast<dfunc_obj<rT,pT>*>(&f);
+ if(pdf)
+ {
+ return pdf->diff(p);
+ }
+ return numdiff(f,p);
+
+ }
+}
+
+#endif
diff --git a/math/vector_operation.hpp b/math/vector_operation.hpp
new file mode 100644
index 0000000..481fdef
--- /dev/null
+++ b/math/vector_operation.hpp
@@ -0,0 +1,18 @@
+#ifndef VECTOR_OPERATION_HPP
+#define VECTOR_OPERATION_HPP
+#include <core/opt_traits.hpp>
+
+template <typename pT>
+typename element_type_trait<pT>::element_type
+inner_product(const pT& v1,const pT& v2)
+{
+ typename element_type_trait<pT>::element_type result;
+ for(int i=0;i<get_size(v1);++i)
+ {
+ result+=get_element(v1,i)*get_element(v2,i);
+ }
+ return result;
+}
+
+
+#endif