c23456789
c estimates a single rotation by combining several different independent
c estimates from data sets with different kappas.
c
c Compile with dtrans,numlib,numlib2,teclib
c
program royer2
c
implicit double precision (a-h,q-z)
parameter (ndatmx=500,msect=100)
character*40 filename
real plev,df
dimension work(6),evd(3),t(3),ttot(3),uc(3),
&qhat(10,3),arot(3),ahat(4),bhat(4),chat(4),
&a(3,3),b(3,3),h(3,3),evz(3,3),v(3,3),p(10,3,3)
dimension xk(ndatmx,ndatmx),numsect(10),np(10),hkap(10),
& qhati(4),wt(2,msect,30),sigma(2,msect,3,3),
& eta(msect,3,3),axis(3),h2(3),numpts(2,msect),axm(3,3)
dimension u(2,msect,ndatmx,3),pone(ndatmx,ndatmx),
& pii(10,ndatmx,ndatmx),trpii(10),trpiisq(10),dfr(10),
& etai(msect,3,2),w(3,3)
common nsect,sigma,qhati,eta,etai,wt,npts,u
data rad/.0174532925199432958/,rfact/4.0528473E07/,
& rfact2/6366.1977/, fmin/5000./,fmax/0./
c
if=0
idet=0
nrowdone=0
ncoldone=3
nsectdone=0
do 17 i =1,ndatmx
do 17 j = 1,ndatmx
17 xk(i,j)=0.0
detmax=-1.d+10
1 write (*,1000)
1000 format ('Enter rotation file name: (=end to end) ',$)
read (*,'(a)') filename
if (filename.eq.'end') goto 10
call readrot(filename,ior,arot,a,b,h,plev,hatkap,df,ndum1)
if (ior.ne.0) goto 1
if=if+1
write (*,'(3f7.2)') (arot(i),i=1,3)
do 5 i=1,3
qhat(if,i)=arot(i)
do 5 j=1,3
5 p(if,i,j)=h(i,j)*hatkap
call detr(h,d)
d=d*hatkap
write (*,'(2i3,d12.3)') if,idet,d
c
c read data
c
1009 write(*,*)' '
write(*,1010)
1010 format(' Enter data filename ',$)
read(*,'(a)')filename
write(*,*)' '
open(10,file=filename,status='old',err=1009)
read(10,*)numsect(if)
do 20 i1=1,2
do 20 i2=nsectdone+1,nsectdone+numsect(if)
numpts(i1,i2)=0
do 20 i3=1,3
do 20 i4=1,3
20 sigma(i1,i2,i3,i4)=0.0
hkap(if)=hatkap
np(if)=ndum1
dfr(if)=np(if)-2*numsect(if)-3
if (fmin .gt. dfr(if)) fmin=dfr(if)
if (fmax .lt. dfr(if)) fmax=dfr(if)
do 100 nk = 1,np(if)
101 read(10,*,err=101)iside,isect,alat,along,sd
if (iside.gt.2) goto 101
isect=nsectdone+isect
numpts(iside,isect)=numpts(iside,isect)+1
call trans1(alat,along,axis)
wt(iside,isect,numpts(iside,isect))=1/sd
do 105 i = 1,3
105 u(iside,isect,numpts(iside,isect),i)=axis(i)
do 120 j1=1,3
do 120 j2=1,3
120 sigma(iside,isect,j1,j2)=sigma(iside,isect,j1,j2)+
& axis(j1)*axis(j2)/sd**2
100 continue
nsectdone=nsectdone+numsect(if)
close(10)
if (detmax.gt.d) goto 1
idet=if
detmax=d
goto 1
c------- calculate covariance matrix v
c
10 nsect=nsectdone
nrowx=0
do 13 i = 1,if
13 nrowx=nrowx+np(i)
ncolxk=3+2*nsect
if (nsect.gt.msect) write(*,*)'STOP! msect exceeded'
if (nrowx.gt.ndatmx)write(*,*)'STOP! ndatmx exceeded'
if ((nsect.gt.msect).or.(nrowx.gt.ndatmx)) stop
do 15 k=1,if
do 15 i=1,3
do 15 j=1,3
15 v(i,j)=v(i,j)+p(k,i,j)
call detr(v,d)
write (*,*) 'Det(v) ',d
c
call jacobi(v,3,3,evd,evz,3,work,nrot)
do 220 i=1,3
do 220 j=1,3
v(i,j)=0.
do 220 k = 1,3
220 v(i,j)=v(i,j)+evz(i,k)*evz(j,k)/evd(k)
c
c------- start main loop
c
21 do 22 i=1,3
ttot(i)=0.
22 arot(i)=qhat(idet,i)
c
25 continue
c
call trans3(arot(1),arot(2),-arot(3),ahat)
c
do 35 k=1,if
if (k.eq.idet) goto 35
c
c -- convert lat,lon,angle into quaternion bhat
c
call trans3(qhat(k,1),qhat(k,2),qhat(k,3),bhat)
c
c -- add the 2 quaternions
c
call qmult(ahat,bhat,chat)
c
c -- convert quaternion chat into lat,lon,angle
c
call trans5(chat,alat,alon,rho)
write (*,'(3f9.3)') alat,alon,rho
call trans1(alat,alon,t)
do 27 i=1,3
27 t(i)=t(i)*rho*rad
c write(*,'(3E16.8)') t
do 29 i=1,3
do 29 j=1,3
29 h(i,j)=p(k,i,j)
call rotvec(h,t,uc)
do 30 i=1,3
30 ttot(i)=ttot(i)+uc(i)
c write(*,'(3E16.8)') ttot
c
35 continue
c
c------------ end of main loop
c
call rotvec(v,ttot,t)
write(*,'(3E16.8)') t
c t converges to 0 as a-hat converges to A
rho=0.
do 40 i=1,3
40 rho=rho+t(i)*t(i)
rho=sqrt(rho)
do 42 i=1,3
42 t(i)=t(i)/rho
call trans6(t,alat,alon)
call trans3(alat,alon,rho/rad,bhat)
do 45 i=2,4
45 ahat(i)=-ahat(i)
call qmult(ahat,bhat,chat)
call trans5(chat,alat,alon,rho)
write (*,*) ' '
write (*,'(3f9.3)') alat,alon,rho
write (*,*) 'Happy with this? 1=yes 2=no'
read (*,*) ian
if (ian.eq.1) goto 50
c
idet=if+1
qhat(idet,1)=alat
qhat(idet,2)=alon
qhat(idet,3)=rho
c
goto 21
c
c set up eta vectors
c
c chat is the quaternion form of new estimate
c
50 call trans4(chat,a)
c
write(*,*)'rotation matrix'
do 51 i = 1,3
51 write(*,*)(a(i,j),j=1,3)
c
do 55 i = 1,4
55 qhati(i)=chat(i)
do 130 i = 1,3
130 h2(i)=0.
rmin=r1(h2)*rfact
c
C
nrowdone=0
nsectdone=0
ncoldone=3
do 615 nrot=1,if
nrow = 1+nrowdone
do 610 isect = 1+nsectdone, numsect(nrot)+nsectdone
do 570 k = 1,3
do 570 j = 1,3
570 axm(k,j) = 0.
do 580 k = 1,3
do 580 j = 1,3
do 580 m = 1,3
580 axm(k,j) = axm(k,j) + a(k,m)*eta(isect,j,m)
do 600 kp = 1,numpts(2,isect)
do 595 k = 1,3
do 590 j = 1,3
590 xk(nrow,k) = xk(nrow,k) + u(2,isect,kp,j)*axm(j,k)
595 xk(nrow,k) = xk(nrow,k)*wt(2,isect,kp)*rfact2
600 nrow = nrow + 1
610 continue
nr=1+nrowdone
nc = 1+ncoldone
do 650 isect = 1+nsectdone,numsect(nrot)+nsectdone
do 620 k = 1,3
do 620 j = 1,2
620 axm(k,j) = 0.
do 630 k = 1,3
do 630 j = 1,2
do 630 m = 1,3
630 axm(k,j) = axm(k,j) + a(k,m)*etai(isect,m,j)
do 645 kp = 1,numpts(2,isect)
do 640 k = 1,3
xk(nr,nc) = xk(nr,nc) + u(2,isect,kp,k)*axm(k,1)
640 xk(nr,nc+1) = xk(nr,nc+1) + u(2,isect,kp,k)*axm(k,2)
xk(nr,nc) = wt(2,isect,kp)*xk(nr,nc)*rfact2
xk(nr,nc+1) = wt(2,isect,kp)*xk(nr,nc+1)*rfact2
645 nr=nr+1
650 nc = nc + 2
nc = 1+ncoldone
do 680 isect = 1+nsectdone,numsect(nrot)+nsectdone
do 670 kp = 1,numpts(1,isect)
do 660 k = 1,3
xk(nr,nc) = xk(nr,nc) + u(1,isect,kp,k)*etai(isect,k,1)
660 xk(nr,nc+1) = xk(nr,nc+1) +
& u(1,isect,kp,k)*etai(isect,k,2)
xk(nr,nc) = xk(nr,nc)*wt(1,isect,kp)*rfact2
xk(nr,nc+1) = xk(nr,nc+1)*wt(1,isect,kp)*rfact2
670 nr=nr+1
680 nc = nc + 2
nrowdone=nrowdone+np(nrot)
nsectdone=nsectdone+numsect(nrot)
615 ncoldone=ncoldone+2*numsect(nrot)
c
c
c transform XK to S^(-1/2)*XK
c
nrowdone=0
ncoldone=3
do 510 k = 1,if
rkap=hkap(k)**.5
do 530 i = 1,np(k)
do 530 j = 1,3
530 xk(nrowdone+i,j)=rkap*xk(nrowdone+i,j)
do 520 j = ncoldone+1,ncoldone+2*numsect(k)
520 xk(nrowdone+i,j)=rkap*xk(nrowdone+i,j)
nrowdone=nrowdone+np(k)
510 ncoldone=ncoldone+2*numsect(k)
npts=nrowx
c
open(unit=15,file='sx.dat',status='unknown')
do 511 i = 1,nrowx
511 write(15,*)(xk(i,j),j=1,ncolxk)
close(15)
c
c calculate P-one
c
call projection(xk,nrowx,ncolxk,pone)
c
c
open(unit=15,file='pone.dat',status='unknown')
do 513 i = 1,nrowx
513 write(15,*)(pone(i,j),j=1,nrowx)
close(15)
c
c
c calculation of correction terms A and C
c
nrow=0
do 710 k=1,if
do 700 i=1,np(k)
do 700 j = 1,np(k)
700 pii(k,i,j)=pone(i+nrow,j+nrow)
710 nrow=nrow+np(k)
do 730 k=1,if
trpii(k)=0.
trpiisq(k)=0.
do 730 i = 1,np(k)
trpii(k)=trpii(k)+pii(k,i,i)
do 730 j = 1,np(k)
730 trpiisq(k)=trpiisq(k) + pii(k,i,j)*pii(k,j,i)
capa=0.
do 740 k = 1,if
740 capa=capa+(3+2*numsect(k)+trpiisq(k)-2*trpii(k))/dfr(k)
capc=0.
do 750 k = 1,if
750 capc=capc+(3+2*numsect(k)-trpii(k))**2/dfr(k)
capc=capc-capa
write(6,*)'A, C',capa,capc
c
c
write(*,*)' '
write(*,*)'np,nsect,trpii,trpiisq,dfr'
do 753 i = 1,if
753 write(*,*)np(i),numsect(i),trpii(i),trpiisq(i),dfr(i)
c
c calculate c and f, where Q is cF(3,f)
c
exq = 3 + 2*capa
vq = 6 + 14*capa + 2*capc
write (6,*) 'mean of Q = ', exq
write (6,*) 'variance of Q = ', vq
ex2 = exq*exq
write (6,*)
df = (12*vq + 2*ex2)/(3*vq - 2*ex2)
cfact = exq*(1 - 2/df)
write (6,*) 'deg. freedom ', df
write (6,*) ' c = ',cfact
c write(6,*)'enter plev'
c read(6,*) plev
plev = .95
call xidf(plev,3.0,df,xf,ier)
cxf = cfact*xf
write(6,*)'xf, critical value= c*f(3,df) :',xf,cxf
write(6,*)' '
write(6,*)' '
c
c
c adjust hatkapc for use in conreg.f
HATKAPC = 1./cfact
C
c calculate the inverse of covariance matrix H11.2
call inv(v,w)
write (*,*) ' rotation:'
write (*,*) ' '
write (*,*) 'Latitude, longitude, angle'
write (*,'(3x,3f8.2)') alat,alon,rho
write (*,*) 'Rotation matrix'
do 56 i=1,3
56 write (*,*) (a(i,j),j=1,3)
write (*,*) 'Covariance matrix'
do 60 i=1,3
60 write (*,*) (v(i,j),j=1,3)
c
65 write(*,1065)
1065 format(/,' Enter name of the output file: ',$)
read(*,'(a)') filename
open(unit=15,file=filename,status='unknown',err=65)
write(*,'(a)') filename
write(15,*)' results from combining estimates'
write(15,*)' '
write(15,*) 'Fitted rotation--alat,along,rho: '
write(15,*) alat,alon,rho
write(15,*)'plev'
write(15,*) plev,1.0,1.0
c flag = 1 is output for use by the program addplus.f
write(15,*) '1/cfact, degrees of freedom, crit. value, flag'
write(15,1066) hatkapc,df,cxf,1.0
1066 format(f12.6,2x,f10.4,2x,f12.4,2x,f4.1)
write(15,*) 'Number of points, fmin, fmax, rank'
write(15,*) nrowx,fmin,fmax,ncolxk
write(15,*) 'ahat: '
do 70 i=1,3
70 write(15,*) (a(i,j),j=1,3)
write(15,*) 'covariance matrix'
do 75 i=1,3
75 write(15,*) (v(i,j),j=1,3)
write(15,*) 'H11.2 matrix: '
do 80 i=1,3
80 write(15,*) (w(i,j),j=1,3)
close (15)
stop
end
c************** readrot.f **********************************************
c subroutine to read a rotation file, with covariance matrix, kappahat ...
c
c input data file: file code 11
c
c 1. best fit rotation (ahat) in form: alat, along, rho
c
c 2. covariance matrix (except for division by kappahat) of ahat
c
c 3. kappahat (or kappa) and degrees of freedom
c
c 4. matrix h11.2
c
c234567
subroutine readrot(filname,ior,alat,alon,rho,ahat,b,h,plev,hatkap,
& df,ndum1)
c
implicit double precision(a-h,o-z)
real plev,df
character filname*40,dumline*40
dimension ahat(3,3),b(3,3),h(3,3)
1000 format (a)
c
ior=0
open(11,file=filname,status='old',err=20)
c
c read 2 first comment lines
c
read(11,1000) dumline
read(11,1000) dumline
c
c read bestfit rotation: alat,alon and angle
c
read(11,1000) dumline
read(11,*) alat,alon,rho
call trans7(alat,alon,rho,ahat)
c
c read confidence level
c
read(11,1000) dumline
read(11,*) plev
c
c read hatkap and degrees of freedom
c
read(11,1000) dumline
read(11,*) hatkap,df
c
c read nbr of points, sections
c
read(11,1000) dumline
read(11,*) dumline
c
c read rotation matrix
c
read(11,1000) dumline
do 5 i=1,3
5 read (11,*) dum1
c
c read covariance matrix
c
read(11,1000) dumline
do 10 i=1,3
10 read(11,*) (b(i,j),j=1,3)
c
c read inverse of covariance matrix: H11.2
c
read(11,1000) dumline
do 15 i=1,3
15 read(11,*) (h(i,j),j=1,3)
c
close(11)
c
return
20 write (*,'(a)') 'Trouble opening filename: ',filname
ior=1
return
end
c=================================================================
c234567
subroutine rotvec(a,x,y)
c
c a*x=y
c
double precision a,x,y
dimension a(3,3),x(3),y(3)
do 1 i=1,3
y(i)=0.
do 1 j=1,3
1 y(i)=y(i)+a(i,j)*x(j)
return
end
c=================================================================
c234567
subroutine detr(a,d)
c
c calculate determinant of a
c
double precision a,d
dimension a(3,3)
d=a(1,1)*(a(2,2)*a(3,3)-a(3,2)*a(2,3))-
& a(1,2)*(a(2,1)*a(3,3)-a(3,1)*a(2,3))+
& a(1,3)*(a(2,1)*a(3,2)-a(2,2)*a(3,1))
return
end
C
C
FUNCTION R1(HR)
IMPLICIT DOUBLE PRECISION(A-H,O-Z)
PARAMETER (MSECT=100)
integer nsect
DIMENSION HR(3),SIGMA(2,MSECT,3,3),QHATI(4),ETA(MSECT,3,3),
& ETAI(MSECT,3,2),AHAT(3,3),SIG(3,3),D(3),Z(3,3),WK(6),QHAT(4)
COMMON NSECT,SIGMA,QHATI,ETA,ETAI
C
CALL TRANS2(HR,QHATI,QHAT)
CALL TRANS4(QHAT,AHAT)
R1=0.
DO 100 I=1,NSECT
DO 110 J=1,3
DO 110 K=1,3
SIG(J,K)=SIGMA(1,I,J,K)
DO 110 K1=1,3
DO 110 K2=1,3
110 SIG(J,K)=SIG(J,K)+AHAT(K1,J)*SIGMA(2,I,K1,K2)*AHAT(K2,K)
CALL JACOBI(SIG,3,3,D,Z,3,WK,NROT)
IF (NROT.LT.0) WRITE(6,*) 'SUBROUTINE JACOBI(3)--NROT: ',NROT
ETA(I,1,1)=0.
ETA(I,2,1)=Z(3,1)
ETA(I,3,1)=-Z(2,1)
ETA(I,1,2)=-Z(3,1)
ETA(I,2,2)=0.
ETA(I,3,2)=Z(1,1)
ETA(I,1,3)=Z(2,1)
ETA(I,2,3)=-Z(1,1)
ETA(I,3,3)=0.
IF (ABS(Z(3,1)).GT.(.2)) THEN
DO 120 J=1,3
ETAI(I,J,1)=ETA(I,J,1)
120 ETAI(I,J,2)=ETA(I,J,2)
ELSE IF (ABS(Z(1,1)).GT.(.2)) THEN
DO 125 J=1,3
ETAI(I,J,1)=ETA(I,J,2)
125 ETAI(I,J,2)=ETA(I,J,3)
ELSE
DO 130 J=1,3
ETAI(I,J,1)=ETA(I,J,1)
130 ETAI(I,J,2)=ETA(I,J,3)
ENDIF
100 R1=R1+D(1)
RETURN
END
C