⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cbess1_cpp.txt

📁 BESSEL PROGRAMS IN C/C
💻 TXT
字号:
/*************************************************************************
*            Functions used By programs TZBESJ, TZBESK, TZBESY           *
*    (Evalute Bessel Functions with complex argument, 1st to 3rd kind)   *
* ---------------------------------------------------------------------- *
* Reference:  AMOS, DONALD E., SANDIA NATIONAL LABORATORIES, 1983.       *
*                                                                        *
*                         C++ Release By J-P Moreau, Paris (07/05/2005). *
*************************************************************************/
#include <math.h>
#include <basis.h>
#include <vmblock.h>

#include "complex.h"

  //Function defined below
  void ZWRSK(REAL ZRR, REAL ZRI, REAL FNU, int KODE, int N, REAL *YR, REAL *YI,
             int *NZ, REAL *CWR, REAL *CWI, REAL TOL, REAL ELIM, REAL ALIM);

  //Functions defined in CBess0.cpp
  void ZSERI(REAL, REAL, REAL, int, int, REAL *, REAL *, int *, REAL, REAL, REAL);

  void ZASYI(REAL, REAL, REAL, int, int, REAL *, REAL *, int *, REAL, REAL, REAL, REAL);

  void ZMLRI(REAL, REAL, REAL, int, int, REAL *, REAL *, int *, REAL);

  void ZS1S2(REAL *, REAL *, REAL *, REAL *, REAL *, REAL *, int *, REAL, REAL, int *);

  void ZSHCH(REAL, REAL, REAL *, REAL *, REAL *, REAL *);

  REAL DGAMLN(REAL, int *);

  void ZUCHK(REAL, REAL, int *, REAL, REAL);

  void ZUOIK(REAL, REAL, REAL, int, int, int, REAL *, REAL *, int *, REAL, REAL, REAL);

  void ZRATI(REAL, REAL, REAL, int, REAL *, REAL *, REAL);

  //Function defined in CBess0
  void ZBKNU(REAL, REAL, REAL, int, int, REAL *, REAL *, int *, REAL, REAL, REAL);

  //Function defined inCBess2.cpp
  void ZBUNI(REAL ZR, REAL ZI, REAL FNU, int KODE, int N, REAL *CYR, REAL *CYI, 
	         int *NZ, int NUI, int *NLAST, REAL FNUL, REAL TOL, REAL ELIM, REAL ALIM);

  //for debug only
  void test(REAL, REAL, REAL, int, int, REAL *, REAL *, int *, REAL, REAL, REAL);


