-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcntrs.f
128 lines (123 loc) · 3.6 KB
/
cntrs.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
C ROUTINES FOR INCREMENTING ARRAYS OF COUNTERS IN SOME WAY.
C ICTNS = INCREMENT COUNTERS TO NEXT STATE
C INCREMENT COUNTERS WITH DIFFERENT MAX VALUES, FROM THE RIGHT
C VALUES=(0,0,0) MAXES=(2,4,3)
C 0 0 0
C 0 0 1
C 0 0 2
C 0 0 3
C 0 1 0
C ...
C 0 1 3
C 0 2 0
C ...
C 0 4 3
C 1 0 0
SUBROUTINE CNTR(VALUES, MAXES, SIZE, ISDONE)
INTEGER VALUES(*), MAXES(*), SIZE
LOGICAL ISDONE
C INDEX THAT WE ARE INCREMENTING
INTEGER I
C VALUE AT PLACE WE ARE GOING TO INCREMENT
INTEGER CURVAL
I = SIZE
ISDONE = .FALSE.
1000 CURVAL = VALUES(I)
IF (CURVAL .LT. MAXES(I)) GOTO 1090
VALUES(I) = 0
I = I - 1
IF (I .GT. 0) GOTO 1000
ISDONE = .TRUE.
GOTO 1100
1090 VALUES(I) = VALUES(I) + 1
1100 END
C LIKE CNTR BUT INCREMENT THE LEFTMOST FIRST
SUBROUTINE CNTL(VALUES, MAXES, SIZE, ISDONE)
INTEGER VALUES(*), MAXES(*), SIZE
LOGICAL ISDONE
C INDEX THAT WE ARE INCREMENTING
INTEGER I
C VALUE AT PLACE WE ARE GOING TO INCREMENT
INTEGER CURVAL
I = 1
ISDONE = .FALSE.
2000 CURVAL = VALUES(I)
IF (CURVAL .LT. MAXES(I)) GOTO 2090
VALUES(I) = 0
I = I + 1
IF (I .LE. SIZE) GOTO 2000
ISDONE = .TRUE.
GOTO 2100
2090 VALUES(I) = VALUES(I) + 1
2100 END
C ICTNS = INCREMENT COUNTERS TO NEXT STATE. WE ARE PASSED AN ARRAY
C OF COUNTERS OF A GIVEN SIZE; THESE ARE ALL EITHER ZERO OR A NUMBER
C BETWEEN 1 AND MAX. IF THERE ARE TRAILING ZERO ENTRIES, WE INCREMENT
C THE FIRST OF THESE TO 1 (THERE ARE NEVER LEADING ZERO ENTRIES). IF
C ALL ENTRIES ARE NON-ZERO, WE INCREMENT THE RIGHT-MOST ENTRY; IF
C THIS WOULD CAUSE IT TO EXCEED THE MAXIMUM THEN WE RESET IT TO ZERO
C AND INCREMENT THE NEXT RIGHT-MOST ENTRY AND SO ON. IF WE FIND
C OURSELVES RESETTING THE LEFT-MOST ENTRY TO ZERO (I.E. WE'VE ENDED
C UP BACK AT THE ALL-ZEROES STATE) WE SET A FLAG TO INDICATE THAT
C WE'VE FINISHED.
C NZLEN IS RETURNED, IT IS THE LENGTH OF THE RUN OF LEFT-MOST NON-ZERO
C ELEMENTS. 1 <= NZLEN <= SIZE
C EXAMPLE, IF SIZE = 3, MAX=2
C 0 0 0
C 1 0 0
C 1 1 0
C 1 1 1
C 1 1 2
C 1 2 0
C 1 2 1
C 1 2 2
C 2 0 0
C 2 1 0
C 2 1 1
C 2 1 2
C 2 2 0
C 2 2 1
C 2 2 2
SUBROUTINE ICTNS(CNTERS, SIZE, MAX, NZLEN, ISDONE)
INTEGER CNTERS(*), SIZE, NZLEN, MAX
LOGICAL ISDONE
C INDEX OF THE LEFT-MOST ZERO
INTEGER LMZ
C INDEX THAT WE ARE ABOUT TO IMPLEMENT
INTEGER INCI
C VALUE AT POSITION THAT WE WANT TO INCREMENT
INTEGER CURVAL
ISDONE = .FALSE.
C SCAN TO FIND THE LEFT-MOST ZERO
LMZ = 1
9000 IF ((LMZ .GT. SIZE) .OR. (CNTERS(LMZ) .EQ. 0)) GOTO 9010
LMZ = LMZ + 1
GOTO 9000
C LMZ NOW POINTS AT THE LEFT-MOST ZERO, OR IS EQUAL TO SIZE + 1. IF IT
C IS LESS THAN OR EQUAL TO SIZE, WE JUST INCREASE THE NUMBER THERE AND
C SET NZLEN
9010 IF (LMZ > SIZE) GOTO 9020
C LMZ <= SIZE, THEREFORE IT POINTS AT ENTRY WHICH IS ZERO, SO WE CAN
C INCREASE IT TO ONE, SET NZLEN AND RETURN
CNTERS(LMZ) = 1
NZLEN = LMZ
GOTO 9100
C WE NEED TO INCREMENT THE RIGHT-MOST NUMBER; IF THIS EXCEEDS MAX THEN
C WE ROLL DOWN TO ZERO AND INCREMENT THE NEXT RIGHT-MOST NUMBER AND SO
C ON. IF WE ROLL THE LEFT-MOST NUMBER DOWN TO ZERO WE'VE FINISHED
9020 INCI = SIZE
9030 CURVAL = CNTERS(INCI)
IF (CURVAL .LT. MAX) GOTO 9050
C CURVAL = MAX, SO WE NEED TO OVERFLOW TO ZERO AND DECREMENT INCI
CNTERS(INCI) = 0
INCI = INCI - 1
IF (INCI .EQ. 0) GOTO 9040
GOTO 9030
C WE'VE RESET EVERYTHING TO ZERO, SO WE'VE FINISHED
9040 ISDONE = .TRUE.
GOTO 9100
C AT INCI IS SOMETHING WHICH CAN BE INCREMENTED WITHOUT OVERFLOW, SO
C INCREMENT AND SET NZLEN TO INCI
9050 CNTERS(INCI) = CURVAL + 1
NZLEN = INCI
9100 END