Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3434458
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T07:42:03+00:00 2026-05-18T07:42:03+00:00

I am trying to speed up my Numpy code and decided that I wanted

  • 0

I am trying to speed up my Numpy code and decided that I wanted to implement one particular function where my code spent most of the time in C.

I’m actually a rookie in C, but I managed to write the function which normalizes every row in a matrix to sum to 1. I can compile it and I tested it with some data (in C) and it does what I want. At that point I was very proud of myself.

Now I’m trying to call my glorious function from Python where it should accept a 2d-Numpy array.

The various things I’ve tried are

  • SWIG

  • SWIG + numpy.i

  • ctypes

My function has the prototype

void normalize_logspace_matrix(size_t nrow, size_t ncol, double mat[nrow][ncol]);

So it takes a pointer to a variable-length array and modifies it in place.

I tried the following pure SWIG interface file:

%module c_utils

%{
extern void normalize_logspace_matrix(size_t, size_t, double mat[*][*]);
%}

extern void normalize_logspace_matrix(size_t, size_t, double** mat);

Then I would do (on Mac OS X 64bit):

> swig -python c-utils.i

> gcc -fPIC c-utils_wrap.c -o c-utils_wrap.o \
     -I/Library/Frameworks/Python.framework/Versions/6.2/include/python2.6/ \
     -L/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/ -c
c-utils_wrap.c: In function ‘_wrap_normalize_logspace_matrix’:
c-utils_wrap.c:2867: warning: passing argument 3 of ‘normalize_logspace_matrix’ from   incompatible pointer type

> g++ -dynamiclib c-utils.o -o _c_utils.so

In Python I then get the following error on importing my module:

>>> import c_utils
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initc_utils)

Next I tried this approach using SWIG + numpy.i:

%module c_utils

%{
#define SWIG_FILE_WITH_INIT
#include "c-utils.h"
%}
%include "numpy.i"
%init %{
import_array();
%}

%apply ( int DIM1, int DIM2, DATA_TYPE* INPLACE_ARRAY2 ) 
       {(size_t nrow, size_t ncol, double* mat)};

%include "c-utils.h"

However, I don’t get any further than this:

> swig -python c-utils.i
c-utils.i:13: Warning 453: Can't apply (int DIM1,int DIM2,DATA_TYPE *INPLACE_ARRAY2). No typemaps are defined.

SWIG doesn’t seem to find the typemaps defined in numpy.i, but I don’t understand why, because numpy.i is in the same directory and SWIG doesn’t complain that it can’t find it.

With ctypes I didn’t get very far, but got lost in the docs pretty quickly since I couldn’t figure out how to pass it a 2d-array and then get the result back.

So could somebody show me the magic trick how to make my function available in Python/Numpy?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T07:42:04+00:00Added an answer on May 18, 2026 at 7:42 am

    Unless you have a really good reason not to, you should use cython to interface C and python. (We are starting to use cython instead of raw C inside numpy/scipy themselves).

    You can see a simple example in my scikits talkbox (since cython has improved quite a bit since then, I think you could write it better today).

    def cslfilter(c_np.ndarray b, c_np.ndarray a, c_np.ndarray x):
        """Fast version of slfilter for a set of frames and filter coefficients.
        More precisely, given rank 2 arrays for coefficients and input, this
        computes:
    
        for i in range(x.shape[0]):
            y[i] = lfilter(b[i], a[i], x[i])
    
        This is mostly useful for processing on a set of windows with variable
        filters, e.g. to compute LPC residual from a signal chopped into a set of
        windows.
    
        Parameters
        ----------
            b: array
                recursive coefficients
            a: array
                non-recursive coefficients
            x: array
                signal to filter
    
        Note
        ----
    
        This is a specialized function, and does not handle other types than
        double, nor initial conditions."""
    
        cdef int na, nb, nfr, i, nx
        cdef double *raw_x, *raw_a, *raw_b, *raw_y
        cdef c_np.ndarray[double, ndim=2] tb
        cdef c_np.ndarray[double, ndim=2] ta
        cdef c_np.ndarray[double, ndim=2] tx
        cdef c_np.ndarray[double, ndim=2] ty
    
        dt = np.common_type(a, b, x)
    
        if not dt == np.float64:
            raise ValueError("Only float64 supported for now")
    
        if not x.ndim == 2:
            raise ValueError("Only input of rank 2 support")
    
        if not b.ndim == 2:
            raise ValueError("Only b of rank 2 support")
    
        if not a.ndim == 2:
            raise ValueError("Only a of rank 2 support")
    
        nfr = a.shape[0]
        if not nfr == b.shape[0]:
            raise ValueError("Number of filters should be the same")
    
        if not nfr == x.shape[0]:
            raise ValueError, \
                  "Number of filters and number of frames should be the same"
    
        tx = np.ascontiguousarray(x, dtype=dt)
        ty = np.ones((x.shape[0], x.shape[1]), dt)
    
        na = a.shape[1]
        nb = b.shape[1]
        nx = x.shape[1]
    
        ta = np.ascontiguousarray(np.copy(a), dtype=dt)
        tb = np.ascontiguousarray(np.copy(b), dtype=dt)
    
        raw_x = <double*>tx.data
        raw_b = <double*>tb.data
        raw_a = <double*>ta.data
        raw_y = <double*>ty.data
    
        for i in range(nfr):
            filter_double(raw_b, nb, raw_a, na, raw_x, nx, raw_y)
            raw_b += nb
            raw_a += na
            raw_x += nx
            raw_y += nx
    
        return ty
    

    As you can see, besides the usual argument checking you would do in python, it is almost the same thing (filter_double is a function which can be written in pure C in a separate library if you want to). Of course, since it is compiled code, failing to check your argument will crash your interpreter instead of raising exception (there are several levels of safety vs speed tradeoffs available with recent cython, though).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.