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.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | bf6cb3f7ec37741be21909f9215de20ea0d879e95fbf9e4ba263032f8ded9fdd |
|
MD5 | 51111c93d739afa83fa44dbb0436ca8f |
|
BLAKE2b-256 | fcc6f7522b86ce54c23bd318ebfdf73ce2d662e2499dc4e0e11f13c77e1945f6 |
Hashes for mattress-0.1.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ae6baa3cc64fafa38e42d25753b0f460bb0c621370716b057c573d269d6674b4 |
|
MD5 | 8879ac42fdf3c1cb9371026c77a8d1af |
|
BLAKE2b-256 | 6a8b55cbfba441f36202bbad62a1d7367c391f85b47548a8487824ce882c750c |
Hashes for mattress-0.1.3-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c55efd9c18196d336b92a17b9b3e6d426ad051318f599cf00265ad6af5e7a1c8 |
|
MD5 | d6479da15a12f0ee342fe007971c344d |
|
BLAKE2b-256 | a9572df18757dbf9f6e2e29a87f557cab390f76ea0d995c149131b02da826521 |
Hashes for mattress-0.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b3f9f10297b33cc63c1d095b4f2ac71e0bea09c709621d6b963ed669963165ed |
|
MD5 | 898be739f034dc6fbebef5422d669690 |
|
BLAKE2b-256 | ba96be060535fd7043c828b3d51a1d3802bea32f9af43eab960d7cf049d01cf8 |
Hashes for mattress-0.1.3-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 142717201f96db46cc86b40fd444609973b2e20739d7d58fe4c1610c80686fdf |
|
MD5 | 6480226475659c2948432cc2eeff99d9 |
|
BLAKE2b-256 | c9f5f8351c0c61c2353cad505e206e89e79ddf72e4d4cf67de7744622add01e0 |
Hashes for mattress-0.1.3-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d8e14eff6f13eb2b5d2022c4e4a0ee03779ea8fde5ac73ebe9fb4339dc5780de |
|
MD5 | aec03c758d2884e51e884df03f4c8218 |
|
BLAKE2b-256 | c5e34dc53f333413afb039fd7ba839dbc31ef24be36b20e0488718de742ac6e6 |
Hashes for mattress-0.1.3-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0370114c32aabe991f6e08ddb69a8fc34ca397c17dc02baaff47857135d235cc |
|
MD5 | 83261fa176d91ee4651739d38bdddbdf |
|
BLAKE2b-256 | e7e7aad17cfb863f148d4be343c2e7b1282d58ad6f31cc15f698f96061f8a32c |
Hashes for mattress-0.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8889142dfd141e9dd1abb657fb67e199a29e389e17c9d826774a87cf69ad3389 |
|
MD5 | dba40ba35253088e359ecc50de099e53 |
|
BLAKE2b-256 | e04e94fd4cdf4496c3011470450f3e659296527139fd54bee6b273fc1bda56bc |
Hashes for mattress-0.1.3-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a8a50803175f08f15ea835373c6ef137e93d41e1680058a0fd701821a049f345 |
|
MD5 | 80d95b20ec075a0873a921216864ed12 |
|
BLAKE2b-256 | 17e2beb520ac6447304b3a39573ad52275352dc421fe48272af83dc134dff2db |
Hashes for mattress-0.1.3-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 84728081e79b7b6b9878b08b1201a5bd1552a3a24fde1a4207ebefaac9e02aa0 |
|
MD5 | 5ceda951fec3327c682260aefcb48d4f |
|
BLAKE2b-256 | f23be8cb46bdb69f23a18e4335dd4b335f91920b15ef5b8277ff06a2b4187470 |
Hashes for mattress-0.1.3-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 99576e0be3ee6b50c0a54b45197b980b256029e404cfc025877ee5793109ccfe |
|
MD5 | 642ccc422463bd5bbc32dbea3d9067eb |
|
BLAKE2b-256 | dbb44c6aed0ca70b65c1fcfa1f77e4be706695f0e1204a71fe511a6cf3c45e86 |
Hashes for mattress-0.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | bda6504e7ad54f8c0d4d5846c25400d485aa90c50beb0121897524ddf43e43b6 |
|
MD5 | b3713c9e80c52e0921a25399500d8b84 |
|
BLAKE2b-256 | 897bfb510488eaa1af6b4cd75a45d72cb83a2f6ad48d1b3fc63157f0babc290f |
Hashes for mattress-0.1.3-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 42c1cd37dcd9c885dc6a4518d795584087758521cdf46f03b7a648c3858c6537 |
|
MD5 | 36273da44f3751ded9b85ba5b13f358a |
|
BLAKE2b-256 | 4b6dcff26300f8514f37dafd4d32837390acb00271f5950c8be65b5100ed80fb |
Hashes for mattress-0.1.3-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b7af9034e40ed874d9587e37155111d29012726b6f71bf681ef9a4640542d8cb |
|
MD5 | 4b747c058c1b085cac703cef2f55ef8d |
|
BLAKE2b-256 | 049486bc2cb720e43f6b2648b8fa2b95705a942166e4af7ce33cafb71b0b3b0e |