12 use pkind, only: spi,dp
13 use pietc, only: u0,u1,o2
18 real(dp),
dimension(2,2,2,2):: id
19 data id/u1,u0,u0,u0, u0,o2,o2,u0, u0,o2,o2,u0, u0,u0,u0,u1/
44 real(dp),
dimension(2,2),
intent(in ):: em
45 real(dp),
dimension(2,2),
intent(out):: vv,oo
46 real(dp):: a,b,c,d,e,f,g,h
47 a=em(1,1); b=em(1,2); c=em(2,2)
49 e=(a+c)*o2; f=(a-c)*o2
51 g=sqrt(b**2+(h+abs(f))**2)
52 if (g==u0)then; vv(:,1)=(/u1,u0/)
53 elseif(f> u0)then; vv(:,1)=(/h+f,b/)/g
54 else ; vv(:,1)=(/b,h-f/)/g
56 vv(:,2)=(/-vv(2,1),vv(1,1)/)
57 oo=matmul(transpose(vv),matmul(em,vv))
58 oo(1,2)=u0; oo(2,1)=u0
77 real(dp),
dimension(2,2),
intent(in ):: em
78 real(dp),
dimension(2,2),
intent(out):: vv,oo
79 real(dp),
dimension(2,2,2,2),
intent(out):: vvd,ood
80 logical,
intent(out):: ff
81 real(dp),
dimension(2,2):: emd,tt,vvr
82 real(dp) :: oodif,dtheta
84 call
eigensym2(em,vv,oo); vvr(1,:)=-vv(2,:); vvr(2,:)=vv(1,:)
85 oodif=oo(1,1)-oo(2,2); ff=oodif==u0;
if(ff)
return
94 emd(i,j)=o2; emd(j,i)=o2
96 tt=matmul(transpose(vv),matmul(emd,vv))
100 vvd(:,:,i,j)=vvr*dtheta
113 real(dp),
dimension(2,2),
intent(in ):: em
114 real(dp),
dimension(2,2),
intent(out):: z
116 z(1,1)=em(2,2); z(2,1)=-em(2,1); z(1,2)=-em(1,2); z(2,2)=em(1,1)
117 detem=em(1,1)*em(2,2)-em(2,1)*em(1,2)
133 real(dp),
dimension(2,2) ,
intent(in ):: em
134 real(dp),
dimension(2,2) ,
intent(out):: z
135 real(dp),
dimension(2,2,2,2),
intent(out):: zd
140 zd(:,:,k,l)=-matmul(matmul(z,zd(:,:,k,l)),z)
151 real(dp),
dimension(2,2),
intent(in ):: em
152 real(dp),
dimension(2,2),
intent(out):: z
153 real(dp),
dimension(2,2):: vv,oo
157 if(oo(i,i)<0)stop
'In sqrtsym2; matrix em is not non-negative'
158 oo(i,i)=sqrt(oo(i,i));
enddo
159 z=matmul(vv,matmul(oo,transpose(vv)))
178 real(dp),
dimension(2,2),
intent(in ):: x
179 real(dp),
dimension(2,2),
intent(out):: z
180 real(dp),
dimension(2,2,2,2),
intent(out):: zd
181 real(dp),
dimension(2,2):: px
182 real(dp) :: rdetx,lrdetx,htrpxs,q
183 rdetx=sqrt(x(1,1)*x(2,2)-x(1,2)*x(2,1))
186 htrpxs= ((px(1,1)+px(2,2))/2)**2
190 z=z*lrdetx; zd=zd/lrdetx
204 real(dp),
dimension(2,2),
intent(in ):: x
205 real(dp),
dimension(2,2),
intent(out):: z
206 real(dp),
dimension(2,2,2,2),
intent(out):: zd
207 real(dp),
dimension(2,2,2,2):: vvd,ood
208 real(dp),
dimension(2,2) :: vv,oo,oori,tt
212 z=u0; z(1,1)=sqrt(oo(1,1)); z(2,2)=sqrt(oo(2,2))
213 z=matmul(matmul(vv,z),transpose(vv))
214 oori=u0; oori(1,1)=u1/sqrt(oo(1,1)); oori(2,2)=u1/sqrt(oo(2,2))
217 tt=matmul(vvd(:,:,i,j),transpose(vv))
218 zd(:,:,i,j)=o2*matmul(matmul(matmul(vv,ood(:,:,i,j)),oori),transpose(vv))&
219 +matmul(tt,z)-matmul(z,tt)
237 real(dp),
dimension(2,2),
intent(in ):: x
238 real(dp),
dimension(2,2),
intent(out):: z
239 real(dp),
dimension(2,2,2,2),
intent(out):: zd
240 integer(spi),
parameter :: nit=300
241 real(dp),
parameter :: crit=1.e-17
242 real(dp),
dimension(2,2) :: r,rp,rd,rpd
244 integer(spi) :: i,j,n
245 r=x; r(1,1)=x(1,1)-1; r(2,2)=x(2,2)-1
246 z=u0; z(1,1)=u1; z(2,2)=u1
252 if(sum(abs(rp))<crit)
exit
253 c=-c*(n*2+1)/(2*(n+2))
262 zd(:,:,i,j)=zd(:,:,i,j)+c*rpd
263 rpd=matmul(rd,rp)+matmul(r,rpd)
265 if(sum(abs(rp))<crit)
exit
266 c=-c*(n*2+1)/(2*(n+2))
278 real(dp),
dimension(2,2),
intent(in ):: em
279 real(dp),
dimension(2,2),
intent(out):: expem
280 real(dp),
dimension(2,2):: vv,oo
283 do i=1,2; oo(i,i)=exp(oo(i,i));
enddo
284 expem=matmul(vv,matmul(oo,transpose(vv)))
295 real(dp),
dimension(2,2),
intent(in ):: x
296 real(dp),
dimension(2,2),
intent(out):: z
297 real(dp),
dimension(2,2,2,2),
intent(out):: zd
298 real(dp),
dimension(2,2):: px
299 real(dp) :: trxh,detpx
300 trxh=(x(1,1)+x(2,2))*o2
301 px=x;px(1,1)=x(1,1)-trxh;px(2,2)=x(2,2)-trxh
302 detpx=abs(px(1,1)*px(2,2)-px(1,2)*px(2,1))
318 real(dp),
dimension(2,2),
intent(in ):: x
319 real(dp),
dimension(2,2),
intent(out):: z
320 real(dp),
dimension(2,2,2,2),
intent(out):: zd
321 real(dp),
dimension(2,2,2,2):: vvd,ood
322 real(dp),
dimension(2,2) :: vv,oo,ooe,tt
326 z=u0; z(1,1)=exp(oo(1,1)); z(2,2)=exp(oo(2,2))
327 z=matmul(matmul(vv,z),transpose(vv))
328 ooe=u0; ooe(1,1)=exp(oo(1,1)); ooe(2,2)=exp(oo(2,2))
331 tt=matmul(vvd(:,:,i,j),transpose(vv))
332 zd(:,:,i,j)=matmul(matmul(matmul(vv,ood(:,:,i,j)),ooe),transpose(vv))&
333 +matmul(tt,z)-matmul(z,tt)
348 real(dp),
dimension(2,2),
intent(in ):: x
349 real(dp),
dimension(2,2),
intent(out):: z
350 real(dp),
dimension(2,2,2,2),
intent(out):: zd
351 integer(spi),
parameter :: nit=100
352 real(dp),
parameter :: crit=1.e-17_dp
353 real(dp),
dimension(2,2) :: xp,xd,xpd
355 integer(spi) :: i,j,n
356 z=0; z(1,1)=u1; z(2,2)=u1
362 if(sum(abs(xp))<crit)
exit
372 zd(:,:,i,j)=zd(:,:,i,j)+c*xpd
373 xpd=matmul(xd,xp)+matmul(x,xpd)
375 if(sum(abs(xpd))<crit)
exit
388 real(dp),
dimension(2,2),
intent(in ):: em
389 real(dp),
dimension(2,2),
intent(out):: logem
390 real(dp),
dimension(2,2):: vv,oo
394 if(oo(i,i)<=u0)stop
'In logsym2; matrix em is not positive definite'
397 logem=matmul(vv,matmul(oo,transpose(vv)))
411 real(dp),
dimension(2,2),
intent(in ):: x
412 real(dp),
dimension(2,2),
intent(out):: z
413 real(dp),
dimension(2,2,2,2),
intent(out):: zd
414 real(dp),
dimension(2,2):: vv,oo,d11,d12,d22,pqr,d11pqr,d12pqr,d22pqr
415 real(dp) :: c,s,cc,cs,ss,c2h,p,q,r,lp,lq,l
418 if(oo(1,1)<=u0 .or. oo(2,2)<=u0)stop
'In logsym2; matrix x is not positive definite'
419 c=vv(1,1); s=vv(1,2); cc=c*c; cs=c*s; ss=s*s; c2h=(cc-ss)*o2
420 p=u1/oo(1,1); q=u1/oo(2,2); lp=log(p); lq=log(q); oo(1,1)=-lp; oo(2,2)=-lq
421 z=matmul(vv,matmul(oo,transpose(vv)))
422 l=(lp-lq)*o2; r=sqrt(p*q)/
sinhox(l)
423 d11(1,:)=(/ cc,cs /); d11(2,:)=(/ cs,ss/)
424 d12(1,:)=(/-cs,c2h/); d12(2,:)=(/c2h,cs/)
425 d22(1,:)=(/ ss,-cs/); d22(2,:)=(/-cs,cc/)
426 pqr(1,:)=(/p,r/) ; pqr(2,:)=(/r,q/)
430 zd(:,:,1,1)=matmul(vv,matmul(d11pqr,transpose(vv)))
431 zd(:,:,1,2)=matmul(vv,matmul(d12pqr,transpose(vv)))
432 zd(:,:,2,2)=matmul(vv,matmul(d22pqr,transpose(vv)))
433 zd(:,:,2,1)=zd(:,:,1,2)
443 real(dp),
dimension(2,2,2,2),
intent(out):: em
444 real(dp),
dimension(2,2,2,2) :: id
460 real(dp),
dimension(2,2),
intent(in ):: s
461 real(dp),
dimension(2,2),
intent(out):: c
462 logical ,
intent(out):: ff
464 ff=s(1,1)<=u0;
if(ff)
return
469 ff=r<=u0;
if(ff)
return
subroutine logsym2d(x, z, zd)
General routine to evaluate the logarithm, z=log(x), and the symmetric derivative, zd = dz/dx, where x is a symmetric 2*2 positive-definite matrix.
subroutine sqrtsym2d(x, z, zd)
General routine to evaluate z=sqrt(x), and the symmetric derivative, zd = dz/dx, where x is a symmetr...
subroutine eigensym2d(em, vv, oo, vvd, ood, ff)
For a symmetric 2*2 matrix, em, return the normalized eigenvectors, vv, and the diagonal matrix of ei...
This module is for evaluating several useful real-valued functions that are not always available in F...
Standard integer, real, and complex single and double precision kinds.
A suite of routines to perform the eigen-decomposition of symmetric 2*2 matrices and to deliver basic...
Some of the commonly used constants (pi etc) mainly for double-precision subroutines.
subroutine expsym2d(x, z, zd)
Get the exp of a symmetric 2*2 matrix, and its symmetric derivative.
subroutine invsym2d(em, z, zd)
Get the inverse, z,of a 2*2 symmetric matrix, em, and its derivative, zd, with respect to symmetric v...