float64 to float32 cython error

  • Last Update :
  • Techknowledgy :

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

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


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'

Suggestion : 2

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)
arr1 = np.zeros((5, 0))
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"
arr = np.empty(3, dtype = object)
arr[: ] = [array_like1, array_like2, array_like3]

Suggestion : 3

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