123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- program CMRH
- !***************************************************************
- ! CMRH program
- !
- ! Created by H. Sadok and M. Heyouni -1999
- ! Updated by S. Duminil dec. 2012
- !***************************************************************
- external SSWAP,DCOPY,DSCAL,DGEMV,DSWAP
- intrinsic dabs,dsqrt
- !********************************************
- ! VARIABLES
- !********************************************
- integer ::n,code,i,j,k,choix,solchoice,iprint
- real(kind=8) ::init(5)
- real(kind=8),allocatable,dimension(:,:) ::A
- real(kind=8) ::btemp,bmax,btemp2,err,res
- real(kind=8),allocatable,dimension(:) ::b,sol,rs,temp,x,work,tempn,c,s,temp2,xx,yy,valeurs
- integer,allocatable,dimension(:) ::p
- real*8 ::dnorm2,D_inv,beta,dnorm,dnrm2,tol,alpha,H_k1,dgam,r
- integer ::indice,idamax,k1,n_k
- real dtime, delta, delta0, da(2), dt1, dt2, dt3
- real etime, eelta, eelta0, ea(2), et1, et2, et3
- real t1, t2, t3, tm1, tm2, tm3
- real dtime1, delta1, delta01, da1(2)
- real etime1, eelta1, eelta01, ea1(2),l,p1,p2
- integer nb_ligne
- real ::rand
- da(1)=0.d0
- da(2)=1.d0
- !call itime(timearray) ! Get the current time
- !i = rand ( timearray(1)+timearray(2)+timearray(3) )
- !************************************
- ! Matrix Initialisation
- !************************************
- open(unit=10,file='inputfile.dat',status='old')
- read(10,*)init
- close(10)
- iprint=int(init(1))
- n=int(init(2))
- choix=int(init(3))
- solchoice=int(init(4))
- tol=init(5)
- !call init(iprint,n,choix,solchoice)
- allocate(b(n),rs(n),x(n),A(n,n),work(n),sol(n))
- if (choix<3)then
- call matrice(A,n,n,2.d0,1.d0,choix)
- else
- allocate(valeurs(n))
- open(unit=30,file='matrixfile.dat',status='old')
- do i=1,n
- read(30,*)valeurs
- A(i,:)=valeurs(:)
- enddo
- close(30)
- endif
- !********************************************
- ! End Matrix initialisation
- !********************************************
- !********************************************
- ! Solution initialisation
- !********************************************
- call solution(A,b,sol,n,n,solchoice)
- !********************************************
- ! End solution initialisation
- !********************************************
- !********************************************
- ! Permutation Vector initialisation
- ! and computation of initial residual
- !********************************************
- allocate(p(n))
- do i=1,n
- p(i)=i
- end do
- dnorm2=dnrm2(n,b,1)
- if (iprint==2)then
- print*,''
- print*,'||r0|| =',dnorm2
- print*,''
- end if
- !********************************************
- ! Computation of max b(i)
- !********************************************
- indice = idamax(n,b,1)
- beta = b(indice)
- D_inv = 1.d0/beta
- !********************************************
- ! First permutation
- !********************************************
- if (indice .ne.1) then
- call dswap(1,b(indice),1,b(1),1)
- call dswap(n,A(1,indice),1,A(1,1),1)
- call dswap(n,A(indice,1),n,A(1,1),n)
- call sswap(1,p(indice),1,p(1),1)
- end if
- !********************************************
- ! End permutation
- !********************************************
- ! call dscal(n,0.d0,x,1)
- call dscal(n,D_inv,b,1)
- rs(1)=beta
- dnorm=dabs(beta)
- allocate(c(n),s(n))
- call dscal(n,0.d0,x,1)
- ! Fin initialisation de A
- !print*,'Fin initialisation des matrices'
- k=0
- if (iprint==2)then
- write(*,*)'iter., pseudo-residual norm'
- end if
- !tol=1.d-7
- delta0 = dtime(da)
- eelta0 = etime(ea)
- open(unit=30,file='residual.dat',status='unknown')
- write(30,*)'Iteration, Pseudo-Residual Norm'
- !********************************************
- ! Loop
- !********************************************
- do while((dnorm.gt.tol).and.(k.lt.n))
- k=k+1;
- n_k=n-k;
- k1=k+1;
- if (iprint==2)then
- write(*,10)k-1,dnorm
- end if
- write(30,10)k-1,dnorm
- 10 format(i5,2x,e12.4)
- !********************************************
- ! workl = A*b
- !********************************************
- call dcopy(n,A(1,k),1,work,1)
- call dgemv('N',n,n_k,1.d0,A(1,k1),n,b(k1),1,1.d0,work,1)
- ! ! call dscal(nl,0.d0,workl,1)
- ! ! do j=k1,n
- ! ! do i=1,nl
- ! ! workl(i)=workl(i)+AL(i,j)*b(j)
- ! ! end do
- ! ! end do
- !********************************************
- ! A(:,k)=b
- !********************************************
- call dcopy(n_k,b(k1),1,A(k1,k),1)
- !********************************************
- ! j Loop
- !********************************************
- do j=1,k
- !********************************************
- ! A(j,k)=workl(j)
- ! workl(j)=0
- !********************************************
- A(j,k)=work(j)
- work(j)=0.d0
- alpha=-A(j,k)
- !********************************************
- ! workl=workl - alpha A(:,j)
- !********************************************
- call daxpy(n-j,alpha,A(j+1,j),1,work(j+1),1)
- end do
- !********************************************
- ! End j Loop
- !********************************************
- if (k.lt.n)then
- !********************************************
- ! Search indice i_0
- !********************************************
- indice=k+idamax(n_k,work(k1),1)
- H_k1=work(indice)
- !********************************************
- ! Permutation
- !********************************************
- if (indice.ne.k1) then
- call sswap(1,p(indice),1,p(k1),1)
- call dswap(1,work(indice),1,work(k1),1)
- call dswap(n,A(1,indice),1,A(1,k1),1)
- call dswap(n,A(indice,1),n,A(k1,1),n)
- end if
- !********************************************
- ! End Permutation
- !********************************************
- if (H_k1.ne.0.d0)then
- !********************************************
- ! b=b/(b)_(i_0)
- !********************************************
- D_inv=1.d0/H_k1
- call dcopy(n,work,1,b,1)
- call dscal(n,D_inv,b,1)
- end if
- else
- H_k1=0.d0
- call dscal(n,0.d0,b,1)
- end if
- !********************************************
- ! Application of Givens rotations
- !********************************************
- if (k.gt.1)then
- do i=2,k
- btemp=A(i-1,k)
- A(i-1,k)=c(i-1)*btemp+s(i-1)*A(i,k)
- A(i,k)=-s(i-1)*btemp+c(i-1)*A(i,k)
- end do
- end if
- if (k.le.n)then
- btemp=A(k,k)
- dgam=dsqrt(btemp**2+H_k1**2)
- c(k)=dabs(btemp)/dgam
- s(k)=(H_k1*dabs(btemp))/(btemp*dgam)
- rs(k1)=-s(k)*rs(k)
- rs(k)=c(k)*rs(k)
- dnorm=dabs(rs(k1))
- A(k,k)=c(k)*btemp+s(k)*H_k1
- end if
- !********************************************
- ! End Givens rotations
- !********************************************
- end do
- !********************************************
- ! Solve H_k d_k = alpha e_1
- !********************************************
- call dtrsv('U','N','N',k,A,n,rs,1)
- call dcopy(k,rs,1,work,1)
- call dtrmv('L','N','U',k,A,n,rs,1)
- call dgemv('N',n-k,k,1.d0,A(k1,1),n,work,1,0.d0,c,1)
- call daxpy(k,1.d0,rs,1,x,1)
- call daxpy(n-k,1.d0,c,1,x(k1),1)
- do j=1,n
- b(p(j))=x(j)
- end do
- !!***********************************************
- !!allocate(b(n),rs(n),x(n),A(n,n),work(n),sol(n))
- !if (choix<3)then
- !call matrice(A,n,n,2.d0,1.d0,choix)
- !else
- !allocate(valeurs(n))
- !open(unit=30,file='matrixfile.dat',status='old')
- !do i=1,n
- !read(30,*)valeurs
- !A(i,:)=valeurs(:)
- !enddo
- !close(30)
- !endif
- !!********************************************
- !! End Matrix initialisation
- !!********************************************
- !!********************************************
- !! Solution initialisation
- !!********************************************
- !call solution(A,work,sol,n,n,solchoice)
- !!*********************************************
- !! Residual and Error Norm
- !!*********************************************
- !call dgemv('N',n,n,-1.d0,A(k1,1),n,b,1,1.d0,work,1)
- !dnorm=dnorm2(n,work,1)
- !call dcopy(n,sol,1,rs,1)
- !call daxpy(n,-1.d0,b,1,rs,1)
- !dnorm2=dnorm2(n,rs,1)
- !!***********************************************
- delta = dtime(da)
- eelta = etime(ea)
- dt2 = delta-delta0
- et2 = eelta-eelta0
- t2 = dt2+et2
- tm2 = 0.5*(t2)
- !tm2=0.d0
- if (iprint >= 2) then
- print*,'Results : iter, pseudo-residual norm, time'
- write(*,40)k,dnorm, tm2
- end if
- write(30,20)k,dnorm
- close(30)
- open(unit=100,file='tempsseq.dat',status='unknown',access='append')
- write(unit=100,FMT=*)'Iteration Number :',k,' temps :',tm2
- close(100)
- !20 format(i5,2x,e12.4,e12.4)
- if (iprint==2) then
- write(*,*)
- write(*,*)' Swap, CMRH Solution, Exact Solution : '
- write(*,*)' ______________________________________________ '
- if (n.lt.10)then
- do i=1,n
- write(*,20)p(i), b(i), sol(i)
- end do
- else
- do i=1,10
- write(*,20)p(i), b(i), sol(i)
- end do
- end if
- end if
- 30 format(A37,4(f14.7,1x))
- 20 format(1x,i5,2(1x,f14.8))
- 40 format(1x,i5,2(1x,e12.4))
- deallocate(A,b,sol,work,c,s,rs,x)
- deallocate(p)
- end program CMRH
- !********************************************
- ! End CMRH
- !********************************************
- !********************************************
- ! Matrix Choice
- !********************************************
- subroutine matrice(A,nl,n,alpha,beta,choix)
- integer ::n,i,j,choix,nl
- real(kind=8),dimension(nl,n)::A
- real*8 ::alpha,beta
- if (choix==1) then
- do i = 1, nl
- do j = 1, i
- A(i,j) = (2.d0*dble(j)-1.d0)/dble(n-i+j)
- end do
- do j = i+1, n
- A(i,j) = (2.d0*dble(i)-1.d0)/dble(n-i+j)
- end do
- end do
- end if
- if (choix==2)then
- do i=1,nl
- do j=1,i
- A(i,j)=dble(i)
- end do
- do j=i+1,n
- A(i,j)=dble(j)
- end do
- end do
- end if
- end subroutine matrice
- !********************************************
- ! Solution Choice
- !********************************************
- subroutine solution(A,b,sol,nl,n,solchoice)
- integer ::n,i,nl,solchoice
- real(kind=8),dimension(n,n) ::A
- real(kind=8),dimension(n) ::sol
- real(kind=8),dimension(nl) ::b
- do i=1,n
- if (solchoice==1) then
- sol(i)=1.d0
- end if
- if (solchoice==2) then
- sol(i)=dble(n-i+1)
- end if
- if (solchoice==3)then
- sol(i)=rand(0)
- end if
- end do
- call dgemv('N',nl,n,1.d0,A,nl,sol,1,0.d0,b,1)
- end subroutine solution
- !subroutine init(iprint,n,choix,choixsol)
- !integer :: iprint,n,choix,choixsol
- !print*,'Would you print results ? : 1-No / 2-All / 3-Time and final residual norm'
- !read*,iprint
- !print*,'Enter matrix size : '
- !read*,n
- !print*,'Enter matrix choice : (more details in README.txt) '
- !print*,'1- A(i,j)=2j-1 / n-i+j for j=1,k '
- !print*,' 2i-1 / n-i+j for j=i+1,n '
- !print*,'2- A(i,j)=i for j=1,i '
- !print*,' j for j=i+1,n '
- !print*,'3- Matrix File (copy in matrixfile.dat) '
- !read*,choix
- !print*,'Enter solution choice : 1- [1,...,1]^T / 2- [n,...,1]^T '
- !read*,choixsol
- !endsubroutine init
|