23
23
import pymc as pm
24
24
import pymc .distributions .transforms as tr
25
25
26
- from pymc .aesaraf import jacobian
26
+ from pymc .aesaraf import floatX , jacobian
27
27
from pymc .distributions import logpt
28
28
from pymc .tests .checks import close_to , close_to_logical
29
29
from pymc .tests .helpers import SeededTest
@@ -285,40 +285,46 @@ def build_model(self, distfam, params, size, transform, initval=None):
285
285
286
286
def check_transform_elementwise_logp (self , model ):
287
287
x = model .free_RVs [0 ]
288
- x0 = x .tag .value_var
289
- assert x .ndim == logpt (x , sum = False ).ndim
288
+ x_val_transf = x .tag .value_var
290
289
291
- pt = model .initial_point
292
- array = np .random .randn (* pt [x0 .name ].shape )
293
- transform = x0 .tag .transform
294
- logp_notrans = logpt ( x , transform .backward (array , * x .owner .inputs ), transformed = False )
290
+ pt = model .recompute_initial_point ( 0 )
291
+ test_array_transf = floatX ( np .random .randn (* pt [x_val_transf .name ].shape ) )
292
+ transform = x_val_transf .tag .transform
293
+ test_array_untransf = transform .backward (test_array_transf , * x .owner .inputs ). eval ( )
295
294
296
- jacob_det = transform . log_jac_det ( aesara . shared ( array ), * x . owner . inputs )
297
- assert logpt ( x , sum = False ). ndim == jacob_det . ndim
295
+ # Create input variable with same dimensionality as untransformed test_array
296
+ x_val_untransf = at . constant ( test_array_untransf ). type ()
298
297
299
- v1 = logpt (x , array , jacobian = False ).eval ()
300
- v2 = logp_notrans .eval ()
298
+ jacob_det = transform .log_jac_det (test_array_transf , * x .owner .inputs )
299
+ assert logpt (x , sum = False ).ndim == x .ndim == jacob_det .ndim
300
+
301
+ v1 = logpt (x , x_val_transf , jacobian = False ).eval ({x_val_transf : test_array_transf })
302
+ v2 = logpt (x , x_val_untransf , transformed = False ).eval ({x_val_untransf : test_array_untransf })
301
303
close_to (v1 , v2 , tol )
302
304
303
- def check_vectortransform_elementwise_logp (self , model , vect_opt = 0 ):
305
+ def check_vectortransform_elementwise_logp (self , model ):
304
306
x = model .free_RVs [0 ]
305
- x0 = x .tag .value_var
306
- # TODO: For some reason the ndim relations
307
- # dont hold up here. But final log-probablity
308
- # values are what we expected.
309
- # assert (x.ndim - 1) == logpt(x, sum=False).ndim
310
-
311
- pt = model .initial_point
312
- array = np .random .randn (* pt [x0 .name ].shape )
313
- transform = x0 .tag .transform
314
- logp_nojac = logpt (x , transform .backward (array , * x .owner .inputs ), transformed = False )
315
-
316
- jacob_det = transform .log_jac_det (aesara .shared (array ), * x .owner .inputs )
317
- # assert logpt(x).ndim == jacob_det.ndim
318
-
307
+ x_val_transf = x .tag .value_var
308
+
309
+ pt = model .recompute_initial_point (0 )
310
+ test_array_transf = floatX (np .random .randn (* pt [x_val_transf .name ].shape ))
311
+ transform = x_val_transf .tag .transform
312
+ test_array_untransf = transform .backward (test_array_transf , * x .owner .inputs ).eval ()
313
+
314
+ # Create input variable with same dimensionality as untransformed test_array
315
+ x_val_untransf = at .constant (test_array_untransf ).type ()
316
+
317
+ jacob_det = transform .log_jac_det (test_array_transf , * x .owner .inputs )
318
+ # Original distribution is univariate
319
+ if x .owner .op .ndim_supp == 0 :
320
+ assert logpt (x , sum = False ).ndim == x .ndim == (jacob_det .ndim + 1 )
321
+ # Original distribution is multivariate
322
+ else :
323
+ assert logpt (x , sum = False ).ndim == (x .ndim - 1 ) == jacob_det .ndim
324
+
325
+ a = logpt (x , x_val_transf , jacobian = False ).eval ({x_val_transf : test_array_transf })
326
+ b = logpt (x , x_val_untransf , transformed = False ).eval ({x_val_untransf : test_array_untransf })
319
327
# Hack to get relative tolerance
320
- a = logpt (x , array .astype (aesara .config .floatX ), jacobian = False ).eval ()
321
- b = logp_nojac .eval ()
322
328
close_to (a , b , np .abs (0.5 * (a + b ) * tol ))
323
329
324
330
@pytest .mark .parametrize (
@@ -406,7 +412,7 @@ def test_vonmises(self, mu, kappa, size):
406
412
)
407
413
def test_dirichlet (self , a , size ):
408
414
model = self .build_model (pm .Dirichlet , {"a" : a }, size = size , transform = tr .simplex )
409
- self .check_vectortransform_elementwise_logp (model , vect_opt = 1 )
415
+ self .check_vectortransform_elementwise_logp (model )
410
416
411
417
def test_normal_ordered (self ):
412
418
model = self .build_model (
@@ -416,7 +422,7 @@ def test_normal_ordered(self):
416
422
initval = np .asarray ([- 1.0 , 1.0 , 4.0 ]),
417
423
transform = tr .ordered ,
418
424
)
419
- self .check_vectortransform_elementwise_logp (model , vect_opt = 0 )
425
+ self .check_vectortransform_elementwise_logp (model )
420
426
421
427
@pytest .mark .parametrize (
422
428
"sd,size" ,
@@ -434,7 +440,7 @@ def test_half_normal_ordered(self, sd, size):
434
440
initval = initval ,
435
441
transform = tr .Chain ([tr .log , tr .ordered ]),
436
442
)
437
- self .check_vectortransform_elementwise_logp (model , vect_opt = 0 )
443
+ self .check_vectortransform_elementwise_logp (model )
438
444
439
445
@pytest .mark .parametrize ("lam,size" , [(2.5 , (2 ,)), (np .ones (3 ), (4 , 3 ))])
440
446
def test_exponential_ordered (self , lam , size ):
@@ -446,7 +452,7 @@ def test_exponential_ordered(self, lam, size):
446
452
initval = initval ,
447
453
transform = tr .Chain ([tr .log , tr .ordered ]),
448
454
)
449
- self .check_vectortransform_elementwise_logp (model , vect_opt = 0 )
455
+ self .check_vectortransform_elementwise_logp (model )
450
456
451
457
@pytest .mark .parametrize (
452
458
"a,b,size" ,
@@ -468,7 +474,7 @@ def test_beta_ordered(self, a, b, size):
468
474
initval = initval ,
469
475
transform = tr .Chain ([tr .logodds , tr .ordered ]),
470
476
)
471
- self .check_vectortransform_elementwise_logp (model , vect_opt = 0 )
477
+ self .check_vectortransform_elementwise_logp (model )
472
478
473
479
@pytest .mark .parametrize (
474
480
"lower,upper,size" ,
@@ -491,7 +497,7 @@ def transform_params(*inputs):
491
497
initval = initval ,
492
498
transform = tr .Chain ([interval , tr .ordered ]),
493
499
)
494
- self .check_vectortransform_elementwise_logp (model , vect_opt = 1 )
500
+ self .check_vectortransform_elementwise_logp (model )
495
501
496
502
@pytest .mark .parametrize ("mu,kappa,size" , [(0.0 , 1.0 , (2 ,)), (np .zeros (3 ), np .ones (3 ), (4 , 3 ))])
497
503
def test_vonmises_ordered (self , mu , kappa , size ):
@@ -503,7 +509,7 @@ def test_vonmises_ordered(self, mu, kappa, size):
503
509
initval = initval ,
504
510
transform = tr .Chain ([tr .circular , tr .ordered ]),
505
511
)
506
- self .check_vectortransform_elementwise_logp (model , vect_opt = 0 )
512
+ self .check_vectortransform_elementwise_logp (model )
507
513
508
514
@pytest .mark .parametrize (
509
515
"lower,upper,size,transform" ,
@@ -522,7 +528,7 @@ def test_uniform_other(self, lower, upper, size, transform):
522
528
initval = initval ,
523
529
transform = transform ,
524
530
)
525
- self .check_vectortransform_elementwise_logp (model , vect_opt = 1 )
531
+ self .check_vectortransform_elementwise_logp (model )
526
532
527
533
@pytest .mark .parametrize (
528
534
"mu,cov,size,shape" ,
@@ -536,7 +542,7 @@ def test_mvnormal_ordered(self, mu, cov, size, shape):
536
542
model = self .build_model (
537
543
pm .MvNormal , {"mu" : mu , "cov" : cov }, size = size , initval = initval , transform = tr .ordered
538
544
)
539
- self .check_vectortransform_elementwise_logp (model , vect_opt = 1 )
545
+ self .check_vectortransform_elementwise_logp (model )
540
546
541
547
542
548
def test_triangular_transform ():
0 commit comments