-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathrnd.f90
145 lines (135 loc) · 3.84 KB
/
rnd.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
module rnd_lib
implicit none
interface random
module procedure d1rnd,z1rnd,d2rnd,z2rnd,d3rnd,z3rnd
end interface
contains
subroutine arnd()
implicit none
integer s,clock,crate,cmax
integer,allocatable :: seed(:)
call random_seed(size=s)
allocate(seed(s))
call random_seed(get=seed)
write(*,*) 'oldseed: ',seed
call system_clock(clock,crate,cmax)
!write(*,*)clock,crate,cmax
seed(1)=clock
call random_seed(put=seed)
write(*,*) 'newseed: ',seed
end subroutine
double precision function drnd( )
implicit none
call random_number(drnd)
return
end function
subroutine d1rnd(d)
double precision,intent(out) :: d(:)
call random_number(d)
end subroutine
subroutine z1rnd(z)
implicit none
double complex,intent(inout) :: z(:)
character(len=*),parameter :: subnam='z1rnd'
double precision,allocatable :: d(:)
integer :: n,info
n=size(z)
allocate(d(2*n),stat=info)
if(info.ne.0)then;write(*,*)subnam,': cannot allocate';stop;endif
call random_number(d)
call dcopy(2*n,d,1,z,1)
deallocate(d)
end subroutine
subroutine d2rnd(d)
double precision,intent(out) :: d(:,:)
call random_number(d)
end subroutine
subroutine z2rnd(z)
implicit none
double complex,intent(inout) :: z(:,:)
character(len=*),parameter :: subnam='z2rnd'
double precision,allocatable :: d(:)
integer :: n,info
n=size(z)
allocate(d(2*n),stat=info)
if(info.ne.0)then;write(*,*)subnam,': cannot allocate';stop;endif
call random_number(d)
call dcopy(2*n,d,1,z,1)
deallocate(d)
end subroutine
subroutine d3rnd(d)
double precision,intent(out) :: d(:,:,:)
call random_number(d)
end subroutine
subroutine z3rnd(z)
implicit none
double complex,intent(inout) :: z(:,:,:)
character(len=*),parameter :: subnam='z3rnd'
double precision,allocatable :: d(:)
integer :: n,info
n=size(z)
allocate(d(2*n),stat=info)
if(info.ne.0)then;write(*,*)subnam,': cannot allocate';stop;endif
call random_number(d)
call dcopy(2*n,d,1,z,1)
deallocate(d)
end subroutine
integer function irnd( maxi )
integer,intent(in) :: maxi
double precision :: d
call random_number(d)
irnd=int(d*maxi)+1
return
end function
subroutine irand(maxi,ix)
integer,intent(in) :: maxi
integer,intent(out) :: ix(:)
integer :: i,n
double precision,allocatable :: d(:)
n=size(ix)
allocate(d(n))
call random_number(d)
ix=int(d*maxi)+1
deallocate(d)
return
end subroutine
subroutine lottery2(npnt,m,n,wcol,wrow,points)
implicit none
integer,intent(in) :: npnt,m,n
double precision,intent(in) :: wcol(m),wrow(n)
integer,intent(out) :: points(npnt,2)
character(len=*),parameter :: subnam='lottery2'
double precision,allocatable :: pcol(:),prow(:),d(:,:)
double precision :: scol,srow
integer :: ipnt,i,j,info
double precision,external :: dasum
allocate(pcol(0:m),prow(0:n),d(npnt,2),stat=info)
if(info.ne.0)then;write(*,*)subnam,': cannot allocate';stop;endif
scol=dasum(m,wcol,1); srow=dasum(n,wrow,1)
pcol(0)=0.d0; do i=1,m;pcol(i)=pcol(i-1)+dabs(wcol(i))/scol;enddo
prow(0)=0.d0; do j=1,n;prow(j)=prow(j-1)+dabs(wrow(j))/srow;enddo
call random_number(d)
do ipnt=1,npnt
points(ipnt,1)=find_d(m+1,pcol,d(ipnt,1)); if(points(ipnt,1).gt.m)points(ipnt,1)=m
points(ipnt,2)=find_d(n+1,prow,d(ipnt,2)); if(points(ipnt,2).gt.n)points(ipnt,2)=n
end do
deallocate(pcol,prow,d)
end subroutine
pure integer function find_d(n,x,y) result (pos)
! for sorted vector x(1) <= x(2) <= ... <= x(n) and value y find pos, s.t. x(pos) <= y < x(pos+1)
implicit none
integer,intent(in) :: n
double precision,intent(in) :: x(n),y
integer :: s,t,i
logical :: key
if(n.eq.0)then;pos=0;return;endif
if(y.lt.x(1))then;pos=0;return;endif
if(x(n).le.y)then;pos=n;return;endif
s=1;t=n;pos=(t+s)/2
do while(t-s.gt.1)
if(y.lt.x(pos))then;t=pos;else;s=pos;end if
pos=(s+t)/2
enddo
return
end function
end module