gonum.org/v1/gonum@v0.14.0/mathext/internal/amos/origcode_test.go (about) 1 // Copyright ©2016 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package amos 6 7 import ( 8 "math" 9 "math/cmplx" 10 ) 11 12 // These routines are the versions directly modified from the Fortran code. 13 // They are used to ensure that code style improvements do not change the 14 // code output. 15 16 func iabs(a int) int { 17 if a >= 0 { 18 return a 19 } 20 return -a 21 } 22 23 func min0(a, b int) int { 24 if a < b { 25 return a 26 } 27 return b 28 } 29 30 func max0(a, b int) int { 31 if a > b { 32 return a 33 } 34 return b 35 } 36 37 func zairyOrig(ZR, ZI float64, ID, KODE int) (AIR, AII float64, NZ, IERR int) { 38 // zairy is adapted from the original Netlib code by Donald Amos. 39 // http://www.netlib.no/netlib/amos/zairy.f 40 41 // Original comment: 42 /* 43 C***BEGIN PROLOGUE ZAIRY 44 C***DATE WRITTEN 830501 (YYMMDD) 45 C***REVISION DATE 890801 (YYMMDD) 46 C***CATEGORY NO. B5K 47 C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD 48 C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES 49 C***PURPOSE TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z 50 C***DESCRIPTION 51 C 52 C ***A DOUBLE PRECISION ROUTINE*** 53 C ON KODE=1, ZAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR 54 C ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON 55 C KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)* 56 C DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN 57 C -PI/3<ARG(Z)<PI/3 AND THE EXPONENTIAL GROWTH IN 58 C PI/3<ABS(ARG(Z))<PI WHERE ZTA=(2/3)*Z*CSQRT(Z). 59 C 60 C WHILE THE AIRY FUNCTIONS AI(Z) AND DAI(Z)/DZ ARE ANALYTIC IN 61 C THE WHOLE Z PLANE, THE CORRESPONDING SCALED FUNCTIONS DEFINED 62 C FOR KODE=2 HAVE A CUT ALONG THE NEGATIVE REAL AXIS. 63 C DEFINTIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF 64 C MATHEMATICAL FUNCTIONS (REF. 1). 65 C 66 C INPUT ZR,ZI ARE DOUBLE PRECISION 67 C ZR,ZI - Z=CMPLX(ZR,ZI) 68 C ID - ORDER OF DERIVATIVE, ID=0 OR ID=1 69 C KODE - A PARAMETER TO INDICATE THE SCALING OPTION 70 C KODE= 1 returnS 71 C AI=AI(Z) ON ID=0 OR 72 C AI=DAI(Z)/DZ ON ID=1 73 C = 2 returnS 74 C AI=CEXP(ZTA)*AI(Z) ON ID=0 OR 75 C AI=CEXP(ZTA)*DAI(Z)/DZ ON ID=1 WHERE 76 C ZTA=(2/3)*Z*CSQRT(Z) 77 C 78 C OUTPUT AIR,AII ARE DOUBLE PRECISION 79 C AIR,AII- COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND 80 C KODE 81 C NZ - UNDERFLOW INDICATOR 82 C NZ= 0 , NORMAL return 83 C NZ= 1 , AI=CMPLX(0.0E0,0.0E0) DUE TO UNDERFLOW IN 84 C -PI/3<ARG(Z)<PI/3 ON KODE=1 85 C IERR - ERROR FLAG 86 C IERR=0, NORMAL return - COMPUTATION COMPLETED 87 C IERR=1, INPUT ERROR - NO COMPUTATION 88 C IERR=2, OVERFLOW - NO COMPUTATION, REAL(ZTA) 89 C TOO LARGE ON KODE=1 90 C IERR=3, CABS(Z) LARGE - COMPUTATION COMPLETED 91 C LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION 92 C PRODUCE LESS THAN HALF OF MACHINE ACCURACY 93 C IERR=4, CABS(Z) TOO LARGE - NO COMPUTATION 94 C COMPLETE LOSS OF ACCURACY BY ARGUMENT 95 C REDUCTION 96 C IERR=5, ERROR - NO COMPUTATION, 97 C ALGORITHM TERMINATION CONDITION NOT MET 98 C 99 C***LONG DESCRIPTION 100 C 101 C AI AND DAI ARE COMPUTED FOR CABS(Z)>1.0 FROM THE K BESSEL 102 C FUNCTIONS BY 103 C 104 C AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA) 105 C C=1.0/(PI*SQRT(3.0)) 106 C ZTA=(2/3)*Z**(3/2) 107 C 108 C WITH THE POWER SERIES FOR CABS(Z)<=1.0. 109 C 110 C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- 111 C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES 112 C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF 113 C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR), 114 C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR 115 C FLAG IERR=3 IS TRIGGERED WHERE UR=dmax(dmach[4),1.0D-18) IS 116 C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. 117 C ALSO, if THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN 118 C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT 119 C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE 120 C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA 121 C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, 122 C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE 123 C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE 124 C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT- 125 C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG- 126 C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN 127 C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN 128 C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, 129 C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE 130 C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER 131 C MACHINES. 132 C 133 C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX 134 C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT 135 C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- 136 C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE 137 C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), 138 C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF 139 C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY 140 C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN 141 C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY 142 C SEVERAL ORDERS OF MAGNITUDE. if ONE COMPONENT IS 10**K LARGER 143 C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, 144 C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS 145 C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER 146 C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY 147 C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER 148 C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE 149 C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, 150 C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, 151 C OR -PI/2+P. 152 C 153 C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ 154 C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF 155 C COMMERCE, 1955. 156 C 157 C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT 158 C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 159 C 160 C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX 161 C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- 162 C 1018, MAY, 1985 163 C 164 C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX 165 C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. 166 C MATH. SOFTWARE, 1986 167 */ 168 var AI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3 complex128 169 var AA, AD, AK, ALIM, ATRM, AZ, AZ3, BK, 170 CC, CK, COEF, CONEI, CONER, CSQI, CSQR, C1, C2, DIG, 171 DK, D1, D2, ELIM, FID, FNU, PTR, RL, R1M5, SFAC, STI, STR, 172 S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, TRM2R, TTH, ZEROI, 173 ZEROR, ZTAI, ZTAR, Z3I, Z3R, ALAZ, BB float64 174 var IFLAG, K, K1, K2, MR, NN int 175 var tmp complex128 176 177 // Extra element for padding. 178 CYR := []float64{math.NaN(), 0} 179 CYI := []float64{math.NaN(), 0} 180 181 _ = AI 182 _ = CONE 183 _ = CSQ 184 _ = CY 185 _ = S1 186 _ = S2 187 _ = TRM1 188 _ = TRM2 189 _ = Z 190 _ = ZTA 191 _ = Z3 192 193 TTH = 6.66666666666666667e-01 194 C1 = 3.55028053887817240e-01 195 C2 = 2.58819403792806799e-01 196 COEF = 1.83776298473930683e-01 197 ZEROR = 0 198 ZEROI = 0 199 CONER = 1 200 CONEI = 0 201 202 NZ = 0 203 if ID < 0 || ID > 1 { 204 IERR = 1 205 } 206 if KODE < 1 || KODE > 2 { 207 IERR = 1 208 } 209 if IERR != 0 { 210 return 211 } 212 AZ = zabs(complex(ZR, ZI)) 213 TOL = dmax(dmach[4], 1.0e-18) 214 FID = float64(ID) 215 if AZ > 1.0e0 { 216 goto Seventy 217 } 218 219 // POWER SERIES FOR CABS(Z)<=1. 220 S1R = CONER 221 S1I = CONEI 222 S2R = CONER 223 S2I = CONEI 224 if AZ < TOL { 225 goto OneSeventy 226 } 227 AA = AZ * AZ 228 if AA < TOL/AZ { 229 goto Forty 230 } 231 TRM1R = CONER 232 TRM1I = CONEI 233 TRM2R = CONER 234 TRM2I = CONEI 235 ATRM = 1.0e0 236 STR = ZR*ZR - ZI*ZI 237 STI = ZR*ZI + ZI*ZR 238 Z3R = STR*ZR - STI*ZI 239 Z3I = STR*ZI + STI*ZR 240 AZ3 = AZ * AA 241 AK = 2.0e0 + FID 242 BK = 3.0e0 - FID - FID 243 CK = 4.0e0 - FID 244 DK = 3.0e0 + FID + FID 245 D1 = AK * DK 246 D2 = BK * CK 247 AD = dmin(D1, D2) 248 AK = 24.0e0 + 9.0e0*FID 249 BK = 30.0e0 - 9.0e0*FID 250 for K = 1; K <= 25; K++ { 251 STR = (TRM1R*Z3R - TRM1I*Z3I) / D1 252 TRM1I = (TRM1R*Z3I + TRM1I*Z3R) / D1 253 TRM1R = STR 254 S1R = S1R + TRM1R 255 S1I = S1I + TRM1I 256 STR = (TRM2R*Z3R - TRM2I*Z3I) / D2 257 TRM2I = (TRM2R*Z3I + TRM2I*Z3R) / D2 258 TRM2R = STR 259 S2R = S2R + TRM2R 260 S2I = S2I + TRM2I 261 ATRM = ATRM * AZ3 / AD 262 D1 = D1 + AK 263 D2 = D2 + BK 264 AD = dmin(D1, D2) 265 if ATRM < TOL*AD { 266 goto Forty 267 } 268 AK = AK + 18.0e0 269 BK = BK + 18.0e0 270 } 271 Forty: 272 if ID == 1 { 273 goto Fifty 274 } 275 AIR = S1R*C1 - C2*(ZR*S2R-ZI*S2I) 276 AII = S1I*C1 - C2*(ZR*S2I+ZI*S2R) 277 if KODE == 1 { 278 return 279 } 280 tmp = zsqrt(complex(ZR, ZI)) 281 STR = real(tmp) 282 STI = imag(tmp) 283 ZTAR = TTH * (ZR*STR - ZI*STI) 284 ZTAI = TTH * (ZR*STI + ZI*STR) 285 tmp = zexp(complex(ZTAR, ZTAI)) 286 STR = real(tmp) 287 STI = imag(tmp) 288 PTR = AIR*STR - AII*STI 289 AII = AIR*STI + AII*STR 290 AIR = PTR 291 return 292 293 Fifty: 294 AIR = -S2R * C2 295 AII = -S2I * C2 296 if AZ <= TOL { 297 goto Sixty 298 } 299 STR = ZR*S1R - ZI*S1I 300 STI = ZR*S1I + ZI*S1R 301 CC = C1 / (1.0e0 + FID) 302 AIR = AIR + CC*(STR*ZR-STI*ZI) 303 AII = AII + CC*(STR*ZI+STI*ZR) 304 305 Sixty: 306 if KODE == 1 { 307 return 308 } 309 tmp = zsqrt(complex(ZR, ZI)) 310 STR = real(tmp) 311 STI = imag(tmp) 312 ZTAR = TTH * (ZR*STR - ZI*STI) 313 ZTAI = TTH * (ZR*STI + ZI*STR) 314 tmp = zexp(complex(ZTAR, ZTAI)) 315 STR = real(tmp) 316 STI = imag(tmp) 317 PTR = STR*AIR - STI*AII 318 AII = STR*AII + STI*AIR 319 AIR = PTR 320 return 321 322 // CASE FOR CABS(Z)>1.0. 323 Seventy: 324 FNU = (1.0e0 + FID) / 3.0e0 325 326 /* 327 SET PARAMETERS RELATED TO MACHINE CONSTANTS. 328 TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18. 329 ELIM IS THE APPROXIMATE EXPONENTIAL OVER-&&UNDERFLOW LIMIT. 330 EXP(-ELIM)<EXP(-ALIM)=EXP(-ELIM)/TOL AND 331 EXP(ELIM)>EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR 332 UNDERFLOW&&OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. 333 RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LA>=Z. 334 DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). 335 */ 336 K1 = imach[15] 337 K2 = imach[16] 338 R1M5 = dmach[5] 339 340 K = min0(iabs(K1), iabs(K2)) 341 ELIM = 2.303e0 * (float64(K)*R1M5 - 3.0e0) 342 K1 = imach[14] - 1 343 AA = R1M5 * float64(K1) 344 DIG = dmin(AA, 18.0e0) 345 AA = AA * 2.303e0 346 ALIM = ELIM + dmax(-AA, -41.45e0) 347 RL = 1.2e0*DIG + 3.0e0 348 ALAZ = dlog(AZ) 349 350 // TEST FOR PROPER RANGE. 351 AA = 0.5e0 / TOL 352 BB = float64(float32(imach[9])) * 0.5e0 353 AA = dmin(AA, BB) 354 AA = math.Pow(AA, TTH) 355 if AZ > AA { 356 goto TwoSixty 357 } 358 AA = dsqrt(AA) 359 if AZ > AA { 360 IERR = 3 361 } 362 tmp = zsqrt(complex(ZR, ZI)) 363 CSQR = real(tmp) 364 CSQI = imag(tmp) 365 ZTAR = TTH * (ZR*CSQR - ZI*CSQI) 366 ZTAI = TTH * (ZR*CSQI + ZI*CSQR) 367 368 // RE(ZTA)<=0 WHEN RE(Z)<0, ESPECIALLY WHEN IM(Z) IS SMALL. 369 IFLAG = 0 370 SFAC = 1.0e0 371 AK = ZTAI 372 if ZR >= 0.0e0 { 373 goto Eighty 374 } 375 BK = ZTAR 376 CK = -dabs(BK) 377 ZTAR = CK 378 ZTAI = AK 379 380 Eighty: 381 if ZI != 0.0e0 { 382 goto Ninety 383 } 384 if ZR > 0.0e0 { 385 goto Ninety 386 } 387 ZTAR = 0.0e0 388 ZTAI = AK 389 Ninety: 390 AA = ZTAR 391 if AA >= 0.0e0 && ZR > 0.0e0 { 392 goto OneTen 393 } 394 if KODE == 2 { 395 goto OneHundred 396 } 397 398 // OVERFLOW TEST. 399 if AA > (-ALIM) { 400 goto OneHundred 401 } 402 AA = -AA + 0.25e0*ALAZ 403 IFLAG = 1 404 SFAC = TOL 405 if AA > ELIM { 406 goto TwoSeventy 407 } 408 409 OneHundred: 410 // CBKNU AND CACON return EXP(ZTA)*K(FNU,ZTA) ON KODE=2. 411 MR = 1 412 if ZI < 0.0e0 { 413 MR = -1 414 } 415 ZTAR, ZTAI, FNU, KODE, MR, _, CYR, CYI, NN, RL, TOL, ELIM, ALIM = zacaiOrig(ZTAR, ZTAI, FNU, KODE, MR, 1, CYR, CYI, NN, RL, TOL, ELIM, ALIM) 416 if NN < 0 { 417 goto TwoEighty 418 } 419 NZ = NZ + NN 420 goto OneThirty 421 422 OneTen: 423 if KODE == 2 { 424 goto OneTwenty 425 } 426 427 // UNDERFLOW TEST. 428 if AA < ALIM { 429 goto OneTwenty 430 } 431 AA = -AA - 0.25e0*ALAZ 432 IFLAG = 2 433 SFAC = 1.0e0 / TOL 434 if AA < (-ELIM) { 435 goto TwoTen 436 } 437 OneTwenty: 438 ZTAR, ZTAI, FNU, KODE, _, CYR, CYI, NZ, TOL, ELIM, ALIM = zbknuOrig(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, TOL, ELIM, ALIM) 439 440 OneThirty: 441 S1R = CYR[1] * COEF 442 S1I = CYI[1] * COEF 443 if IFLAG != 0 { 444 goto OneFifty 445 } 446 if ID == 1 { 447 goto OneFourty 448 } 449 AIR = CSQR*S1R - CSQI*S1I 450 AII = CSQR*S1I + CSQI*S1R 451 return 452 OneFourty: 453 AIR = -(ZR*S1R - ZI*S1I) 454 AII = -(ZR*S1I + ZI*S1R) 455 return 456 OneFifty: 457 S1R = S1R * SFAC 458 S1I = S1I * SFAC 459 if ID == 1 { 460 goto OneSixty 461 } 462 STR = S1R*CSQR - S1I*CSQI 463 S1I = S1R*CSQI + S1I*CSQR 464 S1R = STR 465 AIR = S1R / SFAC 466 AII = S1I / SFAC 467 return 468 OneSixty: 469 STR = -(S1R*ZR - S1I*ZI) 470 S1I = -(S1R*ZI + S1I*ZR) 471 S1R = STR 472 AIR = S1R / SFAC 473 AII = S1I / SFAC 474 return 475 OneSeventy: 476 AA = 1.0e+3 * dmach[1] 477 S1R = ZEROR 478 S1I = ZEROI 479 if ID == 1 { 480 goto OneNinety 481 } 482 if AZ <= AA { 483 goto OneEighty 484 } 485 S1R = C2 * ZR 486 S1I = C2 * ZI 487 OneEighty: 488 AIR = C1 - S1R 489 AII = -S1I 490 return 491 OneNinety: 492 AIR = -C2 493 AII = 0.0e0 494 AA = dsqrt(AA) 495 if AZ <= AA { 496 goto TwoHundred 497 } 498 S1R = 0.5e0 * (ZR*ZR - ZI*ZI) 499 S1I = ZR * ZI 500 TwoHundred: 501 AIR = AIR + C1*S1R 502 AII = AII + C1*S1I 503 return 504 TwoTen: 505 NZ = 1 506 AIR = ZEROR 507 AII = ZEROI 508 return 509 TwoSeventy: 510 NZ = 0 511 IERR = 2 512 return 513 TwoEighty: 514 if NN == (-1) { 515 goto TwoSeventy 516 } 517 NZ = 0 518 IERR = 5 519 return 520 TwoSixty: 521 IERR = 4 522 NZ = 0 523 return 524 } 525 526 // sbknu computes the k bessel function in the right half z plane. 527 func zbknuOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) (ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { 528 /* Old dimension comment. 529 DIMENSION YR(N), YI(N), CC(8), CSSR(3), CSRR(3), BRY(3), CYR(2), 530 * CYI(2) 531 */ 532 533 // TODO(btracey): Find which of these are inputs/outputs/both and clean up 534 // the function call. 535 // YR and YI have length n (but n+1 with better indexing) 536 var AA, AK, ASCLE, A1, A2, BB, BK, CAZ, 537 CBI, CBR, CCHI, CCHR, CKI, CKR, COEFI, COEFR, CONEI, CONER, 538 CRSCR, CSCLR, CSHI, CSHR, CSI, CSR, CTWOR, 539 CZEROI, CZEROR, CZI, CZR, DNU, DNU2, DPI, ETEST, FC, FHS, 540 FI, FK, FKS, FMUI, FMUR, FPI, FR, G1, G2, HPI, PI, PR, PTI, 541 PTR, P1I, P1R, P2I, P2M, P2R, QI, QR, RAK, RCAZ, RTHPI, RZI, 542 RZR, R1, S, SMUI, SMUR, SPI, STI, STR, S1I, S1R, S2I, S2R, TM, 543 TTH, T1, T2, ELM, CELMR, ZDR, ZDI, AS, ALAS, HELIM float64 544 545 var I, IFLAG, INU, K, KFLAG, KK, KMAX, KODED, IDUM, J, IC, INUB, NW int 546 547 var tmp complex128 548 var CSSR, CSRR, BRY [4]float64 549 var CYR, CYI [3]float64 550 551 KMAX = 30 552 CZEROR = 0 553 CZEROI = 0 554 CONER = 1 555 CONEI = 0 556 CTWOR = 2 557 R1 = 2 558 559 DPI = 3.14159265358979324e0 560 RTHPI = 1.25331413731550025e0 561 SPI = 1.90985931710274403e0 562 HPI = 1.57079632679489662e0 563 FPI = 1.89769999331517738e0 564 TTH = 6.66666666666666666e-01 565 566 CC := [9]float64{math.NaN(), 5.77215664901532861e-01, -4.20026350340952355e-02, 567 -4.21977345555443367e-02, 7.21894324666309954e-03, 568 -2.15241674114950973e-04, -2.01348547807882387e-05, 569 1.13302723198169588e-06, 6.11609510448141582e-09} 570 571 CAZ = zabs(complex(ZR, ZI)) 572 CSCLR = 1.0e0 / TOL 573 CRSCR = TOL 574 CSSR[1] = CSCLR 575 CSSR[2] = 1.0e0 576 CSSR[3] = CRSCR 577 CSRR[1] = CRSCR 578 CSRR[2] = 1.0e0 579 CSRR[3] = CSCLR 580 BRY[1] = 1.0e+3 * dmach[1] / TOL 581 BRY[2] = 1.0e0 / BRY[1] 582 BRY[3] = dmach[2] 583 NZ = 0 584 IFLAG = 0 585 KODED = KODE 586 RCAZ = 1.0e0 / CAZ 587 STR = ZR * RCAZ 588 STI = -ZI * RCAZ 589 RZR = (STR + STR) * RCAZ 590 RZI = (STI + STI) * RCAZ 591 INU = int(float32(FNU + 0.5)) 592 DNU = FNU - float64(INU) 593 if dabs(DNU) == 0.5e0 { 594 goto OneTen 595 } 596 DNU2 = 0.0e0 597 if dabs(DNU) > TOL { 598 DNU2 = DNU * DNU 599 } 600 if CAZ > R1 { 601 goto OneTen 602 } 603 604 // SERIES FOR CABS(Z)<=R1. 605 FC = 1.0e0 606 tmp = zlog(complex(RZR, RZI)) 607 SMUR = real(tmp) 608 SMUI = imag(tmp) 609 FMUR = SMUR * DNU 610 FMUI = SMUI * DNU 611 FMUR, FMUI, CSHR, CSHI, CCHR, CCHI = zshchOrig(FMUR, FMUI, CSHR, CSHI, CCHR, CCHI) 612 if DNU == 0.0e0 { 613 goto Ten 614 } 615 FC = DNU * DPI 616 FC = FC / dsin(FC) 617 SMUR = CSHR / DNU 618 SMUI = CSHI / DNU 619 Ten: 620 A2 = 1.0e0 + DNU 621 622 // GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU). 623 T2 = dexp(-dgamln(A2, IDUM)) 624 T1 = 1.0e0 / (T2 * FC) 625 if dabs(DNU) > 0.1e0 { 626 goto Forty 627 } 628 629 // SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU). 630 AK = 1.0e0 631 S = CC[1] 632 for K = 2; K <= 8; K++ { 633 AK = AK * DNU2 634 TM = CC[K] * AK 635 S = S + TM 636 if dabs(TM) < TOL { 637 goto Thirty 638 } 639 } 640 Thirty: 641 G1 = -S 642 goto Fifty 643 Forty: 644 G1 = (T1 - T2) / (DNU + DNU) 645 Fifty: 646 G2 = (T1 + T2) * 0.5e0 647 FR = FC * (CCHR*G1 + SMUR*G2) 648 FI = FC * (CCHI*G1 + SMUI*G2) 649 tmp = zexp(complex(FMUR, FMUI)) 650 STR = real(tmp) 651 STI = imag(tmp) 652 PR = 0.5e0 * STR / T2 653 PI = 0.5e0 * STI / T2 654 tmp = zdiv(complex(0.5, 0), complex(STR, STI)) 655 PTR = real(tmp) 656 PTI = imag(tmp) 657 QR = PTR / T1 658 QI = PTI / T1 659 S1R = FR 660 S1I = FI 661 S2R = PR 662 S2I = PI 663 AK = 1.0e0 664 A1 = 1.0e0 665 CKR = CONER 666 CKI = CONEI 667 BK = 1.0e0 - DNU2 668 if INU > 0 || N > 1 { 669 goto Eighty 670 } 671 672 // GENERATE K(FNU,Z), 0.0E0 <= FNU < 0.5E0 AND N=1. 673 if CAZ < TOL { 674 goto Seventy 675 } 676 tmp = zmlt(complex(ZR, ZI), complex(ZR, ZI)) 677 CZR = real(tmp) 678 CZI = imag(tmp) 679 CZR = 0.25e0 * CZR 680 CZI = 0.25e0 * CZI 681 T1 = 0.25e0 * CAZ * CAZ 682 Sixty: 683 FR = (FR*AK + PR + QR) / BK 684 FI = (FI*AK + PI + QI) / BK 685 STR = 1.0e0 / (AK - DNU) 686 PR = PR * STR 687 PI = PI * STR 688 STR = 1.0e0 / (AK + DNU) 689 QR = QR * STR 690 QI = QI * STR 691 STR = CKR*CZR - CKI*CZI 692 RAK = 1.0e0 / AK 693 CKI = (CKR*CZI + CKI*CZR) * RAK 694 CKR = STR * RAK 695 S1R = CKR*FR - CKI*FI + S1R 696 S1I = CKR*FI + CKI*FR + S1I 697 A1 = A1 * T1 * RAK 698 BK = BK + AK + AK + 1.0e0 699 AK = AK + 1.0e0 700 if A1 > TOL { 701 goto Sixty 702 } 703 Seventy: 704 YR[1] = S1R 705 YI[1] = S1I 706 if KODED == 1 { 707 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 708 } 709 tmp = zexp(complex(ZR, ZI)) 710 STR = real(tmp) 711 STI = imag(tmp) 712 tmp = zmlt(complex(S1R, S1I), complex(STR, STI)) 713 YR[1] = real(tmp) 714 YI[1] = imag(tmp) 715 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 716 717 // GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE. 718 Eighty: 719 if CAZ < TOL { 720 goto OneHundred 721 } 722 tmp = zmlt(complex(ZR, ZI), complex(ZR, ZI)) 723 CZR = real(tmp) 724 CZI = imag(tmp) 725 CZR = 0.25e0 * CZR 726 CZI = 0.25e0 * CZI 727 T1 = 0.25e0 * CAZ * CAZ 728 Ninety: 729 FR = (FR*AK + PR + QR) / BK 730 FI = (FI*AK + PI + QI) / BK 731 STR = 1.0e0 / (AK - DNU) 732 PR = PR * STR 733 PI = PI * STR 734 STR = 1.0e0 / (AK + DNU) 735 QR = QR * STR 736 QI = QI * STR 737 STR = CKR*CZR - CKI*CZI 738 RAK = 1.0e0 / AK 739 CKI = (CKR*CZI + CKI*CZR) * RAK 740 CKR = STR * RAK 741 S1R = CKR*FR - CKI*FI + S1R 742 S1I = CKR*FI + CKI*FR + S1I 743 STR = PR - FR*AK 744 STI = PI - FI*AK 745 S2R = CKR*STR - CKI*STI + S2R 746 S2I = CKR*STI + CKI*STR + S2I 747 A1 = A1 * T1 * RAK 748 BK = BK + AK + AK + 1.0e0 749 AK = AK + 1.0e0 750 if A1 > TOL { 751 goto Ninety 752 } 753 OneHundred: 754 KFLAG = 2 755 A1 = FNU + 1.0e0 756 AK = A1 * dabs(SMUR) 757 if AK > ALIM { 758 KFLAG = 3 759 } 760 STR = CSSR[KFLAG] 761 P2R = S2R * STR 762 P2I = S2I * STR 763 tmp = zmlt(complex(P2R, P2I), complex(RZR, RZI)) 764 S2R = real(tmp) 765 S2I = imag(tmp) 766 S1R = S1R * STR 767 S1I = S1I * STR 768 if KODED == 1 { 769 goto TwoTen 770 } 771 tmp = zexp(complex(ZR, ZI)) 772 FR = real(tmp) 773 FI = imag(tmp) 774 tmp = zmlt(complex(S1R, S1I), complex(FR, FI)) 775 S1R = real(tmp) 776 S1I = imag(tmp) 777 tmp = zmlt(complex(S2R, S2I), complex(FR, FI)) 778 S2R = real(tmp) 779 S2I = imag(tmp) 780 goto TwoTen 781 782 // IFLAG=0 MEANS NO UNDERFLOW OCCURRED 783 // IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH 784 // KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD RECURSION 785 OneTen: 786 tmp = zsqrt(complex(ZR, ZI)) 787 STR = real(tmp) 788 STI = imag(tmp) 789 tmp = zdiv(complex(RTHPI, CZEROI), complex(STR, STI)) 790 COEFR = real(tmp) 791 COEFI = imag(tmp) 792 KFLAG = 2 793 if KODED == 2 { 794 goto OneTwenty 795 } 796 if ZR > ALIM { 797 goto TwoNinety 798 } 799 800 STR = dexp(-ZR) * CSSR[KFLAG] 801 STI = -STR * dsin(ZI) 802 STR = STR * dcos(ZI) 803 tmp = zmlt(complex(COEFR, COEFI), complex(STR, STI)) 804 COEFR = real(tmp) 805 COEFI = imag(tmp) 806 OneTwenty: 807 if dabs(DNU) == 0.5e0 { 808 goto ThreeHundred 809 } 810 // MILLER ALGORITHM FOR CABS(Z)>R1. 811 AK = dcos(DPI * DNU) 812 AK = dabs(AK) 813 if AK == CZEROR { 814 goto ThreeHundred 815 } 816 FHS = dabs(0.25e0 - DNU2) 817 if FHS == CZEROR { 818 goto ThreeHundred 819 } 820 821 // COMPUTE R2=F(E). if CABS(Z)>=R2, USE FORWARD RECURRENCE TO 822 // DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON 823 // 12<=E<=60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(14))= 824 // TOL WHERE B IS THE BASE OF THE ARITHMETIC. 825 T1 = float64(imach[14] - 1) 826 T1 = T1 * dmach[5] * 3.321928094e0 827 T1 = dmax(T1, 12.0e0) 828 T1 = dmin(T1, 60.0e0) 829 T2 = TTH*T1 - 6.0e0 830 if ZR != 0.0e0 { 831 goto OneThirty 832 } 833 T1 = HPI 834 goto OneFourty 835 OneThirty: 836 T1 = datan(ZI / ZR) 837 T1 = dabs(T1) 838 OneFourty: 839 if T2 > CAZ { 840 goto OneSeventy 841 } 842 // FORWARD RECURRENCE LOOP WHEN CABS(Z)>=R2. 843 ETEST = AK / (DPI * CAZ * TOL) 844 FK = CONER 845 if ETEST < CONER { 846 goto OneEighty 847 } 848 FKS = CTWOR 849 CKR = CAZ + CAZ + CTWOR 850 P1R = CZEROR 851 P2R = CONER 852 for I = 1; I <= KMAX; I++ { 853 AK = FHS / FKS 854 CBR = CKR / (FK + CONER) 855 PTR = P2R 856 P2R = CBR*P2R - P1R*AK 857 P1R = PTR 858 CKR = CKR + CTWOR 859 FKS = FKS + FK + FK + CTWOR 860 FHS = FHS + FK + FK 861 FK = FK + CONER 862 STR = dabs(P2R) * FK 863 if ETEST < STR { 864 goto OneSixty 865 } 866 } 867 goto ThreeTen 868 OneSixty: 869 FK = FK + SPI*T1*dsqrt(T2/CAZ) 870 FHS = dabs(0.25 - DNU2) 871 goto OneEighty 872 OneSeventy: 873 // COMPUTE BACKWARD INDEX K FOR CABS(Z)<R2. 874 A2 = dsqrt(CAZ) 875 AK = FPI * AK / (TOL * dsqrt(A2)) 876 AA = 3.0e0 * T1 / (1.0e0 + CAZ) 877 BB = 14.7e0 * T1 / (28.0e0 + CAZ) 878 AK = (dlog(AK) + CAZ*dcos(AA)/(1.0e0+0.008e0*CAZ)) / dcos(BB) 879 FK = 0.12125e0*AK*AK/CAZ + 1.5e0 880 OneEighty: 881 // BACKWARD RECURRENCE LOOP FOR MILLER ALGORITHM. 882 K = int(float32(FK)) 883 FK = float64(K) 884 FKS = FK * FK 885 P1R = CZEROR 886 P1I = CZEROI 887 P2R = TOL 888 P2I = CZEROI 889 CSR = P2R 890 CSI = P2I 891 for I = 1; I <= K; I++ { 892 A1 = FKS - FK 893 AK = (FKS + FK) / (A1 + FHS) 894 RAK = 2.0e0 / (FK + CONER) 895 CBR = (FK + ZR) * RAK 896 CBI = ZI * RAK 897 PTR = P2R 898 PTI = P2I 899 P2R = (PTR*CBR - PTI*CBI - P1R) * AK 900 P2I = (PTI*CBR + PTR*CBI - P1I) * AK 901 P1R = PTR 902 P1I = PTI 903 CSR = CSR + P2R 904 CSI = CSI + P2I 905 FKS = A1 - FK + CONER 906 FK = FK - CONER 907 } 908 // COMPUTE (P2/CS)=(P2/CABS(CS))*(CONJG(CS)/CABS(CS)) FOR BETTER SCALING. 909 TM = zabs(complex(CSR, CSI)) 910 PTR = 1.0e0 / TM 911 S1R = P2R * PTR 912 S1I = P2I * PTR 913 CSR = CSR * PTR 914 CSI = -CSI * PTR 915 tmp = zmlt(complex(COEFR, COEFI), complex(S1R, S1I)) 916 STR = real(tmp) 917 STI = imag(tmp) 918 tmp = zmlt(complex(STR, STI), complex(CSR, CSI)) 919 S1R = real(tmp) 920 S1I = imag(tmp) 921 if INU > 0 || N > 1 { 922 goto TwoHundred 923 } 924 ZDR = ZR 925 ZDI = ZI 926 if IFLAG == 1 { 927 goto TwoSeventy 928 } 929 goto TwoFourty 930 TwoHundred: 931 // COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING. 932 TM = zabs(complex(P2R, P2I)) 933 PTR = 1.0e0 / TM 934 P1R = P1R * PTR 935 P1I = P1I * PTR 936 P2R = P2R * PTR 937 P2I = -P2I * PTR 938 tmp = zmlt(complex(P1R, P1I), complex(P2R, P2I)) 939 PTR = real(tmp) 940 PTI = imag(tmp) 941 STR = DNU + 0.5e0 - PTR 942 STI = -PTI 943 tmp = zdiv(complex(STR, STI), complex(ZR, ZI)) 944 STR = real(tmp) 945 STI = imag(tmp) 946 STR = STR + 1.0e0 947 tmp = zmlt(complex(STR, STI), complex(S1R, S1I)) 948 S2R = real(tmp) 949 S2I = imag(tmp) 950 951 // FORWARD RECURSION ON THE THREE TERM RECURSION WITH RELATION WITH 952 // SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3 953 TwoTen: 954 STR = DNU + 1.0e0 955 CKR = STR * RZR 956 CKI = STR * RZI 957 if N == 1 { 958 INU = INU - 1 959 } 960 if INU > 0 { 961 goto TwoTwenty 962 } 963 if N > 1 { 964 goto TwoFifteen 965 } 966 S1R = S2R 967 S1I = S2I 968 TwoFifteen: 969 ZDR = ZR 970 ZDI = ZI 971 if IFLAG == 1 { 972 goto TwoSeventy 973 } 974 goto TwoFourty 975 TwoTwenty: 976 INUB = 1 977 if IFLAG == 1 { 978 goto TwoSixtyOne 979 } 980 TwoTwentyFive: 981 P1R = CSRR[KFLAG] 982 ASCLE = BRY[KFLAG] 983 for I = INUB; I <= INU; I++ { 984 STR = S2R 985 STI = S2I 986 S2R = CKR*STR - CKI*STI + S1R 987 S2I = CKR*STI + CKI*STR + S1I 988 S1R = STR 989 S1I = STI 990 CKR = CKR + RZR 991 CKI = CKI + RZI 992 if KFLAG >= 3 { 993 continue 994 } 995 P2R = S2R * P1R 996 P2I = S2I * P1R 997 STR = dabs(P2R) 998 STI = dabs(P2I) 999 P2M = dmax(STR, STI) 1000 if P2M <= ASCLE { 1001 continue 1002 } 1003 KFLAG = KFLAG + 1 1004 ASCLE = BRY[KFLAG] 1005 S1R = S1R * P1R 1006 S1I = S1I * P1R 1007 S2R = P2R 1008 S2I = P2I 1009 STR = CSSR[KFLAG] 1010 S1R = S1R * STR 1011 S1I = S1I * STR 1012 S2R = S2R * STR 1013 S2I = S2I * STR 1014 P1R = CSRR[KFLAG] 1015 } 1016 if N != 1 { 1017 goto TwoFourty 1018 } 1019 S1R = S2R 1020 S1I = S2I 1021 TwoFourty: 1022 STR = CSRR[KFLAG] 1023 YR[1] = S1R * STR 1024 YI[1] = S1I * STR 1025 if N == 1 { 1026 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1027 } 1028 YR[2] = S2R * STR 1029 YI[2] = S2I * STR 1030 if N == 2 { 1031 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1032 } 1033 KK = 2 1034 TwoFifty: 1035 KK = KK + 1 1036 if KK > N { 1037 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1038 } 1039 P1R = CSRR[KFLAG] 1040 ASCLE = BRY[KFLAG] 1041 for I = KK; I <= N; I++ { 1042 P2R = S2R 1043 P2I = S2I 1044 S2R = CKR*P2R - CKI*P2I + S1R 1045 S2I = CKI*P2R + CKR*P2I + S1I 1046 S1R = P2R 1047 S1I = P2I 1048 CKR = CKR + RZR 1049 CKI = CKI + RZI 1050 P2R = S2R * P1R 1051 P2I = S2I * P1R 1052 YR[I] = P2R 1053 YI[I] = P2I 1054 if KFLAG >= 3 { 1055 continue 1056 } 1057 STR = dabs(P2R) 1058 STI = dabs(P2I) 1059 P2M = dmax(STR, STI) 1060 if P2M <= ASCLE { 1061 continue 1062 } 1063 KFLAG = KFLAG + 1 1064 ASCLE = BRY[KFLAG] 1065 S1R = S1R * P1R 1066 S1I = S1I * P1R 1067 S2R = P2R 1068 S2I = P2I 1069 STR = CSSR[KFLAG] 1070 S1R = S1R * STR 1071 S1I = S1I * STR 1072 S2R = S2R * STR 1073 S2I = S2I * STR 1074 P1R = CSRR[KFLAG] 1075 } 1076 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1077 1078 // IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW. 1079 TwoSixtyOne: 1080 HELIM = 0.5e0 * ELIM 1081 ELM = dexp(-ELIM) 1082 CELMR = ELM 1083 ASCLE = BRY[1] 1084 ZDR = ZR 1085 ZDI = ZI 1086 IC = -1 1087 J = 2 1088 for I = 1; I <= INU; I++ { 1089 STR = S2R 1090 STI = S2I 1091 S2R = STR*CKR - STI*CKI + S1R 1092 S2I = STI*CKR + STR*CKI + S1I 1093 S1R = STR 1094 S1I = STI 1095 CKR = CKR + RZR 1096 CKI = CKI + RZI 1097 AS = zabs(complex(S2R, S2I)) 1098 ALAS = dlog(AS) 1099 P2R = -ZDR + ALAS 1100 if P2R < (-ELIM) { 1101 goto TwoSixtyThree 1102 } 1103 tmp = zlog(complex(S2R, S2I)) 1104 STR = real(tmp) 1105 STI = imag(tmp) 1106 P2R = -ZDR + STR 1107 P2I = -ZDI + STI 1108 P2M = dexp(P2R) / TOL 1109 P1R = P2M * dcos(P2I) 1110 P1I = P2M * dsin(P2I) 1111 P1R, P1I, NW, ASCLE, TOL = zuchkOrig(P1R, P1I, NW, ASCLE, TOL) 1112 if NW != 0 { 1113 goto TwoSixtyThree 1114 } 1115 J = 3 - J 1116 CYR[J] = P1R 1117 CYI[J] = P1I 1118 if IC == (I - 1) { 1119 goto TwoSixtyFour 1120 } 1121 IC = I 1122 continue 1123 TwoSixtyThree: 1124 if ALAS < HELIM { 1125 continue 1126 } 1127 ZDR = ZDR - ELIM 1128 S1R = S1R * CELMR 1129 S1I = S1I * CELMR 1130 S2R = S2R * CELMR 1131 S2I = S2I * CELMR 1132 } 1133 if N != 1 { 1134 goto TwoSeventy 1135 } 1136 S1R = S2R 1137 S1I = S2I 1138 goto TwoSeventy 1139 TwoSixtyFour: 1140 KFLAG = 1 1141 INUB = I + 1 1142 S2R = CYR[J] 1143 S2I = CYI[J] 1144 J = 3 - J 1145 S1R = CYR[J] 1146 S1I = CYI[J] 1147 if INUB <= INU { 1148 goto TwoTwentyFive 1149 } 1150 if N != 1 { 1151 goto TwoFourty 1152 } 1153 S1R = S2R 1154 S1I = S2I 1155 goto TwoFourty 1156 TwoSeventy: 1157 YR[1] = S1R 1158 YI[1] = S1I 1159 if N == 1 { 1160 goto TwoEighty 1161 } 1162 YR[2] = S2R 1163 YI[2] = S2I 1164 TwoEighty: 1165 ASCLE = BRY[1] 1166 ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM = zksclOrig(ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM) 1167 INU = N - NZ 1168 if INU <= 0 { 1169 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1170 } 1171 KK = NZ + 1 1172 S1R = YR[KK] 1173 S1I = YI[KK] 1174 YR[KK] = S1R * CSRR[1] 1175 YI[KK] = S1I * CSRR[1] 1176 if INU == 1 { 1177 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1178 } 1179 KK = NZ + 2 1180 S2R = YR[KK] 1181 S2I = YI[KK] 1182 YR[KK] = S2R * CSRR[1] 1183 YI[KK] = S2I * CSRR[1] 1184 if INU == 2 { 1185 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1186 } 1187 T2 = FNU + float64(float32(KK-1)) 1188 CKR = T2 * RZR 1189 CKI = T2 * RZI 1190 KFLAG = 1 1191 goto TwoFifty 1192 TwoNinety: 1193 1194 // SCALE BY dexp(Z), IFLAG = 1 CASES. 1195 1196 KODED = 2 1197 IFLAG = 1 1198 KFLAG = 2 1199 goto OneTwenty 1200 1201 // FNU=HALF ODD INTEGER CASE, DNU=-0.5 1202 ThreeHundred: 1203 S1R = COEFR 1204 S1I = COEFI 1205 S2R = COEFR 1206 S2I = COEFI 1207 goto TwoTen 1208 1209 ThreeTen: 1210 NZ = -2 1211 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1212 } 1213 1214 // SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE 1215 // ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN 1216 // return WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL. 1217 func zksclOrig(ZRR, ZRI, FNU float64, N int, YR, YI []float64, NZ int, RZR, RZI, ASCLE, TOL, ELIM float64) ( 1218 ZRRout, ZRIout, FNUout float64, Nout int, YRout, YIout []float64, NZout int, RZRout, RZIout, ASCLEout, TOLout, ELIMout float64) { 1219 var ACS, AS, CKI, CKR, CSI, CSR, FN, STR, S1I, S1R, S2I, 1220 S2R, ZEROI, ZEROR, ZDR, ZDI, CELMR, ELM, HELIM, ALAS float64 1221 1222 var I, IC, KK, NN, NW int 1223 var tmp complex128 1224 var CYR, CYI [3]float64 1225 // DIMENSION YR(N), YI(N), CYR(2), CYI(2) 1226 ZEROR = 0 1227 ZEROI = 0 1228 NZ = 0 1229 IC = 0 1230 NN = min0(2, N) 1231 for I = 1; I <= NN; I++ { 1232 S1R = YR[I] 1233 S1I = YI[I] 1234 CYR[I] = S1R 1235 CYI[I] = S1I 1236 AS = zabs(complex(S1R, S1I)) 1237 ACS = -ZRR + dlog(AS) 1238 NZ = NZ + 1 1239 YR[I] = ZEROR 1240 YI[I] = ZEROI 1241 if ACS < (-ELIM) { 1242 continue 1243 } 1244 1245 tmp = zlog(complex(S1R, S1I)) 1246 CSR = real(tmp) 1247 CSI = imag(tmp) 1248 CSR = CSR - ZRR 1249 CSI = CSI - ZRI 1250 STR = dexp(CSR) / TOL 1251 CSR = STR * dcos(CSI) 1252 CSI = STR * dsin(CSI) 1253 CSR, CSI, NW, ASCLE, TOL = zuchkOrig(CSR, CSI, NW, ASCLE, TOL) 1254 if NW != 0 { 1255 continue 1256 } 1257 YR[I] = CSR 1258 YI[I] = CSI 1259 IC = I 1260 NZ = NZ - 1 1261 } 1262 if N == 1 { 1263 return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM 1264 } 1265 if IC > 1 { 1266 goto Twenty 1267 } 1268 YR[1] = ZEROR 1269 YI[1] = ZEROI 1270 NZ = 2 1271 Twenty: 1272 if N == 2 { 1273 return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM 1274 } 1275 if NZ == 0 { 1276 return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM 1277 } 1278 FN = FNU + 1.0e0 1279 CKR = FN * RZR 1280 CKI = FN * RZI 1281 S1R = CYR[1] 1282 S1I = CYI[1] 1283 S2R = CYR[2] 1284 S2I = CYI[2] 1285 HELIM = 0.5e0 * ELIM 1286 ELM = dexp(-ELIM) 1287 CELMR = ELM 1288 ZDR = ZRR 1289 ZDI = ZRI 1290 1291 // FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF 1292 // S2 GETS LARGER THAN EXP(ELIM/2) 1293 for I = 3; I <= N; I++ { 1294 KK = I 1295 CSR = S2R 1296 CSI = S2I 1297 S2R = CKR*CSR - CKI*CSI + S1R 1298 S2I = CKI*CSR + CKR*CSI + S1I 1299 S1R = CSR 1300 S1I = CSI 1301 CKR = CKR + RZR 1302 CKI = CKI + RZI 1303 AS = zabs(complex(S2R, S2I)) 1304 ALAS = dlog(AS) 1305 ACS = -ZDR + ALAS 1306 NZ = NZ + 1 1307 YR[I] = ZEROR 1308 YI[I] = ZEROI 1309 if ACS < (-ELIM) { 1310 goto TwentyFive 1311 } 1312 tmp = zlog(complex(S2R, S2I)) 1313 CSR = real(tmp) 1314 CSI = imag(tmp) 1315 CSR = CSR - ZDR 1316 CSI = CSI - ZDI 1317 STR = dexp(CSR) / TOL 1318 CSR = STR * dcos(CSI) 1319 CSI = STR * dsin(CSI) 1320 CSR, CSI, NW, ASCLE, TOL = zuchkOrig(CSR, CSI, NW, ASCLE, TOL) 1321 if NW != 0 { 1322 goto TwentyFive 1323 } 1324 YR[I] = CSR 1325 YI[I] = CSI 1326 NZ = NZ - 1 1327 if IC == KK-1 { 1328 goto Forty 1329 } 1330 IC = KK 1331 continue 1332 TwentyFive: 1333 if ALAS < HELIM { 1334 continue 1335 } 1336 ZDR = ZDR - ELIM 1337 S1R = S1R * CELMR 1338 S1I = S1I * CELMR 1339 S2R = S2R * CELMR 1340 S2I = S2I * CELMR 1341 } 1342 NZ = N 1343 if IC == N { 1344 NZ = N - 1 1345 } 1346 goto FourtyFive 1347 Forty: 1348 NZ = KK - 2 1349 FourtyFive: 1350 for I = 1; I <= NZ; I++ { 1351 YR[I] = ZEROR 1352 YI[I] = ZEROI 1353 } 1354 return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM 1355 } 1356 1357 // Y ENTERS AS A SCALED QUANTITY WHOSE MAGNITUDE IS GREATER THAN 1358 // EXP(-ALIM)=ASCLE=1.0E+3*dmach[1)/TOL. THE TEST IS MADE TO SEE 1359 // if THE MAGNITUDE OF THE REAL OR IMAGINARY PART WOULD UNDERFLOW 1360 // WHEN Y IS SCALED (BY TOL) TO ITS PROPER VALUE. Y IS ACCEPTED 1361 // if THE UNDERFLOW IS AT LEAST ONE PRECISION BELOW THE MAGNITUDE 1362 // OF THE LARGEST COMPONENT; OTHERWISE THE PHASE ANGLE DOES NOT HAVE 1363 // ABSOLUTE ACCURACY AND AN UNDERFLOW IS ASSUMED. 1364 func zuchkOrig(YR, YI float64, NZ int, ASCLE, TOL float64) (YRout, YIout float64, NZout int, ASCLEout, TOLout float64) { 1365 var SS, ST, WR, WI float64 1366 NZ = 0 1367 WR = dabs(YR) 1368 WI = dabs(YI) 1369 ST = dmin(WR, WI) 1370 if ST > ASCLE { 1371 return YR, YI, NZ, ASCLE, TOL 1372 } 1373 SS = dmax(WR, WI) 1374 ST = ST / TOL 1375 if SS < ST { 1376 NZ = 1 1377 } 1378 return YR, YI, NZ, ASCLE, TOL 1379 } 1380 1381 // ZACAI APPLIES THE ANALYTIC CONTINUATION FORMULA 1382 // 1383 // K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN) 1384 // MP=PI*MR*CMPLX(0.0,1.0) 1385 // 1386 // TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT 1387 // HALF Z PLANE FOR USE WITH ZAIRY WHERE FNU=1/3 OR 2/3 AND N=1. 1388 // ZACAI IS THE SAME AS ZACON WITH THE PARTS FOR LARGER ORDERS AND 1389 // RECURRENCE REMOVED. A RECURSIVE CALL TO ZACON CAN RESULT if ZACON 1390 // IS CALLED FROM ZAIRY. 1391 func zacaiOrig(ZR, ZI, FNU float64, KODE, MR, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( 1392 ZRout, ZIout, FNUout float64, KODEout, MRout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { 1393 var ARG, ASCLE, AZ, CSGNR, CSGNI, CSPNR, 1394 CSPNI, C1R, C1I, C2R, C2I, DFNU, FMR, PI, 1395 SGN, YY, ZNR, ZNI float64 1396 var INU, IUF, NN, NW int 1397 CYR := []float64{math.NaN(), 0, 0} 1398 CYI := []float64{math.NaN(), 0, 0} 1399 1400 PI = math.Pi 1401 NZ = 0 1402 ZNR = -ZR 1403 ZNI = -ZI 1404 AZ = zabs(complex(ZR, ZI)) 1405 NN = N 1406 DFNU = FNU + float64(float32(N-1)) 1407 if AZ <= 2.0e0 { 1408 goto Ten 1409 } 1410 if AZ*AZ*0.25 > DFNU+1.0e0 { 1411 goto Twenty 1412 } 1413 Ten: 1414 // POWER SERIES FOR THE I FUNCTION. 1415 ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM = zseriOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM) 1416 goto Forty 1417 Twenty: 1418 if AZ < RL { 1419 goto Thirty 1420 } 1421 // ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION. 1422 ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM = zasyiOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM) 1423 if NW < 0 { 1424 goto Eighty 1425 } 1426 goto Forty 1427 Thirty: 1428 // MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION 1429 ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL = zmlriOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL) 1430 if NW < 0 { 1431 goto Eighty 1432 } 1433 Forty: 1434 // ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION. 1435 ZNR, ZNI, FNU, KODE, _, CYR, CYI, NW, TOL, ELIM, ALIM = zbknuOrig(ZNR, ZNI, FNU, KODE, 1, CYR, CYI, NW, TOL, ELIM, ALIM) 1436 if NW != 0 { 1437 goto Eighty 1438 } 1439 FMR = float64(float32(MR)) 1440 SGN = -math.Copysign(PI, FMR) 1441 CSGNR = 0.0e0 1442 CSGNI = SGN 1443 if KODE == 1 { 1444 goto Fifty 1445 } 1446 YY = -ZNI 1447 CSGNR = -CSGNI * dsin(YY) 1448 CSGNI = CSGNI * dcos(YY) 1449 Fifty: 1450 // CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE 1451 // WHEN FNU IS LARGE 1452 INU = int(float32(FNU)) 1453 ARG = (FNU - float64(float32(INU))) * SGN 1454 CSPNR = dcos(ARG) 1455 CSPNI = dsin(ARG) 1456 if INU%2 == 0 { 1457 goto Sixty 1458 } 1459 CSPNR = -CSPNR 1460 CSPNI = -CSPNI 1461 Sixty: 1462 C1R = CYR[1] 1463 C1I = CYI[1] 1464 C2R = YR[1] 1465 C2I = YI[1] 1466 if KODE == 1 { 1467 goto Seventy 1468 } 1469 IUF = 0 1470 ASCLE = 1.0e+3 * dmach[1] / TOL 1471 ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF = zs1s2Orig(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) 1472 NZ = NZ + NW 1473 Seventy: 1474 YR[1] = CSPNR*C1R - CSPNI*C1I + CSGNR*C2R - CSGNI*C2I 1475 YI[1] = CSPNR*C1I + CSPNI*C1R + CSGNR*C2I + CSGNI*C2R 1476 return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1477 Eighty: 1478 NZ = -1 1479 if NW == -2 { 1480 NZ = -2 1481 } 1482 return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1483 } 1484 1485 // ZASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z)>=0.0 BY 1486 // MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE 1487 // REGION CABS(Z)>MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL return. 1488 // NZ<0 INDICATES AN OVERFLOW ON KODE=1. 1489 func zasyiOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( 1490 ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { 1491 var AA, AEZ, AK, AK1I, AK1R, ARG, ARM, ATOL, 1492 AZ, BB, BK, CKI, CKR, CONEI, CONER, CS1I, CS1R, CS2I, CS2R, CZI, 1493 CZR, DFNU, DKI, DKR, DNU2, EZI, EZR, FDN, PI, P1I, 1494 P1R, RAZ, RTPI, RTR1, RZI, RZR, S, SGN, SQK, STI, STR, S2I, 1495 S2R, TZI, TZR, ZEROI, ZEROR float64 1496 1497 var I, IB, IL, INU, J, JL, K, KODED, M, NN int 1498 var tmp complex128 1499 1500 PI = math.Pi 1501 RTPI = 0.159154943091895336e0 1502 ZEROR = 0 1503 ZEROI = 0 1504 CONER = 1 1505 CONEI = 0 1506 1507 NZ = 0 1508 AZ = zabs(complex(ZR, ZI)) 1509 ARM = 1.0e3 * dmach[1] 1510 RTR1 = dsqrt(ARM) 1511 IL = min0(2, N) 1512 DFNU = FNU + float64(float32(N-IL)) 1513 1514 // OVERFLOW TEST 1515 RAZ = 1.0e0 / AZ 1516 STR = ZR * RAZ 1517 STI = -ZI * RAZ 1518 AK1R = RTPI * STR * RAZ 1519 AK1I = RTPI * STI * RAZ 1520 tmp = zsqrt(complex(AK1R, AK1I)) 1521 AK1R = real(tmp) 1522 AK1I = imag(tmp) 1523 CZR = ZR 1524 CZI = ZI 1525 if KODE != 2 { 1526 goto Ten 1527 } 1528 CZR = ZEROR 1529 CZI = ZI 1530 Ten: 1531 if dabs(CZR) > ELIM { 1532 goto OneHundred 1533 } 1534 DNU2 = DFNU + DFNU 1535 KODED = 1 1536 if (dabs(CZR) > ALIM) && (N > 2) { 1537 goto Twenty 1538 } 1539 KODED = 0 1540 tmp = zexp(complex(CZR, CZI)) 1541 STR = real(tmp) 1542 STI = imag(tmp) 1543 tmp = zmlt(complex(AK1R, AK1I), complex(STR, STI)) 1544 AK1R = real(tmp) 1545 AK1I = imag(tmp) 1546 Twenty: 1547 FDN = 0.0e0 1548 if DNU2 > RTR1 { 1549 FDN = DNU2 * DNU2 1550 } 1551 EZR = ZR * 8.0e0 1552 EZI = ZI * 8.0e0 1553 1554 // WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE 1555 // FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE 1556 // EXPANSION FOR THE IMAGINARY PART. 1557 AEZ = 8.0e0 * AZ 1558 S = TOL / AEZ 1559 JL = int(float32(RL+RL)) + 2 1560 P1R = ZEROR 1561 P1I = ZEROI 1562 if ZI == 0.0e0 { 1563 goto Thirty 1564 } 1565 1566 // CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF 1567 // SIGNIFICANCE WHEN FNU OR N IS LARGE 1568 INU = int(float32(FNU)) 1569 ARG = (FNU - float64(float32(INU))) * PI 1570 INU = INU + N - IL 1571 AK = -dsin(ARG) 1572 BK = dcos(ARG) 1573 if ZI < 0.0e0 { 1574 BK = -BK 1575 } 1576 P1R = AK 1577 P1I = BK 1578 if INU%2 == 0 { 1579 goto Thirty 1580 } 1581 P1R = -P1R 1582 P1I = -P1I 1583 Thirty: 1584 for K = 1; K <= IL; K++ { 1585 SQK = FDN - 1.0e0 1586 ATOL = S * dabs(SQK) 1587 SGN = 1.0e0 1588 CS1R = CONER 1589 CS1I = CONEI 1590 CS2R = CONER 1591 CS2I = CONEI 1592 CKR = CONER 1593 CKI = CONEI 1594 AK = 0.0e0 1595 AA = 1.0e0 1596 BB = AEZ 1597 DKR = EZR 1598 DKI = EZI 1599 // TODO(btracey): This loop is executed tens of thousands of times. Why? 1600 // is that really necessary? 1601 for J = 1; J <= JL; J++ { 1602 tmp = zdiv(complex(CKR, CKI), complex(DKR, DKI)) 1603 STR = real(tmp) 1604 STI = imag(tmp) 1605 CKR = STR * SQK 1606 CKI = STI * SQK 1607 CS2R = CS2R + CKR 1608 CS2I = CS2I + CKI 1609 SGN = -SGN 1610 CS1R = CS1R + CKR*SGN 1611 CS1I = CS1I + CKI*SGN 1612 DKR = DKR + EZR 1613 DKI = DKI + EZI 1614 AA = AA * dabs(SQK) / BB 1615 BB = BB + AEZ 1616 AK = AK + 8.0e0 1617 SQK = SQK - AK 1618 if AA <= ATOL { 1619 goto Fifty 1620 } 1621 } 1622 goto OneTen 1623 Fifty: 1624 S2R = CS1R 1625 S2I = CS1I 1626 if ZR+ZR >= ELIM { 1627 goto Sixty 1628 } 1629 TZR = ZR + ZR 1630 TZI = ZI + ZI 1631 tmp = zexp(complex(-TZR, -TZI)) 1632 STR = real(tmp) 1633 STI = imag(tmp) 1634 tmp = zmlt(complex(STR, STI), complex(P1R, P1I)) 1635 STR = real(tmp) 1636 STI = imag(tmp) 1637 tmp = zmlt(complex(STR, STI), complex(CS2R, CS2I)) 1638 STR = real(tmp) 1639 STI = imag(tmp) 1640 S2R = S2R + STR 1641 S2I = S2I + STI 1642 Sixty: 1643 FDN = FDN + 8.0e0*DFNU + 4.0e0 1644 P1R = -P1R 1645 P1I = -P1I 1646 M = N - IL + K 1647 YR[M] = S2R*AK1R - S2I*AK1I 1648 YI[M] = S2R*AK1I + S2I*AK1R 1649 } 1650 if N <= 2 { 1651 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1652 } 1653 NN = N 1654 K = NN - 2 1655 AK = float64(float32(K)) 1656 STR = ZR * RAZ 1657 STI = -ZI * RAZ 1658 RZR = (STR + STR) * RAZ 1659 RZI = (STI + STI) * RAZ 1660 IB = 3 1661 for I = IB; I <= NN; I++ { 1662 YR[K] = (AK+FNU)*(RZR*YR[K+1]-RZI*YI[K+1]) + YR[K+2] 1663 YI[K] = (AK+FNU)*(RZR*YI[K+1]+RZI*YR[K+1]) + YI[K+2] 1664 AK = AK - 1.0e0 1665 K = K - 1 1666 } 1667 if KODED == 0 { 1668 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1669 } 1670 tmp = zexp(complex(CZR, CZI)) 1671 CKR = real(tmp) 1672 CKI = imag(tmp) 1673 for I = 1; I <= NN; I++ { 1674 STR = YR[I]*CKR - YI[I]*CKI 1675 YI[I] = YR[I]*CKI + YI[I]*CKR 1676 YR[I] = STR 1677 } 1678 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1679 OneHundred: 1680 NZ = -1 1681 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1682 OneTen: 1683 NZ = -2 1684 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM 1685 } 1686 1687 // ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z)>=0.0 BY THE 1688 // MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES. 1689 func zmlriOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL float64) ( 1690 ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout float64) { 1691 var ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI, 1692 CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, PTI, PTR, P1I, 1693 P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI, 1694 SUMR, TFNF, TST, ZEROI, ZEROR float64 1695 var I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, M int 1696 var tmp complex128 1697 ZEROR = 0 1698 ZEROI = 0 1699 CONER = 1 1700 CONEI = 0 1701 1702 SCLE = dmach[1] / TOL 1703 NZ = 0 1704 AZ = zabs(complex(ZR, ZI)) 1705 IAZ = int(float32(AZ)) 1706 IFNU = int(float32(FNU)) 1707 INU = IFNU + N - 1 1708 AT = float64(float32(IAZ)) + 1.0e0 1709 RAZ = 1.0e0 / AZ 1710 STR = ZR * RAZ 1711 STI = -ZI * RAZ 1712 CKR = STR * AT * RAZ 1713 CKI = STI * AT * RAZ 1714 RZR = (STR + STR) * RAZ 1715 RZI = (STI + STI) * RAZ 1716 P1R = ZEROR 1717 P1I = ZEROI 1718 P2R = CONER 1719 P2I = CONEI 1720 ACK = (AT + 1.0e0) * RAZ 1721 RHO = ACK + dsqrt(ACK*ACK-1.0e0) 1722 RHO2 = RHO * RHO 1723 TST = (RHO2 + RHO2) / ((RHO2 - 1.0e0) * (RHO - 1.0e0)) 1724 TST = TST / TOL 1725 1726 // COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES. 1727 //fmt.Println("before loop", P2R, P2I, CKR, CKI, RZR, RZI, TST, AK) 1728 AK = AT 1729 for I = 1; I <= 80; I++ { 1730 PTR = P2R 1731 PTI = P2I 1732 P2R = P1R - (CKR*PTR - CKI*PTI) 1733 P2I = P1I - (CKI*PTR + CKR*PTI) 1734 P1R = PTR 1735 P1I = PTI 1736 CKR = CKR + RZR 1737 CKI = CKI + RZI 1738 AP = zabs(complex(P2R, P2I)) 1739 if AP > TST*AK*AK { 1740 goto Twenty 1741 } 1742 AK = AK + 1.0e0 1743 } 1744 goto OneTen 1745 Twenty: 1746 I = I + 1 1747 K = 0 1748 if INU < IAZ { 1749 goto Forty 1750 } 1751 // COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS. 1752 P1R = ZEROR 1753 P1I = ZEROI 1754 P2R = CONER 1755 P2I = CONEI 1756 AT = float64(float32(INU)) + 1.0e0 1757 STR = ZR * RAZ 1758 STI = -ZI * RAZ 1759 CKR = STR * AT * RAZ 1760 CKI = STI * AT * RAZ 1761 ACK = AT * RAZ 1762 TST = dsqrt(ACK / TOL) 1763 ITIME = 1 1764 for K = 1; K <= 80; K++ { 1765 PTR = P2R 1766 PTI = P2I 1767 P2R = P1R - (CKR*PTR - CKI*PTI) 1768 P2I = P1I - (CKR*PTI + CKI*PTR) 1769 P1R = PTR 1770 P1I = PTI 1771 CKR = CKR + RZR 1772 CKI = CKI + RZI 1773 AP = zabs(complex(P2R, P2I)) 1774 if AP < TST { 1775 continue 1776 } 1777 if ITIME == 2 { 1778 goto Forty 1779 } 1780 ACK = zabs(complex(CKR, CKI)) 1781 FLAM = ACK + dsqrt(ACK*ACK-1.0e0) 1782 FKAP = AP / zabs(complex(P1R, P1I)) 1783 RHO = dmin(FLAM, FKAP) 1784 TST = TST * dsqrt(RHO/(RHO*RHO-1.0e0)) 1785 ITIME = 2 1786 } 1787 goto OneTen 1788 Forty: 1789 // BACKWARD RECURRENCE AND SUM NORMALIZING RELATION. 1790 K = K + 1 1791 KK = max0(I+IAZ, K+INU) 1792 FKK = float64(float32(KK)) 1793 P1R = ZEROR 1794 P1I = ZEROI 1795 1796 // SCALE P2 AND SUM BY SCLE. 1797 P2R = SCLE 1798 P2I = ZEROI 1799 FNF = FNU - float64(float32(IFNU)) 1800 TFNF = FNF + FNF 1801 BK = dgamln(FKK+TFNF+1.0e0, IDUM) - dgamln(FKK+1.0e0, IDUM) - dgamln(TFNF+1.0e0, IDUM) 1802 BK = dexp(BK) 1803 SUMR = ZEROR 1804 SUMI = ZEROI 1805 KM = KK - INU 1806 for I = 1; I <= KM; I++ { 1807 PTR = P2R 1808 PTI = P2I 1809 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 1810 P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) 1811 P1R = PTR 1812 P1I = PTI 1813 AK = 1.0e0 - TFNF/(FKK+TFNF) 1814 ACK = BK * AK 1815 SUMR = SUMR + (ACK+BK)*P1R 1816 SUMI = SUMI + (ACK+BK)*P1I 1817 BK = ACK 1818 FKK = FKK - 1.0e0 1819 } 1820 YR[N] = P2R 1821 YI[N] = P2I 1822 if N == 1 { 1823 goto Seventy 1824 } 1825 for I = 2; I <= N; I++ { 1826 PTR = P2R 1827 PTI = P2I 1828 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 1829 P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) 1830 P1R = PTR 1831 P1I = PTI 1832 AK = 1.0e0 - TFNF/(FKK+TFNF) 1833 ACK = BK * AK 1834 SUMR = SUMR + (ACK+BK)*P1R 1835 SUMI = SUMI + (ACK+BK)*P1I 1836 BK = ACK 1837 FKK = FKK - 1.0e0 1838 M = N - I + 1 1839 YR[M] = P2R 1840 YI[M] = P2I 1841 } 1842 Seventy: 1843 if IFNU <= 0 { 1844 goto Ninety 1845 } 1846 for I = 1; I <= IFNU; I++ { 1847 PTR = P2R 1848 PTI = P2I 1849 P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) 1850 P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR) 1851 P1R = PTR 1852 P1I = PTI 1853 AK = 1.0e0 - TFNF/(FKK+TFNF) 1854 ACK = BK * AK 1855 SUMR = SUMR + (ACK+BK)*P1R 1856 SUMI = SUMI + (ACK+BK)*P1I 1857 BK = ACK 1858 FKK = FKK - 1.0e0 1859 } 1860 Ninety: 1861 PTR = ZR 1862 PTI = ZI 1863 if KODE == 2 { 1864 PTR = ZEROR 1865 } 1866 tmp = zlog(complex(RZR, RZI)) 1867 STR = real(tmp) 1868 STI = imag(tmp) 1869 P1R = -FNF*STR + PTR 1870 P1I = -FNF*STI + PTI 1871 AP = dgamln(1.0e0+FNF, IDUM) 1872 PTR = P1R - AP 1873 PTI = P1I 1874 1875 // THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW 1876 // IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES. 1877 P2R = P2R + SUMR 1878 P2I = P2I + SUMI 1879 AP = zabs(complex(P2R, P2I)) 1880 P1R = 1.0e0 / AP 1881 tmp = zexp(complex(PTR, PTI)) 1882 STR = real(tmp) 1883 STI = imag(tmp) 1884 CKR = STR * P1R 1885 CKI = STI * P1R 1886 PTR = P2R * P1R 1887 PTI = -P2I * P1R 1888 tmp = zmlt(complex(CKR, CKI), complex(PTR, PTI)) 1889 CNORMR = real(tmp) 1890 CNORMI = imag(tmp) 1891 for I = 1; I <= N; I++ { 1892 STR = YR[I]*CNORMR - YI[I]*CNORMI 1893 YI[I] = YR[I]*CNORMI + YI[I]*CNORMR 1894 YR[I] = STR 1895 } 1896 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL 1897 OneTen: 1898 NZ = -2 1899 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL 1900 } 1901 1902 // ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z)>=0.0 BY 1903 // MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE 1904 // REGION CABS(Z)<=2*SQRT(FNU+1). NZ=0 IS A NORMAL return. 1905 // NZ>0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO 1906 // DUE TO UNDERFLOW. NZ<0 MEANS UNDERFLOW OCCURRED, BUT THE 1907 // CONDITION CABS(Z)<=2*SQRT(FNU+1) WAS VIOLATED AND THE 1908 // COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ). 1909 func zseriOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) ( 1910 ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { 1911 var AA, ACZ, AK, AK1I, AK1R, ARM, ASCLE, ATOL, 1912 AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU, 1913 FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI, 1914 STR, S1I, S1R, S2I, S2R, ZEROI, ZEROR float64 1915 var I, IB, IDUM, IFLAG, IL, K, L, M, NN, NW int 1916 var WR, WI [3]float64 1917 var tmp complex128 1918 1919 CONER = 1.0 1920 NZ = 0 1921 AZ = zabs(complex(ZR, ZI)) 1922 if AZ == 0.0e0 { 1923 goto OneSixty 1924 } 1925 // TODO(btracey) 1926 // The original fortran line is "ARM = 1.0D+3*D1MACH(1)". Evidently, in Fortran 1927 // this is interpreted as one to the power of +3*D1MACH(1). While it is possible 1928 // this was intentional, it seems unlikely. 1929 //ARM = 1.0E0 + 3*dmach[1] 1930 //math.Pow(1, 3*dmach[1]) 1931 ARM = 1000 * dmach[1] 1932 RTR1 = dsqrt(ARM) 1933 CRSCR = 1.0e0 1934 IFLAG = 0 1935 if AZ < ARM { 1936 goto OneFifty 1937 } 1938 HZR = 0.5e0 * ZR 1939 HZI = 0.5e0 * ZI 1940 CZR = ZEROR 1941 CZI = ZEROI 1942 if AZ <= RTR1 { 1943 goto Ten 1944 } 1945 tmp = zmlt(complex(HZR, HZI), complex(HZR, HZI)) 1946 CZR = real(tmp) 1947 CZI = imag(tmp) 1948 Ten: 1949 ACZ = zabs(complex(CZR, CZI)) 1950 NN = N 1951 tmp = zlog(complex(HZR, HZI)) 1952 CKR = real(tmp) 1953 CKI = imag(tmp) 1954 Twenty: 1955 DFNU = FNU + float64(float32(NN-1)) 1956 FNUP = DFNU + 1.0e0 1957 1958 // UNDERFLOW TEST. 1959 AK1R = CKR * DFNU 1960 AK1I = CKI * DFNU 1961 AK = dgamln(FNUP, IDUM) 1962 AK1R = AK1R - AK 1963 if KODE == 2 { 1964 AK1R = AK1R - ZR 1965 } 1966 if AK1R > (-ELIM) { 1967 goto Forty 1968 } 1969 Thirty: 1970 NZ = NZ + 1 1971 YR[NN] = ZEROR 1972 YI[NN] = ZEROI 1973 if ACZ > DFNU { 1974 goto OneNinety 1975 } 1976 NN = NN - 1 1977 if NN == 0 { 1978 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 1979 } 1980 goto Twenty 1981 Forty: 1982 if AK1R > (-ALIM) { 1983 goto Fifty 1984 } 1985 IFLAG = 1 1986 SS = 1.0e0 / TOL 1987 CRSCR = TOL 1988 ASCLE = ARM * SS 1989 Fifty: 1990 AA = dexp(AK1R) 1991 if IFLAG == 1 { 1992 AA = AA * SS 1993 } 1994 COEFR = AA * dcos(AK1I) 1995 COEFI = AA * dsin(AK1I) 1996 ATOL = TOL * ACZ / FNUP 1997 IL = min0(2, NN) 1998 for I = 1; I <= IL; I++ { 1999 DFNU = FNU + float64(float32(NN-I)) 2000 FNUP = DFNU + 1.0e0 2001 S1R = CONER 2002 S1I = CONEI 2003 if ACZ < TOL*FNUP { 2004 goto Seventy 2005 } 2006 AK1R = CONER 2007 AK1I = CONEI 2008 AK = FNUP + 2.0e0 2009 S = FNUP 2010 AA = 2.0e0 2011 Sixty: 2012 RS = 1.0e0 / S 2013 STR = AK1R*CZR - AK1I*CZI 2014 STI = AK1R*CZI + AK1I*CZR 2015 AK1R = STR * RS 2016 AK1I = STI * RS 2017 S1R = S1R + AK1R 2018 S1I = S1I + AK1I 2019 S = S + AK 2020 AK = AK + 2.0e0 2021 AA = AA * ACZ * RS 2022 if AA > ATOL { 2023 goto Sixty 2024 } 2025 Seventy: 2026 S2R = S1R*COEFR - S1I*COEFI 2027 S2I = S1R*COEFI + S1I*COEFR 2028 WR[I] = S2R 2029 WI[I] = S2I 2030 if IFLAG == 0 { 2031 goto Eighty 2032 } 2033 S2R, S2I, NW, ASCLE, TOL = zuchkOrig(S2R, S2I, NW, ASCLE, TOL) 2034 if NW != 0 { 2035 goto Thirty 2036 } 2037 Eighty: 2038 M = NN - I + 1 2039 YR[M] = S2R * CRSCR 2040 YI[M] = S2I * CRSCR 2041 if I == IL { 2042 continue 2043 } 2044 tmp = zdiv(complex(COEFR, COEFI), complex(HZR, HZI)) 2045 STR = real(tmp) 2046 STI = imag(tmp) 2047 COEFR = STR * DFNU 2048 COEFI = STI * DFNU 2049 } 2050 if NN <= 2 { 2051 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2052 } 2053 K = NN - 2 2054 AK = float64(float32(K)) 2055 RAZ = 1.0e0 / AZ 2056 STR = ZR * RAZ 2057 STI = -ZI * RAZ 2058 RZR = (STR + STR) * RAZ 2059 RZI = (STI + STI) * RAZ 2060 if IFLAG == 1 { 2061 goto OneTwenty 2062 } 2063 IB = 3 2064 OneHundred: 2065 for I = IB; I <= NN; I++ { 2066 YR[K] = (AK+FNU)*(RZR*YR[K+1]-RZI*YI[K+1]) + YR[K+2] 2067 YI[K] = (AK+FNU)*(RZR*YI[K+1]+RZI*YR[K+1]) + YI[K+2] 2068 AK = AK - 1.0e0 2069 K = K - 1 2070 } 2071 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2072 2073 // RECUR BACKWARD WITH SCALED VALUES. 2074 OneTwenty: 2075 // EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE 2076 // UNDERFLOW LIMIT = ASCLE = dmach[1)*SS*1.0D+3. 2077 S1R = WR[1] 2078 S1I = WI[1] 2079 S2R = WR[2] 2080 S2I = WI[2] 2081 for L = 3; L <= NN; L++ { 2082 CKR = S2R 2083 CKI = S2I 2084 S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI) 2085 S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR) 2086 S1R = CKR 2087 S1I = CKI 2088 CKR = S2R * CRSCR 2089 CKI = S2I * CRSCR 2090 YR[K] = CKR 2091 YI[K] = CKI 2092 AK = AK - 1.0e0 2093 K = K - 1 2094 if zabs(complex(CKR, CKI)) > ASCLE { 2095 goto OneFourty 2096 } 2097 } 2098 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2099 OneFourty: 2100 IB = L + 1 2101 if IB > NN { 2102 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2103 } 2104 goto OneHundred 2105 OneFifty: 2106 NZ = N 2107 if FNU == 0.0e0 { 2108 NZ = NZ - 1 2109 } 2110 OneSixty: 2111 YR[1] = ZEROR 2112 YI[1] = ZEROI 2113 if FNU != 0.0e0 { 2114 goto OneSeventy 2115 } 2116 YR[1] = CONER 2117 YI[1] = CONEI 2118 OneSeventy: 2119 if N == 1 { 2120 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2121 } 2122 for I = 2; I <= N; I++ { 2123 YR[I] = ZEROR 2124 YI[I] = ZEROI 2125 } 2126 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2127 2128 // return WITH NZ<0 if CABS(Z*Z/4)>FNU+N-NZ-1 COMPLETE 2129 // THE CALCULATION IN CBINU WITH N=N-IABS(NZ) 2130 2131 OneNinety: 2132 NZ = -NZ 2133 return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM 2134 } 2135 2136 // ZS1S2 TESTS FOR A POSSIBLE UNDERFLOW RESULTING FROM THE 2137 // ADDITION OF THE I AND K FUNCTIONS IN THE ANALYTIC CON- 2138 // TINUATION FORMULA WHERE S1=K FUNCTION AND S2=I FUNCTION. 2139 // ON KODE=1 THE I AND K FUNCTIONS ARE DIFFERENT ORDERS OF 2140 // MAGNITUDE, BUT FOR KODE=2 THEY CAN BE OF THE SAME ORDER 2141 // OF MAGNITUDE AND THE MAXIMUM MUST BE AT LEAST ONE 2142 // PRECISION ABOVE THE UNDERFLOW LIMIT. 2143 func zs1s2Orig(ZRR, ZRI, S1R, S1I, S2R, S2I float64, NZ int, ASCLE, ALIM float64, IUF int) ( 2144 ZRRout, ZRIout, S1Rout, S1Iout, S2Rout, S2Iout float64, NZout int, ASCLEout, ALIMout float64, IUFout int) { 2145 var AA, ALN, AS1, AS2, C1I, C1R, S1DI, S1DR, ZEROI, ZEROR float64 2146 var tmp complex128 2147 2148 ZEROR = 0 2149 ZEROI = 0 2150 NZ = 0 2151 AS1 = zabs(complex(S1R, S1I)) 2152 AS2 = zabs(complex(S2R, S2I)) 2153 if S1R == 0.0e0 && S1I == 0.0e0 { 2154 goto Ten 2155 } 2156 if AS1 == 0.0e0 { 2157 goto Ten 2158 } 2159 ALN = -ZRR - ZRR + dlog(AS1) 2160 S1DR = S1R 2161 S1DI = S1I 2162 S1R = ZEROR 2163 S1I = ZEROI 2164 AS1 = ZEROR 2165 if ALN < (-ALIM) { 2166 goto Ten 2167 } 2168 tmp = zlog(complex(S1DR, S1DI)) 2169 C1R = real(tmp) 2170 C1I = imag(tmp) 2171 2172 C1R = C1R - ZRR - ZRR 2173 C1I = C1I - ZRI - ZRI 2174 tmp = zexp(complex(C1R, C1I)) 2175 S1R = real(tmp) 2176 S1I = imag(tmp) 2177 AS1 = zabs(complex(S1R, S1I)) 2178 IUF = IUF + 1 2179 Ten: 2180 AA = dmax(AS1, AS2) 2181 if AA > ASCLE { 2182 return ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, IUF 2183 } 2184 S1R = ZEROR 2185 S1I = ZEROI 2186 S2R = ZEROR 2187 S2I = ZEROI 2188 NZ = 1 2189 IUF = 0 2190 return ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, IUF 2191 } 2192 2193 // ZSHCH COMPUTES THE COMPLEX HYPERBOLIC FUNCTIONS CSH=SINH(X+iY) AND 2194 // CCH=COSH(X+I*Y), WHERE I**2=-1. 2195 // TODO(btracey): use cmplx.Sinh and cmplx.Cosh. 2196 func zshchOrig(ZR, ZI, CSHR, CSHI, CCHR, CCHI float64) (ZRout, ZIout, CSHRout, CSHIout, CCHRout, CCHIout float64) { 2197 var CH, CN, SH, SN float64 2198 SH = math.Sinh(ZR) 2199 CH = math.Cosh(ZR) 2200 SN = dsin(ZI) 2201 CN = dcos(ZI) 2202 CSHR = SH * CN 2203 CSHI = CH * SN 2204 CCHR = CH * CN 2205 CCHI = SH * SN 2206 return ZR, ZI, CSHR, CSHI, CCHR, CCHI 2207 } 2208 2209 func dmax(a, b float64) float64 { 2210 return math.Max(a, b) 2211 } 2212 2213 func dmin(a, b float64) float64 { 2214 return math.Min(a, b) 2215 } 2216 2217 func dabs(a float64) float64 { 2218 return math.Abs(a) 2219 } 2220 2221 func datan(a float64) float64 { 2222 return math.Atan(a) 2223 } 2224 2225 func dtan(a float64) float64 { 2226 return math.Tan(a) 2227 } 2228 2229 func dlog(a float64) float64 { 2230 return math.Log(a) 2231 } 2232 2233 func dsin(a float64) float64 { 2234 return math.Sin(a) 2235 } 2236 2237 func dcos(a float64) float64 { 2238 return math.Cos(a) 2239 } 2240 2241 func dexp(a float64) float64 { 2242 return math.Exp(a) 2243 } 2244 2245 func dsqrt(a float64) float64 { 2246 return math.Sqrt(a) 2247 } 2248 2249 func zmlt(a, b complex128) complex128 { 2250 return a * b 2251 } 2252 2253 func zdiv(a, b complex128) complex128 { 2254 return a / b 2255 } 2256 2257 func zabs(a complex128) float64 { 2258 return cmplx.Abs(a) 2259 } 2260 2261 func zsqrt(a complex128) complex128 { 2262 return cmplx.Sqrt(a) 2263 } 2264 2265 func zexp(a complex128) complex128 { 2266 return cmplx.Exp(a) 2267 } 2268 2269 func zlog(a complex128) complex128 { 2270 return cmplx.Log(a) 2271 } 2272 2273 // Zshch computes the hyperbolic sin and cosine of the input z. 2274 func Zshch(z complex128) (sinh, cosh complex128) { 2275 return cmplx.Sinh(z), cmplx.Cosh(z) 2276 }