dynare/dynare++/tl/cc/fine_container.hweb

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.