165 lines
5.5 KiB
Plaintext
165 lines
5.5 KiB
Plaintext
|
@q $Id: fine_container.hweb 332 2005-07-15 13:41:48Z kamenik $ @>
|
||
|
@q Copyright 2005, Ondra Kamenik @>
|
||
|
|
||
|
@*2 Refined stack of containers. Start of {\tt fine\_container.h} file.
|
||
|
|
||
|
This file defines a refinement of the stack container. It makes a
|
||
|
vertical refinement of a given stack container, it refines only matrix
|
||
|
items, the items which are always zero, or can be identity matrices
|
||
|
are not refined.
|
||
|
|
||
|
The refinement is done by a simple construction from the stack
|
||
|
container being refined. A parameter is passed meaning a maximum size
|
||
|
of each stack in the refined container. The resulting object is stack
|
||
|
container, so everything works seamlessly.
|
||
|
|
||
|
We define here a class for refinement of sizes |SizeRefinement|, this
|
||
|
is purely an auxiliary class allowing us to write a code more
|
||
|
concisely. The main class of this file is |FineContainer|, which
|
||
|
corresponds to refining. The two more classes |FoldedFineContainer|
|
||
|
and |UnfoldedFineContainer| are its specializations.
|
||
|
|
||
|
NOTE: This code was implemented with a hope that it will help to cut
|
||
|
down memory allocations during the Faa Di Bruno formula
|
||
|
evaluation. However, it seems that this needs to be accompanied with a
|
||
|
similar thing for tensor multidimensional index. Thus, the abstraction
|
||
|
is not currently used, but it might be useful in future.
|
||
|
|
||
|
@s SizeRefinement int
|
||
|
@s FineContainer int
|
||
|
@s FoldedFineContainer int
|
||
|
@s UnfoldedFineContainer int
|
||
|
|
||
|
@c
|
||
|
#ifndef FINE_CONTAINER_H
|
||
|
#define FINE_CONTAINER_H
|
||
|
|
||
|
#include "stack_container.h"
|
||
|
|
||
|
#include <vector>
|
||
|
|
||
|
@<|SizeRefinement| class declaration@>;
|
||
|
@<|FineContainer| class declaration@>;
|
||
|
@<|FoldedFineContainer| class declaration@>;
|
||
|
@<|UnfoldedFineContainer| class declaration@>;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
@ This class splits the first |nc| elements of the given sequence |s|
|
||
|
to a sequence not having items greater than given |max|. The remaining
|
||
|
elements (those behind |nc|) are left untouched. It also remembers the
|
||
|
mapping, i.e. for a given index in a new sequence, it is able to
|
||
|
return a corresponding index in old sequence.
|
||
|
|
||
|
@<|SizeRefinement| class declaration@>=
|
||
|
class SizeRefinement {
|
||
|
vector<int> rsizes;
|
||
|
vector<int> ind_map;
|
||
|
int new_nc;
|
||
|
public:@;
|
||
|
SizeRefinement(const IntSequence& s, int nc, int max);
|
||
|
int getRefSize(int i) const
|
||
|
{@+ return rsizes[i];@+}
|
||
|
int numRefinements() const
|
||
|
{@+ return rsizes.size();@+}
|
||
|
int getOldIndex(int i) const
|
||
|
{@+ return ind_map[i];@+}
|
||
|
int getNC() const
|
||
|
{@+ return new_nc;@+}
|
||
|
};
|
||
|
|
||
|
|
||
|
@ This main class of this class refines a given stack container, and
|
||
|
inherits from the stack container. It also defines the |getType|
|
||
|
method, which returns a type for a given stack as the type of the
|
||
|
corresponding (old) stack of the former stack container.
|
||
|
|
||
|
@<|FineContainer| class declaration@>=
|
||
|
template <class _Ttype>@;
|
||
|
class FineContainer : public SizeRefinement, public StackContainer<_Ttype> {
|
||
|
protected:@;
|
||
|
typedef StackContainer<_Ttype> _Stype;
|
||
|
typedef typename StackContainerInterface<_Ttype>::_Ctype _Ctype;
|
||
|
typedef typename StackContainerInterface<_Ttype>::itype itype;
|
||
|
_Ctype** const ref_conts;
|
||
|
const _Stype& stack_cont;
|
||
|
public:@;
|
||
|
@<|FineContainer| constructor@>;
|
||
|
@<|FineContainer| destructor@>;
|
||
|
itype getType(int i, const Symmetry& s) const
|
||
|
{@+ return stack_cont.getType(getOldIndex(i), s);@+}
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
@ Here we construct the |SizeRefinement| and allocate space for the
|
||
|
refined containers. Then, the containers are created and put to
|
||
|
|conts| array. Note that the containers do not claim any further
|
||
|
space, since all the tensors of the created containers are in-place
|
||
|
submatrices.
|
||
|
|
||
|
Here we use a dirty trick of converting |const| pointer to non-|const|
|
||
|
pointer and passing it to a subtensor container constructor. The
|
||
|
containers are stored in |ref_conts| and then in |conts| from
|
||
|
|StackContainer|. However, this is safe since neither |ref_conts| nor
|
||
|
|conts| are used in non-|const| contexts. For example,
|
||
|
|StackContainer| has only a |const| method to return a member of
|
||
|
|conts|.
|
||
|
|
||
|
@<|FineContainer| constructor@>=
|
||
|
FineContainer(const _Stype& sc, int max)
|
||
|
: SizeRefinement(sc.getStackSizes(), sc.numConts(), max),
|
||
|
StackContainer<_Ttype>(numRefinements(), getNC()),
|
||
|
ref_conts(new _Ctype*[getNC()]),
|
||
|
stack_cont(sc)
|
||
|
{
|
||
|
for (int i = 0; i < numRefinements(); i++)
|
||
|
_Stype::stack_sizes[i] = getRefSize(i);
|
||
|
_Stype::calculateOffsets();
|
||
|
|
||
|
int last_cont = -1;
|
||
|
int last_row = 0;
|
||
|
for (int i = 0; i < getNC(); i++) {
|
||
|
if (getOldIndex(i) != last_cont) {
|
||
|
last_cont = getOldIndex(i);
|
||
|
last_row = 0;
|
||
|
}
|
||
|
union {const _Ctype* c; _Ctype* n;} convert;
|
||
|
convert.c = stack_cont.getCont(last_cont);
|
||
|
ref_conts[i] = new _Ctype(last_row, _Stype::stack_sizes[i],
|
||
|
*(convert.n));
|
||
|
_Stype::conts[i] = ref_conts[i];
|
||
|
last_row += _Stype::stack_sizes[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@ Here we deallocate the refined containers, and deallocate the array of refined containers.
|
||
|
@<|FineContainer| destructor@>=
|
||
|
virtual ~FineContainer()
|
||
|
{
|
||
|
for (int i = 0; i < _Stype::numConts(); i++)
|
||
|
delete ref_conts[i];
|
||
|
delete [] ref_conts;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
@ Here is |FineContainer| specialization for folded tensors.
|
||
|
@<|FoldedFineContainer| class declaration@>=
|
||
|
class FoldedFineContainer : public FineContainer<FGSTensor>, public FoldedStackContainer {
|
||
|
public:@;
|
||
|
FoldedFineContainer(const StackContainer<FGSTensor>& sc, int max)
|
||
|
: FineContainer<FGSTensor>(sc, max) @+ {}
|
||
|
};
|
||
|
|
||
|
@ Here is |FineContainer| specialization for unfolded tensors.
|
||
|
@<|UnfoldedFineContainer| class declaration@>=
|
||
|
class UnfoldedFineContainer : public FineContainer<UGSTensor>, public UnfoldedStackContainer {
|
||
|
public:@;
|
||
|
UnfoldedFineContainer(const StackContainer<UGSTensor>& sc, int max)
|
||
|
: FineContainer<UGSTensor>(sc, max) @+ {}
|
||
|
};
|
||
|
|
||
|
|
||
|
@ End of {\tt fine\_container.h} file.
|