Skip to content

Commit a659d27

Browse files
authored
Merge pull request #59 from jwood000/repcapped-compositions
feat: add capped repetition compositions and fix permuteIter() Extend the compositions framework to support capped (maximum-part) compositions with repetition across counting, generation, ranking, unranking (nth), sampling, and iteration. This includes weak and mapped-zero variants and integrates fully with existing combinatorial APIs such as compositionsGeneral(), compositionsRank(), compositionsSample(), and compositionsIter(). Counting is implemented using exact inclusion–exclusion in the GMP path, with double-return wrappers computing the full sum in mpz_class before converting to double to avoid precision loss and cancellation errors. Harden binomial coefficient helpers (nChooseK, nChooseKGmp) to return 0 for invalid inputs and avoid unsafe signed-to-unsigned conversion into GMP routines, preventing incorrect results and pathological computations. Fix iterator dispatch for permutation-of-partition constrained cases so permuteIter() produces correct results when problems reduce to partition/composition counting. Add extensive tests covering capped composition families, parallel ranking paths, GMP-index workflows, and permutation-of-partition iterator correctness. These changes are additive and maintain backwards compatibility.
2 parents cf05cae + 8417a59 commit a659d27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1872
-238
lines changed

.github/workflows/test-coverage.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ jobs:
2424

2525
- uses: r-lib/actions/setup-r-dependencies@v2
2626
with:
27-
extra-packages: any::covr
27+
extra-packages: |
28+
any::covr
29+
any::xml2
2830
needs: coverage
2931

3032
- name: Test coverage

DESCRIPTION

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,15 @@ URL: https://jwood000.github.io/RcppAlgos/,
3030
BugReports: https://github.com/jwood000/RcppAlgos/issues
3131
LinkingTo: cpp11
3232
Imports: gmp, methods
33-
Suggests: testthat, partitions, microbenchmark, knitr, RcppBigIntAlgos, rmarkdown
33+
Suggests:
34+
testthat,
35+
partitions,
36+
microbenchmark,
37+
knitr,
38+
RcppBigIntAlgos,
39+
rmarkdown,
40+
covr,
41+
xml2
3442
Config/Needs/website: pkgdown
3543
License: GPL (>=2)
3644
SystemRequirements: gmp (>= 4.2.3)

NEWS.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,39 @@
11
# RcppAlgos 2.10.0
22

3+
This release introduces major enhancements to the compositions framework, including support for distinct and repetition-restricted compositions, parallel ranking, and performance improvements across several combinatorial algorithms.
4+
5+
These enhancements integrate fully with the existing counting, ranking, sampling, and iterator infrastructure, and have been validated for correctness and consistency across supported combinatorial families.
6+
37
## New Features:
48

5-
* Added parallel capabilities to all ranking functions via the new `nThreads` argument (e.g. `partitionsRank(..., nThreads = 4)`, `comboRank(..., nThreads = 4)`).
6-
* Implemented a next-lexicographical algorithm for generating distinct integer compositions, enabling efficient large-scale generation such as `compositionsGeneral(50, 8)`.
7-
* Added accompanying algorithms for the distinct integer composition case, exposed through: `compositionsSample`, `compositionsRank`, and `compositionsIter`.
8-
* Enhanced `permuteCount()` to count permutations of partitions when called with `constraintFun = "sum"` and `comparisonFun = "=="`, allowing optimized counting in cases that reduce to partition/composition counting.
9+
* Added parallel capabilities to all ranking functions via a new `nThreads` argument (e.g. `comboRank()`, `partitionsRank()`, `compositionsRank()`), enabling faster ranking of large combinatorial results.
10+
* Implemented a next-lexicographical algorithm for generating **distinct integer compositions**, enabling efficient generation of large problems such as `compositionsGeneral(50, 8)`.
11+
* Added full support for distinct compositions across the compositional framework, including:
912

10-
## Bug Fixes:
13+
* `compositionsGeneral()`
14+
* `compositionsSample()`
15+
* `compositionsRank()`
16+
* `compositionsIter()`
1117

12-
* Improved input validation for constraint-based calls by requiring `comparisonFun` to be a character vector (now errors early with a clearer message).
13-
* Fixed edge-case handling in partition iteration logic where boundary-derived indices could become negative, preventing incorrect behavior in some partition/multiset scenarios.
18+
* Added support for **compositions with repetition subject to a maximum part constraint** ("capped compositions"), including weak and non-weak cases, with full support for counting, ranking, sampling, and iteration.
19+
* Enhanced `permuteCount()` to count permutations of partitions when called with `constraintFun = "sum"` and `comparisonFun = "=="`, enabling faster counting when problems reduce to partition/composition counting.
1420

1521
## Improvements:
1622

