Commit 6ac82e990ee0ab81340d03178f3bd7aec3d7de43

Authored by daniau
1 parent 06ed2f4ac7

git-svn-id: https://lxsd.femto-st.fr/svn/fvn@9 b657c933-2333-4658-acf2-d3c7c2708721

Showing 1 changed file with 0 additions and 1779 deletions Side-by-side Diff

stable/fvnlib.f90
Diff suppressed. Click to show
1   -
2   -module fvn
3   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4   -!
5   -! fvn : a f95 module replacement for some imsl routines
6   -! it uses lapack for linear algebra
7   -! it uses modified quadpack for integration
8   -!
9   -! William Daniau 2007
10   -! william.daniau@femto-st.fr
11   -!
12   -! Routines naming scheme :
13   -!
14   -! fvn_x_name
15   -! where x can be s : real
16   -! d : real double precision
17   -! c : complex
18   -! z : double complex
19   -!
20   -!
21   -! This piece of code is totally free! Do whatever you want with it. However
22   -! if you find it usefull it would be kind to give credits ;-) Nevertheless, you
23   -! may give credits to quadpack authors.
24   -!
25   -! Version 1.1
26   -!
27   -! TO DO LIST :
28   -! + Order eigenvalues and vectors in decreasing eigenvalue's modulus order -> atm
29   -! eigenvalues are given with no particular order.
30   -! + Generic interface for fvn_x_name family -> fvn_name
31   -! + Make some parameters optional, status for example
32   -! + use f95 kinds "double complex" -> complex(kind=8)
33   -! + unify quadpack routines
34   -! + ...
35   -!
36   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
37   -
38   -implicit none
39   -! All quadpack routines are private to the module
40   -private :: d1mach,dqag,dqag_2d_inner,dqag_2d_outer,dqage,dqage_2d_inner, &
41   - dqage_2d_outer,dqk15,dqk15_2d_inner,dqk15_2d_outer,dqk21,dqk21_2d_inner,dqk21_2d_outer, &
42   - dqk31,dqk31_2d_inner,dqk31_2d_outer,dqk41,dqk41_2d_inner,dqk41_2d_outer, &
43   - dqk51,dqk51_2d_inner,dqk51_2d_outer,dqk61,dqk61_2d_inner,dqk61_2d_outer,dqpsrt
44   -
45   -
46   -contains
47   -
48   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
49   -!
50   -! Matrix inversion subroutines
51   -!
52   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
53   -subroutine fvn_s_matinv(d,a,inva,status)
54   - !
55   - ! Matrix inversion of a real matrix using BLAS and LAPACK
56   - !
57   - ! d (in) : matrix rank
58   - ! a (in) : input matrix
59   - ! inva (out) : inversed matrix
60   - ! status (ou) : =0 if something failed
61   - !
62   - integer, intent(in) :: d
63   - real, intent(in) :: a(d,d)
64   - real, intent(out) :: inva(d,d)
65   - integer, intent(out) :: status
66   -
67   - integer, allocatable :: ipiv(:)
68   - real, allocatable :: work(:)
69   - real twork(1)
70   - integer :: info
71   - integer :: lwork
72   -
73   - status=1
74   -
75   - allocate(ipiv(d))
76   - ! copy a into inva using BLAS
77   - !call scopy(d*d,a,1,inva,1)
78   - inva(:,:)=a(:,:)
79   - ! LU factorization using LAPACK
80   - call sgetrf(d,d,inva,d,ipiv,info)
81   - ! if info is not equal to 0, something went wrong we exit setting status to 0
82   - if (info /= 0) then
83   - status=0
84   - deallocate(ipiv)
85   - return
86   - end if
87   - ! we use the query fonction of xxxtri to obtain the optimal workspace size
88   - call sgetri(d,inva,d,ipiv,twork,-1,info)
89   - lwork=int(twork(1))
90   - allocate(work(lwork))
91   - ! Matrix inversion using LAPACK
92   - call sgetri(d,inva,d,ipiv,work,lwork,info)
93   - ! again if info is not equal to 0, we exit setting status to 0
94   - if (info /= 0) then
95   - status=0
96   - end if
97   - deallocate(work)
98   - deallocate(ipiv)
99   -end subroutine
100   -
101   -subroutine fvn_d_matinv(d,a,inva,status)
102   - !
103   - ! Matrix inversion of a double precision matrix using BLAS and LAPACK
104   - !
105   - ! d (in) : matrix rank
106   - ! a (in) : input matrix
107   - ! inva (out) : inversed matrix
108   - ! status (ou) : =0 if something failed
109   - !
110   - integer, intent(in) :: d
111   - double precision, intent(in) :: a(d,d)
112   - double precision, intent(out) :: inva(d,d)
113   - integer, intent(out) :: status
114   -
115   - integer, allocatable :: ipiv(:)
116   - double precision, allocatable :: work(:)
117   - double precision :: twork(1)
118   - integer :: info
119   - integer :: lwork
120   -
121   - status=1
122   -
123   - allocate(ipiv(d))
124   - ! copy a into inva using BLAS
125   - !call dcopy(d*d,a,1,inva,1)
126   - inva(:,:)=a(:,:)
127   - ! LU factorization using LAPACK
128   - call dgetrf(d,d,inva,d,ipiv,info)
129   - ! if info is not equal to 0, something went wrong we exit setting status to 0
130   - if (info /= 0) then
131   - status=0
132   - deallocate(ipiv)
133   - return
134   - end if
135   - ! we use the query fonction of xxxtri to obtain the optimal workspace size
136   - call dgetri(d,inva,d,ipiv,twork,-1,info)
137   - lwork=int(twork(1))
138   - allocate(work(lwork))
139   - ! Matrix inversion using LAPACK
140   - call dgetri(d,inva,d,ipiv,work,lwork,info)
141   - ! again if info is not equal to 0, we exit setting status to 0
142   - if (info /= 0) then
143   - status=0
144   - end if
145   - deallocate(work)
146   - deallocate(ipiv)
147   -end subroutine
148   -
149   -subroutine fvn_c_matinv(d,a,inva,status)
150   - !
151   - ! Matrix inversion of a complex matrix using BLAS and LAPACK
152   - !
153   - ! d (in) : matrix rank
154   - ! a (in) : input matrix
155   - ! inva (out) : inversed matrix
156   - ! status (ou) : =0 if something failed
157   - !
158   - integer, intent(in) :: d
159   - complex, intent(in) :: a(d,d)
160   - complex, intent(out) :: inva(d,d)
161   - integer, intent(out) :: status
162   -
163   - integer, allocatable :: ipiv(:)
164   - complex, allocatable :: work(:)
165   - complex :: twork(1)
166   - integer :: info
167   - integer :: lwork
168   -
169   - status=1
170   -
171   - allocate(ipiv(d))
172   - ! copy a into inva using BLAS
173   - !call ccopy(d*d,a,1,inva,1)
174   - inva(:,:)=a(:,:)
175   -
176   - ! LU factorization using LAPACK
177   - call cgetrf(d,d,inva,d,ipiv,info)
178   - ! if info is not equal to 0, something went wrong we exit setting status to 0
179   - if (info /= 0) then
180   - status=0
181   - deallocate(ipiv)
182   - return
183   - end if
184   - ! we use the query fonction of xxxtri to obtain the optimal workspace size
185   - call cgetri(d,inva,d,ipiv,twork,-1,info)
186   - lwork=int(twork(1))
187   - allocate(work(lwork))
188   - ! Matrix inversion using LAPACK
189   - call cgetri(d,inva,d,ipiv,work,lwork,info)
190   - ! again if info is not equal to 0, we exit setting status to 0
191   - if (info /= 0) then
192   - status=0
193   - end if
194   - deallocate(work)
195   - deallocate(ipiv)
196   -end subroutine
197   -
198   -subroutine fvn_z_matinv(d,a,inva,status)
199   - !
200   - ! Matrix inversion of a double complex matrix using BLAS and LAPACK
201   - !
202   - ! d (in) : matrix rank
203   - ! a (in) : input matrix
204   - ! inva (out) : inversed matrix
205   - ! status (ou) : =0 if something failed
206   - !
207   - integer, intent(in) :: d
208   - double complex, intent(in) :: a(d,d)
209   - double complex, intent(out) :: inva(d,d)
210   - integer, intent(out) :: status
211   -
212   - integer, allocatable :: ipiv(:)
213   - double complex, allocatable :: work(:)
214   - double complex :: twork(1)
215   - integer :: info
216   - integer :: lwork
217   -
218   - status=1
219   -
220   - allocate(ipiv(d))
221   - ! copy a into inva using BLAS
222   - !call zcopy(d*d,a,1,inva,1)
223   - inva(:,:)=a(:,:)
224   -
225   - ! LU factorization using LAPACK
226   - call zgetrf(d,d,inva,d,ipiv,info)
227   - ! if info is not equal to 0, something went wrong we exit setting status to 0
228   - if (info /= 0) then
229   - status=0
230   - deallocate(ipiv)
231   - return
232   - end if
233   - ! we use the query fonction of xxxtri to obtain the optimal workspace size
234   - call zgetri(d,inva,d,ipiv,twork,-1,info)
235   - lwork=int(twork(1))
236   - allocate(work(lwork))
237   - ! Matrix inversion using LAPACK
238   - call zgetri(d,inva,d,ipiv,work,lwork,info)
239   - ! again if info is not equal to 0, we exit setting status to 0
240   - if (info /= 0) then
241   - status=0
242   - end if
243   - deallocate(work)
244   - deallocate(ipiv)
245   -end subroutine
246   -
247   -
248   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
249   -!
250   -! Determinants
251   -!
252   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
253   -function fvn_s_det(d,a,status)
254   - !
255   - ! Evaluate the determinant of a square matrix using lapack LU factorization
256   - !
257   - ! d (in) : matrix rank
258   - ! a (in) : The Matrix
259   - ! status (out) : =0 if LU factorization failed
260   - !
261   - integer, intent(in) :: d
262   - real, intent(in) :: a(d,d)
263   - integer, intent(out) :: status
264   - real :: fvn_s_det
265   -
266   - real, allocatable :: wc_a(:,:)
267   - integer, allocatable :: ipiv(:)
268   - integer :: info,i
269   -
270   - status=1
271   - allocate(wc_a(d,d))
272   - allocate(ipiv(d))
273   - wc_a(:,:)=a(:,:)
274   - call sgetrf(d,d,wc_a,d,ipiv,info)
275   - if (info/= 0) then
276   - status=0
277   - fvn_s_det=0.e0
278   - deallocate(ipiv)
279   - deallocate(wc_a)
280   - return
281   - end if
282   - fvn_s_det=1.e0
283   - do i=1,d
284   - if (ipiv(i)==i) then
285   - fvn_s_det=fvn_s_det*wc_a(i,i)
286   - else
287   - fvn_s_det=-fvn_s_det*wc_a(i,i)
288   - end if
289   - end do
290   - deallocate(ipiv)
291   - deallocate(wc_a)
292   -
293   -end function
294   -
295   -function fvn_d_det(d,a,status)
296   - !
297   - ! Evaluate the determinant of a square matrix using lapack LU factorization
298   - !
299   - ! d (in) : matrix rank
300   - ! a (in) : The Matrix
301   - ! status (out) : =0 if LU factorization failed
302   - !
303   - integer, intent(in) :: d
304   - double precision, intent(in) :: a(d,d)
305   - integer, intent(out) :: status
306   - double precision :: fvn_d_det
307   -
308   - double precision, allocatable :: wc_a(:,:)
309   - integer, allocatable :: ipiv(:)
310   - integer :: info,i
311   -
312   - status=1
313   - allocate(wc_a(d,d))
314   - allocate(ipiv(d))
315   - wc_a(:,:)=a(:,:)
316   - call dgetrf(d,d,wc_a,d,ipiv,info)
317   - if (info/= 0) then
318   - status=0
319   - fvn_d_det=0.d0
320   - deallocate(ipiv)
321   - deallocate(wc_a)
322   - return
323   - end if
324   - fvn_d_det=1.d0
325   - do i=1,d
326   - if (ipiv(i)==i) then
327   - fvn_d_det=fvn_d_det*wc_a(i,i)
328   - else
329   - fvn_d_det=-fvn_d_det*wc_a(i,i)
330   - end if
331   - end do
332   - deallocate(ipiv)
333   - deallocate(wc_a)
334   -
335   -end function
336   -
337   -function fvn_c_det(d,a,status) !
338   - ! Evaluate the determinant of a square matrix using lapack LU factorization
339   - !
340   - ! d (in) : matrix rank
341   - ! a (in) : The Matrix
342   - ! status (out) : =0 if LU factorization failed
343   - !
344   - integer, intent(in) :: d
345   - complex, intent(in) :: a(d,d)
346   - integer, intent(out) :: status
347   - complex :: fvn_c_det
348   -
349   - complex, allocatable :: wc_a(:,:)
350   - integer, allocatable :: ipiv(:)
351   - integer :: info,i
352   -
353   - status=1
354   - allocate(wc_a(d,d))
355   - allocate(ipiv(d))
356   - wc_a(:,:)=a(:,:)
357   - call cgetrf(d,d,wc_a,d,ipiv,info)
358   - if (info/= 0) then
359   - status=0
360   - fvn_c_det=(0.e0,0.e0)
361   - deallocate(ipiv)
362   - deallocate(wc_a)
363   - return
364   - end if
365   - fvn_c_det=(1.e0,0.e0)
366   - do i=1,d
367   - if (ipiv(i)==i) then
368   - fvn_c_det=fvn_c_det*wc_a(i,i)
369   - else
370   - fvn_c_det=-fvn_c_det*wc_a(i,i)
371   - end if
372   - end do
373   - deallocate(ipiv)
374   - deallocate(wc_a)
375   -
376   -end function
377   -
378   -function fvn_z_det(d,a,status)
379   - !
380   - ! Evaluate the determinant of a square matrix using lapack LU factorization
381   - !
382   - ! d (in) : matrix rank
383   - ! a (in) : The Matrix
384   - ! det (out) : determinant
385   - ! status (out) : =0 if LU factorization failed
386   - !
387   - integer, intent(in) :: d
388   - double complex, intent(in) :: a(d,d)
389   - integer, intent(out) :: status
390   - double complex :: fvn_z_det
391   -
392   - double complex, allocatable :: wc_a(:,:)
393   - integer, allocatable :: ipiv(:)
394   - integer :: info,i
395   -
396   - status=1
397   - allocate(wc_a(d,d))
398   - allocate(ipiv(d))
399   - wc_a(:,:)=a(:,:)
400   - call zgetrf(d,d,wc_a,d,ipiv,info)
401   - if (info/= 0) then
402   - status=0
403   - fvn_z_det=(0.d0,0.d0)
404   - deallocate(ipiv)
405   - deallocate(wc_a)
406   - return
407   - end if
408   - fvn_z_det=(1.d0,0.d0)
409   - do i=1,d
410   - if (ipiv(i)==i) then
411   - fvn_z_det=fvn_z_det*wc_a(i,i)
412   - else
413   - fvn_z_det=-fvn_z_det*wc_a(i,i)
414   - end if
415   - end do
416   - deallocate(ipiv)
417   - deallocate(wc_a)
418   -
419   -end function
420   -
421   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
422   -!
423   -! Condition test
424   -!
425   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
426   -! 1-norm
427   -! fonction lapack slange,dlange,clange,zlange pour obtenir la 1-norm
428   -! fonction lapack sgecon,dgecon,cgecon,zgecon pour calculer la rcond
429   -!
430   -subroutine fvn_s_matcon(d,a,rcond,status)
431   - ! Matrix condition (reciprocal of condition number)
432   - !
433   - ! d (in) : matrix rank
434   - ! a (in) : The Matrix
435   - ! rcond (out) : guess what
436   - ! status (out) : =0 if something went wrong
437   - !
438   - integer, intent(in) :: d
439   - real, intent(in) :: a(d,d)
440   - real, intent(out) :: rcond
441   - integer, intent(out) :: status
442   -
443   - real, allocatable :: work(:)
444   - integer, allocatable :: iwork(:)
445   - real :: anorm
446   - real, allocatable :: wc_a(:,:) ! working copy of a
447   - integer :: info
448   - integer, allocatable :: ipiv(:)
449   -
450   - real, external :: slange
451   -
452   -
453   - status=1
454   -
455   - anorm=slange('1',d,d,a,d,work) ! work is unallocated as it is only used when computing infinity norm
456   -
457   - allocate(wc_a(d,d))
458   - !call scopy(d*d,a,1,wc_a,1)
459   - wc_a(:,:)=a(:,:)
460   -
461   - allocate(ipiv(d))
462   - call sgetrf(d,d,wc_a,d,ipiv,info)
463   - if (info /= 0) then
464   - status=0
465   - deallocate(ipiv)
466   - deallocate(wc_a)
467   - return
468   - end if
469   - allocate(work(4*d))
470   - allocate(iwork(d))
471   - call sgecon('1',d,wc_a,d,anorm,rcond,work,iwork,info)
472   - if (info /= 0) then
473   - status=0
474   - end if
475   - deallocate(iwork)
476   - deallocate(work)
477   - deallocate(ipiv)
478   - deallocate(wc_a)
479   -
480   -end subroutine
481   -
482   -subroutine fvn_d_matcon(d,a,rcond,status)
483   - ! Matrix condition (reciprocal of condition number)
484   - !
485   - ! d (in) : matrix rank
486   - ! a (in) : The Matrix
487   - ! rcond (out) : guess what
488   - ! status (out) : =0 if something went wrong
489   - !
490   - integer, intent(in) :: d
491   - double precision, intent(in) :: a(d,d)
492   - double precision, intent(out) :: rcond
493   - integer, intent(out) :: status
494   -
495   - double precision, allocatable :: work(:)
496   - integer, allocatable :: iwork(:)
497   - double precision :: anorm
498   - double precision, allocatable :: wc_a(:,:) ! working copy of a
499   - integer :: info
500   - integer, allocatable :: ipiv(:)
501   -
502   - double precision, external :: dlange
503   -
504   -
505   - status=1
506   -
507   - anorm=dlange('1',d,d,a,d,work) ! work is unallocated as it is only used when computing infinity norm
508   -
509   - allocate(wc_a(d,d))
510   - !call dcopy(d*d,a,1,wc_a,1)
511   - wc_a(:,:)=a(:,:)
512   -
513   - allocate(ipiv(d))
514   - call dgetrf(d,d,wc_a,d,ipiv,info)
515   - if (info /= 0) then
516   - status=0
517   - deallocate(ipiv)
518   - deallocate(wc_a)
519   - return
520   - end if
521   -
522   - allocate(work(4*d))
523   - allocate(iwork(d))
524   - call dgecon('1',d,wc_a,d,anorm,rcond,work,iwork,info)
525   - if (info /= 0) then
526   - status=0
527   - end if
528   - deallocate(iwork)
529   - deallocate(work)
530   - deallocate(ipiv)
531   - deallocate(wc_a)
532   -
533   -end subroutine
534   -
535   -subroutine fvn_c_matcon(d,a,rcond,status)
536   - ! Matrix condition (reciprocal of condition number)
537   - !
538   - ! d (in) : matrix rank
539   - ! a (in) : The Matrix
540   - ! rcond (out) : guess what
541   - ! status (out) : =0 if something went wrong
542   - !
543   - integer, intent(in) :: d
544   - complex, intent(in) :: a(d,d)
545   - real, intent(out) :: rcond
546   - integer, intent(out) :: status
547   -
548   - real, allocatable :: rwork(:)
549   - complex, allocatable :: work(:)
550   - integer, allocatable :: iwork(:)
551   - real :: anorm
552   - complex, allocatable :: wc_a(:,:) ! working copy of a
553   - integer :: info
554   - integer, allocatable :: ipiv(:)
555   -
556   - real, external :: clange
557   -
558   -
559   - status=1
560   -
561   - anorm=clange('1',d,d,a,d,rwork) ! rwork is unallocated as it is only used when computing infinity norm
562   -
563   - allocate(wc_a(d,d))
564   - !call ccopy(d*d,a,1,wc_a,1)
565   - wc_a(:,:)=a(:,:)
566   -
567   - allocate(ipiv(d))
568   - call cgetrf(d,d,wc_a,d,ipiv,info)
569   - if (info /= 0) then
570   - status=0
571   - deallocate(ipiv)
572   - deallocate(wc_a)
573   - return
574   - end if
575   - allocate(work(2*d))
576   - allocate(rwork(2*d))
577   - call cgecon('1',d,wc_a,d,anorm,rcond,work,rwork,info)
578   - if (info /= 0) then
579   - status=0
580   - end if
581   - deallocate(rwork)
582   - deallocate(work)
583   - deallocate(ipiv)
584   - deallocate(wc_a)
585   -end subroutine
586   -
587   -subroutine fvn_z_matcon(d,a,rcond,status)
588   - ! Matrix condition (reciprocal of condition number)
589   - !
590   - ! d (in) : matrix rank
591   - ! a (in) : The Matrix
592   - ! rcond (out) : guess what
593   - ! status (out) : =0 if something went wrong
594   - !
595   - integer, intent(in) :: d
596   - double complex, intent(in) :: a(d,d)
597   - double precision, intent(out) :: rcond
598   - integer, intent(out) :: status
599   -
600   - double complex, allocatable :: work(:)
601   - double precision, allocatable :: rwork(:)
602   - double precision :: anorm
603   - double complex, allocatable :: wc_a(:,:) ! working copy of a
604   - integer :: info
605   - integer, allocatable :: ipiv(:)
606   -
607   - double precision, external :: zlange
608   -
609   -
610   - status=1
611   -
612   - anorm=zlange('1',d,d,a,d,rwork) ! rwork is unallocated as it is only used when computing infinity norm
613   -
614   - allocate(wc_a(d,d))
615   - !call zcopy(d*d,a,1,wc_a,1)
616   - wc_a(:,:)=a(:,:)
617   -
618   - allocate(ipiv(d))
619   - call zgetrf(d,d,wc_a,d,ipiv,info)
620   - if (info /= 0) then
621   - status=0
622   - deallocate(ipiv)
623   - deallocate(wc_a)
624   - return
625   - end if
626   -
627   - allocate(work(2*d))
628   - allocate(rwork(2*d))
629   - call zgecon('1',d,wc_a,d,anorm,rcond,work,rwork,info)
630   - if (info /= 0) then
631   - status=0
632   - end if
633   - deallocate(rwork)
634   - deallocate(work)
635   - deallocate(ipiv)
636   - deallocate(wc_a)
637   -end subroutine
638   -
639   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
640   -!
641   -! Valeurs propres/ Vecteurs propre
642   -!
643   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
644   -
645   -subroutine fvn_s_matev(d,a,evala,eveca,status)
646   - !
647   - ! integer d (in) : matrice rank
648   - ! real a(d,d) (in) : The Matrix
649   - ! complex evala(d) (out) : eigenvalues
650   - ! complex eveca(d,d) (out) : eveca(:,j) = jth eigenvector
651   - ! integer (out) : status =0 if something went wrong
652   - !
653   - ! interfacing Lapack routine SGEEV
654   -
655   - integer, intent(in) :: d
656   - real, intent(in) :: a(d,d)
657   - complex, intent(out) :: evala(d)
658   - complex, intent(out) :: eveca(d,d)
659   - integer, intent(out) :: status
660   -
661   - real, allocatable :: wc_a(:,:) ! a working copy of a
662   - integer :: info
663   - integer :: lwork
664   - real, allocatable :: wr(:),wi(:)
665   - real :: vl ! unused but necessary for the call
666   - real, allocatable :: vr(:,:)
667   - real, allocatable :: work(:)
668   - real :: twork(1)
669   - integer i
670   - integer j
671   -
672   - ! making a working copy of a
673   - allocate(wc_a(d,d))
674   - !call scopy(d*d,a,1,wc_a,1)
675   - wc_a(:,:)=a(:,:)
676   -
677   - allocate(wr(d))
678   - allocate(wi(d))
679   - allocate(vr(d,d))
680   - ! query optimal work size
681   - call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info)
682   - lwork=int(twork(1))
683   - allocate(work(lwork))
684   - call sgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info)
685   -
686   - if (info /= 0) then
687   - status=0
688   - deallocate(work)
689   - deallocate(vr)
690   - deallocate(wi)
691   - deallocate(wr)
692   - deallocate(wc_a)
693   - return
694   - end if
695   -
696   - ! now fill in the results
697   - i=1
698   - do while(i<=d)
699   - evala(i)=cmplx(wr(i),wi(i))
700   - if (wi(i) == 0.) then ! eigenvalue is real
701   - eveca(:,i)=cmplx(vr(:,i),0.)
702   - else ! eigenvalue is complex
703   - evala(i+1)=cmplx(wr(i+1),wi(i+1))
704   - eveca(:,i)=cmplx(vr(:,i),vr(:,i+1))
705   - eveca(:,i+1)=cmplx(vr(:,i),-vr(:,i+1))
706   - i=i+1
707   - end if
708   - i=i+1
709   - enddo
710   - deallocate(work)
711   - deallocate(vr)
712   - deallocate(wi)
713   - deallocate(wr)
714   - deallocate(wc_a)
715   -
716   -end subroutine
717   -
718   -subroutine fvn_d_matev(d,a,evala,eveca,status)
719   - !
720   - ! integer d (in) : matrice rank
721   - ! double precision a(d,d) (in) : The Matrix
722   - ! double complex evala(d) (out) : eigenvalues
723   - ! double complex eveca(d,d) (out) : eveca(:,j) = jth eigenvector
724   - ! integer (out) : status =0 if something went wrong
725   - !
726   - ! interfacing Lapack routine DGEEV
727   - integer, intent(in) :: d
728   - double precision, intent(in) :: a(d,d)
729   - double complex, intent(out) :: evala(d)
730   - double complex, intent(out) :: eveca(d,d)
731   - integer, intent(out) :: status
732   -
733   - double precision, allocatable :: wc_a(:,:) ! a working copy of a
734   - integer :: info
735   - integer :: lwork
736   - double precision, allocatable :: wr(:),wi(:)
737   - double precision :: vl ! unused but necessary for the call
738   - double precision, allocatable :: vr(:,:)
739   - double precision, allocatable :: work(:)
740   - double precision :: twork(1)
741   - integer i
742   - integer j
743   -
744   - ! making a working copy of a
745   - allocate(wc_a(d,d))
746   - !call dcopy(d*d,a,1,wc_a,1)
747   - wc_a(:,:)=a(:,:)
748   -
749   - allocate(wr(d))
750   - allocate(wi(d))
751   - allocate(vr(d,d))
752   - ! query optimal work size
753   - call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,twork,-1,info)
754   - lwork=int(twork(1))
755   - allocate(work(lwork))
756   - call dgeev('N','V',d,wc_a,d,wr,wi,vl,1,vr,d,work,lwork,info)
757   -
758   - if (info /= 0) then
759   - status=0
760   - deallocate(work)
761   - deallocate(vr)
762   - deallocate(wi)
763   - deallocate(wr)
764   - deallocate(wc_a)
765   - return
766   - end if
767   -
768   - ! now fill in the results
769   - i=1
770   - do while(i<=d)
771   - evala(i)=dcmplx(wr(i),wi(i))
772   - if (wi(i) == 0.) then ! eigenvalue is real
773   - eveca(:,i)=dcmplx(vr(:,i),0.)
774   - else ! eigenvalue is complex
775   - evala(i+1)=dcmplx(wr(i+1),wi(i+1))
776   - eveca(:,i)=dcmplx(vr(:,i),vr(:,i+1))
777   - eveca(:,i+1)=dcmplx(vr(:,i),-vr(:,i+1))
778   - i=i+1
779   - end if
780   - i=i+1
781   - enddo
782   -
783   - deallocate(work)
784   - deallocate(vr)
785   - deallocate(wi)
786   - deallocate(wr)
787   - deallocate(wc_a)
788   -
789   -end subroutine
790   -
791   -subroutine fvn_c_matev(d,a,evala,eveca,status)
792   - !
793   - ! integer d (in) : matrice rank
794   - ! complex a(d,d) (in) : The Matrix
795   - ! complex evala(d) (out) : eigenvalues
796   - ! complex eveca(d,d) (out) : eveca(:,j) = jth eigenvector
797   - ! integer (out) : status =0 if something went wrong
798   - !
799   - ! interfacing Lapack routine CGEEV
800   -
801   - integer, intent(in) :: d
802   - complex, intent(in) :: a(d,d)
803   - complex, intent(out) :: evala(d)
804   - complex, intent(out) :: eveca(d,d)
805   - integer, intent(out) :: status
806   -
807   - complex, allocatable :: wc_a(:,:) ! a working copy of a
808   - integer :: info
809   - integer :: lwork
810   - complex, allocatable :: work(:)
811   - complex :: twork(1)
812   - real, allocatable :: rwork(:)
813   - complex :: vl ! unused but necessary for the call
814   -
815   - status=1
816   -
817   - ! making a working copy of a
818   - allocate(wc_a(d,d))
819   - !call ccopy(d*d,a,1,wc_a,1)
820   - wc_a(:,:)=a(:,:)
821   -
822   -
823   - ! query optimal work size
824   - call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info)
825   - lwork=int(twork(1))
826   - allocate(work(lwork))
827   - allocate(rwork(2*d))
828   - call cgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info)
829   -
830   - if (info /= 0) then
831   - status=0
832   - end if
833   - deallocate(rwork)
834   - deallocate(work)
835   - deallocate(wc_a)
836   -
837   -end subroutine
838   -
839   -subroutine fvn_z_matev(d,a,evala,eveca,status)
840   - !
841   - ! integer d (in) : matrice rank
842   - ! double complex a(d,d) (in) : The Matrix
843   - ! double complex evala(d) (out) : eigenvalues
844   - ! double complex eveca(d,d) (out) : eveca(:,j) = jth eigenvector
845   - ! integer (out) : status =0 if something went wrong
846   - !
847   - ! interfacing Lapack routine ZGEEV
848   -
849   - integer, intent(in) :: d
850   - double complex, intent(in) :: a(d,d)
851   - double complex, intent(out) :: evala(d)
852   - double complex, intent(out) :: eveca(d,d)
853   - integer, intent(out) :: status
854   -
855   - double complex, allocatable :: wc_a(:,:) ! a working copy of a
856   - integer :: info
857   - integer :: lwork
858   - double complex, allocatable :: work(:)
859   - double complex :: twork(1)
860   - double precision, allocatable :: rwork(:)
861   - double complex :: vl ! unused but necessary for the call
862   -
863   - status=1
864   -
865   - ! making a working copy of a
866   - allocate(wc_a(d,d))
867   - !call zcopy(d*d,a,1,wc_a,1)
868   - wc_a(:,:)=a(:,:)
869   -
870   - ! query optimal work size
871   - call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,twork,-1,rwork,info)
872   - lwork=int(twork(1))
873   - allocate(work(lwork))
874   - allocate(rwork(2*d))
875   - call zgeev('N','V',d,wc_a,d,evala,vl,1,eveca,d,work,lwork,rwork,info)
876   -
877   - if (info /= 0) then
878   - status=0
879   - end if
880   - deallocate(rwork)
881   - deallocate(work)
882   - deallocate(wc_a)
883   -
884   -end subroutine
885   -
886   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
887   -!
888   -! Akima spline interpolation and spline evaluation
889   -!
890   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
891   -
892   -! Single precision
893   -subroutine fvn_s_akima(n,x,y,br,co)
894   - implicit none
895   - integer, intent(in) :: n
896   - real, intent(in) :: x(n)
897   - real, intent(in) :: y(n)
898   - real, intent(out) :: br(n)
899   - real, intent(out) :: co(4,n)
900   -
901   - real, allocatable :: var(:),z(:)
902   - real :: wi_1,wi
903   - integer :: i
904   - real :: dx,a,b
905   -
906   - ! br is just a copy of x
907   - br(:)=x(:)
908   -
909   - allocate(var(n))
910   - allocate(z(n))
911   - ! evaluate the variations
912   - do i=1, n-1
913   - var(i+2)=(y(i+1)-y(i))/(x(i+1)-x(i))
914   - end do
915   - var(n+2)=2.e0*var(n+1)-var(n)
916   - var(n+3)=2.e0*var(n+2)-var(n+1)
917   - var(2)=2.e0*var(3)-var(4)
918   - var(1)=2.e0*var(2)-var(3)
919   -
920   - do i = 1, n
921   - wi_1=abs(var(i+3)-var(i+2))
922   - wi=abs(var(i+1)-var(i))
923   - if ((wi_1+wi).eq.0.e0) then
924   - z(i)=(var(i+2)+var(i+1))/2.e0
925   - else
926   - z(i)=(wi_1*var(i+1)+wi*var(i+2))/(wi_1+wi)
927   - end if
928   - end do
929   -
930   - do i=1, n-1
931   - dx=x(i+1)-x(i)
932   - a=(z(i+1)-z(i))*dx ! coeff intermediaires pour calcul wd
933   - b=y(i+1)-y(i)-z(i)*dx ! coeff intermediaires pour calcul wd
934   - co(1,i)=y(i)
935   - co(2,i)=z(i)
936   - !co(3,i)=-(a-3.*b)/dx**2 ! mรฉthode wd
937   - !co(4,i)=(a-2.*b)/dx**3 ! mรฉthode wd
938   - co(3,i)=(3.e0*var(i+2)-2.e0*z(i)-z(i+1))/dx ! mรฉthode JP Moreau
939   - co(4,i)=(z(i)+z(i+1)-2.e0*var(i+2))/dx**2 !
940   - ! les coefficients donnรฉs par imsl sont co(3,i)*2 et co(4,i)*6
941   - ! etrangement la fonction csval corrige et donne la bonne valeur ...
942   - end do
943   - co(1,n)=y(n)
944   - co(2,n)=z(n)
945   - co(3,n)=0.e0
946   - co(4,n)=0.e0
947   -
948   - deallocate(z)
949   - deallocate(var)
950   -
951   -end subroutine
952   -
953   -! Double precision
954   -subroutine fvn_d_akima(n,x,y,br,co)
955   -
956   - implicit none
957   - integer, intent(in) :: n
958   - double precision, intent(in) :: x(n)
959   - double precision, intent(in) :: y(n)
960   - double precision, intent(out) :: br(n)
961   - double precision, intent(out) :: co(4,n)
962   -
963   - double precision, allocatable :: var(:),z(:)
964   - double precision :: wi_1,wi
965   - integer :: i
966   - double precision :: dx,a,b
967   -
968   - ! br is just a copy of x
969   - br(:)=x(:)
970   -
971   - allocate(var(n))
972   - allocate(z(n))
973   - ! evaluate the variations
974   - do i=1, n-1
975   - var(i+2)=(y(i+1)-y(i))/(x(i+1)-x(i))
976   - end do
977   - var(n+2)=2.d0*var(n+1)-var(n)
978   - var(n+3)=2.d0*var(n+2)-var(n+1)
979   - var(2)=2.d0*var(3)-var(4)
980   - var(1)=2.d0*var(2)-var(3)
981   -
982   - do i = 1, n
983   - wi_1=dabs(var(i+3)-var(i+2))
984   - wi=dabs(var(i+1)-var(i))
985   - if ((wi_1+wi).eq.0.d0) then
986   - z(i)=(var(i+2)+var(i+1))/2.d0
987   - else
988   - z(i)=(wi_1*var(i+1)+wi*var(i+2))/(wi_1+wi)
989   - end if
990   - end do
991   -
992   - do i=1, n-1
993   - dx=x(i+1)-x(i)
994   - a=(z(i+1)-z(i))*dx ! coeff intermediaires pour calcul wd
995   - b=y(i+1)-y(i)-z(i)*dx ! coeff intermediaires pour calcul wd
996   - co(1,i)=y(i)
997   - co(2,i)=z(i)
998   - !co(3,i)=-(a-3.*b)/dx**2 ! mรฉthode wd
999   - !co(4,i)=(a-2.*b)/dx**3 ! mรฉthode wd
1000   - co(3,i)=(3.d0*var(i+2)-2.d0*z(i)-z(i+1))/dx ! mรฉthode JP Moreau
1001   - co(4,i)=(z(i)+z(i+1)-2.d0*var(i+2))/dx**2 !
1002   - ! les coefficients donnรฉs par imsl sont co(3,i)*2 et co(4,i)*6
1003   - ! etrangement la fonction csval corrige et donne la bonne valeur ...
1004   - end do
1005   - co(1,n)=y(n)
1006   - co(2,n)=z(n)
1007   - co(3,n)=0.d0
1008   - co(4,n)=0.d0
1009   -
1010   - deallocate(z)
1011   - deallocate(var)
1012   -
1013   -end subroutine
1014   -
1015   -!
1016   -! Single precision spline evaluation
1017   -!
1018   -function fvn_s_spline_eval(x,n,br,co)
1019   - implicit none
1020   - real, intent(in) :: x ! x must be br(1)<= x <= br(n+1) otherwise value is extrapolated
1021   - integer, intent(in) :: n ! number of intervals
1022   - real, intent(in) :: br(n+1) ! breakpoints
1023   - real, intent(in) :: co(4,n+1) ! spline coeeficients
1024   - real :: fvn_s_spline_eval
1025   -
1026   - integer :: i
1027   - real :: dx
1028   -
1029   - if (x<=br(1)) then
1030   - i=1
1031   - else if (x>=br(n+1)) then
1032   - i=n
1033   - else
1034   - i=1
1035   - do while(x>=br(i))
1036   - i=i+1
1037   - end do
1038   - i=i-1
1039   - end if
1040   - dx=x-br(i)
1041   - fvn_s_spline_eval=co(1,i)+co(2,i)*dx+co(3,i)*dx**2+co(4,i)*dx**3
1042   -
1043   -end function
1044   -
1045   -! Double precision spline evaluation
1046   -function fvn_d_spline_eval(x,n,br,co)
1047   - implicit none
1048   - double precision, intent(in) :: x ! x must be br(1)<= x <= br(n+1) otherwise value is extrapolated
1049   - integer, intent(in) :: n ! number of intervals
1050   - double precision, intent(in) :: br(n+1) ! breakpoints
1051   - double precision, intent(in) :: co(4,n+1) ! spline coeeficients
1052   - double precision :: fvn_d_spline_eval
1053   -
1054   - integer :: i
1055   - double precision :: dx
1056   -
1057   -
1058   - if (x<=br(1)) then
1059   - i=1
1060   - else if (x>=br(n+1)) then
1061   - i=n
1062   - else
1063   - i=1
1064   - do while(x>=br(i))
1065   - i=i+1
1066   - end do
1067   - i=i-1
1068   - end if
1069   -
1070   - dx=x-br(i)
1071   - fvn_d_spline_eval=co(1,i)+co(2,i)*dx+co(3,i)*dx**2+co(4,i)*dx**3
1072   -
1073   -end function
1074   -
1075   -
1076   -!
1077   -! Muller
1078   -!
1079   -!
1080   -!
1081   -! William Daniau 2007
1082   -!
1083   -! This routine is a fortran 90 port of Hans D. Mittelmann's routine muller.f
1084   -! http://plato.asu.edu/ftp/other_software/muller.f
1085   -!
1086   -! it can be used as a replacement for imsl routine dzanly with minor changes
1087   -!
1088   -!-----------------------------------------------------------------------
1089   -!
1090   -! purpose - zeros of an analytic complex function
1091   -! using the muller method with deflation
1092   -!
1093   -! usage - call fvn_z_muller (f,eps,eps1,kn,n,nguess,x,itmax,
1094   -! infer,ier)
1095   -!
1096   -! arguments f - a complex function subprogram, f(z), written
1097   -! by the user specifying the equation whose
1098   -! roots are to be found. f must appear in
1099   -! an external statement in the calling pro-
1100   -! gram.
1101   -! eps - 1st stopping criterion. let fp(z)=f(z)/p
1102   -! where p = (z-z(1))*(z-z(2))*,,,*(z-z(k-1))
1103   -! and z(1),...,z(k-1) are previously found
1104   -! roots. if ((cdabs(f(z)).le.eps) .and.
1105   -! (cdabs(fp(z)).le.eps)), then z is accepted
1106   -! as a root. (input)
1107   -! eps1 - 2nd stopping criterion. a root is accepted
1108   -! if two successive approximations to a given
1109   -! root agree within eps1. (input)
1110   -! note. if either or both of the stopping
1111   -! criteria are fulfilled, the root is
1112   -! accepted.
1113   -! kn - the number of known roots which must be stored
1114   -! in x(1),...,x(kn), prior to entry to muller
1115   -! nguess - the number of initial guesses provided. these
1116   -! guesses must be stored in x(kn+1),...,
1117   -! x(kn+nguess). nguess must be set equal
1118   -! to zero if no guesses are provided. (input)
1119   -! n - the number of new roots to be found by
1120   -! muller (input)
1121   -! x - a complex vector of length kn+n. x(1),...,
1122   -! x(kn) on input must contain any known
1123   -! roots. x(kn+1),..., x(kn+n) on input may,
1124   -! on user option, contain initial guesses for
1125   -! the n new roots which are to be computed.
1126   -! if the user does not provide an initial
1127   -! guess, zero is used.
1128   -! on output, x(kn+1),...,x(kn+n) contain the
1129   -! approximate roots found by muller.
1130   -! itmax - the maximum allowable number of iterations
1131   -! per root (input)
1132   -! infer - an integer vector of length kn+n. on
1133   -! output infer(j) contains the number of
1134   -! iterations used in finding the j-th root
1135   -! when convergence was achieved. if
1136   -! convergence was not obtained in itmax
1137   -! iterations, infer(j) will be greater than
1138   -! itmax (output).
1139   -! ier - error parameter (output)
1140   -! warning error
1141   -! ier = 33 indicates failure to converge with-
1142   -! in itmax iterations for at least one of
1143   -! the (n) new roots.
1144   -!
1145   -!
1146   -! remarks muller always returns the last approximation for root j
1147   -! in x(j). if the convergence criterion is satisfied,
1148   -! then infer(j) is less than or equal to itmax. if the
1149   -! convergence criterion is not satisified, then infer(j)
1150   -! is set to either itmax+1 or itmax+k, with k greater
1151   -! than 1. infer(j) = itmax+1 indicates that muller did
1152   -! not obtain convergence in the allowed number of iter-
1153   -! ations. in this case, the user may wish to set itmax
1154   -! to a larger value. infer(j) = itmax+k means that con-
1155   -! vergence was obtained (on iteration k) for the defla-
1156   -! ted function
1157   -! fp(z) = f(z)/((z-z(1)...(z-z(j-1)))
1158   -!
1159   -! but failed for f(z). in this case, better initial
1160   -! guesses might help or, it might be necessary to relax
1161   -! the convergence criterion.
1162   -!
1163   -!-----------------------------------------------------------------------
1164   -!
1165   -subroutine fvn_z_muller (f,eps,eps1,kn,nguess,n,x,itmax,infer,ier)
1166   - implicit none
1167   - double precision :: rzero,rten,rhun,rp01,ax,eps1,qz,eps,tpq
1168   - double complex :: d,dd,den,fprt,frt,h,rt,t1,t2,t3, &
1169   - tem,z0,z1,z2,bi,xx,xl,y0,y1,y2,x0, &
1170   - zero,p1,one,four,p5
1171   -
1172   - double complex, external :: f
1173   - integer :: ickmax,kn,nguess,n,itmax,ier,knp1,knpn,i,l,ic, &
1174   - knpng,jk,ick,nn,lm1,errcode
1175   - double complex :: x(kn+n)
1176   - integer :: infer(kn+n)
1177   -
1178   -
1179   - data zero/(0.0,0.0)/,p1/(0.1,0.0)/, &
1180   - one/(1.0,0.0)/,four/(4.0,0.0)/, &
1181   - p5/(0.5,0.0)/, &
1182   - rzero/0.0/,rten/10.0/,rhun/100.0/, &
1183   - ax/0.1/,ickmax/3/,rp01/0.01/
1184   -
1185   - ier = 0
1186   - if (n .lt. 1) then ! What the hell are doing here then ...
1187   - return
1188   - end if
1189   - !eps1 = rten **(-nsig)
1190   - eps1 = min(eps1,rp01)
1191   -
1192   - knp1 = kn+1
1193   - knpn = kn+n
1194   - knpng = kn+nguess
1195   - do i=1,knpn
1196   - infer(i) = 0
1197   - if (i .gt. knpng) x(i) = zero
1198   - end do
1199   - l= knp1
1200   -
1201   - ic=0
1202   -rloop: do while (l<=knpn) ! Main loop over new roots
1203   - jk = 0
1204   - ick = 0
1205   - xl = x(l)
1206   -icloop: do
1207   - ic = 0
1208   - h = ax
1209   - h = p1*h
1210   - if (cdabs(xl) .gt. ax) h = p1*xl
1211   -! first three points are
1212   -! xl+h, xl-h, xl
1213   - rt = xl+h
1214   - call deflated_work(errcode)
1215   - if (errcode == 1) then
1216   - exit icloop
1217   - end if
1218   -
1219   - z0 = fprt
1220   - y0 = frt
1221   - x0 = rt
1222   - rt = xl-h
1223   - call deflated_work(errcode)
1224   - if (errcode == 1) then
1225   - exit icloop
1226   - end if
1227   -
1228   - z1 = fprt
1229   - y1 = frt
1230   - h = xl-rt
1231   - d = h/(rt-x0)
1232   - rt = xl
1233   -
1234   - call deflated_work(errcode)
1235   - if (errcode == 1) then
1236   - exit icloop
1237   - end if
1238   -
1239   -
1240   - z2 = fprt
1241   - y2 = frt
1242   -! begin main algorithm
1243   - iloop: do
1244   - dd = one + d
1245   - t1 = z0*d*d
1246   - t2 = z1*dd*dd
1247   - xx = z2*dd
1248   - t3 = z2*d
1249   - bi = t1-t2+xx+t3
1250   - den = bi*bi-four*(xx*t1-t3*(t2-xx))
1251   -! use denominator of maximum amplitude
1252   - t1 = cdsqrt(den)
1253   - qz = rhun*max(cdabs(bi),cdabs(t1))
1254   - t2 = bi + t1
1255   - tpq = cdabs(t2)+qz
1256   - if (tpq .eq. qz) t2 = zero
1257   - t3 = bi - t1
1258   - tpq = cdabs(t3) + qz
1259   - if (tpq .eq. qz) t3 = zero
1260   - den = t2
1261   - qz = cdabs(t3)-cdabs(t2)
1262   - if (qz .gt. rzero) den = t3
1263   -! test for zero denominator
1264   - if (cdabs(den) .eq. rzero) then
1265   - call trans_rt()
1266   - call deflated_work(errcode)
1267   - if (errcode == 1) then
1268   - exit icloop
1269   - end if
1270   - z2 = fprt
1271   - y2 = frt
1272   - cycle iloop
1273   - end if
1274   -
1275   -
1276   - d = -xx/den
1277   - d = d+d
1278   - h = d*h
1279   - rt = rt + h
1280   -! check convergence of the first kind
1281   - if (cdabs(h) .le. eps1*max(cdabs(rt),ax)) then
1282   - if (ic .ne. 0) then
1283   - exit icloop
1284   - end if
1285   - ic = 1
1286   - z0 = y1
1287   - z1 = y2
1288   - z2 = f(rt)
1289   - xl = rt
1290   - ick = ick+1
1291   - if (ick .le. ickmax) then
1292   - cycle iloop
1293   - end if
1294   -! warning error, itmax = maximum
1295   - jk = itmax + jk
1296   - ier = 33
1297   - end if
1298   - if (ic .ne. 0) then
1299   - cycle icloop
1300   - end if
1301   - call deflated_work(errcode)
1302   - if (errcode == 1) then
1303   - exit icloop
1304   - end if
1305   -
1306   - do while ( (cdabs(fprt)-cdabs(z2)*rten) .ge. rzero)
1307   - ! take remedial action to induce
1308   - ! convergence
1309   - d = d*p5
1310   - h = h*p5
1311   - rt = rt-h
1312   - call deflated_work(errcode)
1313   - if (errcode == 1) then
1314   - exit icloop
1315   - end if
1316   - end do
1317   - z0 = z1
1318   - z1 = z2
1319   - z2 = fprt
1320   - y0 = y1
1321   - y1 = y2
1322   - y2 = frt
1323   - end do iloop
1324   - end do icloop
1325   - x(l) = rt
1326   - infer(l) = jk
1327   - l = l+1
1328   - end do rloop
1329   -
1330   - contains
1331   - subroutine trans_rt()
1332   - tem = rten*eps1
1333   - if (cdabs(rt) .gt. ax) tem = tem*rt
1334   - rt = rt+tem
1335   - d = (h+tem)*d/h
1336   - h = h+tem
1337   - end subroutine trans_rt
1338   -
1339   - subroutine deflated_work(errcode)
1340   - ! errcode=0 => no errors
1341   - ! errcode=1 => jk>itmax or convergence of second kind achieved
1342   - integer :: errcode,flag
1343   -
1344   - flag=1
1345   - loop1: do while(flag==1)
1346   - errcode=0
1347   - jk = jk+1
1348   - if (jk .gt. itmax) then
1349   - ier=33
1350   - errcode=1
1351   - return
1352   - end if
1353   - frt = f(rt)
1354   - fprt = frt
1355   - if (l /= 1) then
1356   - lm1 = l-1
1357   - do i=1,lm1
1358   - tem = rt - x(i)
1359   - if (cdabs(tem) .eq. rzero) then
1360   - !if (ic .ne. 0) go to 15 !! ?? possible?
1361   - call trans_rt()
1362   - cycle loop1
1363   - end if
1364   - fprt = fprt/tem
1365   - end do
1366   - end if
1367   - flag=0
1368   - end do loop1
1369   -
1370   - if (cdabs(fprt) .le. eps .and. cdabs(frt) .le. eps) then
1371   - errcode=1
1372   - return
1373   - end if
1374   -
1375   - end subroutine deflated_work
1376   -
1377   - end subroutine
1378   -
1379   -
1380   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1381   -!
1382   -! Integration
1383   -!
1384   -! Only double precision coded atm
1385   -!
1386   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1387   -
1388   -
1389   -subroutine fvn_d_gauss_legendre(n,qx,qw)
1390   -!
1391   -! This routine compute the n Gauss Legendre abscissas and weights
1392   -! Adapted from Numerical Recipes routine gauleg
1393   -!
1394   -! n (in) : number of points
1395   -! qx(out) : abscissas
1396   -! qw(out) : weights
1397   -!
1398   -implicit none
1399   -double precision,parameter :: pi=3.141592653589793d0
1400   -integer, intent(in) :: n
1401   -double precision, intent(out) :: qx(n),qw(n)
1402   -
1403   -integer :: m,i,j
1404   -double precision :: z,z1,p1,p2,p3,pp
1405   -m=(n+1)/2
1406   -do i=1,m
1407   - z=cos(pi*(dble(i)-0.25d0)/(dble(n)+0.5d0))
1408   -iloop: do
1409   - p1=1.d0
1410   - p2=0.d0
1411   - do j=1,n
1412   - p3=p2
1413   - p2=p1
1414   - p1=((2.d0*dble(j)-1.d0)*z*p2-(dble(j)-1.d0)*p3)/dble(j)
1415   - end do
1416   - pp=dble(n)*(z*p1-p2)/(z*z-1.d0)
1417   - z1=z
1418   - z=z1-p1/pp
1419   - if (dabs(z-z1)<=epsilon(z)) then
1420   - exit iloop
1421   - end if
1422   - end do iloop
1423   - qx(i)=-z
1424   - qx(n+1-i)=z
1425   - qw(i)=2.d0/((1.d0-z*z)*pp*pp)
1426   - qw(n+1-i)=qw(i)
1427   -end do
1428   -end subroutine
1429   -
1430   -
1431   -
1432   -subroutine fvn_d_gl_integ(f,a,b,n,res)
1433   -!
1434   -! This is a simple non adaptative integration routine
1435   -! using n gauss legendre abscissas and weights
1436   -!
1437   -! f(in) : the function to integrate
1438   -! a(in) : lower bound
1439   -! b(in) : higher bound
1440   -! n(in) : number of gauss legendre pairs
1441   -! res(out): the evaluation of the integral
1442   -!
1443   -double precision,external :: f
1444   -double precision, intent(in) :: a,b
1445   -integer, intent(in):: n
1446   -double precision, intent(out) :: res
1447   -
1448   -double precision, allocatable :: qx(:),qw(:)
1449   -double precision :: xm,xr
1450   -integer :: i
1451   -
1452   -! First compute n gauss legendre abs and weight
1453   -allocate(qx(n))
1454   -allocate(qw(n))
1455   -call fvn_d_gauss_legendre(n,qx,qw)
1456   -
1457   -xm=0.5d0*(b+a)
1458   -xr=0.5d0*(b-a)
1459   -
1460   -res=0.d0
1461   -
1462   -do i=1,n
1463   - res=res+qw(i)*f(xm+xr*qx(i))
1464   -end do
1465   -
1466   -res=xr*res
1467   -
1468   -deallocate(qw)
1469   -deallocate(qx)
1470   -
1471   -end subroutine
1472   -
1473   -!!!!!!!!!!!!!!!!!!!!!!!!
1474   -!
1475   -! Simple and double adaptative Gauss Kronrod integration based on
1476   -! a modified version of quadpack ( http://www.netlib.org/quadpack
1477   -!
1478   -! Common parameters :
1479   -!
1480   -! key (in)
1481   -! epsabs
1482   -! epsrel
1483   -!
1484   -!
1485   -!!!!!!!!!!!!!!!!!!!!!!!!
1486   -
1487   -subroutine fvn_d_integ_1_gk(f,a,b,epsabs,epsrel,key,res,abserr,ier,limit)
1488   -!
1489   -! Evaluate the integral of function f(x) between a and b
1490   -!
1491   -! f(in) : the function
1492   -! a(in) : lower bound
1493   -! b(in) : higher bound
1494   -! epsabs(in) : desired absolute error
1495   -! epsrel(in) : desired relative error
1496   -! key(in) : gauss kronrod rule
1497   -! 1: 7 - 15 points
1498   -! 2: 10 - 21 points
1499   -! 3: 15 - 31 points
1500   -! 4: 20 - 41 points
1501   -! 5: 25 - 51 points
1502   -! 6: 30 - 61 points
1503   -!
1504   -! limit(in) : maximum number of subintervals in the partition of the
1505   -! given integration interval (a,b). A value of 500 will give the same
1506   -! behaviour as the imsl routine dqdag
1507   -!
1508   -! res(out) : estimated integral value
1509   -! abserr(out) : estimated absolute error
1510   -! ier(out) : error flag from quadpack routines
1511   -! 0 : no error
1512   -! 1 : maximum number of subdivisions allowed
1513   -! has been achieved. one can allow more
1514   -! subdivisions by increasing the value of
1515   -! limit (and taking the according dimension
1516   -! adjustments into account). however, if
1517   -! this yield no improvement it is advised
1518   -! to analyze the integrand in order to
1519   -! determine the integration difficulaties.
1520   -! if the position of a local difficulty can
1521   -! be determined (i.e.singularity,
1522   -! discontinuity within the interval) one
1523   -! will probably gain from splitting up the
1524   -! interval at this point and calling the
1525   -! integrator on the subranges. if possible,
1526   -! an appropriate special-purpose integrator
1527   -! should be used which is designed for
1528   -! handling the type of difficulty involved.
1529   -! 2 : the occurrence of roundoff error is
1530   -! detected, which prevents the requested
1531   -! tolerance from being achieved.
1532   -! 3 : extremely bad integrand behaviour occurs
1533   -! at some points of the integration
1534   -! interval.
1535   -! 6 : the input is invalid, because
1536   -! (epsabs.le.0 and
1537   -! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
1538   -! or limit.lt.1 or lenw.lt.limit*4.
1539   -! result, abserr, neval, last are set
1540   -! to zero.
1541   -! except when lenw is invalid, iwork(1),
1542   -! work(limit*2+1) and work(limit*3+1) are
1543   -! set to zero, work(1) is set to a and
1544   -! work(limit+1) to b.
1545   -
1546   -implicit none
1547   -double precision, external :: f
1548   -double precision, intent(in) :: a,b,epsabs,epsrel
1549   -integer, intent(in) :: key
1550   -integer, intent(in) :: limit
1551   -double precision, intent(out) :: res,abserr
1552   -integer, intent(out) :: ier
1553   -
1554   -double precision, allocatable :: work(:)
1555   -integer, allocatable :: iwork(:)
1556   -integer :: lenw,neval,last
1557   -
1558   -! imsl value for limit is 500
1559   -lenw=limit*4
1560   -
1561   -allocate(iwork(limit))
1562   -allocate(work(lenw))
1563   -
1564   -call dqag(f,a,b,epsabs,epsrel,key,res,abserr,neval,ier,limit,lenw,last,iwork,work)
1565   -
1566   -deallocate(work)
1567   -deallocate(iwork)
1568   -
1569   -end subroutine
1570   -
1571   -
1572   -
1573   -subroutine fvn_d_integ_2_gk(f,a,b,g,h,epsabs,epsrel,key,res,abserr,ier,limit)
1574   -!
1575   -! Evaluate the double integral of function f(x,y) for x between a and b and y between g(x) and h(x)
1576   -!
1577   -! f(in) : the function
1578   -! a(in) : lower bound
1579   -! b(in) : higher bound
1580   -! g(in) : external function describing lower bound for y
1581   -! h(in) : external function describing higher bound for y
1582   -! epsabs(in) : desired absolute error
1583   -! epsrel(in) : desired relative error
1584   -! key(in) : gauss kronrod rule
1585   -! 1: 7 - 15 points
1586   -! 2: 10 - 21 points
1587   -! 3: 15 - 31 points
1588   -! 4: 20 - 41 points
1589   -! 5: 25 - 51 points
1590   -! 6: 30 - 61 points
1591   -!
1592   -! limit(in) : maximum number of subintervals in the partition of the
1593   -! given integration interval (a,b). A value of 500 will give the same
1594   -! behaviour as the imsl routine dqdag
1595   -!
1596   -! res(out) : estimated integral value
1597   -! abserr(out) : estimated absolute error
1598   -! ier(out) : error flag from quadpack routines
1599   -! 0 : no error
1600   -! 1 : maximum number of subdivisions allowed
1601   -! has been achieved. one can allow more
1602   -! subdivisions by increasing the value of
1603   -! limit (and taking the according dimension
1604   -! adjustments into account). however, if
1605   -! this yield no improvement it is advised
1606   -! to analyze the integrand in order to
1607   -! determine the integration difficulaties.
1608   -! if the position of a local difficulty can
1609   -! be determined (i.e.singularity,
1610   -! discontinuity within the interval) one
1611   -! will probably gain from splitting up the
1612   -! interval at this point and calling the
1613   -! integrator on the subranges. if possible,
1614   -! an appropriate special-purpose integrator
1615   -! should be used which is designed for
1616   -! handling the type of difficulty involved.
1617   -! 2 : the occurrence of roundoff error is
1618   -! detected, which prevents the requested
1619   -! tolerance from being achieved.
1620   -! 3 : extremely bad integrand behaviour occurs
1621   -! at some points of the integration
1622   -! interval.
1623   -! 6 : the input is invalid, because
1624   -! (epsabs.le.0 and
1625   -! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
1626   -! or limit.lt.1 or lenw.lt.limit*4.
1627   -! result, abserr, neval, last are set
1628   -! to zero.
1629   -! except when lenw is invalid, iwork(1),
1630   -! work(limit*2+1) and work(limit*3+1) are
1631   -! set to zero, work(1) is set to a and
1632   -! work(limit+1) to b.
1633   -
1634   -implicit none
1635   -double precision, external:: f,g,h
1636   -double precision, intent(in) :: a,b,epsabs,epsrel
1637   -integer, intent(in) :: key,limit
1638   -integer, intent(out) :: ier
1639   -double precision, intent(out) :: res,abserr
1640   -
1641   -
1642   -double precision, allocatable :: work(:)
1643   -integer, allocatable :: iwork(:)
1644   -integer :: lenw,neval,last
1645   -
1646   -! imsl value for limit is 500
1647   -lenw=limit*4
1648   -allocate(work(lenw))
1649   -allocate(iwork(limit))
1650   -
1651   -call dqag_2d_outer(f,a,b,g,h,epsabs,epsrel,key,res,abserr,neval,ier,limit,lenw,last,iwork,work)
1652   -
1653   -deallocate(iwork)
1654   -deallocate(work)
1655   -end subroutine
1656   -
1657   -
1658   -
1659   -subroutine fvn_d_integ_2_inner_gk(f,x,a,b,epsabs,epsrel,key,res,abserr,ier,limit)
1660   -!
1661   -! Evaluate the single integral of function f(x,y) for y between a and b with a
1662   -! given x value
1663   -!
1664   -! This function is used for the evaluation of the double integral fvn_d_integ_2_gk
1665   -!
1666   -! f(in) : the function
1667   -! x(in) : x
1668   -! a(in) : lower bound
1669   -! b(in) : higher bound
1670   -! epsabs(in) : desired absolute error
1671   -! epsrel(in) : desired relative error
1672   -! key(in) : gauss kronrod rule
1673   -! 1: 7 - 15 points
1674   -! 2: 10 - 21 points
1675   -! 3: 15 - 31 points
1676   -! 4: 20 - 41 points
1677   -! 5: 25 - 51 points
1678   -! 6: 30 - 61 points
1679   -!
1680   -! limit(in) : maximum number of subintervals in the partition of the
1681   -! given integration interval (a,b). A value of 500 will give the same
1682   -! behaviour as the imsl routine dqdag
1683   -!
1684   -! res(out) : estimated integral value
1685   -! abserr(out) : estimated absolute error
1686   -! ier(out) : error flag from quadpack routines
1687   -! 0 : no error
1688   -! 1 : maximum number of subdivisions allowed
1689   -! has been achieved. one can allow more
1690   -! subdivisions by increasing the value of
1691   -! limit (and taking the according dimension
1692   -! adjustments into account). however, if
1693   -! this yield no improvement it is advised
1694   -! to analyze the integrand in order to
1695   -! determine the integration difficulaties.
1696   -! if the position of a local difficulty can
1697   -! be determined (i.e.singularity,
1698   -! discontinuity within the interval) one
1699   -! will probably gain from splitting up the
1700   -! interval at this point and calling the
1701   -! integrator on the subranges. if possible,
1702   -! an appropriate special-purpose integrator
1703   -! should be used which is designed for
1704   -! handling the type of difficulty involved.
1705   -! 2 : the occurrence of roundoff error is
1706   -! detected, which prevents the requested
1707   -! tolerance from being achieved.
1708   -! 3 : extremely bad integrand behaviour occurs
1709   -! at some points of the integration
1710   -! interval.
1711   -! 6 : the input is invalid, because
1712   -! (epsabs.le.0 and
1713   -! epsrel.lt.max(50*rel.mach.acc.,0.5d-28))
1714   -! or limit.lt.1 or lenw.lt.limit*4.
1715   -! result, abserr, neval, last are set
1716   -! to zero.
1717   -! except when lenw is invalid, iwork(1),
1718   -! work(limit*2+1) and work(limit*3+1) are
1719   -! set to zero, work(1) is set to a and
1720   -! work(limit+1) to b.
1721   -
1722   -implicit none
1723   -double precision, external:: f
1724   -double precision, intent(in) :: x,a,b,epsabs,epsrel
1725   -integer, intent(in) :: key,limit
1726   -integer, intent(out) :: ier
1727   -double precision, intent(out) :: res,abserr
1728   -
1729   -
1730   -double precision, allocatable :: work(:)
1731   -integer, allocatable :: iwork(:)
1732   -integer :: lenw,neval,last
1733   -
1734   -! imsl value for limit is 500
1735   -lenw=limit*4
1736   -allocate(work(lenw))
1737   -allocate(iwork(limit))
1738   -
1739   -call dqag_2d_inner(f,x,a,b,epsabs,epsrel,key,res,abserr,neval,ier,limit,lenw,last,iwork,work)
1740   -
1741   -deallocate(iwork)
1742   -deallocate(work)
1743   -end subroutine
1744   -
1745   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1746   -! Include the modified quadpack files
1747   -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1748   -include "fvn_quadpack/dqag_2d_inner.f"
1749   -include "fvn_quadpack/dqk15_2d_inner.f"
1750   -include "fvn_quadpack/dqk31_2d_outer.f"
1751   -include "fvn_quadpack/d1mach.f"
1752   -include "fvn_quadpack/dqk31_2d_inner.f"
1753   -include "fvn_quadpack/dqage.f"
1754   -include "fvn_quadpack/dqk15.f"
1755   -include "fvn_quadpack/dqk21.f"
1756   -include "fvn_quadpack/dqk31.f"
1757   -include "fvn_quadpack/dqk41.f"
1758   -include "fvn_quadpack/dqk51.f"
1759   -include "fvn_quadpack/dqk61.f"
1760   -include "fvn_quadpack/dqk41_2d_outer.f"
1761   -include "fvn_quadpack/dqk41_2d_inner.f"
1762   -include "fvn_quadpack/dqag_2d_outer.f"
1763   -include "fvn_quadpack/dqpsrt.f"
1764   -include "fvn_quadpack/dqag.f"
1765   -include "fvn_quadpack/dqage_2d_outer.f"
1766   -include "fvn_quadpack/dqage_2d_inner.f"
1767   -include "fvn_quadpack/dqk51_2d_outer.f"
1768   -include "fvn_quadpack/dqk51_2d_inner.f"
1769   -include "fvn_quadpack/dqk61_2d_outer.f"
1770   -include "fvn_quadpack/dqk21_2d_outer.f"
1771   -include "fvn_quadpack/dqk61_2d_inner.f"
1772   -include "fvn_quadpack/dqk21_2d_inner.f"
1773   -include "fvn_quadpack/dqk15_2d_outer.f"
1774   -
1775   -
1776   -
1777   -
1778   -
1779   -end module fvn