Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/pypi-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Publish to PyPI

on:
push:
tags:
# Publish on any tag starting with a `v`, e.g., v1.2.3
- v*

jobs:
deploy:
name: Publish to PyPI
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v6
- name: Install prerequisites
uses: astral-sh/setup-uv@v7
- name: Install project
run: uv sync --all-groups
- name: Build wheel
run: uv build --sdist
- name: Publish package to PyPI
run: uv publish
2 changes: 1 addition & 1 deletion .github/workflows/r-cmd-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ jobs:
check-dir: '"check"'
- name: artifacts
if: ${{ matrix.config.r == 'release' && matrix.config.os == 'ubuntu-latest' }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
path: check
4 changes: 2 additions & 2 deletions R/humanleague.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#' \itemize{
#' \item{Iterative Proportional Fitting (IPF), \emph{a la} \pkg{mipfp} package}
#' \item{\href{http://jasss.soc.surrey.ac.uk/20/4/14.html}{Quasirandom Integer Sampling (QIS)} (no seed population)}
#'- \item{Quasirandom Integer Sampling of IPF (QISI): A combination of the two techniques whereby IPF solutions are used to sample an integer population.}
#' \item{Quasirandom Integer Sampling of IPF (QISI): A combination of the two techniques whereby IPF solutions are used to sample an integer population.}
#'}
#'
#' The latter provides a bridge between deterministic reweighting and combinatorial optimisation, offering advantages of both techniques:
Expand All @@ -30,7 +30,7 @@
#' The package also contains the following utility functions:
#' \itemize{
#' \item{a Sobol sequence generator}
#' - \item{functionality to convert fractional to nearest-integer marginals (in 1D). This can also be achieved in multiple dimensions by using the QISI algorithm.}
#' \item{functionality to convert fractional to nearest-integer marginals (in 1D). This can also be achieved in multiple dimensions by using the QISI algorithm.}
#' \item{functionality to 'flatten' a population into a table: this converts a multidimensional array containing the population count for each state into a table listing individuals and their characteristics.}
#'}

Expand Down
20 changes: 10 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "humanleague"
version = "2.4.4"
version = "2.4.5"
authors = [
{ name="Andrew Smith", email="andrew@friarswood.net" },
]
Expand All @@ -25,19 +25,19 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"numpy>=2.4.1",
"pandas>=2.3.3",
"pandas-stubs>=2.2.3.250308",
"numpy>=2.4.5",
"pandas>=3.0.3",
]

[dependency-groups]
dev = [
"pybind11>=3.0.0",
"pytest>=8.1.4",
"ruff>=0.12.9",
"build>=1.2.2.post1",
"ty>=0.0.31",
"pre-commit>=4.5.1",
"pybind11>=3.0.4",
"pytest>=9.0.3",
"ruff>=0.15.13",
"build>=1.5.0",
"ty>=0.0.37",
"pre-commit>=4.6.0",
"pandas-stubs>=3.0.0.260204",
]

[tool.pytest.ini_options]
Expand Down
2 changes: 1 addition & 1 deletion src/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ template <typename T> std::string to_string_impl(T v) { return std::to_string(v)
// print pointer
template <typename T> std::string to_string_impl(T* p) {
constexpr size_t BUF_SIZE = 20;
static char buf[BUF_SIZE];
char buf[BUF_SIZE];
std::snprintf(buf, BUF_SIZE, "0x%016zx", reinterpret_cast<size_t>(p));
return std::string(buf);
}
Expand Down
6 changes: 3 additions & 3 deletions src/NDArrayUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ template <typename T> T min(const NDArray<T>& a) {
}

template <typename T> T max(const NDArray<T>& a) {
T minVal = std::numeric_limits<T>::max();
T maxVal = std::numeric_limits<T>::lowest();
for (Index i(a.sizes()); !i.end(); ++i) {
minVal = std::min(minVal, a[i]);
maxVal = std::max(maxVal, a[i]);
}
return minVal;
return maxVal;
}

// TODO move printing somehwere else
Expand Down
5 changes: 3 additions & 2 deletions src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ template <typename T> NDArray<T> asNDArray(const py::array_t<T>& np) {
}

template <typename T> py::array_t<T> fromNDArray(const NDArray<T>& a) {
// TODO ensure this is safe. may need to explicitly copy data
return py::array_t<T>(a.sizes(), a.rawData());
py::array_t<T> result(a.sizes());
std::copy(a.rawData(), a.rawData() + a.storageSize(), result.mutable_data());
return result;
}

std::vector<std::vector<int64_t>> collect_indices(const py::iterable& iterable) {
Expand Down
9 changes: 0 additions & 9 deletions src/rcpp_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,6 @@ List ipf(NumericVector seed, List indices, List marginals) {
std::vector<int64_t> s;
s.reserve(dim);

if (indices.size() != marginals.size())
throw std::runtime_error("no. of marginals not equal to no. of indices");

// assemble dimensions (row major) for seed
for (int64_t i = dim - 1; i >= 0; --i)
s.push_back(rSizes[(size_t)i]);
Expand Down Expand Up @@ -203,9 +200,6 @@ List qis(List indices, List marginals, int skips = 0) {
std::vector<std::vector<int64_t>> idx;
idx.reserve(k);

if (indices.size() != marginals.size())
throw std::runtime_error("no. of marginals not equal to no. of indices");

// insert indices and marginals in reverse order (R being column-major)
for (int64_t i = k - 1; i >= 0; --i) {
const IntegerVector& iv = indices[i];
Expand Down Expand Up @@ -288,9 +282,6 @@ List qisi(NumericVector seed, List indices, List marginals, int skips = 0) {
std::vector<int64_t> s;
s.reserve(dim);

if (indices.size() != marginals.size())
throw std::runtime_error("no. of marginals not equal to no. of indices");

// assemble dimensions (row major) for seed
for (int64_t i = dim - 1; i >= 0; --i)
s.push_back(rSizes[(size_t)i]);
Expand Down
Loading