File: rfs_tensor.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 (148 lines) | stat: -rw-r--r-- 5,081 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
@q $Id: rfs_tensor.hweb 741 2006-05-09 11:12:46Z kamenik $ @>
@q Copyright 2004, Ondra Kamenik @>

@*2 Row-wise full symmetry tensor. Start of {\tt rfs\_tensor.h} file.

Here we define classes for full symmetry tensors with the
multidimensional index identified with rows. The primary usage is for
storage of data coming from (or from a sum of)
$$\prod_{m=1}^l\left[g_{s^{\vert c_m\vert}}\right]^{\gamma_m}_{c_m(\alpha)}$$
where $\alpha$ coming from a multidimensional index go through some
set $S$ and $c$ is some equivalence. So we model a tensor of the form:
$$\left[\prod_{m=1}^l
\left[g_{s^{\vert c_m\vert}}\right]^{\gamma_m}_{c_m(\alpha)}
\right]_S^{\gamma_1\ldots\gamma_l}$$
Since all $\gamma_1,\ldots,\gamma_l$ correspond to the same variable,
the tensor is fully symmetric.  The set of indices $S$ cannot be very
large and sometimes it is only one element. This case is handled in a
special subclass.

We provide both folded and unfolded versions. Their logic is perfectly
the same as in |UFSTensor| and |FFSTensor| with two exceptions. One
has been already mentioned, the multidimensional index is along the
rows. The second are conversions between the two types. Since this
kind of tensor is used to multiply (from the right) a tensor whose
multidimensional index is identified with columns, we will need a
different way of a conversion. If the multiplication of two folded
tensors is to be equivalent with multiplication of two unfolded, the
folding of the right tensor must sum all equivalent elements since
they are multiplied with the same number from the folded
tensor. (Equivalent here means all elements of unfolded tensor
corresponding to one element in folded tensor.) For this reason, it is
necessary to calculate a column number from the given sequence, so we
implement |getOffset|. Process of unfolding is not used, so we
implemented it so that unfolding and then folding a tensor would yield
the same data.

@c
#ifndef RFS_TENSOR_H
#define RFS_TENSOR_H

#include "tensor.h"
#include "fs_tensor.h"
#include "symmetry.h"

@<|URTensor| class declaration@>;
@<|FRTensor| class declaration@>;
@<|URSingleTensor| class declaration@>;
@<|FRSingleTensor| class declaration@>;

#endif

@ This is straightforward and very similar to |UFSTensor|.
@<|URTensor| class declaration@>=
class FRTensor;
class URTensor : public UTensor {
	int nv;
public:@;
	@<|URTensor| constructor declaration@>;
	virtual ~URTensor()@+ {}

	void increment(IntSequence& v) const;
	void decrement(IntSequence& v) const;
	FTensor& fold() const;

	int getOffset(const IntSequence& v) const;
	int nvar() const
		{@+ return nv;@+}
	Symmetry getSym() const
		{@+ return Symmetry(dimen());@+}
};

@ 
@<|URTensor| constructor declaration@>=
	URTensor(int c, int nvar, int d)
		: UTensor(along_row, IntSequence(d, nvar),
				  UFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar)@+ {}
	URTensor(const URTensor& ut)
		: UTensor(ut), nv(ut.nv)@+ {}
	URTensor(const FRTensor& ft);

@ This is straightforward and very similar to |FFSTensor|.
@<|FRTensor| class declaration@>=
class FRTensor : public FTensor {
	int nv;
public:@;
    @<|FRTensor| constructor declaration@>;
	virtual ~FRTensor()@+ {}

	void increment(IntSequence& v) const;
	void decrement(IntSequence& v) const;
	UTensor& unfold() const;

	int nvar() const
		{@+ return nv;@+}
	int getOffset(const IntSequence& v) const
		{@+ return FTensor::getOffset(v, nv);@+}
	Symmetry getSym() const
		{@+ return Symmetry(dimen());@+}
};

@ 
@<|FRTensor| constructor declaration@>=
	FRTensor(int c, int nvar, int d)
		: FTensor(along_row, IntSequence(d, nvar),
				  FFSTensor::calcMaxOffset(nvar, d), c, d), nv(nvar)@+ {}
	FRTensor(const FRTensor& ft)
		: FTensor(ft), nv(ft.nv)@+ {}
	FRTensor(const URTensor& ut);

@ The following class represents specialization of |URTensor| coming
from Kronecker multiplication of a few vectors. So the resulting
row-oriented tensor has one column. We provide two constructors,
one constructs the tensor from a few vectors stored as
|vector<ConstVector>|. The second makes the Kronecker power of one
given vector.

@<|URSingleTensor| class declaration@>=
class URSingleTensor : public URTensor {
public:@;
	URSingleTensor(int nvar, int d)
		: URTensor(1, nvar, d)@+ {}
	URSingleTensor(const vector<ConstVector>& cols);
	URSingleTensor(const ConstVector& v, int d);
	URSingleTensor(const URSingleTensor& ut)
		: URTensor(ut)@+ {}
	virtual ~URSingleTensor()@+ {}
	FTensor& fold() const;
};

@ This class represents one column row-oriented tensor. The only way
how to construct it is from the |URSingleTensor| or from the
scratch. The folding algorithm is the same as folding of general
|URTensor|. Only its implementation is different, since we do not copy
rows, but only elements.

@<|FRSingleTensor| class declaration@>=
class FRSingleTensor : public FRTensor {
public:@;
	FRSingleTensor(int nvar, int d)
		: FRTensor(1, nvar, d)@+ {}
	FRSingleTensor(const URSingleTensor& ut);
	FRSingleTensor(const FRSingleTensor& ft)
		: FRTensor(ft)@+ {}
	virtual ~FRSingleTensor()@+ {}
};


@ End of {\tt rfs\_tensor.h} file.