17-
* Added a package load-time check that validates the loaded shared library matches the installed package version, producing a clear reinstall/restart error instead of potential crashes from stale binaries.
18-
* Improved handling of singleton `v` with singleton `freqs` so that numeric values are interpreted correctly in some constrained/ranking paths.
19-
* Added nonexported `permutePartsDesign()` to inspect the partition-design/counting setup used by `permuteCount()` when it reduces to a partition/composition counting problem.
23+
* Added validation at package load time to ensure the loaded shared library matches the installed package version, producing a clear error message instead of potential crashes caused by stale compiled code.
24+
* Improved handling of certain constrained and ranking cases involving singleton inputs.
25+
* Added internal tooling to support partition and composition counting workflows.
2026

2127
## Performance:
2228

23-
* General performance improvements for ranking and composition-related algorithms, including multi-threaded ranking support.
29+
* Improved performance of ranking and generation algorithms, including support for parallel ranking.
30+
* Improved performance and scalability of composition-related algorithms, particularly for constrained and distinct composition problems.
2431

25-
## Internal:
32+
## Bug Fixes:
2633

27-
* Added developer tooling and expanded internal type/class infrastructure to support the new composition and counting paths.
34+
* Fixed an issue in `permuteIter()` affecting cases that reduce to permutations of partitions, which could previously produce incorrect iteration results.
35+
* Improved input validation for constraint-based calls, producing clearer error messages for invalid inputs.
36+
* Fixed edge-case issues affecting certain partition and composition iteration scenarios.
2837

2938
# RcppAlgos 2.9.5
3039

inst/NEWS.Rd

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
\name{NEWS}
22
\title{News for Package \pkg{RcppAlgos}}
33

