StatMech
Loading...
Searching...
No Matches
IntegerComposition Class Reference

Lists a weak composition of an integer N up to length L with a constraint that each summand does not exceed Max. More...

#include <IntegerComposition.hpp>

Collaboration diagram for IntegerComposition:
Collaboration graph

Public Member Functions

__host__ __device__ IntegerComposition ()
 Construct a new Integer Composition object.
 
__host__ __device__ IntegerComposition (int N, int Length, int Max)
 
__host__ __device__ IntegerComposition (IntegerComposition const &other)
 
__host__ __device__ int value () const
 
__host__ __device__ int length () const
 
__host__ __device__ int max () const
 
__host__ __device__ Index_t dim () const
 
__host__ void status (void) const
 Show the status of the instance.
 
template<typename Vector_t >
__host__ __device__ Index_t partToOrdinal (Vector_t const &vec) const
 Converts an composition of the integer N from a vector form to an ordinal number.
 
template<class Vector_t >
__host__ __device__ void ordinalToPart (Vector_t &vec, Index_t const num) const
 Converts an ordinal number of a composition of the integer N to a vector form.
 
__host__ __device__ Eigen::RowVectorXi ordinalToPart (Index_t const num) const
 
template<typename Index_ >
__host__ __device__ int locNumber (Index_ const num, Index_ const pos) const
 
template<class Vector_t >
__host__ __device__ Index_t translate (Index_t const num, int trans, Vector_t &workSpace) const
 
__host__ __device__ Index_t translate (Index_t const num, int trans) const
 

Private Types

typedef unsigned long Index_t
 

Private Attributes

int m_N
 
int m_Length
 
int m_Max
 
Index_t m_dim
 
Eigen::MatrixX< Index_tworkA
 
Eigen::MatrixX< Index_tworkB
 

Detailed Description

Lists a weak composition of an integer N up to length L with a constraint that each summand does not exceed Max.

Member Typedef Documentation

◆ Index_t

typedef unsigned long IntegerComposition::Index_t
private

Constructor & Destructor Documentation

◆ IntegerComposition() [1/3]

__host__ __device__ IntegerComposition::IntegerComposition ( )
inline

Construct a new Integer Composition object.

Parameters
NInteger to be decomposed
LengthNumber of parts into which N is decomposed
MaxMaximum number of each part that composes the integer N
75{ debug_constructor_printf(Default); }

◆ IntegerComposition() [2/3]

IntegerComposition::IntegerComposition ( int  N,
int  Length,
int  Max 
)
inline
156 : m_N(N),
157 m_Length(Length),
158 m_Max(Max < N ? Max : N),
159 workA(N + 1, Length),
160 workB(N + 1, Length) {
161 // debug_printf("IntegerComposition::IntegerComposition(%d,%d,%d) : Dim = %d\n", (int)N,
162 // (int)Length, (int)Max, (int)m_dim);
163 if(Length <= 1) {
164 m_dim = Length;
165 return;
166 }
167
168 int max = std::min(Max, N);
169 auto& Dims = workB;
170 for(int l = 0; l < Length; ++l) Dims(0, l) = 1;
171 for(int n = N; n > max; --n) {
172 Dims(n, 1) = 0;
173 Dims(n, 0) = 0;
174 workA(n, 0) = 0;
175 }
176 for(int n = max; n >= 0; --n) {
177 Dims(n, 1) = 1;
178 Dims(n, 0) = 0;
179 workA(n, 0) = 0;
180 }
181 // Recursively calculate Dims(l,n) for remaining (l,n)
182 for(int l = 2; l < Length; ++l)
183 for(int n = 1; n <= N; ++n) {
184 Dims(n, l) = 0;
185 for(int k = 0; k <= std::min(max, n); ++k) { Dims(n, l) += Dims(n - k, l - 1); }
186 }
187 // std::cout << Dims << "\n" << std::endl;
188
189 for(int l = 1; l < Length; ++l) {
190 workA(0, l) = Dims(N, Length - l);
191 for(int n = 1; n <= N; ++n) workA(n, l) = workA(n - 1, l) + Dims(N - n, Length - l);
192 }
193 // std::cout << workA << "\n" << std::endl;
194
195 for(int l = 0; l < Length; ++l) workB(0, l) = 0;
196 for(int n = 1; n <= N; ++n) {
197 for(int l = 1; l < Length - 1; ++l) workB(n, l) = workA(n - 1, l) - workA(n - 1, l + 1);
198 workB(n, Length - 1) = workA(n - 1, Length - 1);
199 }
200 // std::cout << workB << "\n" << std::endl;
201
202 m_dim = workA(max, 1);
203 // std::cout << "Dim = " << m_dim << std::endl;
204 debug_printf("(END) IntegerComposition::IntegerComposition(%d,%d,%d) : Dim = %d\n", (int)N,
205 (int)Length, (int)Max, (int)m_dim);
206}
int m_Length
Definition IntegerComposition.hpp:61
int m_N
Definition IntegerComposition.hpp:60
Eigen::MatrixX< Index_t > workB
Definition IntegerComposition.hpp:65
__host__ __device__ int max() const
Definition IntegerComposition.hpp:89
int m_Max
Definition IntegerComposition.hpp:62
Eigen::MatrixX< Index_t > workA
Definition IntegerComposition.hpp:64
Index_t m_dim
Definition IntegerComposition.hpp:63

