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.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5589718384bde4e0143f731e70b9ddcad8fdcc796341184e348e67d1e0832f50 |
|
MD5 | f5608b7dc4e644cc514e9cc71c8c3968 |
|
BLAKE2b-256 | 164daedbdb5fe918ce19604d19faa7e5b7e07ec5aed2c3dbed2bb4cead47b650 |
Hashes for mattress-0.1.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | da530fd071f8757a72ec57cffd27ecd6027c7903391063ca5beb716b6ac9540d |
|
MD5 | 51448cd5698ef7e44b3708605620ebd7 |
|
BLAKE2b-256 | 4781f05b3dace715ad4c6c64176d30288f320291975b50f450cfe7d5be8e20ac |
Hashes for mattress-0.1.4-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 29fa0e9aa754db8391ce74153033743b767265ed1a6cb8f42630518bdd0face9 |
|
MD5 | 7326122e96ba6ec3771becfe1c1337d4 |
|
BLAKE2b-256 | b295d20c29a629bb27edd12839050ec412e1c23433d53e1767a520168a8704e5 |
Hashes for mattress-0.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | def632fe5666254eacfd0b9678fc86838e3f3c35fc14be6cc208ced072375df2 |
|
MD5 | 3d3efafb65d80bbcdb99351ed21df586 |
|
BLAKE2b-256 | cd65d3d6be697abb19178c1b48dcabb301563237f3726051550ba4e80eb5334a |
Hashes for mattress-0.1.4-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ab107c90480f9a03ee8512e8e262e2cdaf04ea9132a1c3bc1e1be9558bcee5dc |
|
MD5 | 6a833484d6e2eb4f36f503d21f6d8f17 |
|
BLAKE2b-256 | 8ebbc2c59ae0f89a6219501598979f5d000bd7ad2c64966589ad2927dc3bfbdc |
Hashes for mattress-0.1.4-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 28fbbec1ccd29c3c8327a78ebf97a486f3babf377e74c2f1dcf53ae6f39dc937 |
|
MD5 | 1c2b1a67ccf4ba92b63bdeb3399d4b3e |
|
BLAKE2b-256 | bb8ff408fdfef0feccaf2dab668d7bc01b477da0e41107cae82f40ba7b39f842 |
Hashes for mattress-0.1.4-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | da3a852043c53ae00d4c6e1ef2d6b787b11037d75dbb4971e20bdedba4574420 |
|
MD5 | bd0068b33503d6c597b20652ebc49078 |
|
BLAKE2b-256 | e662ecc11dfff527c57cb6cb3e16fb308192aa4b5e01181686fd942f41a53960 |
Hashes for mattress-0.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c709a6d27f74ee76939d333e0f2ec3ec57878a3590bf2778e0d052505ab3a010 |
|
MD5 | 65455d2b551263d7a4eb1dbf7176ada9 |
|
BLAKE2b-256 | 30fba27ddcfbafeb18f0d868eb8f954754b9bb4ada4cb0460f79c6936fd2105d |
Hashes for mattress-0.1.4-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 60b3757751e5d6ba32ace00c6d04f5302bd4def920860b43bf2f3db550d8057f |
|
MD5 | 3cabf75bfe9d3ee7f3a1e63d9b846369 |
|
BLAKE2b-256 | 033422a754130a0eeba93dde8536311010a2478b15d13a78dd2ed4b8dacd1f3d |
Hashes for mattress-0.1.4-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8c0c332d1108b734255301bd17c9d7604321e305e7765c7e9147726e7b55ef67 |
|
MD5 | 5ef023533e4a83d60ce62d308ebae381 |
|
BLAKE2b-256 | 45049cccb7f2d40d609d9e8b8b05c6225acb95255d3e85b515968ba9897928fb |
Hashes for mattress-0.1.4-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 10dda1a04a1e50595acdd1e93f45eba34bb47121de3d6831ba5d10732a9fe1fb |
|
MD5 | b3f11da2806d7dc124f8ada1d3073ad3 |
|
BLAKE2b-256 | 1ebd4fc6e845040bc1da38388f7c159480561e2c2b7dfbf42672082eeb099e73 |
Hashes for mattress-0.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ecc21d5f151bf48e6dd09bd7d9a0bcccf8e912b74701ac5e9bf92cd643754a90 |
|
MD5 | 517788fbf5cacccdda9405d37042f536 |
|
BLAKE2b-256 | 886dea841f56634d74476b3a5d568def467b830c52eeed437be8190cf8507586 |
Hashes for mattress-0.1.4-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | adbb5c6e8f07f3f94ed94634f4fc204f4e611ce1d2c7ff285c6204457256c49d |
|
MD5 | 8a032655a09a199d554f7c9f037e9bde |
|
BLAKE2b-256 | 0eacefd86f22f3191fee50d88d983e108d50925b4a965f8f3e47ee09158d8564 |
Hashes for mattress-0.1.4-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c8cdea31f0f8656ff8f7920e520432434af6a359bb157c7bc194a011e5efa279 |
|
MD5 | bb2483a7b2aacb893b9930a68d6c7535 |
|
BLAKE2b-256 | ce9ddb7b34f8f16f93433cd597d3c3c8ae321cbfdc3b9afa58e4be0b50b1fe60 |