Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_HESSIAN_H
00002 #define OPENTISSUE_CORE_CONTAINERS_GRID_UTIL_GRID_HESSIAN_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace grid
00015 {
00016
00017 template<typename grid_type, typename matrix3x3_type>
00018 inline void hessian(
00019 grid_type const & grid
00020 , size_t i
00021 , size_t j
00022 , size_t k
00023 , matrix3x3_type & H
00024 )
00025 {
00026 using std::min;
00027
00028 typedef typename matrix3x3_type::value_type real_type;
00029
00030 static grid_type * old_grid = 0;
00031 static real_type m_inv_dx2 = 0;
00032 static real_type m_inv_dy2 = 0;
00033 static real_type m_inv_dz2 = 0;
00034 static real_type m_inv_4dxy = 0;
00035 static real_type m_inv_4dxz = 0;
00036 static real_type m_inv_4dyz = 0;
00037
00038 if(old_grid!=&grid)
00039 {
00040 old_grid = const_cast<grid_type*>(&grid);
00041 m_inv_dx2 = 1.0 / grid.dx() * grid.dx();
00042 m_inv_dy2 = 1.0 / grid.dy() * grid.dy();
00043 m_inv_dz2 = 1.0 / grid.dz() * grid.dz();
00044 m_inv_4dxy = 0.25 / grid.dx() * grid.dy();
00045 m_inv_4dxz = 0.25 / grid.dx() * grid.dz();
00046 m_inv_4dyz = 0.25 / grid.dy() * grid.dz();
00047 }
00048
00049 size_t I = grid.I();
00050 size_t J = grid.J();
00051 size_t K = grid.K();
00052
00053 size_t im1 = 0, jm1 = 0, km1 = 0;
00054 if ( i )
00055 im1 = i - 1;
00056 if ( j )
00057 jm1 = j - 1;
00058 if ( k )
00059 km1 = k - 1;
00060 size_t ip1 = min( i + 1u, I - 1u );
00061 size_t jp1 = min( j + 1u, J - 1u );
00062 size_t kp1 = min( k + 1u, K - 1u );
00063
00064 size_t idx_000 = ( k * J + j ) * I + i;
00065 size_t idx_m00 = ( k * J + j ) * I + im1;
00066 size_t idx_p00 = ( k * J + j ) * I + ip1;
00067 size_t idx_0m0 = ( k * J + jm1 ) * I + i;
00068 size_t idx_0p0 = ( k * J + jp1 ) * I + i;
00069 size_t idx_00m = ( km1 * J + j ) * I + i;
00070 size_t idx_00p = ( kp1 * J + j ) * I + i;
00071
00072 real_type d000 = 2.0 * grid( idx_000 );
00073 real_type dp00 = grid( idx_p00 );
00074 real_type dm00 = grid( idx_m00 );
00075 real_type d0p0 = grid( idx_0p0 );
00076 real_type d0m0 = grid( idx_0m0 );
00077 real_type d00p = grid( idx_00p );
00078 real_type d00m = grid( idx_00m );
00079
00080 size_t idx_pp0 = ( k * J + jp1 ) * I + ip1;
00081 size_t idx_mp0 = ( k * J + jp1 ) * I + im1;
00082 size_t idx_pm0 = ( k * J + jm1 ) * I + ip1;
00083 size_t idx_mm0 = ( k * J + jm1 ) * I + im1;
00084 size_t idx_p0p = ( kp1 * J + j ) * I + ip1;
00085 size_t idx_m0p = ( kp1 * J + j ) * I + im1;
00086
00087 real_type dpp0 = grid( idx_pp0 );
00088 real_type dmp0 = grid( idx_mp0 );
00089 real_type dpm0 = grid( idx_pm0 );
00090 real_type dmm0 = grid( idx_mm0 );
00091 real_type dp0p = grid( idx_p0p );
00092 real_type dm0p = grid( idx_m0p );
00093
00094 size_t idx_p0m = ( km1 * J + j ) * I + ip1;
00095 size_t idx_m0m = ( km1 * J + j ) * I + im1;
00096 size_t idx_0pp = ( kp1 * J + jp1 ) * I + i;
00097 size_t idx_0pm = ( km1 * J + jp1 ) * I + i;
00098 size_t idx_0mp = ( kp1 * J + jm1 ) * I + i;
00099 size_t idx_0mm = ( km1 * J + jm1 ) * I + i;
00100
00101 real_type dp0m = grid( idx_p0m );
00102 real_type dm0m = grid( idx_m0m );
00103 real_type d0pp = grid( idx_0pp );
00104 real_type d0pm = grid( idx_0pm );
00105 real_type d0mp = grid( idx_0mp );
00106 real_type d0mm = grid( idx_0mm );
00107
00108
00109
00110
00111
00112
00113
00114
00115 H( 0, 0 ) = ( dp00 + dm00 - d000 ) * m_inv_dx2;
00116 H( 1, 1 ) = ( d0p0 + d0m0 - d000 ) * m_inv_dy2;
00117 H( 2, 2 ) = ( d00p + d00m - d000 ) * m_inv_dz2;
00118 H( 1, 0 ) = H( 0, 1 ) = ( dpp0 - dmp0 - dpm0 + dmm0 ) * m_inv_4dxy;
00119 H( 0, 2 ) = H( 2, 0 ) = ( dp0p - dm0p - dp0m + dm0m ) * m_inv_4dxz;
00120 H( 1, 2 ) = H( 2, 1 ) = ( d0pp - d0pm - d0mp + d0mm ) * m_inv_4dyz;
00121 }
00122
00123 template<typename grid_iterator,typename matrix3x3_type>
00124 inline void hessian (grid_iterator const & iter, matrix3x3_type & H )
00125 {
00126 typedef typename grid_iterator::grid_type grid_type;
00127
00128 size_t i = iter.i();
00129 size_t j = iter.j();
00130 size_t k = iter.k();
00131
00132 grid_type const & grid = iter.get_grid();
00133
00134 hessian(grid, i, j, k, H);
00135 }
00136
00137
00138 template<typename grid_iterator>
00139 inline OpenTissue::math::Matrix3x3< typename grid_iterator::math_types::real_type >
00140 hessian (grid_iterator const & iter )
00141 {
00142 typedef typename grid_iterator::math_types::real_type real_type;
00143 typedef OpenTissue::math::Matrix3x3< real_type > matrix3x3_type;
00144
00145 matrix3x3_type H;
00146
00147 hessian(iter, H);
00148
00149 return H;
00150 }
00151
00152 }
00153 }
00154
00155
00156 #endif