File: t_container.cweb

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 (138 lines) | stat: -rw-r--r-- 3,947 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
@q $Id: t_container.cweb 148 2005-04-19 15:12:26Z kamenik $ @>
@q Copyright 2004, Ondra Kamenik @>

@ Start of {\tt t\_container.cpp} file.
@s USubTensor int
@c
#include "t_container.h" 
#include "kron_prod.h"
#include "ps_tensor.h"
#include "pyramid_prod.h"

const int FGSContainer::num_one_time = 10;
@<|UGSContainer| conversion from |FGSContainer|@>;
@<|UGSContainer::multAndAdd| code@>;
@<|FGSContainer| conversion from |UGSContainer|@>;
@<|FGSContainer::multAndAdd| folded code@>;
@<|FGSContainer::multAndAdd| unfolded code@>;
@<|FGSContainer::getIndices| code@>;

@ 
@<|UGSContainer| conversion from |FGSContainer|@>=
UGSContainer::UGSContainer(const FGSContainer& c)
	: TensorContainer<UGSTensor>(c.num())
{
	for (FGSContainer::const_iterator it = c.begin();
		 it != c.end(); ++it) {
		UGSTensor* unfolded = new UGSTensor(*((*it).second));
		insert(unfolded);
	}
}

@ We set |l| to dimension of |t|, this is a tensor which multiplies
tensors from the container from the left. Also we set |k| to a
dimension of the resulting tensor. We go through all equivalences on
|k| element set and pickup only those which have $l$ classes.

In each loop, we fetch all necessary tensors for the product to the
vector |ts|. Then we form Kronecker product |KronProdAll| and feed it
with tensors from |ts|. Then we form unfolded permuted symmetry tensor
|UPSTensor| as matrix product of |t| and Kronecker product |kp|. Then
we add the permuted data to |out|. This is done by |UPSTensor| method
|addTo|.

@<|UGSContainer::multAndAdd| code@>=
void UGSContainer::multAndAdd(const UGSTensor& t, UGSTensor& out) const
{
	int l = t.dimen();
	int k = out.dimen();
	const EquivalenceSet& eset = ebundle.get(k);

	for (EquivalenceSet::const_iterator it = eset.begin();
		 it != eset.end(); ++it) {
		if ((*it).numClasses() == l) {
			vector<const UGSTensor*> ts =
				fetchTensors(out.getSym(), *it);
			KronProdAllOptim kp(l);
			for (int i = 0; i < l; i++)
				kp.setMat(i, *(ts[i]));
			kp.optimizeOrder();
			UPSTensor ups(out.getDims(), *it, t, kp);
			ups.addTo(out);
		}
	}
}

@ 
@<|FGSContainer| conversion from |UGSContainer|@>=
FGSContainer::FGSContainer(const UGSContainer& c)
	: TensorContainer<FGSTensor>(c.num())
{
	for (UGSContainer::const_iterator it = c.begin();
		 it != c.end(); ++it) {
		FGSTensor* folded = new FGSTensor(*((*it).second));
		insert(folded);
	}
}


@ Here we perform one step of the Faa Di Bruno operation. We call the
|multAndAdd| for unfolded tensor.
@<|FGSContainer::multAndAdd| folded code@>=
void FGSContainer::multAndAdd(const FGSTensor& t, FGSTensor& out) const
{
	UGSTensor ut(t);
	multAndAdd(ut, out);
}

@ This is the same as |@<|UGSContainer::multAndAdd| code@>|
but we do not construct |UPSTensor| from the Kronecker
product, but |FPSTensor|.

@<|FGSContainer::multAndAdd| unfolded code@>=
void FGSContainer::multAndAdd(const UGSTensor& t, FGSTensor& out) const
{
	int l = t.dimen();
	int k = out.dimen();
	const EquivalenceSet& eset = ebundle.get(k);

	for (EquivalenceSet::const_iterator it = eset.begin();
		 it != eset.end(); ++it) {
		if ((*it).numClasses() == l) {
			vector<const FGSTensor*> ts =
				fetchTensors(out.getSym(), *it);
			KronProdAllOptim kp(l);
			for (int i = 0; i < l; i++)
				kp.setMat(i, *(ts[i]));
			kp.optimizeOrder();
			FPSTensor fps(out.getDims(), *it, t, kp);
			fps.addTo(out);
		}
	}
}


@ This fills a given vector with integer sequences corresponding to
first |num| indices from interval |start| (including) to |end|
(excluding). If there are not |num| of such indices, the shorter vector
is returned.

@<|FGSContainer::getIndices| code@>=
Tensor::index
FGSContainer::getIndices(int num, vector<IntSequence>& out,
						 const Tensor::index& start,
						 const Tensor::index& end)
{
	out.clear();
	int i = 0;
	Tensor::index run = start;
	while (i < num && run != end) {
		out.push_back(run.getCoor());
		i++;
		++run;
	}
	return run;
}


@ End of {\tt t\_container.cpp} file.