PageRenderTime 56ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/BAEM/CAMELOT-Wrapper/Scripts/HoogPy_1_0.py

#
Python | 418 lines | 90 code | 8 blank | 320 comment | 25 complexity | 1c3681b0d9f312c86201c01b7f5acc57 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. #Copyright (C) 2009 Karl Bandilla
  2. #
  3. #This program is free software: you can redistribute it and/or modify
  4. #it under the terms of the GNU General Public License as published by
  5. #the Free Software Foundation, either version 3 of the License, or
  6. #at your option) any later version.
  7. #
  8. #This program is distributed in the hope that it will be useful,
  9. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. #GNU General Public License for more details.
  12. #
  13. #You should have received a copy of the GNU General Public License
  14. #along with this program. If not, see http://www.gnu.org/licenses/.
  15. from numpy import *
  16. def HoogTransform(t, gamma, bigT, N, FUN, meth, init, d, work):
  17. '''Numerrical Laplace inversion using the Hoog method.
  18. t (float variable) independent variable at which inverse
  19. function is to be evaluated
  20. gamma (float variable) parameter of inversion integral, governing
  21. accuracy of inversion
  22. bigT (float variable) parameter used to discretize inversion
  23. integral, thus governing discretization error
  24. N (integer variable) must be >= 2 and should be even; number
  25. of terms to be used in sum for approximation, thus
  26. governing truncation error
  27. FUN name of user-supplied function which evaluates the complex
  28. values of transform fbar(p) for complex values of Laplace
  29. transform variable p
  30. meth (integer variable) determines inversion method: 1=epsilon
  31. method; 2=ordinary quotient difference algorithm;
  32. 3=acceleratedquotient difference algorithm
  33. init (integer variable) =1 indicates this is the first call
  34. of the algorithm with these values of gamma, bigT, N and
  35. FUN. !=1 means array is not recomputed
  36. d (complex array dimensioned in calling function) contains
  37. continued fraction coefficient if init >1 and meth=2 or 3
  38. work (complex array dimensioned in calling function) work space
  39. used for calculating successive diagonals of the table
  40. This is a translation of the FORTRAN subroutine LAPADC originally by
  41. J.H. Knight. See code for more information.
  42. Requires numpy.'''
  43. #This is a translation of the FORTRAN subroutine LAPADC by J.H. Knight
  44. #of the Division of Environmental Mechanics, CSIRO, Canberra, ACT2601,
  45. #Australia originally coded in August 1986. The function performs a
  46. #numerical LaPlace inversion using the Hoog method. Two papers are
  47. #referenced in the original FORTRAN code:
  48. #DeHoog, F.R., Knight, J.H. and Stokes, A.N. An improved method for
  49. #numerical inversion of LaPlace transforms. SIAM J. SCI. STA. COMPUT.,
  50. # 3, PP. 357-366, 1982.
  51. #DeHoog, F.R., Knight, J.H. and Stokes, A.N. Subroutine LAPACC for LaPlace
  52. #inversion by acceleration of convergence of complex sum. ACM TRANS.
  53. #MATH. SOFTWARE, (manuscript in preperation).
  54. #Translated by Karl W. Bandilla in July 2009.
  55. #Comments are taken from the FORTRAN code
  56. #Following is the header of the original FORTRAN code
  57. # SUBROUTINE LAPADC(T,GAMMA,BIGT,N,F,FUN,METH,INIT,D,WORK)
  58. #
  59. #-----------------------------------------------------------------------
  60. #
  61. # AUTHOR
  62. #
  63. # J.H. KNIGHT
  64. # DIVISION OF ENVIRONMENTAL MECHANICS
  65. # CSIRO, CANBERRA, ACT 2601, AUSTRALIA
  66. # AUGUST, 1986
  67. #
  68. # REFERENCES
  69. #
  70. # DE HOOG, F.R., KNIGHT, J.H. AND STOKES, A.N.
  71. # AN IMPROVED METHOD FOR NUMERICAL INVERSION OF LAPLACE
  72. # TRANSFORMS. SIAM J. SCI. STAT. COMPUT., 3, PP. 357-366, 1982.
  73. #
  74. # DE HOOG, F.R., KNIGHT, J.H. AND STOKES, A.N.
  75. # SUBROUTINE LAPACC FOR LAPLACE TRANSFORM INVERSION BY
  76. # ACCELERATION OF CONVERGENCE OF COMPLEX SUM.
  77. # ACM TRANS. MATH. SOFTWARE, (MANUSCRIPT IN PREPARATION).
  78. #
  79. # ABSTRACT
  80. #
  81. # LAPADC COMPUTES AN APPROXIMATION TO THE INVERSE LAPLACE
  82. # TRANSFORM F(T) CORRESPONDING TO THE LAPLACE TRANSFORM
  83. # FBAR(P), USING A RATIONAL APPROXIMATION TO THE FOURIER
  84. # SERIES RESULTING WHEN THE INVERSION INTEGRAL IS
  85. # DISCRETIZED USING THE TRAPEZOIDAL RULE.
  86. # THE RATIONAL APPROXIMATION IS A DIAGONAL PADE APPROXIMATION
  87. # COMPUTED USING EITHER THE EPSILON ALGORITHM, IN WHICH THE
  88. # EPSILON TABLE MUST BE RECOMPUTED AT EACH VALUE OF T, OR
  89. # USING THE QUOTIENT-DIFFERENCE ALGORITHM, IN WHICH THE
  90. # QUOTIENT-DIFFERENCE ALGORITHM IS USED TO COMPUTE THE
  91. # COEFFICIENTS OF THE ASSOCIATED CONTINUED FRACTION, AND THE
  92. # CONTINUED FRACTION IS EVALUATED AT EACH VALUE OF T.
  93. # IN ADDITION, THE EVALUATION OF THE CONTINUED FRACTION IS
  94. # MADE MORE ACCURATE WITH AN IMPROVED ESTIMATE OF THE
  95. # REMAINDER.
  96. #
  97. # METHOD
  98. #
  99. # A REAL VALUED INVERSE FUNCTION F(T) IS THE REAL PART OF THE
  100. # INTEGRAL
  101. # INFINITY
  102. #
  103. # (ONE/PI)*EXP(GAMMA*T)* INTEGRAL FBAR(GAMMA+I*W)*EXP(I*W*T)*DW
  104. #
  105. # W=ZERO
  106. #
  107. # WITH FBAR THE LAPLACE TRANSFORM, GAMMA A REAL PARAMETER, AND
  108. # I**2=-1. W IS THE VARIABLE OF INTEGRATION.
  109. # IF THIS IS DISCRETIZED USING THE TRAPEZOIDAL RULE WITH STEP
  110. # SIZE PI/BIGT, A FOURIER SERIES RESULTS, AND F(T) IS THE SUM
  111. # OF THE DISCRETIZATION ERROR
  112. #
  113. # INFINITY
  114. #
  115. # SUM EXP(-TWO*GAMMA*K*BIGT)*F(T+TWO*K*BIGT)
  116. #
  117. # K=1
  118. #
  119. # AND THE REAL PART OF THE FOURIER SERIES
  120. #
  121. # INFINITY
  122. #
  123. # (ONE/BIGT)*EXP(GAMMA*T)* SUM A(K)*EXP(I*K*PI*T/BIGT)
  124. #
  125. # K=0
  126. #
  127. # WITH THE COEFFICIENTS (A(K),K=0,INFINITY) GIVEN BY
  128. #
  129. # A(0) = HALF*FBAR(GAMMA),
  130. #
  131. # A(K) = FBAR(GAMMA+I*K*PI/BIGT), K=1,INFINITY.
  132. #
  133. # THIS EXPRESSION CAN ALSO BE CONSIDERED AS A POWER SERIES IN
  134. # THE VARIABLE Z=EXP(I*PI*T/BIGT), AND WE INTRODUCE A
  135. # TRUNCATION ERROR WHEN WE USE A FINITE POWER SERIES
  136. #
  137. # M2
  138. #
  139. # V(Z,M2) = SUM A(K)*Z**K, M2 = M*2.
  140. #
  141. # K=0
  142. #
  143. # THE EPSILON ALGORITHM CALCULATES THE DIAGONAL PADE
  144. # APPROXIMATION TO THIS FINITE POWER SERIES
  145. #
  146. # M M
  147. #
  148. # V(Z,M2) = SUM B(K)*Z**K / SUM C(K)*Z**K
  149. #
  150. # K=0 K=0
  151. #
  152. # + HIGHER ORDER TERMS, C(0)=ONE.
  153. #
  154. # THE CALCULATION MUST BE DONE FOR EACH NEW VALUE OF T.
  155. # THIS METHOD IS USED FOR METH=1.
  156. #
  157. # THE QUOTIENT-DIFFERENCE (QD) ALGORITHM IS ANOTHER WAY
  158. # OF CALCULATING THIS DIAGONAL PADE APPROXIMATION, IN THE FORM
  159. # OF A CONTINUED FRACTION
  160. #
  161. # V(Z,M2) = D(0)/(ONE+D(1)*Z/(ONE+...+D(M2-1)*Z/(ONE+R2M(Z)))),
  162. #
  163. # WHERE R2M(Z) IS THE UNKNOWN REMAINDER.
  164. # THE QD ALGORITHM GIVES THE COEFFICIENTS (D(K),K=0,M2), AND
  165. # THE CONTINUED FRACTION IS THEN EVALUATED BY FORWARD RECURRENCE,
  166. # FOR EACH NEW VALUE OF T, WITH R2M(Z) TAKEN AS D(M2)*Z.
  167. # THE ANSWERS SHOULD BE IDENTICAL TO THOSE GIVEN BY THE
  168. # EPSILON ALGORITHM, APART FROM ROUNDOFF ERROR.
  169. # THIS METHOD IS USED FOR METH=2.
  170. #
  171. # IN ADDITION, THE CONVERGENCE OF THE CONTINUED FRACTION CAN
  172. # BE ACCELERATED WITH AN IMPROVED ESTIMATE OF THE REMAINDER,
  173. # SATISFYING
  174. #
  175. # R2M + ONE + (D(M2-1)-D(M2))*Z = D(M2)*Z/R2M
  176. #
  177. # THIS METHOD IS USED FOR METH=3.
  178. #
  179. # USAGE
  180. #
  181. # THE USER MUST CHOOSE THE PARAMETERS BIGT AND GAMMA WHICH
  182. # DETERMINE THE DISCRETIZATION ERROR, AND N(=M2) WHICH
  183. # DETERMINES THE TRUNCATION ERROR AND ROUNDOFF ERROR, GIVEN
  184. # THE CHOICE OF BIGT AND GAMMA. AS N IS INCREASED, THE
  185. # TRUNCATION ERROR DECREASES BUT THE ROUNDOFF ERROR INCREASES,
  186. # SINCE THE EPSILON AND QD ALGORITHMS ARE NUMERICALLY UNSTABLE.
  187. # IT IS DESIRABLE TO USE DOUBLE PRECISION FOR THE CALCULATIONS,
  188. # UNLESS THE COMPUTER KEEPS AT LEAST 12 SIGNIFICANT DECIMAL
  189. # DIGITS IN SINGLE PRECISION.
  190. # METH=1 USES THE EPSILON ALGORITHM, METH=2 USES THE QUOTIENT-
  191. # DIFFERENCE ALGORITHM, AND METH=3 USES THE QD ALGORITHM WITH
  192. # IMPROVED ESTIMATE OF THE REMAINDER ON EVALUATION.
  193. #
  194. # AN ESTIMATE OF THE OPTIMAL VALUE OF N FOR GIVEN BIGT AND
  195. # GAMMA CAN BE GOT BY VARYING N AND CHOOSING A VALUE SLIGHTLY
  196. # LESS THAN THAT WHICH CAUSES THE RESULTS FOR METH=1 TO VARY
  197. # SIGNIFICANTLY FROM THOSE FOR METH=2.
  198. #
  199. # CALCULATIONS USING THE QD ALGORITHM ARE MOST EFFICIENT
  200. # AND MOST ACCURATE IF LAPADC IS CALLED WITH METH=3, AND WITH
  201. # INIT=1 ON THE FIRST CALL WITH NEW VALUES OF BIGT, GAMMA, N
  202. # OR FUN, AND WITH INIT=2 ON SUBSEQUENT CALLS WITH NEW VALUES
  203. # OF T AND THE OTHER PARAMETERS UNCHANGED.
  204. #
  205. #
  206. # DESCRIPTION OF ARGUMENTS
  207. #
  208. # T - REAL (DOUBLE PRECISION) VARIABLE. ON INPUT, VALUE
  209. # OF INDEPENDENT VARIABLE AT WHICH INVERSE FUNCTION
  210. # F(T) IS TO BE APPROXIMATED. UNCHANGED ON OUTPUT.
  211. # GAMMA - REAL (DOUBLE PRECISION) VARIABLE. ON INPUT,
  212. # CONTAINS PARAMETER OF INVERSION INTEGRAL, GOVERNING
  213. # ACCURACY OF INVERSION. UNCHANGED ON OUTPUT.
  214. # BIGT - REAL (DOUBLE PRECISION) VARIABLE. ON INPUT,
  215. # CONTAINS PARAMETER USED TO DISCRETIZE INVERSION
  216. # INTEGRAL. GOVERNS DISCRETIZATION ERROR.
  217. # UNCHANGED ON OUTPUT.
  218. # N - INTEGER VARIABLE, SHOULD BE EVEN .GE. 2. ON INPUT,
  219. # CONTAINS NUMBER OF TERMS TO BE USED IN SUM FOR
  220. # APPROXIMATION. DETERMINES TRUNCATION ERROR.
  221. # UNCHANGED ON OUTPUT.
  222. # F - REAL (DOUBLE PRECISION) VARIABLE. ON OUTPUT,
  223. # CONTAINS VALUE OF INVERSE FUNCTION F(T), EVALUATED
  224. # AT T.
  225. # FUN - NAME OF USER-SUPPLIED SUBROUTINE WHICH EVALUATES
  226. # (DOUBLE) COMPLEX VALUES OF TRANSFORM FBAR(P)
  227. # FOR (DOUBLE) COMPLEX VALUES OF LAPLACE
  228. # TRANSFORM VARIABLE P. CALLED IF METH .EQ. 1 .OR.
  229. # INIT .EQ. 1. MUST BE DECLARED EXTERNAL IN
  230. # (SUB)PROGRAM CALLING LAPADC.
  231. # METH - INTEGER VARIABLE, DETERMINING METHOD TO BE USED TO
  232. # ACCELERATE CONVERGENCE OF SUM.
  233. # ON INPUT, METH .EQ. 1 INDICATES THAT THE EPSILON
  234. # ALGORITHM IS TO BE USED.
  235. # METH .EQ. 2 INDICATES THAT THE ORDINARY QUOTIENT
  236. # DIFFERENCE ALGORITHM IS TO BE USED.
  237. # METH .EQ. 3 INDICATES THAT THE QUOTIENT DIFFERENCE
  238. # ALGORITHM IS TO BE USED, WITH FURTHER ACCELERATION
  239. # OF THE CONVERGENCE OF THE CONTINUED FRACTION.
  240. # UNCHANGED ON OUTPUT.
  241. # INIT - INTEGER VARIABLE. ON INPUT, USED ONLY IF Q-D
  242. # ALGORITHM IS SPECIFIED (METH .EQ. 2 OR 3).
  243. # INIT .EQ. 1 INDICATES THAT THIS IS THE FIRST CALL
  244. # OF THE ALGORITHM WITH THESE VALUES OF GAMMA, BIGT,
  245. # N, FUN. IN THIS CASE, THE VALUES OF THE CONTINUED
  246. # FRACTION COEFFICIENTS D(0:N) ARE RECALCULATED, AND
  247. # THE CONTINUED FRACTION IS EVALUATED.
  248. # INIT .NE. 1 INDICATES THAT THE VALUES OF GAMMA,
  249. # BIGT, N, AND FUN ARE UNCHANGED SINCE THE LAST CALL.
  250. # IN THIS CASE, THE INPUT VALUES OF THE CONTINUED
  251. # FRACTION COEFFICIENTS D(0:N) ARE USED, AND THE
  252. # CONTINUED FRACTION IS EVALUATED.
  253. # UNCHANGED ON OUTPUT.
  254. # D - (DOUBLE) COMPLEX ARRAY, OF VARIABLE DIMENSION (0:N).
  255. # MUST BE DIMENSIONED IN CALLING PROGRAM.
  256. # ON INPUT, IF METH .EQ. 2 OR 3 .AND. INIT .NE. 1,
  257. # MUST CONTAIN CONTINUED FRACTION COEFFICIENTS
  258. # OUTPUT ON A PREVIOUS CALL.
  259. # ON OUTPUT, IF METH .EQ. 2 OR 3, CONTAINS CONTINUED
  260. # FRACTION COEFFICIENTS CALCULATED ON THIS CALL
  261. # (INIT .EQ. 1) OR AS SUPPLIED ON INPUT (INIT .NE. 1).
  262. # WORK - (DOUBLE) COMPLEX ARRAY OF VARIABLE DIMENSION (0:N).
  263. # MUST BE DIMENSIONED IN CALLING PROGRAM.
  264. # WORK SPACE USED FOR CALCULATING SUCCESSIVE DIAGONALS
  265. # OF THE TABLE IF METH .EQ. 1 .OR. INIT .EQ. 1.
  266. # ON OUTPUT, CONTAINS LAST CALCULATED DIAGONAL OF
  267. # TABLE.
  268. #
  269. # SUBROUTINE CALLED
  270. #
  271. # FUN(P,FBAR) - USER-SUPPLIED SUBROUTINE WHICH EVALUATES
  272. # (DOUBLE) COMPLEX VALUES OF TRANSFORM FBAR(P)
  273. # FOR (DOUBLE) COMPLEX VALUES OF LAPLACE
  274. # TRANSFORM VARIABLE P. CALLED IF METH .EQ. 1 .OR.
  275. # INIT .EQ. 1. MUST BE DECLARED EXTERNAL IN
  276. # (SUB)PROGRAM WHICH CALLS SUBROUTINE LAPADC.
  277. if N < 2:
  278. print 'Order too low (N at least 2)'
  279. return -1.0
  280. zeror = 0.0
  281. zero = 0.0 + 0.0j
  282. half = 0.5 + 0.0j
  283. one = 1.0 + 0.0j
  284. # work = zeros(N+1,dtype=complex128)
  285. # d = zeros(N+1,dtype=complex128)
  286. #make order multiple of 2
  287. M2 = (N / 2) * 2
  288. factor = pi / bigT
  289. # print 'factor', factor
  290. argR = t * factor
  291. Z = cos(argR) + sin(argR) * 1j
  292. if meth == 1 or init == 1:
  293. #new: get all A's first
  294. ##########################
  295. #need to think of way to do this
  296. ###########################
  297. #calculate table if epsilon algorithm is to be used, or
  298. #if this is the first call to quotient-difference algorithm
  299. #with these parameters and inverse transform
  300. A = FUN(gamma + zeror * 1j)
  301. AOld = half * A
  302. if AOld == 0.0:
  303. return 0.0
  304. argI = factor
  305. A = FUN(gamma + argI * 1j)
  306. #initialize table entries
  307. if meth == 1:
  308. ztoj = Z
  309. term = A * ztoj
  310. work[0] = AOld + term
  311. work[1] = one / term
  312. else:
  313. d[0] = AOld
  314. work[0] = zero
  315. work[1] = A / AOld
  316. d[1] = -1.0 * work[1]
  317. AOld = A
  318. #calculate successive diagonals of table
  319. for j in range(2, N + 1):
  320. #initialize calculation of diagonal
  321. old2 = work[0]
  322. old1 = work[1]
  323. argI += factor
  324. A = FUN(gamma + argI * 1j)
  325. # print 'A', A, A - AOld
  326. if A == 0:
  327. return 0.0
  328. if meth == 1:
  329. #calculate next term and sum of power series
  330. ztoj = Z * ztoj
  331. term = A * ztoj
  332. work[0] += term
  333. work[1] = one / term
  334. else:
  335. work[0] = zero
  336. work[1] = A / AOld
  337. AOld = A
  338. # print work[0:10]
  339. #calculate diagonal using Rhombus rules
  340. for i in range(2, j+1):
  341. old3 = old2
  342. old2 = old1
  343. old1 = work[i]
  344. # print 'old1', old1
  345. if meth == 1:
  346. #epsilon algorithm rule
  347. work[i] = old3 + one / (work[i-1] - old2)
  348. else:
  349. #quotient difference algorithm rules
  350. if i % 2 == 0:
  351. #difference form
  352. # print i, 'up', old3, work[i-1], old2
  353. if old2 == old3:
  354. # print 'ouch', work[i-1]
  355. work[i] = work[i-1]
  356. elif old3 + work[i-1] == 0j:
  357. # print 'pow'
  358. work[i] = old2
  359. else:
  360. work[i] = old3 - old2 + work[i-1]
  361. else:
  362. #quotient form
  363. # print i, 'down', old3, work[i-1], old2
  364. work[i] = old3 * work[i-1] / old2
  365. # print 'work[i-1] old2', work[i-1], old2, old3
  366. # print 'work', work[i]
  367. #save continued fraction coefficients
  368. if meth != 1:
  369. d[j] = -1.0 * work[j]
  370. # print 'd[j]', d[j]
  371. # print 'W', work
  372. # print 'd', d
  373. if meth == 1:
  374. #result of epsilon algorithm computation
  375. Result0 = work[N].real
  376. else:
  377. #evaluate continued fraction
  378. #initialize recurrence relations
  379. AOld1 = d[0]
  380. AOld2 = d[0]
  381. BOld1 = one + d[1] * Z
  382. BOld2 = one
  383. #use recurrence relations
  384. for j in range(2,N+1):
  385. if meth == 3 and j == N+1:
  386. #further acceleration on last iteration if required
  387. h2m = half * (one + (d[N] - d[N+1]) * Z)
  388. print (one + d[N+1] * Z / h2m**2)
  389. r2m = -1.0 * h2m * \
  390. (one - sqrt((one + d[N+1] * Z / h2m**2)))
  391. A = AOld1 + r2m * AOld2
  392. B = BOld1 + r2m * BOld2
  393. else:
  394. # print 'd', j, d[j]
  395. A = AOld1 + d[j] * Z * AOld2
  396. #print 'A', A
  397. AOld2 = AOld1
  398. AOld1 = A
  399. B = BOld1 + d[j] * Z * BOld2
  400. #print 'B', B
  401. BOld2 = BOld1
  402. BOld1 = B
  403. # print 'other', A, B
  404. ctemp = A /B
  405. #result of quotient difference algorithm evaluation
  406. Result0 = ctemp.real
  407. #return required approximate inverse
  408. # print 'hhog', exp(gamma * t), Result0, bigT
  409. return exp(gamma * t) * Result0 / bigT