BLAS
dscal ddot daxpy dswap idamax dasum dnrm2 dcopy
c*********************************************************************** c BLAS c*********************************************************************** c dscal c ddot c daxpy c dswap c idamax c dasum c dnrm2 c dcopy c*********************************************************************** subroutine dscal(n,da,dx,incx) c c scales a vector by a constant. c uses unrolled loops for increment equal to one. c jack dongarra, linpack, 3/11/78. c double precision da,dx(1) integer i,incx,m,mp1,n,nincx c if(n.le.0)return if(incx.eq.1)go to 20 c c code for increment not equal to 1 c nincx = n*incx do 10 i = 1,nincx,incx dx(i) = da*dx(i) 10 continue return c c code for increment equal to 1 c c c clean-up loop c 20 m = mod(n,5) if( m .eq. 0 ) go to 40 do 30 i = 1,m dx(i) = da*dx(i) 30 continue if( n .lt. 5 ) return 40 mp1 = m + 1 do 50 i = mp1,n,5 dx(i) = da*dx(i) dx(i + 1) = da*dx(i + 1) dx(i + 2) = da*dx(i + 2) dx(i + 3) = da*dx(i + 3) dx(i + 4) = da*dx(i + 4) 50 continue return end c*********************************************************************** double precision function ddot(n,dx,incx,dy,incy) c c forms the dot product of two vectors. c uses unrolled loops for increments equal to one. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dy(1),dtemp integer i,incx,incy,ix,iy,m,mp1,n c ddot = 0.0d0 dtemp = 0.0d0 if(n.le.0)return if(incx.eq.1.and.incy.eq.1)go to 20 c c code for unequal increments or equal increments c not equal to 1 c ix = 1 iy = 1 if(incx.lt.0)ix = (-n+1)*incx + 1 if(incy.lt.0)iy = (-n+1)*incy + 1 do 10 i = 1,n dtemp = dtemp + dx(ix)*dy(iy) ix = ix + incx iy = iy + incy 10 continue ddot = dtemp return c c code for both increments equal to 1 c c c clean-up loop c 20 m = mod(n,5) if( m .eq. 0 ) go to 40 do 30 i = 1,m dtemp = dtemp + dx(i)*dy(i) 30 continue if( n .lt. 5 ) go to 60 40 mp1 = m + 1 do 50 i = mp1,n,5 dtemp = dtemp + dx(i)*dy(i) + dx(i + 1)*dy(i + 1) + * dx(i + 2)*dy(i + 2) + dx(i + 3)*dy(i + 3) + dx(i + 4)*dy(i + 4) 50 continue 60 ddot = dtemp return end c*********************************************************************** subroutine daxpy(n,da,dx,incx,dy,incy) c c constant times a vector plus a vector. c uses unrolled loops for increments equal to one. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dy(1),da integer i,incx,incy,ix,iy,m,mp1,n c if(n.le.0)return if (da .eq. 0.0d0) return if(incx.eq.1.and.incy.eq.1)go to 20 c c code for unequal increments or equal increments c not equal to 1 c ix = 1 iy = 1 if(incx.lt.0)ix = (-n+1)*incx + 1 if(incy.lt.0)iy = (-n+1)*incy + 1 do 10 i = 1,n dy(iy) = dy(iy) + da*dx(ix) ix = ix + incx iy = iy + incy 10 continue return c c code for both increments equal to 1 c c c clean-up loop c 20 m = mod(n,4) if( m .eq. 0 ) go to 40 do 30 i = 1,m dy(i) = dy(i) + da*dx(i) 30 continue if( n .lt. 4 ) return 40 mp1 = m + 1 do 50 i = mp1,n,4 dy(i) = dy(i) + da*dx(i) dy(i + 1) = dy(i + 1) + da*dx(i + 1) dy(i + 2) = dy(i + 2) + da*dx(i + 2) dy(i + 3) = dy(i + 3) + da*dx(i + 3) 50 continue return end c*********************************************************************** subroutine dswap (n,dx,incx,dy,incy) c c interchanges two vectors. c uses unrolled loops for increments equal one. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dy(1),dtemp integer i,incx,incy,ix,iy,m,mp1,n c if(n.le.0)return if(incx.eq.1.and.incy.eq.1)go to 20 c c code for unequal increments or equal increments not equal c to 1 c ix = 1 iy = 1 if(incx.lt.0)ix = (-n+1)*incx + 1 if(incy.lt.0)iy = (-n+1)*incy + 1 do 10 i = 1,n dtemp = dx(ix) dx(ix) = dy(iy) dy(iy) = dtemp ix = ix + incx iy = iy + incy 10 continue return c c code for both increments equal to 1 c c c clean-up loop c 20 m = mod(n,3) if( m .eq. 0 ) go to 40 do 30 i = 1,m dtemp = dx(i) dx(i) = dy(i) dy(i) = dtemp 30 continue if( n .lt. 3 ) return 40 mp1 = m + 1 do 50 i = mp1,n,3 dtemp = dx(i) dx(i) = dy(i) dy(i) = dtemp dtemp = dx(i + 1) dx(i + 1) = dy(i + 1) dy(i + 1) = dtemp dtemp = dx(i + 2) dx(i + 2) = dy(i + 2) dy(i + 2) = dtemp 50 continue return end c*********************************************************************** integer function idamax(n,dx,incx) c c finds the index of element having max. absolute value. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dmax integer i,incx,ix,n c idamax = 0 if( n .lt. 1 ) return idamax = 1 if(n.eq.1)return if(incx.eq.1)go to 20 c c code for increment not equal to 1 c ix = 1 dmax = dabs(dx(1)) ix = ix + incx do 10 i = 2,n if(dabs(dx(ix)).le.dmax) go to 5 idamax = i dmax = dabs(dx(ix)) 5 ix = ix + incx 10 continue return c c code for increment equal to 1 c 20 dmax = dabs(dx(1)) do 30 i = 2,n if(dabs(dx(i)).le.dmax) go to 30 idamax = i dmax = dabs(dx(i)) 30 continue return end c*********************************************************************** double precision function dasum(n,dx,incx) c c takes the sum of the absolute values. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dtemp integer i,incx,m,mp1,n,nincx c dasum = 0.0d0 dtemp = 0.0d0 if(n.le.0)return if(incx.eq.1)go to 20 c c code for increment not equal to 1 c nincx = n*incx do 10 i = 1,nincx,incx dtemp = dtemp + dabs(dx(i)) 10 continue dasum = dtemp return c c code for increment equal to 1 c c c clean-up loop c 20 m = mod(n,6) if( m .eq. 0 ) go to 40 do 30 i = 1,m dtemp = dtemp + dabs(dx(i)) 30 continue if( n .lt. 6 ) go to 60 40 mp1 = m + 1 do 50 i = mp1,n,6 dtemp = dtemp + dabs(dx(i)) + dabs(dx(i + 1)) + dabs(dx(i + 2)) * + dabs(dx(i + 3)) + dabs(dx(i + 4)) + dabs(dx(i + 5)) 50 continue 60 dasum = dtemp return end DOUBLE PRECISION FUNCTION DNRM2(N,X,INCX) * .. Scalar Arguments .. INTEGER INCX,N * .. * .. Array Arguments .. DOUBLE PRECISION X(*) * .. * * Purpose * ======= * * DNRM2 returns the euclidean norm of a vector via the function * name, so that * * DNRM2 := sqrt( x`*x ) * * Further Details * =============== * * -- This version written on 25-October-1982. * Modified on 14-October-1993 to inline the call to DLASSQ. * Sven Hammarling, Nag Ltd. * * ===================================================================== * * .. Parameters .. DOUBLE PRECISION ONE,ZERO PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) * .. * .. Local Scalars .. DOUBLE PRECISION ABSXI,NORM,SCALE,SSQ INTEGER IX * .. * .. Intrinsic Functions .. INTRINSIC ABS,SQRT * .. IF (N.LT.1 .OR. INCX.LT.1) THEN NORM = ZERO ELSE IF (N.EQ.1) THEN NORM = ABS(X(1)) ELSE SCALE = ZERO SSQ = ONE * The following loop is equivalent to this call to the LAPACK * auxiliary routine: * CALL DLASSQ( N, X, INCX, SCALE, SSQ ) * DO 10 IX = 1,1 + (N-1)*INCX,INCX IF (X(IX).NE.ZERO) THEN ABSXI = ABS(X(IX)) IF (SCALE.LT.ABSXI) THEN SSQ = ONE + SSQ* (SCALE/ABSXI)**2 SCALE = ABSXI ELSE SSQ = SSQ + (ABSXI/SCALE)**2 END IF END IF 10 CONTINUE NORM = SCALE*SQRT(SSQ) END IF * DNRM2 = NORM RETURN * * End of DNRM2. * END ! c*********************************************************************** ! double precision function dnrm2 ( n, dx, incx) ! integer next ! double precision dx(1), cutlo, cuthi, hitest, sum, xmax,zero,one ! data zero, one /0.0d0, 1.0d0/ ! c ! c euclidean norm of the n-vector stored in dx() with storage ! c increment incx . ! c if n .le. 0 return with result = 0. ! c if n .ge. 1 then incx must be .ge. 1 ! c ! c c.l.lawson, 1978 jan 08 ! c ! c four phase method using two built-in constants that are ! c hopefully applicable to all machines. ! c cutlo = maximum of dsqrt(u/eps) over all known machines. ! c cuthi = minimum of dsqrt(v) over all known machines. ! c where ! c eps = smallest no. such that eps + 1. .gt. 1. ! c u = smallest positive no. (underflow limit) ! c v = largest no. (overflow limit) ! c ! c brief outline of algorithm.. ! c ! c phase 1 scans zero components. ! c move to phase 2 when a component is nonzero and .le. cutlo ! c move to phase 3 when a component is .gt. cutlo ! c move to phase 4 when a component is .ge. cuthi/m ! c where m = n for x() real and m = 2*n for complex. ! c ! c values for cutlo and cuthi.. ! c from the environmental parameters listed in the imsl converter ! c document the limiting values are as follows.. ! c cutlo, s.p. u/eps = 2**(-102) for honeywell. close seconds are ! c univac and dec at 2**(-103) ! c thus cutlo = 2**(-51) = 4.44089e-16 ! c cuthi, s.p. v = 2**127 for univac, honeywell, and dec. ! c thus cuthi = 2**(63.5) = 1.30438e19 ! c cutlo, d.p. u/eps = 2**(-67) for honeywell and dec. ! c thus cutlo = 2**(-33.5) = 8.23181d-11 ! c cuthi, d.p. same as s.p. cuthi = 1.30438d19 ! c data cutlo, cuthi / 8.232d-11, 1.304d19 / ! c data cutlo, cuthi / 4.441e-16, 1.304e19 / ! data cutlo, cuthi / 8.232d-11, 1.304d19 / ! c ! if(n .gt. 0) go to 10 ! dnrm2 = zero ! go to 300 ! c ! 10 assign 30 to next ! sum = zero ! nn = n * incx ! c begin main loop ! i = 1 ! 20 go to next,(30, 50, 70, 110) ! 30 if( dabs(dx(i)) .gt. cutlo) go to 85 ! assign 50 to next ! xmax = zero ! c ! c phase 1. sum is zero ! c ! 50 if( dx(i) .eq. zero) go to 200 ! if( dabs(dx(i)) .gt. cutlo) go to 85 ! c ! c prepare for phase 2. ! assign 70 to next ! go to 105 ! c ! c prepare for phase 4. ! c ! 100 i = j ! assign 110 to next ! sum = (sum / dx(i)) / dx(i) ! 105 xmax = dabs(dx(i)) ! go to 115 ! c ! c phase 2. sum is small. ! c scale to avoid destructive underflow. ! c ! 70 if( dabs(dx(i)) .gt. cutlo ) go to 75 ! c ! c common code for phases 2 and 4. ! c in phase 4 sum is large. scale to avoid overflow. ! c ! 110 if( dabs(dx(i)) .le. xmax ) go to 115 ! sum = one + sum * (xmax / dx(i))**2 ! xmax = dabs(dx(i)) ! go to 200 ! c ! 115 sum = sum + (dx(i)/xmax)**2 ! go to 200 ! c ! c ! c prepare for phase 3. ! c ! 75 sum = (sum * xmax) * xmax ! c ! c ! c for real or d.p. set hitest = cuthi/n ! c for complex set hitest = cuthi/(2*n) ! c ! 85 hitest = cuthi/float( n ) ! c ! c phase 3. sum is mid-range. no scaling. ! c ! do 95 j =i,nn,incx ! if(dabs(dx(j)) .ge. hitest) go to 100 ! 95 sum = sum + dx(j)**2 ! dnrm2 = dsqrt( sum ) ! go to 300 ! c ! 200 continue ! i = i + incx ! if ( i .le. nn ) go to 20 ! c ! c end of main loop. ! c ! c compute square root and adjust for scaling. ! c ! dnrm2 = xmax * dsqrt(sum) ! 300 continue ! return ! end c*********************************************************************** subroutine dcopy(n,dx,incx,dy,incy) c c copies a vector, x, to a vector, y. c uses unrolled loops for increments equal to one. c jack dongarra, linpack, 3/11/78. c double precision dx(1),dy(1) integer i,incx,incy,ix,iy,m,mp1,n c if(n.le.0)return if(incx.eq.1.and.incy.eq.1)go to 20 c c code for unequal increments or equal increments c not equal to 1 c ix = 1 iy = 1 if(incx.lt.0)ix = (-n+1)*incx + 1 if(incy.lt.0)iy = (-n+1)*incy + 1 do 10 i = 1,n dy(iy) = dx(ix) ix = ix + incx iy = iy + incy 10 continue return c c code for both increments equal to 1 c c c clean-up loop c 20 m = mod(n,7) if( m .eq. 0 ) go to 40 do 30 i = 1,m dy(i) = dx(i) 30 continue if( n .lt. 7 ) return 40 mp1 = m + 1 do 50 i = mp1,n,7 dy(i) = dx(i) dy(i + 1) = dx(i + 1) dy(i + 2) = dx(i + 2) dy(i + 3) = dx(i + 3) dy(i + 4) = dx(i + 4) dy(i + 5) = dx(i + 5) dy(i + 6) = dx(i + 6) 50 continue return end