Index

NAME

ArrayGenSimplest(Type)  -  general  array  with  variable  no. of
indices


INCLUDE

include "ArrayGenSimplest_Type.h"

SYNTAX

 class ArrayGenSimplest(Type) : public virtual VecSimplest(Type)
 {
 protected:

   int      ndim;   // number of dimensions
   Ptv(int) nm;     // length of each dimensions, multiple index
   Ptv(int) bm;     // base of each dimensions, multiple index
   int      nm1;    // length of 1D
   int      nm1nm2; // length 1D multiplied with length 2D
   int      bm0;    // for increasing operator() efficiency

   int   local_index;             // relative subscripting parameter
   int   current_iterator_index;  // for iterating over the array entries

   int   totalLength (const Ptv(int)& n);

   void  init (int n1);
   void  init (int n1, int n2);
   void  init (int n1, int n2, int n3);
   void  init (const Ptv(int)& n);

   // avoid function "hiding" warnings:
   bool redim (Type* a, int n, int base = 0);
   bool compatible (const VecSimplest(Type)& X) const;

   // called by the subscript functions having a Ptv(int) argument:
   int elmNo (const Ptv(int)& index, int base) const;

 public:

   ArrayGenSimplest(Type) ();
   ArrayGenSimplest(Type) (int n1);
   ArrayGenSimplest(Type) (int n1, int n2);
   ArrayGenSimplest(Type) (int n1, int n2, int n3);
   ArrayGenSimplest(Type) (const Ptv(int)& n);       // multiple index
  ~ArrayGenSimplest(Type) () {}

   bool redim (int n1);                           // one-dim. array
   bool redim (int n1, int n2);                   // two-dim. array
   bool redim (int n1, int n2, int n3);           // three-dim. array
   bool redim (const Ptv(int)& n);                // multiple index
                                                  // (arbitrary-dim.)

   bool compatible (const ArrayGenSimplest(Type)& a, bool error_message = true);

   void setBase  (int b1);
   void setBase  (int b1, int b2);
   void setBase  (int b1, int b2, int b3);
   void setBase  (const Ptv(int)& b);

   // with getBase and getMaxI one can easily determine lower and
   // upper bounds on loops involving ArrayGenSimplest objects, while
   // getDim finds the length of the loops

   // lower index:
   void getBase  (int& b1) const;
   void getBase  (int& b1, int& b2) const;
   void getBase  (int& b1, int& b2, int& b3) const;
   void getBase  (Ptv(int)& b) const;

   // upper index:
   void getMaxI  (int& n1) const;
   void getMaxI  (int& n1, int& n2) const;
   void getMaxI  (int& n1, int& n2, int& n3) const;
   void getMaxI  (Ptv(int)& n) const;

   int  getNoIndices () const;

   // length of each dimension:
   void getDim   (int& n1) const;                    // length of 1D array
   void getDim   (int& n1, int& n2) const;           // length of 2D array
   void getDim   (int& n1, int& n2, int& n3) const;  // length of 3D array
   void getDim   (Ptv(int)& n) const;                // length of general dD
                                                     // array

   void indexOk1 (int i, const char* message = NULL) const; // for singleIndex1
   void indexOk  (int i, const char* message = NULL) const;
   void indexOk  (int i, int j, const char* message = NULL) const;
   void indexOk  (int i, int j, int k, const char* message = NULL) const;
   void indexOk  (const Ptv(int)& index, const char* message = NULL) const;

   String arraySize () const;

         Type& singleIndex1 (int i);          // single index, 1 to total length
   const Type& singleIndex1 (int i) const;

   // return the single index element number:
   int multiple2single (int i) const;
   int multiple2single (int i,int j) const;
   int multiple2single (int i,int j,int k) const;
   int multiple2single (const Ptv(int)& index) const;

   int length1D() const       { return nm1;   }
   int length1Dx2D() const  { return nm1nm2;}

   // set a local reference index :
   void setLocalIndex (int i) const;
   void setLocalIndex (int i,int j) const;
   void setLocalIndex (int i,int j,int k) const;
   void setLocalIndex (const Ptv(int)& index) const;

   // the single index of the local element:
   int getLocalIndex() const { return local_index; }

   // subscript the neighbors of the local index :
         Type& local (int i);
         Type& local (int i, int j);
         Type& local (int i, int j, int k);
         Type& local (const Ptv(int)& index);
   const Type& local (int i) const;
   const Type& local (int i, int j) const;
   const Type& local (int i, int j, int k) const;
   const Type& local (const Ptv(int)& index) const;


         Type& operator () (int i);
         Type& operator () (int i, int j);
         Type& operator () (int i, int j, int k);
         Type& operator () (const Ptv(int)& index);
   const Type& operator () (int i) const;
   const Type& operator () (int i, int j) const;
   const Type& operator () (int i, int j, int k) const;
   const Type& operator () (const Ptv(int)& index) const;


   void startIterator ();
   bool nextEntry ();             // is there a next entry?
                                     // if yes, move to it
         Type& thisEntry ();         // enables assignment
   const Type& thisEntry () const;   // enables reading only

   // illegal functions (included here with just an error message):
   ArrayGenSimplest(Type) (const ArrayGenSimplest(Type)& v);
   void operator =        (const ArrayGenSimplest(Type)& v);
 };



