code: def test_default_value_transform_logprob(
      pt_dist, dist_params, sp_dist, size
  ):
      """
      This test takes a `RandomVariable` type, plus parameters, and uses it to
      construct a variable ``a`` that's used in the graph ``b =
      pt.random.normal(a, 1.0)``.  The transformed log-probability is then
      computed for ``b``.  We then test that the log-probability of ``a`` is
      properly transformed, as well as any instances of ``a`` that are used
      elsewhere in the graph (i.e. in ``b``), by comparing the graph for the
      transformed log-probability with the SciPy-derived log-probability--using a
      numeric approximation to the Jacobian term.
  
      TODO: This test is rather redundant with those in tess/distributions/test_transform.py
      """
  
      a = pt_dist(*dist_params, size=size)
      a.name = "a"
      a_value_var = pt.tensor(dtype=a.dtype, shape=(None,) * a.ndim)
      a_value_var.name = "a_value"
  
      b = pt.random.normal(a, 1.0)
      b.name = "b"
      b_value_var = b.clone()
      b_value_var.name = "b_value"
  
      transform = _default_transform(a.owner.op, a)
      transform_rewrite = TransformValuesRewrite(
          {a_value_var: transform}
      )
      res = conditional_logp(
          {a: a_value_var, b: b_value_var},
          extra_rewrites=transform_rewrite,
      )
      res_combined = pt.sum([pt.sum(factor) for factor in res.values()])
  
      test_val_rng = np.random.RandomState(3238)
  
      logp_vals_fn = pytensor.function(
          [a_value_var, b_value_var], res_combined
      )
  
      a_forward_fn = pytensor.function(
          [a_value_var], transform.forward(a_value_var, *a.owner.inputs)
      )
      a_backward_fn = pytensor.function(
          [a_value_var],
          transform.backward(a_value_var, *a.owner.inputs),
      )
      log_jac_fn = pytensor.function(
          [a_value_var],
          transform.log_jac_det(a_value_var, *a.owner.inputs),
          on_unused_input="ignore",
      )
  
      for i in range(10):
          a_dist = sp_dist(*dist_params)
          a_val = a_dist.rvs(
              size=size, random_state=test_val_rng
          ).astype(a_value_var.dtype)
          b_dist = sp.stats.norm(a_val, 1.0)
          b_val = b_dist.rvs(random_state=test_val_rng).astype(
              b_value_var.dtype
          )
  
          a_trans_value = a_forward_fn(a_val)
  
          if a_val.ndim > 0:
  
              def jacobian_estimate_novec(value):
                  dim_diff = a_val.ndim - value.ndim
                  if dim_diff > 0:
                      # Make sure the dimensions match the expected input
                      # dimensions for the compiled backward transform function
                      def a_backward_fn_(x):
                          x_ = np.expand_dims(
                              x, axis=list(range(dim_diff))
                          )
                          return a_backward_fn(x_).squeeze()
  
                  else:
                      a_backward_fn_ = a_backward_fn
  
                  jacobian_val = Jacobian(a_backward_fn_)(value)
  
                  n_missing_dims = (
                      jacobian_val.shape[0] - jacobian_val.shape[1]
                  )
                  if n_missing_dims > 0:
                      missing_bases = np.eye(jacobian_val.shape[0])[
                          ..., -n_missing_dims:
                      ]
                      jacobian_val = np.concatenate(
                          [jacobian_val, missing_bases], axis=-1
                      )
  
                  return np.linalg.slogdet(jacobian_val)[-1]
  
              jacobian_estimate = np.vectorize(
                  jacobian_estimate_novec, signature="(n)->()"
              )
  
              exp_log_jac_val = jacobian_estimate(a_trans_value)
          else:
              jacobian_val = np.atleast_2d(
                  sp.misc.derivative(
                      a_backward_fn, a_trans_value, dx=1e-6
                  )
              )
              exp_log_jac_val = np.linalg.slogdet(jacobian_val)[-1]
  
          log_jac_val = log_jac_fn(a_trans_value)
          np.testing.assert_allclose(
              exp_log_jac_val, log_jac_val, rtol=1e-4, atol=1e-10
          )
  
          exp_logprob_val = a_dist.logpdf(a_val).sum()
          exp_logprob_val += exp_log_jac_val.sum()
          exp_logprob_val += b_dist.logpdf(b_val).sum()
  
          logprob_val = logp_vals_fn(a_trans_value, b_val)
  
          np.testing.assert_allclose(
              exp_logprob_val, logprob_val, rtol=1e-4, atol=1e-10
          )
  
imports: import gc
  import operator
  import numpy
  import pytensor
  import pytest
  import scipy
  from numdifftools import Jacobian
  from pytensor import scan
  from pytensor import tensor
  from pytensor.compile.builders import OpFromGraph
  from pytensor.graph import FunctionGraph
  from pytensor.graph.basic import equal_computations
  import pymc
  from pymc.distributions.transforms import _default_transform, log, logodds
  from pymc.logprob import conditional_logp
  from pymc.logprob.abstract import MeasurableVariable, _logprob
  from pymc.logprob.transform_value import TransformValuesMapping, TransformValuesRewrite
  from pymc.logprob.transforms import ExpTransform, LogOddsTransform, LogTransform
  from pymc.testing import assert_no_rvs
  from tests.logprob.test_transforms import DirichletScipyDist
label_desc: Use image node_id 4 for calling a global function with example usage: test_default_value_transform_logprob(pt_dist, dist_params, sp_dist, size) and returns: np, a_backward_fn