[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

permutation.hxx |

1 #ifndef VIGRA_PERMUTATION_HXX
2 #define VIGRA_PERMUTATION_HXX
3
4 #include "config.hxx"
5 #include "error.hxx"
6 #include "array_vector.hxx"
7 #include "tinyvector.hxx"
8
9 namespace vigra {
10
11 template <unsigned int N>
12 class Permutation : public TinyVector<unsigned int, N>
13 {
14 public:
15 typedef TinyVector<unsigned int, N> base_type;
16 typedef typename base_type::size_type size_type;
17 typedef typename base_type::value_type value_type;
18 typedef typename base_type::iterator iterator;
19 typedef typename base_type::const_iterator const_iterator;
20 typedef typename base_type::reference reference;
21 typedef typename base_type::const_reference const_reference;
22 typedef typename base_type::pointer pointer;
23 typedef typename base_type::const_pointer const_pointer;
24 typedef int integral_type;
25
26 Permutation() : base_type() {}
27
28 Permutation(const Permutation<N-1> & other, const size_type index)
29 : base_type()
30 {
31 vigra_precondition(
32 index < N,
33 "Permutation::Permutation(): Invalid index");
34 for (size_type n = 0; n < N; n++)
35 {
36 if (n < index)
37 {
38 (*this)[n] = other[n];
39 }
40 else if (n == index)
41 {
42 (*this)[n] = N - 1;
43 }
44 else
45 {
46 (*this)[n] = other[n-1];
47 }
48 }
49 if ((N - 1 - index) % 2 == 0)
50 {
51 sign_ = (other.sign() == 1);
52 }
53 else
54 {
55 sign_ = (other.sign() == -1);
56 }
57 }
58
59 integral_type sign() const
60 {
61 if (sign_)
62 {
63 return +1;
64 }
65 else
66 {
67 return -1;
68 }
69 }
70
71 private:
72 bool sign_;
73
74 };
75
76 template <>
77 class Permutation<1> : public TinyVector<unsigned int, 1>
78 {
79 public:
80 typedef TinyVector<unsigned int, 1> base_type;
81 typedef base_type::size_type size_type;
82 typedef base_type::value_type value_type;
83 typedef base_type::iterator iterator;
84 typedef base_type::const_iterator const_iterator;
85 typedef base_type::reference reference;
86 typedef base_type::const_reference const_reference;
87 typedef base_type::pointer pointer;
88 typedef base_type::const_pointer const_pointer;
89 typedef int integral_type;
90
91 Permutation() : base_type()
92 {
93 (*this)[0] = 0;
94 (*this).sign_ = true;
95 }
96
97 integral_type sign() const
98 {
99 if (sign_)
100 {
101 return +1;
102 }
103 else
104 {
105 return -1;
106 }
107 }
108
109 private:
110 bool sign_;
111 };
112
113 template <unsigned int N>
114 class PlainChangesPermutations : public ArrayVector<Permutation<N> >
115 {
116 public:
117 typedef ArrayVector<Permutation<N> > base_type;
118 typedef typename base_type::size_type size_type;
119 typedef typename base_type::value_type value_type;
120 typedef typename base_type::iterator iterator;
121 typedef typename base_type::const_iterator const_iterator;
122 typedef typename base_type::reference reference;
123 typedef typename base_type::const_reference const_reference;
124 typedef typename base_type::pointer pointer;
125 typedef typename base_type::const_pointer const_pointer;
126
127 PlainChangesPermutations() : base_type()
128 {
129 PlainChangesPermutations<N-1> permutations;
130 for (auto permutation : permutations)
131 {
132 if (permutation.sign() == -1)
133 {
134 for (unsigned int n = 0; n < N; n++)
135 {
136 this->push_back(Permutation<N>(permutation, n));
137 }
138 }
139 else
140 {
141 for (unsigned int n = N; n > 0; n--)
142 {
143 this->push_back(Permutation<N>(permutation, n - 1));
144 }
145 }
146 }
147 }
148 };
149
150 template <>
151 class PlainChangesPermutations<1> : public ArrayVector<Permutation<1> >
152 {
153 public:
154 typedef ArrayVector<Permutation<1> > base_type;
155 typedef base_type::size_type size_type;
156 typedef base_type::value_type value_type;
157 typedef base_type::iterator iterator;
158 typedef base_type::const_iterator const_iterator;
159 typedef base_type::reference reference;
160 typedef base_type::const_reference const_reference;
161 typedef base_type::pointer pointer;
162 typedef base_type::const_pointer const_pointer;
163
164 PlainChangesPermutations() : base_type()
165 {
166 this->push_back(Permutation<1>());
167 }
168 };
169
170 } /* namespace vigra */
171
172 #endif
vigra::sign
T sign(T t)
The sign function.
Definition: mathutil.hxx:591

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.1 (Fri May 19 2017)