KEYWORDS

array, general array, multi-dimensional array



DESCRIPTION

The class implements a multi-dimensional  array  in  terms  of  a
standard,  one-dimensional C array. The multi-dimensional feature
is created by offering subscript operators for  one,  two,  three
and  Ptv(int)  indices. The bases of the indices can be arbitrary
(see the example below).  The array is parameterized and can con­
tain  any  built-in  or  user  defined  type,  cf.  class VecSim­
plest(Type).  Further features, such  as  arithmetic  operations,
are enabled in the derived class ArrayGen(Type).



CONSTRUCTORS AND INITIALIZATION

There  are  several  constructors.  All constructors allocate the
proper amount of memory and initialize the various internal  data
structure  needed for administrating the multi-dimensional array.
The base of each index must be set manually. The default base  is
1.   The only user required initialization is to assign values to
the entries in the array.

There is a default constructor which coincides with  the  default
constructor  of the base class VecSimplest(Type).  The other con­
structors take the number of entries in  each  dimension  of  the
array  as  arguments.  If  there  are  more  than 3 dimensions, a
Ptv(int) object is given as argument.



MEMBER FUNCTIONS

If the documentation of class VecSimplest is known and the  exam­
ple  below  is  studied,  most  of the member functions should be
self-explanatory.

redim - redimensions the array. With this function one can change
the  dimension  of  the  array, and the number of entries of each
dimension.  The base is set to 1.

setBase - enables the programmer to choose an arbitrary base  for
the index of each dimension.

getBase - returns the base of the index of each dimension.

getMaxI - returns the upper index value of each dimension. If one
wants a loop over the array entries and need to extract the lower
and  upper loop limits, getBase will give the lower limits, while
getMaxI will give the correct upper limits.

getNoIndices - returns the number of dimensions (or  indices)  of
the array.

getDim  -  returns the number of array entries in each dimension.
Note that if the base is unity, the number of entries equals  the
return  values  of  getMaxI. To redimension another array, getDim
extracts the correct size. If the bases should also coicide,  one
must  extract  the  bases (getBase) and set them in the new array
(setBase) after the declaration.

singleIndex1 - enables  the  programmer  to  index  the  possibly
multi-dimensional  array  by using a single index. This is conve­
nient if the programmer wants to avoid separate loops  over  each
dimension  (hence  there  is  no  need  for getBase or getMaxI or
knowledge of the number of dimensions).

arraySize - returns a string containing the array size, e.g., for
a  2-dimensional  array [0:3]x[-1:4] it simply returns the string
"[0:3]x[-1:4]".

operator() - enables subscripting of the array. There are several
overloaded  versions.  If  the  number if indices is less than or
equal to three, one can apply the operator() functions that  have
integer  arguments. These are much more efficient than the opera­
tor()(Ptv) function, but the latter is more general since one can
work  with  a  single  index  object, regardless of the number of
space dimensions.  For  two  and  higher  dimensional  arrays  in
ArrayGenSimplest  it  is  important  to know that the first index
varies most rapidly. In other words, the "storage" is column-ori­
ented  like  in  Fortran  arrays. This makes it easy to interface
ArrayGenSimplest  to  Fortran  code  (simply  send  the   pointer
returned from getPtr0 to the Fortran routine).  Note that MatSim­
plest has a row by row storage that  must  be  transposed  before
calling  Fortran  code.  Interchange  of  matrices  (that is, two
dimensional arrays) between C++ and Fortran  is  then  easier  to
perform if the C++ representation of the matrix is in terms of an
ArrayGenSimplest object and not a MatSimplest object.

