libidx
/home/rex/ebltrunk/core/libidx/include/idx.h
00001 /***************************************************************************
00002  *   Copyright (C) 2011 by Yann LeCun and Pierre Sermanet *
00003  *   yann@cs.nyu.edu, pierre.sermanet@gmail.com *
00004  *   All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Redistribution under a license not approved by the Open Source
00014  *       Initiative (http://www.opensource.org) must display the
00015  *       following acknowledgement in all advertising material:
00016  *        This product includes software developed at the Courant
00017  *        Institute of Mathematical Sciences (http://cims.nyu.edu).
00018  *     * The names of the authors may not be used to endorse or promote products
00019  *       derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00023  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00024  * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY
00025  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00028  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00029  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  ***************************************************************************/
00032 
00033 #ifndef IDX_H
00034 #define IDX_H
00035 
00036 #include <stdio.h>
00037 #include "defines.h"
00038 #include "srg.h"
00039 #include "stl.h"
00040 #include "idxspec.h"
00041 #include "idxiter.h"
00042 #include "smart.h"
00043 
00044 namespace ebl {
00045 
00047 
00051   template <class T> class idx : public smart_pointer {
00052   public:
00053     // basic constructors/destructor ///////////////////////////////////////////
00054 
00056     virtual ~idx();
00059     idx(int n, intg *dims, intg *mods);
00061     idx(const idx<T>& other);
00062 
00063     // constructors initialized with an array //////////////////////////////////
00064 
00067     idx(const T *mat, intg s0, intg s1);
00070     idx(const T *mat, intg s0, intg s1, intg s2);
00071 
00072     // specific constructors for each number of dimensions /////////////////////
00073 
00075     idx();
00077     idx(intg size0);
00079     idx(intg size0, intg size1);
00081     idx(intg size0, intg size1, intg size2);
00083     idx(intg s0, intg s1, intg s2, intg s3, intg s4=-1, intg s5=-1, intg s6=-1,
00084         intg s7=-1);
00086     idx(const idxdim &d);
00087 
00088     // constructors from existing srg and offset ///////////////////////////////
00089 
00091     idx(srg<T> *srg, idxspec &s);
00093     idx(srg<T> *srg, intg o, intg n, intg *dims, intg *mods);
00095     idx(srg<T> *srg, intg o);
00097     idx(srg<T> *srg, intg o, intg size0);
00100     idx(srg<T> *srg, intg o, intg size0, intg size1);
00103     idx(srg<T> *srg, intg o, intg size0, intg size1, intg size2);
00105     idx(srg<T> *srg, intg o, intg s0, intg s1, intg s2, intg s3, intg s4=-1,
00106         intg s5=-1, intg s6=-1, intg s7=-1);
00108     idx(srg<T> *srg, intg o, const idxdim &d);
00109 
00110     // operators ///////////////////////////////////////////////////////////////
00111 
00112     // TODO: Find out why code such as idx<float> = 1 compiles
00113     // (even without default operator below).
00114     // default operator below outputs an error that this is forbidden.
00115     virtual idx<T>& operator=(T other);
00117     virtual idx<T>& operator=(const idx<T>& other);
00120     virtual idx<T> operator[](const intg i);
00121 
00122     // resize methods //////////////////////////////////////////////////////////
00123 
00125     virtual void add_offset(intg n);
00128     virtual intg setoffset(intg o);
00133     virtual void resize(intg s0=-1, intg s1=-1, intg s2=-1, intg s3=-1,
00134                         intg s4=-1, intg s5=-1, intg s6=-1, intg s7=-1);
00139     virtual void resize(const idxdim &d);
00143     virtual void resize1(intg dimn, intg size);
00148     virtual void resize_chunk(intg s_chunk, intg s0=-1, intg s1=-1, intg s2=-1,
00149                               intg s3=-1, intg s4=-1, intg s5=-1, intg s6=-1,
00150                               intg s7=-1);
00151 
00152     // idx manipulation methods ////////////////////////////////////////////////
00153 
00158     idx<T> select(int d, intg i);
00166     idx<T> narrow(int d, intg s, intg o);
00171     idx<T> transpose(int d1, int d2);
00179     idx<T> transpose(int *p);
00186     virtual idx<T> unfold(int d, intg k, intg s);
00195     // TODO: forbid this function as it conflicts with the forbidden
00196     // order-change rule? unfold also conflicts with this rule?
00197     idx<T> view_as_order(int n);
00203     idx<T> shift_dim(int d, int pos);
00204 
00207 
00209     virtual srg<T> *getstorage() { return storage; }
00211     virtual intg dim(int d) const { return spec.dim[d]; }
00213     virtual const intg* dims(){ return spec.dim; }
00215     virtual intg mod(int d) const { return spec.mod[d]; }
00217     virtual const intg* mods(){ return spec.mod; }
00219     virtual int order() const { return spec.ndim; }
00221     virtual intg offset() { return spec.offset; }
00223     virtual intg nelements() const { return spec.nelements(); }
00226     virtual intg footprint() const { return spec.footprint(); }
00229     virtual bool contiguousp() const { return spec.contiguousp(); }
00230 
00233     //  T &operator*() {
00234     //    if (spec.ndim==0) {
00235     //      return *(storage->data + spec.offset);
00236     //    }else { eblerror("idx::operator*: only an idx0 can be dereferenced");}
00237     //  }
00238 
00241     virtual bool same_dim(const idxdim &d);
00244     virtual bool same_dim(intg s0, intg s1, intg s2, intg s3, intg s4, intg s5,
00245                           intg s6, intg s7);
00248     virtual idxdim& get_idxdim();
00253     virtual idxdim get_idxdim() const;
00254 
00255     // data access methods /////////////////////////////////////////////////////
00256 
00258     virtual T *idx_ptr();
00260     virtual const T *idx_ptr() const;
00262     virtual intg *mod_ptr();
00263     
00265     virtual T *ptr();
00267     virtual T *ptr(intg i0);
00269     virtual T *ptr(intg i0, intg i1);
00271     virtual T *ptr(intg i0, intg i1, intg i2);
00273     virtual T *ptr(intg i0, intg i1, intg i2, intg i3, intg i4=-1, intg i5=-1,
00274                    intg i6=-1, intg i7=-1);
00275 
00277     virtual T get() const;
00279     virtual T& get(intg i0) const;
00281     virtual T get(intg i0, intg i1) const;
00283     virtual T get(intg i0, intg i1, intg i2) const;
00285     virtual T get(intg i0, intg i1, intg i2, intg i3, intg i4=-1,
00286                   intg i5=-1, intg i6=-1, intg i7=-1);
00293     virtual T gget(intg i0=0, intg i1=0, intg i2=0, intg i3=0, intg i4=0,
00294                   intg i5=0, intg i6=0, intg i7=0);
00295 
00297     virtual T set(T val);
00299     virtual T set(T val, intg i0);
00301     virtual T set(T val, intg i0, intg i1);
00303     virtual T set(T val, intg i0, intg i1, intg i2);
00305     virtual T set(T val, intg i0, intg i1, intg i2, intg i3, intg i4=-1,
00306                   intg i5=-1, intg i6=-1, intg i7=-1);
00313     virtual T sset(T val, intg i0=0, intg i1=0, intg i2=0, intg i3=0, intg i4=0,
00314                    intg i5=0, intg i6=0, intg i7=0);
00315 
00316     // print methods ///////////////////////////////////////////////////////////
00317 
00319     //friend std::ostream& operator<<(std::ostream& out, idx<T>& tensor );
00320 
00322     virtual void pretty() const;
00324     virtual void pretty(std::ostream& out) const;
00326     virtual void pretty(FILE *) const;
00327 
00329     virtual void print() const;
00330     virtual std::string str() const;
00331     virtual void printElems() const;
00332     virtual void printElems(std::ostream& out, bool newline = true) const;
00333     virtual void printElems(std::string& out, bool newline = true) const;
00334     // void printElems( FILE* out );  doesn't work (cf implementation)
00335 
00337     virtual int fdump(std::ostream &f);
00338 
00339     // friends /////////////////////////////////////////////////////////////////
00340     template <class T2> friend class idxiter;
00341     template <class T2> friend class idxlooper;
00342     template <class T2> friend class contiguous_idxiter;
00343     template <class T2> friend class noncontiguous_idxiter;
00344 
00345     // protected methods ///////////////////////////////////////////////////////
00346   protected:
00348     void growstorage();
00350     void growstorage_chunk(intg s_chunk);
00352     template <class stream>
00353       void printElems_impl(int indent, stream&, bool newline = true) const;
00356     idx(dummyt *dummy);
00357 
00358     // members variables ///////////////////////////////////////////////////////
00359   public:
00360     idxspec spec; 
00361   protected:
00362     srg<T> *storage; 
00363 
00364 
00365 
00366     idxdim *pidxdim;
00367     idxd<intg> idd;
00368   };
00369 
00370   // midx //////////////////////////////////////////////////////////////////////
00371 
00376   template <typename T>
00377     class midx : public idx<idx<T>*> {
00378   public:
00383     midx(intg size, std::file *fp = NULL, idx<int64> *offsets = NULL);
00388     midx(intg size0, intg size1,
00389          std::file *fp = NULL, idx<int64> *offsets = NULL);
00394     midx(idxdim &d, std::file *fp = NULL, idx<int64> *offsets = NULL);
00396     midx();
00398     //    midx(const idx<idx<T>*> &o);
00399     midx(const midx<T> &o);
00401     virtual ~midx();
00402 
00404     virtual midx<T>& operator=(const midx<T>& other);
00405 
00406     // resizing ////////////////////////////////////////////////////////////////
00407 
00410     void resize(intg i0);
00413     void resize(intg i0, intg i1);
00415     void resize(midx<T> &other);
00416 
00417     // deletions ///////////////////////////////////////////////////////////////
00418 
00420     void remove(intg i0);
00422     void remove(intg i0, intg i1);
00424     void clear();
00425 
00426     // accessors ///////////////////////////////////////////////////////////////
00427 
00429     void set(idx<T> &e, intg i0);
00431     void set(idx<T> &e, intg i0, intg i1);
00434     idx<T> get(intg i0);
00437     idx<T> get(intg i0, intg i1);
00438 
00440     midx<T> narrow(int d, intg s, intg o);
00442     midx<T> select(int d, intg s);
00444     bool exists(intg pos) const;
00447     bool exists(intg i0, intg i1) const;
00450     idxdim get_maxdim();
00453     virtual bool same_dim(const midx<T> &other) const;
00455     idx<int64> get_offsets();
00457     std::file *get_file_pointer();
00459     virtual intg nelements_all() const;
00460 
00466     virtual idx<T> pack();
00467 
00469     virtual void shift_dim_internal(int d, int pos);
00470 
00472     virtual void pretty() const;
00474     template <class stream> void pretty(stream &out, bool newline = true) const;
00476     virtual std::string str() const;
00477 
00478     // internal methods ////////////////////////////////////////////////////////
00479   protected:
00482     void lock_all();
00484     void unlock_all();
00485 
00486     // members /////////////////////////////////////////////////////////////////
00487   protected:
00488     std::file *fp; 
00489     idx<int64> offsets; 
00490   };
00491 
00492   // stream printing ///////////////////////////////////////////////////////////
00493 
00495   template <class T>
00496     std::ostream& operator<<(std::ostream& out, const idx<T>& m);
00498   template <class T>
00499     std::string& operator<<(std::string& out, idx<T>& m);
00501   template <class T>
00502     std::string& operator<<(std::string& out, idx<T>* m);
00503 
00505   template <typename T, class stream>
00506     stream& operator<<(stream& out, midx<T>& m);
00507 
00508   // debugging /////////////////////////////////////////////////////////////////
00509 
00510 #ifdef __DEBUGMEM__
00511 
00512 #define INIT_DEBUGMEM()                                                 \
00513   /* memsize */                                                         \
00514   template <typename T> ebl::intg ebl::srg<T>::memsize = 0;             \
00515   template <> EXPORT ebl::intg ebl::srg<double>::memsize = 0;           \
00516   template <> EXPORT ebl::intg ebl::srg<float>::memsize = 0;            \
00517   template <> EXPORT ebl::intg ebl::srg<int>::memsize = 0;              \
00518   template <> EXPORT ebl::intg ebl::srg<long>::memsize = 0;             \
00519   template <> EXPORT ebl::intg ebl::srg<unsigned long>::memsize = 0;    \
00520   template <> EXPORT ebl::intg ebl::srg<short>::memsize = 0;            \
00521   template <> EXPORT ebl::intg ebl::srg<unsigned char>::memsize = 0;    \
00522   template <> EXPORT ebl::intg ebl::srg<signed char>::memsize = 0;      \
00523   template <> EXPORT ebl::intg ebl::srg<unsigned short>::memsize = 0;   \
00524   template <> EXPORT ebl::intg ebl::srg<ebl::idx<float>*>::memsize = 0; \
00525   template <> EXPORT ebl::intg ebl::srg<ebl::idx<unsigned char>*>::memsize = 0; \
00526   template <> EXPORT ebl::intg ebl::srg<const char*>::memsize = 0;      \
00527   template <> EXPORT ebl::intg ebl::srg<void *>::memsize = 0;           \
00528   template <> EXPORT ebl::intg ebl::srg<bool>::memsize = 0;             \
00529   template <> EXPORT ebl::intg ebl::srg<uint>::memsize = 0;             \
00530   /* locks */                                                           \
00531   EXPORT ebl::intg ebl::smart_pointer::locks = 0;                       \
00532   EXPORT ebl::intg ebl::smart_pointer::spointers = 0;
00533 
00535   EXPORT void pretty_memory(const char *prefix = "");
00536 
00537 #define DEBUGMEM_PRETTY(prefix) {               \
00538     std::string pf; pf << prefix;               \
00539     pretty_memory(pf.c_str());                  \
00540 }
00541 
00542 #else
00543 #define INIT_DEBUGMEM()
00544 #define DEBUGMEM_PRETTY(prefix)
00545 #endif
00546 
00547 
00548 } // end namespace ebl
00549 
00550 #include "idx.hpp"
00551 
00552 #endif /* IDX_H_ */