![]() |
Class CorrelationCholesky
Maps unconstrained reals to Cholesky-space correlation matrices.
Inherits From: Bijector
This bijector is a mapping between R^{n}
and the n
-dimensional manifold of
Cholesky-space correlation matrices embedded in R^{m^2}
, where n
is the
(m - 1)
th triangular number; i.e. n = 1 + 2 + ... + (m - 1)
.
Mathematical Details
The image of unconstrained reals under the CorrelationCholesky
bijector is
the set of correlation matrices which are positive definite. A correlation
matrix
can be characterized as a symmetric positive semidefinite matrix with 1s on
the main diagonal. However, the correlation matrix is positive definite if no
component can be expressed as a linear combination of the other components.
For a lower triangular matrix L
to be a valid Cholesky-factor of a positive
definite correlation matrix, it is necessary and sufficient that each row of
L
have unit Euclidean norm [1]. To see this, observe that if L_i
is the
i
th row of the Cholesky factor corresponding to the correlation matrix R
,
then the i
th diagonal entry of R
satisfies:
1 = R_i,i = L_i . L_i = ||L_i||^2
where '.' is the dot product of vectors and ||...||
denotes the Euclidean
norm.
Furthermore, observe that R_i,j
lies in the interval [-1, 1]
. By the
Cauchy-Schwarz inequality:
|R_i,j| = |L_i . L_j| <= ||L_i|| ||L_j|| = 1
This is a consequence of the fact that R
is symmetric positive definite with
1s on the main diagonal.
The LKJ distribution with input_output_cholesky=True
generates samples from
(and computes log-densities on) the set of Cholesky factors of positive
definite correlation matrices. [2] The CorrelationCholesky
bijector provides
a bijective mapping from unconstrained reals to the support of the LKJ
distribution.
Examples
bijector.CorrelationCholesky().forward([2., 2., 1.])
# Result: [[ 1. , 0. , 0. ],
[ 0.70710678, 0.70710678, 0. ],
[ 0.66666667, 0.66666667, 0.33333333]]
# bijector.CorrelationCholesky().inverse(
[[ 1. , 0. , 0. ],
[ 0.70710678, 0.70710678, 0. ],
[ 0.66666667, 0.66666667, 0.33333333]])
# Result: [2., 2., 1.]
References
[1] Stan Manual. Section 24.2. Cholesky LKJ Correlation Distribution. https://mc-stan.org/docs/2_18/functions-reference/cholesky-lkj-correlation-distribution.html [2] Daniel Lewandowski, Dorota Kurowicka, and Harry Joe, "Generating random correlation matrices based on vines and extended onion method," Journal of Multivariate Analysis 100 (2009), pp 1989-2001.
__init__
__init__(
validate_args=False,
name='correlation_cholesky'
)
Constructs Bijector.
A Bijector
transforms random variables into new random variables.
Examples:
# Create the Y = g(X) = X transform.
identity = Identity()
# Create the Y = g(X) = exp(X) transform.
exp = Exp()
See Bijector
subclass docstring for more details and specific examples.
Args:
graph_parents
: Python list of graph prerequisites of thisBijector
.is_constant_jacobian
: Pythonbool
indicating that the Jacobian matrix is not a function of the input.validate_args
: Pythonbool
, defaultFalse
. Whether to validate input with asserts. Ifvalidate_args
isFalse
, and the inputs are invalid, correct behavior is not guaranteed.dtype
:tf.dtype
supported by thisBijector
.None
means dtype is not enforced.forward_min_event_ndims
: Pythoninteger
indicating the minimum number of dimensionsforward
operates on.inverse_min_event_ndims
: Pythoninteger
indicating the minimum number of dimensionsinverse
operates on. Will be set toforward_min_event_ndims
by default, if no value is provided.name
: The name to give Ops created by the initializer.
Raises:
ValueError
: If neitherforward_min_event_ndims
andinverse_min_event_ndims
are specified, or if either of them is negative.ValueError
: If a member ofgraph_parents
is not aTensor
.
Properties
dtype
dtype of Tensor
s transformable by this distribution.
forward_min_event_ndims
Returns the minimal number of dimensions bijector.forward operates on.
graph_parents
Returns this Bijector
's graph_parents as a Python list.
inverse_min_event_ndims
Returns the minimal number of dimensions bijector.inverse operates on.
is_constant_jacobian
Returns true iff the Jacobian matrix is not a function of x.
Returns:
is_constant_jacobian
: Pythonbool
.
name
Returns the string name of this Bijector
.
trainable_variables
validate_args
Returns True if Tensor arguments will be validated.
variables
Methods
__call__
__call__(
value,
name=None,
**kwargs
)
Applies or composes the Bijector
, depending on input type.
This is a convenience function which applies the Bijector
instance in
three different ways, depending on the input:
- If the input is a
tfd.Distribution
instance, returntfd.TransformedDistribution(distribution=input, bijector=self)
. - If the input is a
tfb.Bijector
instance, returntfb.Chain([self, input])
. - Otherwise, return
self.forward(input)
Args:
value
: Atfd.Distribution
,tfb.Bijector
, or aTensor
.name
: Pythonstr
name given to ops created by this function.**kwargs
: Additional keyword arguments passed into the createdtfd.TransformedDistribution
,tfb.Bijector
, orself.forward
.
Returns:
composition
: Atfd.TransformedDistribution
if the input was atfd.Distribution
, atfb.Chain
if the input was atfb.Bijector
, or aTensor
computed byself.forward
.
Examples
sigmoid = tfb.Reciprocal()(
tfb.AffineScalar(shift=1.)(
tfb.Exp()(
tfb.AffineScalar(scale=-1.))))
# ==> `tfb.Chain([
# tfb.Reciprocal(),
# tfb.AffineScalar(shift=1.),
# tfb.Exp(),
# tfb.AffineScalar(scale=-1.),
# ])` # ie, `tfb.Sigmoid()`
log_normal = tfb.Exp()(tfd.Normal(0, 1))
# ==> `tfd.TransformedDistribution(tfd.Normal(0, 1), tfb.Exp())`
tfb.Exp()([-1., 0., 1.])
# ==> tf.exp([-1., 0., 1.])
forward
forward(
x,
name='forward',
**kwargs
)
Returns the forward Bijector
evaluation, i.e., X = g(Y).
Args:
x
:Tensor
. The input to the 'forward' evaluation.name
: The name to give this op.**kwargs
: Named arguments forwarded to subclass implementation.
Returns:
Tensor
.
Raises:
TypeError
: ifself.dtype
is specified andx.dtype
is notself.dtype
.NotImplementedError
: if_forward
is not implemented.
forward_event_shape
forward_event_shape(input_shape)
Shape of a single sample from a single batch as a TensorShape
.
Same meaning as forward_event_shape_tensor
. May be only partially defined.
Args:
input_shape
:TensorShape
indicating event-portion shape passed intoforward
function.
Returns:
forward_event_shape_tensor
:TensorShape
indicating event-portion shape after applyingforward
. Possibly unknown.
forward_event_shape_tensor
forward_event_shape_tensor(
input_shape,
name='forward_event_shape_tensor'
)
Shape of a single sample from a single batch as an int32
1D Tensor
.
Args:
input_shape
:Tensor
,int32
vector indicating event-portion shape passed intoforward
function.name
: name to give to the op
Returns:
forward_event_shape_tensor
:Tensor
,int32
vector indicating event-portion shape after applyingforward
.
forward_log_det_jacobian
forward_log_det_jacobian(
x,
event_ndims,
name='forward_log_det_jacobian',
**kwargs
)
Returns both the forward_log_det_jacobian.
Args:
x
:Tensor
. The input to the 'forward' Jacobian determinant evaluation.event_ndims
: Number of dimensions in the probabilistic events being transformed. Must be greater than or equal toself.forward_min_event_ndims
. The result is summed over the final dimensions to produce a scalar Jacobian determinant for each event, i.e. it has shaperank(x) - event_ndims
dimensions.name
: The name to give this op.**kwargs
: Named arguments forwarded to subclass implementation.
Returns:
Tensor
, if this bijector is injective.
If not injective this is not implemented.
Raises:
TypeError
: ifself.dtype
is specified andy.dtype
is notself.dtype
.NotImplementedError
: if neither_forward_log_det_jacobian
nor {_inverse
,_inverse_log_det_jacobian
} are implemented, or this is a non-injective bijector.
inverse
inverse(
y,
name='inverse',
**kwargs
)
Returns the inverse Bijector
evaluation, i.e., X = g^{-1}(Y).
Args:
y
:Tensor
. The input to the 'inverse' evaluation.name
: The name to give this op.**kwargs
: Named arguments forwarded to subclass implementation.
Returns:
Tensor
, if this bijector is injective.
If not injective, returns the k-tuple containing the unique
k
points (x1, ..., xk)
such that g(xi) = y
.
Raises:
TypeError
: ifself.dtype
is specified andy.dtype
is notself.dtype
.NotImplementedError
: if_inverse
is not implemented.
inverse_event_shape
inverse_event_shape(output_shape)
Shape of a single sample from a single batch as a TensorShape
.
Same meaning as inverse_event_shape_tensor
. May be only partially defined.
Args:
output_shape
:TensorShape
indicating event-portion shape passed intoinverse
function.
Returns:
inverse_event_shape_tensor
:TensorShape
indicating event-portion shape after applyinginverse
. Possibly unknown.
inverse_event_shape_tensor
inverse_event_shape_tensor(
output_shape,
name='inverse_event_shape_tensor'
)
Shape of a single sample from a single batch as an int32
1D Tensor
.
Args:
output_shape
:Tensor
,int32
vector indicating event-portion shape passed intoinverse
function.name
: name to give to the op
Returns:
inverse_event_shape_tensor
:Tensor
,int32
vector indicating event-portion shape after applyinginverse
.
inverse_log_det_jacobian
inverse_log_det_jacobian(
y,
event_ndims,
name='inverse_log_det_jacobian',
**kwargs
)
Returns the (log o det o Jacobian o inverse)(y).
Mathematically, returns: log(det(dX/dY))(Y)
. (Recall that: X=g^{-1}(Y)
.)
Note that forward_log_det_jacobian
is the negative of this function,
evaluated at g^{-1}(y)
.
Args:
y
:Tensor
. The input to the 'inverse' Jacobian determinant evaluation.event_ndims
: Number of dimensions in the probabilistic events being transformed. Must be greater than or equal toself.inverse_min_event_ndims
. The result is summed over the final dimensions to produce a scalar Jacobian determinant for each event, i.e. it has shaperank(y) - event_ndims
dimensions.name
: The name to give this op.**kwargs
: Named arguments forwarded to subclass implementation.
Returns:
ildj
:Tensor
, if this bijector is injective. If not injective, returns the tuple of local log det Jacobians,log(det(Dg_i^{-1}(y)))
, whereg_i
is the restriction ofg
to theith
partitionDi
.
Raises:
TypeError
: ifself.dtype
is specified andy.dtype
is notself.dtype
.NotImplementedError
: if_inverse_log_det_jacobian
is not implemented.