setLocalIndex - ables subscripting relative to  the  local  index
set by this member function. The local index will always have the
index (0,0,).

local - subscripting relative to the index set by  setLocalIndex.
For  example:  local(0) refers to the array entry set by the last
call to setLocalIndex, local(-1) is the previous entry and so on.
When  working  with  2D  finite  difference methods, one can call
local(-1,0), local(0,1) and so on (similarly in  3D  with  triple
indices).  Alternatively, one can call setLocalIndex right before
the innermost loop and then run through the fastest varying index
(the  first  index) using local(i), where i starts at 0.  A sepa­
rate report on the efficiency of various indexing strategies  for
finite difference methods treats this topic in detail.

getLocalIndex  - returns the single index of the local index, set
by the last call to setLocalIndex, that is the index  correspond­
ing to the element number in VecSimplest(Type).

startIterator - starts an iteration over all the array entries.

nextEntry  -  moves  a  pointer  to  the next entry in the array.
Returns a true value of there is a next entry, if  not,  a  false
value is returned.

thisEntry  -  returns the value of the current entry. Actually, a
reference is returned so  that  the  function  can  be  used  for
assigning values to entries (only true for a const object).

Be aware that ArrayGenSimplest does not require the Type class to
have an operator=. Hence, the copy constructor or the  assignment
operator has no meaning for ArrayGenSimplest. Since C++ automati­
cally makes such functions if they are  not  explicitly  declared
(and  such  automatically  generated  functions  lead  to serious
errors in the present case), the functions are declared, but  the
content is just an error message.




EXAMPLES

Below  we  show  a few call statements using the ArrayGenSimplest
class.  More examples are found in the verification program  that
is  used  to  verify the implementation. That program is found in
the directory

    $DPR/src/app/class-verify/category1/ArrayGenSimplest

Study the source file, compile it and study the output.  An exam­
ple  on how the program is run is found in the script in the ver­
ify subdirectory (the script has extension .sh).

    // two-dimensional array with each index starting at 0:
    ArrayGenSimplest(real) v (10, 10);
    v.setBase (0, 0);
    // valid indices: v(i,j), where 0 <= i,j <= 9

    // four-dimensional array with first index starting at 0, the
others
    // starting at 1:
    Ptv(int) b(4), n(4), i(4);
    n(1) = 10;  n(2) = 5;  n(3) = n(4) = 8;   // dimensions
    b(1) = 0;   b(2) = b(3) = b(4) = 1;       // base
    ArrayGenSimplest(real) w (n);
    w.setBase (b);
    i(1) = 1; i(2) = i(3) = i(4) = 3;         // 4-tuple index
    w(i) = 6;                                 // assignment,  one
entry

    // three-dimensional array of class Thing objects, each index
base
    // equals -1, each dimension of the array equals 3:
    ArrayGenSimplest(Thing) t (3,3,3);
    t.setBase (-1,-1,-1);
    t(0,-1,1).scan (cin);

    // copy a to b manually (ArrayGenSimplest(Type) has no opera­
tor=
    // function, cf. class VecSimplest(Type):

    int n1, n2; a.getDim (n1,n2);
    ArrayGenSimplest(real) b(n1,n2);
    int j,k,j1,k1,jn,kn;
    a.getBase (j1,k1);  a.getMaxI (jn,kn);
    for (j=j1; j<=jn; j++)
      for (k=k1; k<=kn; k++)
        b(j,k) = a(j,k);






SEE ALSO

class ArrayGen(Type), class VecSimplest(Type)



DEVELOPED BY

SINTEF Applied Mathematics, Oslo, Norway, and University of Oslo,
Dept. of Mathematics, Norway


AUTHOR

Hans  Petter Langtangen, SINTEF/UiO. Improvements by Johan Berge,
SINTEF.