void ZBINU(REAL ZR, REAL ZI, REAL FNU, int KODE, int N, REAL *CYR, REAL *CYI,
           int *NZ, REAL RL, REAL FNUL, REAL TOL, REAL ELIM, REAL ALIM)  {
/***BEGIN PROLOGUE  ZBINU
!***REFER TO  ZBESH,ZBESI,ZBESJ,ZBESK,ZAIRY,ZBIRY

!   ZBINU COMPUTES THE I FUNCTION IN THE RIGHT HALF Z PLANE

!***ROUTINES CALLED  ZABS,ZASYI,ZBUNI,ZMLRI,ZSERI,ZUOIK,ZWRSK
!***END PROLOGUE  ZBINU */
//Labels: e10,e20,e30,e40,e50,e60,e70,e80,e100,e110,e120,e130

      REAL AZ, DFNU, ZEROI, ZEROR;
      int I, INW, NLAST, NN, NUI, NW;
      REAL *CWR, *CWI;
	  void *vmblock = NULL;

      ZEROR=0.0; ZEROI=0.0;

//    Initialize CWR, CWI
      vmblock = vminit();  
      CWR = (REAL *) vmalloc(vmblock, VEKTOR,  N+1, 0);
      CWI = (REAL *) vmalloc(vmblock, VEKTOR,  N+1, 0);
      if (! vmcomplete(vmblock)) {
        LogError ("No Memory", 0, __FILE__, __LINE__);
        return;
	  } 	 

      *NZ = 0;
      AZ = ZABS(ZR,ZI);
      NN = N;
      DFNU = FNU + 1.0*(N-1);
      if (AZ <= 2.0) goto e10;
      if (AZ*AZ*0.25 > DFNU+1.0) goto e20;
/*----------------------------------------------------------------------
!     POWER SERIES
!---------------------------------------------------------------------*/
e10:  ZSERI(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, TOL, ELIM, ALIM);
//	  test(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, TOL, ELIM, ALIM);
      INW = ABS(NW);
      *NZ = *NZ + INW;
      NN = NN - INW;
      if (NN == 0) {
        vmfree(vmblock);
	    return;
      }
      if (NW >= 0) goto e120;
      DFNU = FNU + 1.0*(NN-1);
e20:  if (AZ < RL) goto e40;
      if (DFNU <= 1.0) goto e30;
      if (AZ+AZ < DFNU*DFNU) goto e50;
/*----------------------------------------------------------------------
!     ASYMPTOTIC EXPANSION FOR LARGE Z
!---------------------------------------------------------------------*/
e30:  ZASYI(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, RL, TOL, ELIM, ALIM);
      if (NW < 0) goto e130;
      goto e120;
e40:  if (DFNU <= 1.0) goto e70;
/*----------------------------------------------------------------------
!     OVERFLOW AND UNDERFLOW TEST ON I SEQUENCE FOR MILLER ALGORITHM
!---------------------------------------------------------------------*/
e50:  ZUOIK(ZR, ZI, FNU, KODE, 1, NN, CYR, CYI, &NW, TOL, ELIM, ALIM);
      if (NW < 0) goto e130;
      *NZ = *NZ + NW;
      NN = NN - NW;
      if (NN == 0) {
        vmfree(vmblock);
	    return;
      }
      DFNU = FNU+1.0*(NN-1);
      if (DFNU > FNUL) goto e110;
      if (AZ > FNUL) goto e110;
e60:  if (AZ > RL) goto e80;
/*----------------------------------------------------------------------
!     MILLER ALGORITHM NORMALIZED BY THE SERIES
!---------------------------------------------------------------------*/
e70:  ZMLRI(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, TOL);
      if (NW < 0) goto e130;
      goto e120;
/*----------------------------------------------------------------------
!     MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------
!     OVERFLOW TEST ON K FUNCTIONS USED IN WRONSKIAN
!---------------------------------------------------------------------*/
e80:  ZUOIK(ZR, ZI, FNU, KODE, 2, 2, CWR, CWI, &NW, TOL, ELIM, ALIM);
      if (NW >= 0) goto e100;
      *NZ = NN;
      for (I=1; I<=NN; I++) {
        CYR[I] = ZEROR;
        CYI[I] = ZEROI;
      }
	  vmfree(vmblock);
      return;
e100: if (NW > 0) goto e130;
      ZWRSK(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, CWR, CWI, TOL, ELIM, ALIM);
      if (NW < 0) goto e130;
      goto e120;
/*----------------------------------------------------------------------
!     INCREMENT FNU+NN-1 UP TO FNUL, COMPUTE AND RECUR BACKWARD
!---------------------------------------------------------------------*/
e110: NUI = (int) (floor(FNUL-DFNU) + 1);
      NUI = IMAX(NUI,0);
      ZBUNI(ZR, ZI, FNU, KODE, NN, CYR, CYI, &NW, NUI, &NLAST, FNUL,TOL,ELIM,ALIM);
      if (NW < 0) goto e130;
      *NZ = *NZ + NW;
      if (NLAST == 0) goto e120;
      NN = NLAST;
      goto e60;
e120: vmfree(vmblock);
	  return;
e130: *NZ = -1;
      if (NW == -2)  *NZ = -2;
	  vmfree(vmblock);
} //ZBINU()


