31 static const unsigned precomputed[]= {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600};
32 GISMO_ASSERT(n < util::size(precomputed),
"Overflow when computing factorial.");
33 return precomputed[n];
71 GISMO_ASSERT(r>=0,
"binomial coefficient (n,r) exists only for n,r positive");
74 const Z diff = math::min( n-r, r );
100 for (
unsigned i = 1; i <= n; ++i)
103 for (
unsigned j= i-1; j>0; --j)
109 template<
int n,
int r>
class binomialT
110 {
public:
enum { value= binomialT<n-1,r-1>::value+binomialT<n-1,r>::value};};
111 template<
int n>
class binomialT<n,n> {
public:
enum { value= 1};};
112 template<>
class binomialT<0,0> {
public:
enum { value= 1};};
113 template<
int n>
class binomialT<n,0> {
public:
enum { value= 1};};
124 template <
unsigned n,
unsigned r>
125 inline unsigned binomial () {
return binomialT<n,r>::value;}
131 Vec result(sz.size());
133 for (
index_t i=1; i != sz.size(); ++i )
134 result[i] = result[i-1] * sz[i-1];
144 res= Vec::LinSpaced(r,0,r-1);
146 std::cerr <<
"Error: r>n combination requested. r="<< r<<
", n="<< n<<
"\n";
156 if (v == Vec::LinSpaced(r,n-r,n-1))
return false;
158 while (v[i] == n-r+i) --i;
173 const index_t n=current.size();
174 current=Vec::LinSpaced(n,0,n-1);
185 const index_t n=current.size();
186 return std::next_permutation(current.data(), current.data()+n);
199 GISMO_ASSERT( d == size.size(),
"Vector sizes don't match in nextLexicographic" );
201 for (
index_t i = 0; i < d; ++i)
204 if (++cur[i] == size[i])
214 GISMO_ERROR(
"Something went wrong in nextLexicographic, wrong input?");
228 "Vector sizes don't match in nextLexicographic");
230 for (
index_t i = 0; i < d; ++i)
233 if (++cur[i] == end[i])
243 GISMO_ERROR(
"Something went wrong in nextLexicographic, wrong input?");
254 const int d = cur.size();
256 "Vector sizes don't match in nextCubeVertex");
258 for (
int i = 0; i != d; ++i)
260 if ( cur[i] != end[i] )
280 "Vector sizes don't match in nextCubeVertex");
282 for (
index_t i = 0; i != d; ++i)
284 if ( cur[i] != end[i] )
305 GISMO_ASSERT( (cur.array() >= 0).all() && (cur.array() <= 1).all(),
306 "Input must be a vector of zeros and ones, got: "<<cur.transpose() );
308 for (
index_t i = 0; i != d; ++i)
331 "Vector sizes don't match in nextCubePoint");
333 for (
index_t i = 0; i != d; ++i)
335 if ( cur[i] != end[i] )
357 d == static_cast<int>(end.size()),
358 "Vector sizes don't match in nextCubePoint");
360 for (
index_t i = 0; i != d; ++i)
362 if ( cur[i] != end[i] )
376 bool nextCubePoint(Vec & ci,
const Vec& start,
const Vec& end,
const Vec& str)
380 d == static_cast<int>(end.size()),
381 "Vector sizes don't match in nextCubePoint");
383 for (
index_t i = 0; i != d; ++i)
385 if ( ci % str[i] != end[i] )
391 ci -= (end[i]-start[i])*str[i];
406 "Vector sizes don't match in nextCubeBoundary");
408 for (
index_t i = 0; i != d; ++i)
410 if ( cur[i] != end[i] )
412 if ( cur[i] == start[i] && ( i!=d-1 || d==1) )
415 for (
int j = c; j!=d; ++j)
416 if ( (cur[j] == start[j]) ||
428 for (
int k = i-1; k!=-1; --k)
446 "Vector sizes don't match in nextCubeBoundaryOffset");
448 for (
index_t i = 0; i != d; ++i)
450 if ( cur[i] != end[i] )
452 if ( cur[i] == start[i]+offset[i] && ( i!=d-1 || d==1) )
455 for (
int j = c; j!=d; ++j)
456 if (cur[j] <= start[j] + offset[j] ||
457 cur[j] >= end[j] - offset[j] )
461 cur[i] = end[i] - offset[i];
468 for (
int k = i-1; k!=-1; --k)
484 Vec & loffset, Vec & uoffset)
488 "Vector sizes don't match in nextCubeBoundaryOffset");
490 for (
index_t i = 0; i != d; ++i)
492 if ( cur[i] != end[i] )
494 if ( cur[i] == start[i]+loffset[i] && ( i!=d-1 || d==1) )
497 for (
int j = c; j!=d; ++j)
498 if (cur[j] <= start[j] + loffset[j] ||
499 cur[j] >= end[j] - uoffset[j] )
503 cur[i] = end[i] - uoffset[i];
510 for (
int k = i-1; k!=-1; --k)
536 return (cur.array() == 2).count();
548 cur.topRows (k ).setConstant(2);
549 cur.bottomRows(d-k).setConstant(0);
562 GISMO_ASSERT(k >= 0 && k<=cur.size(),
"Invalid arguments.");
567 for (i = 0; i != d; ++i)
572 if ( (cur.array() == 2).count() == k )
596 template <
typename Z,
int d>
601 const index_t dd = flip.size();
602 GISMO_ASSERT( dd == perm.size(),
"Dimensions do not match in cubeIsometry");
603 GISMO_ASSERT( perm.sum() == dd*(dd-1)/2,
"Error in the permutation: "<< perm.transpose());
607 pstr[k] = (1<<perm[k]);
609 result.resize(1<<dd);
618 c += ( flip[perm[k]] == v[k] ) * pstr[k];
620 for (i = 0; i != dd; ++i)
651 result(perm(i),i) = (flip(perm(i)) ? 1 : -1);
659 res.derived().resize(dim);
669 const index_t k = v.size() - 1;
673 for (
index_t i = 0; i <= k; ++i)
677 const typename Vec::Scalar t = v[i];
700 template<
class Vec,
class Mat>
705 res.row(0) = a.transpose();
722 for (
index_t j = 0; j != d; ++j)
724 typename Mat::ColXpr c_j = m.col(j);
745 for (
index_t j = 0; j != d; ++j)
746 result *= binomial<unsigned>(a[j]+k-1, k-1);
752 template<
class Z,
unsigned d>
755 bool operator() (
const gsVector<Z,d> & lhs,
const gsVector<Z,d> & rhs)
const
758 while( (i<d) && (lhs[i] == rhs[i++]) ) ;
759 return ( --i==d ?
false : lhs[i] < rhs[i] );
Z binomial(const Z n, const Z r)
Computes the binomial expansion coefficient binomial(n,r)
Definition: gsCombinatorics.h:69
bool nextCubePoint(Vec &cur, const Vec &end)
Iterate in lexigographic order through the points of the integer lattice contained in the cube [0...
Definition: gsCombinatorics.h:327
bool nextCubeBoundary(Vec &cur, const Vec &start, const Vec &end)
Iterates in lex-order through the boundary points of the cube [start,end]. Updates cur with the curre...
Definition: gsCombinatorics.h:402
void firstComposition(typename Vec::Scalar sum, index_t dim, Vec &res)
Construct first composition of sum into dim integers.
Definition: gsCombinatorics.h:657
#define short_t
Definition: gsConfig.h:35
bool nextMultiComposition(Mat &m)
Returns (inplace) the next multi-composition in lexicographic order.
Definition: gsCombinatorics.h:717
#define index_t
Definition: gsConfig.h:32
void firstMultiComposition(const Vec &a, index_t k, Mat &res)
Constructs first multi-composition of a = (a_1,..,a_d) into k integers.
Definition: gsCombinatorics.h:701
index_t numCubeElements(const index_t k, const index_t d)
Returns the number of elements (faces) of dimension k of a d-cube.
Definition: gsCombinatorics.h:522
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition: gsMatrix.h:38
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
index_t dimCubeElement(const Vec &cur)
Returns the dimension of an element (face) of the d-cube [0,1]^d. The element is expected to contain ...
Definition: gsCombinatorics.h:534
bool nextComposition(Vec &v)
Returns (inplace) the next composition in lexicographic order.
Definition: gsCombinatorics.h:667
void firstPermutation(Vec ¤t)
changes current to the first permutation of 0 ... size(current)-1 note that you must resize the vecto...
Definition: gsCombinatorics.h:171
Mathematical functions for use in G+Smo.
void firstCubeElement(Vec &cur, const index_t k=0)
Updates cur to contain the lexicographically first element (face) of the cube [0,1]^d of dimension k...
Definition: gsCombinatorics.h:544
void firstCombination(const unsigned n, const unsigned r, Vec &res)
Computes the first r-combination of {0,..,n-1}.
Definition: gsCombinatorics.h:141
bool nextPermutation(Vec ¤t)
Changes current to the next lexicographically ordered permutation.
Definition: gsCombinatorics.h:183
unsigned numMultiCompositions(const Vec &a, index_t k)
Number of multi-composition of a = (a_1,..,a_d) into k integers.
Definition: gsCombinatorics.h:741
bool nextCubeBoundaryOffset(Vec &cur, const Vec &start, const Vec &end, Vec &offset)
Iterates in lex-order through the boundary points of the cube [start,end], with an \ offset to the in...
Definition: gsCombinatorics.h:442
bool nextCombination(Vec &v, const unsigned n)
Computes the next r-combination of {0,..,n-1}, where r = v.size(). The input v is expected to be a va...
Definition: gsCombinatorics.h:153
bool nextLexicographic(Vec &cur, const Vec &size)
Iterates through a tensor lattice with the given size. Updates cur and returns true if another entry ...
Definition: gsCombinatorics.h:196
Vec stridesOf(const Vec &sz)
Computes the of a vector.
Definition: gsCombinatorics.h:129
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
bool nextCubeElement(Vec &cur, const index_t k)
Iterates in lexicographic order through the elements (faces) of dimension k of the cube [0...
Definition: gsCombinatorics.h:559
This is the main header file that collects wrappers of Eigen for linear algebra.
void cubeIsometryMatrix(const gsVector< bool, d > &flip, const gsVector< index_t, d > &perm, gsMatrix< int, d, d > &result)
Computes the rotation matrix implied by a permutation perm of the cube directions plus a relocation f...
Definition: gsCombinatorics.h:645
void cubeIsometry(const gsVector< bool, d > &flip, const gsVector< index_t, d > &perm, gsVector< Z > &result)
Computes the isometry of the unit d-cube implied by a permutation perm of the cube directions plus a ...
Definition: gsCombinatorics.h:597
unsigned numCompositions(int sum, short_t dim)
Number of compositions of sum into dim integers.
Definition: gsCombinatorics.h:691
unsigned factorial(unsigned n)
Returns the factorial of n i.e. n! Remember that factorial grow too fast and only n! with n<=13 can b...
Definition: gsCombinatorics.h:29
void binomial_into(unsigned n, gsVector< unsigned > &v)
Returns a vector containing all the binomials (n,r) with n fixed.
Definition: gsCombinatorics.h:95
bool nextCubeVertex(Vec &cur, const Vec &start, const Vec &end)
Iterate in lexicographic order through the vertices of the cube [start,end]. Updates cur with the cur...
Definition: gsCombinatorics.h:252