CMRH.f90 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. program CMRH
  2. !***************************************************************
  3. ! CMRH program
  4. !
  5. ! Created by H. Sadok and M. Heyouni -1999
  6. ! Updated by S. Duminil dec. 2012
  7. !***************************************************************
  8. external SSWAP,DCOPY,DSCAL,DGEMV,DSWAP
  9. intrinsic dabs,dsqrt
  10. !********************************************
  11. ! VARIABLES
  12. !********************************************
  13. integer ::n,code,i,j,k,choix,solchoice,iprint
  14. real(kind=8) ::init(5)
  15. real(kind=8),allocatable,dimension(:,:) ::A
  16. real(kind=8) ::btemp,bmax,btemp2,err,res
  17. real(kind=8),allocatable,dimension(:) ::b,sol,rs,temp,x,work,tempn,c,s,temp2,xx,yy,valeurs
  18. integer,allocatable,dimension(:) ::p
  19. real*8 ::dnorm2,D_inv,beta,dnorm,dnrm2,tol,alpha,H_k1,dgam,r
  20. integer ::indice,idamax,k1,n_k
  21. real dtime, delta, delta0, da(2), dt1, dt2, dt3
  22. real etime, eelta, eelta0, ea(2), et1, et2, et3
  23. real t1, t2, t3, tm1, tm2, tm3
  24. real dtime1, delta1, delta01, da1(2)
  25. real etime1, eelta1, eelta01, ea1(2),l,p1,p2
  26. integer nb_ligne
  27. real ::rand
  28. da(1)=0.d0
  29. da(2)=1.d0
  30. !call itime(timearray) ! Get the current time
  31. !i = rand ( timearray(1)+timearray(2)+timearray(3) )
  32. !************************************
  33. ! Matrix Initialisation
  34. !************************************
  35. open(unit=10,file='inputfile.dat',status='old')
  36. read(10,*)init
  37. close(10)
  38. iprint=int(init(1))
  39. n=int(init(2))
  40. choix=int(init(3))
  41. solchoice=int(init(4))
  42. tol=init(5)
  43. !call init(iprint,n,choix,solchoice)
  44. allocate(b(n),rs(n),x(n),A(n,n),work(n),sol(n))
  45. if (choix<3)then
  46. call matrice(A,n,n,2.d0,1.d0,choix)
  47. else
  48. allocate(valeurs(n))
  49. open(unit=30,file='matrixfile.dat',status='old')
  50. do i=1,n
  51. read(30,*)valeurs
  52. A(i,:)=valeurs(:)
  53. enddo
  54. close(30)
  55. endif
  56. !********************************************
  57. ! End Matrix initialisation
  58. !********************************************
  59. !********************************************
  60. ! Solution initialisation
  61. !********************************************
  62. call solution(A,b,sol,n,n,solchoice)
  63. !********************************************
  64. ! End solution initialisation
  65. !********************************************
  66. !********************************************
  67. ! Permutation Vector initialisation
  68. ! and computation of initial residual
  69. !********************************************
  70. allocate(p(n))
  71. do i=1,n
  72. p(i)=i
  73. end do
  74. dnorm2=dnrm2(n,b,1)
  75. if (iprint==2)then
  76. print*,''
  77. print*,'||r0|| =',dnorm2
  78. print*,''
  79. end if
  80. !********************************************
  81. ! Computation of max b(i)
  82. !********************************************
  83. indice = idamax(n,b,1)
  84. beta = b(indice)
  85. D_inv = 1.d0/beta
  86. !********************************************
  87. ! First permutation
  88. !********************************************
  89. if (indice .ne.1) then
  90. call dswap(1,b(indice),1,b(1),1)
  91. call dswap(n,A(1,indice),1,A(1,1),1)
  92. call dswap(n,A(indice,1),n,A(1,1),n)
  93. call sswap(1,p(indice),1,p(1),1)
  94. end if
  95. !********************************************
  96. ! End permutation
  97. !********************************************
  98. ! call dscal(n,0.d0,x,1)
  99. call dscal(n,D_inv,b,1)
  100. rs(1)=beta
  101. dnorm=dabs(beta)
  102. allocate(c(n),s(n))
  103. call dscal(n,0.d0,x,1)
  104. ! Fin initialisation de A
  105. !print*,'Fin initialisation des matrices'
  106. k=0
  107. if (iprint==2)then
  108. write(*,*)'iter., pseudo-residual norm'
  109. end if
  110. !tol=1.d-7
  111. delta0 = dtime(da)
  112. eelta0 = etime(ea)
  113. open(unit=30,file='residual.dat',status='unknown')
  114. write(30,*)'Iteration, Pseudo-Residual Norm'
  115. !********************************************
  116. ! Loop
  117. !********************************************
  118. do while((dnorm.gt.tol).and.(k.lt.n))
  119. k=k+1;
  120. n_k=n-k;
  121. k1=k+1;
  122. if (iprint==2)then
  123. write(*,10)k-1,dnorm
  124. end if
  125. write(30,10)k-1,dnorm
  126. 10 format(i5,2x,e12.4)
  127. !********************************************
  128. ! workl = A*b
  129. !********************************************
  130. call dcopy(n,A(1,k),1,work,1)
  131. call dgemv('N',n,n_k,1.d0,A(1,k1),n,b(k1),1,1.d0,work,1)
  132. ! ! call dscal(nl,0.d0,workl,1)
  133. ! ! do j=k1,n
  134. ! ! do i=1,nl
  135. ! ! workl(i)=workl(i)+AL(i,j)*b(j)
  136. ! ! end do
  137. ! ! end do
  138. !********************************************
  139. ! A(:,k)=b
  140. !********************************************
  141. call dcopy(n_k,b(k1),1,A(k1,k),1)
  142. !********************************************
  143. ! j Loop
  144. !********************************************
  145. do j=1,k
  146. !********************************************
  147. ! A(j,k)=workl(j)
  148. ! workl(j)=0
  149. !********************************************
  150. A(j,k)=work(j)
  151. work(j)=0.d0
  152. alpha=-A(j,k)
  153. !********************************************
  154. ! workl=workl - alpha A(:,j)
  155. !********************************************
  156. call daxpy(n-j,alpha,A(j+1,j),1,work(j+1),1)
  157. end do
  158. !********************************************
  159. ! End j Loop
  160. !********************************************
  161. if (k.lt.n)then
  162. !********************************************
  163. ! Search indice i_0
  164. !********************************************
  165. indice=k+idamax(n_k,work(k1),1)
  166. H_k1=work(indice)
  167. !********************************************
  168. ! Permutation
  169. !********************************************
  170. if (indice.ne.k1) then
  171. call sswap(1,p(indice),1,p(k1),1)
  172. call dswap(1,work(indice),1,work(k1),1)
  173. call dswap(n,A(1,indice),1,A(1,k1),1)
  174. call dswap(n,A(indice,1),n,A(k1,1),n)
  175. end if
  176. !********************************************
  177. ! End Permutation
  178. !********************************************
  179. if (H_k1.ne.0.d0)then
  180. !********************************************
  181. ! b=b/(b)_(i_0)
  182. !********************************************
  183. D_inv=1.d0/H_k1
  184. call dcopy(n,work,1,b,1)
  185. call dscal(n,D_inv,b,1)
  186. end if
  187. else
  188. H_k1=0.d0
  189. call dscal(n,0.d0,b,1)
  190. end if
  191. !********************************************
  192. ! Application of Givens rotations
  193. !********************************************
  194. if (k.gt.1)then
  195. do i=2,k
  196. btemp=A(i-1,k)
  197. A(i-1,k)=c(i-1)*btemp+s(i-1)*A(i,k)
  198. A(i,k)=-s(i-1)*btemp+c(i-1)*A(i,k)
  199. end do
  200. end if
  201. if (k.le.n)then
  202. btemp=A(k,k)
  203. dgam=dsqrt(btemp**2+H_k1**2)
  204. c(k)=dabs(btemp)/dgam
  205. s(k)=(H_k1*dabs(btemp))/(btemp*dgam)
  206. rs(k1)=-s(k)*rs(k)
  207. rs(k)=c(k)*rs(k)
  208. dnorm=dabs(rs(k1))
  209. A(k,k)=c(k)*btemp+s(k)*H_k1
  210. end if
  211. !********************************************
  212. ! End Givens rotations
  213. !********************************************
  214. end do
  215. !********************************************
  216. ! Solve H_k d_k = alpha e_1
  217. !********************************************
  218. call dtrsv('U','N','N',k,A,n,rs,1)
  219. call dcopy(k,rs,1,work,1)
  220. call dtrmv('L','N','U',k,A,n,rs,1)
  221. call dgemv('N',n-k,k,1.d0,A(k1,1),n,work,1,0.d0,c,1)
  222. call daxpy(k,1.d0,rs,1,x,1)
  223. call daxpy(n-k,1.d0,c,1,x(k1),1)
  224. do j=1,n
  225. b(p(j))=x(j)
  226. end do
  227. !!***********************************************
  228. !!allocate(b(n),rs(n),x(n),A(n,n),work(n),sol(n))
  229. !if (choix<3)then
  230. !call matrice(A,n,n,2.d0,1.d0,choix)
  231. !else
  232. !allocate(valeurs(n))
  233. !open(unit=30,file='matrixfile.dat',status='old')
  234. !do i=1,n
  235. !read(30,*)valeurs
  236. !A(i,:)=valeurs(:)
  237. !enddo
  238. !close(30)
  239. !endif
  240. !!********************************************
  241. !! End Matrix initialisation
  242. !!********************************************
  243. !!********************************************
  244. !! Solution initialisation
  245. !!********************************************
  246. !call solution(A,work,sol,n,n,solchoice)
  247. !!*********************************************
  248. !! Residual and Error Norm
  249. !!*********************************************
  250. !call dgemv('N',n,n,-1.d0,A(k1,1),n,b,1,1.d0,work,1)
  251. !dnorm=dnorm2(n,work,1)
  252. !call dcopy(n,sol,1,rs,1)
  253. !call daxpy(n,-1.d0,b,1,rs,1)
  254. !dnorm2=dnorm2(n,rs,1)
  255. !!***********************************************
  256. delta = dtime(da)
  257. eelta = etime(ea)
  258. dt2 = delta-delta0
  259. et2 = eelta-eelta0
  260. t2 = dt2+et2
  261. tm2 = 0.5*(t2)
  262. !tm2=0.d0
  263. if (iprint >= 2) then
  264. print*,'Results : iter, pseudo-residual norm, time'
  265. write(*,40)k,dnorm, tm2
  266. end if
  267. write(30,20)k,dnorm
  268. close(30)
  269. open(unit=100,file='tempsseq.dat',status='unknown',access='append')
  270. write(unit=100,FMT=*)'Iteration Number :',k,' temps :',tm2
  271. close(100)
  272. !20 format(i5,2x,e12.4,e12.4)
  273. if (iprint==2) then
  274. write(*,*)
  275. write(*,*)' Swap, CMRH Solution, Exact Solution : '
  276. write(*,*)' ______________________________________________ '
  277. if (n.lt.10)then
  278. do i=1,n
  279. write(*,20)p(i), b(i), sol(i)
  280. end do
  281. else
  282. do i=1,10
  283. write(*,20)p(i), b(i), sol(i)
  284. end do
  285. end if
  286. end if
  287. 30 format(A37,4(f14.7,1x))
  288. 20 format(1x,i5,2(1x,f14.8))
  289. 40 format(1x,i5,2(1x,e12.4))
  290. deallocate(A,b,sol,work,c,s,rs,x)
  291. deallocate(p)
  292. end program CMRH
  293. !********************************************
  294. ! End CMRH
  295. !********************************************
  296. !********************************************
  297. ! Matrix Choice
  298. !********************************************
  299. subroutine matrice(A,nl,n,alpha,beta,choix)
  300. integer ::n,i,j,choix,nl
  301. real(kind=8),dimension(nl,n)::A
  302. real*8 ::alpha,beta
  303. if (choix==1) then
  304. do i = 1, nl
  305. do j = 1, i
  306. A(i,j) = (2.d0*dble(j)-1.d0)/dble(n-i+j)
  307. end do
  308. do j = i+1, n
  309. A(i,j) = (2.d0*dble(i)-1.d0)/dble(n-i+j)
  310. end do
  311. end do
  312. end if
  313. if (choix==2)then
  314. do i=1,nl
  315. do j=1,i
  316. A(i,j)=dble(i)
  317. end do
  318. do j=i+1,n
  319. A(i,j)=dble(j)
  320. end do
  321. end do
  322. end if
  323. end subroutine matrice
  324. !********************************************
  325. ! Solution Choice
  326. !********************************************
  327. subroutine solution(A,b,sol,nl,n,solchoice)
  328. integer ::n,i,nl,solchoice
  329. real(kind=8),dimension(n,n) ::A
  330. real(kind=8),dimension(n) ::sol
  331. real(kind=8),dimension(nl) ::b
  332. do i=1,n
  333. if (solchoice==1) then
  334. sol(i)=1.d0
  335. end if
  336. if (solchoice==2) then
  337. sol(i)=dble(n-i+1)
  338. end if
  339. if (solchoice==3)then
  340. sol(i)=rand(0)
  341. end if
  342. end do
  343. call dgemv('N',nl,n,1.d0,A,nl,sol,1,0.d0,b,1)
  344. end subroutine solution
  345. !subroutine init(iprint,n,choix,choixsol)
  346. !integer :: iprint,n,choix,choixsol
  347. !print*,'Would you print results ? : 1-No / 2-All / 3-Time and final residual norm'
  348. !read*,iprint
  349. !print*,'Enter matrix size : '
  350. !read*,n
  351. !print*,'Enter matrix choice : (more details in README.txt) '
  352. !print*,'1- A(i,j)=2j-1 / n-i+j for j=1,k '
  353. !print*,' 2i-1 / n-i+j for j=i+1,n '
  354. !print*,'2- A(i,j)=i for j=1,i '
  355. !print*,' j for j=i+1,n '
  356. !print*,'3- Matrix File (copy in matrixfile.dat) '
  357. !read*,choix
  358. !print*,'Enter solution choice : 1- [1,...,1]^T / 2- [n,...,1]^T '
  359. !read*,choixsol
  360. !endsubroutine init