-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrx.py
More file actions
executable file
·149 lines (126 loc) · 3.79 KB
/
rx.py
File metadata and controls
executable file
·149 lines (126 loc) · 3.79 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
Run some some experiments, setting some globals,
the un-doing those changes once the experiment fails.
Example:
class silly:
X=1
Y=min
class solly:
Z=22
B="love"
def f1():
return 3>1
# begin experiments
for _ in rx(solly, Z=[20,30], B=["love","hate"]):
for _ in rx( silly, X=[2,3], Y=[max,f1]):
# insert your experiment here
assert silly.X != 1
assert solly.Z != 22
# afterwards, we are back to the old values.
assert silly.X == 1
assert solly.Z == 22
______
## Programmer's Guide
In the following, `klass` is some with attributes `k.v1,k.v2,..` etc
which we want to (temporarily) set
to something else (and the something else comes from
the values in the dictionary `**d`).
Note that the
values in `d` can be lists or a single items
"""
import itertools,sys,random,ast,tempfile,os
def rx(klass,**d):
lst = [[(k,v) for v in
# Ensure k's value is something we can iterate over.
(vs if type(vs)==list else [vs])]
for k,vs in d.items()]
# Generate all combinations.
combos = list( itertools.product(*lst) )
# Run over the combinations.
for settings in combos:
now = {k:v for k,v in settings}
# Cache the old settings.
saved = {k:getattr(klass,k) for k in now}
# Impose the temp settings.
for k in now:
setattr(klass,k,now[k])
# Let something do something with the temp settings.
yield now
# Reset to old.
for k in saved:
setattr(klass,k,saved[k])
def showrx(lst):
d = {key:val for d in lst for key,val in d.items()}
tmp = []
for k,v in d.items():
i = 1
key = k[:i]
while key in tmp and len(key) < len(k):
i += 1
key = k[:i]
if v==True : v="1"
elif v==False : v="0"
elif type(v)==float: v= "%g" % v
elif type(v)==int : v=v
elif v.__class__.__name__ == 'function': v=v.__name__
tmp += ["%s%s" % (key,v)]
return ':'.join(tmp)
def printm(matrix,sep=","):
s = [[str(e) for e in row] for row in matrix]
lens = [max(map(len, col)) for col in zip(*s)]
sep = '%s ' % sep
fmt = sep.join('{{:>{}}}'.format(x) for x in lens)
for row in [fmt.format(*row) for row in s]:
print(row)
def say(*lst):
print(*lst, sep=' ', end='', file=sys.stdout, flush=True)
def freshFile(dir=None,prefix=None):
dir = dir or os.path.expanduser("~")+"/tmp"
prefix = prefix or "eg_"
if not os.path.exists(dir):
os.makedirs(dir)
fd,file= tempfile.mkstemp(prefix=prefix,dir=dir,text="w")
os.close(fd)
print("#",file)
return file
def watch(src,file,seed=1,every=10,klass="__all__",repeats=20):
random.seed(seed)
n = 0
with open(file,"w") as out:
for _ in range(repeats):
for obj,control in src(klass):
n += 1
if (n % every) == 0 : say("",n)
out.write("("+ str(obj) + ",'" + control + "')\n")
yield obj,control
def watched(file):
with open(file,"r") as hd:
return [ast.literal_eval(x) for x in hd.readlines()]
def dominates(pop,objs=None,betters=None):
betters = betters or [min for _ in pop[0]]
if objs==None:
objs= lambda z: z[1:]
doms={}
for i,one in enumerate( pop):
doms[i] = 0
for i,xs in enumerate(pop):
for j,ys in enumerate(pop):
if cdom1(objs(xs),objs(ys),betters):
doms[i] += 1
return sorted([( doms[i] ,xs) for i,xs in enumerate(pop)],reverse=True)
def cdom1(x, y, betters):
"many objective"
def w(better):
return -1 if better == min else 1
def expLoss(w,x1,y1,n):
return -1*2.71828**( w*(x1 - y1) / n )
def loss(x, y):
losses= []
n = min(len(x),len(y))
for i,bt in enumerate(betters):
x1, y1 = x[i] , y[i]
losses += [expLoss( w(bt),x1,y1,n)]
return sum(losses) / n
l1= loss(x,y)
l2= loss(y,x)
return l1 < l2