◆ IntegerComposition() [3/3]

__host__ __device__ IntegerComposition::IntegerComposition ( IntegerComposition const &  other)
inline
78 : m_N(other.value()),
79 m_Length(other.length()),
80 m_Max(other.max()),
81 m_dim(other.dim()),
82 workA(other.workA),
83 workB(other.workB) {
84 debug_constructor_printf((Copy));
85 }

Member Function Documentation

◆ dim()

__host__ __device__ Index_t IntegerComposition::dim ( ) const
inline
90{ return m_dim; };

◆ length()

__host__ __device__ int IntegerComposition::length ( ) const
inline
88{ return m_Length; };

◆ locNumber()

template<typename Index_ >
__host__ __device__ int IntegerComposition::locNumber ( Index_ const  num,
Index_ const  pos 
) const
inline
254 {
255 // Eigen::ArrayXi config(m_Length);
256 // this->ordinalToPart(config, num);
257 // return config(pos);
258
259 auto num_copy = num;
260 auto position = ((pos % m_Length) + m_Length) % m_Length;
261 int z = 0, zprev = 0;
262 int l;
263 for(l = 1; l != m_Length - position; ++l) {
264 assert(z < workA.rows());
265 assert(l < workA.cols());
266 while(workA(z, l) <= num_copy) z += 1;
267 zprev = z;
268
269 assert(z < workB.rows());
270 assert(l < workB.cols());
271 num_copy -= workB(z, l);
272 }
273 assert(z < workA.rows());
274 assert(l < workA.cols());
275 if(pos == 0) { return m_N - z; }
276 else {
277 while(workA(z, l) <= num_copy) z += 1;
278 return z - zprev;
279 }
280}

◆ max()

__host__ __device__ int IntegerComposition::max ( ) const
inline
89{ return m_Max; };

◆ ordinalToPart() [1/2]

__host__ __device__ Eigen::RowVectorXi IntegerComposition::ordinalToPart ( Index_t const  num) const
inline
136 {
137 Eigen::RowVectorXi res(this->m_Length);
138 this->ordinalToPart(res, num);
139 return res;
140 }
__host__ __device__ void ordinalToPart(Vector_t &vec, Index_t const num) const
Converts an ordinal number of a composition of the integer N to a vector form.
Definition IntegerComposition.hpp:225

◆ ordinalToPart() [2/2]

template<typename Vector_t >
__host__ __device__ void IntegerComposition::ordinalToPart ( Vector_t &  vec,
IntegerComposition::Index_t const  num 
) const
inline

Converts an ordinal number of a composition of the integer N to a vector form.

Parameters
[out]vecA vector to which the resulting composition of the integer N is assigned
[in]numAn ordinal of a composition of the integer N to be converted to a vector form
226 {
227 IntegerComposition::Index_t num_copy = num;
228 int z = 0, zprev = 0;
229#ifndef __CUDA_ARCH__
230 vec.resize(m_Length);
231#else
232 assert(vec.size() >= m_Length);
233#endif
234 // if constexpr(is_container_v<Vector_t>) { vec.resize(m_Length); }
235 for(int l = 1; l != m_Length; ++l) {
236 assert(z < workA.rows());
237 assert(l < workA.cols());
238 while(workA(z, l) <= num_copy) z += 1;
239
240 assert(m_Length - l >= 0);
241 assert(m_Length - l < vec.size());
242 vec[m_Length - l] = z - zprev;
243 zprev = z;
244
245 assert(z < workB.rows());
246 assert(l < workB.cols());
247 num_copy -= workB(z, l);
248 }
249 vec[0] = m_N - z;
250}
unsigned long Index_t
Definition IntegerComposition.hpp:59

