Location>code7788 >text

Cython Converts Numpy Arrays to Custom Structures

Popularity:442 ℃/2024-08-07 09:34:02

Technical background

We've written a few articles about Cython before, such asCython calculates the resonance potentialCython with CCython calls to CUDA Kernel functionsCython has a very Pythonic programming paradigm with performance close to that of C, so it is used for performance optimization in many performance-critical Python software.The basic workflow of Cython is to start by taking the*.pyxThe file is converted to*.cC code, which is then compiled using gcc into a*.soDynamic link library files for Python or other language code to call.

Here we consider a more specific scenario: take a Numpy array, which is commonly used on the Python side, convert it to a C structure, and then perform the corresponding task or calculation.

Cython Structures

In Cython you can use thectypedef structto define a structure that can be generalized with C. For example, we can define a structure for atomic coordinates:

ctypedef struct CRD:
    double x, y, z

This is an atomic coordinate in three-dimensional space, which in Python is equivalent to a shape of(3,)of the array. If this were C++, then we could convert between arrays and structures through conversions such as dynamic_cast. C and Cython on the other hand convert directly by variable type, here is a complete Cython example:

ctypedef struct CRD:
    double x, y, z

cpdef int trans(double[:] crd):
    cdef:
        CRD* crd_s = <CRD*>&crd[0]
    print (crd_s.y)
    return 1

In this example, we input to the functiontrans()is a shape of(3,)array in thecdefThe coordinates of this atom are converted to a structure in Cython, and finally the y-coordinate of the atom is printed out in Cython. After we compile this file in Cython, we can call it in Python:

In [1]: from trans import trans

In [2]: import numpy as np

In [3]: a = ([1,2,3], dtype=np.float64)

In [4]: trans(a)
2.0
Out[4]: 1

It is important to note thatThis conversion is not safe.Here we just demonstrate the use of this conversion method.

polyatomic coordinate structure

In fact, from the perspective of the C language is quite understandable, we can define the spatial coordinates of an atom through a single structure, then with a pointer, you can define the spatial coordinates of multiple atoms. Here we define the structure for multiple atom coordinates as:

ctypedef struct PATH:
    CRD crds

In fact, here still represents a single-atom spatial coordinates, but from one-dimensional pointing to two-dimensional pointing, at this time we can use PATH to construct a multi-atom coordinates of the pointer:

ctypedef struct CRD:
    double x, y, z

ctypedef struct PATH:
    CRD crds

cpdef int trans(double[:] crd, double[:, :] path):
    cdef:
        int atoms = [0]
        int i
        CRD* crd_s = <CRD*>&crd[0]
        PATH* path_s = <PATH*>&path[0][0]
    print (crd_s.y)
    for i in range(atoms):
        print (path_s[i]., path_s[i]., path_s[i].)
    return 1

Similarly, we can call this trans function via Python after Cython compilation:

from trans import trans
import numpy as np

a = ([1,2,3], dtype=np.float64)
b = (12).reshape((4,3)).astype(np.float64)

print (trans(a, b))

The output result is:

2.0
0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
9.0 10.0 11.0
1

Of course, a word of caution is still needed here.This type of pointer conversion is not safe, needs to be used with caution.

Summary outline

This article describes a way to define structures in Cython and convert data between Python's Numpy arrays/MemoryView and custom structures.Cython has a very Pythonic programming paradigm with performance close to that of C, and is really a great tool for Python developers.

copyright statement

This article was first linked to:/dechinphy/p/

Author ID: DechinPhy

More original articles:/dechinphy/

Buy the blogger coffee:/dechinphy/gallery/image/