Example #1
0
def prox_quad_form(v, t=1, Q=None, method="lsqr", *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f(x) = x^TQx` for symmetric
    :math:`Q \\succeq 0`, scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term,
    and d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0,
    and d = 0.
    """
    if np.isscalar(v):
        v = np.array([v])
    if Q is None:
        raise ValueError("Q must be a matrix.")
    elif np.isscalar(Q):
        Q = np.array([[Q]])

    if Q.shape[0] != Q.shape[1]:
        raise ValueError("Q must be a square matrix.")
    if Q.shape[0] != v.shape[0]:
        raise ValueError("Dimension mismatch: nrow(Q) != nrow(v).")
    if sparse.issparse(Q):
        Q_min_eigval = sparse.linalg.eigsh(Q,
                                           k=1,
                                           which="SA",
                                           return_eigenvectors=False)[0]
        if np.iscomplex(Q_min_eigval) or Q_min_eigval < 0:
            raise ValueError(
                "Q must be a symmetric positive semidefinite matrix.")
    else:
        if not np.all(np.linalg.eigvalsh(Q) >= 0):
            raise ValueError(
                "Q must be a symmetric positive semidefinite matrix.")
    if method not in ["lsqr", "lstsq"]:
        raise ValueError("method must be either 'lsqr' or 'lstsq'")
    return prox_scale(prox_quad_form_base, Q=Q, method=method, *args,
                      **kwargs)(v, t)
Example #2
0
def prox_exp(v, t=1, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f(x) = \\exp(x)` applied
    elementwise for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and
    d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and 
    d = 0.
    """
    return prox_scale(prox_exp_base, *args, **kwargs)(v, t)
Example #3
0
def prox_sum_squares_affine(v,
                            t=1,
                            F=None,
                            g=None,
                            method="lsqr",
                            *args,
                            **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f(x) = \\|Fx - g\\|_2^2`
        for matrix F, vector g, scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term,
        and d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0,
        and d = 0.
        """
    if np.isscalar(v):
        v = np.array([v])
    if F is None:
        raise ValueError("F must be a matrix.")
    elif np.isscalar(F):
        F = np.array([[F]])
    if g is None:
        raise ValueError("g must be a vector.")
    elif np.isscalar(g):
        g = np.array([g])

    if F.shape[0] != g.shape[0]:
        raise ValueError("Dimension mismatch: nrow(F) != nrow(g).")
    if F.shape[1] != v.shape[0]:
        raise ValueError("Dimension mismatch: ncol(F) != nrow(v).")
    if method not in ["lsqr", "lstsq"]:
        raise ValueError("method must be either 'lsqr' or 'lstsq'.")
    return prox_scale(prox_sum_squares_affine_base,
                      F=F,
                      g=g,
                      method=method,
                      *args,
                      **kwargs)(v, t)
Example #4
0
def prox_box_constr(v, t=1, v_lo=-np.inf, v_hi=np.inf, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f` is the set indicator that
	:math:`\\underline x \\leq x \\leq \\overline x`. Here the lower/upper bounds are (v_lo, v_hi), which default
	to (-Inf, Inf). The scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and 
	d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
	"""
    return prox_scale(prox_box_constr_base, v_lo, v_hi, *args, **kwargs)(v, t)
Example #5
0
def prox_sigma_max(B, t = 1, *args, **kwargs):
    """Proximal operator of :math:`tf(aB-b) + cB + d\\|B\\|_F^2`, where :math:`f(B) = \\sigma_{\\max}(B)`
    is the maximum singular value of :math:`B`, for scalar t > 0, and the optional arguments are a = scale,
    b = offset, c = lin_term, and d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default,
    t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    return prox_scale(prox_sigma_max_base, *args, **kwargs)(B, t)
Example #6
0
def prox_max(v, t = 1, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f(x) = \\max_i x_i`
    for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if np.isscalar(v):
        v = np.array([v])
    return prox_scale(prox_max_base, *args, **kwargs)(v, t)
Example #7
0
def prox_norm_fro(B, t = 1, *args, **kwargs):
    """Proximal operator of :math:`tf(aB-b) + cB + d\\|B\\|_F^2`, where :math:`f(B) = \\|B\\|_2`
    for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if np.isscalar(B):
        B = np.array([[B]])
    return prox_scale(prox_norm_fro_base, *args, **kwargs)(B, t)
Example #8
0
def prox_kl(v, t = 1, u = None, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where 
    :math:`f(x) = \\sum_i x_i*\\log(x_i/u_i)`
    for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if np.isscalar(v):
        v = np.array([v])
    if u is None:
        u = np.ones(v.shape)
    return prox_scale(prox_kl_base, u, *args, **kwargs)(v, t)
Example #9
0
def prox_neg_log_det(B, t = 1, *args, **kwargs):
    """Proximal operator of :math:`tf(aB-b) + cB + d\\|B\\|_F^2`, where :math:`f(B) = -\\log\\det(B)`, where `B` is a
    symmetric matrix. The scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and
    d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if B.shape[0] != B.shape[1]:
        raise ValueError("B must be a square matrix.")
    B_symm = (B + B.T) / 2.0
    if not (np.allclose(B, B_symm)):
        raise ValueError("B must be a symmetric matrix.")
    return prox_scale(prox_neg_log_det_base, *args, **kwargs)(B_symm, t)
Example #10
0
def prox_soc(v, t=1, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f` is the set indicator that
	:math:`\\|x_{1:n}\\|_2 \\leq x_{n+1}`. The scalar t > 0, and the optional arguments are a = scale, b = offset,
	c = lin_term, and d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, 	t = 1, a = 1, b = 0,
	c = 0, and d = 0.
	"""
    if np.isscalar(v) or not (len(v.shape) == 1 or
                              (len(v.shape) == 2 and v.shape[1] == 1)):
        raise ValueError("v must be a vector")
    if v.shape[0] < 2:
        raise ValueError("v must have at least 2 elements.")
    return prox_scale(prox_soc_base, *args, **kwargs)(v, t)
Example #11
0
def prox_huber(v, t=1, M=1, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where
    .. math::
        f(x) =
            \\begin{cases}
                2M|x|-M^2 & \\text{for } |x| \\geq |M| \\\\
                      |x|^2 & \\text{for } |x| \\leq |M|
            \\end{cases}
    applied elementwise for scalar M > 0, t > 0, and the optional arguments are a = scale, b = offset, c = lin_term,
    and d = quad_term. We must have M > 0, t > 0, a = non-zero, and d >= 0. By default, M = 1, t = 1, a = 1, b = 0, 
    c = 0, and d = 0.
    """
    return prox_scale(prox_huber_base, M, *args, **kwargs)(v, t)
Example #12
0
def prox_logistic(v, t = 1, x0 = None, y = None, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where 
    :math:`f(x) = \\sum_i \\log(1 + \\exp(-y_i*x_i))`
    for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if np.isscalar(v):
        v = np.array([v])
    if x0 is None:
        # x0 = np.random.randn(*v.shape)
        x0 = v
    if y is None:
        y = -np.ones(v.shape)
    return prox_scale(prox_logistic_base, x0, y, *args, **kwargs)(v, t)
Example #13
0
def prox_psd_cone(B, t=1, *args, **kwargs):
    """Proximal operator of :math:`tf(aB-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f` is the set indicator that
	:math:`B \\succeq 0` for :math:`B` a symmetric matrix. The scalar t > 0, and the optional arguments are
	a = scale, b = offset, c = lin_term, and d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default,
	t = 1, a = 1, b = 0, c = 0, and d = 0.
	"""
    if np.isscalar(B):
        B = np.array([[B]])
    if B.shape[0] != B.shape[1]:
        raise ValueError("B must be a square matrix.")
    B_symm = (B + B.T) / 2.0
    if not np.allclose(B, B_symm):
        raise ValueError("B must be a symmetric matrix.")
    return prox_scale(prox_psd_cone_base, *args, **kwargs)(B_symm, t)
Example #14
0
def prox_trace(B, t = 1, C = None, *args, **kwargs):
    """Proximal operator of :math:`tf(aB-b) + cB + d\\|B\\|_F^2`, where :math:`f(B) = tr(C^TB)` is the trace of
    :math:`C^TB`, where C is a given matrix quantity. By default, C is the identity matrix, so :math:`f(B) = tr(B)`.
    The scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if np.isscalar(B):
        B = np.array([[B]])
    if C is None:
        C = sparse.eye(B.shape[0])
    if B.shape[0] != C.shape[0]:
        raise ValueError("Dimension mismatch: nrow(B) != nrow(C)")
    if B.shape[1] != C.shape[1]:
        raise ValueError("Dimension mismatch: ncol(B) != ncol(C)")
    return prox_scale(prox_trace_base, C=C, *args, **kwargs)(B, t)
Example #15
0
def prox_qp(v, t=1, Q=None, q=None, F=None, g=None, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f(x) = x^TQx+q^Tx+I{Fx<=g}`
    for scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and d = quad_term.
    We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
    """
    if Q is None:
        raise ValueError("Q must be a matrix")
    if q is None:
        raise ValueError("q must be a vector")
    if F is None:
        raise ValueError("F must be a matrix")
    if g is None:
        raise ValueError("g must be a vector")
    if Q.shape[0] != Q.shape[1]:
        raise ValueError("Q must be square")
    if Q.shape[0] != q.shape[0]:
        raise ValueError("Dimension mismatch: nrow(Q) != nrow(q)")
    if Q.shape[1] != v.shape[0]:
        raise ValueError("Dimension mismatch: ncol(Q) != nrow(v)")
    if F.shape[0] != g.shape[0]:
        raise ValueError("Dimension mismatch: nrow(F) != nrow(g)")
    if F.shape[1] != v.shape[0]:
        raise ValueError("Dimension mismatch: ncol(F) != nrow(v)")
    return prox_scale(prox_qp_base(Q, q, F, g), *args, **kwargs)(v, t)
Example #16
0
def prox_nonpos_constr(v, t=1, *args, **kwargs):
    """Proximal operator of :math:`tf(ax-b) + c^Tx + d\\|x\\|_2^2`, where :math:`f` is the set indicator that
	:math:`x \\leq 0`. The scalar t > 0, and the optional arguments are a = scale, b = offset, c = lin_term, and
	d = quad_term. We must have t > 0, a = non-zero, and d >= 0. By default, t = 1, a = 1, b = 0, c = 0, and d = 0.
	"""
    return prox_scale(prox_nonpos_constr_base, *args, **kwargs)(v, t)