【问题标题】:How to solve "Invalid use of Function(<built-in function abs>)"如何解决“函数使用无效(<内置函数abs>)”
【发布时间】:2019-07-11 07:51:12
【问题描述】:

我正在尝试计算重力。结果应该是一个列表,但是出现了如下错误:

numba.errors.TypingError:在 nopython 模式管道中失败(步骤: nopython 前端)
函数使用无效() 带参数类型:(array(float64, 1d, C))

@jit(nopython = True)
def gravity_calculator(x, y, h, dx, dy, p):
    calculated_gravity = np.array([])
    for i in range(len(x)):
        cal = 0
        for j in range(len(x)):
            x1 = abs((x[j] - x[i])+0.000001)
            x2 = x1 + dx
            y1 = abs((y[j]-y[i])+0.000001)
            y2 = y1 + dy
            t1 = np.log((y2 + np.sqrt((x2 ** 2) + (y2 ** 2))) / (y2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t2 = np.log((y1 + np.sqrt((x2 ** 2) + (y1 ** 2))) / (y1 + np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t3 = np.log((y2 + np.sqrt((x1 ** 2) + (y2 ** 2))) / (y2 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t4 = np.log((y1 + np.sqrt((x1 ** 2) + (y1 ** 2))) / (y1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t5 = np.log((x2 + np.sqrt((x2 ** 2) + (y2 ** 2))) / (x2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t6 = np.log((x1 + np.sqrt((x1 ** 2) + (y2 ** 2))) / (x1 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t7 = np.log((x2 + np.sqrt((x2 ** 2) + (y1 ** 2))) / (x2 + np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t8 = np.log((x1 + np.sqrt((x1 ** 2) + (y1 ** 2))) / (x1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t9 = np.arcsin(((y2 ** 2) + (h[j] ** 2) + y2 * np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) / (
                        (y2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y2 ** 2) + (h[j] ** 2))))
            t10 = np.arcsin(((y2 ** 2) + (h[j] ** 2) + y2 * np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))) / (
                        (y2 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y2 ** 2) + (h[j] ** 2))))
            t11 = np.arcsin(((y1 ** 2) + (h[j] ** 2) + y1 * np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))) / (
                        (y1 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y1 ** 2) + (h[j] ** 2))))
            t12 = np.arcsin(((y1 ** 2) + (h[j] ** 2) + y1 * np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))) / (
                        (y1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))) * np.sqrt((y1 ** 2) + (h[j] ** 2))))
            G = (x2 * (t1 - t2) - x1 * (t3 - t4) + y2 * (t5 - t6) - y1 * (t7 - t8) + h[j] * (t9 - t10 - t11 + t12))
            cal = cal +(p * G)
        calc = cal * 0.00667
        np.append(calculated_gravity,calc)
    return calculated_gravity

result = gravity_calculator(xi,yi,initial_depth,dx,dy,-0.4)
print(result)

【问题讨论】:

  • 看起来abs() 不会自动分布在数组中,因此您需要编写一个循环将其应用于所有数组元素。

标签: python python-3.x numba


【解决方案1】:

abs() 只接受一个参数,一个要返回其绝对值的数字。参数可以是整数、浮点数或复数。
试试:

np.absolute()

【讨论】:

  • 我试了一下,这发生了:numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend) 无法统一 Literal[int](0) 和 array(float64, 1d, C)对于'cal',在 E:/Programming/Python/Python Projects/gravity_interpretation.py (101) 文件“E:\Programming\Python\Python Projects\gravity_interpretation.py”中定义,第 101 行:defgravity_calculator(x, y, h, dx, dy, p): for i in range(len(x)): cal = 0
  • 尝试定义自己的绝对函数怎么样? def absolute(x, y)
  • 仅使用 np.absolute() 有效,但发生了这种情况:numba.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend) Invalid use of Function( ) 带参数类型:(Literal[int](0), array(float64, 1d, C))
【解决方案2】:

我不能 100% 确定您的函数的输入类型是什么,但我稍微重写了它,因为您似乎根本不需要 append。只需将您的 calculated_gravity 数组预先分配到正确的大小。这通常也应该更快,而不是附加:

import numpy as np
import numba as nb


def gravity_calculator(x, y, h, dx, dy, p):
    calculated_gravity = np.empty(len(x))
    for i in range(len(x)):
        cal = 0
        for j in range(len(x)):
            x1 = abs((x[j] - x[i])+0.000001)
            x2 = x1 + dx
            y1 = abs((y[j]-y[i])+0.000001)
            y2 = y1 + dy
            t1 = np.log((y2 + np.sqrt((x2 ** 2) + (y2 ** 2))) / (y2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t2 = np.log((y1 + np.sqrt((x2 ** 2) + (y1 ** 2))) / (y1 + np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t3 = np.log((y2 + np.sqrt((x1 ** 2) + (y2 ** 2))) / (y2 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t4 = np.log((y1 + np.sqrt((x1 ** 2) + (y1 ** 2))) / (y1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t5 = np.log((x2 + np.sqrt((x2 ** 2) + (y2 ** 2))) / (x2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t6 = np.log((x1 + np.sqrt((x1 ** 2) + (y2 ** 2))) / (x1 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))))
            t7 = np.log((x2 + np.sqrt((x2 ** 2) + (y1 ** 2))) / (x2 + np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t8 = np.log((x1 + np.sqrt((x1 ** 2) + (y1 ** 2))) / (x1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))))
            t9 = np.arcsin(((y2 ** 2) + (h[j] ** 2) + y2 * np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) / (
                        (y2 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y2 ** 2) + (h[j] ** 2))))
            t10 = np.arcsin(((y2 ** 2) + (h[j] ** 2) + y2 * np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))) / (
                        (y2 + np.sqrt((x1 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y2 ** 2) + (h[j] ** 2))))
            t11 = np.arcsin(((y1 ** 2) + (h[j] ** 2) + y1 * np.sqrt((x2 ** 2) + (y1 ** 2) + (h[j] ** 2))) / (
                        (y1 + np.sqrt((x2 ** 2) + (y2 ** 2) + (h[j] ** 2))) * np.sqrt((y1 ** 2) + (h[j] ** 2))))
            t12 = np.arcsin(((y1 ** 2) + (h[j] ** 2) + y1 * np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))) / (
                        (y1 + np.sqrt((x1 ** 2) + (y1 ** 2) + (h[j] ** 2))) * np.sqrt((y1 ** 2) + (h[j] ** 2))))
            G = (x2 * (t1 - t2) - x1 * (t3 - t4) + y2 * (t5 - t6) - y1 * (t7 - t8) + h[j] * (t9 - t10 - t11 + t12))
            cal = cal +(p * G)
        calc = cal * 0.00667
        calculated_gravity[i] = calc
    return calculated_gravity


gravity_calculator_jit = nb.jit(nopython=True)(gravity_calculator)

然后我使用以下方法对其进行了测试:

xi = np.random.normal(size=(10,))
yi = np.random.normal(size=(10,))
initial_depth = np.random.normal(size=(10,))
dx = 1.0
dy = 1.0

print(np.allclose(
    gravity_calculator(xi,yi,initial_depth,dx,dy,-0.4), 
    gravity_calculator_jit(xi,yi,initial_depth,dx,dy,-0.4)))
# True

另请注意,当您在原始函数中使用 np.append(...) 时,您需要像这样使用它:

calculated_gravity = np.append(calculated_gravity,calc)

因为它不是就地操作。见:

https://docs.scipy.org/doc/numpy/reference/generated/numpy.append.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 2012-12-27
    • 1970-01-01
    相关资源
    最近更新 更多