|
| 1 | +* Program to generate a SD version of a given network with an specific |
| 2 | +* Beta and number of dimensions. This program estimates the hidden |
| 3 | +* degrees of each class of degree in order to force the degree |
| 4 | +* distribution. |
| 5 | +* cutoff added |
| 6 | + PROGRAM SD |
| 7 | + IMPLICIT DOUBLE PRECISION (x) |
| 8 | + CHARACTER*300 FILEK,filenet,fileoutk,arg3,arg4,arg5 |
| 9 | + |
| 10 | + INTEGER SEED,D,N,DMAX,Nedgesmax,maxdegree |
| 11 | + INTEGER I,J |
| 12 | + DOUBLE PRECISION B,A,AUX,maxerror,PROB |
| 13 | + DOUBLE PRECISION PI,M,R,TA |
| 14 | + double precision result,c |
| 15 | + double precision ran2 |
| 16 | + |
| 17 | + PARAMETER (N=100000) !Number of nodes |
| 18 | + PARAMETER (Nedgesmax=20000000) !Number of edges |
| 19 | + PARAMETER (DMAX=20) !Similarity space dimension |
| 20 | + PARAMETER (PI=4.D0*DATAN(1.D0)) |
| 21 | + |
| 22 | + INTEGER deg(1:N) !la lista de grado |
| 23 | + INTEGER xd(1:N) !la distribucion de grado |
| 24 | + dimension ndegree(1:N) |
| 25 | + dimension nedge(1:Nedgesmax,1:2) |
| 26 | + dimension npunteroini(1:N) |
| 27 | + dimension npunterofin(1:N) |
| 28 | + dimension xk(1:N) !la kappa de cada clase de degree |
| 29 | + |
| 30 | + dimension xexpk(1:N) !el expected degree de cada clase de degree |
| 31 | + dimension X(1:N,1:DMAX) !Coordenadas de cada nodo |
| 32 | + LOGICAL :: file_exists |
| 33 | + xe=1.0D0 !Precision observed degrees |
| 34 | + CALL get_command_argument(1, FILEK) |
| 35 | + CALL get_command_argument(2, filenet) |
| 36 | + CALL get_command_argument(3, arg3) |
| 37 | + CALL get_command_argument(4, arg4) |
| 38 | + CALL get_command_argument(5, arg5) |
| 39 | + |
| 40 | + |
| 41 | + READ(arg3,*)D |
| 42 | + READ(arg4,*)B |
| 43 | + READ(arg5,*)SEED |
| 44 | + B = dble(B) |
| 45 | + fileoutk = TRIM(FILEK) // "_degrees.dat" |
| 46 | + filenet = TRIM(filenet)//".edge" |
| 47 | + FILEK = TRIM(FILEK)//".edge" |
| 48 | + SEED=-SEED |
| 49 | + write(6,*)"fileoutk" |
| 50 | + write(6,*)fileoutk |
| 51 | + |
| 52 | +********obtaining degree list |
| 53 | + open(1,file=FILEK,status='unknown') |
| 54 | + NODOS=0 |
| 55 | + nlist=0 |
| 56 | + do while(.true.) |
| 57 | + read(1,*,END=10) i,j |
| 58 | + ndegree(i)=ndegree(i)+1 |
| 59 | + ndegree(j)=ndegree(j)+1 |
| 60 | + nlist=nlist+1 |
| 61 | + nedge(nlist,1)=i |
| 62 | + nedge(nlist,2)=j |
| 63 | + if(i.gt.NODOS)then |
| 64 | + NODOS=i |
| 65 | + endif |
| 66 | + if(j.gt.NODOS)then |
| 67 | + NODOS=j |
| 68 | + endif |
| 69 | + enddo |
| 70 | +10 continue |
| 71 | + close(1) |
| 72 | + |
| 73 | +*****writing degrees |
| 74 | + INQUIRE(FILE=fileoutk, EXIST=file_exists) |
| 75 | + if(.NOT.file_exists)then |
| 76 | + open(1,file=fileoutk,status='unknown') |
| 77 | + indexaux=1 |
| 78 | + ndtot=0 |
| 79 | + nodosreal=0 |
| 80 | + xk=0.D0 |
| 81 | + do i=1,NODOS |
| 82 | + if(ndegree(i).gt.0)then |
| 83 | + npunteroini(i)=indexaux |
| 84 | + npunterofin(i)=indexaux-1 |
| 85 | + indexaux=indexaux+ndegree(i) |
| 86 | + ndtot=ndtot+ndegree(i) |
| 87 | + nodosreal=nodosreal+1 |
| 88 | + xk=xk+ndegree(i) |
| 89 | + write(1,*)ndegree(i) |
| 90 | + endif |
| 91 | + enddo |
| 92 | + close(1) |
| 93 | + endif |
| 94 | +*****reading degrees |
| 95 | + |
| 96 | + do i=1,NODOS |
| 97 | + xd(i)=0 |
| 98 | + enddo |
| 99 | + OPEN(UNIT=12,FILE=fileoutk,STATUS="UNKNOWN") |
| 100 | + TA=0.D0 |
| 101 | + NODOS=0 |
| 102 | + maxdegree=1 |
| 103 | + do while(.true.) |
| 104 | + read(12,*,END=20) i |
| 105 | + if(i.gt.maxdegree)then |
| 106 | + maxdegree=i |
| 107 | + endif |
| 108 | + NODOS=NODOS+1 |
| 109 | + xk(NODOS)=NODOS |
| 110 | + xd(i)=xd(i)+1 |
| 111 | + deg(NODOS)=i |
| 112 | + xexpk(NODOS)=0 |
| 113 | + TA=TA+dble(i) |
| 114 | + enddo |
| 115 | +20 continue |
| 116 | + CLOSE(12) |
| 117 | + TA=TA/dble(NODOS) |
| 118 | + WRITE(6,*) "NODES AND AVG K:",NODOS,TA |
| 119 | + WRITE(6,*) "maxdegree:",maxdegree |
| 120 | + |
| 121 | +***************** |
| 122 | + |
| 123 | + write(6,*)NODOS |
| 124 | + write(6,*)"FILEOUT" |
| 125 | + write(6,*)filenet |
| 126 | + |
| 127 | +******assigning coordinates |
| 128 | + DO I=1,NODOS |
| 129 | + DO J=1,D+1 |
| 130 | + X(I,J)=DSQRT(-2.D0*DLOG(DBLE(ran2(SEED))))* |
| 131 | + + DCOS(2.D0*PI*ran2(SEED)) |
| 132 | + ENDDO |
| 133 | + X(I,:)=X(I,:)/DSQRT(SUM(X(I,:)**2)) |
| 134 | + ENDDO |
| 135 | + R=(DBLE(NODOS)*GAMMA((DBLE(D)+1.D0)/2.D0) |
| 136 | + + /(2.D0*PI**((DBLE(D)+1.D0)/2.D0)))**(1.D0/DBLE(D)) |
| 137 | + |
| 138 | + xce=0.D0 |
| 139 | + xsq=0.D0 |
| 140 | + xpe=0.D0 |
| 141 | + |
| 142 | + nodost=0 |
| 143 | + ncont=0 |
| 144 | + A=TA !Initial Avg. degree |
| 145 | + |
| 146 | +30 continue |
| 147 | + DO I=1,maxdegree |
| 148 | + xexpk(I)=0 |
| 149 | + ENDDO |
| 150 | + write(6,*)"Calculating hidden degrees..." |
| 151 | + |
| 152 | + npunteroini=0 |
| 153 | + npunterofin=0 |
| 154 | + ndegree=0 |
| 155 | + |
| 156 | + M=GAMMA(DBLE(D)/2.D0)*B*DSIN(DBLE(D)*PI/B) |
| 157 | + + /(2.D0*PI**(1.D0+DBLE(D)/2.D0)*A) |
| 158 | + |
| 159 | +***************** |
| 160 | + DO I=1,maxdegree |
| 161 | + DO J=I,maxdegree |
| 162 | + !write(6,*)"xk(I),xk(J):",xk(I),xk(J) |
| 163 | + !write(6,*)"xd(I),xd(J):",xd(I),xd(J) |
| 164 | + |
| 165 | + c=R/(((M*xk(I)*xk(J)))**(1/DBLE(D))) |
| 166 | + call pkk(result,D,B,c) |
| 167 | + !write(6,*)"c,pkk:",c,result |
| 168 | + if (I.ne.J)then |
| 169 | + xexpk(I)=xexpk(I)+xd(J)*result |
| 170 | + xexpk(J)=xexpk(J)+xd(I)*result |
| 171 | + else |
| 172 | + xexpk(I)=xexpk(I)+(xd(J)-1)*result |
| 173 | + endif |
| 174 | + ENDDO |
| 175 | + ENDDO |
| 176 | + |
| 177 | + maxerror=0 |
| 178 | + DO I=1,maxdegree |
| 179 | + IF(abs(xexpk(I)-I)>maxerror)then |
| 180 | + maxerror=dabs(xexpk(I)-I) |
| 181 | + ENDIF |
| 182 | + ENDDO |
| 183 | + WRITE(6,*) "maxerror:",maxerror |
| 184 | + IF(maxerror>xe)then |
| 185 | + DO I=1,maxdegree |
| 186 | + xk(I)=abs(xk(I)+(I-xexpk(I))*ran2(SEED)) |
| 187 | + ENDDO |
| 188 | + goto 30 |
| 189 | + ENDIF |
| 190 | + |
| 191 | + |
| 192 | +***************** |
| 193 | + |
| 194 | + AUX=0.D0 |
| 195 | + nlist=0 |
| 196 | + NDS=0 |
| 197 | + |
| 198 | + OPEN(UNIT=10,FILE=filenet,STATUS="UNKNOWN") |
| 199 | + DO I=1,NODOS-1 !connecting the network |
| 200 | + DO J=I+1,NODOS |
| 201 | + !write(6,*)"deg(I),xk(deg(I)):",deg(I),xk(deg(I)) |
| 202 | + PROB=1.D0/(1.D0+(R*DACOS(SUM(X(I,:)*X(J,:))) |
| 203 | + + /(M*xk(deg(I))*xk(deg(J)))**(1.D0/DBLE(D)))**B) |
| 204 | + IF(ran2(SEED).LE.PROB)then |
| 205 | + WRITE(10,*) I,J |
| 206 | + nlist=nlist+1 |
| 207 | + nedge(nlist,1)=i |
| 208 | + nedge(nlist,2)=j |
| 209 | + ndegree(i)=ndegree(i)+1 |
| 210 | + ndegree(j)=ndegree(j)+1 |
| 211 | + if(i.gt.NDS)then |
| 212 | + NDS=i |
| 213 | + endif |
| 214 | + if(j.gt.NDS)then |
| 215 | + NDS=j |
| 216 | + endif |
| 217 | + endif |
| 218 | + AUX=AUX+2.D0*PROB/DBLE(NODOS) |
| 219 | + ENDDO |
| 220 | + ENDDO |
| 221 | + CLOSE(10) |
| 222 | + indexaux=1 |
| 223 | + ndtot=0 |
| 224 | + nodosreal=0 |
| 225 | + do i=1,NDS |
| 226 | + if(ndegree(i).gt.0)then |
| 227 | + npunteroini(i)=indexaux |
| 228 | + npunterofin(i)=indexaux-1 |
| 229 | + indexaux=indexaux+ndegree(i) |
| 230 | + ndtot=ndtot+ndegree(i) |
| 231 | + nodosreal=nodosreal+1 |
| 232 | + endif |
| 233 | + enddo |
| 234 | + END PROGRAM SD |
| 235 | + |
| 236 | + |
| 237 | + |
| 238 | + !call pkk(result,d,beta,c) |
| 239 | + |
| 240 | + subroutine pkk(result,d,beta,c) |
| 241 | + implicit none |
| 242 | + double precision Intnew,pi,a,b,Int0,Int1,error,c,beta |
| 243 | + double precision Intfirst,Intsecond,delta,result |
| 244 | + integer m,d |
| 245 | + delta=1.d-5 |
| 246 | + pi=4.d0*datan(1.d0) |
| 247 | + a=0.d0 |
| 248 | + b=pi |
| 249 | + m=50 |
| 250 | + error=2.d0*delta |
| 251 | + do while(error.gt.delta) |
| 252 | + m=2*m |
| 253 | + |
| 254 | + call trapecis(m,Intnew,a,b,d,c,beta) |
| 255 | + Int0=Intnew |
| 256 | + call trapecis(2*m,Intnew,a,b,d,c,beta) |
| 257 | + Int1=Intnew |
| 258 | + Intfirst=(4.d0*Int1-Int0)/3.d0 |
| 259 | + |
| 260 | + m=2*m |
| 261 | + |
| 262 | + call trapecis(m,Intnew,a,b,d,c,beta) |
| 263 | + Int0=Intnew |
| 264 | + call trapecis(2*m,Intnew,a,b,d,c,beta) |
| 265 | + Int1=Intnew |
| 266 | + Intsecond=(4.d0*Int1-Int0)/3.d0 |
| 267 | + |
| 268 | + error=dabs(Intsecond-Intfirst)/dabs(Intfirst) |
| 269 | + |
| 270 | + enddo |
| 271 | + |
| 272 | + result=Intsecond*dgamma(dble(1+d)/2.d0) |
| 273 | + +/(dsqrt(pi)*dgamma(dble(d)/2.d0)) |
| 274 | + |
| 275 | + return |
| 276 | + end |
| 277 | + |
| 278 | + |
| 279 | + subroutine trapecis(n,Int,a,b,d,c,beta) |
| 280 | + double precision Int,h,x,a,b,func,c,beta |
| 281 | + integer n,i,d |
| 282 | + |
| 283 | + x=a |
| 284 | + Int=func(a,d,c,beta)+func(b,d,c,beta) |
| 285 | + h=(b-a)/dble(n) |
| 286 | + |
| 287 | + do i=1,n-1 |
| 288 | + x=x+h |
| 289 | + Int=Int+2.d0*func(x,d,c,beta) |
| 290 | + enddo |
| 291 | + Int=Int*h/2.d0 |
| 292 | + |
| 293 | + return |
| 294 | + end |
| 295 | + |
| 296 | + |
| 297 | + double precision function func(x,d,c,beta) |
| 298 | + double precision x,c,beta |
| 299 | + integer d |
| 300 | + |
| 301 | + func=(dsin(x))**(d-1)/(1.d0+(c*x)**beta) |
| 302 | + |
| 303 | + |
| 304 | + return |
| 305 | + end |
| 306 | + |
| 307 | + |
| 308 | +******** Uniform Random generator *********************** |
| 309 | + FUNCTION ran2(idum) |
| 310 | + INTEGER idum,IM1,IM2,IMM1,IA1,IA2,IQ1,IQ2,IR1,IR2,NTAB,NDIV |
| 311 | + DOUBLE PRECISION ran2,AM,EPS,RNMX |
| 312 | + PARAMETER (IM1=2147483563,IM2=2147483399,AM=1./IM1,IMM1=IM1-1, |
| 313 | + + IA1=40014,IA2=40692,IQ1=53668,IQ2=52774,IR1=12211, |
| 314 | + + IR2=3791,NTAB=32,NDIV=1+IMM1/NTAB,EPS=1.2e-7,RNMX=1.-EPS) |
| 315 | +!Long period (> 2 x 10 18 ) random number generator of L'Ecuyer with Bays-Durham shuffle |
| 316 | +!and added safeguards. Returns a uniform random deviate between 0.0 and 1.0 (exclusive |
| 317 | +!of the endpoint values). Call with idum a negative integer to initialize; thereafter, do not |
| 318 | +!alter idum between successive deviates in a sequence. RNMX should approximate the largest |
| 319 | +!floating value that is less than 1. |
| 320 | + INTEGER idum2,j,k,iv(NTAB),iy |
| 321 | + SAVE iv,iy,idum2 |
| 322 | + DATA idum2/123456789/, iv/NTAB*0/, iy/0/ |
| 323 | + if (idum.le.0) then !Initialize. |
| 324 | + idum=max(-idum,1) !Be sure to prevent idum = 0. |
| 325 | + idum2=idum |
| 326 | + do j=NTAB+8,1,-1 !Load the shuffle table (after 8 warm-ups). |
| 327 | + k=idum/IQ1 |
| 328 | + idum=IA1*(idum-k*IQ1)-k*IR1 |
| 329 | + if (idum.lt.0) idum=idum+IM1 |
| 330 | + if (j.le.NTAB) iv(j)=idum |
| 331 | + enddo |
| 332 | + iy=iv(1) |
| 333 | + endif |
| 334 | + k=idum/IQ1 !Start here when not initializing. |
| 335 | + idum=IA1*(idum-k*IQ1)-k*IR1 !Compute idum=mod(IA1*idum,IM1) without over- |
| 336 | + if (idum.lt.0) idum=idum+IM1 !flows by Schrage's method. |
| 337 | + k=idum2/IQ2 |
| 338 | + idum2=IA2*(idum2-k*IQ2)-k*IR2 !Compute idum2=mod(IA2*idum2,IM2) likewise. |
| 339 | + if (idum2.lt.0) idum2=idum2+IM2 |
| 340 | + j=1+iy/NDIV !Will be in the range 1:NTAB. |
| 341 | + iy=iv(j)-idum2 !Here idum is shuffled, idum and idum2 are com- |
| 342 | + iv(j)=idum !bined to generate output. |
| 343 | + if(iy.lt.1)iy=iy+IMM1 |
| 344 | + ran2=dmin1(AM*dble(iy),RNMX) !Because users don't expect endpoint values. |
| 345 | + return |
| 346 | + END |
| 347 | +
|
| 348 | +
|
0 commit comments