pynumerics 2.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. pynumerics/__init__.py +73 -0
  2. pynumerics/_bin/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  3. pynumerics/_bin/Microsoft.CodeAnalysis.LICENSE.txt +27 -0
  4. pynumerics/_bin/Microsoft.CodeAnalysis.dll +0 -0
  5. pynumerics/_bin/Numerics.dll +0 -0
  6. pynumerics/_bin/pynumerics.runtimeconfig.json +15 -0
  7. pynumerics/_coverage.py +3825 -0
  8. pynumerics/_util.py +237 -0
  9. pynumerics/_version.py +40 -0
  10. pynumerics/bootstrap.py +593 -0
  11. pynumerics/callbacks.py +791 -0
  12. pynumerics/copulas.py +910 -0
  13. pynumerics/data.py +2233 -0
  14. pynumerics/differentiation.py +348 -0
  15. pynumerics/distributions.py +4043 -0
  16. pynumerics/download.py +623 -0
  17. pynumerics/enums.py +119 -0
  18. pynumerics/errors.py +245 -0
  19. pynumerics/functions.py +1142 -0
  20. pynumerics/goodness_of_fit.py +699 -0
  21. pynumerics/graphs.py +556 -0
  22. pynumerics/hypothesis_tests.py +445 -0
  23. pynumerics/identity.py +144 -0
  24. pynumerics/integration.py +677 -0
  25. pynumerics/linalg.py +1408 -0
  26. pynumerics/machine_learning.py +1335 -0
  27. pynumerics/marshal.py +733 -0
  28. pynumerics/mathematics.py +1053 -0
  29. pynumerics/mcmc.py +1406 -0
  30. pynumerics/multivariate.py +1539 -0
  31. pynumerics/ode.py +156 -0
  32. pynumerics/optimization.py +1736 -0
  33. pynumerics/probability.py +966 -0
  34. pynumerics/py.typed +0 -0
  35. pynumerics/regional.py +522 -0
  36. pynumerics/roots.py +274 -0
  37. pynumerics/runtime.py +384 -0
  38. pynumerics/sampling.py +1758 -0
  39. pynumerics/special.py +1079 -0
  40. pynumerics/statistics.py +1958 -0
  41. pynumerics/timeseries.py +1326 -0
  42. pynumerics-2.3.0.dist-info/METADATA +142 -0
  43. pynumerics-2.3.0.dist-info/RECORD +46 -0
  44. pynumerics-2.3.0.dist-info/WHEEL +5 -0
  45. pynumerics-2.3.0.dist-info/licenses/LICENSE +10 -0
  46. pynumerics-2.3.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,966 @@
