2

Scipy splprep (spline preperation) produces a Tuple tckp

tckp : tuple (t,c,k) a tuple containing the vector of knots, the B-spline coefficients, and the degree of the spline.

tckp = [array[double,double ,..,double], 
       [array[double,double ,..,double],          
        array[double,double ,..... ,double], 
        array[double,double ,..... ,double]], int]                                        

How can I construct and fill an equivalent Cython Structure to be able to use

splev (spline evaluation) within Cython

hivert
  • 10,579
  • 3
  • 31
  • 56
martburg
  • 490
  • 3
  • 12
  • How are you planning to call splev? Are you going to use the one built in to SciPy, or some wrapper of the `splev` function in the corresponding [fortran library](http://www.netlib.org/dierckx/)? The calling procedure will depend on how you want to call it. – IanH Feb 27 '14 at 22:42
  • In the first step the SciPy Wrapper - but i fear that even more optimization will be needed. – martburg Mar 10 '14 at 16:20
  • Okay, the SciPy wrapper is really just a Python wrapper around the Fortran routine. You will need to call it in Cython the same way you would call it in Python. It will be a Python function call and there will still be the corresponding overhead. If you need to avoid the overhead of making the function call through Python, you will have to get some sort of wrapper for the Fortran routine. I'd bet the approach shown at http://www.fortran90.org/src/best-practices.html#interfacing-with-c would be a good place to start. You could try to expose the function pointer from Scipy directly instead. – IanH Mar 10 '14 at 19:12
  • The starting point then takes us to http://stackoverflow.com/tags/fortran-iso-c-binding/info and 20 years back to the last time I read and scribbled fortran – martburg Mar 10 '14 at 19:50
  • You could try using something like the answer to [this question](http://stackoverflow.com/questions/16114100/calling-dot-products-and-linear-algebra-operations-in-cython/16153914#16153914), but that is tricky too. I'm not entirely sure it would work with the spline functions either. – IanH Mar 10 '14 at 19:59

1 Answers1

0

As discussed in the comments, it depends on how you will pass tckp to other functions. One way to store this information and pass to other functions is using a struct.

In the example below you pass the tckp list using a struct to a cdef function that takes a void * as input, simulating a C function... this example function adds 1 to all the arrays assuming that int0 is the size of the arrays.

import numpy as np
cimport numpy as np

cdef struct type_tckp_struct:
    double *array0
    double *array1
    double *array2
    double *array3
    int *int0

def main():
    cdef type_tckp_struct tckp_struct
    cdef np.ndarray[np.float64_t, ndim=1] barray0, barray1, barray2, barray3
    cdef int bint

    tckp = [np.arange(1,11).astype(np.float64),
            2*np.arange(1,11).astype(np.float64),
            3*np.arange(1,11).astype(np.float64),
            4*np.arange(1,11).astype(np.float64), 10]
    barray0 = tckp[0]
    barray1 = tckp[1]
    barray2 = tckp[2]
    barray3 = tckp[3]
    bint = tckp[4]
    tckp_struct.array0 = &barray0[0]
    tckp_struct.array1 = &barray1[0]
    tckp_struct.array2 = &barray2[0]
    tckp_struct.array3 = &barray3[0]
    tckp_struct.int0 = &bint

    intern_func(&tckp_struct)

cdef void intern_func(void *args):
    cdef type_tckp_struct *args_in=<type_tckp_struct *>args
    cdef double *array0
    cdef double *array1
    cdef double *array2
    cdef double *array3
    cdef int int0, i
    array0 = args_in.array0
    array1 = args_in.array1
    array2 = args_in.array2
    array3 = args_in.array3
    int0 = args_in.int0[0]

    for i in range(int0):
        array0[i] += 1
        array1[i] += 1
        array2[i] += 1
        array3[i] += 1
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234