File: fine_container.hweb

package info (click to toggle)
dynare 4.5.7-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 49,408 kB
  • sloc: cpp: 84,998; ansic: 29,058; pascal: 13,843; sh: 4,833; objc: 4,236; yacc: 3,622; makefile: 2,278; lex: 1,541; python: 236; lisp: 69; xml: 8
file content (164 lines) | stat: -rw-r--r-- 5,628 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
@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.