有一個程序涉及搜索(最終)大量的引陣列合,我試圖使用 numba 加速。我試圖更改我的初始代碼以使其兼容,但仍然出現我不知道如何解決的 TypingError。我在使用“np.asarray()”時遇到了很多問題,所以我洗掉了它,現在主要處理標準串列,但它仍然不起作用。我只會提到給定錯誤訊息看起來相關的代碼部分,如果需要更多,我也會提供(只是為了保持相當短)。
錯誤訊息中看似關鍵的部分(據我所知,其余部分只是由于此函式在另一個內部呼叫,而另一個又在另一個內部呼叫)內容如下:
在 nopython 模式管道中失敗(步驟:nopython 前端)未找到用于簽名的函式 Function(<function dot at 0x0000021490EA2400>) 的實作:
點(串列(串列(float64)<iv=None>)<iv=None>,反映串列(float64)<iv=None>)
有 4 個候選實作: - 其中 4 個不匹配,原因是:函式 '_OverloadWrapper._build..ol_generated' 中的多載:檔案:numba\core\overload_glue.py:第 131 行。帶引數:'(list (list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)':由于實作引發特定錯誤而被拒絕:TypingError:在 nopython 模式管道中失敗(步驟:nopython前端)找不到用于簽名的函式 Function() 的實作:
>>> stub(list(list(float64)<iv=None>)<iv=None>, reflected list(float64)<iv=None>)
它似乎源自定義如下的函式“nvaxes_lab”:
# reference position of NV axis vectors, each row holds the orientation (vector) of one NV axis
nvaxes_ref = [[1.0, 1.0, 1.0],
[-1.0, 1.0, -1.0], [1.0, -1.0, -1.0], [-1.0, -1.0, 1.0]]
@njit()
def rot_euler(a, b, g):
"""
:param a: float, angle of third rotation (around z-axis) in radians
:param b: float, angle of second rotation (around x-axis) in radians
:param g: float, angle of first rotation (around z-axis) in radians
:return: rotation matrix for a general rotation around the Euler angles a (=alpha), b (=beta), g (=gamma) defined
as follows: rot_euler(a,b,g) = rotZ(a).rotX(b).rotZ(g)
"""
return [[np.cos(a) * np.cos(g) - np.cos(b) * np.sin(a) * np.sin(g),
-np.cos(b) * np.cos(g) * np.sin(a) - np.cos(a) * np.sin(g), np.sin(a) * np.sin(b)],
[np.cos(g) * np.sin(a) np.cos(a) * np.cos(b) * np.sin(g),
np.cos(a) * np.cos(b) * np.cos(g) - np.sin(a) * np.sin(g), -np.cos(a) * np.sin(b)],
[np.sin(b) * np.sin(g), np.cos(g) * np.sin(b), np.cos(b)]]
@njit()
def nvaxes_lab(a, b, g):
"""
:param a: float, angle of third Euler rotation (around z-axis) in radians
:param b: float, angle of second Euler rotation (around x-axis) in radians
:param g: float, angle of first Euler rotation (around z-axis) in radians
:return: numpy array of dimensions 3x4, each row holds the orientation (vector) of the corresponding NV-axis
after rotation by the Euler angles a,b,g
"""
return [np.dot(rot_euler(a, b, g), nvaxes_ref[0]).astype(float), np.dot(rot_euler(a, b, g), nvaxes_ref[1]).astype(float),
np.dot(rot_euler(a, b, g).astype(float), nvaxes_ref[2]), np.dot(rot_euler(a, b, g), nvaxes_ref[3]).astype(float)]
問題似乎是在'nvaxes_lab'中回傳的陣列的每個組件中的點積......不幸的是,我不知道如何定義陣列(我嘗試了多個版本)或者我還能做些什么來犯這個錯誤消失,因為這是我第一次使用 numba。
我會很感激你的幫助!
uj5u.com熱心網友回復:
你有幾個問題。首先,您看到的實際錯誤來自 numba 編譯您的函式時,它使用 numpy 函式的 C 實作。這些實作需要 numpy 陣列,而不是串列。所以錯誤:
點(串列(串列(float64)<iv=None>)<iv=None>,反映串列(float64)<iv=None>)
基本上是想告訴您該np.dot函式不知道如何處理串列。在 python 版本中,它會將串列強制轉換為 numpy 陣列,但我猜不是在 C/numba 版本中。您可以np.array環繞每個串列,或者更好的選擇是輸出一個陣列rot_euler。
接下來,最好不要參考在您嘗試 JIT 的函式范圍之外定義的可變變數。在nvaxes_lab中,您參考 的每個元素nvaxes_ref。您最好將它們作為函式的引數傳遞,并且為了保持一致,也將它們設為陣列。
最后,您的檔案字串與您的回傳型別不匹配nvaxes_lab。您可以將整個串列 vstack 以使其成為一個陣列。
在將東西轉換為浮點數方面,因為nvaxes_ref陣列已經是一個浮點陣列,所以所有的輸出也將是浮點數,所以你可以放棄這些astype方法。
import numpy as np
from numba import njit
nvaxes_ref = np.array([
[1.0, 1.0, 1.0],
[-1.0, 1.0, -1.0],
[1.0, -1.0, -1.0],
[-1.0, -1.0, 1.0]
])
@njit
def rot_euler(a, b, g):
"""
:param a: float, angle of third rotation (around z-axis) in radians
:param b: float, angle of second rotation (around x-axis) in radians
:param g: float, angle of first rotation (around z-axis) in radians
:return: rotation matrix for a general rotation around the Euler angles
a (=alpha), b (=beta), g (=gamma) defined as follows:
rot_euler(a,b,g) = rotZ(a).rotX(b).rotZ(g)
"""
return np.array([
[
np.cos(a) * np.cos(g) - np.cos(b) * np.sin(a) * np.sin(g),
-np.cos(b) * np.cos(g) * np.sin(a) - np.cos(a) * np.sin(g),
np.sin(a) * np.sin(b)
],
[
np.cos(g) * np.sin(a) np.cos(a) * np.cos(b) * np.sin(g),
np.cos(a) * np.cos(b) * np.cos(g) - np.sin(a) * np.sin(g),
-np.cos(a) * np.sin(b)
],
[
np.sin(b) * np.sin(g),
np.cos(g) * np.sin(b),
np.cos(b)
]
])
@njit
def nvaxes_lab(a, b, g, refs):
"""
:param a: float, angle of third Euler rotation (around z-axis) in radians
:param b: float, angle of second Euler rotation (around x-axis) in radians
:param g: float, angle of first Euler rotation (around z-axis) in radians
:return: numpy array of dimensions 3x4, each row holds the orientation (vector)
of the corresponding NV-axis after rotation by the Euler angles a,b,g
"""
return [
np.dot(rot_euler(a, b, g), refs[0]),
np.dot(rot_euler(a, b, g), refs[1]),
np.dot(rot_euler(a, b, g), refs[2]),
np.dot(rot_euler(a, b, g), refs[3])
]
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/443160.html
上一篇:使用2D光柵陣列生成流圖
下一篇:大向量的外積超出記憶體
