105 interface ctoz;
module procedure ctoz; end
interface 118 function absv_s(a)
result(s)
120 real(sp),
dimension(:),
intent(in):: a
122 s=sqrt(dot_product(a,a))
130 function absv_d(a)
result(s)
132 real(dp),
dimension(:),
intent(in):: a
134 s=sqrt(dot_product(a,a))
143 use pietc_s,
only: u0
145 real(sp),
dimension(:),
intent(IN):: a
146 real(sp),
dimension(size(a)) :: b
148 s=
absv_s(a);
if(s==u0)then; b=u0;else;b=a/s;
endif 159 real(dp),
dimension(:),
intent(IN):: a
160 real(dp),
dimension(size(a)) :: b
162 s=
absv_d(a);
if(s==
u0)then; b=
u0;else;b=a/s;
endif 173 real(sp),
dimension(:),
intent(in):: u,a
174 real(sp),
dimension(size(u)) :: b
177 s=dot_product(u,a); b=a-u*s
188 real(dp),
dimension(:),
intent(in):: u,a
189 real(dp),
dimension(size(u)) :: b
192 s=dot_product(u,a); b=a-u*s
203 real(sp),
dimension(3),
intent(in):: a,b
204 real(sp),
dimension(3) :: c
205 c(1)=a(2)*b(3)-a(3)*b(2); c(2)=a(3)*b(1)-a(1)*b(3); c(3)=a(1)*b(2)-a(2)*b(1)
216 real(dp),
dimension(3),
intent(in):: a,b
217 real(dp),
dimension(3) :: c
218 c(1)=a(2)*b(3)-a(3)*b(2); c(2)=a(3)*b(1)-a(1)*b(3); c(3)=a(1)*b(2)-a(2)*b(1)
233 real(sp),
dimension(4),
intent(in ):: u,v,w
234 real(sp),
dimension(4) :: x
235 real(sp):: uv12,uv13,uv14,uv23,uv24,uv34
236 uv12=u(1)*v(2)-u(2)*v(1); uv13=u(1)*v(3)-u(3)*v(1); uv14=u(1)*v(4)-u(4)*v(1)
237 uv23=u(2)*v(3)-u(3)*v(2); uv24=u(2)*v(4)-u(4)*v(2)
238 uv34=u(3)*v(4)-u(4)*v(3)
239 x(1)=-uv23*w(4)+uv24*w(3)-uv34*w(2)
240 x(2)= uv13*w(4)-uv14*w(3) +uv34*w(1)
241 x(3)=-uv12*w(4) +uv14*w(2)-uv24*w(1)
242 x(4)= uv12*w(3)-uv13*w(2)+uv23*w(1)
254 real(dp),
dimension(4),
intent(in ):: u,v,w
255 real(dp),
dimension(4) :: x
256 real(dp):: uv12,uv13,uv14,uv23,uv24,uv34
257 uv12=u(1)*v(2)-u(2)*v(1); uv13=u(1)*v(3)-u(3)*v(1); uv14=u(1)*v(4)-u(4)*v(1)
258 uv23=u(2)*v(3)-u(3)*v(2); uv24=u(2)*v(4)-u(4)*v(2)
259 uv34=u(3)*v(4)-u(4)*v(3)
260 x(1)=-uv23*w(4)+uv24*w(3)-uv34*w(2)
261 x(2)= uv13*w(4)-uv14*w(3) +uv34*w(1)
262 x(3)=-uv12*w(4) +uv14*w(2)-uv24*w(1)
263 x(4)= uv12*w(3)-uv13*w(2)+uv23*w(1)
274 real(sp),
dimension(:),
intent(in ):: a
275 real(sp),
dimension(:),
intent(in ):: b
276 real(sp),
DIMENSION(size(a),size(b)):: c
279 do i=1,nb; c(:,i)=a*b(i);
enddo 290 real(dp),
dimension(:),
intent(in ):: a
291 real(dp),
dimension(:),
intent(in ):: b
292 real(dp),
dimension(size(a),size(b)):: c
295 do i=1,nb; c(:,i)=a*b(i);
enddo 306 integer(spi),
dimension(:),
intent(in ):: a
307 integer(spi),
dimension(:),
intent(in ):: b
308 integer(spi),
dimension(size(a),size(b)):: c
311 do i=1,nb; c(:,i)=a*b(i);
enddo 323 real(sp),
dimension(3),
intent(IN ):: a,b,c
324 real(sp) :: tripleproduct
337 real(dp),
dimension(3),
intent(IN ):: a,b,c
338 real(dp) :: tripleproduct
347 function det_s(a)
result(det)
348 use pietc_s,
only: u0
350 real(sp),
dimension(:,:),
intent(IN ) :: a
352 real(sp),
dimension(size(a,1),size(a,1)):: b
353 integer(spi) :: n,nrank
368 function det_d(a)
result(det)
371 real(dp),
dimension(:,:),
intent(IN ) :: a
373 real(dp),
dimension(size(a,1),size(a,1)):: b
374 integer(spi) :: n,nrank
389 function det_i(a)
result(idet)
391 integer(spi),
dimension(:,:),
intent(IN ):: a
393 real(dp),
dimension(size(a,1),size(a,2)):: b
395 b=a; bdet=
det(b); idet=nint(bdet)
403 function det_id(a)
result(idet)
406 integer(dpi),
dimension(:,:),
intent(IN ):: a
408 real(dp),
dimension(size(a,1),size(a,2)) :: b
410 b=a; bdet=
det(b); idet=nint(bdet)
420 use pietc_s,
only: u0
422 real(sp),
dimension(3),
intent(IN ):: a
423 real(sp),
dimension(3,3) :: b
424 b=u0;b(3,2)=a(1);b(1,3)=a(2);b(2,1)=a(3);b(2,3)=-a(1);b(3,1)=-a(2);b(1,2)=-a(3)
436 real(dp),
dimension(3),
intent(IN ):: a
437 real(dp),
dimension(3,3) :: b
438 b=
u0;b(3,2)=a(1);b(1,3)=a(2);b(2,1)=a(3);b(2,3)=-a(1);b(3,1)=-a(2);b(1,2)=-a(3)
448 use pietc_s,
only: o2
450 real(sp),
dimension(3,3),
intent(IN ):: b
451 real(sp),
dimension(3) :: a
452 a(1)=(b(3,2)-b(2,3))*o2; a(2)=(b(1,3)-b(3,1))*o2; a(3)=(b(2,1)-b(1,2))*o2
464 real(dp),
dimension(3,3),
intent(IN ):: b
465 real(dp),
dimension(3) :: a
466 a(1)=(b(3,2)-b(2,3))*
o2; a(2)=(b(1,3)-b(3,1))*
o2; a(3)=(b(2,1)-b(1,2))*
o2 478 real(sp),
dimension(:),
intent(IN ) :: a
479 real(sp),
dimension(size(a),size(a)):: b
482 b=
u0;
do i=1,n; b(i,i)=a(i);
enddo 494 real(dp),
dimension(:),
intent(IN ) :: a
495 real(dp),
dimension(size(a),size(a)):: b
498 b=
u0;
do i=1,n; b(i,i)=a(i);
enddo 509 integer(spi),
dimension(:),
intent(IN ) :: a
510 integer(spi),
dimension(size(a),size(a)):: b
513 b=0;
do i=1,n; b(i,i)=a(i);
enddo 524 real(sp),
dimension(:,:),
intent(IN ):: b
525 real(sp),
dimension(size(b,1)) :: a
528 do i=1,n; a(i)=b(i,i);
enddo 539 real(dp),
dimension(:,:),
intent(IN ):: b
540 real(dp),
dimension(size(b,1)) :: a
543 do i=1,n; a(i)=b(i,i);
enddo 554 integer(spi),
dimension(:,:),
intent(IN ):: b
555 integer(spi),
dimension(size(b,1)) :: a
558 do i=1,n; a(i)=b(i,i);
enddo 568 real(sp),
dimension(:,:),
intent(IN ):: b
580 real(dp),
dimension(:,:),
intent(IN ):: b
592 integer(spi),
dimension(:,:),
intent(IN ):: b
604 integer(spi),
intent(IN ) :: n
605 integer(spi),
dimension(n,n):: a
607 a=0;
do i=1,n; a(i,i)=1;
enddo 616 integer(spi),
dimension(3,3):: a
618 a=0;
do i=1,3; a(i,i)=1;
enddo 629 function huarea_s(sa,sb)
result(area)
631 real(sp),
intent(IN ):: sa,sb
636 area=asin(sa*sb/(1+ca*cb))
647 function huarea_d(sa,sb)
result(area)
649 real(dp),
intent(IN ):: sa,sb
654 area=asin(sa*sb/(1+ca*cb))
667 function sarea_s(v1,v2,v3)
result(area)
668 use pietc_s,
only: zero=>u0
670 real(sp),
dimension(3),
intent(IN ):: v1,v2,v3
672 real(sp) :: s123,a1,a2,b,d1,d2,d3
673 real(sp),
dimension(3) :: u0,u1,u2,u3,x,y
679 d1=dot_product(u3-u2,u3-u2)
680 d2=dot_product(u1-u3,u1-u3)
681 d3=dot_product(u2-u1,u2-u1)
684 if(d3<d1 .or. d3<d2)
call cyclic(u1,u2,u3,d1,d2,d3)
685 if(d3<d1 .or. d3<d2)
call cyclic(u1,u2,u3,d1,d2,d3)
690 a1=-dot_product(x,u1-u0); a2= dot_product(x,u2-u0)
704 subroutine cyclic(u1,u2,u3,d1,d2,d3)
706 real(sp),
dimension(3),
intent(INOUT):: u1,u2,u3
707 real(sp),
intent(INOUT):: d1,d2,d3
708 real(sp),
dimension(3) :: ut
710 dt=d1; d1=d2; d2=d3; d3=dt
711 ut=u1; u1=u2; u2=u3; u3=ut
722 function sarea_d(v1,v2,v3)
result(area)
725 real(dp),
dimension(3),
intent(IN ):: v1,v2,v3
727 real(dp) :: s123,a1,a2,b,d1,d2,d3
728 real(dp),
dimension(3) ::
u0,u1,u2,u3,x,y
734 d1=dot_product(u3-u2,u3-u2)
735 d2=dot_product(u1-u3,u1-u3)
736 d3=dot_product(u2-u1,u2-u1)
739 if(d3<d1 .or. d3<d2)
call cyclic(u1,u2,u3,d1,d2,d3)
740 if(d3<d1 .or. d3<d2)
call cyclic(u1,u2,u3,d1,d2,d3)
745 a1=-dot_product(x,u1-
u0); a2= dot_product(x,u2-
u0)
759 subroutine cyclic(u1,u2,u3,d1,d2,d3)
761 real(dp),
dimension(3),
intent(INOUT):: u1,u2,u3
762 real(dp),
intent(INOUT):: d1,d2,d3
763 real(dp),
dimension(3) :: ut
765 dt=d1; d1=d2; d2=d3; d3=dt
766 ut=u1; u1=u2; u2=u3; u3=ut
785 function dtarea_s(rlat,drlata,drlona,drlatb,drlonb)
result(area)
786 use pietc_s,
only: u0,u1
788 real(sp),
intent(in ):: rlat,drlata,drlona,drlatb,drlonb
790 real(sp),
dimension(2):: x2a,x2b,xb,yb
791 real(sp) :: sb,ssb,cb,xa,sa,ca,sc,cc
792 call dlltoxy(rlat,drlata,drlona,x2a)
793 call dlltoxy(rlat,drlatb,drlonb,x2b)
794 ssb=dot_product(x2b,x2b); sb=sqrt(ssb)
795 if(sb==u0)then; area=u0; return;
endif 800 xa=dot_product(xb,x2a)
801 sa=dot_product(yb,x2a)
824 function dtarea_d(rlat,drlata,drlona,drlatb,drlonb)
result(area)
827 real(dp),
intent(in ):: rlat,drlata,drlona,drlatb,drlonb
829 real(dp),
dimension(2):: x2a,x2b,xb,yb
830 real(dp) :: sb,ssb,cb,xa,sa,ca,sc,cc
831 call dlltoxy(rlat,drlata,drlona,x2a)
832 call dlltoxy(rlat,drlatb,drlonb,x2b)
833 ssb=dot_product(x2b,x2b); sb=sqrt(ssb)
834 if(sb==
u0)then; area=
u0; return;
endif 839 xa=dot_product(xb,x2a)
840 sa=dot_product(yb,x2a)
868 (rlat,drlata,drlona,drlatb,drlonb,drlatc,drlonc) result(area)
870 real(sp),
intent(in ):: rlat,drlata,drlona,drlatb,drlonb,drlatc,drlonc
872 area=
sarea(rlat,drlata,drlona,drlatb,drlonb)&
873 -
sarea(rlat,drlatc,drlonc,drlatb,drlonb)
897 (rlat,drlata,drlona,drlatb,drlonb,drlatc,drlonc) result(area)
899 real(dp),
intent(in ):: rlat,drlata,drlona,drlatb,drlonb,drlatc,drlonc
901 area=
sarea(rlat,drlata,drlona,drlatb,drlonb)&
902 -
sarea(rlat,drlatc,drlonc,drlatb,drlonb)
915 subroutine dlltoxy_s(rlat,drlat,drlon,x2)
916 use pietc_s,
only: u2
918 real(sp),
intent(in ):: rlat,drlat,drlon
919 real(sp),
dimension(2),
intent(out):: x2
921 clata=cos(rlat+drlat)
922 x2=(/clata*sin(drlon),sin(drlat)+u2*sin(rlat)*clata*
hav(drlon)/)
935 subroutine dlltoxy_d(rlat,drlat,drlon,x2)
938 real(dp),
intent(in ):: rlat,drlat,drlon
939 real(dp),
dimension(2),
intent(out):: x2
941 clata=cos(rlat+drlat)
942 x2=(/clata*sin(drlon),sin(drlat)+
u2*sin(rlat)*clata*
hav(drlon)/)
950 function hav_s(t)
result(a)
951 use pietc_s,
only: o2
953 real(sp),
intent(in )::
t 963 function hav_d(t)
result(a)
966 real(dp),
intent(in ):: t
976 use pietc_s,
only: u0,u1
978 real(sp),
dimension(:),
intent(inout):: v
980 s=
absv(v);
if(s==0)then; v=u0; v(1)=u1; else; v=v/s;
endif 990 real(dp),
dimension(:),
intent(inout):: v
992 s=
absv(v);
if(s==
u0)then; v=0; v(1)=
u1; else; v=v/s;
endif 1006 subroutine gram_s(as,b,nrank,det)
1007 use pietc_s,
only: u0,u1
1009 real(sp),
dimension(:,:),
intent(IN ) :: as
1010 real(sp),
dimension(:,:),
intent(OUT) :: b
1011 integer(spi),
intent(OUT) :: nrank
1012 real(sp),
intent(OUT) :: det
1013 real(sp),
parameter :: crit=1.e-5_sp
1014 real(sp),
dimension(size(as,1),size(as,2)):: a
1015 real(sp),
dimension(size(as,2),size(as,1)):: ab
1016 real(sp),
dimension(size(as,1)) :: tv,w
1017 real(sp) :: val,s,vcrit
1018 integer(spi) :: i,j,k,l,m,n
1019 integer(spi),
dimension(2) :: ii
1022 if(n/=
size(b,1) .or. n/=
size(b,2))stop
'In gram; incompatible dimensions' 1035 ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
1036 ii =maxloc( abs( ab(k:m,k:n)) )+k-1
1037 val=maxval( abs( ab(k:m,k:n)) )
1050 w(k:n)=matmul( transpose(b(:,k:n)),tv )
1051 b(:,k)=matmul(b(:,k:n),w(k:n) )
1052 s=dot_product(b(:,k),b(:,k))
1059 s=dot_product(b(:,l),b(:,j))
1077 subroutine gram_d(as,b,nrank,det)
1080 real(dp),
dimension(:,:),
intent(IN ) :: as
1081 real(dp),
dimension(:,:),
intent(OUT) :: b
1082 integer(spi),
intent(OUT) :: nrank
1083 real(dp),
intent(OUT) :: det
1084 real(dp),
parameter :: crit=1.e-9_dp
1085 real(dp),
dimension(size(as,1),size(as,2)):: a
1086 real(dp),
dimension(size(as,2),size(as,1)):: ab
1087 real(dp),
dimension(size(as,1)) :: tv,w
1088 real(dp) :: val,s,vcrit
1089 integer(spi) :: i,j,k,l,m,n
1090 integer(spi),
dimension(2) :: ii
1093 if(n/=
size(b,1) .or. n/=
size(b,2))stop
'In gram; incompatible dimensions' 1106 ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
1107 ii =maxloc( abs( ab(k:m,k:n)) )+k-1
1108 val=maxval( abs( ab(k:m,k:n)) )
1121 w(k:n)=matmul( transpose(b(:,k:n)),tv )
1122 b(:,k)=matmul(b(:,k:n),w(k:n) )
1123 s=dot_product(b(:,k),b(:,k))
1130 s=dot_product(b(:,l),b(:,j))
1149 subroutine graml_d(as,b,nrank,detsign,ldet)
1152 real(dp),
dimension(:,:),
intent(IN ) :: as
1153 real(dp),
dimension(:,:),
intent(OUT) :: b
1154 integer(spi),
intent(OUT) :: nrank
1155 integer(spi),
intent(out) :: detsign
1156 real(dp),
intent(OUT) :: ldet
1157 real(dp),
parameter :: crit=1.e-9_dp
1158 real(dp),
dimension(size(as,1),size(as,2)):: a
1159 real(dp),
dimension(size(as,2),size(as,1)):: ab
1160 real(dp),
dimension(size(as,1)) :: tv,w
1161 real(dp) :: val,s,vcrit
1162 integer(spi) :: i,j,k,l,m,n
1163 integer(spi),
dimension(2) :: ii
1167 if(n/=
size(b,1) .or. n/=
size(b,2))stop
'In gram; incompatible dimensions' 1180 ab(k:m,k:n)=matmul( transpose(a(:,k:m)),b(:,k:n) )
1181 ii =maxloc( abs( ab(k:m,k:n)) )+k-1
1182 val=maxval( abs( ab(k:m,k:n)) )
1195 w(k:n)=matmul( transpose(b(:,k:n)),tv )
1196 b(:,k)=matmul(b(:,k:n),w(k:n) )
1197 s=dot_product(b(:,k),b(:,k))
1212 s=dot_product(b(:,l),b(:,j))
1227 use pietc_s,
only: u0
1229 real(sp),
dimension(:,:),
intent(INOUT) :: b
1230 integer(spi),
intent( OUT) :: nrank
1231 real(sp),
parameter :: crit=1.e-5_sp
1232 real(sp) :: val,vcrit
1233 integer(spi) :: j,k,n
1234 n=
size(b,1);
if(n/=
size(b,2))stop
'In gram; matrix needs to be square' 1243 val=sqrt(dot_product(b(:,k),b(:,k)))
1251 b(:,j)=b(:,j)-b(:,k)*dot_product(b(:,k),b(:,j))
1265 real(dp),
dimension(:,:),
intent(INOUT):: b
1266 integer(spi),
intent( OUT):: nrank
1267 real(dp),
parameter:: crit=1.e-9_dp
1268 real(dp) :: val,vcrit
1269 integer(spi) :: j,k,n
1270 n=
size(b,1);
if(n/=
size(b,2))stop
'In gram; matrix needs to be square' 1279 val=sqrt(dot_product(b(:,k),b(:,k)))
1287 b(:,j)=b(:,j)-b(:,k)*dot_product(b(:,k),b(:,j))
1314 subroutine rowgram(m,n,a,ipiv,tt,b,rank)
1317 integer(spi),
intent(IN ):: m,n
1318 real(dp),
dimension(m,n),
intent(in ):: a
1319 integer(spi),
dimension(n),
intent(out):: ipiv
1320 real(dp),
dimension(m,n),
intent(out):: tt
1321 real(dp),
dimension(n,n),
intent(out):: b
1322 integer(spi),
intent(out):: rank
1323 real(dp),
parameter :: eps=1.e-13_dp,epss=eps**2
1324 real(dp),
dimension(m,n) :: aa
1325 real(dp),
dimension(n) :: rowv
1326 real(dp),
dimension(m) :: p
1327 real(dp) :: maxp,nepss
1328 integer(spi),
dimension(1):: jloc
1329 integer(spi) :: i,ii,iii,j,maxi
1330 if(m<n)stop
'In rowgram; this routines needs m>=n please' 1342 p(i)=dot_product(aa(i,:),aa(i,:))
1350 b(1:ii-1,:)=aa(1:ii-1,:)
1355 rowv(j)=maxval(abs(b(1:iii-1,j)))
1361 maxp=dot_product(b(i,:),b(iii,:))
1362 b(iii,:)=b(iii,:)-b(i,:)*maxp
1364 maxp=sqrt(dot_product(b(iii,:),b(iii,:)))
1365 b(iii,:)=b(iii,:)/maxp
1373 aa(ii, :)=aa(maxi,:)
1378 aa(ii,:)=aa(ii,:)/maxp
1381 maxp=dot_product(aa(ii,:),aa(i,:))
1383 aa(i,:)=aa(i,:)-aa(ii,:)*maxp
1399 subroutine rowops(m,n,ipiv,tt,v,vv)
1401 integer(spi),
intent(in ):: m,n
1402 integer(spi),
dimension(n),
intent(in ):: ipiv
1403 real(dp),
dimension(m,n),
intent(in ):: tt
1404 real(dp),
dimension(m),
intent(in ):: v
1405 real(dp),
dimension(m),
intent(out):: vv
1406 integer(spi):: i,j,k
1418 vv(i)=vv(i)-vv(j)*tt(i,j)
1440 subroutine corral(m,n,mask,a,d,aa,e)
1444 integer(spi),
intent(in ):: m,n
1445 logical,
dimension(m,n),
intent(in ):: mask
1446 real(dp),
dimension(m,n),
intent(in ):: a
1447 real(dp),
dimension(m ),
intent(out):: d
1448 real(dp),
dimension(m,n),
intent(out):: aa
1449 real(dp),
dimension( n),
intent(out):: e
1450 real(dp),
dimension(0:m+n,0:m+n):: g
1451 real(dp),
dimension(0:m+n) :: h
1452 integer(spi) :: i,j,k,nh
1457 if(mask(i,j))aa(i,j)=log(abs(a(i,j)))
1503 aa(i,j)=a(i,j)/(d(i)*e(j))
1517 subroutine rottoax(orth33,ax3)
1519 real(dp),
dimension(3,3),
intent(in ):: orth33
1520 real(dp),
dimension(3),
intent(out):: ax3
1521 real(dp),
dimension(3,3) :: plane
1522 real(dp),
dimension(3) :: x,y,z
1524 integer(spi),
dimension(1):: ii
1525 integer(spi) :: i,j,k
1527 do i=1,3; z(i)=dot_product(plane(:,i),plane(:,i));
enddo 1529 k=ii(1); i=1+mod(k,3); j=1+mod(i,3)
1531 s=
absv(ax3);
if(s==0)
return 1537 ax3=ax3*atan2(dot_product(y,z),dot_product(x,z))
1547 subroutine axtorot(ax3,orth33)
1549 real(dp),
dimension(3),
intent(in ):: ax3
1550 real(dp),
dimension(3,3),
intent(out):: orth33
1551 real(dp),
dimension(3,3):: ax33
1563 complex(dpc),
dimension(2,2),
intent(IN ):: cspin
1564 real(dp),
dimension(0:3),
intent(OUT):: q
1565 q(0)=
real(cspin(1,1)); q(3)=aimag(cspin(1,1))
1566 q(2)=
real(cspin(2,1)); q(1)=aimag(cspin(2,1))
1576 real(dp),
dimension(0:3),
intent(IN ):: q
1577 complex(dpc),
dimension(2,2),
intent(OUT):: cspin
1578 cspin(1,1)=cmplx( q(0), q(3))
1579 cspin(2,1)=cmplx( q(2), q(1))
1580 cspin(1,2)=cmplx(-q(2), q(1))
1581 cspin(2,2)=cmplx( q(0),-q(3))
1592 real(dp),
dimension(3,3),
intent(IN ):: rot
1593 real(dp),
dimension(0:3),
intent(OUT):: q
1594 real(dp),
dimension(3,3) :: t1,t2
1595 real(dp),
dimension(3) ::
u1,
u2 1596 real(dp) :: gamma,gammah,s,ss
1598 integer(spi),
dimension(1):: ii
1601 t1=rot;
do i=1,3; t1(i,i)=t1(i,i)-1;
u1(i)=dot_product(t1(i,:),t1(i,:));
enddo 1602 ii=maxloc(
u1); j=ii(1); ss=
u1(j)
1603 if(ss<1.e-16_dp)
then 1604 q=zero; q(0)=one;
return 1606 t1(j,:)=t1(j,:)/sqrt(ss)
1613 t1(i,:)=t1(i,:)-dot_product(t1(1,:),t1(i,:))*t1(1,:)
1614 u1(i)=dot_product(t1(i,:),t1(i,:))
1622 if(ss==zero)stop
'In rotov; invalid rot' 1623 if(j/=2)t1(2,:)=t1(3,:)
1624 t1(2,:)=t1(2,:)/sqrt(ss)
1626 t1(3,1)=t1(1,2)*t1(2,3)-t1(1,3)*t1(2,2)
1627 t1(3,2)=t1(1,3)*t1(2,1)-t1(1,1)*t1(2,3)
1628 t1(3,3)=t1(1,1)*t1(2,2)-t1(1,2)*t1(2,1)
1630 t2=matmul(t1,matmul(rot,transpose(t1)))
1632 gamma=atan2(t2(2,1),t2(1,1)); gammah=gamma/two
1647 real(dp),
dimension(0:3),
intent(IN ):: q
1648 real(dp),
dimension(3,3),
intent(OUT):: rot
1649 call setem(q(0),q(1),q(2),q(3),rot)
1657 subroutine axtoq(v,q)
1659 real(dp),
dimension(3),
intent(in ):: v
1660 real(dp),
dimension(0:3),
intent(out):: q
1661 real(dp),
dimension(3,3):: rot
1664 end subroutine axtoq 1671 subroutine qtoax(q,v)
1673 real(dp),
dimension(0:3),
intent(in ):: q
1674 real(dp),
dimension(3),
intent(out):: v
1675 real(dp),
dimension(3,3):: rot
1678 end subroutine qtoax 1689 subroutine setem(c,d,e,g,r)
1691 real(dp),
intent(IN ):: c,d,e,g
1692 real(dp),
dimension(3,3),
intent(OUT):: r
1693 real(dp):: cc,dd,ee,gg,de,dg,eg,dc,ec,gc
1694 cc=c*c; dd=d*d; ee=e*e; gg=g*g
1695 de=d*e; dg=d*g; eg=e*g
1696 dc=d*c; ec=e*c; gc=g*c
1697 r(1,1)=cc+dd-ee-gg; r(2,2)=cc-dd+ee-gg; r(3,3)=cc-dd-ee+gg
1698 r(2,3)=2*(eg-dc); r(3,1)=2*(dg-ec); r(1,2)=2*(de-gc)
1699 r(3,2)=2*(eg+dc); r(1,3)=2*(dg+ec); r(2,1)=2*(de+gc)
1700 end subroutine setem 1708 function mulqq(a,b)
result(c)
1710 real(dp),
dimension(0:3),
intent(IN ):: a,b
1711 real(dp),
dimension(0:3) :: c
1712 c(0)=a(0)*b(0) -a(1)*b(1) -a(2)*b(2) -a(3)*b(3)
1713 c(1)=a(0)*b(1) +a(1)*b(0) +a(2)*b(3) -a(3)*b(2)
1714 c(2)=a(0)*b(2) +a(2)*b(0) +a(3)*b(1) -a(1)*b(3)
1715 c(3)=a(0)*b(3) +a(3)*b(0) +a(1)*b(2) -a(2)*b(1)
1728 subroutine expmat(n,a,b,detb)
1731 integer(spi),
intent(IN ):: n
1732 real(dp),
dimension(n,n),
intent(IN ):: a
1733 real(dp),
dimension(n,n),
intent(OUT):: b
1734 real(dp),
intent(OUT):: detb
1735 integer(spi),
parameter :: l=5
1736 real(dp),
dimension(n,n):: c,p
1739 m=10+floor(log(
u1+maxval(abs(a)))/log(
u2))
1754 detb=
u0;
do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
1766 subroutine expmatd(n,a,b,bd,detb,detbd)
1769 integer(spi),
intent(IN ):: n
1770 real(dp),
dimension(n,n),
intent(IN ):: a
1771 real(dp),
dimension(n,n),
intent(OUT):: b
1772 real(dp),
dimension(n,n,(n*(n+1))/2),
intent(OUT):: bd
1773 real(dp),
intent(OUT):: detb
1774 real(dp),
dimension((n*(n+1))/2),
intent(OUT):: detbd
1775 integer(spi),
parameter :: L=5
1776 real(dp),
dimension(n,n) :: c,p
1777 real(dp),
dimension(n,n,(n*(n+1))/2):: pd,cd
1779 integer(spi) :: i,j,k,m,n1
1781 m=10+floor(log(
u1+maxval(abs(a)))/log(
u2))
1797 if(k/=n1)stop
'In expmatd; n1 is inconsistent with n' 1803 pd(:,:,k)=(matmul(cd(:,:,k),p)+matmul(c,pd(:,:,k)))/i
1811 bd(:,:,k)=2*bd(:,:,k)+matmul(bd(:,:,k),b)+matmul(b,bd(:,:,k))
1818 detb=
u0;
do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
1819 detbd=
u0;
do k=1,n; detbd(k)=detb;
enddo 1833 subroutine expmatdd(n,a,b,bd,bdd,detb,detbd,detbdd)
1836 integer(spi),
intent(IN ):: n
1837 real(dp),
dimension(n,n),
intent(IN ):: a
1838 real(dp),
dimension(n,n),
intent(OUT):: b
1839 real(dp),
dimension(n,n,(n*(n+1))/2),
intent(OUT):: bd
1840 real(dp),
dimension(n,n,(n*(n+1))/2,(n*(n+1))/2),
intent(OUT):: bdd
1841 real(dp),
intent(OUT):: detb
1842 real(dp),
dimension((n*(n+1))/2),
intent(OUT):: detbd
1843 real(dp),
dimension((n*(n+1))/2,(n*(n+1))/2),
intent(OUT):: detbdd
1844 integer(spi),
parameter :: L=5
1845 real(dp),
dimension(n,n) :: c,p
1846 real(dp),
dimension(n,n,(n*(n+1))/2) :: pd,cd
1847 real(dp),
dimension(n,n,(n*(n+1))/2,(n*(n+1))/2):: pdd,cdd
1849 integer(spi) :: i,j,k,ki,kj,m,n1
1851 m=10+floor(log(
u1+maxval(abs(a)))/log(
u2))
1868 if(k/=n1)stop
'In expmatd; n1 is inconsistent with n' 1877 pdd(:,:,ki,kj)=(matmul(cd(:,:,ki),pd(:,:,kj)) &
1878 + matmul(cd(:,:,kj),pd(:,:,ki)) &
1879 + matmul(c,pdd(:,:,ki,kj)))/i
1883 pd(:,:,k)=(matmul(cd(:,:,k),p)+matmul(c,pd(:,:,k)))/i
1893 bdd(:,:,ki,kj)=
u2*bdd(:,:,ki,kj) &
1894 +matmul(bdd(:,:,ki,kj),b) &
1895 +matmul(bd(:,:,ki),bd(:,:,kj)) &
1896 +matmul(bd(:,:,kj),bd(:,:,ki)) &
1897 +matmul(b,bdd(:,:,ki,kj))
1901 bd(:,:,k)=2*bd(:,:,k)+matmul(bd(:,:,k),b)+matmul(b,bd(:,:,k))
1908 detb=
u0;
do i=1,n; detb=detb+a(i,i); enddo; detb=exp(detb)
1909 detbd=
u0;
do k=1,n; detbd(k)=detb;
enddo 1910 detbdd=
u0;
do ki=1,n;
do kj=1,n; detbdd(ki,kj)=detb; enddo;
enddo 1920 subroutine zntay(n,z,zn)
1923 integer(spi),
intent(IN ):: n
1924 real(dp),
intent(IN ):: z
1925 real(dp),
intent(OUT):: zn
1926 integer(spi),
parameter:: ni=100
1927 real(dp),
parameter :: eps0=1.e-16_dp
1928 integer(spi) :: i,i2,n2
1929 real(dp) :: t,eps,z2
1941 t=t*z2/(i2*(i2+n2-1))
1943 if(abs(t)<eps)
return 1945 print
'("In zntay; full complement of iterations used")' 1946 end subroutine zntay 1959 subroutine znfun(n,z,zn,znd,zndd,znddd)
1962 integer(spi),
intent(IN ):: n
1963 real(dp),
intent(IN ):: z
1964 real(dp),
intent(OUT):: zn,znd,zndd,znddd
1966 integer(spi):: i,i2p3
1971 call zntay(n+1,z,znd)
1972 call zntay(n+2,z,zndd)
1973 call zntay(n+3,z,znddd)
1979 znddd=(znd-
u3*zndd)/z2
1985 znddd=(znd-i2p3*zndd)/z2
1991 znddd=-(znd-
u3*zndd)/z2
1997 znddd=-(znd-i2p3*zndd)/z2
2001 end subroutine znfun 2026 subroutine ctoz(v, z,infz)
2029 real(dp),
dimension(3),
intent(IN ):: v
2030 complex(dpc),
intent(OUT):: z
2031 logical,
intent(OUT):: infz
2034 z=cmplx(v(1),v(2),
dpc)
2039 infz=(rr==
u0);
if(infz)
return 2052 subroutine ztoc(z,infz, v)
2054 complex(dpc),
intent(IN ):: z
2055 logical,
intent(IN ):: infz
2056 real(dp),
dimension(3),
intent(OUT):: v
2057 real(dp),
parameter:: zero=0_dp,one=1_dp,two=2_dp
2058 real(dp) :: r,q,rs,rsc,rsbi
2059 if(infz)then; v=(/zero,zero,-one/); return;
endif 2060 r=
real(z); q=aimag(z); rs=r*r+q*q
2082 subroutine ztocd(z,infz, v,vd)
2084 complex(dpc),
intent(IN ):: z
2085 logical,
intent(IN ):: infz
2086 real(dp),
dimension(3),
intent(OUT):: v
2087 complex(dpc),
dimension(3),
intent(OUT):: vd
2088 real(dp),
parameter :: zero=0_dp,one=1_dp,two=2_dp,four=4_dp
2089 real(dp) :: r,q,rs,rsc,rsbi,rsbis
2090 real(dp),
dimension(3):: u1,u2
2092 if(infz)then; v=(/zero,zero,-one/); return;
endif 2093 r=
real(z); q=aimag(z); rs=r*r+q*q
2100 u1(1)=two*(one+q*q-r*r)*rsbis
2101 u1(2)=-four*r*q*rsbis
2105 vd(i)=cmplx(u1(i),-u2(i),
dpc)
2107 end subroutine ztocd 2122 subroutine setmobius(xc0,xc1,xc2, aa,bb,cc,dd)
2124 real(dp),
dimension(3),
intent(IN ):: xc0,xc1,xc2
2125 complex(dpc),
intent(OUT):: aa,bb,cc,dd
2126 real(dp),
parameter:: zero=0_dp,one=1_dp
2127 logical :: infz0,infz1,infz2
2128 complex(dpc) :: z0,z1,z2,z02,z10,z21
2129 call ctoz(xc0,z0,infz0)
2130 call ctoz(xc1,z1,infz1)
2131 call ctoz(xc2,z2,infz2)
2136 if( (z0==z1.and.infz0.eqv.infz1).or.&
2137 (z1==z2.and.infz1.eqv.infz2).or.&
2138 (z2==z0.and.infz2.eqv.infz0)) &
2139 stop
'In setmobius; anchor points must be distinct' 2140 if(infz2 .or. (.not.infz0 .and. abs(z0)<abs(z2)))
then 2147 aa=sqrt(-z21/(z02*z10))
2167 cc=sqrt(-z10/(z02*z21))
2205 subroutine zsetmobius(z0,infz0, z1,infz1, z2,infz2, aa,bb,cc,dd)
2207 complex(dp),
intent(IN ):: z0,z1,z2
2208 logical,
intent(IN ):: infz0,infz1,infz2
2209 complex(dpc),
intent(OUT):: aa,bb,cc,dd
2210 real(dp),
parameter:: zero=0_dp,one=1_dp
2211 complex(dpc) :: z02,z10,z21
2215 if( (z0==z1.and.infz0.eqv.infz1).or.&
2216 (z1==z2.and.infz1.eqv.infz2).or.&
2217 (z2==z0.and.infz2.eqv.infz0)) &
2218 stop
'In setmobius; anchor points must be distinct' 2219 if(infz2 .or. (.not.infz0 .and. abs(z0)<abs(z2)))
then 2226 aa=sqrt(-z21/(z02*z10))
2246 cc=sqrt(-z10/(z02*z21))
2276 subroutine zmobius(aa,bb,cc,dd, z,infz, w,infw)
2278 complex(dpc),
intent(IN ):: aa,bb,cc,dd,z
2279 logical,
intent(IN ):: infz
2280 complex(dpc),
intent(OUT):: w
2281 logical,
intent(OUT):: infw
2282 real(dp),
parameter:: zero=0_dp
2283 complex(dpc) :: top,bot
2294 if(abs(bot)==zero)
then 2311 subroutine cmobius(aa,bb,cc,dd, vz,vw)
2313 complex(dpc),
intent(IN ):: aa,bb,cc,dd
2314 real(dp),
dimension(3),
intent(IN ):: vz
2315 real(dp),
dimension(3),
intent(OUT):: vw
2317 logical :: infz,infw
2318 call ctoz(vz, z,infz)
2319 call zmobius(aa,bb,cc,dd, z,infz, w,infw)
2320 call ztoc(w,infw, vw)
2335 subroutine zmobiusi(aa,bb,cc,dd, zz,infz, zw,infw)
2337 complex(dpc),
intent(IN ):: aa,bb,cc,dd,zz
2338 logical,
intent(IN ):: infz
2339 complex(dpc),
intent(OUT):: zw
2340 logical,
intent(OUT):: infw
2341 real(dp),
parameter:: one=1_dp
2342 complex(dpc) :: aai,bbi,cci,ddi,d
2348 call zmobius(aai,bbi,cci,ddi, zz,infz, zw,infw)
integer, parameter sp
Single precision real kind.
real(dp) function absv_d(a)
Return the absolute magnitude of a double precision real vector.
integer, parameter dp
Double precision real kind.
subroutine dlltoxy_s(rlat, drlat, drlon, x2)
From a reference latitude, and increments of latitude and longitude, return the local cartesian 2-vec...
real(sp) function huarea_s(sa, sb)
Spherical area of right-angle triangle whose orthogonal sides have orthographic projection dimensions...
Standard integer, real, and complex single and double precision kinds.
real(sp) function, dimension(size(a), size(b)) outer_product_s(a, b)
Return the outer product matrix of two single precision real vectors.
real(sp) function det_s(a)
Return the determinant of a single precision matrix.
real(dp) function hav_d(t)
Haversine function in double precision.
real(sp) function trace_s(b)
Return the trace of a given single precision real matrix.
real(dp) function huarea_d(sa, sb)
Spherical area of right-angle triangle whose orthogonal sides have orthographic projection dimensions...
subroutine plaingram_s(b, nrank)
A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
real(dp), parameter u0
zero
subroutine expmatdd(n, a, b, bd, bdd, detb, detbd, detbdd)
Like expmat, but for the 1st and 2nd derivatives also.
real(dp), parameter u2
two
subroutine normalize_s(v)
Normalize the given single precision real vector.
real(dp) function det_d(a)
Return the determinant of a double precision matrix.
real(dp) function, dimension(size(a), size(a)) diagn_d(a)
Return the diagonal matrix whose elements are the given vector.
real(sp) function absv_s(a)
Return the absolute magnitude of a single precision real vector.
real(sp) function dtarea_s(rlat, drlata, drlona, drlatb, drlonb)
Compute the area of the spherical triangle with a vertex at latitude rlat, and two other vertices...
integer(spi) function det_i(a)
Return the determinant of a single precision integer matrix.
real(dp) function, dimension(size(u)) orthogonalized_d(u, a)
Return the part of vector a that is orthogonal to unit vector u.
subroutine plaingram_d(b, nrank)
A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
real(dp) function trace_d(b)
Return the trace of a given double precision real matrix.
real(dp) function triple_product_d(a, b, c)
Return the triple product of three double precision real 3-vectors.
integer, parameter dpi
Double precision integer kind.
real(dp), parameter u3
three
Module for handy vector and matrix operations in Euclidean geometry.
real(dp) function, dimension(size(a)) normalized_d(a)
Return the normalized version of a double precision real vector.
subroutine normalize_d(v)
Normalize the given double precision real vector.
real(sp) function dqarea_s(rlat, drlata, drlona, drlatb, drlonb, drlatc, drlonc)
Compute the area of the spherical quadrilateral with a vertex at latitude rlat, and three other verti...
real(sp) function, dimension(size(u)) orthogonalized_s(u, a)
Return the part of vector a that is orthogonal to unit vector u.
logical, parameter t
for pain-relief in logical ops
real(sp) function, dimension(3) cross_product_s(a, b)
Return the cross product of two single precision real 3-vectors.
real(dp) function, dimension(3) cross_product_d(a, b)
Return the cross product of two double precision real 3-vectors.
real(sp) function, dimension(size(a)) normalized_s(a)
Return the normalized version of a single precision real vector.
real(dp) function, dimension(3) axial33_d(b)
Return the 3-vector corresponding to the given antisymmetric "axial vector" matrix, assuming a right-handed correspondence.
integer(spi) function, dimension(size(a), size(b)) outer_product_i(a, b)
Return the outer product matrix of two integer vectors.
subroutine zmobius(aa, bb, cc, dd, z, infz, w, infw)
Perform a complex Mobius transformation from (z,infz) to (w,infw) where the transformation coefficien...
subroutine zsetmobius(z0, infz0, z1, infz1, z2, infz2, aa, bb, cc, dd)
Find the Mobius transformation complex coefficients, aa,bb,cc,dd, with aa*dd-bb*cc=1, that takes polar stereographic point, z0 to the north pole, z1 to (lat=0,lon=0), z2 to the south pole (=complex infinity).
subroutine ztocd(z, infz, v, vd)
The convention adopted for the complex derivative is that, for a complex infinitesimal map displaceme...
real(sp) function triple_product_s(a, b, c)
Return the triple product of three single precision real 3-vectors.
real(sp) function, dimension(4) triple_cross_product_s(u, v, w)
Deliver the triple-cross-product, x, of the three 4-vectors, u, v, w, with the sign convention that o...
real(sp) function hav_s(t)
Haversine function in single precision.
subroutine rowgram(m, n, a, ipiv, tt, b, rank)
Without changing (tall) rectangular input matrix a, perform pivoted gram- Schmidt operations to ortho...
integer(spi) function, dimension(size(a), size(a)) diagn_i(a)
Return the diagonal matrix whose elements are the given vector.
real(dp), parameter u1
one
subroutine dlltoxy_d(rlat, drlat, drlon, x2)
From a reference latitude, and increments of latitude and longitude, return the local cartesian 2-vec...
integer(spi) function, dimension(3, 3) identity3_i()
Return the 3-dimensional integer identity matrix.
subroutine gram_d(as, b, nrank, det)
Apply a form of Gram-Schmidt orthogonalization process to return as many normalized orthogonal basis ...
Some of the commonly used constants (pi etc) mainly for double-precision subroutines.
real(sp) function sarea_s(v1, v2, v3)
Compute the area of the spherical triangle, {v1,v2,v3}, measured in the right-handed sense...
real(sp) function, dimension(3) axial33_s(b)
Return the 3-vector corresponding to the given antisymmetric "axial vector" matrix, assuming a right-handed correspondence.
integer, parameter spi
Single precision integer kind.
integer, parameter dpc
Double precision real kind.
subroutine expmatd(n, a, b, bd, detb, detbd)
Like expmat, but for the 1st derivatives also.
real(dp) function, dimension(size(b, 1)) diagnn_d(b)
Return the vector whose elements are the diagonal ones of a given matrix.
integer(dpi) function det_id(a)
Return the determinant of a double precision integer matrix.
subroutine cmobius(aa, bb, cc, dd, vz, vw)
Perform a complex Mobius transformation from cartesian vz to cartesian vw where the transformation co...
integer(spi) function trace_i(b)
Return the trace of a given integer matrix.
real(dp) function, dimension(4) triple_cross_product_d(u, v, w)
Return the triple_cross_product for 4-vectors.
real(dp) function, dimension(size(a), size(b)) outer_product_d(a, b)
Return the outer product matrix of two double precision real vectors.
real(dp) function sarea_d(v1, v2, v3)
Compute the area of the spherical triangle, {v1,v2,v3}.
real(sp) function, dimension(size(a), size(a)) diagn_s(a)
Return the diagonal matrix whose elements are the given vector.
integer(spi) function, dimension(n, n) identity_i(n)
Return the integer identity matrix for a given dimensionality.
real(dp) function dtarea_d(rlat, drlata, drlona, drlatb, drlonb)
Compute the area of the spherical triangle with a vertex at latitude rlat, and two other vertices...
real(dp) function dqarea_d(rlat, drlata, drlona, drlatb, drlonb, drlatc, drlonc)
Compute the area of the spherical quadrilateral with a vertex at latitude rlat, and three other verti...
real(dp), parameter o2
half
subroutine gram_s(as, b, nrank, det)
Apply a form of Gram-Schmidt orthogonalization process to return as many normalized orthogonal basis ...
subroutine zmobiusi(aa, bb, cc, dd, zz, infz, zw, infw)
Perform the inverse of the mobius transformation with coefficients, {aa,bb,cc,dd}.
subroutine cyclic(u1, u2, u3, d1, d2, d3)
Cyclically permute real vectors, u1, u2, u3, and scalars, d1, d2, d3.
integer(spi) function, dimension(size(b, 1)) diagnn_i(b)
Return the vector whose elements are the diagonal ones of a given matrix.
subroutine graml_d(as, b, nrank, detsign, ldet)
A version of gram_d where the determinant information is returned in logarithmic form (to avoid overf...
real(sp) function, dimension(size(b, 1)) diagnn_s(b)
Return the vector whose elements are the diagonal ones of a given matrix.
real(dp) function, dimension(3, 3) axial3_d(a)
Return the axial "vector", as an antisymmetric matrix, corresponding to the given 3-vector assuming a...
real(sp) function, dimension(3, 3) axial3_s(a)
Return the axial "vector", as an antisymmetric matrix, corresponding to the given 3-vector assuming a...