+++ /dev/null
-c===========================================================================
-c
-c This file is part of TISEAN
-c
-c Copyright (c) 1998-2007 Rainer Hegger, Holger Kantz, Thomas Schreiber
-c
-c TISEAN is free software; you can redistribute it and/or modify
-c it under the terms of the GNU General Public License as published by
-c the Free Software Foundation; either version 2 of the License, or
-c (at your option) any later version.
-c
-c TISEAN is distributed in the hope that it will be useful,
-c but WITHOUT ANY WARRANTY; without even the implied warranty of
-c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-c GNU General Public License for more details.
-c
-c You should have received a copy of the GNU General Public License
-c along with TISEAN; if not, write to the Free Software
-c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-c
-c===========================================================================
-c clustering a dissimilarity matrix
-c see Schreiber and Schmitz, Phys. Rev. Lett. 79 (1997) 1475
-c author T. Schreiber (1998)
-c===========================================================================
-
- parameter(npmax=1000)
- dimension d(npmax,npmax), iu(npmax), ifix(npmax)
- character*72 file, fout, filex
- data iverb/3/
-
- call whatido("clustering a dissimilarity matrix",iverb)
- ncl=imust("#")
- iflag=lopt("=",1)
- call stcan('X',filex,' ')
- isout=igetout(fout,iverb)
-
- call nthstring(1,file)
- call infile(file,iunit,iverb)
- if(file.eq."-") file="stdin"
- if(isout.eq.1) call addsuff(fout,file,"_clust")
- do 10 i=1,npmax
- do 10 j=1,npmax
- 10 d(i,j)=-1e20
- np=0
- 1 read(iunit,*,end=999) i,j,dij
- d(i,j)=dij
- np=max(i,j,np)
- goto 1
- 999 if(iv_io(iverb).eq.1) write(0,'(a,i)') "matrix size ", np
- dmean=0
- nd=0
- do 20 i=1,np
- do 20 j=1,np
- if(d(i,j).ne.-1e20) then
- nd=nd+1
- dmean=dmean+d(i,j)
- endif
- 20 continue
- do 30 i=1,np
- do 30 j=1,np
- 30 if(d(i,j).eq.-1e20) d(i,j)=dmean/nd
- do 40 i=1,np
- 40 ifix(i)=0
- if(filex.ne." ") then
- open(10,file=filex,status='old',err=998)
- nfix=0
- 2 read(10,*,end=998,err=2) i, iff
- if(i.lt.1.or.i.gt.np.or.iff.gt.ncl.or.iff.lt.1) goto 1
- ifix(i)=iff
- nfix=nfix+1
- endif
- 998 if(nfix.eq.np) stop "all fixed."
- call clustering(np,d,npmax,ncl,nfix,ifix,iu,iverb,iflag)
- call outfile(fout,iunit,iverb)
- do 50 n=1,np
- 50 write(iunit,*) iu(n), (costi(np,iu,d,n,ic,iflag),ic=1,ncl)
- end
-
- subroutine usage()
-c usage message
-
- call whatineed("-## [-= -X xfile] file")
- call popt("#","number of clusters")
- call popt("=","if set, bias towards similar size clusters")
- call popt("X","list of indices with fixed cluster assignments")
- call pout("file_clust")
- call pall()
- call ptext("Verbosity levels (add what you want):")
- call ptext(" 1 = input/output" )
- call ptext(" 2 = state of clustering")
- call ptext(" 8 = temperature / cost at cooling")
- stop
- end
-
- subroutine clustering(np,d,npmax,ncl,nfix,ifix,iu,iverb,iflag)
- parameter(nt0=20,tfac=10.,tstep=0.99,ntotmaxf=20,nsuccmaxf=2)
- external rand
- character*1 c
- dimension d(npmax,npmax), iu(*), ifix(*)
- equivalence (c,ic)
- data c/'A'/
-
- ntotmax=(np-nfix)*ntotmaxf
- nsuccmax=(np-nfix)*nsuccmaxf
- se=0.
- se2=0.
- do 10 nt=1,nt0
- call ranconf(np,iu,ncl,ifix)
- e=cost(np,iu,d,ncl,iflag)
- se=se+e
- 10 se2=se2+e**2
- t=tfac*sqrt(se2/nt0-(se/nt0)**2)
-
- ntot=0
- nsucc=0
- 1 call cconf(np,iu,ncl,nch,iuold,ifix)
- ec=cost(np,iu,d,ncl,iflag)
- ntot=ntot+1
- if(ec.lt.e.or.(rand(0.0).lt.exp(-(ec-e)/t))) then
- e=ec
- nsucc=nsucc+1
- else
- iu(nch)=iuold
- endif
- if(ntot.eq.ntotmax .or. nsucc.eq.nsuccmax) then
- if(nsucc.eq.0) return
- ntot=0
- nsucc=0
- if(iv_clust(iverb).eq.1) write(istderr(),'(80a1)')
- . (ic+iu(n)-1,n=1,np)
- if(iv_cool(iverb).eq.1) write(istderr(),*) t, e
- t=t*tstep
- endif
- goto 1
- end
-
- function cost(np,iu,d,ncl,iflag)
- parameter(npmax=1000)
- dimension d(npmax,npmax), iu(*), ictab(npmax)
-
- cost=0
- do 10 ic=1,ncl
- nic=0
- do 20 n=1,np
- if(iu(n).ne.ic) goto 20
- nic=nic+1
- ictab(nic)=n
- 20 continue
- cc=0
- do 30 ii=1,nic
- i=ictab(ii)
- do 30 jj=1,nic
- j=ictab(jj)
- 30 cc=cc+d(i,j)
- 10 if(nic.gt.0) cost=cost+cc/(1+(1-iflag)*(nic-1))
- end
-
- function costi(np,iu,d,nn,ic,iflag)
- parameter(npmax=1000)
- dimension d(npmax,npmax), iu(*), ictab(npmax)
-
- costi=0
- nic=0
- do 20 n=1,np
- if(iu(n).ne.ic) goto 20
- nic=nic+1
- ictab(nic)=n
- 20 continue
- cc=0
- do 30 jj=1,nic
- j=ictab(jj)
- 30 cc=cc+d(nn,j)+d(j,nn)
- if(nic.gt.0) costi=0.5*cc/(1+(1-iflag)*(nic-1))
- end
-
- subroutine ranconf(np,iu,ncl,ifix)
- external rand
- dimension iu(*), ifix(*)
-
- do 10 n=1,np
- iu(n)=ifix(n)
- 10 if(ifix(n).eq.0) iu(n)=min(int(rand(0.0)*ncl)+1,ncl)
- end
-
- subroutine cconf(np,iu,ncl,nch,iuold,ifix)
- external rand
- dimension iu(*), ifix(*)
-
- 1 nch=min(int(rand(0.0)*np)+1,np)
- if(ifix(nch).ne.0) goto 1
- iuold=iu(nch)
- iu(nch)=iuold+int(rand(0.0)*(ncl-1))+1
- if(iu(nch).gt.ncl) iu(nch)=iu(nch)-ncl
- end