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