Where would you suggest changing the following code in Cython to speed up the running time?

def pitch\_control\_target(tuple target, tuple ball, dict attackers, dict defenders, dict params):
 cdef int att\_n = len(attackers['x'])
 cdef int def\_n = len(defenders['x'])

 # calculate ball travel time from start position to end position.
 # ball travel time is distance to target position from current ball position divided assumed average ball speed
 cdef float ball\_travel\_time = cmath.sqrt((target[0] - ball[0]) \*\* 2 + (target[1] - ball[1]) \*\* 2).real / params['average\_ball\_speed']

 # solve pitch control model by integrating equation 3 in Spearman et al.
 # set up integration arrays
 cdef np.ndarray[np.double\_t] dT\_array = np.arange(ball\_travel\_time - params['int\_dt'], ball\_travel\_time + params['max\_int\_time'], params['int\_dt'])
 cdef np.ndarray[np.double\_t, ndim=2] PPCFatt = np.zeros(shape=(att\_n, len(dT\_array)))
 cdef np.ndarray[np.double\_t, ndim=2] PPCFdef = np.zeros(shape=(def\_n, len(dT\_array)))

 # calculate the simple time to intercept for each player
 cdef np.ndarray[np.double\_t] att\_time\_to\_intercept = params['reaction\_time'] + np.sqrt(
 (target[0] - (attackers['x'] + attackers['vx'] \* params['reaction\_time'])) \*\* 2 +
 (target[1] - (attackers['y'] + attackers['vy'] \* params['reaction\_time'])) \*\* 2
 ) / params['max\_player\_speed']
 cdef np.ndarray[np.double\_t] def\_time\_to\_intercept = params['reaction\_time'] + np.sqrt(
 (target[0] - (defenders['x'] + defenders['vx'] \* params['reaction\_time'])) \*\* 2 +
 (target[1] - (defenders['y'] + defenders['vy'] \* params['reaction\_time'])) \*\* 2
 ) / params['max\_player\_speed']

 # integration equation 3 of Spearman 2018 until convergence or tolerance limit hit (see 'params')
 cdef float ptot = 0.0
 cdef float t
 cdef np.ndarray[np.double\_t] att\_probs
 cdef np.ndarray[np.double\_t] def\_probs
 cdef np.ndarray[np.double\_t] dPPCFdT\_att
 cdef np.ndarray[np.double\_t] dPPCFdT\_def

 for i in range(1, dT\_array.size):
 if 1 - ptot > params['model\_converge\_tol']:
 t = dT\_array[i]

 # calculate the probabilities of intercepting the ball for each player
 att\_probs = 1 / (1. + np.exp(-cmath.pi / cmath.sqrt(3.).real / params['tti\_sigma'] \* (t - att\_time\_to\_intercept)))
 def\_probs = 1 / (1. + np.exp(-cmath.pi / cmath.sqrt(3.).real / params['tti\_sigma'] \* (t - def\_time\_to\_intercept)))

 # calculate ball control probablity for each player in time interval t + dt
 dPPCFdT\_att = (1 - np.sum(PPCFatt[:, i - 1]) - np.sum(PPCFdef[:, i - 1])) \* att\_probs \* params['lambda\_att']
 dPPCFdT\_def = (1 - np.sum(PPCFatt[:, i - 1]) - np.sum(PPCFdef[:, i - 1])) \* def\_probs \* params['lambda\_def']

 # make sure the probabilities are greater than zero
 assert (dPPCFdT\_att >= 0).all(), 'Invalid attacking player probability (CalcPitchControlTarget)'
 assert (dPPCFdT\_def >= 0).all(), 'Invalid defending player probability (CalcPitchControlTarget)'

 # update the pitch control probabilities for the players in each team
 PPCFatt[:, i] = PPCFatt[:, i - 1] + dPPCFdT\_att \* params['int\_dt']
 PPCFdef[:, i] = PPCFdef[:, i - 1] + dPPCFdT\_def \* params['int\_dt']
 ptot = np.sum(PPCFatt[:, i]) + np.sum(PPCFdef[:, i]) # total pitch control probability
 else:
 break
 
 if i >= dT\_array.size:
 print("Integration failed to converge: %1.3f" % (ptot))

 return PPCFatt[:, i - 1], PPCFdef[:, i - 1]
