00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef METALIC_ARRAY_3D_HH
00029 # define METALIC_ARRAY_3D_HH
00030
00031 # include <mlc/array/objs.hh>
00032 # include <mlc/contract.hh>
00033 # include <mlc/cmp.hh>
00034 # include <ntg/basics.hh>
00035
00036 # include <iostream>
00037
00038
00039 # include <mlc/array/3d.hxx>
00040
00041 namespace mlc
00042 {
00043
00044 class not_implemented_yet{};
00045
00046 template<class Info_, class T_>
00047 struct array3d
00048 {
00049 typedef array3d self;
00050 typedef T_ T;
00051 typedef Info_ Info;
00052
00053
00054
00055
00056
00057 array3d()
00058 {
00059 }
00060
00061 array3d(T* ptr)
00062 {
00063 less< 0, Info_::nplanes >::ensure();
00064 less< 0, Info_::nrows >::ensure();
00065 less< 0, Info_::ncols >::ensure();
00066 less< Info_::card, internal::max_card_ >::ensure();
00067 for (unsigned i = 0; i < Info_::card; ++i)
00068 buffer_[i] = *ptr++;
00069 }
00070
00071
00072
00073 array3d(const self& rhs)
00074 {
00075 for (unsigned i = 0; i < Info_::card; ++i)
00076 buffer_[i] = rhs[i];
00077 }
00078 self& operator=(const self& rhs)
00079 {
00080 for (unsigned i = 0; i < Info_::card; ++i)
00081 buffer_[i] = rhs[i];
00082 return *this;
00083 }
00084
00085
00086
00087
00088 static std::string
00089 name()
00090 {
00091 return std::string("array3d< Info, ") + ntg_name(T) + " >";
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 array3d<Info_, ntg::float_s>
00103 normalize()
00104 {
00105 array3d<Info_, ntg::float_s> tmp;
00106 ntg::float_s sum = 0.f;
00107 const ntg::float_s epsilon = 0.01f;
00108 unsigned i;
00109 for (i = 0; i < Info_::card; ++i)
00110 sum += this->buffer_[i];
00111 for (i = 0; i < Info_::card; ++i)
00112 tmp[i] = this->buffer_[i] / sum;
00113
00114 sum = 0.f;
00115 for (i = 0; i < Info_::card; ++i)
00116 sum += tmp[i];
00117 postcondition(std::abs(sum - 1) <= epsilon);
00118 return tmp;
00119 }
00120
00121
00122
00123 array3d<array3d_info<Info_::nplanes,
00124 Info_::nrows,
00125 Info_::ncols,
00126 Info_::card - Info_::center - 1,
00127 Info_::i>, T>
00128 operator-() const
00129 {
00130 enum { new_center = Info_::card - Info_::center - 1 };
00131 array3d<array3d_info< Info_::nplanes, Info_::nrows, Info_::ncols, new_center, Info_::i>,T> tmp;
00132
00133 for (unsigned i = 0; i < Info_::card; ++i)
00134 tmp[Info_::card - i - 1] = this->operator[](i);
00135 return tmp;
00136 }
00137
00138
00139
00140
00141 array3d<Info, T> transpose() const
00142 {
00143 std::cerr << "[31m===> 3D transposition not implemented yet. <===[0m" << std::endl;
00144 throw not_implemented_yet();
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 template <class U>
00154 array3d< Info, ntg_return_type(times, T, U) >
00155 operator*(U w)
00156 {
00157 array3d< Info, ntg_return_type(times, T, U) > tmp;
00158 for (unsigned i = 0; i < Info::card; ++i)
00159 tmp[i] = this->buffer_[i] * w;
00160 return tmp;
00161 }
00162
00163 template <class U>
00164 array3d< Info, ntg_return_type(div, T, U) >
00165 operator/(U w)
00166 {
00167 array3d< Info, ntg_return_type(div, T, U) > tmp;
00168 for (unsigned i = 0; i < Info::card; ++i)
00169 tmp[i] = this->buffer_[i] / w;
00170 return tmp;
00171 }
00172
00173 self operator+(const self& rhs) const
00174 {
00175 self tmp;
00176 for (unsigned i = 0; i < Info::card; ++i)
00177 tmp[i] = this->buffer_[i] + rhs.buffer_[i];
00178 return tmp;
00179 }
00180 self& operator+=(const self& rhs)
00181 {
00182 for (unsigned i = 0; i < Info::card; ++i)
00183 this->buffer_[i] += rhs.buffer_[i];
00184 return *this;
00185 }
00186
00187 self operator-(const self& rhs) const
00188 {
00189 self tmp;
00190 for (unsigned i = 0; i < Info::card; ++i)
00191 tmp[i] = this->buffer_[i] - rhs.buffer_[i];
00192 return tmp;
00193 }
00194 self& operator-=(const self& rhs)
00195 {
00196 for (unsigned i = 0; i < Info::card; ++i)
00197 this->buffer_[i] -= rhs.buffer_[i];
00198 return *this;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 unsigned size() const
00210 {
00211 return Info_::card;
00212 }
00213
00214 const T* buffer() const
00215 {
00216 return buffer_;
00217 }
00218
00219
00220
00221 T operator[](unsigned i) const
00222 {
00223 precondition(i < Info_::card);
00224 return *(buffer_ + i);
00225 }
00226 T& operator[](unsigned i)
00227 {
00228 precondition(i < Info_::card);
00229 return *(buffer_ + i);
00230 }
00231
00232
00233 T operator()(int plane, int row, int col) const
00234 {
00235 precondition(-Info_::center_plane <= plane);
00236 precondition(plane <= Info::nplanes - Info_::center_plane - 1);
00237 precondition(-Info_::center_row <= row);
00238 precondition(row <= Info_::nrows - Info_::center_row - 1);
00239 precondition(-Info_::center_col <= col);
00240 precondition(col <= Info_::ncols - Info_::center_col - 1);
00241
00242 return *(buffer_ + Info_::center + (plane * Info::nrows * Info::ncols) + (row * Info::ncols) + col);
00243 }
00244
00245 T& operator()(int plane, int row, int col)
00246 {
00247 precondition(-Info_::center_plane <= plane);
00248 precondition(plane <= Info::nplanes - Info_::center_plane - 1);
00249 precondition(-Info_::center_row <= row);
00250 precondition(row <= Info_::nrows - Info_::center_row - 1);
00251 precondition(-Info_::center_col <= col);
00252 precondition(col <= Info_::ncols - Info_::center_col - 1);
00253
00254 return *(buffer_ + Info_::center + (plane * Info::nrows * Info::ncols) + (row * Info::ncols) + col);
00255 }
00256
00257
00258
00259
00260 template<unsigned i>
00261 T get_at_() const {
00262 lesseq<i, Info_::card>::ensure();
00263 return *(buffer_ + i);
00264 }
00265
00266 template<int nplane, int nrow, int ncol>
00267 T get_() const {
00268 lesseq< -Info_::center_plane, nplane >::ensure();
00269 lesseq< nplane, Info::nplanes - Info_::center_plane - 1 >::ensure();
00270 lesseq< -Info_::center_row, nrow >::ensure();
00271 lesseq< nrow, Info_::nrows - Info_::center_row - 1 >::ensure();
00272 lesseq< -Info_::center_col, ncol >::ensure();
00273 lesseq< ncol, Info_::ncols - Info_::center_col - 1 >::ensure();
00274 return *(buffer_ + Info_::center + (nplane * Info::nrows * Info::ncols) + (nrow * Info::ncols) + ncol);
00275 }
00276
00277
00278 protected:
00279
00280 T buffer_[internal::max_card_];
00281 };
00282
00283
00284
00285
00286 template<unsigned i, class Info, class T> inline
00287 T get_at(const array3d<Info, T>& arr)
00288 {
00289 return arr.template get_at_<i>();
00290 }
00291
00292 template<int plane, int row, int col, class Info, class T> inline
00293 T get(const array3d<Info, T>& arr)
00294 {
00295 return arr.template get_<plane, row, col>();
00296 }
00297
00298
00299
00300
00301
00302
00303 # define array3d_starter(T) \
00304 static internal::array3d_start_<T > T##s_3d = internal::array3d_start_<T >()
00305
00306 array3d_starter(int);
00307 array3d_starter(float);
00308
00309
00310
00311
00312 template<class Info, class T>
00313 std::ostream& operator<<(std::ostream& ostr, const array3d<Info, T>& rhs)
00314 {
00315 for (int i = 0; i < Info::card; ++i)
00316 {
00317 if (i == Info::center)
00318 ostr << "<" << rhs[i] << "> ";
00319 else
00320 ostr << rhs[i] << " ";
00321
00322 ostr << ((i + 1) % Info::ncols == 0 ? "\n" : "\t");
00323 ostr << ((i + 1) % (Info::ncols * Info::nrows) == 0 ? "\n" : "");
00324 }
00325 ostr << std::flush;
00326
00327 return ostr;
00328 }
00329
00330
00331 }
00332
00333 #endif // ! METALIC_ARRAY_3D_HH