47 use pkind, only: spi,sp,dp,dpc
105 interface ctoz;
module procedure ctoz;
end interface
120 real(sp),
dimension(:),
intent(in):: a
122 s=sqrt(dot_product(a,a))
132 real(dp),
dimension(:),
intent(in):: a
134 s=sqrt(dot_product(a,a))
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
350 real(sp),
dimension(:,:),
intent(IN ) :: a
352 real(sp),
dimension(size(a,1),size(a,1)):: b
353 integer(spi) :: n,nrank
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)! [det]
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)
404 use pkind, only: dp,dpi
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)
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)
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
631 real(sp),
intent(IN ):: sa,sb
636 area=asin(sa*sb/(1+ca*cb))
649 real(dp),
intent(IN ):: sa,sb
654 area=asin(sa*sb/(1+ca*cb))
667 function sarea_s(v1,v2,v3)result(area)! [sarea]
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)
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)! [sarea]
723 use pietc, only: zero=>u0
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)
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)! [sarea]
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)! [sarea]
825 use pietc, only: u0,u1
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)
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)/)
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)/)
953 real(sp),
intent(in ):: t
966 real(dp),
intent(in ):: t
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
988 use pietc, only: u0,u1
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
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))
1078 use pietc, only: u0,u1
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)! [gram]
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))
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))
1315 use pietc, only: u0,u1
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)! [rowops]
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)! [corral]
1441 use pietc, only: u0,u1
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))
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))
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))
1590 use pietc, only: zero=>u0,one=>u1,two=>u2
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)
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
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
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
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)
1729 use pietc, only: u0,u1,u2,o2
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)
1767 use pietc, only: u0,u1,u2,o2
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)! [expmat]
1834 use pietc, only: u0,u1,u2,o2
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
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)! [znfun]
1960 use pietc, only: u0,u2,u3
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
2027 use pietc, only: u0,u1
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
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
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
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))
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)! [mobius]
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
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) ! [mobiusi]
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)
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 huarea_s(sa, sb)
Spherical area of right-angle triangle whose orthogonal sides have orthographic projection dimensions...
subroutine dlltoxy_d(rlat, drlat, drlon, x2)
From a reference latitude, and increments of latitude and longitude, return the local cartesian 2-vec...
real(dp) function, dimension(size(a)) normalized_d(a)
Return the normalized version of a double 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.
real(dp) function hav_d(t)
Haversine function for double precision real (for geometry on the sphere).
real(dp) function sarea_d(v1, v2, v3)
Compute the area of the spherical triangle, {v1,v2,v3}.
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...
real(dp) function, dimension(size(b, 1)) diagnn_d(b)
Return the vector whose elements are the diagonal ones of a given matrix.
real(sp) function triple_product_s(a, b, c)
Return the triple product of three single precision real 3-vectors.
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(dp) function trace_d(b)
Return the trace of a given double precision real matrix.
real(sp) function trace_s(b)
Return the trace of a given single precision real matrix.
real(dp) function det_d(a)
Return the determinant of a double precision matrix.
integer(spi) function, dimension(size(a), size(a)) diagn_i(a)
Return the diagonal matrix whose elements are the given vector.
real(sp) function hav_s(t)
Haversine function for single precision real (for geometry on the sphere).
subroutine expmatd(n, a, b, bd, detb, detbd)
Like expmat, but for the 1st derivatives also.
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(sp) function, dimension(3) axial33_s(b)
Return the 3-vector corresponding to the given antisymmetric "axial vector" matrix, assuming a right-handed correspondence.
real(dp) function, dimension(size(u)) orthogonalized_d(u, a)
Return the part of vector a that is orthogonal to unit vector u.
real(sp) function absv_s(a)
Return the absolute magnitude of a single precision real vector.
real(sp) function, dimension(size(a)) normalized_s(a)
Return the normalized version of a single precision real vector.
subroutine gram_d(as, b, nrank, det)
Apply a form of Gram-Schmidt orthogonalization process to return as many normalized orthogonal basis ...
subroutine normalize_s(v)
Normalize the given single precision real vector.
subroutine zmobiusi(aa, bb, cc, dd, zz, infz, zw, infw)
Perform the inverse of the mobius transformation with coefficients, {aa,bb,cc,dd}.
real(dp) function, dimension(size(a), size(b)) outer_product_d(a, b)
Return the outer product matrix of two double precision real vectors.
integer(spi) function, dimension(size(a), size(b)) outer_product_i(a, b)
Return the outer product matrix of two integer vectors.
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(u)) orthogonalized_s(u, a)
Return the part of vector a that is orthogonal to unit vector u.
subroutine ztocd(z, infz, v, vd)
The convention adopted for the complex derivative is that, for a complex infinitesimal map displaceme...
subroutine plaingram_d(b, nrank)
A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
subroutine normalize_d(v)
Normalize the given double precision real vector.
integer(dpi) function det_id(a)
Return the determinant of a double precision integer matrix.
Module for handy vector and matrix operations in Euclidean geometry.
real(sp) function det_s(a)
Return the determinant of a single precision matrix.
real(sp) function, dimension(size(b, 1)) diagnn_s(b)
Return the vector whose elements are the diagonal ones of a given matrix.
Standard integer, real, and complex single and double precision kinds.
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...
real(dp) function triple_product_d(a, b, c)
Return the triple product of three double precision real 3-vectors.
subroutine cmobius(aa, bb, cc, dd, vz, vw)
Perform a complex Mobius transformation from cartesian vz to cartesian vw where the transformation co...
subroutine expmatdd(n, a, b, bd, bdd, detb, detbd, detbdd)
Like expmat, but for the 1st and 2nd derivatives also.
real(sp) function, dimension(size(a), size(a)) diagn_s(a)
Return the diagonal matrix whose elements are the given vector.
integer(spi) function trace_i(b)
Return the trace of a given integer matrix.
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).
Some of the commonly used constants (pi etc) mainly for double-precision subroutines.
real(dp) function absv_d(a)
Return the absolute magnitude of a double precision real vector.
subroutine rowgram(m, n, a, ipiv, tt, b, rank)
Without changing (tall) rectangular input matrix a, perform pivoted gram- Schmidt operations to ortho...
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(dp) function, dimension(4) triple_cross_product_d(u, v, w)
Return the triple_cross_product for 4-vectors.
real(sp) function, dimension(3) cross_product_s(a, b)
Return the cross product of two single precision real 3-vectors.
subroutine plaingram_s(b, nrank)
A "plain" (unpivoted) version of Gram-Schmidt, for square matrices only.
integer(spi) function det_i(a)
Return the determinant of a single precision integer matrix.
real(dp) function, dimension(size(a), size(a)) diagn_d(a)
Return the diagonal matrix whose elements are the given vector.
subroutine dlltoxy_s(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.
integer(spi) function, dimension(n, n) identity_i(n)
Return the integer identity matrix for a given dimensionality.
integer(spi) function, dimension(size(b, 1)) diagnn_i(b)
Return the vector whose elements are the diagonal ones of a given matrix.
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(dp) function huarea_d(sa, sb)
Spherical area of right-angle triangle whose orthogonal sides have orthographic projection dimensions...
subroutine gram_s(as, b, nrank, det)
Apply a form of Gram-Schmidt orthogonalization process to return as many normalized orthogonal basis ...
real(sp) function sarea_s(v1, v2, v3)
Compute the area of the spherical triangle, {v1,v2,v3}, measured in the right-handed sense...
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...
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...
subroutine cyclic(u1, u2, u3, d1, d2, d3)
Cyclically permute real vectors, u1, u2, u3, and scalars, d1, d2, d3.
real(dp) function, dimension(3) cross_product_d(a, b)
Return the cross product of two double precision real 3-vectors.