File IS_stat.py added (mode: 100644) (index 0000000..b53080c) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
# coding: utf-8 |
|
3 |
|
|
|
4 |
|
""" |
|
5 |
|
""" |
|
6 |
|
|
|
7 |
|
|
|
8 |
|
import numpy as np |
|
9 |
|
import collections # for defaultdict |
|
10 |
|
#from scipy import optimize # it was needed for spring solution |
|
11 |
|
|
|
12 |
|
|
|
13 |
|
# bisect function is taken from somewhere in internet. |
|
14 |
|
# StackOverflow, maybe? |
|
15 |
|
# Hope it is not big issue. |
|
16 |
|
def bisect(f, target, low, high): |
|
17 |
|
low, high = float(low), float(high) |
|
18 |
|
while low != high: |
|
19 |
|
mid = (low + high) / 2 |
|
20 |
|
f_mid = f(mid) |
|
21 |
|
if f_mid == target: |
|
22 |
|
return mid |
|
23 |
|
elif f_mid > target: |
|
24 |
|
high = mid if mid != high else low |
|
25 |
|
else: |
|
26 |
|
low = mid if mid != low else high |
|
27 |
|
return low |
|
28 |
|
|
|
29 |
|
|
|
30 |
|
class TrueIS: |
|
31 |
|
def __init__(self, f, IS_mode='G'): |
|
32 |
|
self.f_sample = f() |
|
33 |
|
self.series_data = [] |
|
34 |
|
self.IS_mode = IS_mode |
|
35 |
|
self.events = [] |
|
36 |
|
|
|
37 |
|
def add_IS_serie(self, sample, events, alpha=1): |
|
38 |
|
""" |
|
39 |
|
alpha is for rejection sampling, not used |
|
40 |
|
""" |
|
41 |
|
self.series_data.append((sample, events, alpha)) |
|
42 |
|
self.events += events |
|
43 |
|
if self.IS_mode == 'R': |
|
44 |
|
# jestli máme to právé vzorkovácí rozdělení - tak nemáme čo robiť |
|
45 |
|
self.f_sample.add_sample(sample) # smerdží se to po R |
|
46 |
|
# w like weights |
|
47 |
|
#wt.w = to_sample.pdf_R / wt.h.pdf_R |
|
48 |
|
else: #IS_mode == 'G': |
|
49 |
|
# tady musíme provést jeden trik |
|
50 |
|
self.f_sample.add_sample(sample.R, 'G') # R-ko smerdžíme ako G-čko |
|
51 |
|
#wt.w = to_sample.pdf_G / wt.h.pdf_R # snad je to správně |
|
52 |
|
|
|
53 |
|
|
|
54 |
|
def get_weights(self): |
|
55 |
|
accu_denom_w = np.zeros(self.f_sample.nsim, dtype=float) |
|
56 |
|
if self.IS_mode == 'R': |
|
57 |
|
for serie in self.series_data: |
|
58 |
|
h_sample, events, alpha = serie |
|
59 |
|
h = h_sample.new_sample(self.f_sample) |
|
60 |
|
accu_denom_w += h.pdf_R * h_sample.nsim |
|
61 |
|
return self.f_sample.pdf_R / accu_denom_w, self.events |
|
62 |
|
|
|
63 |
|
else: # IS_mode == 'G' |
|
64 |
|
for serie in self.series_data: |
|
65 |
|
h_sample, events, alpha = serie |
|
66 |
|
h = h_sample.new_sample(self.f_sample.G, 'R') |
|
67 |
|
accu_denom_w += h.pdf_R * h_sample.nsim |
|
68 |
|
return self.f_sample.pdf_G / accu_denom_w, self.events |
|
69 |
|
|
|
70 |
|
|
|
71 |
|
def get_means(self): |
|
72 |
|
w, events = self.get_weights() |
|
73 |
|
keys = np.unique(events) |
|
74 |
|
Nsim = len(w) |
|
75 |
|
|
|
76 |
|
means = np.empty(len(keys), dtype=float) |
|
77 |
|
vars = np.empty(len(keys), dtype=float) |
|
78 |
|
|
|
79 |
|
|
|
80 |
|
# tak bacha |
|
81 |
|
ev = np.array(events) |
|
82 |
|
for key, i in zip(keys, range(len(keys))): |
|
83 |
|
|
|
84 |
|
mask = ev==key |
|
85 |
|
ev_w = w[mask] |
|
86 |
|
# podle IS vzorečků (skoro) |
|
87 |
|
key_mean = np.sum(ev_w) |
|
88 |
|
key_var = (np.sum(ev_w**2)*Nsim - key_mean**2) / Nsim |
|
89 |
|
|
|
90 |
|
# uložime |
|
91 |
|
means[i] = key_mean |
|
92 |
|
vars[i] = key_var |
|
93 |
|
|
|
94 |
|
# vyfiltrujeme zbytek |
|
95 |
|
w = w[~mask] |
|
96 |
|
ev = ev[~mask] |
|
97 |
|
|
|
98 |
|
# kontrola |
|
99 |
|
assert len(w)==0 and len(ev)==0, "Что за хренотень?!" |
|
100 |
|
|
|
101 |
|
return means, vars |
|
102 |
|
|
|
103 |
|
|
|
104 |
|
class ISSI: |
|
105 |
|
""" |
|
106 |
|
IS statistics = weights series + events |
|
107 |
|
ISSI calculates probabilities of repeated IS series |
|
108 |
|
with implicit (non-zero) variances |
|
109 |
|
|
|
110 |
|
zda se mi, že tím nelze nic zhoršit |
|
111 |
|
""" |
|
112 |
|
def __init__(self, events=[]): |
|
113 |
|
""" |
|
114 |
|
""" |
|
115 |
|
self.series_data = [] |
|
116 |
|
self.events = events |
|
117 |
|
|
|
118 |
|
def add_IS_serie(self, weights, events, implicit_multiplicator=1): |
|
119 |
|
keys = np.unique(events) |
|
120 |
|
Nsim = len(weights) |
|
121 |
|
|
|
122 |
|
# vytvoříme slovník pro sadu vzorků, který implicitně |
|
123 |
|
# bude předpokládát průměr=0 a rozptyl 1/Nsim^2 |
|
124 |
|
# pro všecko, co se v sadě neobjevilo |
|
125 |
|
if Nsim == 1: |
|
126 |
|
# jedno meření je taky měření) |
|
127 |
|
implicit_var = implicit_multiplicator |
|
128 |
|
else: |
|
129 |
|
implicit_var = implicit_multiplicator*(1-1/Nsim)/Nsim**2 |
|
130 |
|
serie = collections.defaultdict(lambda:(0, implicit_var)) |
|
131 |
|
|
|
132 |
|
# tak bacha |
|
133 |
|
w = np.array(weights) |
|
134 |
|
ev = np.array(events) |
|
135 |
|
for key in keys: |
|
136 |
|
if key not in self.events: |
|
137 |
|
self.events.append(key) |
|
138 |
|
|
|
139 |
|
mask = ev==key |
|
140 |
|
ev_w = w[mask] |
|
141 |
|
# podle IS vzorečků |
|
142 |
|
key_mean = np.sum(ev_w)/Nsim |
|
143 |
|
key_var = (np.sum(ev_w**2)/Nsim - key_mean**2) / Nsim |
|
144 |
|
if key_var == 0: # to nechcem |
|
145 |
|
key_var = implicit_var |
|
146 |
|
|
|
147 |
|
# uložime |
|
148 |
|
serie[key] = (key_mean, key_var) |
|
149 |
|
|
|
150 |
|
# vyfiltrujeme zbytek |
|
151 |
|
w = w[~mask] |
|
152 |
|
ev = ev[~mask] |
|
153 |
|
|
|
154 |
|
# kontrola |
|
155 |
|
assert len(w)==0 and len(ev)==0, "Что за хренотень?!" |
|
156 |
|
|
|
157 |
|
self.series_data.append(serie) |
|
158 |
|
|
|
159 |
|
# ачиз значение утёз |
|
160 |
|
self.get_estimations() |
|
161 |
|
self.estimations = {self.events[i] : self.values[i] for i in range(len(self.events))} |
|
162 |
|
|
|
163 |
|
|
|
164 |
|
def get_means(self): |
|
165 |
|
# počet jevů |
|
166 |
|
# number of events |
|
167 |
|
n_ev = len(self.events) |
|
168 |
|
self.weighted_means = np.empty(n_ev, dtype=float) |
|
169 |
|
self.weighted_vars = np.empty(n_ev, dtype=float) |
|
170 |
|
|
|
171 |
|
# spočteme važené průměry a rozptyly |
|
172 |
|
for event, key in zip(self.events, range(n_ev)): |
|
173 |
|
key_accusum = 0 |
|
174 |
|
key_accuweight = 0 |
|
175 |
|
for serie in self.series_data: |
|
176 |
|
key_mean, key_var = serie[event] |
|
177 |
|
key_accusum += key_mean / key_var |
|
178 |
|
key_accuweight += 1/key_var |
|
179 |
|
|
|
180 |
|
self.weighted_means[key] = key_accusum / key_accuweight |
|
181 |
|
self.weighted_vars[key] = 1/key_accuweight |
|
182 |
|
|
|
183 |
|
|
|
184 |
|
return self.weighted_means, self.weighted_vars, np.array(self.events) |
|
185 |
|
|
|
186 |
|
def get_estimations(self): |
|
187 |
|
|
|
188 |
|
# p-čka. We are still talking about probabilities, right? |
|
189 |
|
p, vars, __ = self.get_means() |
|
190 |
|
|
|
191 |
|
sum_p = np.sum(p) |
|
192 |
|
if sum_p == 1: # а вдруг? |
|
193 |
|
self.values = p |
|
194 |
|
return p, np.array(self.events) |
|
195 |
|
|
|
196 |
|
# spring (non-linear) analogue |
|
197 |
|
# silu, kterou zatížíme system jen tak neseženeme |
|
198 |
|
elif sum_p > 1: # stlačit |
|
199 |
|
low_atF = -np.pi/2 |
|
200 |
|
high_atF = 0 |
|
201 |
|
else: # roztahnout |
|
202 |
|
low_atF = 0 |
|
203 |
|
high_atF = np.pi/2 |
|
204 |
|
|
|
205 |
|
# nuly nám udělaj problém |
|
206 |
|
mask = p==0 |
|
207 |
|
p = np.ma.array(p) |
|
208 |
|
vars = np.ma.array(p) |
|
209 |
|
p.mask = mask |
|
210 |
|
vars.mask = mask |
|
211 |
|
|
|
212 |
|
F = np.tan(bisect(lambda atF: np.sum(np.exp(np.tan(atF)*vars/p)*p), 1, low_atF, high_atF)) |
|
213 |
|
corrected_means = p * np.exp(F * vars/p) |
|
214 |
|
|
|
215 |
|
corrected_means.mask = False |
|
216 |
|
self.values = corrected_means |
|
217 |
|
return corrected_means, np.array(self.events) |
|
218 |
|
|
|
219 |
|
|
|
220 |
|
|
|
221 |
|
|
|
222 |
|
|
|
223 |
|
|
|
224 |
|
|
|
225 |
|
|
|
226 |
|
|
|
227 |
|
|
|
228 |
|
class ISS: |
|
229 |
|
""" |
|
230 |
|
IS statistics = weights series + events |
|
231 |
|
ISS calculates probabilities of repeated IS series |
|
232 |
|
""" |
|
233 |
|
def __init__(self): |
|
234 |
|
""" |
|
235 |
|
defaultdict zajistí, že na každý jev nás čeka seznam, do kterého |
|
236 |
|
může přidávat průměr a rozptyl ze sady |
|
237 |
|
""" |
|
238 |
|
self.data = collections.defaultdict(list) |
|
239 |
|
|
|
240 |
|
def add_IS_serie(self, weights, events): |
|
241 |
|
keys = np.unique(events) |
|
242 |
|
Nsim = len(weights) |
|
243 |
|
|
|
244 |
|
# tak bacha |
|
245 |
|
w = np.array(weights) |
|
246 |
|
ev = np.array(events) |
|
247 |
|
for key in keys: |
|
248 |
|
mask = ev==key |
|
249 |
|
ev_w = w[mask] |
|
250 |
|
# podle IS vzorečků |
|
251 |
|
key_mean = np.sum(ev_w)/Nsim |
|
252 |
|
key_var = (np.sum(ev_w**2)/Nsim - key_mean**2) / Nsim |
|
253 |
|
# uložime |
|
254 |
|
self.data[key].append((key_mean, key_var)) |
|
255 |
|
|
|
256 |
|
# vyfiltrujeme zbytek |
|
257 |
|
w = w[~mask] |
|
258 |
|
ev = ev[~mask] |
|
259 |
|
|
|
260 |
|
# kontrola |
|
261 |
|
assert len(w)==0 and len(ev)==0, "Что за хренотень?!" |
|
262 |
|
|
|
263 |
|
|
|
264 |
|
|
|
265 |
|
def get_means(self): |
|
266 |
|
# počet jevů |
|
267 |
|
# number of events |
|
268 |
|
weighted_means = [] |
|
269 |
|
weighted_vars = [] |
|
270 |
|
|
|
271 |
|
# spočteme važené průměry a rozptyly |
|
272 |
|
for key_data in self.data.values(): |
|
273 |
|
key_accusum = 0 |
|
274 |
|
key_accuweight = 0 |
|
275 |
|
for key_mean, key_var in key_data: |
|
276 |
|
key_accusum += key_mean / key_var |
|
277 |
|
key_accuweight += 1/key_var |
|
278 |
|
|
|
279 |
|
weighted_means.append(key_accusum / key_accuweight) |
|
280 |
|
weighted_vars.append(1/key_accuweight) |
|
281 |
|
|
|
282 |
|
|
|
283 |
|
return weighted_means, weighted_vars, np.array(list(self.data.keys())) |
|
284 |
|
|
|
285 |
|
def get_estimations(self): |
|
286 |
|
weighted_means, weighted_vars, __ = self.get_means() |
|
287 |
|
|
|
288 |
|
# p-čka. We are still talking about probabilities, right? |
|
289 |
|
p = np.array(weighted_means) |
|
290 |
|
vars = np.array(weighted_vars) |
|
291 |
|
|
|
292 |
|
sum_p = np.sum(p) |
|
293 |
|
if sum_p == 1: # а вдруг? |
|
294 |
|
return p, np.array(list(self.data.keys())) |
|
295 |
|
|
|
296 |
|
# spring (non-linear) analogue |
|
297 |
|
# silu, kterou zatížíme system jen tak neseženeme |
|
298 |
|
elif sum_p > 1: # stlačit |
|
299 |
|
low_atF = -np.pi/2 |
|
300 |
|
high_atF = 0 |
|
301 |
|
else: # roztahnout |
|
302 |
|
low_atF = 0 |
|
303 |
|
high_atF = np.pi/2 |
|
304 |
|
|
|
305 |
|
F = np.tan(bisect(lambda atF: np.sum(np.exp(np.tan(atF)*vars/p)*p), 1, low_atF, high_atF)) |
|
306 |
|
corrected_means = p * np.exp(F * vars/p) |
|
307 |
|
|
|
308 |
|
return corrected_means, np.array(list(self.data.keys())) |
|
309 |
|
|
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
|
313 |
|
# scipy проверяет брэкеты, чем вызывает overflow warning, раздражает |
|
314 |
|
# sol = optimize.root_scalar(lambda atF: np.sum(np.exp(np.tan(atF)*vars/p)*p)-1, bracket=(-np.pi/2, np.pi/2) ) |
|
315 |
|
# F = np.tan(sol.root) |
|
316 |
|
|
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
|
320 |
|
|
|
321 |
|
# triangle analogue |
|
322 |
|
# if len(weighted_means) == 2: |
|
323 |
|
# # tak je to jednoduchý |
|
324 |
|
# # it's piece of cake |
|
325 |
|
# # triangle analogue |
|
326 |
|
# a, b = *weighted_means |
|
327 |
|
# # derivations of Heron's formula |
|
328 |
|
# da = 8*a*b**2 + 6*a - 2*b - 2 |
|
329 |
|
# db = 8*b*a**2 + 6*b - 2*a - 2 |
|
330 |
|
# # matice koeficientů přetvořené podmínkové rovnice |
|
331 |
|
# B = np.array([[1,1], [da, db]]) |
|
332 |
|
|
|
333 |
|
# u = 1 - np.sum(p) |
|
334 |
|
# # vzoreček z teorii chyb měření a vyrovnávacího počtu nefunguje |
|
335 |
|
# # dává aj záporné pravděpodobnosti |
|
336 |
|
# #k = (1 - np.sum(weighted_means))/np.sum(weighted_vars) |
|
337 |
|
# #corrected_means = weighted_means + weighted_vars*k |
File blackbox.py added (mode: 100644) (index 0000000..09d2f73) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
# coding: utf-8 |
|
3 |
|
|
|
4 |
|
""" |
|
5 |
|
Zde leží BlackBox (tuším, bude jeden) |
|
6 |
|
BlackBox pěčlivě ukladá věškerá data, |
|
7 |
|
věškeré sady vzorků, průběžné odhady a tak. |
|
8 |
|
Nejsem už jistý, zda BlackBox je šťastný nazev, neboť |
|
9 |
|
teďkom je to spíše jen krabička pro krámy |
|
10 |
|
""" |
|
11 |
|
|
|
12 |
|
|
|
13 |
|
import numpy as np |
|
14 |
|
from scipy import spatial |
|
15 |
|
from . import plot |
|
16 |
|
import pickle |
|
17 |
|
from . import IS_stat |
|
18 |
|
from . import sball # for adaptive censoring |
|
19 |
|
from . import f_models # for adaptive censoring |
|
20 |
|
from scipy import stats # for adaptive censoring |
|
21 |
|
|
|
22 |
|
import inspect # for ._log() function |
|
23 |
|
|
|
24 |
|
from .samplebox import SampleBox # for candidates packing |
|
25 |
|
|
|
26 |
|
# considering to rewrite it with pandas |
|
27 |
|
class GuessBox: |
|
28 |
|
""" |
|
29 |
|
Je tu vynalezaní kola, ale aspoň tak |
|
30 |
|
Odhady můžou tvořít strašnej bordel a proto jsou |
|
31 |
|
ukladany do slovníku. |
|
32 |
|
Tak ale jej nemůžu furt ukladat, |
|
33 |
|
proto to robim s určitým krokem |
|
34 |
|
Na konci je třeba zabalit tuhle krabičku ručně! |
|
35 |
|
""" |
|
36 |
|
def __init__(gb, filename='', flush=100): |
|
37 |
|
""" |
|
38 |
|
.counter - kdy bylo poslední ukladaní |
|
39 |
|
""" |
|
40 |
|
gb.estimations = dict() |
|
41 |
|
gb.filename = filename |
|
42 |
|
gb.counter = 0 |
|
43 |
|
gb.flush = flush |
|
44 |
|
gb.pick() |
|
45 |
|
|
|
46 |
|
def __repr__(self): |
|
47 |
|
return "%s(%r, %s)"%(self.__class__.__name__, self.filename, self.flush) |
|
48 |
|
|
|
49 |
|
def __str__(gb): |
|
50 |
|
return str(gb.estimations) |
|
51 |
|
|
|
52 |
|
def __len__(gb): |
|
53 |
|
return len(gb.estimations) |
|
54 |
|
|
|
55 |
|
def __getitem__(gb, slice): |
|
56 |
|
return gb.estimations[slice] |
|
57 |
|
|
|
58 |
|
def guess(gb, index, nsim, estimation): |
|
59 |
|
if index in gb.estimations: |
|
60 |
|
gb.estimations[index][0].append(nsim) |
|
61 |
|
gb.estimations[index][1].append(estimation) |
|
62 |
|
else: |
|
63 |
|
gb.estimations[index] = [[nsim], [estimation]] |
|
64 |
|
|
|
65 |
|
gb.counter+= 1 |
|
66 |
|
if gb.filename and gb.counter > gb.flush: |
|
67 |
|
gb.put() |
|
68 |
|
|
|
69 |
|
def pick(gb): |
|
70 |
|
if gb.filename: |
|
71 |
|
try: |
|
72 |
|
with open(gb.filename + '.pickle', 'rb') as f: |
|
73 |
|
gb.estimations = pickle.load(f) |
|
74 |
|
except: |
|
75 |
|
# škoda, no |
|
76 |
|
print("GuessBox: Já tu vaši odhady %s.pickle nevidím" % gb.filename) |
|
77 |
|
else: |
|
78 |
|
print('GuessBox is in air mode') |
|
79 |
|
|
|
80 |
|
def put(gb): |
|
81 |
|
if gb.filename: |
|
82 |
|
try: |
|
83 |
|
with open(gb.filename + '.pickle', 'wb') as f: |
|
84 |
|
pickle.dump(gb.estimations, f) |
|
85 |
|
gb.counter = 0 |
|
86 |
|
except: |
|
87 |
|
# nefrčí... |
|
88 |
|
print("GuessBox: Can not write %s.pickle" % gb.filename) |
|
89 |
|
else: |
|
90 |
|
print('GuessBox is in air mode') |
|
91 |
|
|
|
92 |
|
|
|
93 |
|
class BlackBox: |
|
94 |
|
""" |
|
95 |
|
BlackBox pěčlivě ukladá věškerá data, |
|
96 |
|
věškeré sady vzorků (well, no yet), průběžné odhady a tak. |
|
97 |
|
Nejsem už jistý, zda BlackBox je šťastný nazev, neboť |
|
98 |
|
teďkom je to spíše jen krabička pro krámy |
|
99 |
|
|
|
100 |
|
.sampled_plan object |
|
101 |
|
.Z = g_values |
|
102 |
|
.failsi |
|
103 |
|
|
|
104 |
|
Souřadnice primárně z prostoru modelu, ty co jsme rovnou |
|
105 |
|
posilali do g_modelu! |
|
106 |
|
|
|
107 |
|
""" |
|
108 |
|
def __init__(bx, sample_box): |
|
109 |
|
bx.sample_box = sample_box |
|
110 |
|
# not really needed |
|
111 |
|
bx.f = sample_box.sampled_plan() |
|
112 |
|
# sample density (just helpful thing) |
|
113 |
|
bx.h = bx.f |
|
114 |
|
# don't ask me |
|
115 |
|
bx.candidates = sample_box.sampled_plan() |
|
116 |
|
# má bejt GuessBox součástí BlackBoxu? |
|
117 |
|
try: |
|
118 |
|
bx.guessbox = GuessBox(sample_box.filename, flush=20) |
|
119 |
|
except: |
|
120 |
|
bx.guessbox = GuessBox("", flush=20) |
|
121 |
|
bx.regen() |
|
122 |
|
|
|
123 |
|
def __repr__(bx): |
|
124 |
|
return "%s(%s, %s)"%('BlackBox', repr(bx.f)) |
|
125 |
|
|
|
126 |
|
def __str__(bx): |
|
127 |
|
return str('BlackBox ' + bx.sample_box) |
|
128 |
|
|
|
129 |
|
def __len__(bx): |
|
130 |
|
return bx.sample_box.nsim |
|
131 |
|
|
|
132 |
|
def __call__(bx): |
|
133 |
|
""" |
|
134 |
|
Offer next sample |
|
135 |
|
""" |
|
136 |
|
# I do not see nothing illegal here |
|
137 |
|
# LHS_like_correction do right conversion |
|
138 |
|
return bx.LHS_like_correction(bx.h(1)) |
|
139 |
|
|
|
140 |
|
def __getitem__(bx, slice): |
|
141 |
|
# stačí vratit sample_box |
|
142 |
|
return bx.sample_box[slice] |
|
143 |
|
|
|
144 |
|
def __getattr__(bx, attr): |
|
145 |
|
# По всем вопросам обращайтесь |
|
146 |
|
# на нашу горячую линию |
|
147 |
|
return getattr(bx.sample_box, attr) |
|
148 |
|
|
|
149 |
|
# just plot, green points, red points... |
|
150 |
|
plot2D = plot.plot2D |
|
151 |
|
plot3D = plot.plot3D |
|
152 |
|
|
|
153 |
|
# přidávání vzorků musí bejt explicitní! |
|
154 |
|
def add_sample(bx, input_sample): |
|
155 |
|
bx._log("we have got new data:", str(input_sample)) |
|
156 |
|
bx.sample_box.add_sample(input_sample) |
|
157 |
|
# tohle musí převest rozdělení vstupního vzorku na vlastní rozdělení skříňky |
|
158 |
|
inner_sample = bx.sample_box.new_sample(input_sample) |
|
159 |
|
bx.increment(inner_sample) |
|
160 |
|
|
|
161 |
|
|
|
162 |
|
def increment(bx, input_sample): |
|
163 |
|
for i in range(bx.nvar): |
|
164 |
|
for j in range(len(input_sample)): |
|
165 |
|
plan_index = np.searchsorted(bx.sorted_plan_U[i], input_sample.U[j,i]) |
|
166 |
|
bx.sorted_plan_U[i] = np.insert(bx.sorted_plan_U[i], plan_index, input_sample.U[j,i]) |
|
167 |
|
|
|
168 |
|
def regen(bx): |
|
169 |
|
# pro LHS_like_correction |
|
170 |
|
bx.sorted_plan_U = [i for i in range(bx.nvar)] # just create list |
|
171 |
|
for i in range(bx.nvar): |
|
172 |
|
bx.sorted_plan_U[i] = np.concatenate(([0], np.sort(bx.sampled_plan.U[:, i]), [1])) |
|
173 |
|
|
|
174 |
|
# LHS_style correction |
|
175 |
|
def LHS_like_correction(bx, input_sample): |
|
176 |
|
""" |
|
177 |
|
returns sample object (f_model) |
|
178 |
|
""" |
|
179 |
|
# what is input? |
|
180 |
|
# as we need transformation anyway, |
|
181 |
|
# I'll ask for conversion to f sample |
|
182 |
|
# Здесь вижу железную конвертацию до f-ка, |
|
183 |
|
# которая пройдёт по R координатам |
|
184 |
|
# Kruci drát, tady by se nemohlo nic posrat |
|
185 |
|
to_sample_node = bx.f.new_sample(input_sample) |
|
186 |
|
|
|
187 |
|
LHS_node = np.empty(bx.nvar, dtype=float) |
|
188 |
|
for i in range(bx.nvar): |
|
189 |
|
if to_sample_node.U.flatten()[i] <= bx.sorted_plan_U[i][0]: |
|
190 |
|
LHS_node[i] = (bx.sorted_plan_U[i][0] + bx.sorted_plan_U[i][1]) / 2 |
|
191 |
|
elif to_sample_node.U.flatten()[i] >= bx.sorted_plan_U[i][-1]: |
|
192 |
|
LHS_node[i] = (bx.sorted_plan_U[i][-2] + bx.sorted_plan_U[i][-1]) / 2 |
|
193 |
|
else: |
|
194 |
|
plan_index = np.searchsorted(bx.sorted_plan_U[i], to_sample_node.U.flatten()[i]) |
|
195 |
|
# vzdy |
|
196 |
|
LHS_node[i] = (bx.sorted_plan_U[i][plan_index] + bx.sorted_plan_U[i][plan_index - 1]) / 2 |
|
197 |
|
|
|
198 |
|
return bx.f.new_sample(LHS_node, 'U') |
|
199 |
|
|
|
200 |
|
def _log(bx, *msg, indent=0): |
|
201 |
|
print(bx.__class__.__name__ + ":", *msg) |
|
202 |
|
|
|
203 |
|
def _logi(bx, *msg, indent=1): |
|
204 |
|
print("\t"*indent, inspect.currentframe().f_back.f_code.co_name + ":", *msg) |
|
205 |
|
|
|
206 |
|
|
|
207 |
|
class Censoring(BlackBox): |
|
208 |
|
def __init__(bx, sample_object, tri_space='Rn'): |
|
209 |
|
bx.tri_space = tri_space |
|
210 |
|
super().__init__(sample_object) |
|
211 |
|
|
|
212 |
|
def __repr__(bx): |
|
213 |
|
return "%s(%s, %s, %s)"%('Censoring', repr(bx.f), repr(bx.tri_space)) |
|
214 |
|
|
|
215 |
|
def __str__(bx): |
|
216 |
|
return str('Censoring') |
|
217 |
|
|
|
218 |
|
def increment(bx, input_sample): |
|
219 |
|
super().increment(input_sample) |
|
220 |
|
|
|
221 |
|
if "tri" in dir(bx): |
|
222 |
|
# tri - Deloneho triangulace |
|
223 |
|
# sample je jíž převeden na f (v .add_sample()), takže je to bezpěčný |
|
224 |
|
bx.tri.add_points(getattr(input_sample, bx.tri_space)) |
|
225 |
|
# print('increment se podaril') |
|
226 |
|
if len(bx.tri.coplanar): # pokud triangulace není v pořadku |
|
227 |
|
#print('triangulace v pořádku není') |
|
228 |
|
bx._log('triangulation is coplanar') |
|
229 |
|
else: |
|
230 |
|
bx._log('Triangulace (zatím?) neexistuje') |
|
231 |
|
bx.regen() |
|
232 |
|
|
|
233 |
|
|
|
234 |
|
def regen(bx): |
|
235 |
|
super().regen() |
|
236 |
|
# pokud tecek nestaci na vytvareni aspon jedneho simplexu - pokrcim rameny |
|
237 |
|
try: |
|
238 |
|
# tady je to OK |
|
239 |
|
bx.tri = spatial.Delaunay(getattr(bx.sampled_plan, bx.tri_space), incremental=True) |
|
240 |
|
if len(bx.tri.coplanar): # pokud triangulace je v pořadku |
|
241 |
|
#print('triangulace v pořádku není') |
|
242 |
|
bx._log('triangulation is coplanar') |
|
243 |
|
else: |
|
244 |
|
#print('triangulace je v pořádku') |
|
245 |
|
bx._log('triangulation is OK') |
|
246 |
|
except: |
|
247 |
|
# kdyby neco - berem kramle |
|
248 |
|
bx._log('triangulation failed') |
|
249 |
|
|
|
250 |
|
|
|
251 |
|
|
|
252 |
|
def __call__(bx): |
|
253 |
|
# je treba si uvedomit ze pravdepodobnost chytnuti muze byt min jak pf. V soucasne realizaci |
|
254 |
|
try: |
|
255 |
|
# očekávám, že projde kandidaty |
|
256 |
|
# vodkaď jsou - netuším |
|
257 |
|
to_sample, rate = bx.filter() |
|
258 |
|
# když nepovedlo s kandidaty, zkusíme sami nagenerovat |
|
259 |
|
while len(to_sample) == 0: # nekonečno |
|
260 |
|
# tak, děcka, server má spoustu času a nikam nespejchá |
|
261 |
|
# ale pokud tohle sežere věškerou paměť (ne když, ale kdy) |
|
262 |
|
# dostaneš co proto! |
|
263 |
|
# vomezíme pole na 10e6 (desitky mega teda vodhadově) |
|
264 |
|
# by bylo možně použit chytrejší vzoreček s logaritmem |
|
265 |
|
# ale snad tohle postačí |
|
266 |
|
to_sample, rate = bx.filter(bx.h(int(0.9999*rate + 100))) |
|
267 |
|
return bx.LHS_like_correction(to_sample) |
|
268 |
|
|
|
269 |
|
# chcu zachytit spadnuti QHull na začatku, kdy ještě není |
|
270 |
|
# dostatek teček. Je-li bx.tri fakticky existuje, tj. |
|
271 |
|
# triangulace jíž existovala - je třeba nechat QHull spadnout |
|
272 |
|
except AttributeError: |
|
273 |
|
# kdyby neco - berem kramle |
|
274 |
|
print("Triangulation doesn't exist. Censoring failed") |
|
275 |
|
return bx.LHS_like_correction(bx.h(1)) # it should be OK |
|
276 |
|
|
|
277 |
|
def filter(bx, candidates=[]): |
|
278 |
|
""" |
|
279 |
|
supports both sample and sample.R input |
|
280 |
|
|
|
281 |
|
logika metody, nebo, přesněji, implementaci |
|
282 |
|
je taková, že bule-li někdo-něco mimo doménu, |
|
283 |
|
tak funkce je vrátí a zbytek už neřeší |
|
284 |
|
""" |
|
285 |
|
# co to bylo na vstupu? |
|
286 |
|
# když nebyl žádný, |
|
287 |
|
# projdeme vlastními kandidaty |
|
288 |
|
if len(candidates)==0: |
|
289 |
|
candidates = bx.candidates |
|
290 |
|
|
|
291 |
|
|
|
292 |
|
# tady byl problém. Funkce byla původně navržena tak, |
|
293 |
|
# aby ji nezajimalo co je na vstupu |
|
294 |
|
# to ale nefunguje |
|
295 |
|
# další funkce jako výstup očekavají něco s validním R-kem |
|
296 |
|
candidates_to_sample_node = getattr(bx.f.new_sample(candidates), bx.tri_space) |
|
297 |
|
|
|
298 |
|
|
|
299 |
|
found_simplices = bx.tri.find_simplex(candidates_to_sample_node) |
|
300 |
|
# ouside of domain - it's easy |
|
301 |
|
outside = candidates[found_simplices < 0] |
|
302 |
|
if len(outside) > 0: |
|
303 |
|
# my hodnotili svých kandidatov? |
|
304 |
|
if bx.candidates == candidates: |
|
305 |
|
bx.candidates = outside |
|
306 |
|
return outside, len(candidates)/len(outside) |
|
307 |
|
|
|
308 |
|
# tady já chcu vrátit první vhodný vzorek a tím končít |
|
309 |
|
for candidate_id in range(len(candidates)): |
|
310 |
|
# simplex_id >= 0: # inside of domain |
|
311 |
|
simplex_id = found_simplices[candidate_id] |
|
312 |
|
simplex = bx.tri.simplices[simplex_id] |
|
313 |
|
|
|
314 |
|
# fp like a failure points. Number of failure points |
|
315 |
|
fp = len(np.setdiff1d(simplex, bx.failure_points)) |
|
316 |
|
|
|
317 |
|
# pokud je simplex není jednobarevny.. |
|
318 |
|
if (fp != 0) and (fp != bx.nvar+1): |
|
319 |
|
# my hodnotili svých kandidatov? |
|
320 |
|
if bx.candidates == candidates: |
|
321 |
|
bx.candidates = candidates[candidate_id:] |
|
322 |
|
return candidates[candidate_id], candidate_id |
|
323 |
|
|
|
324 |
|
# nepovedlo. nic |
|
325 |
|
# mě nenapadá žádný lepší způsob vrátit prázdnou matici |
|
326 |
|
return candidates[0:0], len(candidates) |
|
327 |
|
|
|
328 |
|
|
|
329 |
|
class AdaptiveCensoring(Censoring): |
|
330 |
|
def __init__(bx, sample_object, tri_space='Rn', pf_lim=(1,0)): |
|
331 |
|
bx._log("instance creating") |
|
332 |
|
bx.sball = sball.Sball(sample_object.nvar) |
|
333 |
|
bx.pf_lim = pf_lim |
|
334 |
|
|
|
335 |
|
bx.base_r = bx.sball.get_r(0.5) |
|
336 |
|
|
|
337 |
|
# pro jistotu pridame |
|
338 |
|
bx.simplex_index = {'failure':[], 'success':[], 'mix':[]} |
|
339 |
|
|
|
340 |
|
|
|
341 |
|
# overall estimations |
|
342 |
|
#bx.oiss = IS_stat.ISSI(['failure', 'success', 'out', 'mix']) |
|
343 |
|
# -1 = 'out', 0=success, 1=failure, 2=mix |
|
344 |
|
bx.oiss = IS_stat.ISSI([-1,0,1,2]) |
|
345 |
|
# current estimations |
|
346 |
|
bx.ciss = IS_stat.ISSI([-1,0,1,2]) |
|
347 |
|
|
|
348 |
|
super().__init__(sample_object, tri_space) |
|
349 |
|
|
|
350 |
|
|
|
351 |
|
def __repr__(bx): |
|
352 |
|
return "%s(%s, %s, %s, %s)"%('AdaptiveCensoring', repr(bx.f), repr(bx.tri_space), repr(bx.pf_lim)) |
|
353 |
|
|
|
354 |
|
def __str__(bx): |
|
355 |
|
return str('AdaptiveCensoring') |
|
356 |
|
|
|
357 |
|
def regen(bx): |
|
358 |
|
bx._logi(inspect.currentframe().f_back.f_code.co_name, "launched regeneration") |
|
359 |
|
|
|
360 |
|
super().regen() |
|
361 |
|
if bx.pf_lim[1] == 0: |
|
362 |
|
bx.drop_r = float("inf") |
|
363 |
|
else: |
|
364 |
|
bx.drop_r = bx.sball.get_r(bx.pf_lim[1]) |
|
365 |
|
|
|
366 |
|
# dropneme (pro jistotu) odhady |
|
367 |
|
bx.oiss = bx.ciss |
|
368 |
|
# -1 = 'out', 0=success, 1=failure, 2=mix |
|
369 |
|
bx.ciss = IS_stat.ISSI([-1,0,1,2]) |
|
370 |
|
|
|
371 |
|
# drop indexes |
|
372 |
|
bx.simplex_index = {'failure':[], 'success':[], 'mix':[]} |
|
373 |
|
|
|
374 |
|
def increment(bx, input_sample): |
|
375 |
|
super().increment(input_sample) |
|
376 |
|
|
|
377 |
|
# drop indexes |
|
378 |
|
bx.simplex_index = {'failure':[], 'success':[], 'mix':[]} |
|
379 |
|
|
|
380 |
|
# current estimations |
|
381 |
|
try: # to čo já vidím v kódu - ISSI slovníky se pokažde generujóu znovu, |
|
382 |
|
# není nutně je explicitně kopirovať |
|
383 |
|
bx.guessbox.guess('TRI_overall_estimations', bx.nsim-1, bx.oiss.estimations) |
|
384 |
|
bx.guessbox.guess('TRI_current_estimations', bx.nsim-1, bx.ciss.estimations) |
|
385 |
|
except AttributeError: |
|
386 |
|
bx.guessbox.guess('TRI_upper_pf', bx.nsim-1, 1) |
|
387 |
|
|
|
388 |
|
# a znovu začneme počítat |
|
389 |
|
# -1 = 'out', 0=success, 1=failure, 2=mix |
|
390 |
|
bx.ciss = IS_stat.ISSI([-1,0,1,2]) |
|
391 |
|
|
|
392 |
|
|
|
393 |
|
def __call__(bx): |
|
394 |
|
bx._log("we were asked for an recommendation") |
|
395 |
|
# je treba si uvedomit ze pravdepodobnost chytnuti muze byt min jak pf. V soucasne realizaci |
|
396 |
|
try: |
|
397 |
|
# očekávám, že projde kandidaty |
|
398 |
|
# odkaď jsou - netuším |
|
399 |
|
to_sample, rate, simplex_id = bx.filter() |
|
400 |
|
# když nepovedlo s kandidaty, zkusíme sami nagenerovat |
|
401 |
|
while len(to_sample) == 0: # nekonečno |
|
402 |
|
# pokusme se nastavit rate tak, abychom získali právě jedneho kandidata |
|
403 |
|
try: # try uvnitř traja |
|
404 |
|
p_rate = bx.oiss.estimations[-1] + bx.oiss.estimations[2] |
|
405 |
|
except: |
|
406 |
|
p_rate = bx.pf_lim[0] - bx.pf_lim[1] |
|
407 |
|
if p_rate < 1e-5: |
|
408 |
|
rate = 100000 |
|
409 |
|
else: |
|
410 |
|
rate = int(1/p_rate) + 1 |
|
411 |
|
to_sample, rate, simplex_id = bx.filter(bx.get_candidates(rate)) |
|
412 |
|
choose = bx.LHS_like_correction(to_sample) |
|
413 |
|
bx._log("finally we choose", str(choose), "of", simplex_id, "simplex") |
|
414 |
|
return choose |
|
415 |
|
|
|
416 |
|
# chcu zachytit spadnuti QHull na začatku, kdy ještě není |
|
417 |
|
# dostatek teček. Je-li bx.tri fakticky existuje, tj. |
|
418 |
|
# triangulace jíž existovala - je třeba nechat QHull spadnout |
|
419 |
|
except AttributeError: |
|
420 |
|
choose = bx.LHS_like_correction(bx.get_candidates(1)) |
|
421 |
|
if bx.nsim < bx.nvar + 1: # je to legální |
|
422 |
|
bx._log("we have no enough points to build triangulation, so", str(choose), "is our recommendation") |
|
423 |
|
return choose |
|
424 |
|
|
|
425 |
|
elif bx.nsim < 2*bx.nvar + 3: # to je ještě budiž |
|
426 |
|
bx._log("we have troubles with triangulation, so we offer random sample for now:", str(choose)) |
|
427 |
|
return choose |
|
428 |
|
else: # no to teda ne! |
|
429 |
|
raise ValueError("AdaptiveCensoring: s tou triangulací je fakt něco není v pořadku") |
|
430 |
|
|
|
431 |
|
|
|
432 |
|
def filter(bx, candidates=[]): |
|
433 |
|
""" |
|
434 |
|
za pvré, jako vstup očekávám kandidaty od .get_candidates() funkce, |
|
435 |
|
zabalené do полукустарного sample_boxu s zadaným .implicit_multiplicator |
|
436 |
|
(je to drobnost pro přesnějši zpracování sad IS IS_statem). |
|
437 |
|
|
|
438 |
|
Metoda musí souřádnicím přiřazovat jev |
|
439 |
|
"success", "failure", "mix", "outside" |
|
440 |
|
|
|
441 |
|
TATO metoda jakmile narazí na "mix" nebo "outside" |
|
442 |
|
ukladá zjištěné informace do ISSI a nalezeného kandidata vrací |
|
443 |
|
""" |
|
444 |
|
# co to bylo na vstupu? |
|
445 |
|
# když nebyl žádný, |
|
446 |
|
# projdeme vlastními kandidaty |
|
447 |
|
if len(candidates)==0: |
|
448 |
|
candidates = bx.candidates |
|
449 |
|
|
|
450 |
|
bx._logi("kandidaty:", candidates) |
|
451 |
|
|
|
452 |
|
# je třeba lokálně zachovat implicit_multiplicator |
|
453 |
|
# jinak se ztrací při slajsingu |
|
454 |
|
# nechceš přepsat SampleBox, Alexi? |
|
455 |
|
try: |
|
456 |
|
implicit_multiplicator = candidates.implicit_multiplicator |
|
457 |
|
except AttributeError: # kandidaty můžou bejt odkudkoliv |
|
458 |
|
# s nekonečným rozptylem nebudou mít váhu "absenční" jevy |
|
459 |
|
# moc to odhadům nepomůže, protože je-li kandidaty |
|
460 |
|
# nemajú .implicit_multiplicator |
|
461 |
|
# asi nebudou mať ani váhy IS v .g_values |
|
462 |
|
implicit_multiplicator = float("inf") |
|
463 |
|
bx._logi("Dobrý den, kandidaty nemajú .implicit_multiplicator")#. S pozdravem, AdaptiveCensoring") |
|
464 |
|
|
|
465 |
|
# tady byl problém. Funkce byla původně navržena tak, |
|
466 |
|
# aby ji nezajimalo co je na vstupu |
|
467 |
|
# to ale nefunguje |
|
468 |
|
# další funkce jako výstup očekavají něco s validním R-kem |
|
469 |
|
# no tj. já zde provádím posouzení transformací z R-ka vstupních souřadnic |
|
470 |
|
candidates_to_sample_node = getattr(bx.f.new_sample(candidates), bx.tri_space) |
|
471 |
|
|
|
472 |
|
|
|
473 |
|
current_simplices = bx.tri.find_simplex(candidates_to_sample_node) |
|
474 |
|
|
|
475 |
|
|
|
476 |
|
# tak bacha |
|
477 |
|
# budeme přepísovat jevy in-place |
|
478 |
|
found_simplices = np.ma.array(current_simplices.copy()) #.copy() |
|
479 |
|
# nemaskované - obsahuji číslo simplexu |
|
480 |
|
# maskované - číslo jevu |
|
481 |
|
# -1 = 'out', 0=success, 1=failure, 2=mix |
|
482 |
|
# tj. procházíme simplexy z náhodné sady vzorků, |
|
483 |
|
# nahrazujeme čislo simplexu odpovidajicím mu jevem |
|
484 |
|
# a skryváme ho |
|
485 |
|
# pote ty "skryté", "projduté" vzorky využiváme k žískání odhadů |
|
486 |
|
|
|
487 |
|
while len(current_simplices):# > 0: |
|
488 |
|
bx._logi("current simplices", current_simplices) |
|
489 |
|
# berem hned prvního kandidata |
|
490 |
|
# a posuzujeme co je zač |
|
491 |
|
simplex_id = current_simplices[0] |
|
492 |
|
mask = found_simplices==simplex_id |
|
493 |
|
|
|
494 |
|
if simplex_id < 0: # -1 means ouside |
|
495 |
|
# berem kramle |
|
496 |
|
break |
|
497 |
|
elif simplex_id in bx.simplex_index['success']: |
|
498 |
|
found_simplices[mask] = 0 |
|
499 |
|
elif simplex_id in bx.simplex_index['failure']: |
|
500 |
|
found_simplices[mask] = 1 |
|
501 |
|
elif simplex_id in bx.simplex_index['mix']: |
|
502 |
|
found_simplices[mask] = 2 |
|
503 |
|
# kramle |
|
504 |
|
break |
|
505 |
|
else: # no index information |
|
506 |
|
# tady já chcu vrátit první vhodný vzorek a tím končít |
|
507 |
|
# simplex_id >= 0: # inside of domain |
|
508 |
|
# asi tady získavam množinu s čísly vrcholů |
|
509 |
|
# kteří zakladají simplex |
|
510 |
|
simplex = bx.tri.simplices[simplex_id] |
|
511 |
|
|
|
512 |
|
# for debug |
|
513 |
|
bx._logi("провал индексу", simplex_id, indent=2) |
|
514 |
|
|
|
515 |
|
# fp like a failure points. Number of failure points |
|
516 |
|
# setdiff "Return the unique values in ar1 that are not in ar2." |
|
517 |
|
fp = len(np.setdiff1d(simplex, bx.failure_points)) |
|
518 |
|
|
|
519 |
|
if fp == bx.nvar+1: # |
|
520 |
|
bx.simplex_index['success'].append(simplex_id) |
|
521 |
|
found_simplices[mask] = 0 |
|
522 |
|
elif fp == 0: |
|
523 |
|
bx.simplex_index['failure'].append(simplex_id) |
|
524 |
|
found_simplices[mask] = 1 |
|
525 |
|
#print("failure simplex", simplex_id) |
|
526 |
|
else: |
|
527 |
|
bx.simplex_index['mix'].append(simplex_id) |
|
528 |
|
found_simplices[mask] = 2 |
|
529 |
|
bx._logi("mixed simplex", simplex_id) |
|
530 |
|
# bacha! kramle |
|
531 |
|
break |
|
532 |
|
|
|
533 |
|
# pridame do seznamu známého |
|
534 |
|
found_simplices[mask] = np.ma.masked |
|
535 |
|
# eště raz |
|
536 |
|
cmask = current_simplices==simplex_id |
|
537 |
|
# vyfiltrujeme |
|
538 |
|
current_simplices = current_simplices[~cmask] |
|
539 |
|
|
|
540 |
|
|
|
541 |
|
|
|
542 |
|
# zde je třeba перехватить ситуацию, куке одӥг но кандидат ӧвӧл |
|
543 |
|
# нужно ли? |
|
544 |
|
# if len(current_simplices) == 0: |
|
545 |
|
# # nepovedlo. nic |
|
546 |
|
# bx.candidates = candidates[0:0] |
|
547 |
|
# # mě nenapadá žádný lepší způsob vrátit prázdnou matici |
|
548 |
|
# return candidates[0:0], len(candidates), -2 # simple_id |
|
549 |
|
|
|
550 |
|
# nemaskované, včetně současného kandidata (nevím proč) - ke kandidatům |
|
551 |
|
# землю - крестьянам, фабрики - рабочим |
|
552 |
|
# předpokladam, že kandidaty jsou se všim všudy |
|
553 |
|
# s vahami (.g_value) a se svým .implicit_multiplicator'em |
|
554 |
|
## zde True hodnoty roušky - to co jíž bylo skryto |
|
555 |
|
bx.candidates = candidates[~np.ma.getmaskarray(found_simplices)][1:] # toho prvního prečo nechcem |
|
556 |
|
try: # na zacatku je tam prazdný f_model, kterému atribut pripsat nemůžeme |
|
557 |
|
bx.candidates.implicit_multiplicator = implicit_multiplicator |
|
558 |
|
except: |
|
559 |
|
pass |
|
560 |
|
|
|
561 |
|
# vrátíme kandidaty, všechny-ne všechny? |
|
562 |
|
# малы одӥг гинэ? уг тодӥськы чик... |
|
563 |
|
selected_candidate = candidates[~np.ma.getmaskarray(found_simplices)][:1] # chcem toho prvního |
|
564 |
|
|
|
565 |
|
|
|
566 |
|
# odešleme ISSI |
|
567 |
|
try: |
|
568 |
|
# pridame do seznamu známého |
|
569 |
|
# rouška musí zůstat z cyklu |
|
570 |
|
# proboha, Alexi, co to je za roušku, co se tu děje? |
|
571 |
|
# jakmile v tom hlavním cyklu nalezli jsme mix nebo outside |
|
572 |
|
# my hned z cyklu vylezli a je neskryli - abychom je vzali jako kandidaty |
|
573 |
|
# teď je však skryváme s tou "rouškou", co musela být před opuštěním cyklu nastavena |
|
574 |
|
# tak ISSI bude mít možnost odhadovat i pravděpodobnosti mix a outside |
|
575 |
|
found_simplices[mask] = np.ma.masked |
|
576 |
|
# zde získáme True hodnoty roušek |
|
577 |
|
# ukazatel |
|
578 |
|
imask = found_simplices.mask |
|
579 |
|
found_simplices.mask = ~imask # invertujem, dotkne to i samotnou imask |
|
580 |
|
events = found_simplices.compressed() |
|
581 |
|
print(candidates) |
|
582 |
|
print(candidates.g_values) |
|
583 |
|
print("imask", imask) |
|
584 |
|
print(candidates.g_values[~imask]) |
|
585 |
|
print(events) |
|
586 |
|
bx.oiss.add_IS_serie(candidates.g_values[~imask], events, implicit_multiplicator) |
|
587 |
|
print("global estimation", bx.oiss.estimations) |
|
588 |
|
bx.ciss.add_IS_serie(candidates.g_values[~imask], events, implicit_multiplicator) |
|
589 |
|
print("current estimation", bx.ciss.estimations) |
|
590 |
|
except AttributeError: |
|
591 |
|
bx._logi("Это вы мне прислали неваженых кандидатов?") |
|
592 |
|
except UnboundLocalError: # čo tu chybu způsobuje? |
|
593 |
|
# asi nebyly žádné kandidaty (třeba hned na začátku) |
|
594 |
|
assert len(candidates)==0 and len(bx.candidates)==0, "AdaptiveCensoring: Что за бурда с этими кандидатама?" |
|
595 |
|
return candidates, 0, -2 |
|
596 |
|
|
|
597 |
|
|
|
598 |
|
# rate = kolík bylo - kolik zůstalo |
|
599 |
|
return selected_candidate, len(candidates) - len(bx.candidates), simplex_id |
|
600 |
|
|
|
601 |
|
|
|
602 |
|
|
|
603 |
|
|
|
604 |
|
def get_candidates(bx, Nsim=int(1e4)): |
|
605 |
|
# -1 = 'out', 0=success, 1=failure, 2=mix |
|
606 |
|
|
|
607 |
|
# не мудрствуя лукаво |
|
608 |
|
user_pf = np.mean(bx.pf_lim) |
|
609 |
|
try: |
|
610 |
|
low_pf = bx.oiss.estimations[1] # failure |
|
611 |
|
upper_pf = 1 - bx.ciss.estimations[0] # sucess |
|
612 |
|
self_pf = (low_pf + upper_pf)/2 |
|
613 |
|
except AttributeError: |
|
614 |
|
self_pf = 0.5 |
|
615 |
|
|
|
616 |
|
# bereme *mean* od svého a uživatelského odhadu |
|
617 |
|
# minimum nejede |
|
618 |
|
sampling_r, __ = bx.sball.get_r_iteration(np.mean((self_pf, user_pf))) |
|
619 |
|
# asi tam bylo sampling_r/bx.base_r, že? |
|
620 |
|
# u stats.norm zadáváme směrodatnou odchylku, je to asi správné |
|
621 |
|
h = f_models.UnCorD([stats.norm(0, sampling_r/bx.base_r) for i in range(bx.nvar)]) |
|
622 |
|
|
|
623 |
|
# for IS_stats |
|
624 |
|
svar = (sampling_r/bx.base_r)**2 # svar like sampling_variance |
|
625 |
|
# něco takovýho bych nahrubo placnul |
|
626 |
|
implicit_multiplicator = svar**bx.nvar * np.exp(bx.nvar/svar - bx.nvar) |
|
627 |
|
|
|
628 |
|
# |
|
629 |
|
# jdeme na to, koťě! |
|
630 |
|
# |
|
631 |
|
|
|
632 |
|
# zgenerujeme vzorky |
|
633 |
|
# nic zajimavýho |
|
634 |
|
h = h(Nsim) |
|
635 |
|
# dropneme priliš vzdálené kandidaty |
|
636 |
|
distance_from_zero = np.sum(h.R**2, axis=1) |
|
637 |
|
mask = distance_from_zero < bx.drop_r |
|
638 |
|
|
|
639 |
|
# a teď bacha! |
|
640 |
|
# tady musíme provést jeden trik |
|
641 |
|
to_sample = bx.f.new_sample(h.R[mask], 'G') # R-ko smerdžíme ako G-čko |
|
642 |
|
w = to_sample.pdf_G / h.pdf_R # snad je to správně |
|
643 |
|
# zabalme do boxu |
|
644 |
|
candidates = SampleBox(to_sample, w, 'BlackBox internal samples and weights') |
|
645 |
|
candidates.implicit_multiplicator = implicit_multiplicator |
|
646 |
|
# vahy máme, zbytek už nejsou naši starosti |
|
647 |
|
return candidates |
|
648 |
|
|
File f_models.py added (mode: 100644) (index 0000000..374874f) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
# coding: utf-8 |
|
3 |
|
|
|
4 |
|
|
|
5 |
|
""" |
|
6 |
|
cs: |
|
7 |
|
|
|
8 |
|
|
|
9 |
|
en: |
|
10 |
|
|
|
11 |
|
""" |
|
12 |
|
|
|
13 |
|
import numpy as np |
|
14 |
|
from scipy import stats |
|
15 |
|
import copy |
|
16 |
|
|
|
17 |
|
|
|
18 |
|
class Ingot: |
|
19 |
|
""" |
|
20 |
|
Prazdná třida pro "nevypalené" vzorky, tj. bez přiřazeného rozdělení |
|
21 |
|
""" |
|
22 |
|
def __init__(self, data, attr='R'): |
|
23 |
|
# data? takový neslaný nazev... |
|
24 |
|
# data suppose to be pandas compatible, i.e. |
|
25 |
|
# nsim, nvar = data.shape |
|
26 |
|
self.attr = attr |
|
27 |
|
try: |
|
28 |
|
self.data = np.atleast_2d(getattr(data, attr)) |
|
29 |
|
except AttributeError: |
|
30 |
|
self.data = np.atleast_2d(data) |
|
31 |
|
|
|
32 |
|
|
|
33 |
|
def __repr__(self): |
|
34 |
|
return "%s(np.%s, '%s')"%('Ingot', repr(self.data), self.attr) |
|
35 |
|
|
|
36 |
|
def __str__(self): |
|
37 |
|
return str(self.data) |
|
38 |
|
|
|
39 |
|
def __len__(self): |
|
40 |
|
return len(self.data) |
|
41 |
|
|
|
42 |
|
def __getitem__(self, slice): |
|
43 |
|
self_copy = copy.copy(self) |
|
44 |
|
# robim kopiu z _data, nebo ne? |
|
45 |
|
self_copy.data = np.atleast_2d(self.data[slice,:]) #.copy() |
|
46 |
|
return self_copy |
|
47 |
|
|
|
48 |
|
|
|
49 |
|
def __getattr__(self, attr): |
|
50 |
|
# Рекурсилы пезьдэт! |
|
51 |
|
if attr in ('attr', 'data'): |
|
52 |
|
raise AttributeError(attr) |
|
53 |
|
#if attr in ('R', 'Rn', 'GK', 'G', 'P', 'U') and attr==self.space: |
|
54 |
|
# return f._data |
|
55 |
|
elif attr == 'nvar': |
|
56 |
|
nsim, nvar = self.data.shape |
|
57 |
|
return nvar |
|
58 |
|
elif attr == 'nsim': |
|
59 |
|
return len(self.data) |
|
60 |
|
|
|
61 |
|
# гулять так гулять |
|
62 |
|
elif attr == self.attr: |
|
63 |
|
return self.data |
|
64 |
|
|
|
65 |
|
raise AttributeError(attr) |
|
66 |
|
|
|
67 |
|
|
|
68 |
|
# vstupné vzorky jsou implicitně R, |
|
69 |
|
# nikoliv z prostoru tohoto krámu |
|
70 |
|
def add_sample(self, sample, space='R'): |
|
71 |
|
# first of all, are you one of us? |
|
72 |
|
if space == self.attr: |
|
73 |
|
# does sample is another sample object? |
|
74 |
|
# zde nechcu, aby spadlo |
|
75 |
|
try: |
|
76 |
|
self.data = np.vstack((self.data, getattr(sample, self.attr))) |
|
77 |
|
except AttributeError: |
|
78 |
|
self.data = np.vstack((self.data, sample)) |
|
79 |
|
|
|
80 |
|
# no, actually |
|
81 |
|
else: |
|
82 |
|
# does sample is another sample object? |
|
83 |
|
# self.data = np.vstack((self.data, getattr(sample, self.attr))) |
|
84 |
|
# ale zde chcu |
|
85 |
|
# (aby spadlo) |
|
86 |
|
raise ValueError |
|
87 |
|
|
|
88 |
|
|
|
89 |
|
# drobná pomucka |
|
90 |
|
def new_sample(f, sample=None, space='R'): |
|
91 |
|
return Ingot(sample, space) # too easy |
|
92 |
|
|
|
93 |
|
|
|
94 |
|
class SNorm: |
|
95 |
|
""" |
|
96 |
|
Standard Gauss distribution |
|
97 |
|
""" |
|
98 |
|
def __init__(self, nvar): |
|
99 |
|
self.__nvar = nvar |
|
100 |
|
# nvar_R + nvar_U + pdf_R |
|
101 |
|
rowsize = nvar*2 + 1 |
|
102 |
|
# data? takový neslaný nazev... |
|
103 |
|
# data suppose to be cKDTree compatible, i.e. |
|
104 |
|
# nsim, nvar = data.shape |
|
105 |
|
self._data = np.empty((0, rowsize), dtype=float) |
|
106 |
|
|
|
107 |
|
def __repr__(self): |
|
108 |
|
return "%s(%s)"%('SNorm', self.__nvar) |
|
109 |
|
|
|
110 |
|
def __str__(f): |
|
111 |
|
return str(f.R) |
|
112 |
|
|
|
113 |
|
def __call__(f, ns=0): |
|
114 |
|
f_copy = eval(f.__repr__()) |
|
115 |
|
if ns: |
|
116 |
|
sample_P = np.random.random((ns, f_copy.nvar)) |
|
117 |
|
sample_R = stats.norm.ppf(sample_P) |
|
118 |
|
|
|
119 |
|
pdfs_R = stats.norm.pdf(sample_R) |
|
120 |
|
pdf_R = np.prod(pdfs_R, axis=1).reshape(-1, 1) |
|
121 |
|
f_copy._data = np.hstack((sample_R, sample_P, pdf_R)) |
|
122 |
|
return f_copy |
|
123 |
|
|
|
124 |
|
def __len__(f): |
|
125 |
|
return len(f._data) |
|
126 |
|
|
|
127 |
|
def __getitem__(f, slice): |
|
128 |
|
f_copy = eval(f.__repr__()) |
|
129 |
|
# robim kopiu z _data, nebo ne? |
|
130 |
|
f_copy._data = np.atleast_2d(f._data[slice,:]) #.copy() |
|
131 |
|
return f_copy |
|
132 |
|
|
|
133 |
|
|
|
134 |
|
# slajsy. Nejsem jist, zda mám robit kopiu, nebo ne. Takže bacha! |
|
135 |
|
def __getattr__(f, attr): |
|
136 |
|
if attr in ('pdf_R', 'pdf_Rn', 'pdf_GK', 'pdf_G'): |
|
137 |
|
return f._data[:,-1] |
|
138 |
|
elif attr in ('R', 'Rn', 'GK', 'G'): |
|
139 |
|
return f._data[:,:f.__nvar] |
|
140 |
|
elif attr in ('P', 'U'): |
|
141 |
|
return f._data[:,f.__nvar:2*f.__nvar] |
|
142 |
|
elif attr == 'nvar': |
|
143 |
|
return f.__nvar |
|
144 |
|
elif attr == 'nsim': |
|
145 |
|
return len(f._data) |
|
146 |
|
elif attr == 'marginals': |
|
147 |
|
return [stats.norm for __ in range(f.__nvar)] |
|
148 |
|
elif attr == 'cor': |
|
149 |
|
return np.diag([1 for __ in range(f.__nvar)]) |
|
150 |
|
|
|
151 |
|
raise AttributeError(attr) |
|
152 |
|
|
|
153 |
|
|
|
154 |
|
# pro určitou konzistenci. Ne že bych chtěl zamykat dveře v Pythonu |
|
155 |
|
def __setattr__(f, attr, value): |
|
156 |
|
if attr in ('_SNorm__nvar','_data'): |
|
157 |
|
f.__dict__[attr] = value |
|
158 |
|
else: |
|
159 |
|
#raise AttributeError('Čo tu robíš?') |
|
160 |
|
#raise AttributeError('Враг не пройдёт!') |
|
161 |
|
#raise AttributeError('Иди отсюда!') |
|
162 |
|
#raise AttributeError('Аслыкъёсы воштыны уг луи!') |
|
163 |
|
raise AttributeError('Atribute %s of %s object is not writable' % (attr, f.__class__.__name__)) |
|
164 |
|
|
|
165 |
|
|
|
166 |
|
def add_sample(f, sample, space='R'): |
|
167 |
|
# does sample is exactly me? |
|
168 |
|
if f.__repr__() == sample.__repr__(): |
|
169 |
|
newdata = sample._data |
|
170 |
|
elif space in ('R', 'Rn', 'GK', 'G'): |
|
171 |
|
# does sample is another f_model object? |
|
172 |
|
try: |
|
173 |
|
sample_R = getattr(sample, space) |
|
174 |
|
except: |
|
175 |
|
# no |
|
176 |
|
sample_R = sample |
|
177 |
|
sample_P = stats.norm.cdf(sample_R) |
|
178 |
|
|
|
179 |
|
pdfs_R = stats.norm.pdf(sample_R) |
|
180 |
|
pdf_R = np.prod(pdfs_R, axis=pdfs_R.ndim-1) |
|
181 |
|
if pdfs_R.ndim == 2: |
|
182 |
|
newdata = np.hstack((sample_R, sample_P, pdf_R.reshape(len(pdf_R), 1))) |
|
183 |
|
else: |
|
184 |
|
newdata = np.hstack((sample_R, sample_P, pdf_R)) |
|
185 |
|
|
|
186 |
|
elif space in ('P', 'U'): |
|
187 |
|
try: |
|
188 |
|
sample_P = getattr(sample, space) |
|
189 |
|
except: |
|
190 |
|
sample_P = sample |
|
191 |
|
sample_R = stats.norm.ppf(sample_P) |
|
192 |
|
|
|
193 |
|
pdfs_R = stats.norm.pdf(sample_R) |
|
194 |
|
pdf_R = np.prod(pdfs_R, axis=pdfs_R.ndim-1) |
|
195 |
|
if pdfs_R.ndim == 2: |
|
196 |
|
newdata = np.hstack((sample_R, sample_P, pdf_R.reshape(len(pdf_R), 1))) |
|
197 |
|
else: |
|
198 |
|
newdata = np.hstack((sample_R, sample_P, pdf_R)) |
|
199 |
|
|
|
200 |
|
f._data = np.vstack((f._data, newdata)) |
|
201 |
|
|
|
202 |
|
|
|
203 |
|
# drobná pomucka |
|
204 |
|
def new_sample(f, sample=None, space='R'): |
|
205 |
|
f_copy = eval(f.__repr__()) |
|
206 |
|
if sample is not None: |
|
207 |
|
f_copy.add_sample(sample, space) |
|
208 |
|
return f_copy |
|
209 |
|
|
|
210 |
|
# # drobná pomucka |
|
211 |
|
# def new_random_sample(f, ns=1): |
|
212 |
|
# f_copy = eval(f.__repr__()) |
|
213 |
|
# f_copy.add_sample(np.random.random((ns, f.nvar)), 'U') |
|
214 |
|
# return f_copy |
|
215 |
|
|
|
216 |
|
|
|
217 |
|
|
|
218 |
|
|
|
219 |
|
|
|
220 |
|
|
|
221 |
|
class UnCorD: # nic moc nazev, ale je přece lepší nez CommonJointDistribution |
|
222 |
|
""" |
|
223 |
|
Takes tuple of scipy stats distribution objects |
|
224 |
|
""" |
|
225 |
|
def __init__(self, marginals): |
|
226 |
|
self.__marginals = marginals |
|
227 |
|
# nvar_Rn + nvar_R + nvar_P + nvar_G + pdf_R + pdf_G |
|
228 |
|
rowsize = len(marginals)*4 + 2 |
|
229 |
|
# data? takový neslaný nazev... |
|
230 |
|
# data suppose to be cKDTree compatible, i.e. |
|
231 |
|
# nsim, nvar** = data.shape |
|
232 |
|
self._data = np.empty((0, rowsize), dtype=float) |
|
233 |
|
|
|
234 |
|
def __repr__(self): |
|
235 |
|
return "%s(%s)"%('UnCorD', repr(self.__marginals)) |
|
236 |
|
|
|
237 |
|
def __str__(f): |
|
238 |
|
return str(f.R) |
|
239 |
|
|
|
240 |
|
def __call__(f, ns=0): |
|
241 |
|
f_copy = copy.copy(f) # nebo deep? |
|
242 |
|
f_copy._data = np.empty((0, f_copy._data.shape[1]), dtype=float) |
|
243 |
|
|
|
244 |
|
if ns: |
|
245 |
|
sample_dict = {'P':np.random.random((ns, f_copy.nvar))} |
|
246 |
|
f._chain(sample_dict) |
|
247 |
|
pdf_G = np.prod(stats.norm.pdf(sample_dict['G']), axis=1).reshape(-1, 1) |
|
248 |
|
pdfs_R = [f.marginals[i].pdf(sample_dict['R'][:, i]) for i in range(f.nvar)] |
|
249 |
|
# je tu fakt axis=0. Dochazí totíž v iterátoru k převracení |
|
250 |
|
pdf_R = np.prod(pdfs_R, axis=0).reshape(-1, 1) |
|
251 |
|
# nvar_Rn + nvar_R + nvar_P + nvar_G + pdf_R + pdf_G |
|
252 |
|
f_copy._data = np.hstack((sample_dict['Rn'], sample_dict['R'], sample_dict['P'], sample_dict['G'], pdf_R, pdf_G)) |
|
253 |
|
return f_copy |
|
254 |
|
|
|
255 |
|
def __len__(f): |
|
256 |
|
return len(f._data) |
|
257 |
|
|
|
258 |
|
def __getitem__(f, slice): |
|
259 |
|
f_copy = copy.copy(f) # nebo deep? |
|
260 |
|
f_copy._data = np.atleast_2d(f._data[slice,:]) #.copy() |
|
261 |
|
return f_copy |
|
262 |
|
|
|
263 |
|
# dúfám, že tyhle slajsy sa vyplatí |
|
264 |
|
def __getattr__(f, attr): |
|
265 |
|
if attr == 'pdf_R': |
|
266 |
|
return f._data[:,-2] |
|
267 |
|
elif attr in ('pdf_GK', 'pdf_G'): |
|
268 |
|
return f._data[:,-1] |
|
269 |
|
elif attr == 'Rn': |
|
270 |
|
return f.__frame(0) |
|
271 |
|
elif attr == 'R': |
|
272 |
|
return f.__frame(1) |
|
273 |
|
elif attr in ('P', 'U'): |
|
274 |
|
return f.__frame(2) |
|
275 |
|
elif attr in ('GK', 'G'): |
|
276 |
|
return f.__frame(3) |
|
277 |
|
|
|
278 |
|
elif attr == 'nvar': |
|
279 |
|
return len(f.__marginals) |
|
280 |
|
elif attr == 'nsim': |
|
281 |
|
return len(f._data) |
|
282 |
|
elif attr == 'marginals': |
|
283 |
|
return f.__marginals |
|
284 |
|
elif attr == 'cor': |
|
285 |
|
return np.diag([1 for __ in range(f.nvar)]) |
|
286 |
|
raise AttributeError(attr) |
|
287 |
|
|
|
288 |
|
# pro určitou konzistenci. Ne že bych chtěl zamykat dveře v Pythonu |
|
289 |
|
def __setattr__(f, attr, value): |
|
290 |
|
if attr in ('_UnCorD__marginals','_data'): |
|
291 |
|
f.__dict__[attr] = value |
|
292 |
|
else: |
|
293 |
|
#raise AttributeError('Аслыкъёсы воштыны уг луи!') |
|
294 |
|
raise AttributeError('Atribute %s of %s object is not writable' % (attr, f.__class__.__name__)) |
|
295 |
|
|
|
296 |
|
def __frame(f, i): |
|
297 |
|
nvar = f.nvar |
|
298 |
|
sl = slice(i*nvar, (i+1)*nvar) |
|
299 |
|
return f._data[:,sl] |
|
300 |
|
|
|
301 |
|
def add_sample(f, sample, space='R'): |
|
302 |
|
# isinstance, ne? |
|
303 |
|
if f.__class__.__name__ == sample.__class__.__name__: |
|
304 |
|
if f.marginals == sample.marginals: |
|
305 |
|
f._data = np.vstack((f._data, sample._data)) |
|
306 |
|
return f |
|
307 |
|
elif space not in ('R', 'Rn', 'P', 'GK', 'G', 'U'): |
|
308 |
|
# co jako, mám gettext sem tahnout?! |
|
309 |
|
raise ValueError('Zadaný prostor %s mi není znám' % space) |
|
310 |
|
raise ValueError('Unknown space %s' % space) |
|
311 |
|
|
|
312 |
|
# does sample is another f_model object? |
|
313 |
|
try: |
|
314 |
|
sample_ = getattr(sample, space) |
|
315 |
|
except: |
|
316 |
|
# no |
|
317 |
|
sample_ = sample |
|
318 |
|
|
|
319 |
|
if space=='GK': |
|
320 |
|
space='G' |
|
321 |
|
elif space=='U': |
|
322 |
|
space='P' |
|
323 |
|
|
|
324 |
|
sample_dict = {space:np.array(sample_, dtype=float).reshape(-1, f.nvar)} |
|
325 |
|
f._chain(sample_dict) |
|
326 |
|
pdf_G = np.prod(stats.norm.pdf(sample_dict['G']), axis=1).reshape(-1, 1) |
|
327 |
|
pdfs_R = [f.marginals[i].pdf(sample_dict['R'][:, i]) for i in range(f.nvar)] |
|
328 |
|
# je tu fakt axis=0. Dochazí totíž v iterátoru k převracení |
|
329 |
|
pdf_R = np.prod(pdfs_R, axis=0).reshape(-1, 1) |
|
330 |
|
# nvar_Rn + nvar_R + nvar_P + nvar_G + pdf_R + pdf_G |
|
331 |
|
newdata = np.hstack((sample_dict['Rn'], sample_dict['R'], sample_dict['P'], sample_dict['G'], pdf_R, pdf_G)) |
|
332 |
|
|
|
333 |
|
f._data = np.vstack((f._data, newdata)) |
|
334 |
|
|
|
335 |
|
|
|
336 |
|
# drobná pomucka |
|
337 |
|
def new_sample(f, sample=None, space='R'): |
|
338 |
|
f_copy = f() |
|
339 |
|
if sample is not None: |
|
340 |
|
f_copy.add_sample(sample, space) |
|
341 |
|
return f_copy |
|
342 |
|
|
|
343 |
|
# # drobná pomucka |
|
344 |
|
# def new_random_sample(f, ns=1): |
|
345 |
|
# f_copy = f() |
|
346 |
|
# f_copy.add_sample(np.random.random((ns, f.nvar)), 'U') |
|
347 |
|
# return f_copy |
|
348 |
|
|
|
349 |
|
def _chain(f, sample_dict): |
|
350 |
|
# chain tam |
|
351 |
|
# чаль татысь |
|
352 |
|
if 'R' not in sample_dict and 'Rn' in sample_dict: |
|
353 |
|
sample_dict['R'] = np.empty_like(sample_dict['Rn']) |
|
354 |
|
for i in range(f.nvar): |
|
355 |
|
sample_dict['R'][:, i] = sample_dict['Rn'][:, i]*f.marginals[i].std() + f.marginals[i].mean() |
|
356 |
|
|
|
357 |
|
if 'P' not in sample_dict and 'R' in sample_dict: |
|
358 |
|
sample_dict['P'] = np.empty_like(sample_dict['R']) |
|
359 |
|
for i in range(f.nvar): |
|
360 |
|
sample_dict['P'][:, i] = f.marginals[i].cdf(sample_dict['R'][:, i]) |
|
361 |
|
|
|
362 |
|
if 'G' not in sample_dict and 'P' in sample_dict: |
|
363 |
|
sample_dict['G'] = stats.norm.ppf(sample_dict['P']) |
|
364 |
|
|
|
365 |
|
# chain sem |
|
366 |
|
# чаль татчи |
|
367 |
|
elif 'P' not in sample_dict and 'G' in sample_dict: |
|
368 |
|
sample_dict['P'] = stats.norm.cdf(sample_dict['G']) |
|
369 |
|
|
|
370 |
|
if 'R' not in sample_dict and 'P' in sample_dict: |
|
371 |
|
sample_dict['R'] = np.empty_like(sample_dict['P']) |
|
372 |
|
for i in range(f.nvar): |
|
373 |
|
sample_dict['R'][:, i] = f.marginals[i].ppf(sample_dict['P'][:, i]) |
|
374 |
|
|
|
375 |
|
if 'Rn' not in sample_dict and 'R' in sample_dict: |
|
376 |
|
sample_dict['Rn'] = np.empty_like(sample_dict['R']) |
|
377 |
|
for i in range(f.nvar): |
|
378 |
|
sample_dict['Rn'][:, i] = (sample_dict['R'][:, i] - f.marginals[i].mean())/f.marginals[i].std() |
|
379 |
|
|
|
380 |
|
|
|
381 |
|
|
|
382 |
|
# def Rn2R(f, sample): |
|
383 |
|
# sample_Rn = np.array(sample).reshape(-1, f.nvar) |
|
384 |
|
# sample_R = np.empty_like(sample_Rn) |
|
385 |
|
# for i in range(f.nvar): |
|
386 |
|
# sample_R[:, i] = sample_Rn[:, i]*f.marginals[i].std() + f.marginals[i].mean() |
|
387 |
|
# return sample_R |
|
388 |
|
# |
|
389 |
|
# def R2P(f, sample): |
|
390 |
|
# sample_R = np.array(sample).reshape(-1, f.nvar) |
|
391 |
|
# sample_P = np.empty_like(sample_R) |
|
392 |
|
# for i in range(f.nvar): |
|
393 |
|
# sample_P[:, i] = sample_Rn[:, i]*f.marginals[i].std() + f.marginals[i].mean() |
|
394 |
|
# return sample_P |
File g_models.py added (mode: 100644) (index 0000000..eb3a878) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
# coding: utf-8 |
|
3 |
|
|
|
4 |
|
|
|
5 |
|
""" |
|
6 |
|
cs: |
|
7 |
|
|
|
8 |
|
|
|
9 |
|
en: |
|
10 |
|
data should be pandas compatible, i.e. |
|
11 |
|
nsim, nvar = data.shape |
|
12 |
|
|
|
13 |
|
g_model returns SampleBox object, which actually contains: |
|
14 |
|
1. what-was-on-input |
|
15 |
|
2. values of perfomance function |
|
16 |
|
AND 3. so called gm_signature - some string to identify data |
|
17 |
|
and do not let them be mixed up. |
|
18 |
|
Currently WhiteBox treat as gm_signature __name__ attribute (free functions has it), |
|
19 |
|
otherwise repr(). Classes supposed to define __repr__ function for correct work. |
|
20 |
|
|
|
21 |
|
Fence off! |
|
22 |
|
Some of performance functions (g_models) are able to draw |
|
23 |
|
failure region boundary, in this case |
|
24 |
|
.get_2D_R_boundary(nrod, xlim, ylim) is defined. |
|
25 |
|
nrod - number of "rods" in "fencing" |
|
26 |
|
xlim, ylim describes your viewport, plotting terminal, whatever |
|
27 |
|
g_model uses these parameters only for inspiration, |
|
28 |
|
g_model is allowed to ignore them |
|
29 |
|
xlim = (xmin, xmax) |
|
30 |
|
ylim = (ymin, ymax) |
|
31 |
|
|
|
32 |
|
returns tuple (or list) of R samples |
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
|
36 |
|
""" |
|
37 |
|
|
|
38 |
|
import numpy as np |
|
39 |
|
from .f_models import Ingot |
|
40 |
|
from .samplebox import SampleBox |
|
41 |
|
|
|
42 |
|
|
|
43 |
|
class GetQuadrantBoundary2D: |
|
44 |
|
""" |
|
45 |
|
sebemenší pomocná třida pro vykreslení hranici L tvaru |
|
46 |
|
""" |
|
47 |
|
def __init__(self, center_point=(0,0), quadrant='I'): |
|
48 |
|
""" |
|
49 |
|
quadrants also сэрегъёс-compatible |
|
50 |
|
#### CORNERS 2D ##### |
|
51 |
|
# print(сэрегъёс) |
|
52 |
|
# numbering: |
|
53 |
|
# 2 | 3 |
|
54 |
|
# -----|----- |
|
55 |
|
# 0 | 1 |
|
56 |
|
""" |
|
57 |
|
self.center_point = center_point |
|
58 |
|
self.quadrant = quadrant |
|
59 |
|
|
|
60 |
|
def __call__(self, nrod=100, xlim=(-5,5), ylim=(-5,5)): |
|
61 |
|
xc, yc = self.center_point |
|
62 |
|
xmin = min(*xlim, xc-1) |
|
63 |
|
xmax = max(*xlim, xc+1) |
|
64 |
|
ymin = min(*ylim, yc-1) |
|
65 |
|
ymax = max(*ylim, yc+1) |
|
66 |
|
|
|
67 |
|
nrod = int(nrod/2) |
|
68 |
|
# mně nic hezčího prostě nenapadá( |
|
69 |
|
if self.quadrant in ('I', 3): |
|
70 |
|
xbound = np.append(np.full(nrod, xc), np.linspace(xc, xmax, nrod, endpoint=True)) |
|
71 |
|
ybound = np.append(np.linspace(ymax, yc, nrod, endpoint=True), np.full(nrod, yc)) |
|
72 |
|
elif self.quadrant in ('II', 2): |
|
73 |
|
xbound = np.append(np.linspace(xmin, xc, nrod, endpoint=True), np.full(nrod, xc)) |
|
74 |
|
ybound = np.append(np.full(nrod, yc), np.linspace(yc, ymax, nrod, endpoint=True)) |
|
75 |
|
elif self.quadrant in ('III', 0): |
|
76 |
|
xbound = np.append(np.linspace(xmin, xc, nrod, endpoint=True), np.full(nrod, xc)) |
|
77 |
|
ybound = np.append(np.full(nrod, yc), np.linspace(yc, ymin, nrod, endpoint=True)) |
|
78 |
|
else: # self.quadrant in ('IV', 1): |
|
79 |
|
xbound = np.append(np.full(nrod, xc), np.linspace(xc, xmax, nrod, endpoint=True)) |
|
80 |
|
ybound = np.append(np.linspace(ymin, yc, nrod, endpoint=True), np.full(nrod, yc)) |
|
81 |
|
|
|
82 |
|
|
|
83 |
|
# sample compatible |
|
84 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
85 |
|
bound_R = np.vstack((xbound, ybound)).T |
|
86 |
|
# tuple of tuple |
|
87 |
|
return (Ingot(bound_R),) |
|
88 |
|
|
|
89 |
|
|
|
90 |
|
|
|
91 |
|
def get_R_coordinates(input_sample, envar=0): |
|
92 |
|
""" |
|
93 |
|
Tohle je pomocná funkce, vrácí g_modelům numpy 2d pole s daty |
|
94 |
|
|
|
95 |
|
envar - zadavejte, pokud chcete zkontrolovat |
|
96 |
|
počet náhodných proměnných |
|
97 |
|
envar like estimated number of variables |
|
98 |
|
""" |
|
99 |
|
# is it sample object? |
|
100 |
|
try: |
|
101 |
|
if envar > 0 and input_sample.nvar != envar: |
|
102 |
|
raise ValueError('%sD data expected, but %sD sample given'% (envar, input_sample.nvar)) |
|
103 |
|
else: |
|
104 |
|
return input_sample.R |
|
105 |
|
|
|
106 |
|
# it is not an sample object, |
|
107 |
|
# but maybe numpy can handle this? |
|
108 |
|
except AttributeError: |
|
109 |
|
sample = np.atleast_2d(np.array(input_sample)) |
|
110 |
|
# invar like input number of variables |
|
111 |
|
nsim, invar = sample.shape |
|
112 |
|
if envar > 0 and invar != envar: |
|
113 |
|
raise ValueError('%sD data expected, but %sD sample given'% (envar, invar)) |
|
114 |
|
else: |
|
115 |
|
return sample |
|
116 |
|
|
|
117 |
|
class Linear_nD: |
|
118 |
|
""" |
|
119 |
|
Class takes for inicialization tuple of betas |
|
120 |
|
Betas are coeffitients in sense of Regression Analysis |
|
121 |
|
|
|
122 |
|
g= a*X1 + b*X2 + c |
|
123 |
|
becames |
|
124 |
|
gm = Linear_nD(betas=(a,b,c)) |
|
125 |
|
gm(samples) |
|
126 |
|
gm.get_2D_R_boundary(nrod, xlim) returns |
|
127 |
|
xbounds a ybounds zabalené do tuplu, ty zabalené do listu |
|
128 |
|
""" |
|
129 |
|
|
|
130 |
|
def __init__(self, betas): |
|
131 |
|
self._betas = betas |
|
132 |
|
|
|
133 |
|
# sign |
|
134 |
|
def __repr__(self): |
|
135 |
|
return 'Linear_nD(%s)' % repr(self._betas) |
|
136 |
|
|
|
137 |
|
def __call__(self, input_sample): |
|
138 |
|
selfnvar = len(self._betas)-1 |
|
139 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
140 |
|
sample = get_R_coordinates(input_sample, selfnvar) |
|
141 |
|
# teďkom zasahujeme přímo do tohoto pole |
|
142 |
|
sim = sample.copy() |
|
143 |
|
for i in range(selfnvar): |
|
144 |
|
sim[:,i] = sim[:,i]*self._betas[i] |
|
145 |
|
g = np.sum(sim, axis=1) + self._betas[-1] |
|
146 |
|
return SampleBox(input_sample, g, repr(self)) |
|
147 |
|
|
|
148 |
|
|
|
149 |
|
|
|
150 |
|
# Fence off! |
|
151 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), *args): |
|
152 |
|
""" |
|
153 |
|
Fence off! |
|
154 |
|
nrod - number of rods in fencing |
|
155 |
|
""" |
|
156 |
|
|
|
157 |
|
xbound = np.linspace(xlim[0], xlim[1], nrod, endpoint=True) |
|
158 |
|
|
|
159 |
|
selfnvar = len(self._betas)-1 |
|
160 |
|
# g= a*X1 + b*X2 + 0*X3 + 0*X4 + ... + c |
|
161 |
|
a = self._betas[0] |
|
162 |
|
b = self._betas[1] |
|
163 |
|
c = self._betas[-1] |
|
164 |
|
|
|
165 |
|
# 1D je spíše vtip |
|
166 |
|
if selfnvar == 1: |
|
167 |
|
return (-c/a) |
|
168 |
|
else: |
|
169 |
|
# sample compatible |
|
170 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
171 |
|
bound_R = np.array((xbound, -c/b + (-a/b)*xbound)).T |
|
172 |
|
# tuple of tuple |
|
173 |
|
return (Ingot(bound_R),) |
|
174 |
|
|
|
175 |
|
|
|
176 |
|
class Z_sum: |
|
177 |
|
""" |
|
178 |
|
suma velicin plus beta*sqrt(Nvar. ) |
|
179 |
|
Pro IID Gaussian ma tohle ind. spol. beta = beta |
|
180 |
|
The same as Linear_nD, but defined via |
|
181 |
|
beta in sense of reliability index |
|
182 |
|
""" |
|
183 |
|
def __init__(self, nvar, beta_exact): |
|
184 |
|
self._nvar = nvar |
|
185 |
|
self._beta_exact = beta_exact |
|
186 |
|
|
|
187 |
|
# sign |
|
188 |
|
def __repr__(self): |
|
189 |
|
return 'Z_sum(%s, %s)' % (repr(self._nvar), repr(self._beta_exact)) |
|
190 |
|
|
|
191 |
|
def __call__(self, input_sample): |
|
192 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
193 |
|
sample = get_R_coordinates(input_sample, self._nvar) |
|
194 |
|
g = np.sum(sample, axis=1) + self._beta_exact * np.sqrt(self._nvar) |
|
195 |
|
return SampleBox(input_sample, g, repr(self)) |
|
196 |
|
|
|
197 |
|
# Fence off! |
|
198 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), *args): |
|
199 |
|
""" |
|
200 |
|
Fence off! |
|
201 |
|
nrod - number of rods in fencing |
|
202 |
|
""" |
|
203 |
|
|
|
204 |
|
xbound = np.linspace(xlim[0], xlim[1], nrod, endpoint=True) |
|
205 |
|
|
|
206 |
|
# g= a*X1 + b*X2 + 0*X3 + 0*X4 + ... + c |
|
207 |
|
a = 1 |
|
208 |
|
b = 1 |
|
209 |
|
c = self._beta_exact * np.sqrt(self._nvar) |
|
210 |
|
|
|
211 |
|
# sample compatible |
|
212 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
213 |
|
bound_R = np.array((xbound, -c/b + (-a/b)*xbound)).T |
|
214 |
|
# tuple of tuple |
|
215 |
|
return (Ingot(bound_R),) |
|
216 |
|
|
|
217 |
|
|
|
218 |
|
|
|
219 |
|
class Z_prod: |
|
220 |
|
""" |
|
221 |
|
soucin velicin plus nějaká konstanta |
|
222 |
|
# g= X1 * X2 * X3 * X4 + c |
|
223 |
|
""" |
|
224 |
|
# tenhle model ani nvar si neukladá, tohle vůbec neřeší |
|
225 |
|
def __init__(self, const): |
|
226 |
|
self._const = const |
|
227 |
|
|
|
228 |
|
# sign |
|
229 |
|
def __repr__(self): |
|
230 |
|
return 'Z_prod(%s)' % repr(self._const) |
|
231 |
|
|
|
232 |
|
def __call__(self, input_sample): |
|
233 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
234 |
|
sample = get_R_coordinates(input_sample) |
|
235 |
|
g = np.prod(sample, axis=1) + self._const |
|
236 |
|
return SampleBox(input_sample, g, repr(self)) |
|
237 |
|
|
|
238 |
|
# Fence off! |
|
239 |
|
def get_2D_R_boundary(self, nrod=100, *args): |
|
240 |
|
""" |
|
241 |
|
Fence off! |
|
242 |
|
nrod - number of rods in fencing |
|
243 |
|
""" |
|
244 |
|
# g= X1 * X2 + c |
|
245 |
|
# a^2 = 2*X^2 |
|
246 |
|
# a=b= X * sqrt(2) |
|
247 |
|
# a^2 = 2*c |
|
248 |
|
# r = a*b / np.sqrt(b**2 * np.cos(phi)**2 - a**2 * np.sin(phi)**2) |
|
249 |
|
|
|
250 |
|
c = self._const |
|
251 |
|
_c = np.sign(c) |
|
252 |
|
# náš oblibený trik - hranici nakreslime pomoci polárních souřádnic |
|
253 |
|
phi = np.linspace(0.25*np.pi, (0.25+_c/2)*np.pi, nrod , endpoint=False)[1:] |
|
254 |
|
r = np.sqrt(2*c / (np.sin(phi)**2 - np.cos(phi)**2)) |
|
255 |
|
bound_x_left = r * np.cos(phi+np.pi/4) |
|
256 |
|
bound_y_left = r * np.sin(phi+np.pi/4) |
|
257 |
|
|
|
258 |
|
phi = np.linspace(-0.75*np.pi, (_c/2-0.75)*np.pi, nrod , endpoint=False)[1:] |
|
259 |
|
r = np.sqrt(2*c / (np.sin(phi)**2 - np.cos(phi)**2)) |
|
260 |
|
bound_x_right = r * np.cos(phi+np.pi/4) |
|
261 |
|
bound_y_right = r * np.sin(phi+np.pi/4) |
|
262 |
|
|
|
263 |
|
# sample compatible |
|
264 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
265 |
|
bound_R_left = np.array((bound_x_left, bound_y_left)).T |
|
266 |
|
bound_R_right = np.array((bound_x_right, bound_y_right)).T |
|
267 |
|
# tuple of samples |
|
268 |
|
return (Ingot(bound_R_left), Ingot(bound_R_right)) |
|
269 |
|
|
|
270 |
|
|
|
271 |
|
|
|
272 |
|
class Z_min: |
|
273 |
|
""" |
|
274 |
|
min velicin plus nějaká konstanta |
|
275 |
|
# g= min(X1, X2, X3, X4) + c |
|
276 |
|
""" |
|
277 |
|
def __init__(self, const): |
|
278 |
|
self._const = const |
|
279 |
|
self.get_2D_R_boundary = GetQuadrantBoundary2D(center_point=(-const,-const), quadrant='I') |
|
280 |
|
|
|
281 |
|
# sign |
|
282 |
|
def __repr__(self): |
|
283 |
|
return 'Z_min(%s)' % repr(self._const) |
|
284 |
|
|
|
285 |
|
def __call__(self, input_sample): |
|
286 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
287 |
|
sample = get_R_coordinates(input_sample) |
|
288 |
|
g = np.min(sample, axis=1) + self._const |
|
289 |
|
return SampleBox(input_sample, g, repr(self)) |
|
290 |
|
|
|
291 |
|
# samotná "volaná" se určí v __init__ |
|
292 |
|
# trik aby se nezabindila |
|
293 |
|
@staticmethod |
|
294 |
|
def get_2D_R_boundary(): return None |
|
295 |
|
|
|
296 |
|
|
|
297 |
|
|
|
298 |
|
class Z_sumexp: |
|
299 |
|
""" |
|
300 |
|
""" |
|
301 |
|
def __init__(self, const): |
|
302 |
|
self._const = const |
|
303 |
|
|
|
304 |
|
# sign |
|
305 |
|
def __repr__(self): |
|
306 |
|
return 'Z_sumexp(%s)' % repr(self._const) |
|
307 |
|
|
|
308 |
|
def __call__(self, input_sample): |
|
309 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
310 |
|
sample = get_R_coordinates(input_sample) |
|
311 |
|
g = np.sum(np.exp(-(sample**2)), axis=1) + self._const |
|
312 |
|
return SampleBox(input_sample, g, repr(self)) |
|
313 |
|
|
|
314 |
|
# Fence off! |
|
315 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), ylim=(-5,5)): |
|
316 |
|
""" |
|
317 |
|
Fence off! |
|
318 |
|
nrod - number of rods in fencing |
|
319 |
|
""" |
|
320 |
|
|
|
321 |
|
|
|
322 |
|
def e_bound(xbound): return np.sqrt(-np.log(-self._const - np.exp(-xbound**2))) |
|
323 |
|
|
|
324 |
|
# let's mirror about (s,s) point |
|
325 |
|
# 0 = 2*e^(-s^2)+c |
|
326 |
|
# log(-c/2) = -s^2 |
|
327 |
|
# s = sqrt(-log(-c/2)) |
|
328 |
|
s = np.sqrt(-np.log(-self._const/2)) |
|
329 |
|
xmin = min(*xlim, -s-1) |
|
330 |
|
xmax = max(*xlim, s+1) |
|
331 |
|
ymin = min(*ylim, -s-1) |
|
332 |
|
ymax = max(*ylim, s+1) |
|
333 |
|
|
|
334 |
|
xb_1eft = np.linspace(xmin, -s, nrod, endpoint=False) |
|
335 |
|
xb_right = np.linspace(xmax, s, nrod, endpoint=False) |
|
336 |
|
yb_up = np.linspace(s, ymax, nrod) |
|
337 |
|
yb_down = np.linspace(-s, ymin, nrod) |
|
338 |
|
|
|
339 |
|
|
|
340 |
|
# numerace je náhodná |
|
341 |
|
bound_R_1 = np.array((np.append(xb_1eft, -e_bound(yb_up)), np.append(e_bound(xb_1eft), yb_up))).T |
|
342 |
|
bound_R_2 = np.array((np.append(xb_1eft, -e_bound(yb_down)), np.append(-e_bound(xb_1eft), yb_down))).T |
|
343 |
|
bound_R_3 = np.array((np.append(xb_right, e_bound(yb_up)), np.append(e_bound(xb_right), yb_up))).T |
|
344 |
|
bound_R_4 = np.array((np.append(xb_right, e_bound(yb_down)), np.append(-e_bound(xb_right), yb_down))).T |
|
345 |
|
|
|
346 |
|
# sample compatible |
|
347 |
|
# tuple of samples |
|
348 |
|
return (Ingot(bound_R_1), Ingot(bound_R_2), Ingot(bound_R_3), Ingot(bound_R_4)) |
|
349 |
|
|
|
350 |
|
|
|
351 |
|
|
|
352 |
|
|
|
353 |
|
class S_ballSin2D: |
|
354 |
|
""" |
|
355 |
|
c = 0.5 # wave amplitude in Gaussian space |
|
356 |
|
d = 3.0 # average of sine fiunction in Gaussian space |
|
357 |
|
k = 6 # number of sine waves (design points) |
|
358 |
|
""" |
|
359 |
|
def __init__(self, c, d, k): |
|
360 |
|
self._c = c |
|
361 |
|
self._d = d |
|
362 |
|
self._k = k |
|
363 |
|
|
|
364 |
|
# sign |
|
365 |
|
def __repr__(self): |
|
366 |
|
return 'S_ballSin2D(%s,%s,%s)' % (self._c, self._d, self._k) |
|
367 |
|
|
|
368 |
|
def __call__(self, input_sample): |
|
369 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
370 |
|
sample = get_R_coordinates(input_sample, 2) |
|
371 |
|
|
|
372 |
|
R2 = np.sum(np.square(sample), axis=1) |
|
373 |
|
R = np.sqrt(R2) |
|
374 |
|
phi = np.arctan2(sample[:,1] , sample[:,0]) #arctan2(y,x) |
|
375 |
|
rmax = self._c * np.sin(self._k * phi) + self._d |
|
376 |
|
g = rmax - R |
|
377 |
|
return SampleBox(input_sample, g, repr(self)) |
|
378 |
|
|
|
379 |
|
# Fence off! |
|
380 |
|
def get_2D_R_boundary(self, nrod=100, *args): |
|
381 |
|
""" |
|
382 |
|
Fence off! |
|
383 |
|
nrod - number of rods in fencing |
|
384 |
|
""" |
|
385 |
|
|
|
386 |
|
phi = np.linspace(0, 6.283185307, nrod , endpoint=True) |
|
387 |
|
r = self._c * np.sin(self._k * phi) + self._d |
|
388 |
|
bound_x = r * np.cos(phi) |
|
389 |
|
bound_y = r * np.sin(phi) |
|
390 |
|
|
|
391 |
|
# sample compatible |
|
392 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
393 |
|
bound_R = np.array((bound_x, bound_y)).T |
|
394 |
|
# tuple of samples |
|
395 |
|
return (Ingot(bound_R),) |
|
396 |
|
|
|
397 |
|
|
|
398 |
|
class Z_sumsq: |
|
399 |
|
""" |
|
400 |
|
""" |
|
401 |
|
def __init__(self, const): |
|
402 |
|
self._const = const |
|
403 |
|
|
|
404 |
|
# sign |
|
405 |
|
def __repr__(self): |
|
406 |
|
return 'Z_sumsq(%s)' % repr(self._const) |
|
407 |
|
|
|
408 |
|
def __call__(self, input_sample): |
|
409 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
410 |
|
sample = get_R_coordinates(input_sample) |
|
411 |
|
g = np.sum(sample**2, axis=1) - self._const |
|
412 |
|
return SampleBox(input_sample, g, repr(self)) |
|
413 |
|
|
|
414 |
|
# Fence off! |
|
415 |
|
def get_2D_R_boundary(self, nrod=100, *args): |
|
416 |
|
""" |
|
417 |
|
Fence off! |
|
418 |
|
nrod - number of rods in fencing |
|
419 |
|
""" |
|
420 |
|
|
|
421 |
|
phi = np.linspace(0, 2*np.pi, nrod , endpoint=True) |
|
422 |
|
r = np.sqrt(self._const) |
|
423 |
|
bound_x = r * np.cos(phi) |
|
424 |
|
bound_y = r * np.sin(phi) |
|
425 |
|
|
|
426 |
|
# sample compatible |
|
427 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
428 |
|
bound_R = np.array((bound_x, bound_y)).T |
|
429 |
|
# tuple of samples |
|
430 |
|
return (Ingot(bound_R),) |
|
431 |
|
|
|
432 |
|
|
|
433 |
|
|
|
434 |
|
class S_ball: |
|
435 |
|
""" |
|
436 |
|
Find 10 differences with Z_sumsq |
|
437 |
|
""" |
|
438 |
|
def __init__(self, r): |
|
439 |
|
self._r = r |
|
440 |
|
|
|
441 |
|
# sign |
|
442 |
|
def __repr__(self): |
|
443 |
|
return 'S_ball(%s)' % repr(self._r) |
|
444 |
|
|
|
445 |
|
def __call__(self, input_sample): |
|
446 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
447 |
|
sample = get_R_coordinates(input_sample) |
|
448 |
|
R2 = np.sum(np.square(sample), axis=1) |
|
449 |
|
g = self._r**2 - R2 |
|
450 |
|
return SampleBox(input_sample, g, repr(self)) |
|
451 |
|
|
|
452 |
|
# Fence off! |
|
453 |
|
def get_2D_R_boundary(self, nrod=100, *args): |
|
454 |
|
""" |
|
455 |
|
Fence off! |
|
456 |
|
nrod - number of rods in fencing |
|
457 |
|
""" |
|
458 |
|
phi = np.linspace(0, 6.283185307, nrod, endpoint=True) |
|
459 |
|
r = self._r |
|
460 |
|
bound_x = r * np.cos(phi) |
|
461 |
|
bound_y = r * np.sin(phi) |
|
462 |
|
|
|
463 |
|
# sample compatible |
|
464 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
465 |
|
bound_R = np.array((bound_x, bound_y)).T |
|
466 |
|
# tuple of samples |
|
467 |
|
return (Ingot(bound_R),) |
|
468 |
|
|
|
469 |
|
|
|
470 |
|
class Exp_P: |
|
471 |
|
""" |
|
472 |
|
g = y - 1./np.exp(x)**5 |
|
473 |
|
""" |
|
474 |
|
def __init__(self, k=1., pow=5): |
|
475 |
|
self._k = k |
|
476 |
|
self._pow = pow |
|
477 |
|
|
|
478 |
|
# sign |
|
479 |
|
def __repr__(self): |
|
480 |
|
return 'Exp_P(%s, %s)' % (self._k, self._pow) |
|
481 |
|
|
|
482 |
|
def __call__(self, input_sample): |
|
483 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
484 |
|
sample = get_R_coordinates(input_sample, 2) |
|
485 |
|
|
|
486 |
|
x = sample[:,0] |
|
487 |
|
y = sample[:,1] |
|
488 |
|
g = y - self._k/np.exp(x)**self._pow |
|
489 |
|
return SampleBox(input_sample, g, repr(self)) |
|
490 |
|
|
|
491 |
|
# Fence off! |
|
492 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), *args): |
|
493 |
|
""" |
|
494 |
|
Fence off! |
|
495 |
|
nrod - number of rods in fencing |
|
496 |
|
""" |
|
497 |
|
|
|
498 |
|
xbound = np.linspace(xlim[0], xlim[1], nrod, endpoint=True) |
|
499 |
|
|
|
500 |
|
bound_y = self._k/np.exp(xbound)**self._pow |
|
501 |
|
|
|
502 |
|
# sample compatible |
|
503 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
504 |
|
bound_R = np.array((xbound, bound_y)).T |
|
505 |
|
# tuple of samples |
|
506 |
|
return (Ingot(bound_R),) |
|
507 |
|
|
|
508 |
|
|
|
509 |
|
class Sin2D: |
|
510 |
|
""" |
|
511 |
|
""" |
|
512 |
|
def __init__(self, kx=-1/4., ky=-1, kxsin=5, const=5): |
|
513 |
|
self._kx = kx |
|
514 |
|
self._ky = ky |
|
515 |
|
self._kxsin = kxsin |
|
516 |
|
self._const = const |
|
517 |
|
|
|
518 |
|
# sign |
|
519 |
|
def __repr__(self): |
|
520 |
|
return 'Sin2D(%s, %s, %s, %s)' % (self._kx, self._ky, self._kxsin, self._const) |
|
521 |
|
|
|
522 |
|
def __call__(self, input_sample): |
|
523 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
524 |
|
sample = get_R_coordinates(input_sample, 2) |
|
525 |
|
|
|
526 |
|
x = sample[:,0] |
|
527 |
|
y = sample[:,1] |
|
528 |
|
g = self._kx * x + self._ky * y + np.sin(self._kxsin*x) + self._const |
|
529 |
|
return SampleBox(input_sample, g, repr(self)) |
|
530 |
|
|
|
531 |
|
# Fence off! |
|
532 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), *args): |
|
533 |
|
""" |
|
534 |
|
Fence off! |
|
535 |
|
nrod - number of rods in fencing |
|
536 |
|
""" |
|
537 |
|
xbound = np.linspace(xlim[0], xlim[1], nrod, endpoint=True) |
|
538 |
|
|
|
539 |
|
bound_y = -(self._kx * xbound + np.sin(self._kxsin * xbound) + self._const) / self._ky |
|
540 |
|
|
|
541 |
|
# sample compatible |
|
542 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
543 |
|
bound_R = np.array((xbound, bound_y)).T |
|
544 |
|
# tuple of samples |
|
545 |
|
return (Ingot(bound_R),) |
|
546 |
|
|
|
547 |
|
|
|
548 |
|
|
|
549 |
|
class Prod_FourBetas: |
|
550 |
|
""" |
|
551 |
|
g = beta^2/2 - |x1 * x2| |
|
552 |
|
""" |
|
553 |
|
def __init__(self, beta=2.0): |
|
554 |
|
self._beta = beta |
|
555 |
|
|
|
556 |
|
# sign |
|
557 |
|
def __repr__(self): |
|
558 |
|
return 'Prod_FourBetas(beta=%s)' % repr(self._beta) |
|
559 |
|
|
|
560 |
|
def __call__(self, input_sample): |
|
561 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
562 |
|
sample = get_R_coordinates(input_sample) |
|
563 |
|
|
|
564 |
|
g = self._beta**2/2.0 - np.prod(np.abs(sample), axis=1) |
|
565 |
|
return SampleBox(input_sample, g, repr(self)) |
|
566 |
|
|
|
567 |
|
# Fence off! |
|
568 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), ylim=(-5,5)): |
|
569 |
|
""" |
|
570 |
|
Fence off! |
|
571 |
|
nrod - number of rods in fencing |
|
572 |
|
""" |
|
573 |
|
# zde vynechal abs(), ale úpravil znaménka dolů |
|
574 |
|
# don't ask me why. Ачим но уг тодӥськы. |
|
575 |
|
def e_bound(xbound): return self._beta**2/2 / xbound |
|
576 |
|
|
|
577 |
|
# let's mirror about (s,s) point |
|
578 |
|
# 0 = beta^2/2 - s^2 |
|
579 |
|
# beta^2/2 = s^2 |
|
580 |
|
# s = beta/sqrt(2) |
|
581 |
|
s = self._beta / np.sqrt(2) |
|
582 |
|
xmin = min(*xlim, -s-1) |
|
583 |
|
xmax = max(*xlim, s+1) |
|
584 |
|
ymin = min(*ylim, -s-1) |
|
585 |
|
ymax = max(*ylim, s+1) |
|
586 |
|
|
|
587 |
|
xb_1eft = np.linspace(xmin, -s, nrod, endpoint=False) |
|
588 |
|
xb_right = np.linspace(xmax, s, nrod, endpoint=False) |
|
589 |
|
yb_up = np.linspace(s, ymax, nrod) |
|
590 |
|
yb_down = np.linspace(-s, ymin, nrod) |
|
591 |
|
|
|
592 |
|
|
|
593 |
|
# numerace je náhodná. Je tu hračka se znaménky. |
|
594 |
|
bound_R_1 = np.array((np.append(xb_1eft, -e_bound(yb_up)), np.append(-e_bound(xb_1eft), yb_up))).T |
|
595 |
|
bound_R_2 = np.array((np.append(xb_1eft, e_bound(yb_down)), np.append(e_bound(xb_1eft), yb_down))).T |
|
596 |
|
bound_R_3 = np.array((np.append(xb_right, e_bound(yb_up)), np.append(e_bound(xb_right), yb_up))).T |
|
597 |
|
bound_R_4 = np.array((np.append(xb_right, -e_bound(yb_down)), np.append(-e_bound(xb_right), yb_down))).T |
|
598 |
|
|
|
599 |
|
# sample compatible |
|
600 |
|
# tuple of samples |
|
601 |
|
return (Ingot(bound_R_1), Ingot(bound_R_2), Ingot(bound_R_3), Ingot(bound_R_4)) |
|
602 |
|
|
|
603 |
|
|
|
604 |
|
|
|
605 |
|
class BlackSwan2D: |
|
606 |
|
""" |
|
607 |
|
a = 2.0 # boundary for x1 |
|
608 |
|
b = 5.0 # boundary for x2 |
|
609 |
|
y = np.where(sim[:,0] <= a, sim[:,0], sim[:,1]) |
|
610 |
|
# pro x1 <= a y = x1 |
|
611 |
|
# pro x1 > a y = x2 |
|
612 |
|
g = b - y # failure for b<y |
|
613 |
|
""" |
|
614 |
|
def __init__(self, a=2.0, b=5.0): |
|
615 |
|
self._a = a |
|
616 |
|
self._b = b |
|
617 |
|
if a<b: |
|
618 |
|
self.get_2D_R_boundary = GetQuadrantBoundary2D(center_point=(a, b), quadrant='I') |
|
619 |
|
|
|
620 |
|
# sign |
|
621 |
|
def __repr__(self): |
|
622 |
|
return 'BlackSwan2D(%s, %s)' % (self._a, self._b) |
|
623 |
|
|
|
624 |
|
def __call__(self, input_sample): |
|
625 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
626 |
|
sample = get_R_coordinates(input_sample, 2) |
|
627 |
|
|
|
628 |
|
y = np.where(sample[:,0] <= self._a, sample[:,0], sample[:,1]) |
|
629 |
|
g = self._b - y # failure for b<y |
|
630 |
|
return SampleBox(input_sample, g, repr(self)) |
|
631 |
|
|
|
632 |
|
|
|
633 |
|
# samotná "volaná" se určí v __init__ |
|
634 |
|
# trik aby se nezabindila |
|
635 |
|
@staticmethod |
|
636 |
|
def get_2D_R_boundary(*args, **kwargs): |
|
637 |
|
# jako kdyby .get_2D_R_boundary nebyla vůbec definována. |
|
638 |
|
raise AttributeError |
|
639 |
|
|
|
640 |
|
|
|
641 |
|
|
|
642 |
|
class Metaballs2D: |
|
643 |
|
""" |
|
644 |
|
""" |
|
645 |
|
def __init__(self, const=5): |
|
646 |
|
# sebemenší parametrizace |
|
647 |
|
self._const = const |
|
648 |
|
|
|
649 |
|
# sign |
|
650 |
|
def __repr__(self): |
|
651 |
|
return 'Metaballs2D(%s)' % repr(self._const) |
|
652 |
|
|
|
653 |
|
def __call__(self, input_sample): |
|
654 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
655 |
|
sample = get_R_coordinates(input_sample, 2) |
|
656 |
|
|
|
657 |
|
x1 = sample[:,0] |
|
658 |
|
x2 = sample[:,1] |
|
659 |
|
|
|
660 |
|
# auxiliary variables |
|
661 |
|
y1 = 4/9*(x1 + 2 )**2 + 1/25 * (x2 )**2 |
|
662 |
|
y2 = 1/4*(x1 - 2.5)**2 + 1/25 * (x2-0.5)**2 |
|
663 |
|
g = 30.0/( y1**2 + 1.0 ) + 20.0/( y2**2 + 1.0 ) - self._const |
|
664 |
|
return SampleBox(input_sample, g, repr(self)) |
|
665 |
|
|
|
666 |
|
#hranice poruchy ӧвӧл :( |
|
667 |
|
|
|
668 |
|
|
|
669 |
|
|
|
670 |
|
class Logistic2D: |
|
671 |
|
""" |
|
672 |
|
""" |
|
673 |
|
def __init__(self, c1=5, c2=4, easy_version=True): |
|
674 |
|
# sebemenší parametrizace |
|
675 |
|
self._c1 = c1 |
|
676 |
|
self._c2 = c2 |
|
677 |
|
self.easy_version = easy_version |
|
678 |
|
|
|
679 |
|
# For both versions |
|
680 |
|
|
|
681 |
|
self.get_2D_R_boundary = GetQuadrantBoundary2D(center_point=(c1,-c2), quadrant='II') |
|
682 |
|
|
|
683 |
|
def __call__(self, input_sample): |
|
684 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
685 |
|
sample = get_R_coordinates(input_sample, 2) |
|
686 |
|
|
|
687 |
|
x1 = sample[:,0] |
|
688 |
|
x2 = sample[:,1] |
|
689 |
|
|
|
690 |
|
# auxiliary variables |
|
691 |
|
y1 = self._c1 - x1 |
|
692 |
|
y2 = self._c2 + x2 |
|
693 |
|
y3 = 1.0/(1+np.exp(-2.0*y2)) - 0.5 |
|
694 |
|
|
|
695 |
|
if self.easy_version: |
|
696 |
|
g = np.minimum(y1,y2) # easy version for SuS |
|
697 |
|
else: |
|
698 |
|
g = np.minimum(y1,y3) # difficult version for SuS |
|
699 |
|
return SampleBox(input_sample, g, repr(self)) |
|
700 |
|
|
|
701 |
|
def __repr__(self): |
|
702 |
|
return 'Logistic2D(%s, %s, easy_version=%s)'%(self._c1, self._c2, self.easy_version) |
|
703 |
|
|
|
704 |
|
def pf_expression(self, f_model): |
|
705 |
|
""" |
|
706 |
|
We trying to say how to calculate pf |
|
707 |
|
to someone, who will know actual distribution |
|
708 |
|
""" |
|
709 |
|
a = f_model.marginals[0].sf(self._c1) |
|
710 |
|
b = f_model.marginals[1].cdf(-self._c2) |
|
711 |
|
# subtract the twice calculated intersection |
|
712 |
|
return a + b - a*b, 'exact solution' |
|
713 |
|
|
|
714 |
|
@staticmethod |
|
715 |
|
def get_2D_R_boundary(): return None |
|
716 |
|
|
|
717 |
|
|
|
718 |
|
|
|
719 |
|
class CosExp2D: |
|
720 |
|
""" |
|
721 |
|
""" |
|
722 |
|
def __init__(self, s=5): |
|
723 |
|
# sebemenší parametrizace |
|
724 |
|
self._s = s |
|
725 |
|
|
|
726 |
|
# sign |
|
727 |
|
def __repr__(self): |
|
728 |
|
return 'CosExp2D(s=%s)' % repr(self._s) |
|
729 |
|
|
|
730 |
|
def __call__(self, input_sample): |
|
731 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
732 |
|
sample = get_R_coordinates(input_sample) |
|
733 |
|
|
|
734 |
|
# auxiliary variables |
|
735 |
|
s = self._s |
|
736 |
|
# g = cos((np.exp(-xm-s ))*xm) * np.exp(-(x +s )/3) |
|
737 |
|
g = np.cos( ( np.exp(-sample[:,0] - s ) )*sample[:,0]) * np.exp( -(sample[:,0] + s )/3 ) |
|
738 |
|
return SampleBox(input_sample, g, repr(self)) |
|
739 |
|
|
|
740 |
|
# Fence off! |
|
741 |
|
def get_2D_R_boundary(self, nrod=100, xlim=(-5,5), ylim=(-5,5)): |
|
742 |
|
""" |
|
743 |
|
Fence off! |
|
744 |
|
nrod - number of rods in fencing |
|
745 |
|
""" |
|
746 |
|
|
|
747 |
|
if self._s == 5: |
|
748 |
|
# it is not mine |
|
749 |
|
xa = -4.05229846333861 |
|
750 |
|
xb = -4.95067172463682 |
|
751 |
|
xc = -5.37859367619679 |
|
752 |
|
xd = -5.66345816541508 |
|
753 |
|
xe = -5.87765022259327 |
|
754 |
|
xf = -6.04950202015156 |
|
755 |
|
xg = -6.19309680892552 |
|
756 |
|
|
|
757 |
|
# ikska |
|
758 |
|
xes = (xa, xb, xc, xd, xe, xf, xg) |
|
759 |
|
|
|
760 |
|
boundaries = [] |
|
761 |
|
ymin, ymax = ylim |
|
762 |
|
|
|
763 |
|
for x in xes: |
|
764 |
|
xbound = np.full(nrod, x) |
|
765 |
|
ybound = np.linspace(ymin, ymax, nrod, endpoint=True) |
|
766 |
|
# sample compatible |
|
767 |
|
# малы транспонировать кароно? Озьы кулэ! |
|
768 |
|
bound_R = np.vstack((xbound, ybound)).T |
|
769 |
|
boundaries.append(Ingot(bound_R)) |
|
770 |
|
|
|
771 |
|
|
|
772 |
|
return boundaries |
|
773 |
|
|
|
774 |
|
|
|
775 |
|
|
|
776 |
|
else: |
|
777 |
|
# jako kdyby .get_2D_R_boundary nebyla vůbec definována. |
|
778 |
|
raise AttributeError("Hranice poruchy pro s!=5 není spočitana") |
|
779 |
|
|
|
780 |
|
|
|
781 |
|
|
|
782 |
|
|
|
783 |
|
|
|
784 |
|
|
|
785 |
|
# |
|
786 |
|
# Free functions |
|
787 |
|
# |
|
788 |
|
|
|
789 |
|
# signature |
|
790 |
|
#inspect.currentframe().f_code.co_name |
|
791 |
|
|
|
792 |
|
|
|
793 |
|
def piecewise_2D_linear(input_sample): |
|
794 |
|
selfnvar = 2 |
|
795 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
796 |
|
sample = get_R_coordinates(input_sample, selfnvar) |
|
797 |
|
x1, x2 = sample[:,0], sample[:,1] |
|
798 |
|
g1 = np.where(x1 > 3.5, 4-x1, 0.85-0.1*x1) |
|
799 |
|
g2 = np.where(x2 > 2, 0.5-0.1*x2, 2.3-x2) |
|
800 |
|
g = np.min((g1,g2), axis=0) |
|
801 |
|
return SampleBox(input_sample, g, 'piecewise_2D_linear') |
|
802 |
|
|
|
803 |
|
# boundary |
|
804 |
|
piecewise_2D_linear.get_2D_R_boundary = GetQuadrantBoundary2D(center_point=(4,5), quadrant='III') |
|
805 |
|
piecewise_2D_linear.pf_expression = lambda fm, a=4, b=5: (fm.marginals[0].sf(a) + fm.marginals[1].sf(b) - fm.marginals[0].sf(a)*fm.marginals[1].sf(b), 'exact solution') |
|
806 |
|
|
|
807 |
|
|
|
808 |
|
|
|
809 |
|
|
|
810 |
|
def non_chi_squares(input_sample): |
|
811 |
|
selfnvar = 2 |
|
812 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
813 |
|
sample = get_R_coordinates(input_sample, selfnvar) |
|
814 |
|
x1, x2 = sample[:,0], sample[:,1] |
|
815 |
|
g = 0.1 * (52 - 1.5 * x1**2 - x2**2) |
|
816 |
|
return SampleBox(input_sample, g, 'non_chi_squares') |
|
817 |
|
|
|
818 |
|
|
|
819 |
|
|
|
820 |
|
|
|
821 |
|
def branin_2D(input_sample): |
|
822 |
|
""" |
|
823 |
|
Rescaled Branin function |
|
824 |
|
""" |
|
825 |
|
selfnvar = 2 |
|
826 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
827 |
|
sample = get_R_coordinates(input_sample, selfnvar) |
|
828 |
|
x1, x2 = sample[:,0], sample[:,1] |
|
829 |
|
g = 80 - ((15*x2 - 5/(4*np.pi**2)*(15*x1-5)**2 + 5/np.pi*(15*x1-5)-6)**2 + 10*(1-1/8/np.pi)*np.cos(15*x1-5) + 10) |
|
830 |
|
return SampleBox(input_sample, g, 'branin_2D') |
|
831 |
|
|
|
832 |
|
|
|
833 |
|
|
|
834 |
|
|
|
835 |
|
|
|
836 |
|
def four_branch_2D(input_sample): |
|
837 |
|
""" |
|
838 |
|
Four branch system |
|
839 |
|
""" |
|
840 |
|
selfnvar = 2 |
|
841 |
|
# očekávam, že get_R_coordinates mně vrátí 2D pole |
|
842 |
|
sample = get_R_coordinates(input_sample, selfnvar) |
|
843 |
|
x1, x2 = sample[:,0], sample[:,1] |
|
844 |
|
g1 = 3 + 0.1*(x1 - x2)**2 - (x1 + x2)/np.sqrt(2) |
|
845 |
|
g2 = 3 + 0.1*(x1 - x2)**2 + (x1 + x2)/np.sqrt(2) |
|
846 |
|
g3 = (x1 - x2) + 7/np.sqrt(2) |
|
847 |
|
g4 = (x2 - x1) + 7/np.sqrt(2) # byl tu překlep v članku |
|
848 |
|
g = np.min((g1, g2, g3, g4), axis=0) |
|
849 |
|
return SampleBox(input_sample, g, 'four_branch_2D') |
|
850 |
|
|
|
851 |
|
|
|
852 |
|
|
File reader.py added (mode: 100644) (index 0000000..fc18a41) |
|
1 |
|
|
|
2 |
|
import csv |
|
3 |
|
import numpy as np |
|
4 |
|
from .samplebox import SampleBox |
|
5 |
|
from .f_models import Ingot |
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
class Reader: |
|
10 |
|
""" |
|
11 |
|
stateful object to keep consistency of using append() |
|
12 |
|
First rule of writing API - write example of use |
|
13 |
|
# musel tedy tady bejt... |
|
14 |
|
|
|
15 |
|
zkusím takovehle delegování |
|
16 |
|
|
|
17 |
|
# reader bude pokažde otevirat/zavirat soubor, což není úplně ideální, |
|
18 |
|
# ale zás, |
|
19 |
|
# předpokladá se, že každej vzorek musí být schvalen vědeckou radou |
|
20 |
|
# csv umožňuje dozápis |
|
21 |
|
""" |
|
22 |
|
|
|
23 |
|
# piece of black magic |
|
24 |
|
def __new__(cls, filename, f_model=None): |
|
25 |
|
""" |
|
26 |
|
Здесь отталкиваемся от файла |
|
27 |
|
""" |
|
28 |
|
sb = super().__new__(cls) |
|
29 |
|
sb.filename = filename |
|
30 |
|
try: # sample box nemá vůbec smysl schovavat |
|
31 |
|
sb.sample_box = reader(filename, f_model) |
|
32 |
|
sb.append_allowed = True |
|
33 |
|
except FileNotFoundError: |
|
34 |
|
# Штош... |
|
35 |
|
sb.append_allowed = False |
|
36 |
|
if f_model is not None: |
|
37 |
|
sb.sample_box = SampleBox(f_model) |
|
38 |
|
print("Reader:", filename + '.csv', "ӧвӧл") |
|
39 |
|
return sb |
|
40 |
|
|
|
41 |
|
@classmethod |
|
42 |
|
def FromSampleBox(cls, filename, sample_box): |
|
43 |
|
""" |
|
44 |
|
Здесь отталкиваемся от сэмплбоксу |
|
45 |
|
""" |
|
46 |
|
sb = super().__new__(cls) |
|
47 |
|
# nepotrebujeme žádné rozdělení, nic |
|
48 |
|
sb.sample_box = sample_box |
|
49 |
|
sb.filename = filename |
|
50 |
|
sb.append_allowed = False |
|
51 |
|
return sb |
|
52 |
|
|
|
53 |
|
def __len__(self): |
|
54 |
|
return self.sample_box.nsim |
|
55 |
|
|
|
56 |
|
def __getitem__(sb, slice): |
|
57 |
|
# stačí vratit sample_box |
|
58 |
|
return sb.sample_box[slice] |
|
59 |
|
|
|
60 |
|
def __getattr__(sb, attr): |
|
61 |
|
# По всем (почти) вопросам обращайтесь |
|
62 |
|
# на нашу горячую линию |
|
63 |
|
if attr == 'sample_box': |
|
64 |
|
return None |
|
65 |
|
else: |
|
66 |
|
return getattr(sb.sample_box, attr) |
|
67 |
|
|
|
68 |
|
# def read(self): |
|
69 |
|
# return self.__sbox |
|
70 |
|
|
|
71 |
|
def force_read(self): |
|
72 |
|
try: |
|
73 |
|
self.sample_box = reader(self.filename, self.sample_box.sampled_plan) |
|
74 |
|
self.append_allowed = True |
|
75 |
|
return self.sample_box |
|
76 |
|
except AttributeError: |
|
77 |
|
self.sample_box = reader(self.filename) |
|
78 |
|
self.append_allowed = True |
|
79 |
|
return self.sample_box |
|
80 |
|
except FileNotFoundError: |
|
81 |
|
# Штош... |
|
82 |
|
print("Reader:", self.filename + '.csv', "opravdu ӧвӧл") |
|
83 |
|
|
|
84 |
|
def write(self): |
|
85 |
|
export(self.filename, self.sample_box) |
|
86 |
|
self.append_allowed = True |
|
87 |
|
|
|
88 |
|
# что бы эта бурда могла делать? |
|
89 |
|
# def force_write(self): |
|
90 |
|
# self.__sbox = sample_box |
|
91 |
|
# export(self.__filename, sample_box) |
|
92 |
|
|
|
93 |
|
def add_sample(self, sample_box): |
|
94 |
|
if self.append_allowed and (self.sample_box.gm_signature == sample_box.gm_signature): |
|
95 |
|
self.sample_box.add_sample(sample_box) |
|
96 |
|
append(self.filename, sample_box) |
|
97 |
|
elif 'sample_box' in dir(self): |
|
98 |
|
self.sample_box.add_sample(sample_box) |
|
99 |
|
if self.sample_box.nsim > 0: |
|
100 |
|
export(self.filename, self.sample_box) |
|
101 |
|
self.append_allowed = True |
|
102 |
|
else: |
|
103 |
|
self.sample_box = sample_box |
|
104 |
|
if self.sample_box.nsim > 0: |
|
105 |
|
export(self.filename, self.sample_box) |
|
106 |
|
self.append_allowed = True |
|
107 |
|
|
|
108 |
|
|
|
109 |
|
# průbežný export |
|
110 |
|
# if bx.filename: |
|
111 |
|
# if gm_signature == input_sample.gm_signature: |
|
112 |
|
# reader.append(bx.filename + '.csv', input_sample) |
|
113 |
|
# else: |
|
114 |
|
# bx.export(bx.filename) |
|
115 |
|
|
|
116 |
|
|
|
117 |
|
|
|
118 |
|
|
|
119 |
|
# |
|
120 |
|
# import simulations |
|
121 |
|
# |
|
122 |
|
def reader(filename, f_model=None): |
|
123 |
|
rows = [] |
|
124 |
|
with open(filename + '.csv', 'r', newline='') as f: |
|
125 |
|
reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC) |
|
126 |
|
for row in reader: |
|
127 |
|
rows.append(row) |
|
128 |
|
|
|
129 |
|
# předpokladam, že na prvních dvou řadcích jsou gm_signature a popísek |
|
130 |
|
data = np.atleast_2d(rows[2:]) |
|
131 |
|
|
|
132 |
|
if f_model is None: |
|
133 |
|
# veškeré datové řadky, sloupy - od (včetně) do (nezahrnuje) |
|
134 |
|
return SampleBox(Ingot(data[:,:-2]), data[:,-2:-1].flatten(), rows[0][0]) |
|
135 |
|
else: |
|
136 |
|
sample = f_model() |
|
137 |
|
sample.add_sample(data[:,:-2]) |
|
138 |
|
return SampleBox(sample, data[:,-2:-1].flatten(), rows[0][0]) |
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
|
142 |
|
def append(filename, sample_box): |
|
143 |
|
""" |
|
144 |
|
Святые угодники, объясните мне кто-нибудь, почему я здесь не использ..овал |
|
145 |
|
context manager? |
|
146 |
|
""" |
|
147 |
|
if sample_box.nsim == 0: |
|
148 |
|
return False |
|
149 |
|
|
|
150 |
|
with open(filename + '.csv', 'a', newline='') as csvfile: |
|
151 |
|
csv_writer = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC) |
|
152 |
|
|
|
153 |
|
# bacha! není tu žádná kontrola, co se kam zapisuje! |
|
154 |
|
for i in range(sample_box.nsim): |
|
155 |
|
row = [sample_box.R[i, j] for j in range(sample_box.nvar)] |
|
156 |
|
row.append(sample_box.g_values[i]) |
|
157 |
|
row.append(int(sample_box.failsi[i])) |
|
158 |
|
csv_writer.writerow(row) |
|
159 |
|
#csvfile.close() |
|
160 |
|
|
|
161 |
|
def Export(filename, sample_box): |
|
162 |
|
""" |
|
163 |
|
vratíme nový Reader objekt |
|
164 |
|
""" |
|
165 |
|
export(filename, sample_box) |
|
166 |
|
return Reader.FromSampleBox(filename, sample_box) |
|
167 |
|
|
|
168 |
|
def export(filename, sample_box): |
|
169 |
|
if sample_box.nsim == 0: |
|
170 |
|
return False |
|
171 |
|
|
|
172 |
|
with open(filename + '.csv', 'w', newline='') as csvfile: |
|
173 |
|
csv_writer = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC) |
|
174 |
|
|
|
175 |
|
# gm_signature |
|
176 |
|
csv_writer.writerow([sample_box.gm_signature]) |
|
177 |
|
|
|
178 |
|
# popísky |
|
179 |
|
row = ['var ' + str(j+1) for j in range(sample_box.nvar)] |
|
180 |
|
row.append('value') |
|
181 |
|
row.append('failure') |
|
182 |
|
csv_writer.writerow(row) |
|
183 |
|
|
|
184 |
|
for i in range(sample_box.nsim): |
|
185 |
|
row = [sample_box.R[i, j] for j in range(sample_box.nvar)] |
|
186 |
|
row.append(sample_box.g_values[i]) |
|
187 |
|
row.append(int(sample_box.failsi[i])) |
|
188 |
|
csv_writer.writerow(row) |
|
189 |
|
# csvfile.close() |
|
190 |
|
|
|
191 |
|
|
File whitebox.py added (mode: 100644) (index 0000000..5134b7a) |
|
1 |
|
#!/usr/bin/env python |
|
2 |
|
# coding: utf-8 |
|
3 |
|
|
|
4 |
|
""" |
|
5 |
|
Zde leží whiteboxy |
|
6 |
|
Zatimco BlackBox pěčlivě ukladá věškerá data, |
|
7 |
|
věškeré sady vzorků, průběžné odhady a tak, |
|
8 |
|
WhiteBox musí obsahovat jen pf_exact, které buď už předem zná, |
|
9 |
|
nebo jej spočítá a není vůbec/nachren nutný cokoliv ukladat. |
|
10 |
|
|
|
11 |
|
en: |
|
12 |
|
f_model + g_model = pf |
|
13 |
|
WhiteBox = [f_model, g_model, pf_exact] |
|
14 |
|
pf_exact is most important part of WhiteBox |
|
15 |
|
Knowledge of pf is the only reason to create WhiteBox |
|
16 |
|
|
|
17 |
|
whitebox actually IS g_model PLUS: |
|
18 |
|
.f f_model |
|
19 |
|
.pf_exact |
|
20 |
|
.pf_exact_method |
|
21 |
|
""" |
|
22 |
|
import numpy as np |
|
23 |
|
from scipy import stats |
|
24 |
|
from scipy import special # for S_ball |
|
25 |
|
from scipy import integrate # for S_ball |
|
26 |
|
|
|
27 |
|
from .samplebox import SampleBox |
|
28 |
|
|
|
29 |
|
from . import f_models |
|
30 |
|
import copy |
|
31 |
|
from . import g_models |
|
32 |
|
|
|
33 |
|
from . import plot |
|
34 |
|
|
|
35 |
|
|
|
36 |
|
class WhiteBox: |
|
37 |
|
""" |
|
38 |
|
Bazová třida pro dědictví |
|
39 |
|
|
|
40 |
|
úkolem whiteboxu je spočítat pf-ko |
|
41 |
|
.pf_exact |
|
42 |
|
.pf_exact_method |
|
43 |
|
""" |
|
44 |
|
pf_exact_method = 'None' |
|
45 |
|
|
|
46 |
|
def __init__(wt, f_model, g_model): |
|
47 |
|
wt.gm = g_model |
|
48 |
|
wt.f = f_model |
|
49 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
50 |
|
wt.sample_box = SampleBox(wt.f(), gm_signature=wt.gm_signature) |
|
51 |
|
|
|
52 |
|
try: # no to jsme líný. Možná samotný g_model tuší jak se spočte pf-ko? |
|
53 |
|
wt.pf_exact, wt.pf_exact_method = g_model.pf_expression(f_model) |
|
54 |
|
except AttributeError: |
|
55 |
|
pass |
|
56 |
|
|
|
57 |
|
def __str__(wt): |
|
58 |
|
return wt.__class__.__name__ + ' of' + str(wt.g_model) |
|
59 |
|
|
|
60 |
|
def __repr__(wt): |
|
61 |
|
return 'WhiteBox(%s, %s)' %(repr(wt.f), repr(wt.gm)) |
|
62 |
|
|
|
63 |
|
def __len__(wt): |
|
64 |
|
return len(wt.sample_box) |
|
65 |
|
|
|
66 |
|
|
|
67 |
|
def __call__(wt, sample=None): |
|
68 |
|
if sample is None: |
|
69 |
|
sample = wt.sample_box() |
|
70 |
|
|
|
71 |
|
# zamykame se do sebe |
|
72 |
|
result = wt.gm(sample) |
|
73 |
|
wt.sample_box.add_sample(result) |
|
74 |
|
return result |
|
75 |
|
|
|
76 |
|
|
|
77 |
|
def __getitem__(self, slice): |
|
78 |
|
self_copy = copy.copy(self) |
|
79 |
|
self_copy.sample_box = self.sample_box[slice] |
|
80 |
|
return self_copy |
|
81 |
|
|
|
82 |
|
def __getattr__(wt, attr): |
|
83 |
|
# co patři g_modelovi? |
|
84 |
|
if attr == 'get_2D_R_boundary': |
|
85 |
|
return wt.gm.get_2D_R_boundary |
|
86 |
|
elif attr == 'gm_signature': |
|
87 |
|
try: # byla volná funkce? |
|
88 |
|
return wt.gm.__name__ |
|
89 |
|
# asi to byla trida? |
|
90 |
|
except AttributeError: |
|
91 |
|
return repr(wt.gm) |
|
92 |
|
|
|
93 |
|
|
|
94 |
|
# co mělo být definováno ve WhiteBoxu? Ale teda není? |
|
95 |
|
elif attr == 'pf_exact_method': |
|
96 |
|
raise AttributeError |
|
97 |
|
|
|
98 |
|
# пытка-непытка |
|
99 |
|
elif attr == 'pf_exact': |
|
100 |
|
if 'beta_exact' in wt.__dict__: |
|
101 |
|
return stats.norm.cdf(-wt.beta_exact) |
|
102 |
|
else: |
|
103 |
|
# мы нищего не знаем |
|
104 |
|
raise AttributeError("Nothing known about failure probability") |
|
105 |
|
|
|
106 |
|
elif attr == 'beta_exact': |
|
107 |
|
if 'pf_exact' in wt.__dict__: |
|
108 |
|
return -stats.norm.ppf(wt.pf_exact) |
|
109 |
|
else: |
|
110 |
|
raise AttributeError("Nothing known about failure probability") |
|
111 |
|
|
|
112 |
|
|
|
113 |
|
# branime sa rekurzii |
|
114 |
|
# defend against recursion |
|
115 |
|
elif attr == 'sample_box': |
|
116 |
|
raise AttributeError |
|
117 |
|
|
|
118 |
|
# zbytek teda nievím |
|
119 |
|
else: |
|
120 |
|
return getattr(wt.sample_box, attr) |
|
121 |
|
|
|
122 |
|
# just plot, green points, red points... |
|
123 |
|
plot2D = plot.plot2D |
|
124 |
|
plot3D = plot.plot3D |
|
125 |
|
|
|
126 |
|
|
|
127 |
|
def get_2D_boundary(wt, nrod=100, viewport_sample=None, viewport_space='R'): |
|
128 |
|
""" |
|
129 |
|
Fence off! |
|
130 |
|
nrod - number of rods in fencing |
|
131 |
|
viewport_sample - limit points of viewport |
|
132 |
|
(function will get xlim and ylim from there, |
|
133 |
|
assuming there will be at least two points) |
|
134 |
|
""" |
|
135 |
|
|
|
136 |
|
if (viewport_sample is not None): # and viewport_sample.nsim: #>0 |
|
137 |
|
breakpoint |
|
138 |
|
if viewport_space=='R': |
|
139 |
|
viewport_sample_R = viewport_sample |
|
140 |
|
else: |
|
141 |
|
viewport_sample_R = wt.f.new_sample(viewport_sample, viewport_space).R |
|
142 |
|
else: |
|
143 |
|
viewport_sample_R = wt.f.new_sample([[-7,-7],[7,7]], 'G').R |
|
144 |
|
|
|
145 |
|
# should I tolerate nD? |
|
146 |
|
viewport_sample_R = np.vstack((viewport_sample_R, wt.sample_box.R[:,0:2])) |
|
147 |
|
xmin = np.min(viewport_sample_R[:,0]) |
|
148 |
|
xmax = np.max(viewport_sample_R[:,0]) |
|
149 |
|
ymin = np.min(viewport_sample_R[:,1]) |
|
150 |
|
ymax = np.max(viewport_sample_R[:,1]) |
|
151 |
|
|
|
152 |
|
# získám seznam polí |
|
153 |
|
bounds_R = wt.get_2D_R_boundary(nrod, (xmin, xmax), (ymin, ymax)) |
|
154 |
|
# transformuji na seznam vzorků |
|
155 |
|
return [wt.f.new_sample(bounds_R[i]) for i in range(len(bounds_R))] |
|
156 |
|
|
|
157 |
|
|
|
158 |
|
|
|
159 |
|
|
|
160 |
|
# Monte Carlo, n-krátá realizace |
|
161 |
|
def MC(wt, Nsim=int(1e6)): |
|
162 |
|
|
|
163 |
|
|
|
164 |
|
# tohlensto může bejt dost těžkým |
|
165 |
|
result = wt.gm(wt.f(Nsim)) |
|
166 |
|
# should I stay or should I go? |
|
167 |
|
wt.sample_box.add_sample(result) |
|
168 |
|
|
|
169 |
|
# je tu jakoby že g_model vždy vrací nějakej sample_box |
|
170 |
|
pf_exact = np.count_nonzero(result.failsi)/Nsim |
|
171 |
|
|
|
172 |
|
# šlo by to? |
|
173 |
|
if wt.pf_exact_method == 'None' or wt.pf_exact_method == 'MC' and wt.Nsim <= Nsim: |
|
174 |
|
wt.pf_exact = pf_exact |
|
175 |
|
wt.Nsim = Nsim |
|
176 |
|
wt.pf_exact_method = 'MC' |
|
177 |
|
|
|
178 |
|
print('Monte Carlo estimation of pf is %s (%s simulations)'%(pf_exact, Nsim)) |
|
179 |
|
return result |
|
180 |
|
|
|
181 |
|
|
|
182 |
|
|
|
183 |
|
# IS, (n-2)-krátá realizace, n>2 |
|
184 |
|
def IS(wt, Nsim=int(1e4), h_model=None, IS_mode='G'): |
|
185 |
|
""" |
|
186 |
|
IS_mode - v jakých souřadnicích robím merge a jaká PDF použiváme? |
|
187 |
|
může být 'R' nebo 'G' |
|
188 |
|
jinde # čo jinde? |
|
189 |
|
""" |
|
190 |
|
|
|
191 |
|
if h_model is not None: |
|
192 |
|
wt.h = h_model |
|
193 |
|
wt.IS_mode = IS_mode |
|
194 |
|
elif 'h' not in wt.__dict__: |
|
195 |
|
wt.h = f_models.UnCorD([stats.norm(0,2.5) for i in range(wt.f.nvar)]) |
|
196 |
|
wt.IS_mode = 'G' |
|
197 |
|
|
|
198 |
|
|
|
199 |
|
# |
|
200 |
|
# jdeme na to, koťě! |
|
201 |
|
# |
|
202 |
|
|
|
203 |
|
# zgenerujeme vzorky |
|
204 |
|
# nic zajimavýho |
|
205 |
|
wt.h = wt.h(Nsim) |
|
206 |
|
|
|
207 |
|
# a teď bacha! |
|
208 |
|
if wt.IS_mode == 'R': |
|
209 |
|
# jestli máme to právé vzorkovácí rozdělení - tak nemáme čo robiť |
|
210 |
|
to_sample = wt.f.new_sample(wt.h) # smerdží se to po R |
|
211 |
|
# w like weights |
|
212 |
|
wt.w = to_sample.pdf_R / wt.h.pdf_R |
|
213 |
|
elif wt.IS_mode == 'G': |
|
214 |
|
# tady musíme provést jeden trik |
|
215 |
|
to_sample = wt.f.new_sample(wt.h.R, 'G') # R-ko smerdžíme ako G-čko |
|
216 |
|
wt.w = to_sample.pdf_G / wt.h.pdf_R # snad je to správně |
|
217 |
|
else: |
|
218 |
|
# шо-то тут не то... |
|
219 |
|
# čo blbnéš, kámo? |
|
220 |
|
# What's going on with my IS_mode? |
|
221 |
|
raise ValueError("IS_mode should be either 'R' or 'G'") |
|
222 |
|
|
|
223 |
|
# vahy máme, jedeme dál |
|
224 |
|
# sample_box jíž není prázdnej |
|
225 |
|
result = wt.gm(to_sample) |
|
226 |
|
wt.sample_box.add_sample(result) |
|
227 |
|
|
|
228 |
|
# hodilo by sa to? |
|
229 |
|
pf_exact = np.sum(wt.w[result.failsi])/Nsim |
|
230 |
|
|
|
231 |
|
if wt.pf_exact_method in ('None', 'IS_norm', 'IS'): |
|
232 |
|
wt.Nsim = Nsim |
|
233 |
|
if pf_exact < 1: |
|
234 |
|
wt.pf_exact = pf_exact |
|
235 |
|
wt.pf_exact_method = 'IS' |
|
236 |
|
else: |
|
237 |
|
# ať mně nerobí ostudu |
|
238 |
|
wt.pf_exact = np.sum(wt.w[result.failsi]) / np.sum(wt.w) |
|
239 |
|
wt.pf_exact_method = 'IS_norm' |
|
240 |
|
|
|
241 |
|
print('Importance Sampling pure estimation of pf is %s (%s simulations)'%(pf_exact, Nsim)) |
|
242 |
|
return result |
|
243 |
|
|
|
244 |
|
|
|
245 |
|
|
|
246 |
|
class HyperPlane(WhiteBox): # куда ж без него... |
|
247 |
|
def __init__(self, betas=(1,2,3)): |
|
248 |
|
""" |
|
249 |
|
Class takes for inicialization tuple of betas |
|
250 |
|
Betas are coeffitients in sense of Regression Analysis (well, not really) |
|
251 |
|
g= a*X1 + b*X2 + c |
|
252 |
|
betas=(a,b,c) |
|
253 |
|
""" |
|
254 |
|
self._betas = betas |
|
255 |
|
self.gm = g_models.Linear_nD(betas) |
|
256 |
|
self.f = f_models.SNorm(len(betas)-1) |
|
257 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
258 |
|
self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
259 |
|
|
|
260 |
|
# tady už je to ta, "náše" beta ) |
|
261 |
|
# beta = c/np.sqrt(a**2 + b**2) |
|
262 |
|
self.beta_exact = betas[-1]/np.sqrt(np.sum(np.array(betas[:-1])**2)) |
|
263 |
|
self.pf_exact = stats.norm.cdf(-self.beta_exact) |
|
264 |
|
self.pf_exact_method = 'FORM (exact solution)' # Ang, Tang and Pythagoras |
|
265 |
|
|
|
266 |
|
|
|
267 |
|
def __str__(wt): |
|
268 |
|
return 'HyperPlaneBox%sD'%(len(wt._betas)-1) |
|
269 |
|
|
|
270 |
|
def __repr__(wt): |
|
271 |
|
return 'HyperPlane(%s)' % repr(wt._betas) |
|
272 |
|
|
|
273 |
|
|
|
274 |
|
|
|
275 |
|
class Weibull_Z_min(WhiteBox): |
|
276 |
|
def __init__(self, wb_scales=(1,1), shape=5, **kwargs): |
|
277 |
|
""" |
|
278 |
|
parametry pravdepodobnostniho rozdeleni pro Z_min, pripadne dalsi fce s Weib. velicinami |
|
279 |
|
wb_scales=(1,1) - tuple of Weibull scale parameters, len(wb_scales)==nvar |
|
280 |
|
shape = 5 |
|
281 |
|
je třeba zadat buď pf_exact, nebo konštantu u funkce minima Z_min |
|
282 |
|
""" |
|
283 |
|
self.wb_scales = wb_scales |
|
284 |
|
self.shape = 5 |
|
285 |
|
self.f = f_models.UnCorD([stats.weibull_min(shape, scale=sc_i) for sc_i in wb_scales]) |
|
286 |
|
|
|
287 |
|
# scale parametr minima z nvar Weibullovskych |
|
288 |
|
# tohle by platilo pro stejná rozdělení |
|
289 |
|
#sn = scale * nvar ** (-1.0 / shape) |
|
290 |
|
# pro nás musí to být něco takovýho |
|
291 |
|
sn = np.sum(np.power(wb_scales, -shape)) ** (-1.0 / shape) |
|
292 |
|
self.rvweibmin = stats.weibull_min(shape, scale=sn) |
|
293 |
|
|
|
294 |
|
# je třeba zadat buď pf_exact, nebo konštantu u funkce minima Z_min |
|
295 |
|
self.pf_exact_method = 'exact solution' |
|
296 |
|
if 'pf_exact' in kwargs: |
|
297 |
|
self.pf_exact = kwargs['pf_exact'] |
|
298 |
|
self.const = -self.rvweibmin.ppf(self.pf_exact) |
|
299 |
|
elif 'beta_exact' in kwargs: |
|
300 |
|
self.beta_exact = kwargs['beta_exact'] |
|
301 |
|
self.const = -self.rvweibmin.ppf(self.pf_exact) |
|
302 |
|
elif 'const' in kwargs: |
|
303 |
|
self.const = kwargs['const'] |
|
304 |
|
self.pf_exact = self.rvweibmin.cdf(-self.const) # asi |
|
305 |
|
else: |
|
306 |
|
# no to teda uživatele пошли |
|
307 |
|
self.pf_exact = 1e-4 |
|
308 |
|
self.const = -self.rvweibmin.ppf(self.pf_exact) |
|
309 |
|
|
|
310 |
|
self.gm = g_models.Z_min(self.const) |
|
311 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
312 |
|
self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
313 |
|
|
|
314 |
|
def __str__(self): |
|
315 |
|
return 'Weibull_Z_min%sD'%(len(self.wb_scales)) |
|
316 |
|
|
|
317 |
|
def __repr__(self): |
|
318 |
|
return 'Weibull_Z_min(%s, %s, pf_exact=%s)' % (repr(self.wb_scales), repr(self.shape), repr(self.pf_exact)) |
|
319 |
|
|
|
320 |
|
|
|
321 |
|
|
|
322 |
|
|
|
323 |
|
# já teda tridu zababachnu, ale že to teoreticky platí jsem neodvozoval |
|
324 |
|
# UPD: testy neprochází, logicky hodnoty nesedí |
|
325 |
|
# vůbec netuším jak by se to mohlo odvozovat |
|
326 |
|
class Gaussian_Z_sumexp(WhiteBox): |
|
327 |
|
def __init__(self, nvar=2, **kwargs): |
|
328 |
|
""" |
|
329 |
|
je třeba zadat buď pf_exact, nebo konštantu u funkce Z_sumexp |
|
330 |
|
""" |
|
331 |
|
|
|
332 |
|
# je tam předpoklad SNormu? |
|
333 |
|
self.f = f_models.SNorm(nvar) |
|
334 |
|
|
|
335 |
|
self.C1 = np.sqrt(np.sqrt(5) / 3. - 1. / 3.) |
|
336 |
|
self.C2 = np.sqrt(3.) / 3. |
|
337 |
|
# je třeba zadat buď pf_exact, nebo konštantu u funkce Z_sumexp |
|
338 |
|
self.pf_exact_method = 'tešt solution' |
|
339 |
|
if 'pf_exact' in kwargs: |
|
340 |
|
self.pf_exact = kwargs['pf_exact'] |
|
341 |
|
self.C = self.beta_exact * self.C1 * np.sqrt(nvar) - self.C2 * nvar |
|
342 |
|
elif 'beta_exact' in kwargs: |
|
343 |
|
self.beta_exact = kwargs['beta_exact'] |
|
344 |
|
self.C = self.beta_exact * self.C1 * np.sqrt(nvar) - self.C2 * nvar |
|
345 |
|
elif 'const' in kwargs: |
|
346 |
|
self.const = kwargs['const'] |
|
347 |
|
self.C = self.const |
|
348 |
|
self.beta_exact = (self.C + self.C2 * nvar) / self.C1 / np.sqrt(nvar) |
|
349 |
|
elif 'C' in kwargs: |
|
350 |
|
self.C = kwargs['C'] |
|
351 |
|
self.beta_exact = (self.C + self.C2 * nvar) / self.C1 / np.sqrt(nvar) |
|
352 |
|
else: |
|
353 |
|
# no to teda uživatele пошли |
|
354 |
|
self.pf_exact = 1e-4 |
|
355 |
|
self.C = self.beta_exact * self.C1 * np.sqrt(nvar) - self.C2 * nvar |
|
356 |
|
|
|
357 |
|
|
|
358 |
|
self.const = self.C |
|
359 |
|
self.gm = g_models.Z_sumexp(self.const) |
|
360 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
361 |
|
self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
362 |
|
|
|
363 |
|
def __str__(self): |
|
364 |
|
return 'Gaussian_Z_sumexp%sD'%(self.nvar) |
|
365 |
|
|
|
366 |
|
def __repr__(self): |
|
367 |
|
return 'Gaussian_Z_sumexp(%s, pf_exact=%s)' % (repr(self.nvar), repr(self.pf_exact)) |
|
368 |
|
|
|
369 |
|
|
|
370 |
|
|
|
371 |
|
class SNorm_Z_sumsq(WhiteBox): |
|
372 |
|
def __init__(self, nvar=2, **kwargs): |
|
373 |
|
""" |
|
374 |
|
je třeba zadat buď pf_exact, nebo konštantu u funkce Z_sumsq |
|
375 |
|
""" |
|
376 |
|
|
|
377 |
|
# je tu předpoklad SNormu, to vím |
|
378 |
|
self.f = f_models.SNorm(nvar) |
|
379 |
|
|
|
380 |
|
self.rvchisq = stats.chi2(nvar) |
|
381 |
|
|
|
382 |
|
# je třeba zadat buď pf_exact, nebo konštantu u funkce Z_sumsq |
|
383 |
|
self.pf_exact_method = 'exact solution' |
|
384 |
|
if 'pf_exact' in kwargs: |
|
385 |
|
self.pf_exact = kwargs['pf_exact'] |
|
386 |
|
self.C = self.rvchisq.ppf(self.pf_exact) |
|
387 |
|
elif 'beta_exact' in kwargs: |
|
388 |
|
self.beta_exact = kwargs['beta_exact'] |
|
389 |
|
self.C = self.rvchisq.ppf(self.pf_exact) |
|
390 |
|
elif 'const' in kwargs: |
|
391 |
|
self.const = kwargs['const'] |
|
392 |
|
self.C = self.const |
|
393 |
|
self.pf_exact = self.rvchisq.cdf(self.C) |
|
394 |
|
elif 'C' in kwargs: |
|
395 |
|
self.C = kwargs['C'] |
|
396 |
|
self.pf_exact = self.rvchisq.cdf(self.C) |
|
397 |
|
else: |
|
398 |
|
# no to teda uživatele пошли |
|
399 |
|
self.pf_exact = 1e-4 |
|
400 |
|
self.C = self.rvchisq.ppf(self.pf_exact) |
|
401 |
|
|
|
402 |
|
|
|
403 |
|
self.const = self.C |
|
404 |
|
self.gm = g_models.Z_sumsq(self.C) |
|
405 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
406 |
|
self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
407 |
|
|
|
408 |
|
def __str__(self): |
|
409 |
|
return 'SNorm_Z_sumsq%sD'%(self.nvar) |
|
410 |
|
|
|
411 |
|
def __repr__(self): |
|
412 |
|
return 'SNorm_Z_sumsq(%s, pf_exact=%s)' % (repr(self.nvar), repr(self.pf_exact)) |
|
413 |
|
|
|
414 |
|
|
|
415 |
|
|
|
416 |
|
|
|
417 |
|
|
|
418 |
|
|
|
419 |
|
class SNorm_S_ball(WhiteBox): |
|
420 |
|
#r = 5.256521 # pf 1.00000404635e-06 |
|
421 |
|
def __init__(self, nvar=2, r=5.256521): |
|
422 |
|
|
|
423 |
|
|
|
424 |
|
# SNorm |
|
425 |
|
self.f = f_models.SNorm(nvar) |
|
426 |
|
|
|
427 |
|
|
|
428 |
|
# |
|
429 |
|
# pf, jen tak, hračka |
|
430 |
|
# |
|
431 |
|
self.pf_exact_method = 'precise solution' |
|
432 |
|
if nvar == 1: |
|
433 |
|
#self.pf_exact = 1 - 2**(1-nvar/2) / special.gamma(nvar/2) * (np.sqrt(np.pi)*special.erf(r/np.sqrt(2)))/np.sqrt(2) |
|
434 |
|
self.pf_exact = 1 - special.erf(r/1.4142135623730951) |
|
435 |
|
elif nvar == 2: |
|
436 |
|
self.pf_exact = np.exp(-r**2/2) |
|
437 |
|
elif nvar == 3: |
|
438 |
|
#self.pf_exact = 1 - 2**(1-nvar/2) / special.gamma(nvar/2) * (np.exp(-r**2/2)*(np.sqrt(np.pi)*np.exp(r**2/2)*special.erf(r/np.sqrt(2))-np.sqrt(2)*r))/np.sqrt(2) |
|
439 |
|
self.pf_exact = 1 - 0.5641895835477564 * (np.exp(-r**2/2)*(np.sqrt(np.pi)*np.exp(r**2/2)*special.erf(r/np.sqrt(2))-np.sqrt(2)*r)) |
|
440 |
|
elif nvar == 4: |
|
441 |
|
self.pf_exact = (r**2/2+1)*np.exp(-r**2/2) |
|
442 |
|
elif nvar == 6: |
|
443 |
|
self.pf_exact = (r**4+4*r**2+8)*np.exp(-r**2/2)/8 |
|
444 |
|
|
|
445 |
|
# nvar=8: (48-(r^6+6*r^4+24*r^2+48)*e^(-r^2/2) / 2**(nvar/2))/48 |
|
446 |
|
|
|
447 |
|
# hračička ve hračce |
|
448 |
|
# nemám žádnou jistotu, že tohle počítá přesněji |
|
449 |
|
elif nvar % 2 == 0: # sudé |
|
450 |
|
poly = [1] |
|
451 |
|
for i in range(nvar-2, 0, -2): |
|
452 |
|
poly.append(0) |
|
453 |
|
poly.append(i*poly[-2]) |
|
454 |
|
self.pf_exact = np.polyval(np.array(poly) / poly[-1], r) * np.exp(-r**2/2) |
|
455 |
|
|
|
456 |
|
else: |
|
457 |
|
self.pf_exact = 1 - 2**(1-nvar/2) / special.gamma(nvar/2) * integrate.quad(lambda x: np.exp(-(x**2)/2)*x**(nvar-1), 0, r)[0] |
|
458 |
|
|
|
459 |
|
|
|
460 |
|
self.r = r |
|
461 |
|
self.gm = g_models.S_ball(r) |
|
462 |
|
# na začatku nemáme vzorky - pouze rozdělení a podpís |
|
463 |
|
self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
464 |
|
|
|
465 |
|
def __str__(self): |
|
466 |
|
return 'SNorm_S_ball%sD'%(self.nvar) |
|
467 |
|
|
|
468 |
|
def __repr__(self): |
|
469 |
|
return 'SNorm_S_ball(nvar=%s, r=%s)' % (repr(self.nvar), repr(self.r)) |
|
470 |
|
|
|
471 |
|
|
|
472 |
|
# |
|
473 |
|
#corner_values = np.full(2**nvar, 1, np.int8) # -1 means inertní, 0 failure, 1 success. |
|
474 |
|
#alpha = [1, 1] |
|
475 |
|
# |
|
476 |
|
#if fce_por == 'Sin2D': |
|
477 |
|
# corner_values[0] = 1 |
|
478 |
|
# corner_values[3] = 0 |
|
479 |
|
# pf_exact = 4.1508e-4 |
|
480 |
|
#elif fce_por == 'S_ball': |
|
481 |
|
# corner_values = np.full(2**nvar, 0, np.int8) |
|
482 |
|
# pf_exact = 1 - 2**(1-nvar/2) / gamma(nvar/2) * integrate.quad(lambda x: np.exp(-(x**2)/2)*x**(nvar-1), 0, r)[0] |
|
483 |
|
#elif fce_por == 'S_ballSin2D': |
|
484 |
|
# corner_values = np.full(2**nvar, 0, np.int8) |
|
485 |
|
# pf_exact = 0 # I don't know, really |
|
486 |
|
#elif fce_por == 'Prod_FourBetas': |
|
487 |
|
# corner_values = np.full(2**nvar, 0, np.int8) # dont know in any corner |
|
488 |
|
# beta = 2.0 |
|
489 |
|
# pf_exact = 2*np.sqrt(2)*stats.norm.cdf(-beta) # true only for beta -> infinity!! |
|
490 |
|
#elif fce_por == 'BlackSwan2D': |
|
491 |
|
# corner_values[0] = 1 |
|
492 |
|
# corner_values[3] = 0 |
|
493 |
|
# #corner_values = np.full(2**nvar, 1, np.int8) # Success in all corners |
|
494 |
|
# #corner_values[0] = 0 #failure somwehere in top right corner |
|
495 |
|
# a = 2.0 |
|
496 |
|
# b = 5.0 |
|
497 |
|
# p = stats.norm.cdf(-a)*stats.norm.cdf(-b) |
|
498 |
|
# # a<b |
|
499 |
|
# pf_exact = p |
|
500 |
|
# # a>b |
|
501 |
|
# # pf_exact = stats.norm.cdf(a) - stats.norm.cdf(b) + p |
|
502 |
|
#elif fce_por == 'Metaballs2D': |
|
503 |
|
# corner_values = np.full(2**nvar, 0, np.int8) # dont know in any corner |
|
504 |
|
|
|
505 |
|
|
|
506 |
|
|
|
507 |
|
|
|
508 |
|
#def get_quadrant_probability(center_point=(0,0), quadrant='I'): |
|
509 |
|
""" |
|
510 |
|
sebemenší pomocná funkce pri hranici L tvaru |
|
511 |
|
quadrants also сэрегъёс-compatible |
|
512 |
|
#### CORNERS 2D ##### |
|
513 |
|
# print(сэрегъёс) |
|
514 |
|
# numbering: |
|
515 |
|
# 2 | 3 |
|
516 |
|
# -----|----- |
|
517 |
|
# 0 | 1 |
|
518 |
|
""" |
|
519 |
|
|
|
520 |
|
#class Quadrant2D(WhiteBox): |
|
521 |
|
# def __new__(cls, g_model, f_model=f_models.SNorm(2)): |
|
522 |
|
# """ |
|
523 |
|
# Trik je v tom, že já odhaduji pf na základě hranici poruchy, |
|
524 |
|
# prohlašenou g_modelem. |
|
525 |
|
# g_model MUST have .mins or .maxs setted up! |
|
526 |
|
# """ |
|
527 |
|
# if f_model.nvar != 2: |
|
528 |
|
# raise ValueError("Reliability problem is supposed to be 2D") |
|
529 |
|
# |
|
530 |
|
# else: |
|
531 |
|
# wt = super(Quadrant2D, cls).__new__(cls) |
|
532 |
|
# wt.gm = g_model |
|
533 |
|
# wt.f = f_model |
|
534 |
|
# # na začatku nemáme vzorky - pouze rozdělení a podpís |
|
535 |
|
# wt.sample_box = SampleBox(wt.f(), gm_signature=wt.gm_signature) |
|
536 |
|
# |
|
537 |
|
# f1, f2 = f_model.marginals |
|
538 |
|
# try: |
|
539 |
|
# (c1, k1), (c2, k2) = g_model.mins |
|
540 |
|
# if k1 > 0: |
|
541 |
|
# a = f1.cdf(-c1/k1) |
|
542 |
|
# else: |
|
543 |
|
# a = f1.sf(-c1/k1) |
|
544 |
|
# if k2 > 0: |
|
545 |
|
# b = f2.cdf(-c2/k2) |
|
546 |
|
# else: |
|
547 |
|
# b = f2.sf(-c2/k2) |
|
548 |
|
# |
|
549 |
|
# quadrant = g_model.get_2D_R_boundary.quadrant |
|
550 |
|
# xc, yc = g_model.get_2D_R_boundary.center_point |
|
551 |
|
# |
|
552 |
|
# #quadrants also сэрегъёс-compatible |
|
553 |
|
# #### CORNERS 2D ##### |
|
554 |
|
# # print(сэрегъёс) |
|
555 |
|
# # numbering: |
|
556 |
|
# # 2 | 3 |
|
557 |
|
# # -----|----- |
|
558 |
|
# # 0 | 1 |
|
559 |
|
# |
|
560 |
|
# wt.pf_exact_method = 'exact solution' # under condition of right g_model |
|
561 |
|
# # mně nic hezčího prostě nenapadá( |
|
562 |
|
# if self.quadrant in ('I', 3): |
|
563 |
|
# xbound = np.append(np.full(nrod, xc), np.linspace(xc, xmax, nrod, endpoint=True)) |
|
564 |
|
# ybound = np.append(np.linspace(ymax, yc, nrod, endpoint=True), np.full(nrod, yc)) |
|
565 |
|
# elif self.quadrant in ('II', 2): |
|
566 |
|
# xbound = np.append(np.linspace(xmin, xc, nrod, endpoint=True), np.full(nrod, xc)) |
|
567 |
|
# ybound = np.append(np.full(nrod, yc), np.linspace(yc, ymax, nrod, endpoint=True)) |
|
568 |
|
# elif self.quadrant in ('III', 0): |
|
569 |
|
# xbound = np.append(np.linspace(xmin, xc, nrod, endpoint=True), np.full(nrod, xc)) |
|
570 |
|
# ybound = np.append(np.full(nrod, yc), np.linspace(yc, ymin, nrod, endpoint=True)) |
|
571 |
|
# else: # self.quadrant in ('IV', 1): |
|
572 |
|
# xbound = np.append(np.full(nrod, xc), np.linspace(xc, xmax, nrod, endpoint=True)) |
|
573 |
|
# ybound = np.append(np.linspace(ymin, yc, nrod, endpoint=True), np.full(nrod, yc)) |
|
574 |
|
# |
|
575 |
|
#elif fce_por == 'Logistic2D': |
|
576 |
|
# a = 4. |
|
577 |
|
# b = 5. #one line, second line and subtract the twice calculated intersection |
|
578 |
|
# pf_exact = lambda a=4, b=5: stats.norm.cdf(-a) + stats.norm.cdf(-b) - stats.norm.cdf(-a)*stats.norm.cdf(-b) |
|
579 |
|
|
|
580 |
|
|
|
581 |
|
|
|
582 |
|
|
|
583 |
|
# no pf information - no reason to create such wbox |
|
584 |
|
|
|
585 |
|
#class UniformBranin2D(WhiteBox): |
|
586 |
|
# def __init__(self): |
|
587 |
|
# |
|
588 |
|
# # Uniform-uniform |
|
589 |
|
# self.f = f_models.UnCorD((stats.uniform, stats.uniform)) |
|
590 |
|
# |
|
591 |
|
# self.gm = g_models.branin_2D |
|
592 |
|
# # na začatku nemáme vzorky - pouze rozdělení a podpís |
|
593 |
|
# self.sample_box = SampleBox(self.f, gm_signature=self.gm_signature) |
|
594 |
|
# |
|
595 |
|
# def __str__(self): |
|
596 |
|
# return 'UniformBranin2D' |
|
597 |
|
# |
|
598 |
|
# def __repr__(self): |
|
599 |
|
# return 'UniformBranin2D()' |
|
600 |
|
|
|
601 |
|
|