lamv Subroutine

public subroutine lamv(v, xi, Vm, Vl, Dl)

Compute lambda function with arbitrary order v, and their derivative

Note

In the original version of this routine, x was returned modified as x = abs(x).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: v

Order of lambda function

real(kind=wp), intent(in) :: xi

Argument of lambda function

real(kind=wp), intent(out) :: Vm

Highest order computed

real(kind=wp), intent(out), dimension(0:*) :: Vl

Lambda function of order n+v0

real(kind=wp), intent(out), dimension(0:*) :: Dl

Derivative of lambda function


Calls

proc~~lamv~~CallsGraph proc~lamv specfun_module::lamv proc~gam0 specfun_module::gam0 proc~lamv->proc~gam0 proc~msta1 specfun_module::msta1 proc~lamv->proc~msta1 proc~msta2 specfun_module::msta2 proc~lamv->proc~msta2 proc~envj specfun_module::envj proc~msta1->proc~envj proc~msta2->proc~envj

Source Code

   subroutine lamv(v,xi,Vm,Vl,Dl)

      real(wp),intent(in) :: v !! Order of lambda function
      real(wp),intent(in) :: xi !! Argument of lambda function
      real(wp),intent(out) :: Vm !! Highest order computed
      real(wp),dimension(0:*),intent(out) :: Vl !! Lambda function of order `n+v0`
      real(wp),dimension(0:*),intent(out) :: Dl !! Derivative of lambda function

      real(wp) :: a0 , bjv0 , bjv1 , bk , ck , cs , f , f0 ,  &
                  f1 , f2 , fac , ga , px , qx , r , r0 , rc ,&
                  rp, x, rq , sk , uk , v0 , vk , vv , x2 , xk
      integer :: i , j , k , k0 , m , n

      real(wp),parameter :: rp2 = 2.0_wp / pi ! 0.63661977236758d0

      x = abs(xi)
      x2 = x*x
      n = int(v)
      v0 = v - n
      Vm = v
      if ( x<=12.0_wp ) then
         do k = 0 , n
            vk = v0 + k
            bk = 1.0_wp
            r = 1.0_wp
            do i = 1 , 50
               r = -0.25_wp*r*x2/(i*(i+vk))
               bk = bk + r
               if ( abs(r)<abs(bk)*1.0e-15_wp ) exit
            enddo
            Vl(k) = bk
            uk = 1.0_wp
            r = 1.0_wp
            do i = 1 , 50
               r = -0.25_wp*r*x2/(i*(i+vk+1.0_wp))
               uk = uk + r
               if ( abs(r)<abs(uk)*1.0e-15_wp ) exit
            enddo
            Dl(k) = -0.5_wp*x/(vk+1.0_wp)*uk
         enddo
         return
      endif
      k0 = 11
      if ( x>=35.0_wp ) k0 = 10
      if ( x>=50.0_wp ) k0 = 8
      bjv0 = 0.0_wp
      bjv1 = 0.0_wp
      do j = 0 , 1
         vv = 4.0_wp*(j+v0)*(j+v0)
         px = 1.0_wp
         rp = 1.0_wp
         do k = 1 , k0
            rp = -0.78125e-2_wp*rp*(vv-(4.0_wp*k-3.0_wp)**2.0_wp) &
                 *(vv-(4.0_wp*k-1.0_wp)**2.0_wp)/(k*(2.0_wp*k-1.0_wp)*x2)
            px = px + rp
         enddo
         qx = 1.0_wp
         rq = 1.0_wp
         do k = 1 , k0
            rq = -0.78125e-2_wp*rq*(vv-(4.0_wp*k-1.0_wp)**2.0_wp) &
                 *(vv-(4.0_wp*k+1.0_wp)**2.0_wp)/(k*(2.0_wp*k+1.0_wp)*x2)
            qx = qx + rq
         enddo
         qx = 0.125_wp*(vv-1.0_wp)*qx/x
         xk = x - (0.5_wp*(j+v0)+0.25_wp)*pi
         a0 = sqrt(rp2/x)
         ck = cos(xk)
         sk = sin(xk)
         if ( j==0 ) bjv0 = a0*(px*ck-qx*sk)
         if ( j==1 ) bjv1 = a0*(px*ck-qx*sk)
      enddo
      if ( v0==0.0_wp ) then
         ga = 1.0_wp
      else
         call gam0(v0,ga)
         ga = v0*ga
      endif
      fac = (2.0_wp/x)**v0*ga
      Vl(0) = bjv0
      Dl(0) = -bjv1 + v0/x*bjv0
      Vl(1) = bjv1
      Dl(1) = bjv0 - (1.0_wp+v0)/x*bjv1
      r0 = 2.0_wp*(1.0_wp+v0)/x
      if ( n<=1 ) then
         Vl(0) = fac*Vl(0)
         Dl(0) = fac*Dl(0) - v0/x*Vl(0)
         Vl(1) = fac*r0*Vl(1)
         Dl(1) = fac*r0*Dl(1) - (1.0_wp+v0)/x*Vl(1)
         return
      endif
      if ( n>=2 .and. n<=int(0.9_wp*x) ) then
         f0 = bjv0
         f1 = bjv1
         do k = 2 , n
            f = 2.0_wp*(k+v0-1.0_wp)/x*f1 - f0
            f0 = f1
            f1 = f
            Vl(k) = f
         enddo
      elseif ( n>=2 ) then
         m = msta1(x,200)
         if ( m<n ) then
            n = m
         else
            m = msta2(x,n,15)
         endif
         f = 0.0_wp
         f2 = 0.0_wp
         f1 = 1.0e-100_wp
         do k = m , 0 , -1
            f = 2.0_wp*(v0+k+1.0_wp)/x*f1 - f2
            if ( k<=n ) Vl(k) = f
            f2 = f1
            f1 = f
         enddo
         cs = 0.0_wp
         if ( abs(bjv0)>abs(bjv1) ) then
            cs = bjv0/f
         else
            cs = bjv1/f2
         endif
         do k = 0 , n
            Vl(k) = cs*Vl(k)
         enddo
      endif
      Vl(0) = fac*Vl(0)
      do j = 1 , n
         rc = fac*r0
         Vl(j) = rc*Vl(j)
         Dl(j-1) = -0.5_wp*x/(j+v0)*Vl(j)
         r0 = 2.0_wp*(j+v0+1)/x*r0
      enddo
      Dl(n) = 2.0_wp*(v0+n)*(Vl(n-1)-Vl(n))/x
      Vm = n + v0

   end subroutine lamv