4-
\section{Changes in RcppAlgos version 2.10.0 (Release date: 2026-02-21)}{
4+
\section{Changes in RcppAlgos version 2.10.0 (Release date: 2026-03-05)}{
55
\itemize{
6-
\item New Features:
7-
\itemize{
8-
\item Added parallel capabilities to all ranking functions via the new \code{nThreads} argument (e.g. \code{partitionsRank(..., nThreads = 4)}, \code{comboRank(..., nThreads = 4)}).
9-
\item Implemented a next-lexicographical algorithm for generating distinct integer compositions, enabling efficient large-scale generation such as \code{compositionsGeneral(50, 8)}.
10-
\item Added accompanying algorithms for the distinct integer composition case, exposed through: \code{compositionsSample}, \code{compositionsRank}, and \code{compositionsIter}.
11-
\item Enhanced \code{permuteCount()} to count permutations of partitions when called with \code{constraintFun = "sum"} and \code{comparisonFun = "=="}, allowing optimized counting in cases that reduce to partition/composition counting.
12-
}
136

14-
\item Bug Fixes:
7+
\item New Features:
158
\itemize{
16-
\item Improved input validation for constraint-based calls by requiring \code{comparisonFun} to be a character vector (now errors early with a clearer message).
17-
\item Fixed edge-case handling in partition iteration logic where boundary-derived indices could become negative, preventing incorrect behavior in some partition/multiset scenarios.
9+
\item Added parallel capabilities to all ranking functions via the new \code{nThreads} argument (e.g. \code{comboRank()}, \code{partitionsRank()}, \code{compositionsRank()}), enabling faster ranking of large combinatorial results.
10+
\item Implemented a next-lexicographical algorithm for generating distinct integer compositions, enabling efficient generation of large problems such as \code{compositionsGeneral(50, 8)}.
11+
\item Added full support for distinct compositions across the compositional framework, including \code{compositionsGeneral()}, \code{compositionsSample()}, \code{compositionsRank()}, and \code{compositionsIter()}.
12+
\item Added support for compositions with repetition subject to a maximum part constraint ("capped compositions"), including weak and non-weak cases, with full support for counting, ranking, sampling, and iteration.
13+
\item Enhanced \code{permuteCount()} to count permutations of partitions when called with \code{constraintFun = "sum"} and \code{comparisonFun = "=="}, enabling faster counting when problems reduce to partition/composition counting.
1814
}
1915

2016
\item Improvements:
2117
\itemize{
22-
\item Added a package load-time check that validates the loaded shared library matches the installed package version, producing a clear reinstall/restart error instead of potential crashes from stale binaries.
23-
\item Improved handling of singleton \code{v} with singleton \code{freqs} so that numeric values are interpreted correctly in some constrained/ranking paths.
24-
\item Added nonexported \code{permutePartsDesign()} to inspect the partition-design/counting setup used by \code{permuteCount()} when it reduces to a partition/composition counting problem.
18+
\item Added validation at package load time to ensure the loaded shared library matches the installed package version, producing a clear error message instead of potential crashes caused by stale compiled code.
19+
\item Improved handling of certain constrained and ranking cases involving singleton inputs.
20+
\item Added internal tooling to support partition and composition counting workflows.
2521
}
2622

2723
\item Performance:
2824
\itemize{
29-
\item General performance improvements for ranking and composition-related algorithms, including multi-threaded ranking support.
25+
\item Improved performance of ranking and generation algorithms, including support for parallel ranking.
26+
\item Improved performance and scalability of composition-related algorithms, particularly for constrained and distinct composition problems.
3027
}
3128

32-
\item Internal:
29+
\item Bug Fixes:
3330
\itemize{
34-
\item Added developer tooling and expanded internal type/class infrastructure to support the new composition and counting paths.
31+
\item Fixed an issue in \code{permuteIter()} affecting cases that reduce to permutations of partitions, which could previously produce incorrect iteration results.
32+
\item Improved input validation for constraint-based calls, producing clearer error messages for invalid inputs.
33+
\item Fixed edge-case issues affecting certain partition and composition iteration scenarios.
3534
}
3635
}
3736
}

inst/include/Partitions/BigPartsCountDistinct.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void CountPartsDistinctRstrctdMZ(
3030
int n, int m, const std::vector<int> &allowed, int strtLen
3131
);
3232

33-
void CountCompDistLenRstrctd(
33+
void CountCompsDistLenRstrctd(
3434
mpz_class &res, std::vector<std::vector<mpz_class>> &p2d,
3535
int n, int m, const std::vector<int> &allowed, int strtLen = 0
3636
);

inst/include/Partitions/BigPartsCountRep.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ void CountCompsRepLen(
2424
const std::vector<int> &allowed = std::vector<int>(), int strtLen = 0
2525
);
2626

27+
void CountCompsRepLenCap(mpz_class &res, int n, int m,
28+
const std::vector<int> &allowed, int strtLen = 0);
29+
30+
void CountCompsRepCapZNotWk(mpz_class &res, int n, int m,
31+
const std::vector<int> &allowed, int strtLen = 0);
32+
2733
void CountCompsRepZNotWk(
2834
mpz_class &res, int n, int m,
2935
const std::vector<int> &allowed = std::vector<int>(), int strtLen = 0

inst/include/Partitions/CompositionsRep.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@
33
#include "RMatrix.h"
44
#include <vector>
55

6+
template <int one_or_zero, typename T>
7+
int CompsGenRepCapped(T* mat, const std::vector<T> &v, std::vector<int> &z,
8+
std::size_t width, std::size_t nRows);
9+
610
template <int one_or_zero, typename T>
711
int CompsGenRep(T* mat, const std::vector<T> &v, std::vector<int> &z,
812
std::size_t width, std::size_t nRows);
913

14+
template <int one_or_zero, typename T>
15+
int CompsGenRepCapped(RcppParallel::RMatrix<T> &mat, const std::vector<T> &v,
16+
std::vector<int> &z, std::size_t strt,
17+
std::size_t width, std::size_t nRows);
18+
1019
template <int one_or_zero, typename T>
1120
int CompsGenRep(RcppParallel::RMatrix<T> &mat, const std::vector<T> &v,
1221
std::vector<int> &z, std::size_t strt,

inst/include/Partitions/CompositionsDistinctUtils.h renamed to inst/include/Partitions/CompositionsUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ bool IsComplementZeroBased(bool firstZero, bool isWeak, bool IsGen);
99
int GetFirstPartitionDistinct(const std::vector<int> &v, std::vector<int> &z,
1010
int target, int m, int lenV);
1111

12+
template <int one_or_zero>
13+
void FillTailRep(std::vector<int> &z, int strt, int cap, int lastCol);
14+
1215
int NextDistinctBlock(const std::vector<int> &v, std::vector<int> &idx,
1316
std::vector<int> &tailSum, int target, int m);
1417

inst/include/Partitions/NextComposition.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
template <int one_or_zero>
66
void NextCompositionRep(std::vector<int> &z, int lastCol);
77

8+
template <int one_or_zero>
9+
void NextCompositionRep(std::vector<int> &z, int lastCol, int cap);
10+
811
void NextCompositionDistinct(
912
std::vector<int> &z, std::vector<int> &complement, std::vector<int> &idx,
1013
std::vector<int> &tailSum, int &i1, int &i2, int &myMax, int lastCol,

inst/include/Partitions/PartitionsClass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#include "Partitions/CompositionsDistinctUtils.h"
3+
#include "Partitions/CompositionsUtils.h"
44
#include "Partitions/NextComposition.h"
55
#include "ClassUtils/ComboResClass.h"
66
#include "Partitions/NextPartition.h"

0 commit comments

Comments
 (0)