// =======================================================================================
// F2_layout.h
// Time-stamp: <2004-03-03 15:22:14 aknoblau>
// Definition of layouts for defining spatial arrangements of elements
// programmed in May 2001 by Andreas Knoblauch
// Department of Neural Information Processing
// University of Ulm, Germany
// Version 1.0 alpha
// last documented change: May 28, 2001
// =======================================================================================
// types/classes/interfaces:
// TLayout
// TCuboidLT
// TProjectionMap
// TMMarray
// ---------------------------------------------------------------------------------------
// global objects:
// ---------------------------------------------------------------------------------------
// related modules:
// ---------------------------------------------------------------------------------------
// notes:
// ---------------------------------------------------------------------------------------
// history:
// Version 1.0 alpha programmed on May 28, 2001 by Andreas Knoblauch
// ---------------------------------------------------------------------------------------
// bugs:
// ---------------------------------------------------------------------------------------
// 2 do:
// =======================================================================================
#ifndef F2_layout_H
#define F2_layout_H
#include "F2_types.h"
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TLayout is the base class for all layouts. A layout specifies how a set of units (for example, a neuron population)
* is spatially arranged. For example, a population of 100 neurons can be arranged as a two-dimensional 10x10 array. For
* this you can create a @ref TCuboid layout by calling the constructor TCuboid(10,10).
*
* Layouts are usually required if you create a neuron population or a connection between two neuron populations.
* For example, class @ref TNeuron expects a TLayout object in its constructors @ref TNeuron#TNeuron
*
* @short base type for layouts for defining spatial arrangements of elements
* @author Andreas Knoblauch
* @version 1.0 alpha,
* last change: May 28, 2001
*/
class TLayout {
// **************************************************************************************************************************
public:
static const int LT_CUBOID = 0; // value for layout type 'cuboid'
static const int LT_ELLIPSOID = 1; // value for layout type 'ellipsoid'
static const int LT_CYLINDER = 2; // value for layout type 'cylinder'
typedef int TLayoutType;
int N; // number of elements to be layed out
TLayoutType type; // type of layout
TLayout(int N_arg, TLayoutType type_arg); // constructor
TLayout(const TLayout& copy); // copy constructor
~TLayout(); // destructor
bool operator==(const TLayout& lt) const; // compare function
bool operator!=(const TLayout& lt) const; // compare function
bool sameSize(const TLayout& lt) const; // as befor but only size fields are compared (i.e. N and size)
virtual bool isOdd() const; // returns 1 <=> all dimensions of layout are odd
virtual bool isOdd(const int* fullDimFlags) const; // returns 1 <=> all dimensions i with !fullDimFlags[i] of layout are odd
template
void outputData(ostream& os, const T* data) const; // pretty output of data according to the layout
template
void outputNumData(ostream& os, const TNum* data, int bin, int packed) const;
void outputState(ostream & os) const; // output of all object fields
};
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TCuboidLT is a cuboid layout. It specifies the spatial arrangement of a set of units (for example, a neuron population)
* in a cuboid. For example, a population of 100 neurons can be arranged as a two-dimensional 10x10 array. For
* this you can create a @ref TCuboid layout by calling the constructor TCuboid(10,10).
*
* @short class for multi-dimensional cuboid layouts (e.g. points, lines, grids, cuboids, etc.)
* @author Andreas Knoblauch
* @version 1.0 alpha,
* last change: May 28, 2001
*/
class TCuboidLT : public TLayout {
// **************************************************************************************************************************
public:
class TPos; // position type; (0,0,...,0) is left upper position!
class TzcPos; // zero centered position type; (0,0,...,0) central position!
int nDim; // number of dimensions of the cuboid layout
int* size; // size of each dimension of the cuboid layout
int* size_s; // size_s[i]=1*size[i+1]*size[i+2]*...*size[nDim-1] for i=0..nDim-1
TFlag closed; // default UNSET; if SET dimensions are handled closed, e.g. pos(0) and pos(N-1) neighbored
TGenericFlag genericNDim; // set GENERIC if nDim is unknown a priori, usually for operator>>()
TGenericFlag genericSize; // set GENERIC if size is unknown a prioir, usually for operator>>() of an descendant
TCuboidLT(); // constructor for 0-dim TCuboidLT
TCuboidLT(int N1); // constructor for 1-dim TCuboidLT
TCuboidLT(int N1, TFlag closed_arg); // constructor for 1-dim TCuboidLT with flag closed
TCuboidLT(int N1, int N2); // constructor for 2-dim TCuboidLT
TCuboidLT(int N1, int N2, TFlag closed_arg); // constructor for 2-dim TCuboidLT with flag closed
TCuboidLT(int N1, int N2, int N3); // constructor for 3-dim TCuboidLT with flag closed
TCuboidLT(int N1, int N2, int N3, TFlag closed_arg); // constructor for 3-dim TCuboidLT
TCuboidLT(int N1, int N2, int N3, int N4); // constructor for 4-dim TCuboidLT with flag closed
TCuboidLT(int N1, int N2, int N3, int N4, TFlag closed_arg); // constructor for 4-dim TCuboidLT
TCuboidLT(int nDim_arg, int* size_arg); // constructor for the general case
TCuboidLT(int nDim_arg, int* size_arg, TFlag closed_arg); // constructor for the general case with flag closed
TCuboidLT(TGenericFlag genericNDim_arg); // constructor where genericNDim/genericSize are usually set GENERIC
TCuboidLT(int nDim_arg, TGenericFlag genericSize_arg); // constructor with FIXED genericNDim, but usually GENERIC genericSize
TCuboidLT(const TCuboidLT& copy); // copy constructor
TCuboidLT(const TCuboidLT& copy, int nDim_arg, int* size_arg); // copy constructor where nDim and size are resized
~TCuboidLT(); // destructor
void operator=(const TCuboidLT& copy); // copy function
bool operator==(const TCuboidLT& lt) const; // compare function
bool operator!=(const TCuboidLT& lt) const; // compare function
bool sameSize(const TCuboidLT& lt) const; // as befor but only size fields are compared (i.e. N and size)
void resize(int nDim_arg); // change nDim to nDim_arg, size is pre-initialized with ones
void resize(int* size_arg); // let nDim the same, but change size to size_arg
void resize(int nDim_arg, int* size_arg); // change nDim to nDim_arg and size to size_arg
inline int index(int* idx) const; // get 1D-index
inline int index(int idx, int* relpos) const; // get 1D-index as summation of idx and relativ position relpos
inline int index(int idx) const; // get 1D-index
inline int index(int idx1, int idx2) const; // get 1D-index
inline int index(int idx1, int idx2, int idx3) const; // get 1D-index
inline int index(int idx1, int idx2, int idx3, int idx4)const; // get 1D-index
inline int* indexPos(int idx) const; // get position of index idx (inverse of index())
inline int* indexPos(int idx, int* pos) const; // get position of index idx; pos must be allocated
virtual bool isOdd() const; // returns true <=> size[i] is odd for all i
virtual bool isOdd(const int* fullDimFlags) const; // returns true <=> all dimensions with !fullDimFlags[i] are odd
template
void outputData(ostream& os, const T* data) const; // pretty output of data according to the layout
template
void outputNumData(ostream& os, const T* data, int bin, int packed) const;
void outputState(ostream & os) const; // output all fields of this object
static int* getSizeBuffer(int i1); // delivers int array {i1} for size_arg in constructors
static int* getSizeBuffer(int i1, int i2); // delivers int array {i1,i2} for size_arg in constructors
static int* getSizeBuffer(int i1, int i2, int i3); // delivers int array {i1,i2,i3} for size_arg in constructors
static int* getSizeBuffer(int i1, int i2, int i3, int i4); // delivers int array {i1,i2,i3,i4} for size_arg in constructors
static int getTotalSize(int nDim_arg, int* size_arg); // delivers size_arg[0]*size_arg[1]*...*size_arg[nDim_arg-1]
friend ostream& operator<<(ostream& os, const TCuboidLT& par); // output operator
friend istream& operator>>(istream& os, TCuboidLT& par); // input operator
protected:
static const int lenSizeBuffer=4; // length of sizeBuffer;
static int sizeBuffer[lenSizeBuffer]; // buffer for Marray size, see getSizeBuffer()
};
ostream& operator<<(ostream& os, const TCuboidLT& par); // output operator
istream& operator>>(istream& os, TCuboidLT& par); // input operator
class TCuboidLT::TPos {
public:
const TCuboidLT& cLT;
const int& nDim;
int* pos; // nDim-dimensional position within cuboid relative to upper left position
int idx; // index corresponding to pos
TPos(const TCuboidLT& cLT_arg); // constructor
~TPos(); // destructor
inline void setZero(); // set to first position
inline void inc(); // set to next position
inline void dec(); // set to previous position
inline bool first() {return idx==0;} // true <=> first index position
inline bool last() {return idx==(cLT.N-1);} // true <=> last index position
inline bool equal(TPos& p) {return idx==p.idx;} // true <=> same index position as p
void outputState(ostream& os); // output of complete object state
void outputState(ostream& os, int complete); // output of complete object state
protected:
// auxiliary variables for more efficient computation (e.g. see incIndexPos())
int& leafPos; // reference to pos[nDim-1]
int& leafSize; // referenece to cLT.size[nDim-1]
};
class TCuboidLT::TzcPos {
public:
const TCuboidLT& cLT;
const int& nDim;
int* fullDimFlags; // full dimension flags (see F2_kernel)
int* from; // for each dimension the start position, i.e. from[i]=-cLT.size[i]/2 for non-full dimensions
int* to ; // for each dimension the end position, i.e. to[i]=cLT.size[i]/2 for non-full dimensions
int* centers; // center positions (only defined for non-full dimensions!!!)
int* pos; // nDim-dimensional position within ellipsoid relative to central position
int idx; // index corresponding to pos
TzcPos(const TCuboidLT& cLT_arg); // constructor; cLT_arg.isOdd() must be true!
TzcPos(const TCuboidLT& cLT_arg, int* fullDimFlags_arg); // constructor; cLT_arg.isOdd(fullDimFlags) must be true!
~TzcPos(); // destructor
inline void setZero(); // set to first position
inline void inc(); // set to next position
inline void dec(); // set to previous position
inline bool first() {return idx==0;} // true <=> first index position
inline bool last() {return idx==(cLT.N-1);} // true <=> last index position
inline bool equal(TPos& p) {return idx==p.idx;} // true <=> same index position as p
void outputState(ostream& os); // output of complete object state
void outputState(ostream& os, int complete); // output of complete object state
protected:
// auxiliary variables for more efficient computation (e.g. see incIndexPos())
int& leafPos; // reference to pos[nDim-1]
int& leafFrom; // referenece to centers[nDim-1]
int& leafTo; // referenece to centers[nDim-1]
};
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TEllipsoidLT/TMEllipsoidLT
* classes for multi-dimensional ellipsoid layouts (e.g. for kernels)
* definition of a ellipsoid subspace of a TCuboidLT
* all dimensions must be odd (therefore a central point can be defined along each dimension)
* border is determined by a1*x1^2 + a2*x2^2 + ... + an*xn^2 = 1, see AB1/69 p.88 and AB2/43 p.152
* TEllispoidLT is implemented by template TMEllipsoid
* It is recommended to use only TEllipsoidLT since some derived classes that access layouts via TLayout (e.g. TKernel)
* rely on the standard types TNum=TFloat and TNumRadius=TInt.
* @short definition of a ellipsoid subspace of a @ref TCuboidLT
*
* @author Andreas Knoblauch
* @version 1.0 alpha,
* last change: July 16, 2001
*/
template
class TMEllipsoidLT : public TLayout {
// **************************************************************************************************************************
public:
class TPos; // defines position manipulaiton within an ellipsoid; (0,0,...0) is center!
TCuboidLT cuboid; // ellipsoid is within this cuboid
int &nDim, *&size; // references to cuboid
int *centers; // index of central position for each dimension (all dimensions must be odd!!)
int *rest; // rest[i]=size[i]-centers[i]-1 (auxiliary variables)
TNum thresh; // threshold for inside/outside decision in ellipse equation (1+eps)
TNum *a; // factors to check if a point is inside or outside the ellipsoid
TNum a0,a1,a2; // short-cut for a[0],a[1],a[2]
int* radiusSize; // for each dimension radius size (cf. AB2/43 p.154)
TNumRadius **radius; // for each dimension radius array
int **tree; // tree[d][i] points to the starting radius[d+1][tree[d][i]] of expansion of radius[d][i] (d=0..nDim-2)
TMEllipsoidLT(const TCuboidLT& cuboid_arg, TNum eps); // constructor
TMEllipsoidLT(const TCuboidLT& cuboid_arg); // constructor (eps=0)
TMEllipsoidLT(const TMEllipsoidLT& copy); // copy constructor
~TMEllipsoidLT(); // destructor
void operator=(const TMEllipsoidLT& copy); // copy function
bool operator==(const TMEllipsoidLT& lt) const;// compare function
bool operator!=(const TMEllipsoidLT& lt) const;// compare function
bool sameSize(const TMEllipsoidLT& lt) const; // as befor but only size fields are compared (i.e. N and size)
void resize(const TCuboidLT& cuboid_arg); // resize to new cuboid layout
inline bool inside(int *pos); // returns TRUE if pos is inside the ellipse
inline bool inside(int pos0); // as befor, but for simpler 1D case
inline bool inside(int pos0, int pos1); // as befor, but for simpler 2D case
inline bool inside(int pos0, int pos1, int pos2); // as befor, but for simpler 3D case
inline int index(int* pos, TPos& pos1) const; // get 1D-index, updates pos1, so far rather unefficient!
inline int index(int idx, int* relpos, TPos& pos1) const; // get 1D-index as summation of idx and relative position
inline int index(int idx, TPos& pos1) const; // get 1D-index, updates pos1, so far rather unefficient!
inline int index(int idx1,int idx2, TPos& pos1) const; // get 1D-index, updates pos1, so far rather unefficient!
inline int index(int idx1,int idx2,int idx3, TPos& pos1) const; // get 1D-index, updates pos1, so far rather unefficient!
inline int index(int idx1,int idx2,int idx3,int idx4, TPos& pos1) const; // get 1D-index, updates pos1, so far rather unefficient!
inline TPos& indexPos(int idx, TPos& pos ) const; // get position of index idx (inverse of index())
virtual bool isOdd() const; // returns true <=> size[i] is odd for all i
virtual bool isOdd(const int* fullDimFlags) const; // returns true <=> all dimensions with !fullDimFlags[i] are odd
template
void cuboid2ellipsoid(const T* cuboidData, T* ellipsoidData) const; // transform cuboid data to ellipsoid data
template
void ellipsoid2cuboid(const T* ellipsoidData, T* cuboidData, T empty) const; // transform ellipsoid data to cuboid with zero symbol
template
void cuboid2ellipsoidNum(const TNum1* cuboidData, TNum1* ellipsoidData, int packed) const; // same as befor, for numerical data
template
void ellipsoid2cuboidNum(const TNum1* ellipsoidData, TNum1* cuboidData, int packed) const; // same as befor, for numerical data
template
void outputData(ostream& os, const T* data) const; // pretty output of data according to the layout
template
void outputNumData(ostream& os, const TNum1* data, int bin, int packed) const;
void outputState(ostream & os) const; // output all fields of this object
void outputState(ostream & os, int complete) const; // if (complete==0) only output of most important fields
protected:
void deallocate(); // deallocate memory
};
template
class TMEllipsoidLT::TPos {
public:
const TMEllipsoidLT& eLT;
const int& nDim;
int* pos; // nDim-dimensional position within ellipsoid relative to centers
int* rpos; // position within radius corresponding to pos
int* dflg; // direction flags indicate in which direction the radius arrays are scanned
int idx; // index corresponding to pos
int idxCuboid; // index corresponding to a cuboid layout
TPos(const TMEllipsoidLT& eLT_arg); // constructor
~TPos(); // destructor
inline void setZero(); // set to first position
inline void inc(); // set to next position
inline void dec(); // set to previous position
inline bool first() {return idx==0;} // true <=> first index position
inline bool last() {return idx==(eLT.N-1);} // true <=> last index position
inline bool equal(TPos& p) {return idx==p.idx;} // true <=> same index position as p
void outputState(ostream& os); // output of complete object state
void outputState(ostream& os, int complete); // output of complete object state
protected:
// auxiliary variables for more efficient computation (e.g. see incIndexPos())
int& leafPos; // reference to pos[nDim-1]
int& leafRPos; // reference to rpos[nDim-1]
int& leafDFlg; // reference to dflg[nDim-1]
const int& leafRest; // reference to eLT.rest[nDim-1]
const int& leafRadiusSize; // reference to eLT.radiusSize[nDim-1]
const TNumRadius*& leafRadiusArray; // reference to eLT.radius[nDim-1]
TNumRadius leafRadius; // must be dynamically(!) updated to eLT.radius[nDim-1][leafRPos]
};
typedef TMEllipsoidLT TEllipsoidLT; // use this type if possible, and not the template!
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TProjectionMap is a class containing information about the projection from one set of items to another.
* For example, it may be necessary, to implement a connection from a 10x10 array of neurons to another
* array of 20x20 neurons. The first neuron array (or neuron population) is the address population, the second one
* the target population. A TProjectionMap contains for each address neuron the target neuron at the center of
* its projection field. For example neuron (2,2) in the 10x10 array will be mapped (approximately) to neuron (4,4) in the
* target 20x20 array.
*
* @short projection information for two TCuboidLT layouts
* @author Andreas Knoblauch
* @version 1.0 alpha,
* last change: June 8, 2001
*/
class TProjectionMap {
// **************************************************************************************************************************
public:
static const int EFFERENT=0; // map refers to the direction of address to target
static const int AFFERENT=1; // map refers to the direction of target from address
int direction; // either EFFERENT or AFFERENT; default value is EFFERENT
TCuboidLT addressLT; // layout of address population
TCuboidLT targetLT; // layout of target population
TCuboidLT *mapLT; // points either to addressLT (direction==EFFERENT) or targetLT (AFFERENT)
TCuboidLT *mappedLT; // points either to targetLT (direction==EFFERENT) or addressLT (AFFERENT)
int& nDim; // number of dimensions in the topographic areas (reference to addressLT.nDim)
int** map; // for direction=EFFERENT(AFFERENT) is map[i][dim] center index of dimension dim in target (address) area
// corresponding to element i in address (target) area; map[i][nDim] is total corresponding position
TProjectionMap(TCuboidLT& addressLT_arg, TCuboidLT& targetLT_arg); // general constructor
TProjectionMap(TCuboidLT& addressLT_arg, TCuboidLT& targetLT_arg, int direction_arg);
TProjectionMap(int sizeA, int sizeT); // constructor for one-dimensional case
TProjectionMap(int sizeA, int sizeT, int direction_arg);
TProjectionMap(int sizeAY,int sizeAX, int sizeTY, int sizeTX); // constructor for two-dimensional case
TProjectionMap(int sizeAY,int sizeAX, int sizeTY, int sizeTX, int direction_arg);
TProjectionMap(int sizeAZ,int sizeAY,int sizeAX, int sizeTZ,int sizeTY,int sizeTX); // constructor for three-dimensional case
TProjectionMap(int sizeAZ,int sizeAY,int sizeAX, int sizeTZ,int sizeTY,int sizeTX, int direction_arg);
~TProjectionMap(); // destructor
inline int*& operator[](unsigned int); // array subscript operator delivers map[i]
void setDirection(int direction_arg); // set direction to either EFFERENT or AFFERENT
void outputState(ostream & os); // output of all fields of the object
void outputState(ostream & os, int complete); // if complete==0 only output most important fields
protected:
void deallocate(); // deallocate map memory
void create(); // create map; called by constructors
};
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TMMarray is the base template for multi-dimensional arrays. A TMMarray is physically implemented as a one-dimensional
* array (field T* data), where the topographical information is represented by a cuboid layout @ref TCuboidLT.
* Actually, TMMarray inherits from @ref TCuboidLT.
*
* @short template for multi-dimensional arrays of any type T
* @version 1.0 alpha,
* last change: April 6, 2001
*/
template
class TMMarray : public TCuboidLT {
// **************************************************************************************************************************
public:
T* data; // data field, length of array is N (inherited from TLayout)
TMMarray(const TCuboidLT& layout); // constructor, data will be allocated
TMMarray(const TCuboidLT& layout, T* data_arg); // constructor, no memory is allocated for data
TMMarray(const TMMarray& copy); // copy constructor, new memory will be allocated for data!
TMMarray(const TMMarray& copy, T* data_arg); // copy constructor, no memory is allocated for data
~TMMarray(); // destructor
void operator=(const TMMarray& copy); // copy function, new memory will be allocated for data!
inline T& operator[](unsigned i)const; // array subscript operator: delivers reference to data[i]
bool sameDataAs(const TMMarray& ma)const;// returns true iff ma has same data
void referenceBy(T* data_arg); // set data to data_arg and set referencedFlag
void resize(const TCuboidLT& layout); // resizes and reinitializes multi-array, old data is lost!
void resize(const TCuboidLT& layout, int keepGenericFlags); // as befor, but flags genericNDim/genericSize are kept
void resize(const TCuboidLT& layout, T* data_new); // resizes and reinitializes multi-array, old data is lost!
inline void set(T* data_arg); // sets data
inline void set(T data_arg, int* idx); // sets one parameter data according to index idx
inline void set(T* data_arg, int idx); // sets data; only for nDim>=1
inline void set(T* data_arg, int idx1, int idx2); // sets data; only for nDim>=2
inline void set(T* data_arg, int idx1, int idx2, int idx3); // sets data; only for nDim>=3
inline void set(T* data_arg, int idx1, int idx2, int idx3, int idx4); // sets data; only for nDim>=4
inline T* get() const; // returns pointer to parameter data
inline T* get(int* idx) const; // returns data according to index idx
inline T* get(int idx) const; // returns data; only for nDim>=1
inline T* get(int idx1, int idx2) const; // returns data; only for nDim>=2
inline T* get(int idx1, int idx2, int idx3) const; // returns data; only for nDim>=3
inline T* get(int idx1, int idx2, int idx3, int idx4) const; // returns data; only for nDim>=4
void setSubBlock(TMMarray& subBlock, int* pos, T* zero); // set subblock at position pos
template // set data as rotated original
void rotate(TMMarray& original, TNum* rot, // rotated around center position
int* center, int* center_org, T* zero);
void outputState(ostream & os); // output all fields of this object
friend ostream & operator<< (ostream & os, const TMMarray & par); // output operator
friend istream & operator>> (istream & os, TMMarray & par); // input operator
protected:
TReferencedFlag referencedFlag; // flag is REFERENCED if data is only a reference
};
template
ostream & operator <<(ostream & os, const TMMarray & par); // output operator
template
istream & operator >>(istream & is, TMMarray & par); // input operator
// **************************************************************************************************************************
// **************************************************************************************************************************
/**
* TMNumMarray is a multi-dimensional array template for numerical types and inherits from @ref TMMarray.
* In contrast to TMMarray, this class provides some further methods which can be applied only on numerical
* template types. For example method @ref TMNumMarray#conv(a,k) sets the object as the convolution of TMNumMarray a and
* a kernel TMNumMarray k. TMNumMarray is also the base type for many numerical parameters (see @TNumParameter)
*
* @short template for numerical multi-arrays of numerical type TNum
* @version 1.0 alpha,
* last change: December 6, 2001
*/
template
class TMNumMarray : public TMMarray {
// **************************************************************************************************************************
public:
TMNumMarray(const TCuboidLT& layout); // constructor, data will be allocated
TMNumMarray(const TCuboidLT& layout, TNum* data_arg); // constructor, no memory is allocated for data
TMNumMarray(const TMNumMarray& copy); // copy constructor, new memory will be allocated for data!
TMNumMarray(const TMNumMarray& copy, TNum* data_arg); // copy constructor, no memory is allocated for data!
~TMNumMarray(); // destructor
void clear(); // set all items to 0
void conv(TMNumMarray& numMarray1, TMNumMarray& kernel); // convolution data = numMarray * kernel
};
// include inline methods
#define INLINE 1
#include "F2_layout.cpp"
#undef INLINE
#endif /* F2_layout_H */
| Generated by: aknoblau on synfire on Sat May 1 14:32:16 2004, using kdoc 2.0a54. |