Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_INTERPOLATION_INTERPOLATION_VARIATIONAL_INTERPOLATOR_H
00002 #define OPENTISSUE_CORE_MATH_INTERPOLATION_INTERPOLATION_VARIATIONAL_INTERPOLATOR_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/big/big_lu.h>
00013
00014 #include <boost/lambda/lambda.hpp>
00015
00016 #include <cmath>
00017 #include <algorithm>
00018 #include <iterator>
00019
00020 #ifndef NDEBUG
00021 #include <fstream>
00022 #endif
00023
00024 namespace OpenTissue
00025 {
00026 namespace interpolation
00027 {
00028
00029 namespace detail
00030 {
00031
00039 template<typename vector_type>
00040 inline typename vector_type::value_type radial_basis_function(vector_type const & x)
00041 {
00042 using std::log;
00043 typedef typename vector_type::value_type real_type;
00044
00045 real_type dot_prod = x*x;
00046 real_type norm = sqrt(dot_prod);
00047 if(norm>0)
00048 return dot_prod * log( norm );
00049 return norm;
00050 }
00051
00052
00056 template<typename small_vector_type>
00057 class ImplicitFunction
00058 {
00059 public:
00060
00061 typedef typename small_vector_type::value_type real_type;
00062
00063 typedef typename ublas::matrix<real_type> big_matrix_type;
00064 typedef typename ublas::vector<real_type> big_vector_type;
00065 typedef typename big_matrix_type::size_type size_type;
00066
00067 typedef small_vector_type return_type;
00068
00069 protected:
00070
00071 big_vector_type m_x;
00072 big_vector_type m_b;
00073 big_matrix_type m_A;
00074
00075 size_type m_N;
00076 size_type m_dim;
00077 size_type m_M;
00078 std::vector<small_vector_type> m_c;
00079
00080 public:
00081
00090 template<typename iterator>
00091 void init( iterator point_begin,iterator point_end, iterator normal_begin,iterator normal_end)
00092 {
00093 real_type k = 0.01;
00094
00095 using std::distance;
00096
00097 size_type cnt_points = distance(point_begin,point_end);
00098 size_type cnt_normals = distance(normal_begin,normal_end);
00099
00100 assert(cnt_points==cnt_normals || !"implicit_function::init(): The number of normals and points did not match");
00101
00102 m_dim = point_begin->size();
00103
00104 m_N = cnt_points+cnt_normals;
00105 m_M = m_N + m_dim + 1;
00106
00107 std::copy(point_begin, point_end, std::back_inserter( m_c ) );
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 {
00118 using namespace boost::lambda;
00119 std::transform( point_begin, point_end, normal_begin, std::back_inserter( m_c ),
00120 ret<small_vector_type>(_1 + ret<small_vector_type>(_2*k)) );
00121 }
00122
00123
00124
00125
00126
00127 m_x.resize( m_M );
00128 m_b.resize( m_M );
00129 m_A.resize( m_M, m_M );
00130
00131 m_A.clear();
00132 m_b.clear();
00133 m_x.clear();
00134
00135
00136 for(unsigned int i=0;i<m_M;++i)
00137 {
00138 if(i<cnt_points)
00139 m_b(i) = 0;
00140 else if (i<m_N)
00141 m_b(i) = 1;
00142 else
00143 m_b(i) = 0;
00144 }
00145
00146 for(unsigned int i=0;i<m_N;++i)
00147 for(unsigned int j=i;j<m_N;++j)
00148 {
00149 real_type phi_ij = radial_basis_function( m_c[i] - m_c[j] );
00150 m_A(i,j) = m_A(j,i) = phi_ij;
00151 }
00152
00153 for(unsigned int i=0;i<m_N;++i)
00154 {
00155 m_A(i, m_N) = m_A(m_N , i) = 1;
00156 for(unsigned int j=0;j<m_dim;++j)
00157 m_A(i,j+m_N+1) = m_A(j+m_N+1,i) = m_c[i](j);
00158 }
00159 math::big::lu(m_A,m_x,m_b);
00160 }
00161
00162 public:
00163
00171 real_type operator()( small_vector_type const & x ) const
00172 {
00173 real_type value = 0;
00174
00175 for(unsigned int j=0;j<m_N;++j)
00176 value += m_x(j)*radial_basis_function( x - m_c[j] );
00177
00178 value += m_x(m_N);
00179 for(unsigned int j=0;j<m_dim;++j)
00180 value += m_x(m_N + j +1)*(x(j));
00181
00182 return value;
00183 }
00184
00185 };
00186
00187 }
00188
00189
00265 template<typename iterator>
00266 inline detail::ImplicitFunction<typename iterator::value_type> variational_interpolator(
00267 iterator point_begin
00268 , iterator point_end
00269 , iterator normal_begin
00270 , iterator normal_end
00271 )
00272 {
00273 typedef typename iterator::value_type small_vector_type;
00274 typedef detail::ImplicitFunction<small_vector_type> implicit_function_type;
00275 implicit_function_type f;
00276 f.init(point_begin,point_end,normal_begin,normal_end);
00277 return f;
00278 }
00279
00280 }
00281
00282 }
00283
00284
00285 #endif