일부 변수에 형식을 추가하여 파이썬 함수를 파이썬 함수로 변환했습니다. 그러나 cython 함수는 원래 파이썬 함수보다 약간 다른 출력을 생성합니다.cython 함수 출력이 파이썬 함수 출력과 약간 다릅니다.
나는 Cython: unsigned int indices for numpy arrays gives different result 그러나 심지어 나는 여전히 파이썬과 동일한 결과를 생성하는 사이 썬 기능을 얻을 수없는이 게시물에서 배운 내용과이 게시물의 차이에 대한 이유의 일부를 배웠다 .
그래서 내가 시도한 것을 보여주는 4 가지 기능을 조합했습니다. 누군가가 각 기능에 대해 약간 다른 결과를 얻는 이유를 공개 할 수 있습니까? function1과 똑같은 값을 반환하는 cython 함수를 얻는 방법은 무엇입니까?
%%cython
import numpy as np
cimport numpy as np
def function1(response, max_loc):
x, y = int(max_loc[0]), int(max_loc[1])
tmp1 = (response[y,x+1] - response[y,x-1])/2*(response[y,x] - min(response[y,x-1], response[y,x+1]))
tmp2 = (response[y,x+1] - response[y,x-1])
tmp3 = 2*(response[y,x] - min(response[y,x-1], response[y,x+1]))
print tmp1, tmp2, tmp3
return tmp1, tmp2, tmp3
cpdef function2(np.ndarray[np.float32_t, ndim=2] response, np.ndarray[np.float64_t, ndim=1] max_loc):
cdef unsigned int x, y
x, y = int(max_loc[0]), int(max_loc[1])
tmp1 = (response[y,x+1] - response[y,x-1])/2*(response[y,x] - min(response[y,x-1], response[y,x+1]))
tmp2 = (response[y,x+1] - response[y,x-1])
tmp3 = 2*(response[y,x] - min(response[y,x-1], response[y,x+1]))
print tmp1, tmp2, tmp3
return tmp1, tmp2, tmp3
cpdef function3(np.ndarray[np.float32_t, ndim=2] response, np.ndarray[np.float64_t, ndim=1] max_loc):
cdef unsigned int x, y
x, y = int(max_loc[0]), int(max_loc[1])
cdef np.float32_t tmp1, tmp2, tmp3
cdef np.float32_t r1 =response[y,x+1]
cdef np.float32_t r2 =response[y,x-1]
cdef np.float32_t r3 =response[y,x]
cdef np.float32_t r4 =response[y,x-1]
cdef np.float32_t r5 =response[y,x+1]
tmp1 = (r1 - r2)/2*(r3 - min(r4, r5))
tmp2 = (r1 - r2)
tmp3 = 2*(r3 - min(r4, r5))
print tmp1, tmp2, tmp3
return tmp1, tmp2, tmp3
def function4(response, max_loc):
x, y = int(max_loc[0]), int(max_loc[1])
tmp1 = (float(response[y,x+1]) - response[y,x-1])/2*(float(response[y,x]) - min(response[y,x-1], response[y,x+1]))
tmp2 = (float(response[y,x+1]) - response[y,x-1])
tmp3 = 2*(float(response[y,x]) - min(response[y,x-1], response[y,x+1]))
print tmp1, tmp2, tmp3
return tmp1, tmp2, tmp3
max_loc = np.asarray([ 15., 25.], dtype=np.float64)
response = np.zeros((49,49), dtype=np.float32)
x, y = int(max_loc[0]), int(max_loc[1])
response[y,x] = 0.959878861904
response[y,x-1] = 0.438348740339
response[y,x+1] = 0.753262758255
result1 = function1(response, max_loc)
result2 = function2(response, max_loc)
result3 = function3(response, max_loc)
result4 = function4(response, max_loc)
print result1
print result2
print result3
print result4
결과 :
0.0821185777156 0.314914 1.04306030273
0.082118573023 0.314914017916 1.04306024313
0.0821185708046 0.314914017916 1.04306030273
0.082118573023 0.314914017916 1.04306024313
(0.082118577715618812, 0.31491402, 1.043060302734375)
(0.08211857302303427, 0.3149140179157257, 1.0430602431297302)
(0.08211857080459595, 0.3149140179157257, 1.043060302734375)
(0.082118573023034269, 0.31491401791572571, 1.0430602431297302)
기능 1 내가 내 원래 파이썬 기능에서했던 작업을 나타냅니다 나는 울부 짖는 소리 몇 가지 의견을. tmp1이 결과입니다.
function2은 약간 다른 결과를 생성하는 내 첫번째 cython 버전입니다. 분명히, 응답 배열이 형식화 된 변수 인 unsigned int 또는 int로 인덱싱되면 배열의 유형이 np.float32_t 인 경우에도 결과는 PyFloat_FromDouble을 사용하여 double로 강제 변환됩니다. 그러나 배열이 파이썬 int로 인덱싱 된 경우 PyObject_GetItem 함수가 대신 사용되며 function1에서 발생하는 np.float32_t를 얻습니다. 따라서 function1의 표현식은 np.float32_t 피연산자를 사용하여 계산되지만 function2의 표현식은 double을 사용하여 계산됩니다. function1보다 약간 다른 인쇄물이 나옵니다.
function3은 function1과 동일한 출력을 얻으려는 두 번째 cython 시도입니다. 여기 서명되지 않은 int 인덱스를 사용하여 배열 응답에 액세스하지만 그 결과는 계산에 사용되는 np.float32_t 중간 변수에 남아 있습니다. 나는 약간 다른 결과를 얻는다. 분명히 print 문은 PyFloat_FromDouble을 사용하므로 np.float32_t를 인쇄 할 수 없습니다.
그런 다음 파이썬 함수를 cython과 일치하도록 변경하려고했습니다. function4은 각 표현식에서 하나 이상의 피연산자를 부동 소수점으로 변환하여이를 수행하려고하므로 나머지 피연산자도 python float로 강제 변환됩니다. 이는 cython에서 double이고 expression은 function2 에서처럼 double로 계산됩니다. 함수 내의 print는 function2와 똑같지 만 반환 된 값은 약간 다릅니다.
차이는 (a 억 한 부분)는 약 10^-9 최대이다. 왜 다른 구현물이 그 정도의 크기만큼 다른지 놀랍 니? (어떤 응용 프로그램에서 문제가 발생합니까?) –
hex(),'print ",".join ([result4의 x에 대해 x.hex()])로 플로트 값을 인쇄하십시오. – HYRY
함수 1은'tmp1','tmp2','tmp3'에 파이썬'float' (IEEE double) 값을 사용합니다. 함수 3은이를 명시 적으로'np.float32_t' (IEEE single)로 선언합니다. 그들이 어떻게 똑같은 것을 돌려 줄 수 있을까요? 중간 유형을 일치 시키려고하지만, 완전히 다른 최종 유형을 사용하면 목적을 달성 할 수 없습니다. – abarnert