2016-06-15 1 views
1

데이터 생성 함수는 상당히 복잡하기 때문에 가능한 한 명확하게하려고 노력할 것입니다. 그렇게하지 않을 경우 충분히 의견을 말하십시오.Scipy의 쿼드는 "매우 매끄러운"기능을 수행하지 못합니다.

나는 여러 변수에서 함수를 가지고 있고 다른 변수를 일정하게 유지하려고한다. 그러나 이차 변수의 다른 값에 대해 통합 프로세스는 완전히 다른 결과를 산출합니다. 함수가 많이 변경되지는 않았지만!

fig, ax = plt.subplots() 
tPrimeGrid = [0.16, 0.18, 0.22] 
from scipy import integrate 
for ttPrime in tPrimeGrid: 
    # compute grid 
    lowerBar = continuousTime.getPLowerBarAnalytical(ttPrime, Param.S, Param) 
    upperBar = Param.r 

    # integrate function 
    h = integrate.quad(myFunc, lowerBar, upperBar, args=(0.6, ttPrime, Param), full_output=True) 
    print('tPrime {} value {} erorr {}'.format(ttPrime, h[0], h[1])) 
    # plot function to be evaluated 
    pGrid = np.linspace(lowerBar, upperBar, 100) 
    plt.plot(pGrid, [myFunc(pp, 0.6, ttPrime, Param) for pp in pGrid], label='t {} (h: {})'.format(ttPrime, h[0])) 
plt.legend() 

quad의 출력은

tPrime 0.16 value 6.63310536371 erorr 0.000345564616621 
tPrime 0.18 value 5.93645658492 erorr 0.00045956820487 
tPrime 0.22 value 0.359208009237 erorr 3.98801002485e-15 

오류가 허용 오차 내 수준 내에서 잘있다, 그러나 값이 많이 뛰어 : (. 재현하지 unfort)

여기 내 예제 코드입니다 . 다음 그래프는 다음과 같습니다

plot of functions

그래서 이러한 기능은 매우 유사한 형태를 가지고있다. 육안으로 볼 때, 적분의 차이는 실제로 의미가 없습니다. 그래서 나는 "수동으로"계산했습니다 :

(np.array([myFunc(pp, 0.6, ttPrime, Param) for pp in pGrid])).sum()*(pGrid[1]-pGrid[0]) 
0.35538925924926557 

작은 값이 실제로 올바른 것임을 암시하십시오. 그래서 여기