1
+ """Probability combination for risk analysis from ``Numerics.Data.Statistics.Probability``.
2
+
3
+ Joint, union and mutually exclusive probabilities of events under independence, perfect positive
4
+ or negative dependence, a correlation matrix through the product of conditional marginals (PCM),
5
+ a multivariate normal, or an equicorrelated single-factor Gaussian structure. Each function calls
6
+ one Numerics member.
7
+
8
+ Indicator rows mark which events occur (1) or do not (0). ``binomial_combinations`` and
9
+ ``indicators`` are the subset counts and indicator rows of the inclusion-exclusion expansion in
10
+ subset-size order; the forms without them enumerate every combination. Event lists come back as
11
+ a probability vector and an int32 indicator matrix with one row per exclusive event.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import Any
17
+
18
+ import numpy as np
19
+
20
+ from pynumerics._util import namespace, net_enum
21
+ from pynumerics.enums import NetEnum
22
+ from pynumerics.errors import translate_public
23
+ from pynumerics.marshal import (
24
+ _int32_array,
25
+ _net_rectangular,
26
+ to_net_doubles,
27
+ to_net_ints,
28
+ to_net_matrix,
29
+ to_numpy_doubles,
30
+ to_numpy_ints,
31
+ )
32
+
33
+ _TOLERANCE = 1e-4
34
+ """Numerics' default absolute and relative inclusion-exclusion tolerances."""
35
+
36
+
37
+ class DependencyType(NetEnum):
38
+ """Dependence between events (``Probability.DependencyType``)."""
39
+
40
+ INDEPENDENT = "Independent"
41
+ PERFECTLY_POSITIVE = "PerfectlyPositive"
42
+ PERFECTLY_NEGATIVE = "PerfectlyNegative"
43
+ CORRELATION_MATRIX = "CorrelationMatrix"
44
+
45
+
46
+ class ExclusiveEnumerationStatus(NetEnum):
47
+ """Outcome of a lazily enumerated exclusive-probability expansion (``Probability.ExclusiveEnumerationStatus``)."""
48
+
49
+ COMPLETE = "Complete"
50
+ CONVERGED = "Converged"
51
+ CAPPED = "Capped"
52
+
53
+
54
+ def _probability() -> Any:
55
+ """Return ``Numerics.Data.Statistics.Probability`` after starting the runtime."""
56
+ return namespace("Numerics.Data.Statistics").Probability
57
+
58
+
59
+ def _dependency(value: DependencyType | str) -> Any:
60
+ """Map a dependency to the .NET enum member."""
61
+ return net_enum(_probability().DependencyType, value)
62
+
63
+
64
+ def _status(value: Any) -> ExclusiveEnumerationStatus:
65
+ """Map a .NET enumeration status to the Python enum."""
66
+ return ExclusiveEnumerationStatus(str(value))
67
+
68
+
69
+ def _int_matrix(values: Any) -> Any:
70
+ """Copy a 2-D integer array into a new ``Int32[,]`` in one copy, refusing values outside the int32 range."""
71
+ array = np.asarray(values)
72
+ if array.ndim != 2:
73
+ raise ValueError(f"indicators must be two-dimensional; got shape {array.shape}.")
74
+ return _net_rectangular(_int32_array(array))
75
+
76
+
77
+ def _rows(indicators: Any) -> tuple[Any, bool]:
78
+ """Return the indicators as ``Int32[]`` or ``Int32[,]`` and whether they are one row."""
79
+ array = np.asarray(indicators)
80
+ if array.ndim == 1:
81
+ return to_net_ints(array), True
82
+ return _int_matrix(array), False
83
+
84
+
85
+ def _mvn(multivariate_normal: Any) -> Any:
86
+ """Return the .NET ``MultivariateNormal`` behind a wrapper (or the object itself)."""
87
+ return getattr(multivariate_normal, "net", multivariate_normal)
88
+
89
+
90
+ def _event_lists() -> tuple[Any, Any]:
91
+ """Return new empty .NET ``List<double>`` and ``List<int[]>`` output lists."""
92
+ import System # noqa: PLC0415 - the runtime is running once _probability returns
93
+ from System.Collections.Generic import List # noqa: PLC0415
94
+
95
+ return List[System.Double](), List[System.Array[System.Int32]]()
96
+
97
+
98
+ def _events(probabilities: Any, indicators: Any) -> tuple[np.ndarray, np.ndarray]:
99
+ """Return .NET event lists as a probability vector and an int32 indicator matrix."""
100
+ values = to_numpy_doubles(probabilities)
101
+ rows = [to_numpy_ints(row) for row in indicators]
102
+ if not rows:
103
+ return values, np.empty((0, 0), dtype=np.int32)
104
+ return values, np.vstack(rows)
105
+
106
+
107
+ def _pair_member(name: str, a: float, b: float, rho: float) -> float:
108
+ return float(getattr(_probability(), name)(float(a), float(b), float(rho)))
109
+
110
+
111
+ def a_and_b(a: float, b: float, rho: float = 0.0) -> float:
112
+ """Return P(A and B) of two events with correlated Gaussian variates (``Probability.AAndB``).
113
+
114
+ Parameters
115
+ ----------
116
+ a, b : float
117
+ The marginal probabilities.
118
+ rho : float, optional
119
+ The Pearson correlation of the underlying standard normal variates; default 0.
120
+
121
+ Returns
122
+ -------
123
+ float
124
+ The joint probability, ``a b`` at zero correlation.
125
+ """
126
+ return _pair_member("AAndB", a, b, rho)
127
+
128
+
129
+ def a_or_b(a: float, b: float, rho: float = 0.0) -> float:
130
+ """Return P(A or B) of two events (``Probability.AOrB``).
131
+
132
+ Parameters
133
+ ----------
134
+ a, b : float
135
+ The marginal probabilities.
136
+ rho : float, optional
137
+ The correlation of the underlying standard normal variates; default 0.
138
+
139
+ Returns
140
+ -------
141
+ float
142
+ ``a + b - P(A and B)``.
143
+ """
144
+ return _pair_member("AOrB", a, b, rho)
145
+
146
+
147
+ def a_not_b(a: float, b: float, rho: float = 0.0) -> float:
148
+ """Return P(A and not B) of two events (``Probability.ANotB``).
149
+
150
+ Parameters
151
+ ----------
152
+ a, b : float
153
+ The marginal probabilities.
154
+ rho : float, optional
155
+ The correlation of the underlying standard normal variates; default 0.
156
+
157
+ Returns
158
+ -------
159
+ float
160
+ ``a - P(A and B)``.
161
+ """
162
+ return _pair_member("ANotB", a, b, rho)
163
+
164
+
165
+ def b_not_a(a: float, b: float, rho: float = 0.0) -> float:
166
+ """Return P(B and not A) of two events (``Probability.BNotA``).
167
+
168
+ Parameters
169
+ ----------
170
+ a, b : float
171
+ The marginal probabilities.
172
+ rho : float, optional
173
+ The correlation of the underlying standard normal variates; default 0.
174
+
175
+ Returns
176
+ -------
177
+ float
178
+ ``b - P(A and B)``.
179
+ """
180
+ return _pair_member("BNotA", a, b, rho)
181
+
182
+
183
+ def a_given_b(a: float, b: float, rho: float = 0.0) -> float:
184
+ """Return P(A | B) of two events (``Probability.AGivenB``).
185
+
186
+ Parameters
187
+ ----------
188
+ a, b : float
189
+ The marginal probabilities.
190
+ rho : float, optional
191
+ The correlation of the underlying standard normal variates; default 0.
192
+
193
+ Returns
194
+ -------
195
+ float
196
+ ``P(A and B) / b``.
197
+ """
198
+ return _pair_member("AGivenB", a, b, rho)
199
+
200
+
201
+ def b_given_a(a: float, b: float, rho: float = 0.0) -> float:
202
+ """Return P(B | A) of two events (``Probability.BGivenA``).
203
+
204
+ Parameters
205
+ ----------
206
+ a, b : float
207
+ The marginal probabilities.
208
+ rho : float, optional
209
+ The correlation of the underlying standard normal variates; default 0.
210
+
211
+ Returns
212
+ -------
213
+ float
214
+ ``P(A and B) / a``.
215
+ """
216
+ return _pair_member("BGivenA", a, b, rho)
217
+
218
+
219
+ def joint_probability(probabilities: Any, indicators: Any = None, correlation_matrix: Any = None,
220
+ dependency: DependencyType | str | None = None) -> float:
221
+ """Return the joint probability of events under a dependence model (``Probability.JointProbability``).
222
+
223
+ Without ``indicators`` every event occurs and ``dependency`` defaults to independence. With
224
+ ``indicators`` the indicated events occur and the others do not; ``dependency`` then defaults to
225
+ the correlation matrix (the PCM method of :func:`joint_probability_hpcm`), and NaN results when
226
+ no correlation matrix is given.
227
+
228
+ Parameters
229
+ ----------
230
+ probabilities : array_like
231
+ The marginal probabilities.
232
+ indicators : array_like, optional
233
+ One 0/1 indicator per event.
234
+ correlation_matrix : array_like, optional
235
+ The correlation matrix, used with indicators and the correlation-matrix dependency.
236
+ dependency : DependencyType or str, optional
237
+ The dependence model.
238
+
239
+ Returns
240
+ -------
241
+ float
242
+ The joint probability.
243
+ """
244
+ p = _probability()
245
+ values = to_net_doubles(probabilities)
246
+ if indicators is None:
247
+ if correlation_matrix is not None:
248
+ raise ValueError("correlation_matrix requires indicators.")
249
+ return float(p.JointProbability(values, _dependency(dependency or DependencyType.INDEPENDENT)))
250
+ matrix = None if correlation_matrix is None else to_net_matrix(correlation_matrix)
251
+ return float(p.JointProbability(values, to_net_ints(indicators), matrix,
252
+ _dependency(dependency or DependencyType.CORRELATION_MATRIX)))
253
+
254
+
255
+ def _indicated(name: str, probabilities: Any, indicators: Any) -> float:
256
+ member = getattr(_probability(), name)
257
+ values = to_net_doubles(probabilities)
258
+ return float(member(values) if indicators is None else member(values, to_net_ints(indicators)))
259
+
260
+
261
+ def independent_joint_probability(probabilities: Any, indicators: Any = None) -> float:
262
+ """Return the joint probability under independence (``Probability.IndependentJointProbability``).
263
+
264
+ Parameters
265
+ ----------
266
+ probabilities : array_like
267
+ The marginal probabilities.
268
+ indicators : array_like, optional
269
+ One 0/1 indicator per event; only indicated events take part. Default all.
270
+
271
+ Returns
272
+ -------
273
+ float
274
+ The product of the participating probabilities.
275
+ """
276
+ return _indicated("IndependentJointProbability", probabilities, indicators)
277
+
278
+
279
+ def positive_joint_probability(probabilities: Any, indicators: Any = None) -> float:
280
+ """Return the joint probability under perfect positive dependence (``Probability.PositiveJointProbability``).
281
+
282
+ Parameters
283
+ ----------
284
+ probabilities : array_like
285
+ The marginal probabilities.
286
+ indicators : array_like, optional
287
+ One 0/1 indicator per event; only indicated events take part. Default all.
288
+
289
+ Returns
290
+ -------
291
+ float
292
+ The smallest participating probability (the Frechet-Hoeffding upper bound).
293
+ """
294
+ return _indicated("PositiveJointProbability", probabilities, indicators)
295
+
296
+
297
+ def negative_joint_probability(probabilities: Any, indicators: Any = None) -> float:
298
+ """Return the Frechet-Hoeffding lower bound of the joint probability (``Probability.NegativeJointProbability``).
299
+
300
+ Parameters
301
+ ----------
302
+ probabilities : array_like
303
+ The marginal probabilities.
304
+ indicators : array_like, optional
305
+ One 0/1 indicator per event; only indicated events take part. Default all.
306
+
307
+ Returns
308
+ -------
309
+ float
310
+ ``max(0, sum p - (k - 1))`` over the k participating events; 1 when none participate.
311
+ """
312
+ return _indicated("NegativeJointProbability", probabilities, indicators)
313
+
314
+
315
+ def _pcm(name: str, probabilities: Any, indicators: Any, correlation_matrix: Any,
316
+ return_conditional: bool) -> float | tuple[float, np.ndarray]:
317
+ import System # noqa: PLC0415 - the runtime is running once _probability returns
318
+
319
+ member = getattr(_probability(), name)
320
+ values = np.asarray(probabilities, dtype=np.float64)
321
+ conditional = System.Array[System.Double](values.size) if return_conditional else None
322
+ result = float(member(to_net_doubles(values), to_net_ints(indicators), to_net_matrix(correlation_matrix),
323
+ conditional))
324
+ return (result, to_numpy_doubles(conditional)) if return_conditional else result
325
+
326
+
327
+ def joint_probability_hpcm(probabilities: Any, indicators: Any, correlation_matrix: Any,
328
+ return_conditional: bool = False) -> float | tuple[float, np.ndarray]:
329
+ """Return the joint probability by the modified PCM method (``Probability.JointProbabilityHPCM``).
330
+
331
+ Haden Smith's modification of Pandey's product of conditional marginals.
332
+
333
+ Parameters
334
+ ----------
335
+ probabilities : array_like
336
+ The marginal probabilities.
337
+ indicators : array_like
338
+ One 0/1 indicator per event.
339
+ correlation_matrix : array_like
340
+ The symmetric correlation matrix of the underlying normal variates.
341
+ return_conditional : bool, optional
342
+ Also return the conditional probability of each event; default False.
343
+
344
+ Returns
345
+ -------
346
+ probability : float
347
+ The joint probability.
348
+ conditional : numpy.ndarray
349
+ Only when ``return_conditional`` is True: the conditional probabilities.
350
+ """
351
+ return _pcm("JointProbabilityHPCM", probabilities, indicators, correlation_matrix, return_conditional)
352
+
353
+
354
+ def joint_probability_pcm(probabilities: Any, indicators: Any, correlation_matrix: Any,
355
+ return_conditional: bool = False) -> float | tuple[float, np.ndarray]:
356
+ """Return the joint probability by Pandey's PCM method (``Probability.JointProbabilityPCM``).
357
+
358
+ Parameters
359
+ ----------
360
+ probabilities : array_like
361
+ The marginal probabilities.
362
+ indicators : array_like
363
+ One 0/1 indicator per event.
364
+ correlation_matrix : array_like
365
+ The symmetric correlation matrix of the underlying normal variates.
366
+ return_conditional : bool, optional
367
+ Also return the conditional probability of each event; default False.
368
+
369
+ Returns
370
+ -------
371
+ probability : float
372
+ The joint probability.
373
+ conditional : numpy.ndarray
374
+ Only when ``return_conditional`` is True: the conditional probabilities.
375
+ """
376
+ return _pcm("JointProbabilityPCM", probabilities, indicators, correlation_matrix, return_conditional)
377
+
378
+
379
+ def joint_probabilities_pcm(probabilities: Any, indicators: Any, correlation_matrix: Any) -> np.ndarray:
380
+ """Return the PCM joint probability of each indicator row (``Probability.JointProbabilitiesPCM``).
381
+
382
+ Parameters
383
+ ----------
384
+ probabilities : array_like
385
+ The marginal probabilities.
386
+ indicators : array_like
387
+ A 2-D 0/1 array, one row per combination, in subset-size order. Precondition: the first
388
+ ``len(probabilities)`` rows must be the singleton rows, row ``i`` flagging event ``i`` alone.
389
+ Numerics returns ``probabilities[i]`` for those rows without reading them and does not check
390
+ the layout.
391
+ correlation_matrix : array_like
392
+ The correlation matrix.
393
+
394
+ Returns
395
+ -------
396
+ numpy.ndarray
397
+ One joint probability per row.
398
+ """
399
+ p = _probability()
400
+ return to_numpy_doubles(p.JointProbabilitiesPCM(to_net_doubles(probabilities), _int_matrix(indicators),
401
+ to_net_matrix(correlation_matrix)))
402
+
403
+
404
+ def joint_probability_mvn(probabilities: Any, indicators: Any, multivariate_normal: Any) -> float:
405
+ """Return the joint probability from a multivariate normal (``Probability.JointProbabilityMVN``).
406
+
407
+ Dimensions above two use the distribution's randomized lattice, which advances with each call.
408
+
409
+ Parameters
410
+ ----------
411
+ probabilities : array_like
412
+ The marginal probabilities.
413
+ indicators : array_like
414
+ One 0/1 indicator per event.
415
+ multivariate_normal : MultivariateNormal
416
+ The standard multivariate normal of the underlying variates (a wrapper or the .NET object).
417
+
418
+ Returns
419
+ -------
420
+ float
421
+ The joint probability.
422
+ """
423
+ p = _probability()
424
+ return float(p.JointProbabilityMVN(to_net_doubles(probabilities), to_net_ints(indicators),
425
+ _mvn(multivariate_normal)))
426
+
427
+
428
+ def joint_probabilities_mvn(probabilities: Any, indicators: Any, multivariate_normal: Any) -> np.ndarray:
429
+ """Return the multivariate normal joint probability of each indicator row (``Probability.JointProbabilitiesMVN``).
430
+
431
+ Rows are evaluated serially in order, so a freshly seeded distribution gives a reproducible batch.
432
+
433
+ Parameters
434
+ ----------
435
+ probabilities : array_like
436
+ The marginal probabilities.
437
+ indicators : array_like
438
+ A 2-D 0/1 array, one row per combination, in subset-size order. Precondition: the first
439
+ ``len(probabilities)`` rows must be the singleton rows, row ``i`` flagging event ``i`` alone.
440
+ Numerics returns ``probabilities[i]`` for those rows without reading them and does not check
441
+ the layout.
442
+ multivariate_normal : MultivariateNormal
443
+ The standard multivariate normal of the underlying variates.
444
+
445
+ Returns
446
+ -------
447
+ numpy.ndarray
448
+ One joint probability per row.
449
+ """
450
+ p = _probability()
451
+ return to_numpy_doubles(p.JointProbabilitiesMVN(to_net_doubles(probabilities), _int_matrix(indicators),
452
+ _mvn(multivariate_normal)))
453
+
454
+
455
+ def union(probabilities: Any, dependency: DependencyType | str = DependencyType.INDEPENDENT) -> float:
456
+ """Return the probability of the union of events (``Probability.Union``).
457
+
458
+ Parameters
459
+ ----------
460
+ probabilities : array_like
461
+ The marginal probabilities.
462
+ dependency : DependencyType or str, optional
463
+ Independence (default), perfect positive or perfect negative dependence.
464
+
465
+ Returns
466
+ -------
467
+ float
468
+ The union probability.
469
+ """
470
+ return float(_probability().Union(to_net_doubles(probabilities), _dependency(dependency)))
471
+
472
+
473
+ def independent_union(probabilities: Any) -> float:
474
+ """Return the union probability under independence, ``1 - prod(1 - p)`` (``Probability.IndependentUnion``).
475
+
476
+ Parameters
477
+ ----------
478
+ probabilities : array_like
479
+ The marginal probabilities.
480
+
481
+ Returns
482
+ -------
483
+ float
484
+ The union probability.
485
+ """
486
+ return float(_probability().IndependentUnion(to_net_doubles(probabilities)))
487
+
488
+
489
+ def positively_dependent_union(probabilities: Any) -> float:
490
+ """Return the union probability under perfect positive dependence, ``max p`` (``PositivelyDependentUnion``).
491
+
492
+ Parameters
493
+ ----------
494
+ probabilities : array_like
495
+ The marginal probabilities.
496
+
497
+ Returns
498
+ -------
499
+ float
500
+ The unimodal lower bound of the union.
501
+ """
502
+ return float(_probability().PositivelyDependentUnion(to_net_doubles(probabilities)))
503
+
504
+
505
+ def negatively_dependent_union(probabilities: Any) -> float:
506
+ """Return the union probability under perfect negative dependence, ``min(1, sum p)`` (``NegativelyDependentUnion``).
507
+
508
+ Parameters
509
+ ----------
510
+ probabilities : array_like
511
+ The marginal probabilities.
512
+
513
+ Returns
514
+ -------
515
+ float
516
+ The unimodal upper bound of the union.
517
+ """
518
+ return float(_probability().NegativelyDependentUnion(to_net_doubles(probabilities)))
519
+
520
+
521
+ def union_single_factor(probabilities: Any, rho: float, relative_tolerance: float = 1e-8) -> float:
522
+ """Return the union probability under an equicorrelated single-factor Gaussian (``UnionSingleFactor``).
523
+
524
+ ``P = int phi(z) [1 - prod(1 - Phi((b_i - sqrt(rho) z) / sqrt(1 - rho)))] dz`` with
525
+ ``b_i = Phi^-1(p_i)``: the events are independent given one shared standard normal factor.
526
+
527
+ Parameters
528
+ ----------
529
+ probabilities : array_like
530
+ The marginal probabilities.
531
+ rho : float
532
+ The common correlation, in [0, 1].
533
+ relative_tolerance : float, optional
534
+ The quadrature relative tolerance; default 1e-8.
535
+
536
+ Returns
537
+ -------
538
+ float
539
+ The union probability.
540
+ """
541
+ return float(_probability().UnionSingleFactor(to_net_doubles(probabilities), float(rho),
542
+ float(relative_tolerance)))
543
+
544
+
545
+ def single_factor_conditional_probabilities(normal_thresholds: Any, rho: float, z: float) -> np.ndarray:
546
+ """Return ``Phi((b_i - sqrt(rho) z) / sqrt(1 - rho))`` per threshold (``SingleFactorConditionalProbabilities``).
547
+
548
+ Parameters
549
+ ----------
550
+ normal_thresholds : array_like
551
+ The standard normal thresholds ``b_i = Phi^-1(p_i)``.
552
+ rho : float
553
+ The common correlation, in [0, 1).
554
+ z : float
555
+ The shared factor value.
556
+
557
+ Returns
558
+ -------
559
+ numpy.ndarray
560
+ The conditional event probabilities.
561
+ """
562
+ import System # noqa: PLC0415 - the runtime is running once _probability returns
563
+
564
+ p = _probability()
565
+ thresholds = to_net_doubles(normal_thresholds)
566
+ out = System.Array[System.Double](int(thresholds.Length))
567
+ p.SingleFactorConditionalProbabilities(thresholds, float(rho), float(z), out)
568
+ return to_numpy_doubles(out)
569
+
570
+
571
+ def union_pcm(probabilities: Any, correlation_matrix: Any, binomial_combinations: Any = None, indicators: Any = None,
572
+ absolute_tolerance: float = _TOLERANCE, relative_tolerance: float = _TOLERANCE,
573
+ return_events: bool = False) -> float | tuple[float, np.ndarray, np.ndarray]:
574
+ """Return the union probability by inclusion-exclusion with PCM joint probabilities (``Probability.UnionPCM``).
575
+
576
+ Parameters
577
+ ----------
578
+ probabilities : array_like
579
+ The marginal probabilities.
580
+ correlation_matrix : array_like
581
+ The correlation matrix.
582
+ binomial_combinations : array_like, optional
583
+ The number of combinations of each subset size; given together with ``indicators``.
584
+ indicators : array_like, optional
585
+ The 2-D indicator rows in subset-size order.
586
+ absolute_tolerance, relative_tolerance : float, optional
587
+ The convergence tolerances of the expansion; default 1e-4.
588
+ return_events : bool, optional
589
+ Also return the exclusive event probabilities and indicators; needs
590
+ ``binomial_combinations`` and ``indicators``. Default False.
591
+
592
+ Returns
593
+ -------
594
+ probability : float
595
+ The union probability.
596
+ event_probabilities : numpy.ndarray
597
+ Only when ``return_events`` is True.
598
+ event_indicators : numpy.ndarray
599
+ Only when ``return_events`` is True: one int32 row per event.
600
+ """
601
+ p = _probability()
602
+ values, matrix = to_net_doubles(probabilities), to_net_matrix(correlation_matrix)
603
+ atol, rtol = float(absolute_tolerance), float(relative_tolerance)
604
+ if binomial_combinations is None and indicators is None:
605
+ if return_events:
606
+ raise ValueError("return_events needs binomial_combinations and indicators.")
607
+ return float(p.UnionPCM(values, matrix, atol, rtol))
608
+ combinations, rows = to_net_ints(binomial_combinations), _int_matrix(indicators)
609
+ if not return_events:
610
+ return float(p.UnionPCM(values, combinations, rows, matrix, atol, rtol))
611
+ result, events, event_rows = p.UnionPCM(values, combinations, rows, matrix, None, None, atol, rtol)
612
+ return (float(result), *_events(events, event_rows))
613
+
614
+
615
+ def union_pcm_lazy(probabilities: Any, correlation_matrix: Any, absolute_tolerance: float = _TOLERANCE,
616
+ relative_tolerance: float = _TOLERANCE) -> tuple[float, ExclusiveEnumerationStatus]:
617
+ """Return the PCM union probability with combinations generated lazily (``Probability.UnionPCMLazy``).
618
+
619
+ Parameters
620
+ ----------
621
+ probabilities : array_like
622
+ The marginal probabilities.
623
+ correlation_matrix : array_like
624
+ The correlation matrix.
625
+ absolute_tolerance, relative_tolerance : float, optional
626
+ The convergence tolerances; default 1e-4.
627
+
628
+ Returns
629
+ -------
630
+ probability : float
631
+ The union probability.
632
+ status : ExclusiveEnumerationStatus
633
+ Whether the expansion completed or converged early.
634
+ """
635
+ p = _probability()
636
+ result, status = p.UnionPCMLazy(to_net_doubles(probabilities), to_net_matrix(correlation_matrix),
637
+ p.ExclusiveEnumerationStatus.Complete, float(absolute_tolerance),
638
+ float(relative_tolerance))
639
+ return float(result), _status(status)
640
+
641
+
642
+ def union_mvn(probabilities: Any, multivariate_normal: Any, binomial_combinations: Any = None,
643
+ indicators: Any = None) -> float:
644
+ """Return the union probability by inclusion-exclusion with multivariate normal joints (``Probability.UnionMVN``).
645
+
646
+ Parameters
647
+ ----------
648
+ probabilities : array_like
649
+ The marginal probabilities.
650
+ multivariate_normal : MultivariateNormal
651
+ The standard multivariate normal of the underlying variates.
652
+ binomial_combinations : array_like, optional
653
+ The number of combinations of each subset size; given together with ``indicators``.
654
+ indicators : array_like, optional
655
+ The 2-D indicator rows in subset-size order.
656
+
657
+ Returns
658
+ -------
659
+ float
660
+ The union probability.
661
+ """
662
+ p = _probability()
663
+ values, mvn = to_net_doubles(probabilities), _mvn(multivariate_normal)
664
+ if binomial_combinations is None and indicators is None:
665
+ return float(p.UnionMVN(values, mvn))
666
+ return float(p.UnionMVN(values, to_net_ints(binomial_combinations), _int_matrix(indicators), mvn))
667
+
668
+
669
+ def _exclusive(name: str, probabilities: Any, indicators: Any, binomial_combinations: Any,
670
+ absolute_tolerance: float, relative_tolerance: float) -> Any:
671
+ """Dispatch the shared overload set of ``IndependentExclusive`` and ``PositivelyDependentExclusive``."""
672
+ member = getattr(_probability(), name)
673
+ values = to_net_doubles(probabilities)
674
+ if binomial_combinations is not None:
675
+ if indicators is None:
676
+ raise ValueError("binomial_combinations needs indicators.")
677
+ events, rows = member(values, to_net_ints(binomial_combinations), _int_matrix(indicators), None, None,
678
+ float(absolute_tolerance), float(relative_tolerance))
679
+ return _events(events, rows)
680
+ if indicators is None:
681
+ return to_numpy_doubles(member(values))
682
+ net_rows, single = _rows(indicators)
683
+ result = member(values, net_rows)
684
+ return float(result) if single else to_numpy_doubles(result)
685
+
686
+
687
+ def independent_exclusive(probabilities: Any, indicators: Any = None, binomial_combinations: Any = None,
688
+ absolute_tolerance: float = _TOLERANCE, relative_tolerance: float = _TOLERANCE) -> Any:
689
+ """Return mutually exclusive event probabilities under independence (``Probability.IndependentExclusive``).
690
+
691
+ Parameters
692
+ ----------
693
+ probabilities : array_like
694
+ The marginal probabilities.
695
+ indicators : array_like, optional
696
+ One 0/1 row (one exclusive probability) or a 2-D array of rows; default every combination.
697
+ binomial_combinations : array_like, optional
698
+ The number of combinations of each subset size; with 2-D ``indicators`` this runs the
699
+ convergent inclusion-exclusion expansion and returns the event lists.
700
+ absolute_tolerance, relative_tolerance : float, optional
701
+ The convergence tolerances of the expansion; default 1e-4.
702
+
703
+ Returns
704
+ -------
705
+ float, numpy.ndarray or tuple of numpy.ndarray
706
+ The exclusive probability of one row, one per row (or per combination), or, with
707
+ ``binomial_combinations``, the event probabilities and their int32 indicator rows.
708
+ """
709
+ return _exclusive("IndependentExclusive", probabilities, indicators, binomial_combinations, absolute_tolerance,
710
+ relative_tolerance)
711
+
712
+
713
+ def positively_dependent_exclusive(probabilities: Any, indicators: Any = None, binomial_combinations: Any = None,
714
+ absolute_tolerance: float = _TOLERANCE,
715
+ relative_tolerance: float = _TOLERANCE) -> Any:
716
+ """Return exclusive probabilities under perfect positive dependence (``PositivelyDependentExclusive``).
717
+
718
+ Parameters
719
+ ----------
720
+ probabilities : array_like
721
+ The marginal probabilities.
722
+ indicators : array_like, optional
723
+ One 0/1 row or a 2-D array of rows; default every combination.
724
+ binomial_combinations : array_like, optional
725
+ The number of combinations of each subset size; with 2-D ``indicators`` this runs the
726
+ convergent expansion and returns the event lists.
727
+ absolute_tolerance, relative_tolerance : float, optional
728
+ The convergence tolerances of the expansion; default 1e-4.
729
+
730
+ Returns
731
+ -------
732
+ float, numpy.ndarray or tuple of numpy.ndarray
733
+ As for :func:`independent_exclusive`.
734
+ """
735
+ return _exclusive("PositivelyDependentExclusive", probabilities, indicators, binomial_combinations,
736
+ absolute_tolerance, relative_tolerance)
737
+
738
+
739
+ def independent_exclusive_lazy(probabilities: Any, include_no_event_row: bool = False,
740
+ max_emitted_combinations: int = 0, absolute_tolerance: float = _TOLERANCE,
741
+ relative_tolerance: float = _TOLERANCE,
742
+ ) -> tuple[np.ndarray, np.ndarray, ExclusiveEnumerationStatus]:
743
+ """Enumerate exclusive event probabilities under independence lazily (``Probability.IndependentExclusiveLazy``).
744
+
745
+ Combinations are generated in subset-size order instead of read from a materialized indicator
746
+ matrix.
747
+
748
+ Parameters
749
+ ----------
750
+ probabilities : array_like
751
+ The marginal probabilities.
752
+ include_no_event_row : bool, optional
753
+ Emit the all-zero row, carrying ``prod(1 - p)``, first; default False.
754
+ max_emitted_combinations : int, optional
755
+ The cap on emitted combinations; 0 (default) for none.
756
+ absolute_tolerance, relative_tolerance : float, optional
757
+ The convergence tolerances; default 1e-4.
758
+
759
+ Returns
760
+ -------
761
+ event_probabilities : numpy.ndarray
762
+ The exclusive event probabilities.
763
+ event_indicators : numpy.ndarray
764
+ One int32 indicator row per event.
765
+ status : ExclusiveEnumerationStatus
766
+ Complete, converged or capped.
767
+ """
768
+ events, rows = _event_lists()
769
+ status = _probability().IndependentExclusiveLazy(to_net_doubles(probabilities), events, rows,
770
+ bool(include_no_event_row), int(max_emitted_combinations),
771
+ float(absolute_tolerance), float(relative_tolerance))
772
+ return (*_events(events, rows), _status(status))
773
+
774
+
775
+ def positively_dependent_exclusive_lazy(probabilities: Any, absolute_tolerance: float = _TOLERANCE,
776
+ relative_tolerance: float = _TOLERANCE,
777
+ ) -> tuple[np.ndarray, np.ndarray, ExclusiveEnumerationStatus]:
778
+ """Enumerate exclusive probabilities under perfect positive dependence (``PositivelyDependentExclusiveLazy``).
779
+
780
+ Parameters
781
+ ----------
782
+ probabilities : array_like
783
+ The marginal probabilities.
784
+ absolute_tolerance, relative_tolerance : float, optional
785
+ The convergence tolerances; default 1e-4.
786
+
787
+ Returns
788
+ -------
789
+ event_probabilities : numpy.ndarray
790
+ The exclusive event probabilities.
791
+ event_indicators : numpy.ndarray
792
+ One int32 indicator row per event.
793
+ status : ExclusiveEnumerationStatus
794
+ Complete or converged.
795
+ """
796
+ events, rows = _event_lists()
797
+ status = _probability().PositivelyDependentExclusiveLazy(to_net_doubles(probabilities), events, rows,
798
+ float(absolute_tolerance), float(relative_tolerance))
799
+ return (*_events(events, rows), _status(status))
800
+
801
+
802
+ def exclusive_pcm(probabilities: Any, correlation_matrix: Any, binomial_combinations: Any = None,
803
+ indicators: Any = None, absolute_tolerance: float = _TOLERANCE,
804
+ relative_tolerance: float = _TOLERANCE, return_events: bool = False) -> Any:
805
+ """Return mutually exclusive event probabilities with PCM dependence (``Probability.ExclusivePCM``).
806
+
807
+ Parameters
808
+ ----------
809
+ probabilities : array_like
810
+ The marginal probabilities.
811
+ correlation_matrix : array_like
812
+ The correlation matrix.
813
+ binomial_combinations : array_like, optional
814
+ The number of combinations of each subset size; given together with ``indicators``.
815
+ indicators : array_like, optional
816
+ The 2-D indicator rows in subset-size order.
817
+ absolute_tolerance, relative_tolerance : float, optional
818
+ The convergence tolerances of the expansion (``return_events`` only); default 1e-4.
819
+ return_events : bool, optional
820
+ Run the convergent expansion and return the event lists; needs ``binomial_combinations``
821
+ and ``indicators``. Default False.
822
+
823
+ Returns
824
+ -------
825
+ numpy.ndarray or tuple of numpy.ndarray
826
+ One exclusive probability per combination, or the event probabilities and their int32
827
+ indicator rows.
828
+ """
829
+ p = _probability()
830
+ values, matrix = to_net_doubles(probabilities), to_net_matrix(correlation_matrix)
831
+ if binomial_combinations is None and indicators is None:
832
+ if return_events:
833
+ raise ValueError("return_events needs binomial_combinations and indicators.")
834
+ return to_numpy_doubles(p.ExclusivePCM(values, matrix))
835
+ combinations, rows = to_net_ints(binomial_combinations), _int_matrix(indicators)
836
+ if not return_events:
837
+ return to_numpy_doubles(p.ExclusivePCM(values, combinations, rows, matrix))
838
+ events, event_rows = p.ExclusivePCM(values, combinations, rows, matrix, None, None, float(absolute_tolerance),
839
+ float(relative_tolerance))
840
+ return _events(events, event_rows)
841
+
842
+
843
+ def exclusive_pcm_lazy(probabilities: Any, correlation_matrix: Any, absolute_tolerance: float = _TOLERANCE,
844
+ relative_tolerance: float = _TOLERANCE,
845
+ ) -> tuple[np.ndarray, np.ndarray, ExclusiveEnumerationStatus]:
846
+ """Enumerate exclusive event probabilities with PCM dependence lazily (``Probability.ExclusivePCMLazy``).
847
+
848
+ Parameters
849
+ ----------
850
+ probabilities : array_like
851
+ The marginal probabilities.
852
+ correlation_matrix : array_like
853
+ The correlation matrix.
854
+ absolute_tolerance, relative_tolerance : float, optional
855
+ The convergence tolerances; default 1e-4.
856
+
857
+ Returns
858
+ -------
859
+ event_probabilities : numpy.ndarray
860
+ The exclusive event probabilities.
861
+ event_indicators : numpy.ndarray
862
+ One int32 indicator row per event.
863
+ status : ExclusiveEnumerationStatus
864
+ Complete or converged.
865
+ """
866
+ events, rows = _event_lists()
867
+ status = _probability().ExclusivePCMLazy(to_net_doubles(probabilities), to_net_matrix(correlation_matrix),
868
+ events, rows, float(absolute_tolerance), float(relative_tolerance))
869
+ return (*_events(events, rows), _status(status))
870
+
871
+
872
+ def exclusive_mvn(probabilities: Any, multivariate_normal: Any, binomial_combinations: Any = None,
873
+ indicators: Any = None, absolute_tolerance: float = _TOLERANCE,
874
+ relative_tolerance: float = _TOLERANCE, return_events: bool = False) -> Any:
875
+ """Return mutually exclusive event probabilities with multivariate normal dependence (``Probability.ExclusiveMVN``).
876
+
877
+ Parameters
878
+ ----------
879
+ probabilities : array_like
880
+ The marginal probabilities.
881
+ multivariate_normal : MultivariateNormal
882
+ The standard multivariate normal of the underlying variates.
883
+ binomial_combinations : array_like, optional
884
+ The number of combinations of each subset size; given together with ``indicators``.
885
+ indicators : array_like, optional
886
+ The 2-D indicator rows in subset-size order.
887
+ absolute_tolerance, relative_tolerance : float, optional
888
+ The convergence tolerances of the expansion (``return_events`` only); default 1e-4.
889
+ return_events : bool, optional
890
+ Run the convergent expansion and return the event lists; default False.
891
+
892
+ Returns
893
+ -------
894
+ numpy.ndarray or tuple of numpy.ndarray
895
+ As for :func:`exclusive_pcm`.
896
+ """
897
+ p = _probability()
898
+ values, mvn = to_net_doubles(probabilities), _mvn(multivariate_normal)
899
+ if binomial_combinations is None and indicators is None:
900
+ if return_events:
901
+ raise ValueError("return_events needs binomial_combinations and indicators.")
902
+ return to_numpy_doubles(p.ExclusiveMVN(values, mvn))
903
+ combinations, rows = to_net_ints(binomial_combinations), _int_matrix(indicators)
904
+ if not return_events:
905
+ return to_numpy_doubles(p.ExclusiveMVN(values, combinations, rows, mvn))
906
+ events, event_rows = p.ExclusiveMVN(values, combinations, rows, mvn, None, None, float(absolute_tolerance),
907
+ float(relative_tolerance))
908
+ return _events(events, event_rows)
909
+
910
+
911
+ def common_cause_adjustment(probabilities: Any, correlation_matrix: Any = None,
912
+ dependency: DependencyType | str = DependencyType.CORRELATION_MATRIX) -> float:
913
+ """Return the common cause adjustment factor (``Probability.CommonCauseAdjustment``).
914
+
915
+ ``(1 - P(no event)) / sum p``: the union of the events under the dependence model over the sum
916
+ of their probabilities. Without a correlation matrix the events are independent.
917
+
918
+ Parameters
919
+ ----------
920
+ probabilities : array_like
921
+ The marginal probabilities.
922
+ correlation_matrix : array_like, optional
923
+ The correlation matrix for the correlation-matrix dependence.
924
+ dependency : DependencyType or str, optional
925
+ The dependence model with a correlation matrix; default the correlation matrix.
926
+
927
+ Returns
928
+ -------
929
+ float
930
+ The adjustment factor; 1 for a single event or zero total.
931
+ """
932
+ p = _probability()
933
+ values = to_net_doubles(probabilities)
934
+ if correlation_matrix is None:
935
+ return float(p.CommonCauseAdjustment(values))
936
+ return float(p.CommonCauseAdjustment(values, to_net_matrix(correlation_matrix), _dependency(dependency)))
937
+
938
+
939
+ def mutually_exclusive_adjustment(probabilities: Any) -> float:
940
+ """Return the mutually exclusive adjustment factor (``Probability.MutuallyExclusiveAdjustment``).
941
+
942
+ Parameters
943
+ ----------
944
+ probabilities : array_like
945
+ The marginal probabilities.
946
+
947
+ Returns
948
+ -------
949
+ float
950
+ The adjustment factor.
951
+ """
952
+ return float(_probability().MutuallyExclusiveAdjustment(to_net_doubles(probabilities)))
953
+
954
+
955
+ __all__ = [
956
+ "DependencyType", "ExclusiveEnumerationStatus", "a_and_b", "a_given_b", "a_not_b", "a_or_b", "b_given_a",
957
+ "b_not_a", "common_cause_adjustment", "exclusive_mvn", "exclusive_pcm", "exclusive_pcm_lazy",
958
+ "independent_exclusive", "independent_exclusive_lazy", "independent_joint_probability", "independent_union",
959
+ "joint_probabilities_mvn", "joint_probabilities_pcm", "joint_probability", "joint_probability_hpcm",
960
+ "joint_probability_mvn", "joint_probability_pcm", "mutually_exclusive_adjustment", "negative_joint_probability",
961
+ "negatively_dependent_union", "positive_joint_probability", "positively_dependent_exclusive",
962
+ "positively_dependent_exclusive_lazy", "positively_dependent_union", "single_factor_conditional_probabilities",
963
+ "union", "union_mvn", "union_pcm", "union_pcm_lazy", "union_single_factor",
964
+ ]
965
+
966
+ translate_public(globals())