00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef IMPALGEBRA_INTERPOLATION_H
00010 #define IMPALGEBRA_INTERPOLATION_H
00011
00012
00013
00014 #include "IMP/algebra/algebra_config.h"
00015 #include "IMP/algebra/utility.h"
00016 #include "IMP/algebra/Matrix2D.h"
00017 #include "IMP/algebra/Matrix3D.h"
00018 #include "IMP/algebra/Vector2D.h"
00019 #include "IMP/algebra/Vector3D.h"
00020 #include <complex>
00021
00022 IMPALGEBRA_BEGIN_NAMESPACE
00023
00024
00025
00026
00027
00028 template<typename T>
00029 T get_linearly_interpolated(double diff,T lower,T upper) {
00030 return lower+diff*(upper-lower);
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040 template<typename T,typename H>
00041 T linear_interpolation(H &v,int size,double idx) {
00042 int i = (int)floor(idx);
00043
00044 IMP_INTERNAL_CHECK(i>=0 && i<size,"linear_interpolation: Index out of range");
00045 if(i=0 || i==(size-1)) return v[i];
00046 return simple_interpolate(idx-i,v[i],v[i+1]);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template<typename T>
00063 T trilinear_interpolation(Matrix3D<T> &m,
00064 VectorD<3> &idx,
00065 bool wrap,
00066 T outside) {
00067
00068
00069 int lower[3], upper[3];
00070 double diff[3];
00071 T result;
00072 if(!wrap) {
00073
00074 if(!m.is_logical_element(idx)) {
00075 return outside;
00076 } else {
00077
00078 for(int i=0;i<3;i++) {
00079 lower[i] = (int)floor(idx[i]);
00080
00081 if(lower[i]==m.get_finish(i)) {
00082 return outside;
00083 } else {
00084 upper[i] = lower[i]+1;
00085 }
00086 diff[i] = (double)idx[i] - (double)lower[i];
00087 }
00088 }
00089
00090 } else {
00091 for(int i=0;i<3;i++) {
00092 lower[i] = (int)floor(idx[i]);
00093 upper[i] = lower[i]+1;
00094 int size = m.get_size(i);
00095
00096 diff[i] = (double)idx[i] - (double)lower[i];
00097
00098 if(lower[i]<m.get_start(i) ) { lower[i]+=size; }
00099 if(upper[i]<m.get_start(i) ) { upper[i]+=size; }
00100 if(lower[i]>m.get_finish(i)) { lower[i]-=size; }
00101 if(upper[i]>m.get_finish(i)) { upper[i]-=size; }
00102 }
00103 }
00104
00105 T c00 = simple_interpolate(diff[0],m(lower[0],lower[1],lower[2]),
00106 m(upper[0],lower[1],lower[2]));
00107 T c10 = simple_interpolate(diff[0],m(lower[0],upper[1],lower[2]),
00108 m(upper[0],upper[1],lower[2]));
00109 T c01 = simple_interpolate(diff[0],m(lower[0],lower[1],upper[2]),
00110 m(upper[0],lower[1],upper[2]));
00111 T c11 = simple_interpolate(diff[0],m(lower[0],upper[1],upper[2]),
00112 m(upper[0],upper[1],upper[2]));
00113 T c0 = simple_interpolate(diff[1],c00,c10);
00114 T c1 = simple_interpolate(diff[1],c01,c11);
00115 result= simple_interpolate(diff[2],c0,c1);
00116 #ifdef IMP_DEBUG_INTERPOLATION
00117 IMP_LOG(VERBOSE," lower " << lower[0] << " " << lower[1] << " " << lower[2]
00118 << " upper " << upper[0] << " " << upper[1] << " " << upper[2]
00119 << " diff " << diff[0] << " " << diff[1] << " " << diff[2]
00120 << std::endl);
00121 #endif
00122 return result;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 double interpolate(algebra::Matrix2D<double> &m,
00140 VectorD<2>& idx,
00141 bool wrap = false,
00142 double outside = 0.0,
00143 int interp=0);
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 template<typename T>
00161 T interpolate(algebra::Matrix3D<T> &m,
00162 VectorD<3> &idx,
00163 bool wrap = false,
00164 T outside = 0.0,
00165 int interp=0) {
00166 T result;
00167 switch(interp) {
00168 case 0:
00169 result=trilinear_interpolation(m,idx,wrap,(T)outside);
00170 break;
00171 case 1:
00172
00173
00174 result = 0.0;
00175 break;
00176 }
00177 return result;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 IMPALGEBRAEXPORT double bilinear_interpolation(Matrix2D<double>& m,
00196 VectorD<2>& idx,
00197 bool wrap = false,
00198 double outside = 0.0);
00199 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
00200
00201
00202 IMPALGEBRAEXPORT double Bspline_interpolation(Matrix2D<double>& m,
00203 VectorD<2>& idx,
00204 bool wrap = false,
00205 double outside = 0.0);
00206 #endif
00207
00208
00209
00210 IMPALGEBRA_END_NAMESPACE
00211
00212 #endif