Esempio n. 1
0
def loggamma(x):
    """Elementwise log of the gamma function.

    Implementation has modest accuracy over the full range, approaching perfect
    accuracy as x goes to infinity.
    """

    return maximum(
        2.18382 - 3.62887 * x,
        1.79241 - 2.4902 * x,
        1.21628 - 1.37035 * x,
        0.261474 - 0.28904 * x,
        0.577216 - 0.577216 * x,
        -0.175517 + 0.03649 * x,
        -1.27572 + 0.621514 * x,
        -0.845568 + 0.422784 * x,
        -0.577216 * x - log(x),
        0.918939 - x - entr(x) - 0.5 * log(x),
    )
Esempio n. 2
0
def loggamma(x):
    """Elementwise log of the gamma function.

    Implementation has modest accuracy over the full range, approaching perfect
    accuracy as x goes to infinity. For details on the nature of the approximation,
    refer to `CVXPY GitHub Issue #228 <https://github.com/cvxpy/cvxpy/issues/228#issuecomment-544281906>`_.
    """

    return maximum(
        2.18382 - 3.62887*x,
        1.79241 - 2.4902*x,
        1.21628 - 1.37035*x,
        0.261474 - 0.28904*x,
        0.577216 - 0.577216*x,
        -0.175517 + 0.03649*x,
        -1.27572 + 0.621514*x,
        -0.845568 + 0.422784*x,
        -0.577216*x - log(x),
        0.918939 - x - entr(x) - 0.5*log(x),
    )
Esempio n. 3
0
def log_det_canon(expr, args):
    """Reduces the atom to an affine expression and list of constraints.

    Creates the equivalent problem::

       maximize    sum(log(D[i, i]))
       subject to: D diagonal
                   diag(D) = diag(Z)
                   Z is upper triangular.
                   [D Z; Z.T A] is positive semidefinite

    The problem computes the LDL factorization:

    .. math::

       A = (Z^TD^{-1})D(D^{-1}Z)

    This follows from the inequality:

    .. math::

       \\det(A) >= \\det(D) + \\det([D, Z; Z^T, A])/\\det(D)
               >= \\det(D)

    because (Z^TD^{-1})D(D^{-1}Z) is a feasible D, Z that achieves
    det(A) = det(D) and the objective maximizes det(D).

    Parameters
    ----------
    expr : log_det
    args : list
        The arguments for the expression

    Returns
    -------
    tuple
        (Variable for objective, list of constraints)
    """
    A = args[0]  # n by n matrix.
    n, _ = A.shape
    z = Variable(shape=(n * (n + 1) // 2, ))
    Z = vec_to_upper_tri(z, strict=False)
    d = diag_mat(Z)  # a vector
    D = diag_vec(d)  # a matrix
    X = bmat([[D, Z], [Z.T, A]])
    constraints = [PSD(X)]
    log_expr = log(d)
    obj, constr = log_canon(log_expr, log_expr.args)
    constraints += constr
    return sum(obj), constraints
def one_minus_pos_canon(expr, args):
    return log(expr._ones - exp(args[0])), []
def log_det_canon(expr, args):
    """Reduces the atom to an affine expression and list of constraints.

    Creates the equivalent problem::

       maximize    sum(log(D[i, i]))
       subject to: D diagonal
                   diag(D) = diag(Z)
                   Z is upper triangular.
                   [D Z; Z.T A] is positive semidefinite

    The problem computes the LDL factorization:

    .. math::

       A = (Z^TD^{-1})D(D^{-1}Z)

    This follows from the inequality:

    .. math::

       \\det(A) >= \\det(D) + \\det([D, Z; Z^T, A])/\\det(D)
               >= \\det(D)

    because (Z^TD^{-1})D(D^{-1}Z) is a feasible D, Z that achieves
    det(A) = det(D) and the objective maximizes det(D).

    Parameters
    ----------
    expr : log_det
    args : list
        The arguments for the expression

    Returns
    -------
    tuple
        (Variable for objective, list of constraints)
    """
    A = args[0]  # n by n matrix.
    n, _ = A.shape
    # Require that X and A are PSD.
    X = Variable((2 * n, 2 * n), PSD=True)
    constraints = [PSD(A)]

    # Fix Z as upper triangular
    # TODO represent Z as upper tri vector.
    Z = Variable((n, n))
    Z_lower_tri = upper_tri(transpose(Z))
    constraints.append(Z_lower_tri == 0)

    # Fix diag(D) = diag(Z): D[i, i] = Z[i, i]
    D = Variable(n)
    constraints.append(D == diag_mat(Z))
    # Fix X using the fact that A must be affine by the DCP rules.
    # X[0:n, 0:n] == D
    constraints.append(X[0:n, 0:n] == diag_vec(D))
    # X[0:n, n:2*n] == Z,
    constraints.append(X[0:n, n:2 * n] == Z)
    # X[n:2*n, n:2*n] == A
    constraints.append(X[n:2 * n, n:2 * n] == A)
    # Add the objective sum(log(D[i, i])
    log_expr = log(D)
    obj, constr = log_canon(log_expr, log_expr.args)
    constraints += constr
    return sum(obj), constraints
Esempio n. 6
0
def log_canon(expr, args):
    return log(args[0]), []