Skip to content

relative_entropy_quadrature

Compute relative entropy quadrature from CVXQUAD.

relative_entropy_quadrature

relative_entropy_quadrature(
    vec_x: ndarray | Expression, vec_y: ndarray | Expression
) -> ndarray | float

Compute element-wise relative entropy \(x_i \log(x_i / y_i)\).

For numeric inputs this returns the element-wise values 1. Constant CVXPY expressions with a concrete .value are routed through the numeric path. Affine or variable CVXPY inputs are not supported; use relative_entropy_quadrature_epi_cone (with its m / k quadrature parameters) for composition in a parent SDP.

Parameters:

  • vec_x (ndarray | Expression) –

    Positive vector (or CVXPY expression).

  • vec_y (ndarray | Expression) –

    Positive vector (or CVXPY expression), broadcastable with vec_x.

Returns:

  • ndarray | float

    Element-wise values for numeric inputs.

Raises:

  • ValueError

    If inputs are not numpy arrays or CVXPY expressions.

  • ValueError

    If shapes are incompatible.

  • ValueError

    If inputs are not positive at evaluation points.

  • ValueError

    If a constant CVXPY expression has no numeric .value.

  • ValueError

    If affine or variable CVXPY inputs are passed.

Examples:

import numpy as np
from toqito.state_props import relative_entropy_quadrature
vec_x = np.array([0.3, 0.7])
vec_y = np.array([0.5, 0.5])
print(relative_entropy_quadrature(vec_x, vec_y))
[-0.15324769  0.23553057]

References

1 Fawzi, Hamza and Saunderson, James. Lieb's concavity theorem, matrix geometric means and semidefinite optimization. (2015). link.

Source code in toqito/state_props/relative_entropy_quadrature.py
def relative_entropy_quadrature(
    vec_x: np.ndarray | cvxpy.Expression,
    vec_y: np.ndarray | cvxpy.Expression,
) -> np.ndarray | float:
    r"""Compute element-wise relative entropy \(x_i \log(x_i / y_i)\).

    For numeric inputs this returns the element-wise values
    [@fawzi2015matrixgeometric]. Constant CVXPY expressions with a concrete
    ``.value`` are routed through the numeric path. Affine or variable CVXPY
    inputs are not supported; use ``relative_entropy_quadrature_epi_cone``
    (with its ``m`` / ``k`` quadrature parameters) for composition in a parent
    SDP.

    Args:
        vec_x: Positive vector (or CVXPY expression).
        vec_y: Positive vector (or CVXPY expression), broadcastable with ``vec_x``.

    Returns:
        Element-wise values for numeric inputs.

    Raises:
        ValueError: If inputs are not numpy arrays or CVXPY expressions.
        ValueError: If shapes are incompatible.
        ValueError: If inputs are not positive at evaluation points.
        ValueError: If a constant CVXPY expression has no numeric ``.value``.
        ValueError: If affine or variable CVXPY inputs are passed.

    Examples:
        ```python exec="1" source="above" result="text"
        import numpy as np
        from toqito.state_props import relative_entropy_quadrature
        vec_x = np.array([0.3, 0.7])
        vec_y = np.array([0.5, 0.5])
        print(relative_entropy_quadrature(vec_x, vec_y))
        ```

    """
    if not isinstance(vec_x, (np.ndarray, cvxpy.Expression)):
        raise ValueError("vec_x must be a numpy array or a cvxpy expression")
    if not isinstance(vec_y, (np.ndarray, cvxpy.Expression)):
        raise ValueError("vec_y must be a numpy array or a cvxpy expression")

    vec_x, vec_y, _sz = _broadcast_shape(vec_x, vec_y)

    if isinstance(vec_x, np.ndarray) and isinstance(vec_y, np.ndarray):
        x_b = np.asarray(vec_x, dtype=float)
        y_b = np.asarray(vec_y, dtype=float)
        if np.any(x_b <= 0) or np.any(y_b <= 0):
            raise ValueError("vec_x and vec_y must be positive")
        return x_b * np.log(x_b / y_b)

    if isinstance(vec_x, np.ndarray):
        vec_x = cvxpy.Constant(vec_x)
    if isinstance(vec_y, np.ndarray):
        vec_y = cvxpy.Constant(vec_y)

    if vec_x.is_constant() and vec_y.is_constant():
        return relative_entropy_quadrature(
            _constant_value(vec_x),
            _constant_value(vec_y),
        )

    _reject_nonconstant_cvxpy(vec_x, vec_y)