134 lines
3.3 KiB
Fortran
134 lines
3.3 KiB
Fortran
**** Custom extension to random.f
|
|
*** NOTE: IF THE RNG HAS BEEN INITIALIZED BY vranf ANYWHERE
|
|
*** IN THE CODE, IT IS NOT NECESSARY TO REINITIALIZE.
|
|
|
|
|
|
|
|
subroutine granvec(vecs,vdim,nvec,seed)
|
|
implicit none
|
|
! Generates vectors of dimension vdim. Resulting vectors are
|
|
! distributed uniformly for all angles.
|
|
! The vector norm is distributed normally (r>0) and centered at the
|
|
! origin but limited to an interval
|
|
! rmin <= r <= rmax for numerical reasons.
|
|
! rmin and rmax scale with sqrt(vdim) due to the progression of
|
|
! |(1)|, |(1 1)|, |(1 1 1)| ...
|
|
!
|
|
! vdim: dimension of a single vector.
|
|
! nvec: number of vectors to be stored in vecs
|
|
! vecs: random vectors
|
|
! seed: seed for RNG
|
|
|
|
integer vdim,nvec
|
|
double precision vecs(vdim,nvec)
|
|
integer seed
|
|
|
|
double precision rmin,rmax
|
|
double precision norm
|
|
integer iout
|
|
integer j,k
|
|
|
|
parameter (rmin=0.1d0,rmax=1.5,iout=6)
|
|
|
|
! force seed to be negative integer
|
|
seed=-iabs(seed)
|
|
|
|
! initalize RNG
|
|
call gautrg(vecs,0,seed,iout)
|
|
|
|
do j=1,nvec
|
|
norm=-1.0d0
|
|
! sort out too large/small vectors
|
|
do while ((norm.le.rmin).or.(norm.ge.rmax))
|
|
! generate vector
|
|
call gautrg(vecs(1,j),vdim,0,iout)
|
|
! calculate norm
|
|
norm=0.0d0
|
|
do k=1,vdim
|
|
norm=norm+vecs(k,j)**2
|
|
enddo
|
|
norm=dsqrt(norm/vdim)
|
|
enddo
|
|
enddo
|
|
end
|
|
|
|
subroutine nnorm_grv(vecs,vdim,nvec)
|
|
implicit none
|
|
! Generates vector(s) of dimension vdim. Resulting vectors are
|
|
! distributed uniformly for all angles. vranf is assumed
|
|
! to be already initialized.
|
|
!
|
|
! The norm is set to be sqrt(vdim), such that the in case
|
|
! of all vector elements being the same size they would be
|
|
! 'normalized' to 1.
|
|
!
|
|
! vdim: dimension of a single vector.
|
|
! nvec: number of vectors to be stored in vecs
|
|
! vecs: random vectors.
|
|
|
|
integer vdim,nvec
|
|
double precision vecs(vdim,nvec)
|
|
integer seed
|
|
|
|
double precision norm
|
|
|
|
integer j,k
|
|
|
|
! generate vectors
|
|
seed=0
|
|
call granvec(vecs,vdim,nvec,seed)
|
|
|
|
do j=1,nvec
|
|
! calculate norm
|
|
norm=0.0d0
|
|
do k=1,vdim
|
|
norm=norm+vecs(k,j)**2
|
|
enddo
|
|
! renorm vectors to vdim
|
|
norm=dsqrt(vdim/norm)
|
|
do k=1,vdim
|
|
vecs(k,j)=vecs(k,j)*norm
|
|
enddo
|
|
enddo
|
|
|
|
end
|
|
|
|
subroutine normal_grv(vecs,vdim,nvec)
|
|
implicit none
|
|
! Generates vector(s) of dimension vdim. Resulting vectors are
|
|
! distributed uniformly for all angles. vranf is assumed
|
|
! to be already initialized.
|
|
!
|
|
! The norm is set to be 1.
|
|
!
|
|
! vdim: dimension of a single vector.
|
|
! nvec: number of vectors to be stored in vecs
|
|
! vecs: random vectors.
|
|
|
|
integer vdim,nvec
|
|
double precision vecs(vdim,nvec)
|
|
integer seed
|
|
|
|
double precision norm
|
|
|
|
integer j,k
|
|
|
|
! generate vectors
|
|
seed=0
|
|
call granvec(vecs,vdim,nvec,seed)
|
|
|
|
do j=1,nvec
|
|
! calculate norm
|
|
norm=0.0d0
|
|
do k=1,vdim
|
|
norm=norm+vecs(k,j)**2
|
|
enddo
|
|
! renorm vectors to vdim
|
|
norm=dsqrt(1.0d0/norm)
|
|
do k=1,vdim
|
|
vecs(k,j)=vecs(k,j)*norm
|
|
enddo
|
|
enddo
|
|
|
|
end
|