我在 Python (v. 3.8.8) 代碼中遇到了一些奇怪的行為:對同一函式的多次呼叫(具有完全相同的輸入)回傳不同的值。下面的代碼重現了這個問題。
預期行為:每次呼叫具有完全相同輸入引數的函式都應回傳相同的輸出。換句話說,zmin所有迭代的值都應該是常數。
觀察到的行為:即使輸入引數相同,對函式的每次呼叫都會給出(略微)不同的輸出:zmin在示例中不是恒定的。差異相當大,例如下面的代碼給出:zmin = array([1.94777151, 1.95983567, 1.97510284, 1.99350764, 2.01497125, 2.03940178, 2.66,278, 2.606,296] .26,286, 2.59)。
為什么會發生這種情況?
無論輔助函式quarternion_mul是否使用 向量化,問題仍然存在@guvectorize。
import numpy as np
from numba import guvectorize
import matplotlib.pyplot as plt
# Update MC cycle parameters
def change_to(state,position=None,rotation=None):
"""Update the current state to the state described by the center of mass
position and the applied rotation.
"""
# If provided, apply rotation to all points:
point = np.zeros(4,dtype=float)
if rotation is not None:
rotation_inverse = np.array([rotation[0], -rotation[1],
-rotation[2], -rotation[3]])
for i in range(1,state.shape[0]):
# Translate center of mass to origin
coords = state[i,:3] - state[0,:3]
point[0] = 0.0
point[1:] = coords
# Apply rotation
rp = quaternion_mul(rotation,point)
rpr_inv = quaternion_mul(rp,rotation_inverse)
state[i,:3] = rpr_inv[1:] state[0,:3]
# Move points to target location
delta = np.zeros(len(state[0,:]),dtype=float)
delta[:3] = position - state[0,:3]
return state delta
# Function to calculate Hamilton product
@guvectorize(['(float64[:], float64[:], float64[:])'], '(n),(n)->(n)', nopython=True, target="parallel")
def quaternion_mul(a,b,c):
# Hamilton quaternion product
c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]
c[1] = a[0]*b[1] a[1]*b[0] a[2]*b[3] - a[3]*b[2]
c[2] = a[0]*b[2] - a[1]*b[3] a[2]*b[0] a[3]*b[1]
c[3] = a[0]*b[3] a[1]*b[2] - a[2]*b[1] a[3]*b[0]
# def quaternion_mul(a,b):
# # Hamilton quaternion product
# c = np.zeros(4)
# c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]
# c[1] = a[0]*b[1] a[1]*b[0] a[2]*b[3] - a[3]*b[2]
# c[2] = a[0]*b[2] - a[1]*b[3] a[2]*b[0] a[3]*b[1]
# c[3] = a[0]*b[3] a[1]*b[2] - a[2]*b[1] a[3]*b[0]
# return c
start_state = np.array([[-0.053442, 2.05268, 1.92046, 0, 0, 0, 0],
[1.02709, 1.6784, 1.03511, 0.6365, 11310, 10156, 1],
[0.956003, 2.04269, 0.949338, 0.5853, 8225, 11248, 0],
[0.615004, 2.05092, 0.784356, 0.6365, 12229, 14318, 0],
[0.488786, 2.28627, 0.520153, 0.4509, 8414, 9459, 0],
[0.174876, 2.47819, 0.607007, 0.6563, 13127, 11105, 1],
[-0.0532915, 2.29712, 0.359422, 0.5477, 9610, 7634, 0],
[0.107118, 1.95669, 0.407201, 0.5927, 10666, 8236, -1],
[0.0313548, 1.98191, 0.781065, 0.6187, 7632, 7583, 0]],dtype=float)
position = np.array([0,0,3.5])
rotation = np.array([0.9994646047913096, 0.0146483594354613,
-0.0194742908484703, 0.0218330330268212])
iters = 10
zmin = np.zeros(iters)
for i in range(iters):
end = change_to(start_state,
position=position,
rotation=rotation)
zmin[i] = np.min(end[1:,2])
uj5u.com熱心網友回復:
你正在修改start_state.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/389396.html
