📄 idx.h
字号:
//! Pretty-prints IDx metadata to a file pointer. virtual void pretty(FILE *); virtual void pretty(std::ostream& out); //! Pretty-prints elements to a stream. virtual void printElems(); // calls printElems( std::cout ); virtual void printElems( std::ostream& out ); // void printElems( FILE* out ); doesn't work (cf implementation) //! destructor: unlocks the Srg. virtual ~Idx(); // TODO: Find out why code such as Idx<float> = 1 compiles // (even without default operator below). // default operator below outputs an error that this is forbidden. virtual Idx<T>& operator=(T other){ ylerror("Forbidden Idx assignment. Idx can only be assigned another Idx."); return *this; } virtual Idx<T>& operator=(const Idx<T>& other) { Srg<T> *tmp = NULL; if (this->storage != NULL) tmp = this->storage; this->storage = other.storage; this->spec = other.spec; this->storage->lock(); if (tmp) tmp->unlock(); return *this; } virtual Idx<T> operator[](const intg i) { return this->select(0,i); } //! Copy constructor. Prevents implcit calls via '='. // Keep this 'explicit' until we decide to implement operator=. //Idx( Idx<T>& other ); //Idx( const Idx<T>& other ); //! generic constructor with IdxSpec. Idx(Srg<T> *srg, IdxSpec &s); //! constructor without offset: appends to current storage. Idx(Srg<T> *srg, int n, intg *dims, intg *mods); //! generic constructor with dims and mods creates //! the storage and set offset to zero. Idx(int n, intg *dims, intg *mods); //! specific constructors for each number of dimensions //! creates an Idx0 with existing Srg and offset. Idx(Srg<T> *srg, intg o); //! creates an Idx0 from scratch; Idx(); Idx( const Idx<T>& other ) :storage(other.storage), spec(other.spec) { storage->lock(); } // create an Idx0 and fill it with val. // removed because ambiguous. // Idx(T val); //! creates an Idx1 of size size0, with existing Srg and offset. Idx(Srg<T> *srg, intg o, intg size0); //! creates an Idx1 of size size0. Idx(intg size0); //! creates an Idx2 of size (size0,size1), //! with existing Srg and offset. Idx(Srg<T> *srg, intg o, intg size0, intg size1); //! creates an Idx2 of size (size0,size1). Idx(intg size0, intg size1); //! creates an Idx3 of size (size0,size1,size2), //! with existing Srg and offset. Idx(Srg<T> *srg, intg o, intg size0, intg size1, intg size2); //! creates an Idx3 of size (size0,size1,size2). Idx(intg size0, intg size1, intg size2); //! creates an Idx of any order with existing Srg and offset. Idx(Srg<T> *srg, intg o, intg s0, intg s1, intg s2, intg s3, intg s4=-1, intg s5=-1, intg s6=-1, intg s7=-1); //! creates an Idx of any order. Idx(intg s0, intg s1, intg s2, intg s3, intg s4=-1, intg s5=-1, intg s6=-1, intg s7=-1); //! change the offset of an Idx. The Storage is //! resized accordingly. Returns the new offset. virtual intg setoffset(intg o); //! resize an Idx. The order (ndim) is not allowed to change. //! This is to prevent nasty bugs. virtual void resize(intg s0=-1, intg s1=-1, intg s2=-1, intg s3=-1, intg s4=-1, intg s5=-1, intg s6=-1, intg s7=-1); //! same as resize, but the storage is enlarged by a step of s_chunk if needed virtual void resize_chunk(intg s_chunk, intg s0=-1, intg s1=-1, intg s2=-1, intg s3=-1, intg s4=-1, intg s5=-1, intg s6=-1, intg s7=-1); /** * Resizes the Idx using the dimension sizes listed * in a sequence. * @param sizesBegin: An iterator type, points to beginning of size list. * @param sizesEnd: An iterator type, points to one past the last size. */ template<typename SizeIter> void resize( SizeIter& sizesBegin, SizeIter& sizesEnd ){ const int ndims = std::distance( sizesBegin, sizesEnd ); if ( ndims > MAXDIMS ){ std::ostringstream oss; oss<<"Number of dimensions ("<<ndims<<") exceeds MAX_DIMS ("<<MAXDIMS<<")"; ylerror(oss.str().c_str()); } std::vector<T> sizes(ndims+1); std::copy(sizesBegin, sizesEnd, sizes.begin()); sizes.back() = -1; spec.resize( sizesBegin, sizesEnd ); growstorage(); } //! select: return a new Idx corresponding to //! a slice of the current Idx with slice i //! in dimension d. In other words, if m is an //! Idx of order 2 of size (10,4), the call //! Idx p = m.select(0,3) will set p to //! an Idx or order 1 containing the 4-th //! row of m. Idx<T> select(int d, intg i); //! narrow: return a new Idx in which the d-th //! dimension has been reduced to size s, starting //! at item o. In other words, if m is an //! Idx of order 2 of size (10,4), the call //! Idx p = m.narrow(0,6,2) will set p to //! an Idx or order 2 of size (6,4) whose rows //! are rows 2 to 7 of m. Idx<T> narrow(int d, intg s, intg o); //! Return an new Idx in which dimensions //! d1 and d2 are transposed. No data is actually //! moved around, this merely manipulates the Idx //! structure itself. Idx<T> transpose(int d1, int d2); //! Return an new Idx in which the dimensions //! are permuted using the permutation vector p. //! For example, if m is an idx of size (2,4,6), //! int p[] = {1,2,0}; m.transpose(p); //! returns an Idx of size (4,6,2). No data is actually //! moved around, this merely manipulates the Idx //! structure itself. Idx<T> transpose(int *p); //! Return a new Idx prepared for a convolution. //! Returns an idx on the same storage as m (pointing to the //! same data) with an added dimension at the end obtained by //! "unfolding" the n -th dimension. The size of the new dimension //! is k. This essentially manipulates the mod array to make //! convolutions look like matrix-vector multiplies. virtual Idx<T> unfold(int d, intg k, intg s); // field access //! return pointer to storage virtual Srg<T> *getstorage() { return storage; } //! return size of Idx in d-th dimension. virtual intg dim(int d) { return spec.dim[d]; } //! return const ptr to dims virtual const intg* dims(){ return spec.dim; } //! return stride of Idx in d-th dimension. virtual intg mod(int d) { return spec.mod[d]; } //! return const ptr to mods virtual const intg* mods(){ return spec.mod; } //! return order of Idx (number of dimensions). virtual int order() { return spec.ndim; } //! return offset of Idx. virtual intg offset() { return spec.offset; } //! return total number of elements virtual intg nelements() { return spec.nelements(); } //! return total footprint in the storage //! (index after last cell occupied in the storage) virtual intg footprint() { return spec.footprint(); } //! return true if elements of Idx are //! contiguous in memory. virtual bool contiguousp() { return spec.contiguousp(); } //! return element if this is an Idx0, //! otherwise generate an error// T &operator*() {// if (spec.ndim==0) {// return *(storage->data + spec.offset);// } else { ylerror("Idx::operator*: only an Idx0 can be dereferenced"); }// } //! return pointer on data chunk (on first element) virtual T *idx_ptr() { return storage->data + spec.offset; } //! return a pointer to an element (Idx0 version) virtual T *ptr() { if (spec.ndim != 0) ylerror("not an Idx0"); return storage->data + spec.offset; } //! return a pointer to an element (Idx1 version) virtual T *ptr(intg i0); //! return a pointer to an element (Idx2 version) virtual T *ptr(intg i0, intg i1); //! return a pointer to an element (Idx3 version) virtual T *ptr(intg i0, intg i1, intg i2); //! return a pointer to an element (generic version) virtual T *ptr(intg i0, intg i1, intg i2, intg i3, intg i4=-1, intg i5=-1, intg i6=-1, intg i7=-1); //! return the value of an element (Idx0 version) virtual T get(); //! return the value of an element (Idx1 version) virtual T get(intg i0); //! return the value of an element (Idx2 version) virtual T get(intg i0, intg i1); //! return the value of an element (Idx3 version) virtual T get(intg i0, intg i1, intg i2); //! return the value of an element (generic version) virtual T get(intg i0, intg i1, intg i2, intg i3, intg i4=-1, intg i5=-1, intg i6=-1, intg i7=-1); //! sets the value of an element (Idx0 version) virtual T set(T val); //! sets the value of an element (Idx1 version) virtual T set(T val, intg i0); //! sets the value of an element (Idx2 version) virtual T set(T val, intg i0, intg i1); //! sets the value of an element (Idx3 version) virtual T set(T val, intg i0, intg i1, intg i2); //! sets the value of an element (generic version) virtual T set(T val, intg i0, intg i1, intg i2, intg i3, intg i4=-1, intg i5=-1, intg i6=-1, intg i7=-1); //! print content of Idx on stream virtual int fdump(FILE *f);#if USING_STL_ITERS == 0 // horrible syntax again. This time we have to // use U for type symbol otherwise the compiler // complains about T. template <class U> friend class IdxIter; template <class U> friend class IdxLooper;#endif};} // end namespace ebl#include "IdxIterators.h"namespace ebl {#if USING_STL_ITERS == 0////////////////////////////////////////////////////////////////// Idx Iterators are a subclass of Idx//! IdxLooper: a kind of iterator used by bloop//! and eloop macros. IdxLooper is a subclass of Idx,//! It is used as follows://! for (IdxLooper z(&idx,0); z.notdone(); z.next()) { .... }template <class T> class IdxLooper : public Idx<T> { public: intg i; // loop index intg dimd; // number of elements to iterated upon intg modd; // stride in dimension being iterated upon //! generic constructor loops over dimensin ld IdxLooper(Idx<T> &idx, int ld); //! return true if loop is over bool notdone(); //! increment to next item. Return pointer to data. T *next(); void operator++();};////////////////////////////////////////////////////////////////// Idx Iterators: gives you a pointer to the actual data,// unlike IdxLooper which gives you another Idx.//! IdxIter allows to iterate over all elements of an Idx.//! Although it can be used directly, it is easier to use//! it with the idx_aloopX macros. Example://! IdxIter<double> idx;//! for ( idx.init(m); idx.notdone(); idx.next() ) {//! printf("%g ",*idx);//! }//! Here is an example that uses the aloop macro to fill up//! an Idx with numbers corresponding to the loop index://! IdxIter<double> idx;//! idx_aloop_on(idx,m) { *idx = idx.i; }//! At any point during the loop, the indices of the element//! being worked on is stored in idx.d[k] for k=0//! to idx.order()-1.template <class T> class IdxIter { public: //! pointer to current item T *data; //! number of elements visited so far (loop index) intg i; //! total number of elements in Idx intg n; //! dimension being looped over int j; //! loop index array for non-contiguous Idx intg d[MAXDIMS]; //! pointer to Idx being looped over. Idx<T> *iterand; //! empty constructor; IdxIter(); //! Initialize an IdxIter to the start of //! the Idx passed as argument. T *init(Idx<T> &idx); //! Return true while the loop is not completed bool notdone(); //! Increments IdxIter to next element T *next(); //! dereferencing operator: returns data item. T& operator*() { return *data; }};////////////////////////////////////////////////////////////////#endif // if USING_STL_ITERS == 0} // end namespace ebl////////////////////////////////////////////////////////////////#include "IdxIterators.hpp"#include "Idx.hpp"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -