00001
00002
00003
00004
00005
00006
00007
00008 #ifndef IMPALGEBRA_MATRIX_3D_H
00009 #define IMPALGEBRA_MATRIX_3D_H
00010
00011 #include "IMP/base_types.h"
00012 #include "IMP/exception.h"
00013 #include "MultiArray.h"
00014 #include <complex>
00015
00016
00017 IMPALGEBRA_BEGIN_NAMESPACE
00018
00019
00020
00021
00022
00023
00024 template<typename T>
00025 class Matrix3D: public MultiArray<T,3>
00026 {
00027 public:
00028 typedef boost::multi_array_types::index index;
00029 typedef MultiArray<T,3> MA3;
00030 typedef Matrix3D<T> This;
00031
00032
00033 Matrix3D() : MA3() {}
00034
00035
00036 Matrix3D(int Zdim, int Ydim, int Xdim) : MA3() {
00037 this->resize(Zdim, Ydim, Xdim);
00038 }
00039
00040
00041 Matrix3D(const This& v) : MA3() {
00042 this->reshape(v);
00043 MA3::copy((MA3 &)v);
00044 }
00045
00046
00047
00048
00049
00050
00051
00052 void resize(int Zdim, int Ydim, int Xdim) {
00053 typename This::extent_gen extents;
00054 MA3::resize(extents[Zdim][Ydim][Xdim]);
00055 }
00056
00057
00058
00059
00060
00061 template<typename T1>
00062 void resize(const Matrix3D<T1> &v) {
00063 this->resize(v.shape()[0], v.shape()[1], v.shape()[2]);
00064 }
00065
00066
00067
00068
00069
00070 template<typename T1>
00071 void reshape(const Matrix3D<T1>& v) {
00072 boost::array<index,3> shape,start;
00073 int dims=v.num_dimensions();
00074 for(int i=0;i<dims;i++) {
00075 shape[i]=v.shape()[i];
00076 start[i]=v.index_bases()[i];
00077 }
00078 resize(shape[0], shape[1], shape[2]);
00079 this->reindex(start);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 void pad(This& padded,T val) {
00090 padded.resize(2*this->get_size(0),2*this->get_size(1),2*this->get_size(2));
00091
00092 padded.fill_with_value(val);
00093 std::vector<index> idx(3),idx_for_padded(3);
00094 while (internal::roll_inds(idx, this->shape(),this->index_bases())) {
00095 for(int i=0;i<3;i++) {
00096 idx_for_padded[i]=idx[i]+(int)this->get_size(i)/2;
00097 }
00098 padded(idx_for_padded)=(*this)(idx);
00099 }
00100 }
00101
00102
00103
00104
00105
00106
00107 void pad(This& padded) {
00108 double avg = this->compute_avg();
00109 this->pad(padded,avg);
00110 }
00111
00112
00113 template<typename T1>
00114 void cast_values(Matrix3D<T1> &out) {
00115 out.resize(*this);
00116 for(unsigned int i=0; i<this->num_elements(); i++) {
00117 out.data()[i] = (T1)this->data()[i];
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 T& operator()(int k,int j, int i) const {
00130 if (this->get_start(0) <= k && k <= this->get_finish(0) &&
00131 this->get_start(1) <= j && j <= this->get_finish(1) &&
00132 this->get_start(2) <= i && i <= this->get_finish(2)) {
00133 return (T&)(*this)[k][j][i];
00134 } else {
00135 String msg = "Matri3D::(): Index out of range." ;
00136 throw ValueException(msg.c_str());
00137 }
00138 }
00139
00140
00141
00142
00143
00144
00145 template<typename T1>
00146 T& operator()(T1& idx) const {
00147 return (T&)((*this)[idx[0]][idx[1]][idx[2]]);
00148 }
00149
00150
00151 int get_number_of_slices() const {
00152 return (int)this->get_size(0);
00153 }
00154
00155
00156 int get_number_of_rows() const {
00157 return (int)this->get_size(1);
00158 }
00159
00160
00161 int get_number_of_columns() const {
00162 return (int)this->get_size(2);
00163 }
00164
00165 void operator=(const This& v) {
00166 this->reshape(v);
00167 MA3::copy((MA3 &)v);
00168 }
00169
00170
00171 This operator+(const This& v) const {
00172 This result;
00173 result.resize(*this);
00174 internal::operate_arrays(*this, v, result, '+');
00175 return result;
00176 }
00177
00178
00179 This operator-(const This& v) const {
00180 This result;
00181 result.resize(*this);
00182 internal::operate_arrays(*this, v, result, '-');
00183 return result;
00184 }
00185
00186
00187 This operator*(const This& v) const {
00188 This result;
00189 result.resize(*this);
00190 internal::operate_arrays(*this, v, result, '*');
00191 return result;
00192 }
00193
00194
00195 This operator/(const This& v) const {
00196 This result;
00197 result.resize(*this);
00198 internal::operate_arrays(*this, v, result, '/');
00199 return result;
00200 }
00201
00202
00203 This operator+(const T& v) const {
00204 This result;
00205 result.resize(*this);
00206 internal::operate_array_and_scalar(*this, v, result, '+');
00207 return result;
00208 }
00209
00210
00211 This operator-(const T& v) const {
00212 This result;
00213 result.resize(*this);
00214 internal::operate_array_and_scalar(*this, v, result, '-');
00215 return result;
00216 }
00217
00218
00219 This operator*(const T& v) const {
00220 This result;
00221 result.resize(*this);
00222 internal::operate_array_and_scalar(*this, v, result, '*');
00223 return result;
00224 }
00225
00226
00227 This operator/(const T& v) const {
00228 This result;
00229 result.resize(*this);
00230 internal::operate_array_and_scalar(*this, v, result, '/');
00231 return result;
00232 }
00233
00234
00235 This& operator+=(const This& v) {
00236 internal::operate_arrays(*this, v, *this, '+');
00237 return *this;
00238 }
00239
00240
00241 This& operator-=(const This& v) {
00242 internal::operate_arrays(*this, v, *this, '-');
00243 return *this;
00244 }
00245
00246
00247 This& operator*=(const This& v) {
00248 internal::operate_arrays(*this, v, *this, '*');
00249 return *this;
00250 }
00251
00252
00253 This& operator/=(const This& v) {
00254 internal::operate_arrays(*this, v, *this, '/');
00255 return *this;
00256 }
00257
00258
00259 This& operator+=(const T& v) {
00260 internal::operate_array_and_scalar(*this, v, *this, '+');
00261 return *this;
00262 }
00263
00264
00265 This& operator-=(const T& v) {
00266 internal::operate_array_and_scalar(*this, v, *this, '-');
00267 return *this;
00268 }
00269
00270
00271 This& operator*=(const T& v) {
00272 internal::operate_array_and_scalar(*this, v, *this, '*');
00273 return *this;
00274 }
00275
00276
00277 This& operator/=(const T& v) {
00278 internal::operate_array_and_scalar(*this, v, *this, '/');
00279 return *this;
00280 }
00281
00282
00283 friend This operator+(const T& X, const This& a1) {
00284 This result;
00285 result.resize(a1);
00286 internal::operate_scalar_and_array(X,a1,result,"+");
00287 return result;
00288 }
00289
00290
00291 friend This operator-(const T& X, const This& a1) {
00292 This result;
00293 result.resize(a1);
00294 internal::operate_scalar_and_array(X,a1,result,"-");
00295 return result;
00296 }
00297
00298
00299 friend This operator*(const T& X, const This& a1) {
00300 This result;
00301 result.resize(a1);
00302 internal::operate_scalar_and_array(X,a1,result,"*");
00303 return result;
00304 }
00305
00306
00307 friend This operator/(const T& X, const This& a1) {
00308 This result;
00309 result.resize(a1);
00310 internal::operate_scalar_and_array(X,a1,result,"/");
00311 return result;
00312 }
00313
00314 protected:
00315 };
00316
00317 IMPALGEBRA_END_NAMESPACE
00318
00319 #endif