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