integrate.quad(myFunc, lowerBar, upperBar, args=(0.6, 0.16, Param), full_output=True) 
Out[19]: 
(6.634157704675579, 
0.004721148834250418, 
{'alist': array([ 1.99994895, 1.78826738, 1.86060326, 1.79090489, 1.93030163, 
      1.72120652, 1.96515082, 1.75605571, 1.98257541, 1.7734803 , 
      1.9912877 , 1.7821926 , 1.99564385, 1.78872682, 1.99782193, 
      1.78654874, 1.99940018, 1.78763778, 1.99945548, 1.99891096, 
      1.78845456, 1.99972774, 1.99918322, 1.78831843, 1.99988939, 
      1.99931935, 1.7881823 , 1.99999149, 1.99942145, 1.7882844 , 
      1.9998979 , 1.9999447 , 1.99940443, 1.78825036, 1.99996597, 
      1.99986387, 1.99991492, 1.99995746, 1.99938742, 1.78827589, 
      1.99993194, 1.99990641, 1.99998298, 1.99988089, 1.99995321, 
      1.99939592, 1.78827164, 1.99994044, 1.99995108, 1.99940231]), 
    'blist': array([ 1.99995108, 1.78827164, 1.93030163, 1.86060326, 1.96515082, 
      1.75605571, 1.98257541, 1.7734803 , 1.9912877 , 1.7821926 , 
      1.99564385, 1.78654874, 1.99782193, 1.79090489, 1.99891096, 
      1.78763778, 1.99940231, 1.7881823 , 1.99972774, 1.99918322, 
      1.78872682, 1.99986387, 1.99931935, 1.78845456, 1.9998979 , 
      1.99938742, 1.78825036, 2.  , 1.99945548, 1.78831843, 
      1.99990641, 1.99994895, 1.99942145, 1.78826738, 1.99998298, 
      1.99988089, 1.99993194, 1.99996597, 1.99939592, 1.7882844 , 
      1.99994044, 1.99991492, 1.99999149, 1.99988939, 1.99995746, 
      1.99940018, 1.78827589, 1.9999447 , 1.99995321, 1.99940443]), 
    'elist': array([ 4.61134496e-03, 4.14135579e-06, 1.27804393e-15, 
      1.55808958e-15, 5.54429458e-16, 0.00000000e+00, 
      2.90617202e-16, 0.00000000e+00, 2.27720143e-15, 
      0.00000000e+00, 3.91514838e-15, 0.00000000e+00, 
      2.15987477e-14, 5.40749179e-17, 1.19682144e-12, 
      0.00000000e+00, 1.03521880e-04, 0.00000000e+00, 
      2.48275100e-08, 6.85735811e-13, 6.78454062e-18, 
      8.65204618e-09, 1.64268148e-13, 3.39437556e-18, 
      4.65487056e-08, 1.12644353e-13, 0.00000000e+00, 
      6.19443638e-08, 4.08066769e-09, 8.48813317e-19, 
      5.99147851e-07, 1.21478039e-06, 9.39741081e-10, 
      0.00000000e+00, 6.32087778e-14, 2.19912539e-10, 
      6.97448944e-09, 1.85114515e-13, 1.28558440e-13, 
      2.12217047e-19, 8.89451362e-08, 8.45167083e-09, 
      1.25621961e-14, 2.59393721e-08, 2.45738052e-15, 
      1.19106919e-12, 1.06110581e-19, 4.91812027e-08, 
      2.72831861e-15, 3.06819516e-12]), 
    'iord': array([ 1, 17, 50, 49, 48, 47, 46, 45, 44, 43, 42, 29, 40, 39, 38, 23, 35, 
     11, 34, 3, 7, 21, 30, 18, 12, 8, 6, 0, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32), 
    'last': 50, 
    'neval': 2079, 
    'rlist': array([ 1.04205921e-01, 6.52426361e-06, 1.15115963e-01, 
      1.40340233e-01, 4.99385660e-02, 0.00000000e+00, 
      2.33230318e-02, 0.00000000e+00, 1.12779305e-02, 
      0.00000000e+00, 5.54633015e-03, 0.00000000e+00, 
      2.75040018e-03, 4.87063561e-03, 1.36955727e-03, 
      0.00000000e+00, 8.85474806e-03, 0.00000000e+00, 
      1.73731989e+00, 3.41803845e-04, 6.11097092e-04, 
      1.73678061e+00, 1.70814248e-04, 3.05738170e-04, 
      2.00530044e-01, 8.53852175e-05, 0.00000000e+00, 
      5.29681716e-06, 1.51991445e-01, 7.64543067e-05, 
      2.17985628e-01, 2.00512965e-01, 7.26773425e-02, 
      0.00000000e+00, 1.06564581e-05, 3.34545761e-01, 
      5.59012296e-01, 5.32838374e-06, 1.06721256e-05, 
      1.91148122e-05, 3.34512038e-01, 2.38773007e-01, 
      5.32807434e-06, 1.85664300e-01, 2.66423055e-06, 
      5.33597722e-06, 9.55759147e-06, 1.85647516e-01, 
      1.33212494e-06, 8.93844378e-03])}, 
'The maximum number of subdivisions (50) has been achieved.\n If increasing the limit yields no improvement it is advised to analyze \n the integrand in order to determine the difficulties. If the position of a \n local difficulty can be determined (singularity, discontinuity) one will \n probably gain from splitting up the interval and calling the integrator \n on the subranges. Perhaps a special-purpose integrator should be used.') 

내 관련 질문은 다음과 같습니다 : 따라서, 나는 또한 나쁜 사람 중 하나 여기 quad()의 최대 출력을 추가 할 것입니다

  1. 방법이 될 수 있도록 유사한 모양으로, 일부 매개 변수는 작동하지만 일부 매개 변수는 작동하지 않습니다. 앞으로 이러한 실패를 "예측"할 수 있습니까?
  2. 전체 출력 (아래)은 최대 세분화 수를 달성했다는 것을 나에게 알려줍니다. 오류가 잠재적으로 예측하지 못했다고 나는 말하지 않습니다. 그것은 암시 되어야만 하는가? 5.9-0.0004 님은 0.3와 (과) 가까이 있지 않습니다.
  3. 증가 한계가 도움이되지 않았으므로 (아래 참조) 잠재적 대안은 무엇입니까? 이 기능을 어떻게 통합 할 수 있습니까?

나는 limit 증가했지만, 그게 단지 나에게 다음과 같은 (안 좋은) 출력했다 : full_output에 해당하는 경우

integrate.quad(expectedUtility, lowerBar, upperBar, args=(0.6, 0.16, Param), full_output=True, limit=500) 
Out[24]: 
(6.633112814769514, 
4.74743687572826e-06, 
[...] 
'The occurrence of roundoff error is detected, which prevents \n the requested tolerance from being achieved. The error may be \n underestimated.') 

답변

2

quad 반환 값에 대한 약간 펑키 규칙을 가지고 있습니다. quad이 문제를 발견하지 못하면 y, abserr, infodict을 반환합니다. quad이 어떤 형식의 오류를 감지하면 y, abserr, infodict, message을 반환합니다. infodict에는 실패를 나타내는 간단한 status 필드가 없기 때문에 네 번째 반환 값이 있는지 확인해야합니다. 그곳에 있으면 문제를 설명하는 문자열입니다.

The maximum number of subdivisions (50) has been achieved. 
If increasing the limit yields no improvement it is advised to analyze 
the integrand in order to determine the difficulties. If the position of a 
local difficulty can be determined (singularity, discontinuity) one will 
probably gain from splitting up the interval and calling the integrator 
on the subranges. Perhaps a special-purpose integrator should be used. 

이것은 수치 적분에 실패했습니다 의미합니다. (코드에서, 당신은 if len(h) > 3: ...handle the failure... 같은 것을 추가 할 수 있습니다) 나쁜 케이스의 전체 출력에서, 당신은 message이 포함 된 문자열 인 것을 알 수있다. integrand myFunc에 대해 더 많이 알지 못하면 왜 실패했는지 말할 수 없습니다.

관련 문제