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

permutation.hxx VIGRA

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
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)