void ZWRSK(REAL ZRR, REAL ZRI, REAL FNU, int KODE, int N, REAL *YR, REAL *YI,
           int *NZ, REAL *CWR, REAL *CWI, REAL TOL, REAL ELIM, REAL ALIM)  {
/***BEGIN PROLOGUE  ZWRSK
!***REFER TO  ZBESI,ZBESK
!
!     ZWRSK COMPUTES THE I BESSEL FUNCTION FOR RE(Z) >= 0.0 BY
!     NORMALIZING THE I FUNCTION RATIOS FROM ZRATI BY THE WRONSKIAN
!
!***ROUTINES CALLED  D1MACH,ZBKNU,ZRATI,ZABS
!***END PROLOGUE  ZWRSK
!     COMPLEX CINU,CSCL,CT,CW,C1,C2,RCT,ST,Y,ZR */
//Labels: e10,e20,e30,e50

      REAL ACT, ACW, ASCLE, CINUI, CINUR, CSCLR, CTI, CTR, C1I, C1R,
      C2I, C2R, PTI, PTR, RACT, STI, STR;
      int I, NW;
/*----------------------------------------------------------------------
!     I(FNU+I-1,Z) BY BACKWARD RECURRENCE FOR RATIOS
!     Y(I)=I(FNU+I,Z)/I(FNU+I-1,Z) FROM CRATI NORMALIZED BY THE
!     WRONSKIAN WITH K(FNU,Z) AND K(FNU+1,Z) FROM CBKNU.
!---------------------------------------------------------------------*/
      *NZ = 0;
      ZBKNU(ZRR, ZRI, FNU, KODE, 2, CWR, CWI, &NW, TOL, ELIM, ALIM);
      if (NW != 0) goto e50;
      ZRATI(ZRR, ZRI, FNU, N, YR, YI, TOL);
/*----------------------------------------------------------------------
!     RECUR FORWARD ON I(FNU+1,Z) = R(FNU,Z)*I(FNU,Z),
!     R(FNU+J-1,Z)=Y(J),  J=1,...,N
!---------------------------------------------------------------------*/
      CINUR = 1.0;
      CINUI = 0.0;
      if (KODE == 1) goto e10;
      CINUR = COS(ZRI);
      CINUI = SIN(ZRI);
/*----------------------------------------------------------------------
!     ON LOW EXPONENT MACHINES THE K FUNCTIONS CAN BE CLOSE TO BOTH
!     THE UNDER AND OVERFLOW LIMITS AND THE NORMALIZATION MUST BE
!     SCALED TO PREVENT OVER OR UNDERFLOW. CUOIK HAS DETERMINED THAT
!     THE RESULT IS ON SCALE.
!---------------------------------------------------------------------*/
e10:  ACW = ZABS(CWR[2],CWI[2]);
      ASCLE = 1000*D1MACH(1)/TOL;
      CSCLR = 1.0;
      if (ACW > ASCLE) goto e20;
      CSCLR = 1.0/TOL;
      goto e30;
e20:  ASCLE = 1.0/ASCLE;
      if (ACW < ASCLE) goto e30;
      CSCLR = TOL;
e30:  C1R = CWR[1]*CSCLR;
      C1I = CWI[1]*CSCLR;
      C2R = CWR[2]*CSCLR;
      C2I = CWI[2]*CSCLR;
      STR = YR[1];
      STI = YI[1];
/*----------------------------------------------------------------------
!     CINU=CINU*(CONJG(CT)/CABS(CT))*(1.0D0/CABS(CT) PREVENTS
!     UNDER- OR OVERFLOW PREMATURELY BY SQUARING CABS(CT)
!---------------------------------------------------------------------*/
      PTR = STR*C1R - STI*C1I;
      PTI = STR*C1I + STI*C1R;
      PTR = PTR + C2R;
      PTI = PTI + C2I;
      CTR = ZRR*PTR - ZRI*PTI;
      CTI = ZRR*PTI + ZRI*PTR;
      ACT = ZABS(CTR,CTI);
      RACT = 1.0/ACT;
      CTR = CTR*RACT;
      CTI = -CTI*RACT;
      PTR = CINUR*RACT;
      PTI = CINUI*RACT;
      CINUR = PTR*CTR - PTI*CTI;
      CINUI = PTR*CTI + PTI*CTR;
      YR[1] = CINUR*CSCLR;
      YI[1] = CINUI*CSCLR;
      if (N == 1) return;
      for (I=2; I<=N; I++) {
        PTR = STR*CINUR - STI*CINUI;
        CINUI = STR*CINUI + STI*CINUR;
        CINUR = PTR;
        STR = YR[I];
        STI = YI[I];
        YR[I] = CINUR*CSCLR;
        YI[I] = CINUI*CSCLR;
      }
      return;
e50:  *NZ = -1;
      if (NW = -2) *NZ=-2;
} //ZWRSK()

//end of file cbess1.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -