VARCOMPUTE.FOR
varcompute.for is a Fortran program used to compute the variance components for the paper
“How Much Does Industry Matter?” Rumelt, Richard P. “Strategic management journal 12, no. 3 (1991): 167-185.
PROGRAM VARCOMPUTE
C
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
IMPLICIT INTEGER*4 (I-N)
INTEGER NIT(0:249,0:4), NKT(0:499,0:4)
INTEGER NIK(2000),IIK(2000),KIK(2000)
INTEGER T, LEVELS(6)
CHARACTER*15 NAME(6)
DIMENSION A(5,6),TADJ(5),XXX(11),xl(6)
real*4 roa, r(8192)
COMMON /KVCOM / KV(8192,4)
common /rcom/ r
COMMON /XCOM/ XMA,XMB,XMC,XMD,XME,XAB,XAC,XBA,XBC,XCA,XCB
COMMON /LEVCOM/ LEVA,LEVB,LEVC,LEVD,LEVE,LEVERROR
EQUIVALENCE (XMA,XXX(1))
EQUIVALENCE (LEVA,LEVELS(1))
C
DATA NIT/1250*0/, NKT/2500*0/, NIK/2000*0/
DATA IIK/2000*0/, KIK/2000*0/
C
DATA SIGE2 /102.66/
DATA TADJ /347423.96,340475.23,548.91,537841.56,
1 1294372.15/
NAME(1) = ‘INDUSTRY’
NAME(2) = ‘CORPORATION’
NAME(3) = ‘TIME’
NAME(4) = ‘TIME*INDUSTRY’
NAME(5) = ‘SBU’
NAME(6)=’ERROR’
LEVERROR = 0
DO 50 I=1,11
50 XXX(I) = 0.0
C TA HOLDS THE CALCULATED VALUES OF T – TM
C TADJ(1) = TA – TM
C TADJ(2) = TB – TM
C TADJ(3) = TC – TM
C TADJ(4) = TD – TM
C TADJ(5) = TE – TM
C
C
OPEN(9,FILE=’VARCOMPUTE.LOG’)
CLOSE (9,STATUS=’DELETE’)
OPEN(9,FILE=’VARCOMPUTE.LOG’)
WRITE(9,10)
10 FORMAT(‘ VARIANCE COMPONENTS RESULTS’//)
print ‘(” Opening lbd file”)’
OPEN(8,FILE=’d:\data\LBD1.dat’,STATUS=’OLD’)
NOB = 0
C
C READ INTO KV(.,1) IYEAR (C)
C READ INTO KV(.,2) NCORP (B)
C READ INTO KV(.,3) IND4 (A)
C READ INTO KV(.,4) NSBU (E)
C
tz=0.0
tm=0.0
ta=0.0
tb=0.0
tc=0.0
td=0.0
tf=0.0
200 READ(8,202,END=220) IYEAR, NCORP, IND4, roa
202 FORMAT(I2,I4,I5,f8.3)
NOB=NOB+1
tz = tz+roa*roa
tm = tm+roa
r(nob)=roa
KV(NOB,1)= IYEAR
KV(NOB,2)= NCORP
KV(NOB,3)= IND4
KV(NOB,4)= 10000*NCORP + IND4
GOTO 200
220 CLOSE (8)
PRINT ‘(I5,” OBSERVATIONS”)’,NOB
tm = tm/dble(nob)
C
CALL LEVELER(NOB,LEVA,KV(1,3))
CALL LEVELER(NOB,LEVB,KV(1,2))
CALL LEVELER(NOB,LEVC,KV(1,1))
CALL LEVELER(NOB,LEVE,KV(1,4))
LEVD = 0
DO 250 N=1,NOB
T = KV(N,1)
I = KV(N,3)
K = KV(N,2)
J = KV(N,4)
NIT(I,T) = NIT(I,T) + 1
IF(NIT(I,T).EQ.1) LEVD = LEVD + 1
NIT(I,0) = NIT(I,0) + 1
NIT(0,T) = NIT(0,T) + 1
NKT(K,T) = NKT(K,T) + 1
NKT(0,T) = NKT(0,T) + 1
NKT(K,0) = NKT(K,0) + 1
IF(NIK(J).EQ.0) THEN
NIK(J) = 1
IIK(J) = I
KIK(J) = K
ELSE
NIK(J) = NIK(J) + 1
IF(IIK(J).NE.I.OR.KIK(J).NE.K) THEN
PRINT ‘(” DATA CONFUSION PROBLEM”)’
GOTO 1000
ENDIF
ENDIF
250 CONTINUE
C nit holds obs in (i,t)
c nkt holds obs in (k,t)
c nik holds obs in bus unit (j)
c iik tells i associated with j
c kik tells k associated with j
c
DO 275 J = 1,LEVE
FNIKD2 = NIK(J)*NIK(J)
XME = XME + FNIKD2/NOB
CALL CONDADD(XAB,FNIKD2,NIT(IIK(J),0))
CALL CONDADD(XBA,FNIKD2,NKT(KIK(J),0))
275 CONTINUE
C
DO 300 I = 1,LEVA
FNIDD = NIT(I,0)
XMA = XMA + FNIDD*FNIDD/NOB
DO 300 T = 1,LEVC
FNIDT2 = NIT(I,T)*NIT(I,T)
XMD = XMD + FNIDT2/NOB
CALL CONDADD(XAC,FNIDT2,NIT(I,0))
CALL CONDADD(XCA,FNIDT2,NIT(0,T))
300 CONTINUE
C
DO 350 K = 1,LEVB
FNDKD = NKT(K,0)
XMB = XMB + FNDKD*FNDKD/NOB
DO 350 T=1,LEVC
FNDKT2 = NKT(K,T)*NKT(K,T)
CALL CONDADD(XBC,FNDKT2,NKT(K,0))
CALL CONDADD(XCB,FNDKT2,NKT(0,T))
350 CONTINUE
DO 400 T=1,LEVC
FNDDT2 = NKT(0,T)*NKT(0,T)
400 XMC = XMC + FNDDT2/NOB
C
A(1,1) = NOB – XMA
A(1,2) = XAB – XMB
A(1,3) = XAC – XMC
A(1,4) = XAC – XMD
A(1,5) = XAB – XME
A(1,6) = TADJ(1) – (LEVA-1)*SIGE2
A(2,1) = XBA – XMA
A(2,2) = NOB – XMB
A(2,3) = XBC – XMC
A(2,4) = LEVB – XMD
A(2,5) = XBA – XME
A(2,6) = TADJ(2) – (LEVB-1)*SIGE2
A(3,1) = XCA – XMA
A(3,2) = XCB – XMB
A(3,3) = NOB – XMC
A(3,4) = XCA – XMD
A(3,5) = LEVC – XME
A(3,6) = TADJ(3) – (LEVC-1)*SIGE2
A(4,1) = NOB – XMA
A(4,2) = LEVD – XMB
A(4,3) = NOB – XMC
A(4,4) = NOB – XMD
A(4,5) = LEVD – XME
A(4,6) = TADJ(4) – (LEVD-1)*SIGE2
A(5,1) = NOB – XMA
A(5,2) = NOB – XMB
A(5,3) = LEVE – XMC
A(5,4) = LEVE – XMD
A(5,5) = NOB – XME
A(5,6) = TADJ(5) – (LEVE-1)*SIGE2
501 format(7f20.9)
xl(1) = leva
xl(2) = levb
xl(3) = levc
xl(4) = levd
xl(5) = leve
write(9,501) nob-xma,nob-xmb,nob-xmc,nob-xmd,nob-xme,nob-1.0,0.0
do 510 i = 1,5
write(9,501) (a(i,j),j=1,6),xl(i)-1,tadj(i)
510 continue
CALL SOLVER(5,6,A)
601 FORMAT(‘SOURCE’,T17,’LEVELS’,T34,’ADJ SSQ R’,T50,
1 ‘VARIANCE COMPONENT’)
602 FORMAT(A15,I7,2F20.6)
603 FORMAT(‘ERROR’,T43,F20.6)
WRITE(9,601)
DO 600 I=1,5
600 WRITE(9,602) NAME(I),LEVELS(I),TADJ(I),A(I,6)
WRITE(9,603) SIGE2
WRITE(*,601)
DO 610 I=1,5
610 WRITE(*,602) NAME(I),LEVELS(I),TADJ(I),A(I,6)
WRITE(*,603) SIGE2
1000 CLOSE(8)
CLOSE (9)
END
C
SUBROUTINE CONDADD(X,F,N)
DOUBLE PRECISION X,F
IF(N.GT.0) X = X + F/N
RETURN
END
C SUBROUTINE LEVELER
C
C THIS SUBROUTINE ACCEPTS AN INTEGER VECTOR
C CODES(.) AND REPLACES EACH UNIQUE CODE WITH
C ITS ORDER NUMBER (LEVEL) ON AN ASCENDING SORT.
C THE NUMBER OF LEVELS (LARGEST ORDER NUMBER) IS
C RETURNED IN NLEV AND THE VECTOR IW(.) IS USED AS
C WORKSAPCE. CODES AND IW ARE ADJ TO SIZE N.
C
SUBROUTINE LEVELER(N,NLEV,CODES)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
IMPLICIT INTEGER*4 (I-N)
INTEGER CODES(N)
INTEGER IW(8192)
CALL INDEXX(N,CODES,IW)
NLEV = 1
LAST = CODES(IW(1))
DO 100 I =1,N
IF(LAST.NE.CODES(IW(I))) THEN
NLEV = NLEV + 1
LAST = CODES(IW(I))
ENDIF
CODES(IW(I)) = NLEV
100 CONTINUE
RETURN
END
C
C SUBROUTINE INDEXX
C THIS SUBROUTINE SORTS THE INTEGER VECTOR A(.)
C VIA AN INDEX VECTOR INDX(.). THE ADJUSTED SIZES
C OF THESE VECTORS IS N.
C A HEAPSORT METHOD IS USED. THE CONTENTS OF A(.)
C ARE NOT ALTERED.
C
SUBROUTINE INDEXX(N,A,INDX)
INTEGER A(N), INDX(N), Q
DO 100 J =1,N
100 INDX(J) = J
L = N/2 + 1
IR = N
110 CONTINUE
IF(L.GT.1) THEN
L = L-1
INDXT = INDX(L)
Q = A(INDXT)
ELSE
INDXT = INDX(IR)
Q = A(INDXT)
INDX(IR) = INDX(1)
IR = IR-1
IF(IR.EQ.1) THEN
INDX(1) = INDXT
RETURN
ENDIF
ENDIF
I=L
J=L+L
120 IF(J.LE.IR) THEN
IF(J.LT.IR) THEN
IF(A(INDX(J)).LT.A(INDX(J+1))) J=J+1
ENDIF
IF(Q.LT.A(INDX(J))) THEN
INDX(I)=INDX(J)
I=J
J=J+J
ELSE
J=IR+1
ENDIF
GOTO 120
ENDIF
INDX(I) = INDXT
GOTO 110
END
C
SUBROUTINE SOLVER(N,M,A)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
IMPLICIT INTEGER*4 (I-N)
DIMENSION A(N,M)
C
C DO EACH COLUMN IN TURN
C
DO 500 JP = 1,N
C
C SEARCH FOR BIGGEST ELEMENT TO PIVOT ON
IP = 0
BIG = 0.0
DO 100 I = JP,N
IF(DABS(A(I,JP)).GT.BIG) THEN
BIG = dabs(A(I,JP))
IP = I
ENDIF
100 CONTINUE
IF(IP.EQ.0) THEN
STOP
ENDIF
C
C IF NOT ON DIAGONAL, EXCHANGE ROWS
120 IF(IP.NE.JP) THEN
DO 140 J=1,M
X = A(IP,J)
A(IP,J) = A(JP,J)
A(JP,J) = X
140 CONTINUE
IP = JP
ENDIF
C
C MAKE THE PIVOT UNITY
C
Q = A(IP,JP)
DO 200 J=JP,M
200 A(IP,J) = A(IP,J)/Q
C
C CLEAR REST OF COLUMN
C
DO 250 I = 1, N
IF(I.EQ.IP) GOTO 250
Q = A(I,JP)
A(I,JP) = 0.0
DO 220 J=JP+1,M
220 A(I,J) = A(I,J) – Q*A(IP,J)
250 CONTINUE
500 CONTINUE
RETURN
END