21
21
import numpy as np
22
22
23
23
from aeppl import factorized_joint_logprob
24
+ from aeppl .logprob import logcdf as logcdf_aeppl
25
+ from aeppl .logprob import logprob as logp_aeppl
24
26
from aeppl .transforms import TransformValuesOpt
25
27
from aesara import config
26
28
from aesara .graph .basic import graph_inputs , io_toposort
36
38
)
37
39
from aesara .tensor .var import TensorVariable
38
40
39
- from pymc .aesaraf import extract_rv_and_value_vars , floatX , rvs_to_value_vars
41
+ from pymc .aesaraf import floatX
40
42
41
43
42
44
@singledispatch
@@ -260,128 +262,18 @@ def logpt(
260
262
return logp_var
261
263
262
264
263
- def logcdfpt (
264
- var : TensorVariable ,
265
- rv_values : Optional [Union [TensorVariable , Dict [TensorVariable , TensorVariable ]]] = None ,
266
- * ,
267
- scaling : bool = True ,
268
- sum : bool = True ,
269
- ** kwargs ,
270
- ) -> TensorVariable :
271
- """Create a measure-space (i.e. log-cdf) graph for a random variable at a given point.
272
-
273
- Parameters
274
- ==========
275
- var
276
- The `RandomVariable` output that determines the log-likelihood graph.
277
- rv_values
278
- A variable, or ``dict`` of variables, that represents the value of
279
- `var` in its log-likelihood. If no `rv_value` is provided,
280
- ``var.tag.value_var`` will be checked and, when available, used.
281
- jacobian
282
- Whether or not to include the Jacobian term.
283
- scaling
284
- A scaling term to apply to the generated log-likelihood graph.
285
- transformed
286
- Apply transforms.
287
- sum
288
- Sum the log-likelihood.
289
-
290
- """
291
- if not isinstance (rv_values , Mapping ):
292
- rv_values = {var : rv_values } if rv_values is not None else {}
293
-
294
- rv_var , rv_value_var = extract_rv_and_value_vars (var )
265
+ def logp (rv , value ):
266
+ """Return the log-probability graph of a Random Variable"""
295
267
296
- rv_value = rv_values .get (rv_var , rv_value_var )
268
+ value = at .as_tensor_variable (value , dtype = rv .dtype )
269
+ return logp_aeppl (rv , value )
297
270
298
- if rv_var is not None and rv_value is None :
299
- raise ValueError (f"No value variable specified or associated with { rv_var } " )
300
271
301
- if rv_value is not None :
302
- rv_value = at .as_tensor (rv_value )
303
-
304
- if rv_var is not None :
305
- # Make sure that the value is compatible with the random variable
306
- rv_value = rv_var .type .filter_variable (rv_value .astype (rv_var .dtype ))
307
-
308
- if rv_value_var is None :
309
- rv_value_var = rv_value
310
-
311
- rv_node = rv_var .owner
312
-
313
- rng , size , dtype , * dist_params = rv_node .inputs
314
-
315
- # Here, we plug the actual random variable into the log-likelihood graph,
316
- # because we want a log-likelihood graph that only contains
317
- # random variables. This is important, because a random variable's
318
- # parameters can contain random variables themselves.
319
- # Ultimately, with a graph containing only random variables and
320
- # "deterministics", we can simply replace all the random variables with
321
- # their value variables and be done.
322
- tmp_rv_values = rv_values .copy ()
323
- tmp_rv_values [rv_var ] = rv_var
324
-
325
- logp_var = _logcdf (rv_node .op , rv_var , tmp_rv_values , * dist_params , ** kwargs )
326
-
327
- transform = getattr (rv_value_var .tag , "transform" , None ) if rv_value_var else None
328
-
329
- # Replace random variables with their value variables
330
- replacements = rv_values .copy ()
331
- replacements .update ({rv_var : rv_value , rv_value_var : rv_value })
332
-
333
- (logp_var ,), _ = rvs_to_value_vars (
334
- (logp_var ,),
335
- apply_transforms = False ,
336
- initial_replacements = replacements ,
337
- )
338
-
339
- if sum :
340
- logp_var = at .sum (logp_var )
341
-
342
- if scaling :
343
- logp_var *= _get_scaling (
344
- getattr (rv_var .tag , "total_size" , None ), rv_value .shape , rv_value .ndim
345
- )
346
-
347
- # Recompute test values for the changes introduced by the replacements
348
- # above.
349
- if config .compute_test_value != "off" :
350
- for node in io_toposort (graph_inputs ((logp_var ,)), (logp_var ,)):
351
- compute_test_value (node )
352
-
353
- if rv_var .name is not None :
354
- logp_var .name = f"__logp_{ rv_var .name } "
355
-
356
- return logp_var
357
-
358
-
359
- def logp (var , rv_values , ** kwargs ):
360
- """Create a log-probability graph."""
361
-
362
- # Attach the value_var to the tag of var when it does not have one
363
- if not hasattr (var .tag , "value_var" ):
364
- if isinstance (rv_values , Mapping ):
365
- value_var = rv_values [var ]
366
- else :
367
- value_var = rv_values
368
- var .tag .value_var = at .as_tensor_variable (value_var , dtype = var .dtype )
369
-
370
- return logpt (var , rv_values , ** kwargs )
371
-
372
-
373
- def logcdf (var , rv_values , ** kwargs ):
374
- """Create a log-CDF graph."""
375
-
376
- # Attach the value_var to the tag of var when it does not have one
377
- if not hasattr (var .tag , "value_var" ):
378
- if isinstance (rv_values , Mapping ):
379
- value_var = rv_values [var ]
380
- else :
381
- value_var = rv_values
382
- var .tag .value_var = at .as_tensor_variable (value_var , dtype = var .dtype )
272
+ def logcdf (rv , value ):
273
+ """Return the log-cdf graph of a Random Variable"""
383
274
384
- return logcdfpt (var , rv_values , ** kwargs )
275
+ value = at .as_tensor_variable (value , dtype = rv .dtype )
276
+ return logcdf_aeppl (rv , value )
385
277
386
278
387
279
@singledispatch
@@ -402,4 +294,5 @@ def logpt_sum(*args, **kwargs):
402
294
Subclasses can use this to improve the speed of logp evaluations
403
295
if only the sum of the logp values is needed.
404
296
"""
297
+ # TODO: Deprecate this
405
298
return logpt (* args , sum = True , ** kwargs )
0 commit comments