00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE
00013 #define MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE
00014
00015 #include <cmath>
00016 #include <boost/numeric/mtl/utility/exception.hpp>
00017 #include <boost/numeric/mtl/concept/collection.hpp>
00018
00019 namespace mtl { namespace matrix {
00020
00022
00024 template <typename Matrix, typename Value>
00025 void hessian_setup(Matrix& matrix, Value factor)
00026 {
00027 typedef typename Matrix::value_type value_type;
00028 typedef typename Matrix::size_type size_type;
00029 for (size_type r= matrix.begin_row(); r < matrix.end_row(); r++)
00030 for (size_type c= matrix.begin_col(); c < matrix.end_col(); c++)
00031 matrix[r][c]= factor * (value_type(r) + value_type(c));
00032 }
00033
00034 namespace impl {
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 template <typename Value>
00045 double inline hessian_product_i_j (Value i, Value j, Value N)
00046 {
00047 return 1.0/3.0 * N * (1.0 - 3*i - 3*j + 6*i*j - 3*N + 3*i*N + 3*j*N + 2*N*N);
00048 }
00049
00050 template <typename Value>
00051 inline bool similar_values(Value x, Value y)
00052 {
00053 using std::abs; using std::max;
00054 return abs(x - y) / max(abs(x), abs(y)) < 0.000001;
00055 }
00056 }
00057
00058
00059
00060
00061
00062 template <typename Matrix>
00063 void check_hessian_matrix_product(Matrix const& c, typename Matrix::size_type reduced_dim, double factor= 1.0)
00064 {
00065 using impl::similar_values; using impl::hessian_product_i_j;
00066 typedef typename Matrix::value_type value_type;
00067 typedef typename Matrix::size_type size_type;
00068 size_type rb= c.begin_row(), rl= c.end_row() - 1,
00069 cb= c.begin_col(), cl= c.end_col() - 1;
00070
00071 if (!similar_values(value_type(factor * hessian_product_i_j(rb, cb, reduced_dim)), c[rb][cb])) {
00072 std::cout << "Result in c[" << rb << "][" << cb << "] should be "
00073 << factor * hessian_product_i_j(rb, cb, reduced_dim)
00074 << " but is " << c[rb][cb] << "\n";
00075 MTL_THROW(unexpected_result());
00076 }
00077
00078 if (!similar_values(value_type(factor * hessian_product_i_j(rl, cb, reduced_dim)), c[rl][cb])) {
00079 std::cout << "Result ixn c[" << rl << "][" << cb << "] should be "
00080 << factor * hessian_product_i_j(rl, cb, reduced_dim)
00081 << " but is " << c[rl][cb] << "\n";
00082 MTL_THROW(unexpected_result());
00083 }
00084
00085 if (!similar_values(value_type(factor * hessian_product_i_j(rb, cl, reduced_dim)), c[rb][cl])) {
00086 std::cout << "Result in c[" << rb << "][" << cb << "] should be "
00087 << factor * hessian_product_i_j(rb, cl, reduced_dim)
00088 << " but is " << c[rb][cl] << "\n";
00089 MTL_THROW(unexpected_result());
00090 }
00091
00092 if (!similar_values(value_type(factor * hessian_product_i_j(rl, cl, reduced_dim)), c[rl][cl])) {
00093 std::cout << "Result in c[" << rl << "][" << cb << "] should be "
00094 << factor * hessian_product_i_j(rl, cl, reduced_dim)
00095 << " but is " << c[rl][cl] << "\n";
00096 MTL_THROW(unexpected_result());
00097 }
00098
00099
00100 if (!similar_values(value_type(factor * hessian_product_i_j((rb+rl)/2, (cb+cl)/2, reduced_dim)),
00101 c[(rb+rl)/2][(cb+cl)/2])) {
00102 std::cout << "Result in c[" << (rb+rl)/2 << "][" << (cb+cl)/2 << "] should be "
00103 << factor * hessian_product_i_j((rb+rl)/2, (cb+cl)/2, reduced_dim)
00104 << " but is " << c[(rb+rl)/2][(cb+cl)/2] << "\n";
00105 MTL_THROW(unexpected_result());
00106 }
00107 }
00108
00109 }
00110
00111 using matrix::hessian_setup;
00112 using matrix::check_hessian_matrix_product;
00113
00114 }
00115
00116 #endif // MTL_HESSIAN_MATRIX_UTILITIES_INCLUDE