iam-git / WellMet (public) (License: MIT) (since 2021-08-31) (hash sha1)
WellMet is pure Python framework for spatial structural reliability analysis. Or, more specifically, for "failure probability estimation and detection of failure surfaces by adaptive sequential decomposition of the design domain".
List of commits:
Subject Hash Author Date (UTC)
wireframe: finish and clean up module. implement DirectContact. f7ff9c02f25a3ed8fe04e99036da69766afa5a49 I am 2022-11-10 04:58:58
qt_gui.qt_pairwise.ContactWidget: implement Qhull check e362df1f8b87ab7c6a27643cd6f4091b9caec9a3 I am 2022-11-09 21:35:10
wireframe: add Qframe class cf52d85dd1663537cd8c52a98514c7d041913979 I am 2022-11-09 21:34:12
qt_gui.qt_pairwise: add auto arnge and auto levels controls 9bc2cf10a9a1695c2c1a5f6a9959f375d3808a71 I am 2022-11-09 18:16:47
qt_gui.qt_pairwise: set blue -1 by default. Add force_update option in Contact widget 7371575784df7fd41bd76ad29caf38f474a06a26 I am 2022-11-09 15:39:03
qt_gui.qt_pairwise: prepare Contact widget bfa78d7493f5eb04b6bd3a4ad26dd1a92d17a895 I am 2022-11-09 03:36:05
qt_gui.qt_pairwise: prepare more mouse event signals c60e613508480c68483b3d0d6ad6c876b27f539c I am 2022-11-08 01:55:14
qt_gui: introduce reworked matrix view window e28b95c5f418a7a3cea0cb84ca82b40275a71061 I am 2022-11-07 02:20:45
introduce wireframe module for the contacts finding functionality b6068dd92663699859ea7cbf3aac00178d120e0f I am 2022-10-25 14:24:37
voronoi.TwoPoints: atleast_2d() one line fix 9f8bd9e5370ccf30887b6218331ee664788a3b91 I am 2022-10-25 07:09:57
voronoi: implement faster TwoPoints class. c0af78f64bc78a6b8cf06e3ea244339549318b66 I am 2022-10-24 13:03:26
voronoi: implement TwoHorses class. Třída je, bohužel, bezcenná :( 4f6fe186f3f344fa7ee9e518798499099615b466 I am 2022-10-23 10:00:43
voronoi: WIP 23c63ede5bc2ec51d25aed850dc59299db438e34 I am 2022-10-21 12:27:01
IS_stat.sample_alike: use any possible fallback options to sample 80fb6d086e9f17350a1725a319e40bf29591869e I am 2022-10-20 08:56:42
voronoi: WIP ba912d406de12142f2e15a73090118184a0166a4 I am 2022-10-20 02:43:12
IS_stat: add sample_alike() function 2e5394d264b7aaaf5f2486c736ed8cc37afbd030 I am 2022-10-19 13:00:17
voronoi: WIP c3bfa60b6db2042df11528fe95a51d7cc88d3c6b I am 2022-10-19 11:18:13
voronoi: WIP baff3c5ccaf857f60194917fe5d6e33c40b01265 I am 2022-10-19 09:28:33
voronoi.ConvexSpline: little fix of np.sign() for better sleep 968f649e54d97abd596cd60749872fa3ef788c06 I am 2022-10-19 06:28:46
implement even more optimized Convex.. now ConvexSpline class c08511aecb32b880e73c9f10d07feff4dc588e8b I am 2022-10-19 04:11:13
Commit f7ff9c02f25a3ed8fe04e99036da69766afa5a49 - wireframe: finish and clean up module. implement DirectContact.
Author: I am
Author date (UTC): 2022-11-10 04:58
Committer name: I am
Committer date (UTC): 2022-11-10 04:58
Parent(s): e362df1f8b87ab7c6a27643cd6f4091b9caec9a3
Signer:
Signing key:
Signing status: N
Tree: fb6b8ee77a2d3f4663dc25ebdeac3c78a69c1f5b
File Lines added Lines deleted
wellmet/wireframe.py 296 149
File wellmet/wireframe.py changed (mode: 100644) (index 84fac7a..2c83232)
2 2 # coding: utf-8 # coding: utf-8
3 3
4 4 import numpy as np import numpy as np
5 import numpy.ma as ma
6 import scipy.stats as stats
7
8 from scipy.spatial import KDTree
9 from scipy.spatial import Delaunay
10 from scipy import spatial
11 from scipy.spatial.distance import cdist
12 from scipy import interpolate
13
14 import collections # for defaultdict, namedtuple
15
16 from . import f_models
17 from . import simplex as six
18 from . import IS_stat
19 from .IS_stat import IS
20 from .candynodes import CandyNodes
21 from . import sball
22
5 from scipy.spatial import Delaunay, KDTree
23 6
24 7
25 8
9 #
10 # Qhull
11 #
26 12
27 13 class Qframe(Delaunay): class Qframe(Delaunay):
28 14 def is_couple(self, couple_indices): def is_couple(self, couple_indices):
 
... ... def convex_solver_test(points, tries_to_fix=1, tol=1e-7):
96 82
97 83
98 84
99 def is_line_convex(points, line_indices):
85 #
86 # DirectContact
87 #
88
89 #č zda existuje přímy kontakt, prostě na usečce
90 class DirectContact(KDTree):
91 """
92 č Obecně, skoro pro každou dimenzi v rozmězí od 2D do 100D
93 č nejlevnější bylo
94 č 1. strom s pár bodíků
95 č 2. ConvexSolver
96 č 3. strom s nsim bodíků
97 """
98 def is_couple(self, couple_indices, **kwargs):
99 i, j = couple_indices
100
101 half_point = np.mean(self.data[[i, j]], axis=0)
102
103 __dd, ii = self.query(half_point, k=2, **kwargs)
104 #č pro jediný bod jednoducha kontrola je rychlejší
105 #č jak volání numpy množinových funkcí
106 return (i in ii) and (j in ii)
107
108
109
110 #
111 # ConvexSolver
112 #
113
114
115 def get_offsets(a, X):
116 #č nejak tuším, že v poslední dimenzi
117 #č znaménko normál musí být jednotné
118 # a = a * -np.sign(a[-1])
119 a = a * (1 - 2 * (a[-1] > 0))
120 b = X @ a
121 return b
122
123
124 #č podoba tamtamtoho tehdejšího prvního pokusu.
125 #č Jen pro srandu. Pro historickej záznam
126 def convex_solver(points, line_indices, tries_to_fix=1, tol=1e-7):
100 127 i, j = line_indices i, j = line_indices
101 128
102 129 X = points X = points
 
... ... def is_line_convex(points, line_indices):
114 141
115 142 # get constrain # get constrain
116 143 a = basis[:, dim] a = basis[:, dim]
117 #č nejak tuším, že v poslední dimenzi
118 #č znaménko normál musí být jednotné
119 a = a * -np.sign(a[-1])
120 b = X @ a
121 if np.max(b) - np.max(b[[i, j]]) < 1e-7:
144 b = get_offsets(a, X)
145 if np.max(b) - np.max(b[[i, j]]) < tol:
122 146 return True return True
123 147 else: else:
124 148 idx = np.argmax(b) idx = np.argmax(b)
 
... ... def is_line_convex(points, line_indices):
127 151
128 152
129 153
130 for __ in range(ndim):
154 for __ in range(ndim + tries_to_fix):
131 155 basis, __ = np.linalg.qr(basis) basis, __ = np.linalg.qr(basis)
132 156
133 157 # get constrain # get constrain
134 158 a = basis[:, -1] a = basis[:, -1]
135 #č nejak tuším, že v poslední dimenzi
136 #č znaménko normál musí být jednotné
137 a = a * -np.sign(a[-1])
138 b = X @ a
139 if np.max(b) - np.max(b[[i, j]]) < 1e-7:
159 b = get_offsets(a, X)
160 if np.max(b) - np.max(b[[i, j]]) < tol:
140 161 return True return True
141 162 else: else:
142 163 idx = np.argmax(b) idx = np.argmax(b)
 
... ... def is_line_convex(points, line_indices):
145 166
146 167 basis, __ = np.linalg.qr(basis) basis, __ = np.linalg.qr(basis)
147 168 a = basis[:, -1] a = basis[:, -1]
148 #č nejak tuším, že v poslední dimenzi
149 #č znaménko normál musí být jednotné
150 a = a * -np.sign(a[-1])
151 b = X @ a
152 return np.max(b) - np.max(b[[i, j]]) < 1e-7
153
169 b = get_offsets(a, X)
170 return np.max(b) - np.max(b[[i, j]]) < tol
154 171
155 172
173
174
175 #č Hlavní pointa ConvexSpline třídy:
176 #č Využit navíc geometrických informací, které už předem známé:
177 #č 1. Známe souřadnice vzorků.
178 #č 2. Víme, že přímka mezí těmi dvěma vzorky leží v hyperrovině
179 #č 3. Vždyť to my zvedáme na povrch convexního paraboloidu!
180 #č Můžeme tedy v každém její bodě najit tečnou hyperrovinu.
181 def convex_spline(points, couple_indices, tries_to_fix=1, tol=1e-7):
182 i, j = couple_indices
156 183
157 class ConvexSolver:
158 """
159 č Hlavní pointa třídy:
160 č pokud dva body zvednuté na povrch convexního paraboloidu
161 č v prostoru ndim+1 (feature space, quadratic kernel)
162 č lze lineárně separovat (hyperrovinou) od ostatních bodů,
163 č znamená to, že v původním prostoru
164 č jejich Voroného buňky budou mít společnou stěnu (kontakt),
165 č neboli, což je totež, u Delone triangulace by měly společné simplexy
184 X = points
185 __nsim, ndim = X.shape
166 186
167 č nebudeme puntičkařit a pro jednoduchost předepíšeme,
168 č nechť dva body zájmu leží přímo v hyperrovině
169 č (bude to hlasít existence rozhraní i v degenerovaných případech
170 č jako např. tří teček na jedné přímce. Mně to ale nevadí)
171 """
172 def __init__(self, points):
173 nsim, ndim = points.shape
187
188
189
190 basis = np.random.random((ndim, ndim))
191 #č první vektor musí být zadán přímkou mezí vzorky
192 #č jinak se posype náš předpoklad, že leží v hyperrovině
193 #č a žádné výsledky "za", "před" hyperrovinou nebudou nic znamenat
194 basis[:, 0] = X[j] - X[i] #č QR rozklad jede po sloupcich
195
196 #č jako indice zkusme použit bod na usečce uprostřed mezí vzorky
197 half_point = np.mean(X[[i, j]], axis=0)
198
199 #č všechy souřadnice jsou dány radius-vektorem od středu,
200 #č ale poslední souřadnice je to naše zvednutí,
201 #č kde bychom mohli zkusit dát korrektnější směr.
202 #č Mně humpolackými uvahami o tečně paraboly
203 #č na caru paríru vyšlo něco jako
204 #č že stačí dát poslední složku 0,5.
205 #č Jakože čím je roloměr je větší,
206 #č tím je "svislá" složka automaticky měnší.
207 #č Jakože netřeba ani normalizovat, ani nic "složitě" počítat
208 half_point[-1] = -0.5
209
210 #č ten náš radius-vektor není ortogonální
211 #č k přímce, na které leží ty naši dva vzorky
212 #č QR rozklad je ortogonalizuje
213 #č a vygeneruje další ortogonalní vektory
214 basis[:, 1] = half_point
215 basis, __ = np.linalg.qr(basis)
216
217
218 #č vytahneme náš ortogonalizovaný odhad
219 #č normálního vektoru
220 a = basis[:, 1]
221 b = get_offsets(a, X)
222
223 if np.max(b) - np.max(b[[i, j]]) < tol:
224 #č bylo to myšleno jako jakési zoufalství
225 #č ale funguje překvapivě dobře
226 return True
227 else:
228 idx = np.argmax(b)
229 #č nahradíme v jedničce naš odhad normálního vektoru
230 #č nalezenou překažkou.
231 #č Zbytek bazí jíž byl ortogonální
232 #č k té naši pomyšlené normále
233 basis[:, 1] = X[idx] - X[i]
234
235 #č Ve zbytku pokračujeme jako vždycky.
236 #č Pořad ndim pokusu u False párečku
237 for __ in range(ndim + tries_to_fix):
238 basis, __ = np.linalg.qr(basis)
174 239
175 self.lifted_points = np.empty((nsim, ndim + 1))
176 self.lifted_points[:, :ndim] = points
177 # kind of datascience. feature space, quadratic kernel...
178 self.lifted_points[:, -1] = np.sum(np.square(points), axis=1)
240 # get constrain
241 a = basis[:, -1]
242 b = get_offsets(a, X)
243 if np.max(b) - np.max(b[[i, j]]) < tol:
244 return True
245 else:
246 idx = np.argmax(b)
247 basis[:, 2:] = basis[:, 1:-1]
248 basis[:, 1] = X[idx] - X[i]
249
250 basis, __ = np.linalg.qr(basis)
251 a = basis[:, -1]
252 b = get_offsets(a, X)
253 return np.max(b) - np.max(b[[i, j]]) < tol
254
255
256
257
258
259
260
261
262 #č na rozdil od předchozího spline,
263 #č sort nesestavuje hned ortogonální k normále bazi, dělá to postupně
264 #č klíčovým stalo to, že v každem kroku obnovujeme původní odhad normály
265 def convex_sort(points, couple_indices, tries_to_fix=1, tol=1e-7):
266 i, j = couple_indices
267
268 X = points
269 __nsim, ndim = X.shape
270
271
272
273
274 basis = np.empty((ndim, ndim))
275 #č první vektor musí být zadán přímkou mezí vzorky
276 #č jinak se posype náš předpoklad, že leží v hyperrovině
277 #č a žádné výsledky "za", "před" hyperrovinou nebudou nic znamenat
278 basis[:, 0] = X[j] - X[i] #č QR rozklad jede po sloupcich
279
280 #č jako indice zkusme použit bod na usečce uprostřed mezí vzorky
281 half_point = np.mean(points[[i, j]], axis=0)
282
283
284 #č všechy souřadnice jsou dány radius-vektorem od středu,
285 #č ale poslední souřadnice je to naše zvednutí,
286 #č kde bychom mohli zkusit dát korrektnější směr.
287 #č Mně humpolackými uvahami o tečně paraboly
288 #č na caru paríru vyšlo něco jako
289 #č že stačí dát poslední složku 0,5.
290 #č Jakože čím je roloměr větší,
291 #č tím je "svislá" složka automaticky měnší.
292 #č Jakože netřeba ani normalizovat, ani nic "složitě" počítat
293 half_point[-1] = -0.5
294 basis[:, 1] = half_point
295
296 #č ten náš radius-vektor není ortogonální
297 #č k přímce, na které leží ty naši dva vzorky
298 #č musíme ho (QR rozkladem) ortogonalizovat
299 for dim in range(1, ndim-1):
300 #č co jsem viděl, numpy matici Q normalizuje
301 #č a první sloupec zůstavá (skoro) tím samým, co byl před tím
302 basis[:, :dim+1], __ = np.linalg.qr(basis[:, :dim+1])
179 303
304 # get constrain
305 a = basis[:, dim]
306 b = get_offsets(a, X)
307 if (np.max(b) - np.max(b[[i, j]])) < tol:
308 return True
180 309
181 def is_couple(self, couple_indices):
182 return is_line_convex(self.lifted_points, couple_indices)
310 #else:
311 idx = np.argmax(b)
312 basis[:, 2:dim+1] = basis[:, 1:dim]
313 basis[:, 1] = X[idx] - X[i]
314 basis[:, dim+1] = half_point
315
316
317
318 for __ in range(tries_to_fix):
319 basis, __ = np.linalg.qr(basis)
320 # get constrain
321 a = basis[:, -1]
322 b = get_offsets(a, X)
323 if (np.max(b) - np.max(b[[i, j]])) < tol:
324 return True
325 idx = np.argmax(b)
326 basis[:, 2:] = basis[:, 1:-1]
327 basis[:, 1] = X[idx] - X[i]
328
329
330 basis, __ = np.linalg.qr(basis)
331 a = basis[:, -1]
332 b = get_offsets(a, X)
333 return (np.max(b) - np.max(b[[i, j]])) < tol
334
335
336
337
338
339
340 def convex_sprite(X, couple_indices, tries_to_fix=1, tol=1e-7):
341 i, j = couple_indices
342 __nsim, ndim = X.shape
343
344 baseline = X[j] - X[i]
345
346 # sprite does not mean anything. Just a word
347 #č místo vyslovéné bazi budeme vektory ukladat do
348 #č jakési obecné matici
349 sprite = np.empty((ndim + tries_to_fix, ndim))
350 #č první vektor musí být zadán přímkou mezí vzorky
351 #č jinak se posype náš předpoklad, že leží v hyperrovině
352 #č a žádné výsledky "za", "před" hyperrovinou nebudou nic znamenat
353 baseline = X[j] - X[i]
354 sprite[-2] = baseline
355
356 #č jako indice zkusme použit bod na usečce uprostřed mezí vzorky
357 half_point = np.mean(X[[i, j]], axis=0)
358
359
360 #č všechy souřadnice jsou dány radius-vektorem od středu,
361 #č ale poslední souřadnice je to naše zvednutí,
362 #č kde bychom mohli zkusit dát korrektnější směr.
363 #č Mně humpolackými uvahami o tečně paraboly
364 #č na caru paríru vyšlo něco jako
365 #č že stačí dát poslední složku 0,5.
366 #č Jakože čím je roloměr větší,
367 #č tím je "svislá" složka automaticky měnší.
368 #č Jakože netřeba ani normalizovat, ani nic "složitě" počítat
369 half_point[-1] = -0.5
370 sprite[-1] = half_point
371
372 #č ten náš radius-vektor není ortogonální
373 #č k přímce, na které leží ty naši dva vzorky
374 #č musíme ho (QR rozkladem) ortogonalizovat
375 for dim in range(1, ndim-1):
376 basis, __ = np.linalg.qr(sprite[-dim-1:].T)
183 377
378 # get constrain
379 a = basis[:, -1]
380 b = get_offsets(a, X)
381 if (np.max(b) - np.max(b[[i, j]])) < tol:
382 return True
184 383
185 #č Odbočka z odbočky
186 class ConvexSpline:
384 #else:
385 idx = np.argmax(b)
386 sprite[-dim-1] = X[idx] - X[i]
387 sprite[-dim-2] = baseline
388
389
390 #č tady máme
391 #č sprite[-ndim+1] = nějaký vektor
392 #č sprite[-ndim] = baseline
393
394 for t in range(tries_to_fix):
395 basis, __ = np.linalg.qr(sprite[-ndim-t:].T)
396 # get constrain
397 a = basis[:, -1]
398 b = get_offsets(a, X)
399 if (np.max(b) - np.max(b[[i, j]])) < tol:
400 return True
401 idx = np.argmax(b)
402 sprite[-ndim-t] = X[idx] - X[i]
403 sprite[-ndim-1-t] = baseline
404
405 assert (sprite[0] == baseline).all()
406
407 basis, __ = np.linalg.qr(sprite.T)
408 a = basis[:, -1]
409 b = get_offsets(a, X)
410 return (np.max(b) - np.max(b[[i, j]])) < tol
411
412
413
414
415
416
417 class ConvexSolver:
187 418 """ """
188 č Hlavní pointa CS tříd:
419 č Hlavní pointa třídy:
189 420 č pokud dva body zvednuté na povrch convexního paraboloidu č pokud dva body zvednuté na povrch convexního paraboloidu
190 421 č v prostoru ndim+1 (feature space, quadratic kernel) č v prostoru ndim+1 (feature space, quadratic kernel)
191 422 č lze lineárně separovat (hyperrovinou) od ostatních bodů, č lze lineárně separovat (hyperrovinou) od ostatních bodů,
 
... ... class ConvexSpline:
193 424 č jejich Voroného buňky budou mít společnou stěnu (kontakt), č jejich Voroného buňky budou mít společnou stěnu (kontakt),
194 425 č neboli, což je totež, u Delone triangulace by měly společné simplexy č neboli, což je totež, u Delone triangulace by měly společné simplexy
195 426
196 č Hlavní pointa ConvexSpline třídy:
197 č Využit navíc geometrických informací, které už předem známé:
198 č 1. Známe souřadnice vzorků.
199 č 2. Víme, že přímka mezí těmi dvěma vzorky leží v hyperrovině
200 č 3. Vždyť to my zvedáme na povrch convexního paraboloidu!
201 č Můžeme tedy v každém její bodě najit tečnou hyperrovinu.
202
203
204 427 č nebudeme puntičkařit a pro jednoduchost předepíšeme, č nebudeme puntičkařit a pro jednoduchost předepíšeme,
205 428 č nechť dva body zájmu leží přímo v hyperrovině č nechť dva body zájmu leží přímo v hyperrovině
206 429 č (bude to hlasít existence rozhraní i v degenerovaných případech č (bude to hlasít existence rozhraní i v degenerovaných případech
207 430 č jako např. tří teček na jedné přímce. Mně to ale nevadí) č jako např. tří teček na jedné přímce. Mně to ale nevadí)
208 431 """ """
209 def __init__(self, points):
432 def __init__(self, points, convex_solver=convex_sprite):
210 433 nsim, ndim = points.shape nsim, ndim = points.shape
211 434
212 435 self.lifted_points = np.empty((nsim, ndim + 1)) self.lifted_points = np.empty((nsim, ndim + 1))
 
... ... class ConvexSpline:
214 437 # kind of datascience. feature space, quadratic kernel... # kind of datascience. feature space, quadratic kernel...
215 438 self.lifted_points[:, -1] = np.sum(np.square(points), axis=1) self.lifted_points[:, -1] = np.sum(np.square(points), axis=1)
216 439
440 self.convex_solver = convex_solver
217 441
218 def is_couple(self, couple_indices, tries_to_fix=1, tol=1e-7):
219 i, j = couple_indices
220
221 X = self.lifted_points
222 __nsim, ndim = X.shape
223
224
225
226
227 basis = np.empty((ndim, ndim))
228 #č první vektor musí být zadán přímkou mezí vzorky
229 #č jinak se posype náš předpoklad, že leží v hyperrovině
230 #č a žádné výsledky "za", "před" hyperrovinou nebudou nic znamenat
231 basis[:, 0] = X[j] - X[i] #č QR rozklad jede po sloupcich
232
233 #č jako indice zkusme použit bod na usečce uprostřed mezí vzorky
234 half_point = np.mean(self.lifted_points[[i, j]], axis=0)
235
236
237 #č všechy souřadnice jsou dány radius-vektorem od středu,
238 #č ale poslední souřadnice je to naše zvednutí,
239 #č kde bychom mohli zkusit dát korrektnější směr.
240 #č Mně humpolackými uvahami o tečně paraboly
241 #č na caru paríru vyšlo něco jako
242 #č že stačí dát poslední složku 0,5.
243 #č Jakože čím je roloměr větší,
244 #č tím je "svislá" složka automaticky měnší.
245 #č Jakože netřeba ani normalizovat, ani nic "složitě" počítat
246 half_point[-1] = -0.5
247 basis[:, 1] = half_point
248
249 #č ten náš radius-vektor není ortogonální
250 #č k přímce, na které leží ty naši dva vzorky
251 #č musíme ho (QR rozkladem) ortogonalizovat
252 for dim in range(1, ndim-1):
253 #č co jsem viděl, numpy matici Q normalizuje
254 #č a první sloupec zůstavá (skoro) tím samým, co byl před tím
255 basis[:, :dim+1], __ = np.linalg.qr(basis[:, :dim+1])
256
257 # get constrain
258 a = basis[:, dim]
259 #č nejak tuším, že v poslední dimenzi
260 #č znaménko normál musí být jednotné
261 a = a * (1 - 2 * (a[-1] > 0)) # a = a * -np.sign(a[-1])
262 b = X @ a
263 if (np.max(b) - np.max(b[[i, j]])) < tol:
264 return True
265
266 #else:
267 idx = np.argmax(b)
268 basis[:, 2:dim+1] = basis[:, 1:dim]
269 basis[:, 1] = X[idx] - X[i]
270 basis[:, dim+1] = half_point
271
272
273
274 for __ in range(tries_to_fix):
275 basis, __ = np.linalg.qr(basis)
276 # get constrain
277 a = basis[:, -1]
278 #č nejak tuším, že v poslední dimenzi
279 #č znaménko normál musí být jednotné
280 a = a * (1 - 2 * (a[-1] > 0)) # a = a * -np.sign(a[-1])
281 b = X @ a
282 if (np.max(b) - np.max(b[[i, j]])) < tol:
283 return True
284 idx = np.argmax(b)
285 basis[:, 2:] = basis[:, 1:-1]
286 basis[:, 1] = X[idx] - X[i]
287
288
289 basis, __ = np.linalg.qr(basis)
290 a = basis[:, -1]
291 #č nejak tuším, že v poslední dimenzi
292 #č znaménko normál musí být jednotné
293 a = a * (1 - 2 * (a[-1] > 0)) # a = a * -np.sign(a[-1])
294 b = X @ a
295 return (np.max(b) - np.max(b[[i, j]])) < tol
296
442 def is_couple(self, couple_indices, *args, **kwargs):
443 return self.convex_solver(self.lifted_points, couple_indices, *args, **kwargs)
297 444
298 445
299 446
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/iam-git/WellMet

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/iam-git/WellMet

Clone this repository using git:
git clone git://git.rocketgit.com/user/iam-git/WellMet

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main