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.6-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5c25ef752af213b2da974d11c65dfd2a2aac23823c3346ed1b86004b5f118eb4 |
|
MD5 | 8365b35c64d69c4b053a080a3391352d |
|
BLAKE2b-256 | 7b34f3c502d0dfde21092239de3b916d4247ec1a6acc8c80de6aa97ec7bfb353 |
Hashes for mattress-0.1.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6e6ff9331b1e4016ee9d57df19b5ca9e2339c2dea6b31a871166488f0b8a168b |
|
MD5 | cd78bfd1ebb5744285cebb51f44f772e |
|
BLAKE2b-256 | 979fa355fee9596263858c41eb9635308e51487df22a5a3ced698af3cad13fff |
Hashes for mattress-0.1.6-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 398376ae05b84b4a832048fabdf4de1c7b12d4ec67fe0d3dc5df55d4e3da06d3 |
|
MD5 | 2e1954e9f2c7ce6af181c8fb75eab46c |
|
BLAKE2b-256 | 01cda8bbeee9ef92f18e5c704bff3659c909a802cd99ac256ac9186587f0580e |
Hashes for mattress-0.1.6-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f563e6f0b1e977ffe1c9c29b1233f80526fae1f40ee40e1e0dac55e8ca9264b7 |
|
MD5 | 0904d70eb35c09123395612e0f13370f |
|
BLAKE2b-256 | 49a1aba7b25f820bcc5651ea0af517aecf49503d30ae1a4432b790f711a0ce64 |
Hashes for mattress-0.1.6-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 15b33dfb841aa069aba6506165f3aea81323b79d312b471fe5aca451f193f7a8 |
|
MD5 | 8514bd5ae467d3534c0a5e6f822eead5 |
|
BLAKE2b-256 | cff526c82d0d30461a7e9c4f7da6a2c7f2fbe2c3a8284bdd6de36e37532072b7 |
Hashes for mattress-0.1.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 26682ee55e07c12a233f1d1b5f8e405960aebc1b63327e976db4a032729161a7 |
|
MD5 | c869a34c52b7d541e44f262672d1dfc8 |
|
BLAKE2b-256 | 0dd32256e46e292c0043748916084eaa06b6f186df201adbcfeb5ddb92f26910 |
Hashes for mattress-0.1.6-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2d72d1b7a2e31ca17d18357826402bc632567c3d05fc55124120896eb571a71f |
|
MD5 | 638cfaca89e1d3bcce80d52bad1b71a9 |
|
BLAKE2b-256 | 1297349dc33b2669eb24d6d33604768fcdd06181a580b0295123312a5f793b32 |
Hashes for mattress-0.1.6-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 07496b1d62bed343ff9ada5f7542bd3702d24ec6d6d0dde8dcecb3724255e114 |
|
MD5 | 36c7470b55f663e317d939c97b55475d |
|
BLAKE2b-256 | 625e9a15bb75d73750371f5ee26c6c6d9d70e38d3e171fac2bd91f7acea35d11 |
Hashes for mattress-0.1.6-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 784486d9da474304dba23942a327f1924489c2922cb9f6befdf24457c7a9a521 |
|
MD5 | 279a27c3e76c98e77194caa05847ea2d |
|
BLAKE2b-256 | 4260b5107f1645c5fba6b78e78d45d78b103af8a6a893932cdf2ba508010cfe7 |
Hashes for mattress-0.1.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a464f64c5638c323f522ba0900161b3246603a3aef1a2845bb70e6c9a127330f |
|
MD5 | 01d211268ff56a05f9f5b856f6d3883a |
|
BLAKE2b-256 | 136d95a43f49e6438fe4dd0cc5698e059b9dd0739f4d65bf0dfe5cf89261dd65 |
Hashes for mattress-0.1.6-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c63deaa2ccfe39c3670ef7921af7c959cc933d0b93709917232357dcc20f12d9 |
|
MD5 | b12a8f00b0cee2d9511f4b96c94a5377 |
|
BLAKE2b-256 | b4f76b691ac9ffb070aea353401e7abd31a510035382a7645233276ee1b1e9bd |
Hashes for mattress-0.1.6-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2b7e2dd64d682214612e137d0c9e609ed2930f8dd167213d16c0d1bd0c9c3c37 |
|
MD5 | 78866a09673800436848aec89f415f9d |
|
BLAKE2b-256 | a9bf32903a3892da13264c938865ff714f1507f4035c1415f5d9a2d3d3fe8320 |
Hashes for mattress-0.1.6-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 92ab08dfc511f0cae97edbd0521a02d600cc3243bdb7c4c3706952e01b39fbb6 |
|
MD5 | f476fb876c576c2673ec2cb6ea9d9bff |
|
BLAKE2b-256 | d34c78f4bf95dbf00c4dbd239887935671f6df85a8051332dc16f15900840f89 |
Hashes for mattress-0.1.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9d7704ed0d1840132824d0dcfd6bf0b6bc5f73f8df29b68a748da731a1e8cd4b |
|
MD5 | a98fc3ef17ef4ad5c345fe755a98a8db |
|
BLAKE2b-256 | 165f78fe82b35759748d181c42d12ac6d66d78316b41c90178d0851c5bc1b37d |
Hashes for mattress-0.1.6-cp38-cp38-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8d62089e627b5158dfeb5db9dff1cf445bb270812a3c7f0161152ba951bc5f8b |
|
MD5 | cd70326ecf130d072d995934c83eea06 |
|
BLAKE2b-256 | 5e359cc5e960a6cef494751cf3b3c85f4fb00b5750b6a4a6033133e148dafba5 |
Hashes for mattress-0.1.6-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a1c0ef3ba0a9ccb9e7858106d13958d094a85e2f7f0c8d2f83c113198602ceab |
|
MD5 | 4942d4bf2426a9fa61fc25c7eab45f1d |
|
BLAKE2b-256 | 9ea8569b2f64ff717cb32cc12f57ce0811f650a9042edca48aa4db3db11305c0 |