여기서 실행 시간을 단축하기 위해 Cython에서 다음 코드를 변경하는 것이 좋을까요?def pitch\_control\_target(튜플 대상, 튜플 볼, 딕셔너리 공격자, 딕셔너리 수비자, 딕셔너리 매개변수): cdef int att\_n = len(attackers['x']) cdef int def\_n = len(defenders['x']) # 시작 위치에서 끝 위치까지의 공 이동 시간을 계산합니다. # 공 이동 시간은 현재 공 위치에서 목표 위치까지의 거리를 가정한 평균 공 속도로 나눈 값입니다. cdef float ball\_travel\_time = cmath.sqrt((target[0] - ball[0]) \*\* 2 + (target[1] - ball[1]) \*\* 2).real / params['average\_ball\_speed'] # 스피어만 외의 방정식 3을 적분하여 피치 제어 모델을 해결합니다. # 적분 배열 설정 cdef np.ndarray[np.double\_t] dT\_array = np.arange(ball\_travel\_time - params['int\_dt'], ball\_travel\_time + params['max\_int\_time'], params['int\_dt']) cdef np.ndarray[np.double\_t, ndim=2] PPCFatt = np.zeros(shape=(att\_n, len(dT\_array))) cdef np.ndarray[np.double\_t, ndim=2] PPCFdef = np.zeros(shape=(def\_n, len(dT\_array))) # 각 플레이어에 대한 간단한 가로채기 시간을 계산합니다. cdef np.ndarray[np.double\_t] att\_time\_to\_intercept = params['reaction\_time'] + np.sqrt( (target[0] - (공격자['x'] + 공격자['vx'] \* params['reaction\_time'])) \*\* 2 + (target[1] - (attackers['y'] + attackers['vy'] \* params['reaction\_time'])) \*\* 2 ) / params['max\_player\_speed'] cdef np.ndarray[np.double\_t] def\_time\_to\_intercept = params['reaction\_time'] + np.sqrt( (target[0] - (defenders['x'] + defenders['vx'] \* params['reaction\_time'])) \*\* 2 + (target[1] - (defenders['y'] + defenders['vy'] \* params['reaction\_time'])) \*\* 2 ) / params['max\_player\_speed'] 수렴 또는 허용 한계에 도달할 때까지 Spearman 2018의 # 적분 방정식 3 ('params' 참조) cdef float ptot = 0.0 CDEF 플로트 T cdef np.ndarray[np.double\_t] att\_probs cdef np.ndarray[np.double\_t] def\_probs cdef np.ndarray[np.double\_t] dPPCFdT\_att cdef np.ndarray[np.double\_t] dPPCFdT\_def for i in range(1, dT\_array.size): if 1 - ptot > params['model\_converge\_tol']: t = dT\_array[i] # 각 선수의 공을 가로챌 확률을 계산합니다. att\_probs = 1 / (1. + np.exp(-cmath.pi / cmath.sqrt(3.).real / params['tti\_sigma'] \* (t - att\_time\_to\_intercept))) def\_probs = 1 / (1. + np.exp(-cmath.pi / cmath.sqrt(3.).real / params['tti\_sigma'] \* (t - def\_time\_to\_intercept)))) # 각 선수의 볼 컨트롤 확률을 시간 간격 t + dt로 계산합니다. dPPCFdT\_att = (1 - np.sum(PPCFatt[:, i - 1]) - np.sum(PPCFdef[:, i - 1])) \* att\_probs \* params['lambda\_att'] dPPCFdT\_def = (1 - np.sum(PPCFatt[:, i - 1]) - np.sum(PPCFdef[:, i - 1])) \* def\_probs \* params['lambda\_def'] # 확률이 0보다 큰지 확인합니다. assert (dPPCFdT\_att >= 0).all(), '잘못된 공격 플레이어 확률 (CalcPitchControlTarget)' 어서트 (dPPCFdT\_def >= 0).all(), '유효하지 않은 수비 플레이어 확률 (CalcPitchControlTarget)' # 각 팀의 선수에 대한 피치 컨트롤 확률을 업데이트합니다. PPCFatt[:, i] = PPCFatt[:, i - 1] + dPPCFdT\_att \* params['int\_dt'] PPCFdef[:, i] = PPCFdef[:, i - 1] + dPPCFdT\_def \* params['int\_dt'] ptot = np.sum(PPCFatt[:, i]) + np.sum(PPCFdef[:, i]) # 총 피치 제어 확률 else: break  if i >= dT\_array.size: print("통합에 실패했습니다: %1.3f" % (ptot)) 반환 PPCFatt[:, i - 1], PPCFdef[:, i - 1]