All your matrix representations belong here!
Project description
Python bindings for tatami
Overview
The mattress package implements Python bindings to the tatami C++ library for matrix representations. Downstream packages can use mattress to develop C++ extensions that are interoperable with many different matrix classes, e.g., dense, sparse, delayed or file-backed. mattress is inspired by the beachmat Bioconductor package, which does the same thing for R packages.
Instructions
mattress is published to PyPI, so installation is simple:
pip install mattress
mattress is intended for Python package developers writing C++ extensions that operate on matrices.
- Add
mattress.includes()
to theinclude_dirs=
of yourExtension()
definition insetup.py
. This will give you access to the various tatami headers to compile your C++ code. - Add
#include "Mattress.h"
to your C++ source files. This defines aMattress
class where theptr
member is a pointer to a tatami matrix. Python-visible C++ functions should expect to take aMattress*
or equivalent address (e.g.,uintptr_t
), after which theptr
should be extracted for use in tatami-compatible functions. - Call
mattress.tatamize()
on Python matrix objects within each of your functions that call tatami C++ code. This will wrap the Python matrix in a tatami-compatible C++ representation for use in the C++ code. The pointer to the C++ instance can be accessed through theptr
property of the returned object, which can then be passed to C++ code as anuintptr_t
to aMattress
instance.
So, for example, we can write ctypes bindings like:
#include "Mattress.h"
extern "C" {
int do_something_interesting(const void* mat) {
return reinterpret_cast<const Mattress*>(mat)->ptr->nrow();
}
}
Which we can subsequently call like:
import mattress
import ctypes as ct
lib = ct.CDLL("compiled.so")
lib.do_something_interesting.restype = ct.c_int
lib.do_something_interesting.argtypes = [ ct.c_void_p ]
def do_something_interesting(x):
mat = mattress.tatamize(x)
return do_something_interesting(x.ptr)
Of course, any FFI that accepts a pointer address can be used here.
Supported matrices
Dense numpy matrices of varying numeric type:
import numpy as np
from mattress import tatamize
x = np.random.rand(1000, 100)
tatamat = tatamize(x)
ix = (x * 100).astype(np.uint16)
tatamat2 = tatamize(ix)
Compressed sparse matrices from scipy with varying index/data types:
from scipy import sparse as sp
from mattress import tatamize
xc = sp.random(100, 20, format="csc")
tatamat = tatamize(xc)
xr = sp.random(100, 20, format="csc", dtype=np.uint8)
tatamat2 = tatamize(xr)
Delayed arrays from the delayedarray package:
from delayedarray import DelayedArray
from scipy import sparse as sp
from mattress import tatamize
import numpy
xd = DelayedArray(sp.random(100, 20, format="csc"))
xd = numpy.log1p(xd * 5)
tatada = tatamize(xd)
To be added:
- File-backed matrices from the FileBackedArray package, including HDF5 and TileDB.
- Arbitrary Python matrices?
Utility methods
The TatamiNumericPointer
instance returned by tatamize()
provides a few Python-visible methods for querying the C++ matrix.
tatamat.nrow() // number of rows
tatamat.column(1) // contents of column 1
tatamat.sparse() // whether the matrix is sparse.
It also has a few methods for computing common statistics:
tatamat.row_sums()
tatamat.column_variances(num_threads = 2)
grouping = [i%3 for i in range(tatamat.ncol())]
tatamat.row_medians_by_group(grouping)
tatamat.row_nan_counts()
tatamat.column_ranges()
These are mostly intended for non-intensive work or testing/debugging. It is expected that any serious computation should be performed by iterating over the matrix in C++.
Operating on an existing pointer
If we already have a TatamiNumericPointer
, we can easily apply additional operations by wrapping it in the relevant delayedarray layers and calling tatamize()
afterwards.
For example, if we want to add a scalar, we might do:
from delayedarray import DelayedArray
from mattress import tatamize
import numpy
x = numpy.random.rand(1000, 10)
tatamat = tatamize(x)
wrapped = DelayedArray(tatamat) + 1
tatamat2 = tatamize(wrapped)
This avoids relying on x
and is more efficient as it re-uses the TatamiNumericPointer
generated from x
.
Developer Notes
Build the shared object file:
python setup.py build_ext --inplace
For quick testing, we usually do:
pytest
For more complex testing, we do:
python setup.py build_ext --inplace && tox
To rebuild the ctypes bindings with cpptypes:
cpptypes src/mattress/lib --py src/mattress/_cpphelpers.py --cpp src/mattress/lib/bindings.cpp --dll _core
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for mattress-0.1.5-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2b192c5c1a2fc6ff7940e325fa444728e7fbe22902392ee5b62fa4fd427bdadf |
|
MD5 | 286d7b655a53a7f49a8575c9d22c845a |
|
BLAKE2b-256 | 7545b6f35bd287964eed844a6a3960584c9d00dd196474430b730a0bae429569 |
Hashes for mattress-0.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 38bc1cddb5a465b91152951bb9ed5bbe67400c27c7bcbff967e214f4e96b8673 |
|
MD5 | 341adc3f8a23a8966cfd5711a14b7805 |
|
BLAKE2b-256 | b76a26bff8daa3b083032be9c3a05d91f2e086166dd41e711fda473ede884dce |
Hashes for mattress-0.1.5-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cb75b846834679eb1380d96e2c313c73d8c7b89a022072fe7caf34b3192f9309 |
|
MD5 | 76007d2a2873f71e983a1921cc17fc0b |
|
BLAKE2b-256 | eb63820c88968796b8cc74d11aa1ecee9b40d3be87a945f467f15aab5a9bf815 |
Hashes for mattress-0.1.5-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 53fbc307dbf487ee1840696e0c1ba8c490a818baf0475cc6208cea4c2519b5cd |
|
MD5 | d68c248272a1439c9f69c3bc683bbaed |
|
BLAKE2b-256 | 3f90cb26c3cd746cebc54af54c1f325c1c0b6a02dc9dcd921a0fde0e289b8e4b |
Hashes for mattress-0.1.5-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b44b6fce1db8b44be6effee7e803264c2cc0d621ca9c63f08a65ce23ed79c909 |
|
MD5 | 6d7937c31a6f4285b6b2a721e4b5ad4c |
|
BLAKE2b-256 | 3f0ebfb131eff8666e691a36fd2894860c3c2dc77ee9e4df4cc30d6057a2d037 |
Hashes for mattress-0.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 73548c350fa99b851f70efb7af46c621dc3ed3c6b5ceea9563f8c7fc55bef6e1 |
|
MD5 | 06e75d335218c976ef651dfe559ac9f7 |
|
BLAKE2b-256 | 590a97b1a722d89a985973c954d42d941067ff7782f6eae993d0a4d9e37ffcde |
Hashes for mattress-0.1.5-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 13bd76a2caff13a7c0381ceb3d6d6907a3ac5128a267ddb52e6be7a97140e4d7 |
|
MD5 | 4f13558c8e67c49d164cd09ac7ddc782 |
|
BLAKE2b-256 | 58f987b57195a645f5294091f7654288f739703e80577655ce2150cc324b9a5b |
Hashes for mattress-0.1.5-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aa737a5a2de05da8b66213acc48e4fc77a6dbb45447318389efabc3dc8a7a9c9 |
|
MD5 | f03b1b632cdee1124cb894b1eb4d8bca |
|
BLAKE2b-256 | fa25e906764987ae942e1033651127b0c279fc8c2943aa469e7627e942f161e1 |
Hashes for mattress-0.1.5-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 67594bd0136e166ad69cf745c5d2bf3af297cc1a13c414b31d4036ff1e0aa440 |
|
MD5 | 30762dc12036f2f4a49371c704078b5f |
|
BLAKE2b-256 | 212ce5095d5c64fc6274253216e0392f35435c7da040fdb25b2a90fd14192a90 |
Hashes for mattress-0.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 57632eba14bcf17aa567f8d4fb0d6690025e4f5299d22e2a07c74cfb151d2b4b |
|
MD5 | 933097a9f50bc4a4d858f70763848f71 |
|
BLAKE2b-256 | 151f17391c362a7aea618b4fd74f2110972533b5bfb55c8ab48bd7efa7e75041 |
Hashes for mattress-0.1.5-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e27a6e9d20e4537d921000d1b8140ae3f324742418d2918bc004f895af94ddae |
|
MD5 | ea09319cc5ebe1ea5b6c5d9f64ff4f09 |
|
BLAKE2b-256 | 9402aaa85c310fb2f3b87c7c07a407a3a3862b5ac33e57bdf120afcfa906f81f |
Hashes for mattress-0.1.5-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6a5dabcd58db27fe17b6d47b8f3b8be506af9efd5122e5e08de4952f256ccb34 |
|
MD5 | 47b049babaebcd0bb0897b8c0e9e34ac |
|
BLAKE2b-256 | fac77276e83a72850c45fb05903cb1c8e73f27a1000fd1f2de806da3511ce5d9 |
Hashes for mattress-0.1.5-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e2e4f3d64086814387c9a55df06bc2de98b9ca7eea49a581259c38439956cb04 |
|
MD5 | 3ad13dd6cef3a62bb6ebdb59ecac9236 |
|
BLAKE2b-256 | b24061edcaa0024f6c10f7ae87d239497f6c8bf63c018e7c25abdf2e050c5657 |
Hashes for mattress-0.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 677dc08c3b2d4f5130d1dae4b86aa3ef08a6f5f03a3e7917114bf7c4258f9495 |
|
MD5 | 425704436f1d3cfceb8db345e6923a07 |
|
BLAKE2b-256 | 0d79c29f9bf95295e820355768edee98ed85078676473e0df4efac9dc90f51c9 |
Hashes for mattress-0.1.5-cp38-cp38-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 756b2504d8d2be0b95ad03579b4be2963d39389cc0afbe295f58e9284fb4aa45 |
|
MD5 | e7ffb558435d93c891beebd6f0fc0b55 |
|
BLAKE2b-256 | a20e70a37b2ef127b344c0051da71ddbd889f4e264fc7c9264864275eb081b76 |
Hashes for mattress-0.1.5-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2e6b19686e446925b129b059af8761224848b677feb3898f3d961be71713de86 |
|
MD5 | 0f00bb793a15192f174d9247dacbd7a0 |
|
BLAKE2b-256 | 0fd4662239dbff479ae9211ebac333eafc72380847d34e7a2f808c500c9a7288 |