【发布时间】:2017-06-20 20:26:46
【问题描述】:
我有一个 np 数组,其中包含分数形式的元素以实现机器精度。我想应用像高斯消元这样的线性代数过程。这是我到目前为止的 Cython 代码(请注意,它只显示了获取上三角形形式的步骤,但实际上并没有引用它)。
在 Python 中生成的数据:
size = 5
foo = np.array([[Fc(v).limit_denominator(100) for v in r]
for r in np.random.randn(size, size)])
identity = np.array([[Fc(v) for v in r] for r in np.identity(len(foo))])
m_id = np.concatenate([foo, identity], axis=1)
赛通:
%%cython
import numpy as np
cimport numpy as np
from quicktions import Fraction as Fc
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def invert_gaussian4(np.ndarray matrix):
cdef int matrix_size = matrix.shape[1] // 2
cdef int c_i
cdef int r_i
cdef int swap
for c_i in range(matrix_size - 1):
swap = np.argmax(np.abs(matrix[c_i:, c_i])) + c_i
matrix[[swap, c_i]] = matrix[[c_i, swap]]
row = matrix[c_i, :] / matrix[c_i, c_i]
for r_i in range(c_i+1, matrix_size):
del_row = row * matrix[r_i, c_i]
matrix[r_i, :] = matrix[r_i, :] - del_row
与 Python 相比,Cython 函数的性能并没有提高那么多。我已经认识到循环和分数元素中的 np 函数调用是减慢代码的原因。有关如何更好地优化此代码的任何建议?
【问题讨论】:
-
您的数组是对象 dtype,对象是这些
Fraction对象。所以cython代码必须重复调用numpy和Fraction函数。换句话说,有很多东西可以转换为纯c。查看带注释的c代码。你会看到很多黄色。 -
@hpaulj 数组上是否有与 argmax 和 abs 等效的 C 函数?或者,我需要从头开始编写一个函数吗?
-
为什么要使用分数对象而不是浮点数? Cython 和 NumPy 在优化浮点运算方面要好得多。
-
对象数组索引
matrix[c_i:, c_i]也需要调用numpy代码。 -
@Kevin,这是为了我的研究任务,将值保留为分数实际上很重要,因为浮点数是任意四舍五入的。