File wellmet/voronoi.py changed (mode: 100644) (index 3ae660c..98e7151) |
... |
... |
class ContactVoronoi: |
478 |
478 |
self.base_r = sball.get_Radius_ps(sample_box.nvar, p_base) |
self.base_r = sball.get_Radius_ps(sample_box.nvar, p_base) |
479 |
479 |
#č pro funkci IS_stat.sample_like(), víz. diskuse v poznamkách |
#č pro funkci IS_stat.sample_like(), víz. diskuse v poznamkách |
480 |
480 |
self.d = (sball.get_Radius_ps(sample_box.nvar - 1, p_base) / self.base_r)**2 |
self.d = (sball.get_Radius_ps(sample_box.nvar - 1, p_base) / self.base_r)**2 |
481 |
|
|
|
|
481 |
|
self.ndim = sample_box.nvar |
482 |
482 |
|
|
483 |
483 |
self._nsim = 0 |
self._nsim = 0 |
484 |
484 |
self._enabled = False # if nsim < 2 and not failsi |
self._enabled = False # if nsim < 2 and not failsi |
|
... |
... |
class ContactVoronoi: |
559 |
559 |
def update_contacts(self): |
def update_contacts(self): |
560 |
560 |
#č já vím, že sample box pokážde failsi přepočítavá |
#č já vím, že sample box pokážde failsi přepočítavá |
561 |
561 |
self.failsi = failsi = self.sample_box.failsi |
self.failsi = failsi = self.sample_box.failsi |
|
562 |
|
self.failure_points = self.sample_box.failure_points # for undiscovered |
562 |
563 |
|
|
563 |
564 |
self.CS = ConvexSpline(sampled_plan_model) |
self.CS = ConvexSpline(sampled_plan_model) |
564 |
565 |
self.PDF = self.sample_box.pdf(self.model_space) |
self.PDF = self.sample_box.pdf(self.model_space) |
|
... |
... |
class ContactVoronoi: |
658 |
659 |
self.red_couples[couple] = nodes_idx |
self.red_couples[couple] = nodes_idx |
659 |
660 |
|
|
660 |
661 |
|
|
661 |
|
def update_couple(self, couple_indices, event_id): |
|
662 |
|
pass |
|
663 |
|
|
|
664 |
|
def invalidate_couple(self, couple_indices): |
|
665 |
|
pass |
|
666 |
|
|
|
667 |
|
def onboard_couple(self, couple_indices, event_id): |
|
|
662 |
|
def _check_undiscovered(self, gmask, ii, dd, nodes_model, h_pdf=None): |
668 |
663 |
""" |
""" |
669 |
|
č Obecně, skoro pro každou dimenzi v rozmězí od 2D do 100D |
|
670 |
|
č nejlevnější bylo |
|
671 |
|
č 1. strom s pár bodíků |
|
672 |
|
č 2. ConvexSolver |
|
673 |
|
č 3. strom s nsim bodíků |
|
|
664 |
|
č logika celé třídy je, že máme-li příslušné kontaktu bodíky, |
|
665 |
|
č tak stojí za to je uložit. |
674 |
666 |
""" |
""" |
|
667 |
|
couples = self.couples |
675 |
668 |
|
|
676 |
|
#č (i, j)? poprvé ta čísla vidíme |
|
677 |
|
i, j = couple_indices |
|
|
669 |
|
iim = ii[gmask] #č dovezli nám nedodělané zboží |
678 |
670 |
|
|
679 |
|
#č Nejdřív - zda je přímy kontakt, prostě na usečce |
|
680 |
|
couple_nodes = self.sampled_plan_model[[i, j]] |
|
681 |
|
contact_node_model = np.sum(couple_nodes, axis=0) |
|
682 |
|
np.divide(contact_node_model, 2, out=contact_node_model) |
|
|
671 |
|
#č vymaskovat čerstvé víno |
|
672 |
|
mask = np.all(iim < self._nsim, axis=1) |
|
673 |
|
iim = iim[mask] #č chcu/nechcu globální masku |
|
674 |
|
#č vymaskovat zelené kontakty |
|
675 |
|
in_failure = np.isin(iim, self.failure_points) |
|
676 |
|
has_failure = in_failure.any(axis=1) |
|
677 |
|
iim = iim[has_failure] |
683 |
678 |
|
|
684 |
|
#č bodík nebude mít vahu - nechť si s tím integrovačka poradí! |
|
685 |
|
#č (ten bodík by neměl být omylem doporučen k integraci) |
|
686 |
|
idx, dd, ii, mask = self._store_masked(contact_node_model, couple_indices, event_id) |
|
687 |
|
|
|
688 |
|
#č kontakt neexistuje, netřeba nic robiť, j-ko i-čkem není dotčen |
|
689 |
|
if not (idx or self.CS.is_couple(couple_indices)): |
|
|
679 |
|
#č zbytečnost |
|
680 |
|
if not iim.size: # if empty |
690 |
681 |
return None |
return None |
691 |
682 |
|
|
692 |
|
#č kontakt existuje, dáme vědět aktualizovačce |
|
693 |
|
#č (snad jediné místo kde tuhle funkci voláme) |
|
694 |
|
self._add_indices_to_update(j) |
|
|
683 |
|
#č min-max nepočítá se zadarmo |
|
684 |
|
#č nejdřív projedeme smyčkou část, |
|
685 |
|
#č kde je první index větší a pak ten zbytek |
|
686 |
|
mask = iim[:0] > iim[:1] |
|
687 |
|
for i, j in iim[mask]: |
|
688 |
|
if (i, j) not in couples: |
|
689 |
|
#č ok. Ten vzacnej případ nastal. |
|
690 |
|
#č kašleme na masky, posíláme všechno na explore |
|
691 |
|
self._explore(couple, ii, dd, nodes_model, h_pdf) |
|
692 |
|
|
|
693 |
|
for j, i in iim[~mask]: |
|
694 |
|
if (i, j) not in couples: |
|
695 |
|
#č ok. Ten vzacnej případ nastal. |
|
696 |
|
#č kašleme na masky, posíláme všechno na explore |
|
697 |
|
self._explore(couple, ii, dd, nodes_model, h_pdf) |
|
698 |
|
|
|
699 |
|
|
|
700 |
|
|
|
701 |
|
|
|
702 |
|
def _explore(self, couple, ii, dd, nodes_model, h_pdf): |
|
703 |
|
print("ContactVoronoi: undiscovered" + str(couple)\ |
|
704 |
|
+ " pair has been found!") |
|
705 |
|
i, j = couple |
|
706 |
|
|
|
707 |
|
# similar approach is used in numpy code |
|
708 |
|
mask = np.all((ii == i) | (ii == j), axis=1) |
|
709 |
|
|
|
710 |
|
self._check_undiscovered(ii[~mask], dd[~mask], nodes_model[~mask]) |
|
711 |
|
|
|
712 |
|
if not np.any(mask): |
|
713 |
|
return False, dd, ii, mask |
|
714 |
|
|
|
715 |
|
|
|
716 |
|
#č přídat, zavolat kólbek |
|
717 |
|
f = self.sample_box.f_model |
|
718 |
|
#č tady je to super, ťažké datové struktury f-modelu |
|
719 |
|
#č vytvaříme na jíž vyfiltrovaných datéch |
|
720 |
|
#č Tahle filtrace stromem zaručuje, |
|
721 |
|
#č že bodíky (přenejmenším na vstupu f_modelu) |
|
722 |
|
#č mají konečné souřadnice bez nan a nekonečno. |
|
723 |
|
#č To ale nic neříká o hustotách |
|
724 |
|
nodes = f.new_sample(nodes_model[mask], self.model_space) |
|
725 |
|
couple_stats = {'event_id': event_id, 'couple': couple_indices} |
|
726 |
|
nodes = CandyNodes(nodes, couple_stats) |
|
727 |
|
idx = self.nodes.add(nodes) |
|
728 |
|
nodes.idx = idx |
|
729 |
|
|
|
730 |
|
|
|
731 |
|
ddm = dd[mask] #č tohle je kvůli malé pomyšlené |
|
732 |
|
nodes.dd1 = ddm[:, 0] #č pytlovince v sample_alike |
|
733 |
|
|
|
734 |
|
#č červené kontakty prostě rovnou integrujeme |
|
735 |
|
#č takže netřeba pro ně ukladat zbytečná data |
|
736 |
|
# -1 = 'outside', 0=success, 1=failure, 2=mix |
|
737 |
|
if event_id == 2: |
|
738 |
|
#ddm = dd[mask] |
|
739 |
|
iim = ii[mask] |
|
740 |
|
#nodes.dd1 = ddm[:, 0] #č teď je pro všechny |
|
741 |
|
nodes.dd2 = ddm[:, 1] |
|
742 |
|
nodes.ii1 = iim[:, 0] |
|
743 |
|
nodes.ii2 = iim[:, 1] |
|
744 |
|
if self.on_add_mixed is not None: |
|
745 |
|
self.on_add_mixed(idx) |
|
746 |
|
|
|
747 |
|
|
|
748 |
|
## checklist |
|
749 |
|
self.couples[couple_indices].append(idx) |
|
750 |
|
#self.couples_stats #č nevím |
|
751 |
|
#self.mixed_couples #č v této fázi nevíme, |
|
752 |
|
#self.red_couples #č zda je sada ta nejlepší |
|
753 |
|
#self._add_indices_to_update(j) #č vždyť já nevím, jestli se jedná o aktualizaci |
|
754 |
|
|
|
755 |
|
return idx, dd, ii, mask |
|
756 |
|
|
695 |
757 |
|
|
696 |
758 |
|
|
697 |
|
#č a teď deme vzorkovat |
|
698 |
|
ndim = len(contact_node_model) |
|
699 |
|
#č vzdalenost tamten strom už má spočítanou (pro zadanou p_norm) |
|
700 |
|
r = dd[0,0] |
|
701 |
|
# #č ale nechcu kvůli jedinému poloměru komplikovat kód |
|
702 |
|
# vec = couple_nodes[0] - couple_nodes[1] |
|
703 |
|
# r = np.sqrt(np.inner(vec, vec)) / 2 |
|
704 |
759 |
|
|
705 |
760 |
# initially we'll perform IS from multivariate Gaussian distribution |
# initially we'll perform IS from multivariate Gaussian distribution |
706 |
761 |
# with center at contact node (i. e. in beetween of two points) |
# with center at contact node (i. e. in beetween of two points) |
707 |
762 |
# and single standard deviation (let's say "ball" sampling) |
# and single standard deviation (let's say "ball" sampling) |
708 |
763 |
#č r-ko dělíme base_r'kem k získání sigmy. |
#č r-ko dělíme base_r'kem k získání sigmy. |
709 |
|
sampling_plan_N, pdf = IS_stat.get_norm_plan(self.ns, ndim, \ |
|
|
764 |
|
sampling_plan_N, h_pdf = IS_stat.get_norm_plan(self.ns, ndim, \ |
710 |
765 |
mean=contact_node_model, |
mean=contact_node_model, |
711 |
766 |
std=r/self.base_r, design=None) |
std=r/self.base_r, design=None) |
712 |
767 |
|
|
713 |
|
idx, dd, ii, mask = self._store_masked(sampling_plan_N, couple_indices, event_id) |
|
|
768 |
|
idx, score = self.score(sampling_plan_N, h_pdf, couple_indices, event_id) |
|
769 |
|
|
714 |
770 |
if not idx: |
if not idx: |
715 |
771 |
return None |
return None |
716 |
772 |
|
|
717 |
|
#č uspěch. Dodáme bodíkům vahy |
|
718 |
|
nodes = self.nodes[idx] |
|
719 |
|
w = nodes.pdf(self.model_space) / pdf[mask] / self.ns |
|
720 |
|
#č Tamta filtrace stromem zaručuje, |
|
721 |
|
#č že bodíky (přenejmenším na vstupu f_modelu) |
|
722 |
|
#č mají konečné souřadnice bez nan a nekonečno. |
|
723 |
|
#č To ale nic neříká o hustotách |
|
724 |
|
mask = np.isfinite(w) |
|
725 |
|
nodes.w = w * mask |
|
726 |
|
#č p_couple není finální pravděpodobnost |
|
727 |
|
#č bodíky ještě musejí projít konvexní obálkou |
|
728 |
|
nodes.p_couple = np.sum(w[mask]) |
|
729 |
|
nodes.score = nodes.p_couple / np.sqrt(np.var(nodes.w)/len(nodes)) |
|
730 |
|
#č a doporučíme (dočasně) k integraci |
|
|
773 |
|
#č doporučíme (dočasně) k integraci |
731 |
774 |
self._recommend_to_integration(idx) |
self._recommend_to_integration(idx) |
732 |
775 |
|
|
733 |
|
if len(nodes) < ndim + 1: |
|
734 |
|
return None |
|
735 |
|
|
|
736 |
776 |
#č jdeme do adaptivního IS vzorkování |
#č jdeme do adaptivního IS vzorkování |
737 |
777 |
#č zde jenom vzorkujeme; |
#č zde jenom vzorkujeme; |
738 |
778 |
#č integrování, vyhodnocování je jinde a později! |
#č integrování, vyhodnocování je jinde a později! |
|
... |
... |
class ContactVoronoi: |
1035 |
1075 |
|
|
1036 |
1076 |
|
|
1037 |
1077 |
|
|
1038 |
|
def score(self, nodes_model, h_pdf, couple_indices, event_id): |
|
1039 |
|
"returns: node_index, score" |
|
1040 |
1078 |
|
|
1041 |
|
idx, _dd, _ii, mask = self._store_masked(nodes_model, couple_indices, event_id) |
|
1042 |
|
if not idx: |
|
1043 |
|
return idx, -1 |
|
|
1079 |
|
|
1044 |
1080 |
|
|
1045 |
|
#č uspěch. Dodáme bodíkům vahy |
|
1046 |
|
nodes = self.nodes[idx] |
|
1047 |
|
nis = len(h_pdf) |
|
1048 |
|
w = nodes.pdf(self.model_space) / h_pdf[mask] / nis |
|
1049 |
|
#č Tamta filtrace stromem zaručuje, |
|
|
1081 |
|
#č přídat, zavolat kólbek |
|
1082 |
|
f = self.sample_box.f_model |
|
1083 |
|
#č tady je to super, ťažké datové struktury f-modelu |
|
1084 |
|
#č vytvaříme na jíž vyfiltrovaných datéch |
|
1085 |
|
#č Tahle filtrace stromem zaručuje, |
1050 |
1086 |
#č že bodíky (přenejmenším na vstupu f_modelu) |
#č že bodíky (přenejmenším na vstupu f_modelu) |
1051 |
1087 |
#č mají konečné souřadnice bez nan a nekonečno. |
#č mají konečné souřadnice bez nan a nekonečno. |
1052 |
1088 |
#č To ale nic neříká o hustotách |
#č To ale nic neříká o hustotách |
1053 |
|
mask = np.isfinite(w) #č bacha! Nová, již jiná maska! |
|
1054 |
|
nodes.w = w * mask |
|
1055 |
|
#č p_couple není finální pravděpodobnost |
|
1056 |
|
#č bodíky ještě musejí projít konvexní obálkou |
|
1057 |
|
nodes.p_couple = np.sum(w[mask]) |
|
1058 |
|
nodes.score = nodes.p_couple / np.sqrt(np.var(nodes.w)/len(nodes)) |
|
1059 |
|
return idx, nodes.score |
|
|
1089 |
|
nodes = f.new_sample(nodes_model[mask], self.model_space) |
|
1090 |
|
couple_stats = {'event_id': event_id, 'couple': couple_indices} |
|
1091 |
|
nodes = CandyNodes(nodes, couple_stats) |
|
1092 |
|
idx = self.nodes.add(nodes) |
|
1093 |
|
nodes.idx = idx |
|
1094 |
|
|
|
1095 |
|
|
|
1096 |
|
ddm = dd[mask] #č tohle je kvůli malé pomyšlené |
|
1097 |
|
nodes.dd1 = ddm[:, 0] #č pytlovince v sample_alike |
|
1098 |
|
|
|
1099 |
|
#č červené kontakty prostě rovnou integrujeme |
|
1100 |
|
#č takže netřeba pro ně ukladat zbytečná data |
|
1101 |
|
# -1 = 'outside', 0=success, 1=failure, 2=mix |
|
1102 |
|
if event_id == 2: |
|
1103 |
|
#ddm = dd[mask] |
|
1104 |
|
iim = ii[mask] |
|
1105 |
|
#nodes.dd1 = ddm[:, 0] #č teď je pro všechny |
|
1106 |
|
nodes.dd2 = ddm[:, 1] |
|
1107 |
|
nodes.ii1 = iim[:, 0] |
|
1108 |
|
nodes.ii2 = iim[:, 1] |
|
1109 |
|
if self.on_add_mixed is not None: |
|
1110 |
|
self.on_add_mixed(idx) |
|
1111 |
|
|
|
1112 |
|
|
|
1113 |
|
## checklist |
|
1114 |
|
self.couples[couple_indices].append(idx) |
|
1115 |
|
#self.couples_stats #č nevím |
|
1116 |
|
#self.mixed_couples #č v této fázi nevíme, |
|
1117 |
|
#self.red_couples #č zda je sada ta nejlepší |
|
1118 |
|
#self._add_indices_to_update(j) #č vždyť já nevím, jestli se jedná o aktualizaci |
|
1119 |
|
|
|
1120 |
|
return idx, dd, ii, mask |
1060 |
1121 |
|
|
1061 |
1122 |
|
|
|
1123 |
|
def update_couple(self, couple_indices, event_id): |
|
1124 |
|
#č při aktualizaci páry kontrolujeme, |
|
1125 |
|
#č zda nejsou změny u sady, doporučenou k integraci |
|
1126 |
|
#č teček je třeba mít na vědomí, |
|
1127 |
|
#č že se můžou zůstávat oblasti, ve kterých jsou |
|
1128 |
|
pass |
1062 |
1129 |
|
|
1063 |
1130 |
|
|
|
1131 |
|
def invalidate_couple(self, couple_indices): |
|
1132 |
|
pass |
1064 |
1133 |
|
|
1065 |
|
# for simplex: d = nvar+2 |
|
1066 |
|
# for cell: d = base_r**2 |
|
1067 |
|
def IS_like(f_plan, sampling_space='G', weights=None, nis=1000, d=1, design=None): |
|
|
1134 |
|
def onboard_couple(self, couple_indices, event_id): |
1068 |
1135 |
""" |
""" |
1069 |
|
takes sample and returns sampling plan with the same cov (in case d=1) |
|
1070 |
|
covariance matrix we'll divide by d |
|
|
1136 |
|
č Obecně, skoro pro každou dimenzi v rozmězí od 2D do 100D |
|
1137 |
|
č nejlevnější bylo |
|
1138 |
|
č 1. strom s pár bodíků |
|
1139 |
|
č 2. ConvexSolver |
|
1140 |
|
č 3. strom s nsim bodíků |
1071 |
1141 |
""" |
""" |
1072 |
1142 |
|
|
1073 |
|
plan = getattr(f_plan, sampling_space) |
|
|
1143 |
|
#č (i, j)? poprvé ta čísla vidíme |
|
1144 |
|
i, j = couple_indices |
1074 |
1145 |
|
|
1075 |
|
|
|
1076 |
|
S_bc = np.cov(plan, rowvar=False, bias=True, aweights=weights) |
|
1077 |
|
barycenter = np.average(plan, axis=0, weights=weights) |
|
|
1146 |
|
#č Nejdřív - zda je přímy kontakt, prostě na usečce |
|
1147 |
|
couple_nodes = self.sampled_plan_model[[i, j]] |
|
1148 |
|
contact_node_model = np.sum(couple_nodes, axis=0) |
|
1149 |
|
np.divide(contact_node_model, 2, out=contact_node_model) |
|
1150 |
|
|
|
1151 |
|
#č bodík nebude mít vahu - nechť si s tím integrovačka poradí! |
|
1152 |
|
#č (ten bodík by neměl být omylem doporučen k integraci) |
|
1153 |
|
idx, dd, ii, mask = self._store_masked(contact_node_model, couple_indices, event_id) |
|
1154 |
|
|
|
1155 |
|
#č kontakt neexistuje, netřeba nic robiť, j-ko i-čkem není dotčen |
|
1156 |
|
if not (idx or self.CS.is_couple(couple_indices)): |
|
1157 |
|
return None |
1078 |
1158 |
|
|
|
1159 |
|
#č kontakt existuje, dáme vědět aktualizovačce |
|
1160 |
|
#č (snad jediné místo kde tuhle funkci voláme) |
|
1161 |
|
self._add_indices_to_update(j) |
1079 |
1162 |
|
|
1080 |
|
#č matika |
|
1081 |
|
w, v = np.linalg.eig(S_bc) |
|
1082 |
1163 |
|
|
1083 |
|
# use IS sampling density with center equal to the simplex's barycenter |
|
1084 |
|
# set the minimum distance as the standard deviation of IS densisty |
|
1085 |
|
#č u stats.norm zadáváme směrodatnou odchylku, to je asi správné |
|
1086 |
|
sigmas = np.sqrt(w/d) |
|
1087 |
|
mean = 0 |
|
1088 |
|
h_plan_N, pdf_N = get_norm_plan(nis, f_plan.nvar, mean, sigmas, design) |
|
|
1164 |
|
#č a teď deme vzorkovat |
|
1165 |
|
ndim = len(contact_node_model) |
|
1166 |
|
#č vzdalenost tamten strom už má spočítanou (pro zadanou p_norm) |
|
1167 |
|
r = dd[0,0] |
|
1168 |
|
# #č ale nechcu kvůli jedinému poloměru komplikovat kód |
|
1169 |
|
# vec = couple_nodes[0] - couple_nodes[1] |
|
1170 |
|
# r = np.sqrt(np.inner(vec, vec)) / 2 |
1089 |
1171 |
|
|
1090 |
|
#ёӵ здесь уже так легко не отделаемся. Трансформовать кароно. |
|
1091 |
|
h_plan_bc = (v @ h_plan_N.T).T |
|
1092 |
|
h_plan_sing = h_plan_bc + barycenter |
|
|
1172 |
|
# initially we'll perform IS from multivariate Gaussian distribution |
|
1173 |
|
# with center at contact node (i. e. in beetween of two points) |
|
1174 |
|
# and single standard deviation (let's say "ball" sampling) |
|
1175 |
|
#č r-ko dělíme base_r'kem k získání sigmy. |
|
1176 |
|
sampling_plan_N, h_pdf = IS_stat.get_norm_plan(self.ns, ndim, \ |
|
1177 |
|
mean=contact_node_model, |
|
1178 |
|
std=r/self.base_r, design=None) |
|
1179 |
|
|
|
1180 |
|
idx, score = self.score(sampling_plan_N, h_pdf, couple_indices, event_id, h_pdf) |
|
1181 |
|
|
|
1182 |
|
if not idx: |
|
1183 |
|
return None |
|
1184 |
|
|
|
1185 |
|
#č doporučíme (dočasně) k integraci |
|
1186 |
|
self._recommend_to_integration(idx) |
1093 |
1187 |
|
|
|
1188 |
|
if len(nodes) < ndim + 1: |
|
1189 |
|
return None |
|
1190 |
|
|
|
1191 |
|
#č jdeme do adaptivního IS vzorkování |
|
1192 |
|
#č zde jenom vzorkujeme; |
|
1193 |
|
#č integrování, vyhodnocování je jinde a později! |
1094 |
1194 |
|
|
|
1195 |
|
nodes_model = getattr(nodes, self.model_space) |
|
1196 |
|
status, nodes_model, h_pdf = IS_stat.sample_alike(nodes_model, \ |
|
1197 |
|
weights=nodes.w, nis=self.ns, d=self.d) |
|
1198 |
|
if not status: |
|
1199 |
|
return None |
|
1200 |
|
|
|
1201 |
|
idx, dd, ii, mask = self._store_masked(nodes_model, couple_indices, event_id, h_pdf) |
|
1202 |
|
if not idx: |
|
1203 |
|
return None |
|
1204 |
|
|
|
1205 |
|
#č uspěch. Dodáme bodíkům vahy |
|
1206 |
|
nodes = self.nodes[idx] |
|
1207 |
|
w = nodes.pdf(self.model_space) / h_pdf[mask] / self.ns |
|
1208 |
|
#č Tamta filtrace stromem zaručuje, |
|
1209 |
|
#č že bodíky (přenejmenším na vstupu f_modelu) |
|
1210 |
|
#č mají konečné souřadnice bez nan a nekonečno. |
|
1211 |
|
#č To ale nic neříká o hustotách |
|
1212 |
|
mask = np.isfinite(w) |
|
1213 |
|
nodes.w = w * mask |
|
1214 |
|
#č p_couple není finální pravděpodobnost |
|
1215 |
|
#č bodíky ještě musejí projít konvexní obálkou |
|
1216 |
|
nodes.p_couple = np.sum(w[mask]) |
|
1217 |
|
nodes.score = nodes.p_couple / np.sqrt(np.var(nodes.w)/len(nodes)) |
|
1218 |
|
#č a doporučíme (dočasně) k integraci |
|
1219 |
|
self._recommend_to_integration(idx) |
1095 |
1220 |
|
|
1096 |
|
#č sice to má nazev h_plan, ale nese rozdělení a hustoty v f-ku |
|
1097 |
|
# |
|
1098 |
|
#č jelikož výtvaříme nový vzorek z "čístých" souřadnic |
|
1099 |
|
#č máme zaručeno, že h_plan vždy bude f_modelem (podle současného kódu CandyBox) |
|
1100 |
|
h_plan = f_plan.new_sample(h_plan_sing, sampling_space) |
|
1101 |
|
## desired: w = h_plan.pdf(sampling_space) / pdf_N # snad je to správně |
|
1102 |
|
w = np.divide(h_plan.pdf(sampling_space), pdf_N, out=pdf_N); del(pdf_N) |
|
1103 |
1221 |
|
|
1104 |
|
#č vahy máme |
|
1105 |
|
#č zabalme do boxu |
|
1106 |
|
#č zbytek už nejsou naši starosti |
|
1107 |
|
return CandyBox(h_plan, w=w) |
|
|
1222 |
|
if len(nodes) < nodes.nvar + 1: |
|
1223 |
|
# in case of update reset the final score only |
|
1224 |
|
nodes.score = -2 |
|
1225 |
|
return None |
1108 |
1226 |
|
|
|
1227 |
|
nodes_model = getattr(nodes, self.model_space) |
|
1228 |
|
nodes_pdf = nodes.pdf(self.model_space) |
1109 |
1229 |
|
|
1110 |
|
def sample_alike(self, nodes): |
|
1111 |
|
""" |
|
1112 |
|
č zde jenom vzorkujeme; |
|
1113 |
|
č integrování, vyhodnocování je jinde a později! |
|
1114 |
|
""" |
|
|
1230 |
|
S_bc = np.cov(nodes_model, rowvar=False, bias=True, aweights=nodes_pdf) |
1115 |
1231 |
|
|
|
1232 |
|
#č matika |
|
1233 |
|
w, v = eig = np.linalg.eig(S_bc) |
1116 |
1234 |
|
|
|
1235 |
|
if not np.all(w > 0): |
|
1236 |
|
nodes.score = -1 |
|
1237 |
|
return None |
1117 |
1238 |
|
|
1118 |
|
# use IS sampling density with center equal to the current point |
|
1119 |
|
# set the minimum distance as the standard deviation of IS densisty |
|
1120 |
|
# mindist dělíme dvěma - hranice buňky je na půlcesty |
|
1121 |
|
# a dělíme base_r'kem k získání sigmy. Přemejmenším empiricky mně to vychází |
|
1122 |
|
# (u Norm'u vždy zadaváme směrodatnou odchylku) |
|
1123 |
|
h_i = [stats.norm(sampled_plan_sing[i,j], mindist_sing[i]/2/base_r) for j in range(sample_box.nvar)] |
|
1124 |
|
h = f_models.UnCorD(h_i) |
|
|
1239 |
|
barycenter = np.average(nodes_model, axis=0, weights=nodes_pdf) |
|
1240 |
|
nodes.set_attrs(eig=eig, barycenter=barycenter) |
|
1241 |
|
nodes.score = np.trace(S_bc) * np.sqrt(len(nodes)) |
1125 |
1242 |
|
|
1126 |
|
|
|
1127 |
|
# select nis points from IS density |
|
1128 |
|
# sice to má nazev h_plan, ale nese rozdělení a hustoty v f-ku |
|
1129 |
|
h_plan = IS(f, h, space_from_h='R', space_to_f=sampling_space, Nsim=nis) |
|
1130 |
1243 |
|
|
1131 |
|
# součet váh nemá cenu kontrolovat, jedná tam nebude, nevyjde |
|
1132 |
1244 |
|
|
1133 |
|
h_plan_model = getattr(h_plan, model_space) |
|
1134 |
|
dd, ii = tree.query(h_plan_model, k=1, p=p_norm) |
|
1135 |
1245 |
|
|
1136 |
1246 |
|
|
1137 |
1247 |
# nechám s velkým písmenkem |
# nechám s velkým písmenkem |
|
... |
... |
class ContactVoronoi: |
1141 |
1251 |
# dd1 jsou vzdalenosti tečiček do centra Voroneho buňky |
# dd1 jsou vzdalenosti tečiček do centra Voroneho buňky |
1142 |
1252 |
dd1 = dd[Vor_mask] |
dd1 = dd[Vor_mask] |
1143 |
1253 |
|
|
1144 |
|
trace = 0 |
|
|
1254 |
|
|
1145 |
1255 |
nis_ma = len(weights_sim) |
nis_ma = len(weights_sim) |
1146 |
1256 |
|
|
1147 |
1257 |
h_plan_sing_ma = getattr(h_plan, sampling_space)[Vor_mask] |
h_plan_sing_ma = getattr(h_plan, sampling_space)[Vor_mask] |
1148 |
|
S_bc = np.cov(h_plan_sing_ma, rowvar=False, bias=True, aweights=weights_sim) |
|
1149 |
|
barycenter = np.average(h_plan_sing_ma, axis=0, weights=weights_sim) |
|
|
1258 |
|
|
|
1259 |
|
nodes_model = getattr(nodes, self.model_space) |
|
1260 |
|
nodes_pdf = nodes.pdf(self.model_space) |
|
1261 |
|
S_bc = np.cov(nodes_model, rowvar=False, bias=True, aweights=nodes_pdf) |
|
1262 |
|
barycenter = np.average(nodes_model, axis=0, weights=nodes_pdf) |
|
1263 |
|
trace = np.trace(S_bc) |
|
1264 |
|
nodes.set_attrs(S_bc=S_bc, barycenter=barycenter, trace=trace) |
|
1265 |
|
|
|
1266 |
|
# matika |
|
1267 |
|
w, v = np.linalg.eig(S_bc) |
|
1268 |
|
|
|
1269 |
|
if np.any(w <= 0): |
|
1270 |
|
return None |
|
1271 |
|
|
|
1272 |
|
goal = trace*len(nodes) |
|
1273 |
|
|
1150 |
1274 |
# effective nis |
# effective nis |
1151 |
1275 |
nis_eff = nis |
nis_eff = nis |
1152 |
1276 |
#print("start", i) |
#print("start", i) |
1153 |
1277 |
|
|
1154 |
|
while trace < np.trace(S_bc): |
|
1155 |
|
# number of nodes inside the cell matters too |
|
1156 |
|
trace = np.trace(S_bc)# * nis_ma |
|
1157 |
|
#print(S_bc) |
|
1158 |
|
#print(nis_ma) |
|
1159 |
|
|
|
1160 |
|
|
|
1161 |
|
|
|
1162 |
|
|
|
|
1278 |
|
max_trace = 0 |
|
1279 |
|
while max_trace < trace: |
|
1280 |
|
trace = np.trace(S_bc) |
|
1281 |
|
|
1163 |
1282 |
# matika |
# matika |
1164 |
1283 |
w, v = np.linalg.eig(S_bc) |
w, v = np.linalg.eig(S_bc) |
1165 |
1284 |
|
|
|
1285 |
|
# r_ball/r_base = sigma |
|
1286 |
|
|
1166 |
1287 |
# use IS sampling density with center equal to the cell's barycenter |
# use IS sampling density with center equal to the cell's barycenter |
1167 |
1288 |
# set the minimum distance as the standard deviation of the IS densisty |
# set the minimum distance as the standard deviation of the IS densisty |
1168 |
1289 |
# u stats.norm zadáváme směrodatnou odchylku, to je asi správné |
# u stats.norm zadáváme směrodatnou odchylku, to je asi správné |
|
... |
... |
class ContactVoronoi: |
1368 |
1489 |
mindist_sing = dd2.flatten() |
mindist_sing = dd2.flatten() |
1369 |
1490 |
|
|
1370 |
1491 |
|
|
1371 |
|
def _store_masked(self, nodes_model, couple_indices, event_id): |
|
|
1492 |
|
|
|
1493 |
|
def score(self, nodes_model, h_pdf, couple_indices, event_id): |
|
1494 |
|
"returns: node_index, score" |
|
1495 |
|
|
|
1496 |
|
idx, _dd, _ii, mask = self._store_masked(nodes_model, couple_indices, event_id, h_pdf) |
|
1497 |
|
if not idx: |
|
1498 |
|
return idx, -1 |
|
1499 |
|
|
|
1500 |
|
#č uspěch. Dodáme bodíkům vahy |
|
1501 |
|
nodes = self.nodes[idx] |
|
1502 |
|
nis = len(h_pdf) |
|
1503 |
|
w = nodes.pdf(self.model_space) / h_pdf[mask] / nis |
|
1504 |
|
#č Tamta filtrace stromem zaručuje, |
|
1505 |
|
#č že bodíky (přenejmenším na vstupu f_modelu) |
|
1506 |
|
#č mají konečné souřadnice bez nan a nekonečno. |
|
1507 |
|
#č To ale nic neříká o hustotách |
|
1508 |
|
mask = np.isfinite(w) #č bacha! Nová, již jiná maska! |
|
1509 |
|
nodes.w = w * mask |
|
1510 |
|
#č p_couple není finální pravděpodobnost |
|
1511 |
|
#č bodíky ještě musejí projít konvexní obálkou |
|
1512 |
|
nodes.p_couple = np.sum(w[mask]) |
|
1513 |
|
#č rozptyl může být i nulový |
|
1514 |
|
#nodes.score = nodes.p_couple / np.sqrt(np.var(nodes.w)/len(nodes)) |
|
1515 |
|
nodes.score = nodes.p_couple * np.sqrt(len(nodes)) |
|
1516 |
|
return idx, nodes.score |
|
1517 |
|
|
|
1518 |
|
|
|
1519 |
|
|
|
1520 |
|
|
|
1521 |
|
|
|
1522 |
|
|
|
1523 |
|
def sample_alike(self, nodes): |
|
1524 |
|
""" |
|
1525 |
|
č zde jenom vzorkujeme; |
|
1526 |
|
č integrování, vyhodnocování je jinde a později! |
|
1527 |
|
returns: node_idx, score |
|
1528 |
|
""" |
|
1529 |
|
assert len(nodes) > 0 |
|
1530 |
|
|
|
1531 |
|
nodes_model = getattr(nodes, self.model_space) |
|
1532 |
|
|
|
1533 |
|
if len(nodes) < 2: |
|
1534 |
|
#č máme jeden bodík. To znaméná, že kontakt existuje |
|
1535 |
|
#č a zákazník hodla provést vzorkování. |
|
1536 |
|
#č Pro tento vzácný případ naše společnost nabízí řešení - |
|
1537 |
|
#č zapojít informace o těch dvou vzorkách, ke kterým patří. |
|
1538 |
|
#č Na ty dva vzorky se nemůžeme spoléhat z hlediska směrových |
|
1539 |
|
#č preferencí, použijme je jen jako zdroj jakési |
|
1540 |
|
#č charakteristické délky. Těžiště necháme v tamtamtom bodíku. |
|
1541 |
|
|
|
1542 |
|
#č Specifika CandyNodes je, že dd1 pro jeden bodík může vrátit |
|
1543 |
|
#č jak skalarní hodnotu, tak i pole s jediným prvkem |
|
1544 |
|
#č numpy si poradí s obojí |
|
1545 |
|
r = nodes.dd1 |
|
1546 |
|
|
|
1547 |
|
# we'll perform IS from multivariate Gaussian distribution |
|
1548 |
|
# centered at the isolated node |
|
1549 |
|
# and some standard deviation |
|
1550 |
|
#č r-ko dělíme base_r'kem k získání sigmy. |
|
1551 |
|
sampling_plan_N, h_pdf = IS_stat.get_norm_plan(self.ns, self.ndim,\ |
|
1552 |
|
mean=nodes_model[0], |
|
1553 |
|
std=r/self.base_r, design=None) |
|
1554 |
|
|
|
1555 |
|
return self.score(sampling_plan_N, h_pdf, nodes.couple, nodes.event_id) |
|
1556 |
|
|
|
1557 |
|
|
|
1558 |
|
try: |
|
1559 |
|
weights = nodes.w |
|
1560 |
|
except AttributeError: |
|
1561 |
|
weights = None |
|
1562 |
|
|
|
1563 |
|
sampling_plan, h_pdf = IS_stat.sample_alike(nodes_model, \ |
|
1564 |
|
weights=weights, nis=self.ns, d=self.d) |
|
1565 |
|
|
|
1566 |
|
return self.score(sampling_plan, h_pdf, nodes.couple, nodes.event_id) |
|
1567 |
|
|
|
1568 |
|
|
|
1569 |
|
|
|
1570 |
|
#č h_pdf je jen pro _check_undiscovered() |
|
1571 |
|
def _store_masked(self, nodes_model, couple_indices, event_id, h_pdf=None): |
1372 |
1572 |
""" |
""" |
1373 |
1573 |
č logika celé třídy je, že máme-li příslušné kontaktu bodíky, |
č logika celé třídy je, že máme-li příslušné kontaktu bodíky, |
1374 |
1574 |
č tak stojí za to je uložit. |
č tak stojí za to je uložit. |
|
... |
... |
class ContactVoronoi: |
1386 |
1586 |
|
|
1387 |
1587 |
# similar approach is used in numpy code |
# similar approach is used in numpy code |
1388 |
1588 |
mask = np.all((ii == i) | (ii == j), axis=1) |
mask = np.all((ii == i) | (ii == j), axis=1) |
|
1589 |
|
if not np.all(mask): |
|
1590 |
|
#č aniž by se tu trapil if-ámi s h_pdf, pošlu všecko do funkce, |
|
1591 |
|
#č neboť ta to všechno potřebuje jen ve velmi vzacném případě |
|
1592 |
|
self._check_undiscovered(~mask, ii, dd, nodes_model, h_pdf) |
1389 |
1593 |
|
|
1390 |
1594 |
if not np.any(mask): |
if not np.any(mask): |
1391 |
1595 |
return False, dd, ii, mask |
return False, dd, ii, mask |
|
... |
... |
class ContactVoronoi: |
1405 |
1609 |
idx = self.nodes.add(nodes) |
idx = self.nodes.add(nodes) |
1406 |
1610 |
nodes.idx = idx |
nodes.idx = idx |
1407 |
1611 |
|
|
|
1612 |
|
|
|
1613 |
|
ddm = dd[mask] #č tohle je kvůli malé pomyšlené |
|
1614 |
|
nodes.dd1 = ddm[:, 0] #č pytlovince v sample_alike |
|
1615 |
|
|
1408 |
1616 |
#č červené kontakty prostě rovnou integrujeme |
#č červené kontakty prostě rovnou integrujeme |
1409 |
1617 |
#č takže netřeba pro ně ukladat zbytečná data |
#č takže netřeba pro ně ukladat zbytečná data |
1410 |
1618 |
# -1 = 'outside', 0=success, 1=failure, 2=mix |
# -1 = 'outside', 0=success, 1=failure, 2=mix |
1411 |
1619 |
if event_id == 2: |
if event_id == 2: |
1412 |
|
dd = dd[mask] |
|
1413 |
|
ii = ii[mask] |
|
1414 |
|
nodes.dd1 = dd[:, 0] |
|
1415 |
|
nodes.dd2 = dd[:, 1] |
|
1416 |
|
nodes.ii1 = ii[:, 0] |
|
1417 |
|
nodes.ii2 = ii[:, 1] |
|
|
1620 |
|
#ddm = dd[mask] |
|
1621 |
|
iim = ii[mask] |
|
1622 |
|
#nodes.dd1 = ddm[:, 0] #č teď je pro všechny |
|
1623 |
|
nodes.dd2 = ddm[:, 1] |
|
1624 |
|
nodes.ii1 = iim[:, 0] |
|
1625 |
|
nodes.ii2 = iim[:, 1] |
1418 |
1626 |
if self.on_add_mixed is not None: |
if self.on_add_mixed is not None: |
1419 |
1627 |
self.on_add_mixed(idx) |
self.on_add_mixed(idx) |
1420 |
1628 |
|
|