Sire Model - 역행렬을 이용하여 해를 구하기
자료
1 1 1 28
1 2 1 19
1 3 2 25
2 1 1 30
2 3 2 21
2 3 2 30
3 2 1 21
3 1 1 27
3 3 2 25
3 2 2 19
위 자료를 sire_model.dat로 저장
자료 설명:1st column : 생년2nd column : age of dam3rd column : sire(random)4th column : observation
프로그램 소스
PROGRAM sire_model
! program name - sire_model
! programmer - Park Byoungho
! usage - sire_model < parameter_file
! purpose : read data file, construct left-hand side and right-hand side and find solution
! Date - 2009.4.15.
! update - none USE gi
IMPLICIT NONE
! data dictionary
CHARACTER(LEN = 40) :: filename ! data file name
INTEGER :: No_Of_Effects ! number of effects(including sire effect)
INTEGER, ALLOCATABLE :: no_of_levels(:) ! number of levels of each fixed and sire effect
INTEGER :: first_equation_of_sire ! first equaton number of sire effect
REAL :: var_ratio ! variance ratio
INTEGER, ALLOCATABLE :: data_line(:) ! fixed and sire effects for each line
REAL :: y ! observation for each line REAL, ALLOCATABLE :: lhs(:,:), gi_lhs(:,:), rhs(:), solution(:) ! left-hand side, right-hand side and solutions
INTEGER :: No_Of_Equations ! number of equation
INTEGER :: i, j ! do loop
INTEGER :: status ! I/O status
CHARACTER(LEN = 40) :: error_msg ! error message
! get data file name
WRITE (*,*) "Enter data file name : "
READ (*,*) filename ! get number of effects
WRITE (*,*) "Enter the number of effects(including fixed and sire effects) : "
READ (*,*) No_Of_Effects ! allocate dimensions of no_of_levels and fixed_data
ALLOCATE(no_of_levels(no_of_effects), data_line(no_of_effects))
WRITE (*,*) "Enter the number of levels for each fixed and sire effect : "
READ (*,*) no_of_levels
! get the variance ratio
WRITE (*,*) "Enter the variance ratio : "
READ (*,*) var_ratio ! calculate first equation number of sire and total number of equation
first_equation_of_sire = SUM(no_of_levels(1:no_of_effects-1)) + 1
no_of_equations = SUM(no_of_levels) ALLOCATE(lhs(no_of_equations,no_of_equations), &
gi_lhs(no_of_equations,no_of_equations), &
rhs(no_of_equations), &
solution(no_of_equations) &
) ! initialize
lhs = 0
rhs = 0
gi_lhs = 0
solution = 0
! open data file
OPEN(UNIT = 11, FILE = filename, STATUS = 'OLD', ACTION = 'READ', IOSTAT = status, IOMSG = error_msg)
IF (status /= 0) THEN ! file open failed
WRITE (*,'(1X, A, A)') 'File open failed -- error message : ', error_msg
STOP
END IF DO ! read each line
READ(UNIT = 11, FMT = *, IOSTAT = status) data_line, y
IF (status /= 0) EXIT ! end of file ! convert fixed effect into equation number
DO i = 2, no_of_effects
data_line(i) = data_line(i) + SUM(no_of_levels(1:i - 1))
END DO
!add 1 to appropriate location of lhs(ex : 9 elements for 2 fixed and 1 sire effect)
lhs(data_line,data_line) = lhs(data_line,data_line) + 1 ! add observation to each fixed and sire location of rhs
rhs(data_line) = rhs(data_line) + y END DO ! add variance ratio to sire effect diagonal part of lhs
DO i = first_equation_of_sire, no_of_equations
lhs(i, i) = lhs(i, i) + var_ratio
END DO ! constraint
lhs(1,:)=0
lhs(:,1)=0
rhs(1)=0 CALL geninv(lhs, gi_lhs)
solution = MATMUL(gi_lhs, rhs)
WRITE(*,*) 'left-hand side ='
WRITE(*,'(8(F3.0, 1X))') ((lhs(i,j), j = 1, no_of_equations), i = 1, no_of_equations)
WRITE(*,*) 'right-hand side ='
WRITE(*,'(F6.1)') (rhs(i),i = 1, no_of_equations) WRITE(*,*) 'ginverse of lhs ='
WRITE(*,'(8(F6.4, 1X))') ((gi_lhs(i,j), j = 1, no_of_equations), i = 1, no_of_equations)
WRITE(*,*) 'solutions ='
WRITE(*,*) (solution(i),i = 1, no_of_equations)
END PROGRAM sire_model
위 소스를 sire_model_1.f95로 저장
다음은 역행렬을 구하기 위한 소스
MODULE gi CONTAINS
SUBROUTINE geninv(x,gix) REAL, DIMENSION(:,:), INTENT(IN) :: x ! square matrix to inverse
REAL, DIMENSION(:,:), INTENT(OUT) :: gix ! square matirx after inverse
INTEGER :: i, j, no_of_eq, size_x, mr
REAL(KIND = 8), ALLOCATABLE :: upperd(:)
INTEGER, DIMENSION(99) :: iw
REAL(KIND = 8) :: z no_of_eq = SIZE(x,1) ALLOCATE(upperd((no_of_eq*(no_of_eq +1)/2)))
upperd = 0
DO i = 1, no_of_eq
DO j = 1, no_of_eq
upperd(ihmssf(i,j,no_of_eq))=x(i,j)
END DO
END DO !WRITE(*,*) 'upperd = ', upperd CALL DJNVHF(upperd,no_of_eq,iw,z,mr) DO i = 1, no_of_eq
DO j = 1, no_of_eq
gix(i,j) = upperd(ihmssf(i,j,no_of_eq))
END DO
END DO END SUBROUTINE geninv SUBROUTINE DJNVHF(A,N,IS,Z,IR)
!
! MATRIX INVERSION SUBROUTINE
!
! 'A' IS A HALF-STORED MATRIX TO BE INVERTED. THE INVERTED
! RESULT IS RETURNED IN 'A'.
! 'N' IS THE ORDER OF THE MATRIX TO BE INVERTED.
! 'IS' IS A WORK VECTOR.
! 'Z' IS SET TO ZERO ON CALLS TO THIS SUBROUTINE FROM THE BEEF
! SIRE MONITORING SYSTEM.
! 'IR' RETURNS THE RANK OF THE MATRIX.
!
! THIS SUBROUTINE CALLS THE SUBROUTINE DREARN.
!
DIMENSION A(1),IS(1)
REAL*8 A,BIG,Z,RECIP,R
201 NP=(N*(N+1))/2
IF(N-1) 21,23,96
21 WRITE(6,22)
22 FORMAT(' N.LT.1')
23 IF(A(1)) 25,24,25
24 IR=0
26 RETURN
25 IR=1
A(1)=1.D0/A(1)
RETURN
96 DO 50 L=1,N
BIG=0.D1
DO 2 I=L,N
II=-(I*(I-3))/2+N*(I-1)
IF(DABS(A(II))-DABS(BIG)) 2,2,1
1 IS(L)=I
BIG=A(II)
2 CONTINUE
IF(DABS(BIG)-Z) 63,63,62
63 IR=L-1
IF(IR) 26,26,98
98 DO 64 I=1,L
LI=-(I*(I-1))/2+N*(I-1)
DO 64 J=L,N
LIJ=LI+J
64 A(LIJ)=-0.D1
IF(L-N) 66,69,67
67 STOP 67
66 LP1=L+1
DO 68 I=LP1,N
LI=-(I*(I-1))/2+N*(I-1)
DO 68 J=I,N
LIJ=LI+J
68 A(LIJ)=-0.D1
69 IF(IR-2) 56,27,27
56 CALL DREARN(A,N,IS,1)
DO 57 I=1,NP
57 A(I)=-A(I)
RETURN
27 LP1=L+1
DO 65 I=2,L
J=LP1-I
65 CALL DREARN(A,N,IS,J)
DO 101 I=1,NP
101 A(I)=-A(I)
RETURN
62 CALL DREARN(A,N,IS,L)
28 K3=N*(L-1)-(L*(L-3))/2
RECIP=1./A(K3)
A(K3)=-RECIP
DO 50 I=1,N
IF(I-L) 6,50,7
6 K11=N*(I-1)-(I*(I-3)/2)
K1=K11+L-I
GO TO 8
7 K11=N*(I-1)-(I*(I-3))/2
K1=K3+I-L
8 R=A(K1)*RECIP
301 DO 12 J=I,N
K4=K11+J-I
IF(J-L) 10,12,11
10 K5=N*(J-1)-(J*(J-3)/2)+L-J
GO TO 14
11 K5=K3+J-L
14 A(K4)=A(K4)-R*A(K5)
12 CONTINUE
A(K1)=R
50 CONTINUE
NP=(N*(N+1))/2
DO 100 I=1,NP
100 A(I)=-A(I)
NP1=N+1
DO 61 I=2,N
L=NP1-I
61 CALL DREARN(A,N,IS,L)
IR=N
RETURN
END SUBROUTINE
SUBROUTINE DREARN(A,N,IS,L)
!
! THIS IS A SUPPORT SUBROUTINE CALLED BY THE MATRIX INVERSION
! SUBROUTINE DJNVHF.
!
DIMENSION A(1),IS(1)
DOUBLE PRECISION A,SAVE
ISL=IS(L)
IF(ISL-L) 3,28,4
3 STOP 3
4 LM1=L-1
IF(LM1) 22,22,5
5 DO 21 I=1,LM1
IL=-(I*(I-1))/2+N*(I-1)+L
IISL=IL-L+ISL
SAVE=A(IL)
A(IL)=A(IISL)
21 A(IISL)=SAVE
22 LP1=L+1
ISLM1=ISL-1
IF(LP1-ISLM1) 23,23,25
23 DO 24 I=LP1,ISLM1
LI=-(L*(L-1))/2+N*(L-1)+I
IISL=-(I*(I-1))/2+N*(I-1)+ISL
SAVE=A(LI)
A(LI)=A(IISL)
24 A(IISL)=SAVE
25 ISLP1=ISL+1
IF(ISLP1-N) 26,26,38
26 DO 27 I=ISLP1,N
ISLI=-(ISL*ISLM1)/2+N*ISLM1+I
LI=-(L*LM1)/2+N*LM1+I
SAVE=A(ISLI)
A(ISLI)=A(LI)
27 A(LI)=SAVE
38 LL=-(L*(L-3))/2+N*(L-1)
ISLISL=-(ISL*(ISL-3))/2+ISLM1*N
SAVE=A(LL)
A(LL)=A(ISLISL)
A(ISLISL)=SAVE
28 RETURN
END SUBROUTINE FUNCTION IHMSSF(IR,IC,N)
JR=IR
JC=IC
IF(IR-IC)40,40,41
41 JC=IR
JR=IC
40 NR=JR-1
KK=(JR*NR)/2
KK=KK+NR*(N-NR)
KK=KK+JC-NR
IHMSSF=KK
RETURN
END FUNCTION
END MODULE gi
위 소스를 inverse.f95로 저장
실행을 편리하게 하기 위하여
sire_model.dat
3
3 3 2
10
위 소스를 sire_model_1.par로 저장
프로그램 컴파일 및 실행
'Animal Breeding > Fortran program' 카테고리의 다른 글
animal model - gauss seidel, iteration on data (0) | 2009.04.22 |
---|---|
근교계수(inbreeding coefficient)와 Dii 구하기 (0) | 2009.04.21 |
Sire Model - Gauss Seidel 방법을 이용 (0) | 2009.04.20 |
Fixed Model 2 (0) | 2009.04.08 |
Fixed Model (0) | 2009.03.23 |