◆ partToOrdinal()

template<typename Vector_t >
__host__ __device__ IntegerComposition::Index_t IntegerComposition::partToOrdinal ( Vector_t const &  vec) const
inline

Converts an composition of the integer N from a vector form to an ordinal number.

Parameters
[in]vecComposition of the integer N
Returns
unsigned long : An ordinal number corresponding to the input composition (vec) of N.
Note
An ordinal here is a non-negative number, including zero.
210 {
211 IntegerComposition::Index_t z = 0, res = 0;
212 for(int l = 1; l != int(m_Length); ++l) {
213 assert(m_Length - l >= 0);
214 assert(m_Length - l < vec.size());
215 z += vec[m_Length - l];
216
217 assert(z < workB.rows());
218 assert(l < workB.cols());
219 res += workB(z, l);
220 }
221 return res;
222}

◆ status()

__host__ void IntegerComposition::status ( void  ) const
inline

Show the status of the instance.

  • N: Integer to be decomposed
  • Length: Number of parts into which N is decomposed
  • Max: Maximum number of each part that composes the integer N
  • Dim: Number of ways to decompose the integer N
99 {
100 std::cout << "IntegerComposition.status()"
101 << "\n"
102 << "\tValue:" << this->m_N << "\n"
103 << "\tLength:" << this->m_Length << "\n"
104 << "\tMax: " << this->m_Max << "\n"
105 << "\tDim: " << this->m_dim << std::endl;
106 std::cout << "workA:\n"
107 << workA << "\n"
108 << "workB:\n"
109 << workB << std::endl;
110 }

◆ translate() [1/2]

__host__ __device__ Index_t IntegerComposition::translate ( Index_t const  num,
int  trans 
) const
inline
149 {
150 Eigen::ArrayXi config(m_Length);
151 return this->translate(num, trans, config);
152 }
__host__ __device__ Index_t translate(Index_t const num, int trans, Vector_t &workSpace) const
Definition IntegerComposition.hpp:283

◆ translate() [2/2]

template<class Vector_t >
__host__ __device__ IntegerComposition::Index_t IntegerComposition::translate ( IntegerComposition::Index_t const  num,
int  trans,
Vector_t &  workSpace 
) const
inline
284 {
285 if(workSpace.size() < m_Length)
286 debug_printf("%s\n\tworkSpace.size()=%d\n", __PRETTY_FUNCTION__, (int)workSpace.size());
287 assert(workSpace.size() >= m_Length);
288 // debug_printf("%s\n\t workSpace=%p, workSpace.size()=%d, m_Length=%d\n", __PRETTY_FUNCTION__,
289 // workSpace.data(), (int)workSpace.size(), (int)m_Length);
290 this->ordinalToPart(workSpace, num);
291 Index_t z = 0, res = 0;
292 for(int l = 0; l < int(m_Length); ++l) {
293 // if(!(z < workB.rows()) || !(l < workB.cols())) {
294 // debug_printf("\t (z=%d, l=%d), workB.rows()=%d, workB.cols()=%d\n", (int)z, (int)l,
295 // (int)workB.rows(), (int)workB.cols());
296 // }
297 assert(z < workB.rows());
298 assert(l < workB.cols());
299 res += workB(z, l);
300
301 assert(int(m_Length - 1 - l + trans) % workSpace.size() < workSpace.size());
302 z += workSpace[int(m_Length - 1 - l + trans) % workSpace.size()];
303 }
304 return res;
305}

◆ value()

__host__ __device__ int IntegerComposition::value ( ) const
inline
87{ return m_N; };

Member Data Documentation

◆ m_dim

Index_t IntegerComposition::m_dim
private

◆ m_Length

int IntegerComposition::m_Length
private

◆ m_Max

int IntegerComposition::m_Max
private

◆ m_N

int IntegerComposition::m_N
private

◆ workA

Eigen::MatrixX<Index_t> IntegerComposition::workA
private

◆ workB

Eigen::MatrixX<Index_t> IntegerComposition::workB
private

The documentation for this class was generated from the following file: