I've created a Cython code to make matrix operations between a dense matrix and a sparse vector,as follows (as I'm learning Cython I'm not sure this is a good code, but it's the best I could come up with so far):
import numpy as np cimport numpy as np ctypedef np.float64_t dtype_t ctypedef np.int32_t dtypei_t cimport cython @cython.boundscheck(False) @cython.wraparound(False) @cython.nonecheck(False) def cdenseXsparse(np.ndarray[dtype_t, ndim = 2] Y, np.ndarray[dtype_t, ndim = 1] V, np.ndarray[dtypei_t, ndim = 1] I, np.ndarray[dtype_t, ndim = 1] A = None): "" " Computes A = Y * (V_I) "" " if Y is None: raise ValueError("Input cannot be Null") A = np.zeros(Y.shape[1]) cdef Py_ssize_t i, indice cdef dtype_t s for i in range(A.shape[0]): s = 0 for indice in range(len(I)): s += Y[I[indice], i] * V[indice] A[i] = s return A
It works fine. But when I change the third line from:
ctypedef np.float64_t dtype_t
to:
ctypedef np.float32_t dtype_t
As an example, when compiling using np.float32_t and running the code:
In [3]: from numpy import random as rd, array, int32, float32
In [4]: y = array(rd.rand(10, 200), dtype = float32)
In [5]: v = array([1, 2, 3], dtype = float32)
In [6]: i = array([0, 1, 2], dtype = int32)
In [7]: from cdenseXsparse import cdenseXsparse
In [8]: r = cdenseXsparse(y, v, i)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-319f9c8c8d49> in <module>()
----> 1 r = cdenseXsparse(y, v, i)
/home/will/workspace/s3_RecSys/SVD/cdenseXsparse.so in cdenseXsparse.cdenseXsparse (cdenseXsparse.c:1484)()
ValueError: Buffer dtype mismatch, expected 'dtype_t' but got 'double'
To give a clear guideline for the vast majority of cases, for the types bool, object, str (and unicode) using the plain version is shorter and clear, and generally a good replacement. For float and complex you can use float64 and complex128 if you wish to be more explicit about the precision.,For np.int a direct replacement with np.int_ or int is also good and will not change behavior, but the precision will continue to depend on the computer and operating system. If you want to be more explicit and review the current use, you have the following alternatives:,np.int64 or np.int32 to specify the precision exactly. This ensures that results cannot depend on the computer or operating system.,If you wish to ensure that the old behaviour remains unchanged, please create an object array and then fill it explicitly, for example:
>>> np.broadcast_shapes((1, 2), (3, 1)) (3, 2) >>> np.broadcast_shapes(2, (3, 1)) (3, 2) >>> np.broadcast_shapes((6, 7), (5, 6, 1), (7, ), (5, 1, 7)) (5, 6, 7)
np.float(123)
arr1 = np.zeros((5, 0)) arr1[[20]] arr2 = np.zeros((5, 5)) arr2[[20],: 0]
import numpy as np arr = np.array([ [3, 6, 6], [4, 5, 1] ]) # mode: inexact match np.ravel_multi_index(arr, (7, 6), mode = "clap") # should be "clip" # searchside: inexact match np.searchsorted(arr[0], 4, side = 'random') # should be "right"
np.array([np.array(array_like)])
arr = np.empty(3, dtype = object) arr[: ] = [array_like1, array_like2, array_like3]
This tutorial is aimed at NumPy users who have no experience with Cython at all. If you have some knowledge of Cython you may want to skip to the ‘’Efficient indexing’’ section.,As of this writing SAGE comes with an older release of Cython than required for this tutorial. So if using SAGE you should download the newest Cython and then execute :,This function uses NumPy and is already really fast, so it might be a bit overkill to do it again with Cython. This is for demonstration purposes. Nonetheless, we will show that we achieve a better speed and memory efficiency than NumPy at the cost of more verbosity.,What happened is that most of the time spend in this code is spent in the following lines, and those lines are slower to execute than in pure Python:
pip install Cython
$ cd path / to / cython - distro $ path - to - sage / sage - python setup.py install
$ cython yourmod.pyx
$ gcc - shared - pthread - fPIC - fwrapv - O2 - Wall - fno - strict - aliasing - I / usr / include / python2 .7 - o yourmod.so yourmod.c
cimport numpy
def compute_np(array_1, array_2, a, b, c):
return np.clip(array_1, 2, 10) * a + array_2 * b + c