-
Notifications
You must be signed in to change notification settings - Fork 48
/
ch13-cache.py
120 lines (79 loc) · 2.97 KB
/
ch13-cache.py
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
import random
import feedback as fb
class Cache( fb.Component ):
def __init__( self, size, demand ):
self.t = 0 # internal time counter, needed for last access time
self.size = size # size limit of cache
self.cache = {} # actual cache: cache[key] = last_accessed_time
self.demand = demand # demand function
def work( self, u ):
self.t += 1
self.size = max( 0, int(u) ) # non-negative integer
i = self.demand( self.t ) # this is the "requested item"
if i in self.cache:
self.cache[i] = self.t # update last access time
return 1
if len(self.cache) >= self.size: # must make room
m = 1 + len(self.cache) - self.size # number of elements to delete
tmp = {}
for k in self.cache.keys(): # key by last_access_time
tmp[ self.cache[k] ] = k
for t in sorted( tmp.keys() ): # delete the oldest elements
del self.cache[ tmp[t] ]
m -= 1
if m == 0:
break
self.cache[i] = self.t # insert into cache
return 0
class SmoothedCache( Cache ):
def __init__( self, size, demand, avg ):
Cache.__init__( self, size, demand );
self.f = fb.FixedFilter( avg )
def work( self, u ):
y = Cache.work( self, u )
return self.f.work(y)
# ============================================================
def statictest(demand_width):
def demand( t ):
return int( random.gauss( 0, demand_width ) )
fb.static_test( SmoothedCache, (0, demand, 100), 150, 100, 5, 3000 )
def stepresponse():
def demand( t ):
return int( random.gauss( 0, 15 ) )
def setpoint( t ):
return 40
p = SmoothedCache( 0, demand, 100 )
fb.step_response( setpoint, p )
def closedloop():
def demand( t ):
return int( random.gauss( 0, 15 ) )
def setpoint( t ):
if t > 5000:
return 0.5
return 0.7
p = SmoothedCache( 0, demand, 100 )
c = fb.PidController( 100, 250 )
fb.closed_loop( setpoint, c, p, 10000 )
def closedloop_jumps():
def demand( t ):
if t < 3000:
return int( random.gauss( 0, 15 ) )
elif t < 5000:
return int( random.gauss( 0, 35 ) )
else:
return int( random.gauss( 100, 15 ) )
def setpoint( t ):
return 0.7
p = SmoothedCache( 0, demand, 100 )
c = fb.PidController( 270, 7.5 ) # Ziegler-Nichols - closedloop1
# c = fb.PidController( 100, 4.3 ) # Cohen-Coon - 2
# c = fb.PidController( 80, 2.0 ) # AMIGO - 3
# c = fb.PidController( 150, 2 ) # 4
fb.closed_loop( setpoint, c, p, 10000 )
# ============================================================
if __name__ == '__main__':
fb.DT = 1
# statictest(35) # 5, 15, 35
# stepresponse()
# closedloop()
closedloop_jumps()