1d.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef METALIC_ARRAY_1D_HH
00029 # define METALIC_ARRAY_1D_HH
00030 
00031 # include <mlc/contract.hh>
00032 # include <mlc/cmp.hh>
00033 # include <mlc/array/objs.hh>
00034 # include <ntg/basics.hh>
00035 # include <iostream>
00036 
00037 
00038 // impl
00039 # include <mlc/array/1d.hxx>
00040 
00041 namespace mlc
00042 {
00043 
00044   template<class Info_, class T_>
00045   struct array1d
00046   {
00047     typedef array1d self;
00048     typedef T_ T;
00049     typedef Info_ Info;
00050 
00051 
00052     //
00053     // Constructors
00054     //
00055 
00056     array1d()
00057     {
00058     }
00059 
00060     array1d(T* ptr)
00061     {
00062       less<0, Info_::card>::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     // Copy
00069 
00070     array1d(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     // Name
00084 
00085     static std::string
00086     name()
00087     {
00088       return std::string("array1d< Info, ") + ntg_name(T) + " >";
00089     }
00090 
00091 
00092 
00093     //
00094     // Operations on array
00095     //
00096 
00097     // Normalize (absolute values -> relative values)
00098 
00099     array1d<Info_, ntg::float_s>
00100     normalize()
00101     {
00102       array1d<Info_, ntg::float_s> tmp;
00103       ntg::float_s sum = 0.f;
00104       const ntg::float_s epsilon = 0.01f; // FIXME : epsilon should be global
00105       unsigned i;
00106       for (i = 0; i < Info_::card; ++i)
00107         sum += this->buffer_[i];
00108       for (i = 0; i < Info_::card; ++i)
00109         tmp[i] = this->buffer_[i] / sum;
00110       // security
00111       sum = 0.f;
00112       for (i = 0; i < Info_::card; ++i)
00113         sum += tmp[i];
00114       postcondition(std::abs(sum - 1) <= epsilon);
00115       return tmp;
00116     }
00117 
00118     // Central symmetry
00119 
00120     array1d<array1d_info<Info_::card,
00121                          Info_::card - Info_::center - 1,
00122                          Info_::i>, T>
00123     operator-() const
00124     {
00125       enum { new_center =  Info_::card - Info_::center - 1 };
00126       array1d<array1d_info< Info_::card, new_center, Info_::i>,T> tmp;
00127 
00128       for (unsigned i = 0; i < Info_::card; ++i)
00129         tmp[Info_::card - i - 1] = this->operator[](i);
00130       return tmp;
00131     }
00132 
00133 
00134     // Operators
00135 
00136     // FIXME: This code should be factorized between 1d, 2d and 3d.
00137     // Think of a mechanism similar to apply() and apply2().
00138 
00139     template <class U>
00140     array1d< Info, ntg_return_type(times, T, U) >
00141     operator*(U w)
00142     {
00143       array1d< Info, ntg_return_type(times, T, U) > tmp;
00144       for (unsigned i = 0; i < Info::card; ++i)
00145         tmp[i] = this->buffer_[i] * w;
00146       return tmp;
00147     }
00148 
00149     template <class U>
00150     array1d< Info, ntg_return_type(div, T, U) >
00151     operator/(U w)
00152     {
00153       array1d< Info, ntg_return_type(div, T, U) > tmp;
00154       for (unsigned i = 0; i < Info::card; ++i)
00155         tmp[i] = this->buffer_[i] / w;
00156       return tmp;
00157     }
00158 
00159     self operator+(const self& rhs) const
00160     {
00161       self tmp;
00162       for (unsigned i = 0; i < Info::card; ++i)
00163         tmp[i] = this->buffer_[i] + rhs.buffer_[i];
00164       return tmp;
00165     }
00166     self& operator+=(const self& rhs)
00167     {
00168       for (unsigned i = 0; i < Info::card; ++i)
00169         this->buffer_[i] += rhs.buffer_[i];
00170       return *this;
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 
00188     //
00189     // Accessors
00190     //
00191 
00192     unsigned size() const
00193     {
00194       return Info_::card;
00195     }
00196 
00197     const T* buffer() const
00198     {
00199       return buffer_;
00200     }
00201 
00202     // dynamic accessors:
00203 
00204     T operator[](unsigned i) const      // Absolute position
00205     {
00206       precondition(i < Info_::card);
00207       return *(buffer_ + i);
00208     }
00209     T& operator[](unsigned i)
00210     {
00211       precondition(i < Info_::card);
00212       return *(buffer_ + i);
00213     }
00214 
00215     T operator()(int i) const           // Relative position
00216     {
00217       precondition(-Info_::center <= i);
00218       precondition(i <= Info_::card - Info_::center - 1);
00219       return *(buffer_ + Info_::center + i);
00220     }
00221     T& operator()(int i)
00222     {
00223       precondition(-Info_::center <= i);
00224       precondition(i <= Info_::card - Info_::center - 1);
00225       return *(buffer_ + Info_::center + i);
00226     }
00227 
00228 
00229     // do not use these methods...
00230 
00231     template<unsigned i>
00232     T get_at_() const {
00233       lesseq<i, Info_::card>::ensure();
00234       return *(buffer_ + i);
00235     }
00236 
00237     template<int i>
00238     T get_() const {
00239       lesseq<-Info_::center, i>::ensure();
00240       lesseq<i, Info_::card - Info_::center - 1>::ensure();
00241       return *(buffer_ + Info_::center + i);
00242     }
00243 
00244   protected:
00245 
00246     T buffer_[Info_::card];
00247   };
00248 
00249 
00250   // ...but these static accessors:
00251 
00252   template<unsigned i, class Info, class T> inline
00253   T get_at(const array1d<Info, T>& arr)
00254   {
00255     return arr.template get_at_<i>();
00256   }
00257 
00258   template<int i, class Info, class T> inline
00259   T get(const array1d<Info, T>& arr)
00260   {
00261     return arr.template get_<i>();
00262   }
00263 
00264   // starter objects
00265 
00266   // FIXME: what about other types? Replace this by a function
00267   // returning a starter.
00268 
00269 # define array1d_starter(T) \
00270   static internal::array1d_start_<T >   T##s_1d   = internal::array1d_start_<T >()
00271 
00272   array1d_starter(int);         // ints_1d
00273   array1d_starter(float);       // floats_1d
00274 
00275 
00276 
00277   // print
00278 
00279   template<class Info, class T>
00280   std::ostream& operator<<(std::ostream& ostr, const array1d<Info, T>& rhs)
00281   {
00282     for (int i = 0; i < Info::card; ++i)
00283       if (i == Info::center)
00284         ostr << "<" << rhs[i] << "> ";
00285       else
00286         ostr << rhs[i] << " ";
00287     ostr << std::endl;
00288 
00289     return ostr;
00290   }
00291 
00292 } // end of mlc
00293 
00294 #endif // ! METALIC_ARRAY_1D_HH

Generated on Thu Apr 15 20:13:04 2004 for Olena by doxygen 1.3.6-20040222