File: symmetry.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 (153 lines) | stat: -rw-r--r-- 3,632 bytes parent folder | download | duplicates (4)
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
@q Copyright (C) 2004-2011, Ondra Kamenik @>

@ Start of {\tt symmetry.cpp} file.

@c
#include "symmetry.h"
#include "permutation.h"

#include <cstdio>

@<|Symmetry| constructor code@>;
@<|Symmetry::findClass| code@>;
@<|Symmetry::isFull| code@>;
@<|symiterator| constructor code@>;
@<|symiterator| destructor code@>;
@<|symiterator::operator++| code@>;
@<|InducedSymmetries| constructor code@>;
@<|InducedSymmetries| permuted constructor code@>;
@<|InducedSymmetries::print| code@>;

@ Construct symmetry as numbers of successively equal items in the sequence.

@<|Symmetry| constructor code@>=
Symmetry::Symmetry(const IntSequence& s)
	: IntSequence(s.getNumDistinct(), 0)
{
	int p = 0;
	if (s.size() > 0)
		operator[](p) = 1;
	for (int i = 1; i < s.size(); i++) {
		if (s[i] != s[i-1])
			p++; 
		operator[](p)++;
	}
}

@ Find a class of the symmetry containing a given index.
@<|Symmetry::findClass| code@>=
int Symmetry::findClass(int i) const
{
	int j = 0;
	int sum = 0;
	do {
		sum += operator[](j);
		j++;
	} while (j < size() && sum <= i);

	return j-1;
}

@ The symmetry is full if it allows for any permutation of indices. It
means, that there is at most one non-zero index.

@<|Symmetry::isFull| code@>=
bool Symmetry::isFull() const
{
	int count = 0;
	for (int i = 0; i < num(); i++)
		if (operator[](i) != 0)
			count++;
	return count <=1;
}


@ Here we construct the beginning of the |symiterator|. The first
symmetry index is 0. If length is 2, the second index is the
dimension, otherwise we create the subordinal symmetry set and its
beginning as subordinal |symiterator|.

@<|symiterator| constructor code@>=
symiterator::symiterator(SymmetrySet& ss)
	: s(ss), subit(NULL), subs(NULL), end_flag(false)
{
	s.sym()[0] = 0;
	if (s.size() == 2) {
		s.sym()[1] = s.dimen();
	} else {
		subs = new SymmetrySet(s, s.dimen());
		subit = new symiterator(*subs);
	}
}


@ 
@<|symiterator| destructor code@>=
symiterator::~symiterator( )
{
	if (subit)
		delete subit;
	if (subs)
		delete subs;
}

@ Here we move to the next symmetry. We do so only, if we are not at
the end. If length is 2, we increase lower index and decrease upper
index, otherwise we increase the subordinal symmetry. If we got to the
end, we recreate the subordinal symmetry set and set the subordinal
iterator to the beginning. At the end we test, if we are not at the
end. This is recognized if the lowest index exceeded the dimension.

@<|symiterator::operator++| code@>=
symiterator& symiterator::operator++()
{
	if (!end_flag) {
		if (s.size() == 2) {
			s.sym()[0]++;
			s.sym()[1]--;
		} else {
			++(*subit);
			if (subit->isEnd()) {
				delete subit;
				delete subs;
				s.sym()[0]++;
				subs = new SymmetrySet(s, s.dimen()-s.sym()[0]);
				subit = new symiterator(*subs);
			}
		}
		if (s.sym()[0] == s.dimen()+1)
			end_flag=true;
	}
	return *this;
}

@ 
@<|InducedSymmetries| constructor code@>=
InducedSymmetries::InducedSymmetries(const Equivalence& e, const Symmetry& s)
{
	for (Equivalence::const_seqit i = e.begin(); i != e.end(); ++i) {
		push_back(Symmetry(s, *i));
	}
}

@ 
@<|InducedSymmetries| permuted constructor code@>=
InducedSymmetries::InducedSymmetries(const Equivalence& e, const Permutation& p,
									 const Symmetry& s)
{
	for (int i = 0; i < e.numClasses(); i++) {
		Equivalence::const_seqit it = e.find(p.getMap()[i]);
		push_back(Symmetry(s, *it));
	}
}

@ Debug print.
@<|InducedSymmetries::print| code@>=
void InducedSymmetries::print() const
{
	printf("Induced symmetries: %lu\n", (unsigned long) size());
	for (unsigned int i = 0; i < size(); i++)
		operator[](i).print();
}

@ End of {\tt symmetry.cpp} file.