@@ -278,21 +278,24 @@ def logcdf(self, value):
278
278
279
279
Parameters
280
280
----------
281
- value: numeric
281
+ value: numeric or np.ndarray or theano.tensor
282
282
Value(s) for which log CDF is calculated. If the log CDF for multiple
283
283
values are desired the values must be provided in a numpy array or theano tensor.
284
284
285
285
Returns
286
286
-------
287
287
TensorVariable
288
288
"""
289
+ lower = self .lower
290
+ upper = self .upper
291
+
289
292
return tt .switch (
290
- tt .or_ ( tt . lt (value , self . lower ), tt .gt ( value , self . upper ) ),
293
+ tt .lt (value , lower ) | tt .lt ( upper , lower ),
291
294
- np .inf ,
292
295
tt .switch (
293
- tt .eq (value , self .upper ),
296
+ tt .lt (value , upper ),
297
+ tt .log (value - lower ) - tt .log (upper - lower ),
294
298
0 ,
295
- tt .log (value - self .lower ) - tt .log (self .upper - self .lower ),
296
299
),
297
300
)
298
301
@@ -344,7 +347,7 @@ def logcdf(self, value):
344
347
345
348
Parameters
346
349
----------
347
- value: numeric
350
+ value: numeric or np.ndarray or theano.tensor
348
351
Value(s) for which log CDF is calculated. If the log CDF for multiple
349
352
values are desired the values must be provided in a numpy array or theano tensor.
350
353
@@ -401,7 +404,7 @@ def logcdf(self, value):
401
404
402
405
Parameters
403
406
----------
404
- value: numeric
407
+ value: numeric or np.ndarray or theano.tensor
405
408
Value(s) for which log CDF is calculated. If the log CDF for multiple
406
409
values are desired the values must be provided in a numpy array or theano tensor.
407
410
@@ -542,7 +545,7 @@ def logcdf(self, value):
542
545
543
546
Parameters
544
547
----------
545
- value: numeric
548
+ value: numeric or np.ndarray or theano.tensor
546
549
Value(s) for which log CDF is calculated. If the log CDF for multiple
547
550
values are desired the values must be provided in a numpy array or theano tensor.
548
551
@@ -900,7 +903,7 @@ def logcdf(self, value):
900
903
901
904
Parameters
902
905
----------
903
- value: numeric
906
+ value: numeric or np.ndarray or theano.tensor
904
907
Value(s) for which log CDF is calculated. If the log CDF for multiple
905
908
values are desired the values must be provided in a numpy array or theano tensor.
906
909
@@ -910,10 +913,10 @@ def logcdf(self, value):
910
913
"""
911
914
sigma = self .sigma
912
915
z = zvalue (value , mu = 0 , sigma = sigma )
913
- return tt .switch (
914
- tt .lt (z , - 1.0 ),
915
- tt .log (tt .erfcx (- z / tt .sqrt (2.0 ))) - tt .sqr (z ),
916
+ return bound (
916
917
tt .log1p (- tt .erfc (z / tt .sqrt (2.0 ))),
918
+ 0 <= value ,
919
+ 0 < sigma ,
917
920
)
918
921
919
922
@@ -1106,7 +1109,7 @@ def logcdf(self, value):
1106
1109
1107
1110
Parameters
1108
1111
----------
1109
- value: numeric
1112
+ value: numeric or np.ndarray or theano.tensor
1110
1113
Value(s) for which log CDF is calculated. If the log CDF for multiple
1111
1114
values are desired the values must be provided in a numpy array or theano tensor.
1112
1115
@@ -1297,20 +1300,30 @@ def logcdf(self, value):
1297
1300
Parameters
1298
1301
----------
1299
1302
value: numeric
1300
- Value(s) for which log CDF is calculated. If the log CDF for multiple
1301
- values are desired the values must be provided in a numpy array or theano tensor.
1303
+ Value(s) for which log CDF is calculated.
1302
1304
1303
1305
Returns
1304
1306
-------
1305
1307
TensorVariable
1306
1308
"""
1307
- value = floatX (tt .as_tensor (value ))
1308
- a = floatX (tt .as_tensor (self .alpha ))
1309
- b = floatX (tt .as_tensor (self .beta ))
1310
- return tt .switch (
1311
- tt .le (value , 0 ),
1312
- - np .inf ,
1313
- tt .switch (tt .ge (value , 1 ), 0 , tt .log (incomplete_beta (a , b , value ))),
1309
+ # incomplete_beta function can only handle scalar values (see #4342)
1310
+ if np .ndim (value ):
1311
+ raise TypeError (
1312
+ f"Beta.logcdf expects a scalar value but received a { np .ndim (value )} -dimensional object."
1313
+ )
1314
+
1315
+ a = self .alpha
1316
+ b = self .beta
1317
+
1318
+ return bound (
1319
+ tt .switch (
1320
+ tt .lt (value , 1 ),
1321
+ tt .log (incomplete_beta (a , b , value )),
1322
+ 0 ,
1323
+ ),
1324
+ 0 <= value ,
1325
+ 0 < a ,
1326
+ 0 < b ,
1314
1327
)
1315
1328
1316
1329
def _distr_parameters_for_repr (self ):
@@ -1515,7 +1528,7 @@ def logcdf(self, value):
1515
1528
1516
1529
Parameters
1517
1530
----------
1518
- value: numeric
1531
+ value: numeric or np.ndarray or theano.tensor
1519
1532
Value(s) for which log CDF is calculated. If the log CDF for multiple
1520
1533
values are desired the values must be provided in a numpy array or theano tensor.
1521
1534
@@ -1630,7 +1643,7 @@ def logcdf(self, value):
1630
1643
1631
1644
Parameters
1632
1645
----------
1633
- value: numeric
1646
+ value: numeric or np.ndarray or theano.tensor
1634
1647
Value(s) for which log CDF is calculated. If the log CDF for multiple
1635
1648
values are desired the values must be provided in a numpy array or theano tensor.
1636
1649
@@ -1786,7 +1799,7 @@ def logcdf(self, value):
1786
1799
1787
1800
Parameters
1788
1801
----------
1789
- value: numeric
1802
+ value: numeric or np.ndarray or theano.tensor
1790
1803
Value(s) for which log CDF is calculated. If the log CDF for multiple
1791
1804
values are desired the values must be provided in a numpy array or theano tensor.
1792
1805
@@ -1949,20 +1962,32 @@ def logcdf(self, value):
1949
1962
Parameters
1950
1963
----------
1951
1964
value: numeric
1952
- Value(s) for which log CDF is calculated. If the log CDF for multiple
1953
- values are desired the values must be provided in a numpy array or theano tensor.
1965
+ Value(s) for which log CDF is calculated.
1954
1966
1955
1967
Returns
1956
1968
-------
1957
1969
TensorVariable
1958
1970
"""
1971
+ # incomplete_beta function can only handle scalar values (see #4342)
1972
+ if np .ndim (value ):
1973
+ raise TypeError (
1974
+ f"StudentT.logcdf expects a scalar value but received a { np .ndim (value )} -dimensional object."
1975
+ )
1976
+
1959
1977
nu = self .nu
1960
1978
mu = self .mu
1961
1979
sigma = self .sigma
1980
+ lam = self .lam
1962
1981
t = (value - mu ) / sigma
1963
1982
sqrt_t2_nu = tt .sqrt (t ** 2 + nu )
1964
1983
x = (t + sqrt_t2_nu ) / (2.0 * sqrt_t2_nu )
1965
- return tt .log (incomplete_beta (nu / 2.0 , nu / 2.0 , x ))
1984
+
1985
+ return bound (
1986
+ tt .log (incomplete_beta (nu / 2.0 , nu / 2.0 , x )),
1987
+ 0 < nu ,
1988
+ 0 < sigma ,
1989
+ 0 < lam ,
1990
+ )
1966
1991
1967
1992
1968
1993
class Pareto (Continuous ):
@@ -2084,7 +2109,7 @@ def logcdf(self, value):
2084
2109
2085
2110
Parameters
2086
2111
----------
2087
- value: numeric
2112
+ value: numeric or np.ndarray or theano.tensor
2088
2113
Value(s) for which log CDF is calculated. If the log CDF for multiple
2089
2114
values are desired the values must be provided in a numpy array or theano tensor.
2090
2115
@@ -2203,7 +2228,7 @@ def logcdf(self, value):
2203
2228
2204
2229
Parameters
2205
2230
----------
2206
- value: numeric
2231
+ value: numeric or np.ndarray or theano.tensor
2207
2232
Value(s) for which log CDF is calculated. If the log CDF for multiple
2208
2233
values are desired the values must be provided in a numpy array or theano tensor.
2209
2234
@@ -2311,7 +2336,7 @@ def logcdf(self, value):
2311
2336
2312
2337
Parameters
2313
2338
----------
2314
- value: numeric
2339
+ value: numeric or np.ndarray or theano.tensor
2315
2340
Value(s) for which log CDF is calculated. If the log CDF for multiple
2316
2341
values are desired the values must be provided in a numpy array or theano tensor.
2317
2342
@@ -2462,7 +2487,7 @@ def logcdf(self, value):
2462
2487
2463
2488
Parameters
2464
2489
----------
2465
- value: numeric
2490
+ value: numeric or np.ndarray or theano.tensor
2466
2491
Value(s) for which log CDF is calculated. If the log CDF for multiple
2467
2492
values are desired the values must be provided in a numpy array or theano tensor.
2468
2493
@@ -2472,7 +2497,17 @@ def logcdf(self, value):
2472
2497
"""
2473
2498
alpha = self .alpha
2474
2499
beta = self .beta
2475
- return bound (tt .log (tt .gammainc (alpha , beta * value )), value >= 0 , alpha > 0 , beta > 0 )
2500
+ # Avoid C-assertion when the gammainc function is called with invalid values (#4340)
2501
+ safe_alpha = tt .switch (tt .lt (alpha , 0 ), 0 , alpha )
2502
+ safe_beta = tt .switch (tt .lt (beta , 0 ), 0 , beta )
2503
+ safe_value = tt .switch (tt .lt (value , 0 ), 0 , value )
2504
+
2505
+ return bound (
2506
+ tt .log (tt .gammainc (safe_alpha , safe_beta * safe_value )),
2507
+ 0 <= value ,
2508
+ 0 < alpha ,
2509
+ 0 < beta ,
2510
+ )
2476
2511
2477
2512
def _distr_parameters_for_repr (self ):
2478
2513
return ["alpha" , "beta" ]
@@ -2626,7 +2661,7 @@ def logcdf(self, value):
2626
2661
2627
2662
Parameters
2628
2663
----------
2629
- value: numeric
2664
+ value: numeric or np.ndarray or theano.tensor
2630
2665
Value(s) for which log CDF is calculated. If the log CDF for multiple
2631
2666
values are desired the values must be provided in a numpy array or theano tensor.
2632
2667
@@ -2636,11 +2671,16 @@ def logcdf(self, value):
2636
2671
"""
2637
2672
alpha = self .alpha
2638
2673
beta = self .beta
2674
+ # Avoid C-assertion when the gammaincc function is called with invalid values (#4340)
2675
+ safe_alpha = tt .switch (tt .lt (alpha , 0 ), 0 , alpha )
2676
+ safe_beta = tt .switch (tt .lt (beta , 0 ), 0 , beta )
2677
+ safe_value = tt .switch (tt .lt (value , 0 ), 0 , value )
2678
+
2639
2679
return bound (
2640
- tt .log (tt .gammaincc (alpha , beta / value )),
2641
- value >= 0 ,
2642
- alpha > 0 ,
2643
- beta > 0 ,
2680
+ tt .log (tt .gammaincc (safe_alpha , safe_beta / safe_value )),
2681
+ 0 <= value ,
2682
+ 0 < alpha ,
2683
+ 0 < beta ,
2644
2684
)
2645
2685
2646
2686
@@ -2802,7 +2842,7 @@ def logcdf(self, value):
2802
2842
2803
2843
Parameters
2804
2844
----------
2805
- value: numeric
2845
+ value: numeric or np.ndarray or theano.tensor
2806
2846
Value(s) for which log CDF is calculated. If the log CDF for multiple
2807
2847
values are desired the values must be provided in a numpy array or theano tensor.
2808
2848
@@ -3102,7 +3142,7 @@ def logcdf(self, value):
3102
3142
3103
3143
Parameters
3104
3144
----------
3105
- value: numeric
3145
+ value: numeric or np.ndarray or theano.tensor
3106
3146
Value(s) for which log CDF is calculated. If the log CDF for multiple
3107
3147
values are desired the values must be provided in a numpy array or theano tensor.
3108
3148
@@ -3491,7 +3531,7 @@ def logcdf(self, value):
3491
3531
3492
3532
Parameters
3493
3533
----------
3494
- value: numeric
3534
+ value: numeric or np.ndarray or theano.tensor
3495
3535
Value(s) for which log CDF is calculated. If the log CDF for multiple
3496
3536
values are desired the values must be provided in a numpy array or theano tensor.
3497
3537
@@ -3620,7 +3660,7 @@ def logcdf(self, value):
3620
3660
3621
3661
Parameters
3622
3662
----------
3623
- value: numeric
3663
+ value: numeric or np.ndarray or theano.tensor
3624
3664
Value(s) for which log CDF is calculated. If the log CDF for multiple
3625
3665
values are desired the values must be provided in a numpy array or theano tensor.
3626
3666
@@ -3902,7 +3942,7 @@ def logcdf(self, value):
3902
3942
3903
3943
Parameters
3904
3944
----------
3905
- value: numeric
3945
+ value: numeric or np.ndarray or theano.tensor
3906
3946
Value(s) for which log CDF is calculated. If the log CDF for multiple
3907
3947
values are desired the values must be provided in a numpy array or theano tensor.
3908
3948
@@ -4244,7 +4284,7 @@ def logcdf(self, value):
4244
4284
4245
4285
Parameters
4246
4286
----------
4247
- value: numeric
4287
+ value: numeric or np.ndarray or theano.tensor
4248
4288
Value(s) for which log CDF is calculated. If the log CDF for multiple
4249
4289
values are desired the values must be provided in a numpy array or theano tensor.
4250
4290
0 commit comments