将复杂的numpy阵列传递到Cython中的C
Pass complex numpy array to C++ in Cython
我想对pyx
脚本的cythonize部分进行cythize,该部分涉及使用具有复数数字的Numpy阵列。Python脚本的相关部分如下所示:
M = np.dot(N , Q)
在我的工作中,N
,Q
和M
是具有复杂数字条目的Numpy数组。
具体来说,我想将矩阵N
和Q
传输到C++
代码,然后在C++
中执行矩阵乘法。
我知道使用指针转移到C++
脚本的方法的方法,然后使用Cython,但我对如何处理具有复杂值的Numpy阵列的事物感到有些困惑。
这就是我目前试图将数组从pyx
转移到C++
的方式。
import numpy as np
cimport numpy as np
cdef extern from "./matmult.h" nogil:
void mult(double* M, double* N, double* Q)
def sim():
cdef:
np.ndarray[np.complex128_t,ndim=2] N = np.zeros(( 2 , 2 ), dtype=np.float64)
np.ndarray[np.complex128_t,ndim=2] Q = np.zeros(( 2 , 2 ), dtype=np.float64)
np.ndarray[np.complex128_t,ndim=2] M = np.zeros(( 2 , 2 ), dtype=np.float64)
N = np.array([[1.1 + 2j,2.2],[3.3,4.4]])
Q = np.array([[3.3,4.4+5j],[5.5,6.6]])
mult(&M[0,0], &N[0,0], &Q[0,0])
print M
这是我的C 代码:
#include "matmult.h"
using namespace std;
int main(){}
void mult(double *M, double *N, double *Q)
{
double P[2][2], A[2][2], B[2][2];
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
A[i][j] = *( N + ((2*i) + j) );
B[i][j] = *( Q + ((2*i) + j) );
P[i][j] = 0;
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
for (int k=0; k<2; k++)
{
P[i][j] += A[i][k]*B[k][i];
}
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
*( M + ((2*i) + j) ) = P[i][j];
}
}
}
当我使用Cython对此进行编译时,我会收到以下错误
mat.pyx:17:27: Cannot assign type 'double complex *' to 'double *'
我将很高兴在这里得到一些帮助。
此错误消息告诉您出了什么问题:
mat.pyx:17:27:无法将'双重复杂 *'分配给'double *'
也就是说,您有一个双重复杂的指针,从numpy(指针到复杂的128 numpy dtype(,您正在尝试使用双重指针将其传递到C 函数中。C 需要能够处理复数,因此,如果您更改double* -> std ::复合物,则可以解决问题
void mult(double *M, double *N, double *Q)
变成
#include <complex>
void mult(std::complex<double> *M, std::complex<double> *N, std::complex<double> *Q)
numpy矩阵是否足以满足您的用例?Cython可能过于杀伤。
编辑:好的,我终于得到了一些东西,与C STD :: Complex and C Double _complex类型相处有些奇怪。
cppmul.pyx:
import numpy as np
cimport numpy as np
cdef extern from "./matmult.h" nogil:
void mult(np.complex128_t* M, np.complex128_t* N, np.complex128_t* Q)
def sim():
cdef:
np.ndarray[np.complex128_t,ndim=2] N = np.zeros(( 2 , 2 ), dtype=np.complex128)
np.ndarray[np.complex128_t,ndim=2] Q = np.zeros(( 2 , 2 ), dtype=np.complex128)
np.ndarray[np.complex128_t,ndim=2] M = np.zeros(( 2 , 2 ), dtype=np.complex128)
N = np.array([[1.1 + 2j,2.2],[3.3,4.4]])
Q = np.array([[3.3,4.4+5j],[5.5,6.6]])
mult(&M[0,0], &N[0,0], &Q[0,0])
print M
matmul.c:
#include "matmult.h"
void mult(complex_t *M, complex_t *N, complex_t *Q)
{
complex_t P[2][2], A[2][2], B[2][2];
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
A[i][j] = *( N + ((2*i) + j) );
B[i][j] = *( Q + ((2*i) + j) );
P[i][j] = 0;
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
for (int k=0; k<2; k++)
{
P[i][j] += A[i][k]*B[k][i];
}
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
*( M + ((2*i) + j) ) = P[i][j];
}
}
}
matmult.h:
#include <complex.h>
typedef double _Complex complex_t;
void mult(complex_t *M, complex_t *N, complex_t *Q);
setup.py:
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
import numpy as np
sourcefiles = ['cppmul.pyx', 'matmult.c']
extensions = [Extension("cppmul",
sourcefiles,
include_dirs=[np.get_include()],
extra_compile_args=['-O3']
)]
setup(
ext_modules = cythonize(extensions)
)
运行python setup.py build_ext --inplace
后,它会导入并按预期运行
import cppmul
cppmul.sim()
结果:
[[15.73 +6.6j 15.73 +6.6j]
[43.56+16.5j 43.56+16.5j]]
尝试此
#include "matmult.h"
using namespace std;
int main(){}
void mult(double *M, double *N, double *Q)
{
double P[2][2], A[2][2], B[2][2];
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
A[i][j] = *( N + ((2*i) + j) );
B[i][j] = *( Q + ((2*i) + j) );
P[i][j] = 0;
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
for (int k=0; k<2; k++)
{
P[i][j] += A[i][k]*B[k][i];
}
}
}
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
*( ((2*i) + j) )+ M = P[i][j];
}
}
}
相关文章:
- 在 Cython 中传递浮点数组的最佳选择
- 如何在 Cython 中定义返回 cpp 定义类型的函数?
- Cython中带有自定义比较器的优先级队列
- 重载的 operator() 在 Cython 中失败
- Cython 中对象动态大小的数组
- 包装一个函数,在 Cython 中返回复杂类型的向量
- 在Cython中使用移动方法时的汇编误差
- 如何在 Cython 中使用不同的C++编译器
- 如何在cython中包含C++所需的路径
- 使用 mlpack 时 Cython 模块中的未定义符号
- 将复杂的numpy阵列传递到Cython中的C
- 包装C 朋友在Cython中的非会员运营商
- 包装在Cython中的继承模板
- Cython中的引用
- Cython中的C++结构继承
- 无法修改cython中的集合
- 试一试.Catch宏包装器在cython中的等效
- Cython中的c++指针
- 从 Cython 中的 std:vector 中删除一个元素
- Cython中的抽象类(带有纯虚方法)