Convex.ProblemDepot.PROBLEMSConstant
const PROBLEMS = Dict{String, Dict{String, Function}}()

A "depot" of Convex.jl problems, subdivided into categories. Each problem is stored as a function with the signature

f(handle_problem!, ::Val{test}, atol, rtol, ::Type{T}) where {T, test}

where handle_problem! specifies what to do with the Problem instance (e.g., solve! it with a chosen solver), an option test to choose whether or not to test the values (assuming it has been solved), tolerances for the tests, and a numeric type in which the problem should be specified (currently, this is not respected and all problems are specified in Float64 precision).

See also run_tests and benchmark_suite for helpers to use these problems in testing or benchmarking.

Examples

julia> PROBLEMS["affine"]["affine_diag_atom"]
affine_diag_atom (generic function with 1 method)
Convex.ProblemDepot.benchmark_suiteFunction
benchmark_suite(
    handle_problem!::Function,
    problems::Union{Nothing, Vector{String}, Vector{Regex}} = nothing;
    exclude::Vector{Regex} = Regex[],
    test = Val(false),
    T=Float64, atol=1e-3, rtol=0.0,
)

Create a benchmarksuite of benchmarks. `handleproblem!should be a function that takes one argument, a Convex.jlProblemand processes it (e.g.solve!the problem with a specific solver). Pass a second argumentproblems` to specify run benchmarks only with certain problems (specified by exact names or regex).

Use exclude to exclude a subset of benchmarks. Optionally, pass a second argument problems to only allow certain problems (specified by exact names or regex). Set test=true to also check the answers, with tolerances specified by atol and rtol. Set T to choose a numeric type for the problem. Currently this is only used for choosing the type parameter of the underlying MathOptInterface model, but not for the actual problem data.

Examples

benchmark_suite(exclude=[r"mip"]) do p
    solve!(p, SCS.Optimizer; silent=true)
end
Convex.ProblemDepot.foreach_problemFunction
foreach_problem(apply::Function, [class::String],
    problems::Union{Nothing, Vector{String}, Vector{Regex}} = nothing;
    exclude::Vector{Regex} = Regex[])

Provides a convience method for iterating over problems in PROBLEMS. For each problem in PROBLEMS, apply the function apply, which takes two arguments: the name of the function associated to the problem, and the function associated to the problem itself.

Optionally, pass a second argument class to only iterate over a class of problems (class should satsify class ∈ keys(PROBLEMS)), and pass third argument problems to only allow certain problems (specified by exact names or regex). Use the exclude keyword argument to exclude problems by regex.

Convex.ProblemDepot.run_testsFunction
run_tests(
    handle_problem!::Function;
    problems::Union{Nothing, Vector{String}, Vector{Regex}} = nothing;
    exclude::Vector{Regex} = Regex[],
    T=Float64, atol=1e-3, rtol=0.0,
)

Run a set of tests. handle_problem! should be a function that takes one argument, a Convex.jl Problem and processes it (e.g. solve! the problem with a specific solver).

Use exclude to exclude a subset of sets; automatically excludes r"benchmark". Optionally, pass a second argument problems to only allow certain problems (specified by exact names or regex). The test tolerances specified by atol and rtol. Set T to choose a numeric type for the problem. Currently this is only used for choosing the type parameter of the underlying MathOptInterface model, but not for the actual problem data.

Examples

run_tests(exclude=[r"mip"]) do p
    solve!(p, SCS.Optimizer; silent=true)
end
Convex.MAXDEPTHConstant
MAXDEPTH

Controls depth of tree printing globally for Convex.jl; defaults to 3. Set via

Convex.MAXDEPTH[] = 5
Convex.MAXDIGITSConstant
MAXDIGITS

When priting IDs of variables, only show the initial and final digits if the full ID has more than double the number of digits specified here. So, with the default setting MAXDIGITS=3, any ID longer than 7 digits would be shortened; for example, ID 14656210999710729289 would be printed as 146…289.

This setting controls tree printing globally for Convex.jl; defaults to 3.

Set via:

Convex.MAXDIGITS[] = 3
Convex.MAXWIDTHConstant
MAXWIDTH

Controls width of tree printing globally for Convex.jl; defaults to 3. Set via

Convex.MAXWIDTH[] = 10
Convex.AbstractVariableType
abstract type AbstractVariable <: AbstractExpr end

An AbstractVariable should have head field, and a size field to conform to the AbstractExpr interface, and implement methods (or use the field-access fallbacks) for

  • _value, set_value!: get or set the numeric value of the variable. _value should return nothing when no numeric value is set. Note: evaluate is the user-facing method to access the value of x.
  • vexity, vexity!: get or set the vexity of the variable. The vexity should be AffineVexity() unless the variable has been fix!'d, in which case it is ConstVexity().
  • sign, vartype, and get_constraints: get the Sign, VarType, numeric type, and a (possibly empty) vector of constraints which are to be applied to any problem in which the variable is used.

Optionally, also implement sign!, vartype!, and add_constraint! to allow users to modify those values or add a constraint.

Convex.GeometricMeanEpiConeSquareType
GeometricMeanEpiConeSquare(t::Rational, side_dimension::Int)

The constraint (T, A, B) in GeometricMeanEpiConeSquare(t, side_dimension) constrains T to

A #_t B ⪯ T

where:

  • A #_t B is the t-weighted geometric mean of A and B: A^{1/2} (A^{-1/2} B A^{-1/2})^t A^{1/2}
  • Parameter t must be in [-1, 0] or [1, 2].
  • Constraints A ⪰ 0, B ⪰ 0 are added.

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Convex.GeometricMeanHypoConeSquareType

Constrains T to A #_t B ⪰ T where:

  • A #_t B is the t-weighted geometric mean of A and B: A^{1/2} (A^{-1/2} B A^{-1/2})^t A^{1/2} Parameter t should be in [0,1].
  • Constraints A ⪰ 0, B ⪰ 0 are added.

Note on parameter fullhyp: In many applications one doesn't need the full hypograph hypt = {(A,B,T) : A #t B ⪰ T} but rather it is enough to work with a convex set Ct that satisfies (A,B,A #t B) \in Ct (A,B,T) \in Ct => A #_t B ⪰ T In this case one should set fullhyp = false. The SDP description will be (slightly) smaller. (By default fullhyp is set to true).

All expressions and atoms are subtypes of AbstractExpr. Please read expressions.jl first.

REFERENCE Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Convex.LogSumExpAtomType
LogSumExpAtom(x::AbstractExpr, dims::Union{Colon,Int} = :)

Represents the expression log.(sum(exp.(x); dims)).

Convex.RelativeEntropyEpiConeSquareType
RelativeEntropyEpiConeSquare(
    side_dimension::Int,
    m::Integer = 3,
    k::Integer = 3,
    e::AbstractArray = Matrix(1.0 * LinearAlgebra.I(side_dimension)),
)

Constrains (τ, X, Y) to:

τ ⪰ e' * X^{1/2} * logm(X^{1/2}*Y^{-1}*X^{1/2}) * X^{1/2} * e

This set implements the semidefinite programming approximation given in the reference below.

Parameters m and k control the accuracy of this approximation: m is the number of quadrature nodes to use and k the number of square-roots to take. See reference for more details.

Reference

Ported from CVXQUAD which is based on the paper: "Semidefinite approximations of matrix logarithm" by Hamza Fawzi, James Saunderson and Pablo A. Parrilo (arXiv:1705.00812)

Convex.TraceMpowerAtomType
TraceMpowerAtom(A::AbstractExpr, t::Rational, C::AbstractMatrix)

trace_mpower(A, t, C) returns LinearAlgebra.tr(C*A^t) where A and C are positive definite matrices and C is constant and t ∈ [-1, 2].

When t ∈ [0,1], trace_mpower(A, t, C) is concave in A (for fixed positive semidefinite matrix C) and convex for t ∈ [-1, 0) or (1, 2].

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Base.:*Method
Base.:*(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The binary multiplication operator $x \times y$.

Examples

ulia> x = Variable();

julia> 2 * x
* (affine; real)
├─ [2;;]
└─ real variable (id: 709…007)
julia> x = Variable(3);

julia> y = [1, 2, 3];

julia> x' * y
* (affine; real)
├─ reshape (affine; real)
│  └─ * (affine; real)
│     ├─ 3×3 SparseArrays.SparseMatrixCSC{Int64, Int64} with 3 stored entries
│     └─ reshape (affine; real)
│        └─ …
└─ [1; 2; 3;;]
Base.:+Method
Base.:+(x::Convex.AbstractExpr, y::Convex.AbstractExpr)
Base.:+(x::Convex.Value, y::Convex.AbstractExpr)
Base.:+(x::Convex.AbstractExpr, y::Convex.Value)

The addition operator $x + y$.

Examples

Applies to scalar expressions:

julia> x = Variable();

julia> x + 1
+ (affine; real)
├─ real variable (id: 110…477)
└─ [1;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = [1, 2, 3];

julia> atom = x + y
+ (affine; real)
├─ 3-element real variable (id: 458…482)
└─ [1; 2; 3;;]

julia> size(atom)
(3, 1)
Base.:-Method
Base.:-(x::Convex.AbstractExpr, y::Convex.AbstractExpr)
Base.:-(x::Convex.Value, y::Convex.AbstractExpr)
Base.:-(x::Convex.AbstractExpr, y::Convex.Value)

The subtraction operator $x - y$.

Examples

Applies to scalar expressions:

julia> x = Variable();

julia> x - 1
+ (affine; real)
├─ real variable (id: 161…677)
└─ [-1;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = [1, 2, 3];

julia> atom = y - x
+ (affine; real)
├─ [1; 2; 3;;]
└─ Convex.NegateAtom (affine; real)
   └─ 3-element real variable (id: 242…661)
Base.:-Method
Base.:-(x::Convex.AbstractExpr)

The univariate negation operator $-x$.

Examples

Applies to scalar expressions:

julia> x = Variable();

julia> -x
Convex.NegateAtom (affine; real)
├─ real variable (id: 161…677)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = -x
Convex.NegateAtom (affine; real)
└─ 3-element real variable (id: 137…541)

julia> size(atom)
(3, 1)
Base.:/Method
Base.:/(x::Convex.AbstractExpr, y::Convex.Value)

The binary division operator $\frac{x}{y}$.

Examples

Applies to a scalar expression:

ulia> x = Variable();

julia> x / 2

and element-wise to a matrix:

julia> x = Variable(3);

julia> atom = x / 2
* (affine; real)
├─ 3-element real variable (id: 129…611)
└─ [0.5;;]

julia> size(atom)
(3, 1)
Base.Broadcast.broadcastedMethod
x::Convex.AbstractExpr .* y::Convex.AbstractExpr

Element-wise multiplication between matrices x and y.

Examples

julia> x = Variable(2);

julia> atom = x .* 2
* (affine; real)
├─ 2-element real variable (id: 197…044)
└─ [2;;]

julia> atom = x .* [2, 4]
.* (affine; real)
├─ 2-element real variable (id: 197…044)
└─ [2; 4;;]

julia> size(atom)
(2, 1)
Base.Broadcast.broadcastedMethod
x::Convex.AbstractExpr ./ y::Convex.AbstractExpr

Element-wise division between matrices x and y.

Examples

julia> x = Variable(2);

julia> atom = x ./ 2
* (affine; real)
├─ 2-element real variable (id: 875…859)
└─ [0.5;;]

julia> atom = x ./ [2, 4]
.* (affine; real)
├─ 2-element real variable (id: 875…859)
└─ [0.5; 0.25;;]

julia> size(atom)
(2, 1)
Base.Broadcast.broadcastedMethod
x::Convex.AbstractExpr .^ k::Int

Element-wise exponentiation of x to the power of k.

Examples

julia> x = Variable(2);

julia> atom = x .^ 2
qol_elem (convex; positive)
├─ 2-element real variable (id: 131…737)
└─ [1.0; 1.0;;]

julia> size(atom)
(2, 1)
Base.absMethod
Base.abs(x::Convex.AbstractExpr)

The epigraph of $|x|$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> abs(x)
abs (convex; positive)
└─ real variable (id: 103…720)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = abs(x)
abs (convex; positive)
└─ 3-element real variable (id: 389…882)

julia> size(atom)
(3, 1)
Base.abs2Method
Base.abs2(x::Convex.AbstractExpr)

The epigraph of $|x|^2$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> abs2(x)
qol_elem (convex; positive)
├─ abs (convex; positive)
│  └─ real variable (id: 319…413)
└─ [1.0;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = abs2(x)
qol_elem (convex; positive)
├─ abs (convex; positive)
│  └─ 3-element real variable (id: 123…996)
└─ [1.0; 1.0; 1.0;;]

julia> size(atom)
(3, 1)
Base.adjointMethod
LinearAlgebra.adjoint(x::AbstractExpr)

The transpose of the conjugated matrix x.

Examples

julia> x = ComplexVariable(2, 2);

julia> atom = adjoint(x)
reshape (affine; complex)
└─ * (affine; complex)
   ├─ 4×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 4 stored entries
   └─ reshape (affine; complex)
      └─ conj (affine; complex)
         └─ …

julia> size(atom)
(2, 2)
Base.conjMethod
Base.conj(x::Convex.AbstractExpr)

The complex conjugate of x.

If x is real, this function returns x.

Examples

Applies to a single expression:

julia> x = ComplexVariable();

julia> conj(x)
conj (affine; complex)
└─ complex variable (id: 180…137)

And element-wise to a matrix of expressions:

conj (affine; complex)
└─ complex variable (id: 180…137)

julia> x = ComplexVariable(3);

julia> atom = conj(x)
conj (affine; complex)
└─ 3-element complex variable (id: 104…031)

julia> size(atom)
(3, 1)
Base.expMethod
Base.exp(x::Convex.AbstractExpr)

The epigraph of $e^x$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> exp(x)
exp (convex; positive)
└─ real variable (id: 103…720)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = exp(x)
exp (convex; positive)
└─ 3-element real variable (id: 389…882)

julia> size(atom)
(3, 1)
Base.hcatMethod
Base.hcat(args::AbstractExpr...)

Horizontally concatenate args.

Examples

Applies to a matrix:

julia> x = Variable(2, 2);

julia> atom = hcat(x, x)
hcat (affine; real)
├─ 2×2 real variable (id: 111…376)
└─ 2×2 real variable (id: 111…376)

julia> size(atom)
(2, 4)

You can also use the Julia [x x] syntax:

julia> x = Variable(2, 2);

julia> atom = [x x]
hcat (affine; real)
├─ 2×2 real variable (id: 111…376)
└─ 2×2 real variable (id: 111…376)

julia> size(atom)
(2, 4)
Base.hvcatMethod
Base.hvcat(
    rows::Tuple{Vararg{Int}},
    args::Union{AbstractExpr,Value}...,
)

Horizontally and vertically concatenate args in single call.

rows is the number of arguments to vertically concatenate into each column.

Examples

Applies to a matrix:

To make the matrix:

a    b[1] b[2]
c[1] c[2] c[3]

do:

julia> a = Variable();

julia> b = Variable(1, 2);

julia> c = Variable(1, 3);

julia> atom = [a b; c]  # Syntactic sugar for: hvcat((2, 1), a, b, c)
vcat (affine; real)
├─ hcat (affine; real)
│  ├─ real variable (id: 429…021)
│  └─ 1×2 real variable (id: 120…326)
└─ hcat (affine; real)
   └─ 1×3 real variable (id: 124…615)

julia> size(atom)
(2, 3)
Base.imagMethod
Base.imag(x::Convex.AbstractExpr)

Return the imaginary component of x.

Examples

Applies to a single expression:

julia> x = ComplexVariable();

julia> imag(x)
imag (affine; real)
└─ complex variable (id: 407…692)

And element-wise to a matrix of expressions:

julia> x = ComplexVariable(3);

julia> atom = imag(x)
imag (affine; real)
└─ 3-element complex variable (id: 435…057)

julia> size(atom)
(3, 1)
Base.kronMethod
Base.kron(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The Kronecker (outer) product.

Examples

julia> x = Variable(2);

julia> y = [1 2];

julia> atom = kron(x, y)
vcat (affine; real)
├─ * (affine; real)
│  ├─ index (affine; real)
│  │  └─ 2-element real variable (id: 369…232)
│  └─ [1 2]
└─ * (affine; real)
   ├─ index (affine; real)
   │  └─ 2-element real variable (id: 369…232)
   └─ [1 2]

julia> size(atom)
(2, 2)
Base.logMethod
Base.log(x::Convex.AbstractExpr)

The hypograph of $\log(x)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> log(x)
log (concave; real)
└─ real variable (id: 103…720)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = log(x)
log (concave; real)
└─ 3-element real variable (id: 161…499)

julia> size(atom)
(3, 1)
Base.maxMethod
Base.max(x::Convex.AbstractExpr, y::Convex.AbstractExpr)
Base.max(x::Convex.AbstractExpr, y::Convex.Value)
Base.max(x::Convex.Value, y::Convex.AbstractExpr)

The hypograph of $max(x, y)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> max(x, 1)
max (convex; real)
├─ real variable (id: 183…974)
└─ [1;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = [1, 2, 3];

julia> atom = max(x, y)
max (convex; real)
├─ 3-element real variable (id: 153…965)
└─ [1; 2; 3;;]

julia> size(atom)
(3, 1)
Base.maximumMethod
Base.maximum(x::Convex.AbstractExpr)

The hypograph of $max(x...)$.

Examples

Applies to a matrix expression:

julia> x = Variable(3);

julia> atom = maximum(x)
maximum (convex; real)
└─ 3-element real variable (id: 159…219)

julia> size(atom)
(1, 1)
Base.minMethod
Base.min(x::Convex.AbstractExpr, y::Convex.AbstractExpr)
Base.min(x::Convex.Value, y::Convex.AbstractExpr)
Base.min(x::Convex.AbstractExpr, y::Convex.Value)

The epigraph of $min(x, y)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> min(x, 1)
min (concave; real)
├─ real variable (id: 183…974)
└─ [1;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = [1, 2, 3];

julia> atom = min(x, y)
min (concave; real)
├─ 3-element real variable (id: 153…965)
└─ [1; 2; 3;;]

julia> size(atom)
(3, 1)
Base.minimumMethod
Base.minimum(x::Convex.AbstractExpr)

The epigraph of $min(x...)$.

Examples

Applies to a matrix expression:

julia> x = Variable(3);

julia> atom = minimum(x)
minimum (convex; real)
└─ 3-element real variable (id: 159…219)

julia> size(atom)
(1, 1)
Base.realMethod
Base.real(x::Convex.AbstractExpr)

Return the real component of x.

Examples

Applies to a single expression:

julia> x = ComplexVariable();

julia> real(x)
real (affine; real)
└─ complex variable (id: 407…692)

And element-wise to a matrix of expressions:

julia> x = ComplexVariable(3);

julia> atom = real(x)
real (affine; real)
└─ 3-element complex variable (id: 435…057)

julia> size(atom)
(3, 1)
Base.reshapeMethod
Base.reshape(x::AbstractExpr, m::Int, n::Int)

Reshapes the expression x into a matrix with m rows and n columns.

Examples

Applies to a matrix:

julia> x = Variable(6, 1);

julia> size(x)
(6, 1)

julia> atom = reshape(x, 2, 3)
reshape (affine; real)
└─ 6-element real variable (id: 103…813)

julia> size(atom)
(2, 3)
Base.signMethod
Base.sign(x::AbstractVariable)

Returns the current sign of x.

Base.sqrtMethod
Base.sqrt(x::Convex.AbstractExpr)

The hypograph of $\sqrt x$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> sqrt(x)
geomean (concave; positive)
├─ real variable (id: 576…546)
└─ [1.0;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = sqrt(x)
geomean (concave; positive)
├─ 3-element real variable (id: 181…583)
└─ [1.0; 1.0; 1.0;;]

julia> size(atom)
(3, 1)
Base.sumMethod
Base.sum(x::Convex.AbstractExpr; dims = :)

Sum x, optionally along a dimension dims.

Examples

Sum all elements in an expression:

julia> x = Variable(2, 2);

julia> atom = sum(x)
sum (affine; real)
└─ 2×2 real variable (id: 263…449)

julia> size(atom)
(1, 1)

Sum along the first dimension, creating a row vector:

julia> x = Variable(2, 2);

julia> atom = sum(x; dims = 1)
* (affine; real)
├─ [1.0 1.0]
└─ 2×2 real variable (id: 143…826)

julia> size(atom)
(1, 2)

Sum along the second dimension, creating a columnn vector:

julia> atom = sum(x; dims = 2)
* (affine; real)
├─ 2×2 real variable (id: 143…826)
└─ [1.0; 1.0;;]

julia> size(atom)
(2, 1)
Base.summaryMethod
Base.summary(io::IO, x::AbstractVariable)

Prints a one-line summary of a variable x to io.

Examples

julia> x = ComplexVariable(3,2);

julia> summary(stdout, x)
3×2 complex variable (id: 732…737)
Base.transposeMethod
LinearAlgebra.transpose(x::AbstractExpr)

The transpose of the matrix x.

Examples

julia> x = Variable(2, 2);

julia> atom = transpose(x)
reshape (affine; real)
└─ * (affine; real)
   ├─ 4×4 SparseArrays.SparseMatrixCSC{Int64, Int64} with 4 stored entries
   └─ reshape (affine; real)
      └─ 2×2 real variable (id: 151…193)

julia> size(atom)
(2, 2)
Base.vcatMethod
Base.vcat(args::AbstractExpr...)

Vertically concatenate args.

Examples

Applies to a matrix:

julia> x = Variable(2, 2);

julia> atom = vcat(x, x)
vcat (affine; real)
├─ 2×2 real variable (id: 111…376)
└─ 2×2 real variable (id: 111…376)

julia> size(atom)
(4, 2)

You can also use the Julia [x; x] syntax:

julia> x = Variable(2, 2);

julia> atom = [x; x]
vcat (affine; real)
├─ 2×2 real variable (id: 111…376)
└─ 2×2 real variable (id: 111…376)

julia> size(atom)
(4, 2)
Base.vecMethod
Base.vec(x::AbstractExpr)

Reshapes the expression x into a column vector.

Examples

Applies to a matrix:

julia> x = Variable(2, 2);

julia> atom = vec(x)
reshape (affine; real)
└─ 2×2 real variable (id: 115…295)

julia> size(atom)
(4, 1)
Convex._add_vectorized_exp_coneMethod
_add_vectorized_exp_cone(
    context::Context{T},
    x,
    permutation::Vector{Int},
) where {T}

Constrains (x[i], 1, t[i]) ∈ ExponentialCone() for each element of x and returns t.

Permutation is a permuted vector of [1, 2, 3] to reorder the triple before it is constrained. This is helpful for LogAtom and EntropyAtom.

Motivation

A naive implementation of this method is:

    m, n = size(x)
    t = Variable(m, n)
    for i in 1:m, j in 1:n
        f = vcat(x[i, j], 1, t[i, j])[collect(permutation)]
        add_constraint!(context, Constraint{MOI.ExponentialCone}(f))
    end
    return conic_form!(context, t)
end

This is slow because we are indexing on the Convex side, and Convex is based around vector/matrix operations. We don't want to produce n*m IndexAtoms!

Instead, we will drop to the MOI level to implement this in terms of scalar operations.

Convex._gauss_legendre_quadratureMethod

Compute Gauss-Legendre quadrature nodes and weights on [0, 1].

Code below is from Trefethen (2008), "Is Gauss quadrature better than Clenshaw-Curtis?", SIAM Review, and computes the weights and nodes on [-1, 1].

Convex._is_psdMethod
_is_psd(A; tol)

Check whether A is positive semi-definite by computing a LDLᵀ factorization of A + tol*I

Convex._valueMethod
_value(x::AbstractVariable)

Raw access to the current value of x; used internally by Convex.jl.

Convex.add_constraint!Method
add_constraint!(x::AbstractVariable, C::Constraint)

Adds an constraint to those carried by x.

Convex.conic_form!Method
conic_form!(context::Context, a::AbstractExpr)

Return the conic form for a. If it as already been created, it is directly accessed in context[a], otherwise, it is created by calling Convex.new_conic_form! and then cached in context so that the next call with the same expression does not create a duplicate one.

Convex.convMethod
Convex.conv(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The convolution between two vectors x and y.

Examples

julia> x = Variable(2);

julia> y = [2, 4];

julia> atom = conv(x, y)
* (affine; real)
├─ 3×2 SparseArrays.SparseMatrixCSC{Int64, Int64} with 4 stored entries
└─ 2-element real variable (id: 663…363)

julia> size(atom)
(3, 1)
Convex.conv1D_matrixMethod
conv1D_matrix(h::AbstractVector, n::Integer) -> SparseMatrixCSC

Create a sparse matrix A such that if x has length n, then we have A * x ≈ conv1d(h, x).

Convex.dotsortMethod
dotsort(x::Convex.AbstractExpr, y::Convex.Value)
dotsort(x::Convex.Value, y::Convex.AbstractExpr)

Computes dot(sort(x), sort(y)), where x or y is constant.

For example, if x = Variable(6) and y = [1 1 1 0 0 0], this atom computes the sum of the three largest elements of x.

Examples

julia> x = Variable(4);

julia> atom = dotsort(x, [1, 0, 0, 1])
dotsort (convex; real)
└─ 4-element real variable (id: 128…367)

julia> size(atom)
(1, 1)
Convex.entropyMethod
entropy(x::Convex.AbstractExpr)

The hypograph of $\sum_i -x_i \log x_i$.

Examples

Applies to a matrix of expressions:

julia> x = Variable(3);

julia> atom = entropy(x)
sum (concave; real)
└─ entropy (concave; real)
   └─ 3-element real variable (id: 901…778)

julia> size(atom)
(1, 1)
Convex.entropy_elementwiseMethod
entropy_elementwise(x::Convex.AbstractExpr)

The hypograph of $-x \log x$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> entropy_elementwise(x)
entropy (concave; real)
└─ real variable (id: 172…395)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = entropy_elementwise(x)
entropy (concave; real)
└─ 3-element real variable (id: 140…126)

julia> size(atom)
(3, 1)
Convex.evaluateMethod
evaluate(x::AbstractVariable)

Returns the current value of x if assigned; errors otherwise.

Convex.fix!Method
fix!(x::AbstractVariable, v = value(x))

Fixes x to v. It is subsequently treated as a constant in future optimization problems. See also free!.

Convex.free!Method
free!(x::AbstractVariable)

Frees a previously fix!'d variable x, to treat it once again as a variable to optimize over.

Convex.geomeanMethod
geomean(x::Convex.AbstractExpr...)

The hypograph of the geometric mean $\sqrt[n]{x_1 \cdot x_2 \cdot \ldots x_n}$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> y = Variable();

julia> geomean(x, y)
geomean (concave; positive)
├─ real variable (id: 163…519)
└─ real variable (id: 107…393)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = Variable(3);

julia> atom = geomean(x, y)
geomean (concave; positive)
├─ 3-element real variable (id: 177…782)
└─ 3-element real variable (id: 307…913)

julia> size(atom)
(3, 1)
Convex.get_constraintsMethod
get_constraints(x::AbstractVariable)

Returns the current constraints carried by x.

Convex.hinge_lossMethod
hinge_loss(x::Convex.AbstractExpr)

The epigraph of $\max(1 - x, 0)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> hinge_loss(x)
max (convex; positive)
├─ + (affine; real)
│  ├─ [1;;]
│  └─ Convex.NegateAtom (affine; real)
│     └─ real variable (id: 129…000)
└─ [0;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = hinge_loss(x)
max (convex; positive)
├─ + (affine; real)
│  ├─ * (constant; positive)
│  │  ├─ [1;;]
│  │  └─ [1.0; 1.0; 1.0;;]
│  └─ Convex.NegateAtom (affine; real)
│     └─ 3-element real variable (id: 125…591)
└─ [0;;]

julia> size(atom)
(3, 1)
Convex.huberFunction
huber(x::Convex.AbstractExpr, M::Real = 1.0)

The epigraph of the Huber loss function:

\[\begin{cases} x^2 & |x| \le M \\ 2M|x| - M^2 & |x| > M \end{cases}\]

where $M \ge 1$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> huber(x, 2.5)
huber (convex; positive)
└─ real variable (id: 973…369)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = huber(x)
huber (convex; positive)
└─ 3-element real variable (id: 896…728)

julia> size(atom)
(3, 1)
Convex.inner_productMethod
inner_product(x::AbstractExpr, y::AbstractExpr)

The inner product $tr(x^\top y)$ where x and y are square matrices.

Examples

julia> x = Variable(2, 2);

julia> y = [1 3; 2 4];

julia> atom = inner_product(x, y)
real (affine; real)
└─ sum (affine; real)
   └─ diag (affine; real)
      └─ * (affine; real)
         ├─ …
         └─ …

julia> size(atom)
(1, 1)
Convex.invposMethod
invpos(x::Convex.AbstractExpr)

The epigraph of $\frac{1}{x}$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> invpos(x)
qol_elem (convex; positive)
├─ [1.0;;]
└─ real variable (id: 139…839)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = invpos(x)
qol_elem (convex; positive)
├─ [1.0; 1.0; 1.0;;]
└─ 3-element real variable (id: 133…285)

julia> size(atom)
(3, 1)
Convex.lieb_andoMethod
lieb_ando(
    A::Union{AbstractMatrix,Constant},
    B::Union{AbstractMatrix,Constant},
    K::Union{AbstractMatrix,Constant},
    t::Rational,
)

Returns LinearAlgebra.tr(K' * A^{1-t} * K * B^t) where A and B are positive semidefinite matrices and K is an arbitrary matrix (possibly rectangular).

lieb_ando(A, B, K, t) is concave in (A, B) for t in [0, 1], and convex in (A, B) for t in [-1, 0) or (1, 2]. K is a fixed matrix.

Seems numerically unstable when t is on the endpoints of these ranges.

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Examples

Note that lieb_ando is implemented as a subproblem, so the returned atom is a Convex.Problem object. The Problem atom can still be used as a regular 1x1 atom in other expressions.

julia> A = Semidefinite(2, 2);

julia> B = Semidefinite(3, 3);

julia> K = [1 2 3; 4 5 6];

julia> atom = lieb_ando(A, B, K, 1 // 2)
Problem statistics
  problem is DCP         : true
  number of variables    : 3 (49 scalar elements)
  number of constraints  : 4 (157 scalar elements)
  number of coefficients : 76
  number of atoms        : 26

Solution summary
  termination status : OPTIMIZE_NOT_CALLED
  primal status      : NO_SOLUTION
  dual status        : NO_SOLUTION

Expression graph
  maximize
   └─ real (affine; real)
      └─ sum (affine; real)
         └─ diag (affine; real)
            └─ …
  subject to
   ├─ GeometricMeanHypoConeSquare constraint (convex)
   │  └─ vcat (affine; real)
   │     ├─ reshape (affine; real)
   │     │  └─ …
   │     ├─ reshape (affine; real)
   │     │  └─ …
   │     └─ reshape (affine; real)
   │        └─ …
   ├─ PSD constraint (convex)
   │  └─ 6×6 real variable (id: 173…902)
   ├─ PSD constraint (convex)
   │  └─ 6×6 real variable (id: 173…902)
   ⋮


julia> size(atom)
(1, 1)
Convex.log_perspectiveMethod
log_perspective(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The hypograph the perspective of of the log function: $\sum y_i*\log \frac{x_i}{y_i}$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> y = Variable();

julia> log_perspective(x, y)
Convex.NegateAtom (concave; real)
└─ relative_entropy (convex; real)
   ├─ real variable (id: 136…971)
   └─ real variable (id: 131…344)

And to a matrix of expressions:

julia> x = Variable(3);

julia> y = Variable(3);

julia> atom = log_perspective(x, y)
Convex.NegateAtom (concave; real)
└─ relative_entropy (convex; real)
   ├─ 3-element real variable (id: 854…248)
   └─ 3-element real variable (id: 111…174)

julia> size(atom)
(1, 1)
Convex.logisticlossMethod
logisticloss(x::Convex.AbstractExpr)

Reformulation for epigraph of the logistic loss: $\sum_i \log(e^x_i + 1)$.

This reformulation uses logsumexp.

Examples

Applies to a single expression:

julia> x = Variable();

julia> logisticloss(x)
logsumexp (convex; real)
└─ vcat (affine; real)
   ├─ real variable (id: 444…892)
   └─ [0;;]

And to a matrix of expressions:

julia> x = Variable(3);

julia> atom = logisticloss(x)
+ (convex; real)
├─ logsumexp (convex; real)
│  └─ vcat (affine; real)
│     ├─ index (affine; real)
│     │  └─ …
│     └─ [0;;]
├─ logsumexp (convex; real)
│  └─ vcat (affine; real)
│     ├─ index (affine; real)
│     │  └─ …
│     └─ [0;;]
└─ logsumexp (convex; real)
   └─ vcat (affine; real)
      ├─ index (affine; real)
      │  └─ …
      └─ [0;;]

julia> size(atom)
(1, 1)
Convex.logsumexpMethod
logsumexp(x::Convex.AbstractExpr)

The epigraph of $\log\left(\sum_i e^{x_i}\right)$.

Examples

Applies to a single expression:

julia> x = Variable(2, 3);

julia> atom = logsumexp(x)
logsumexp (convex; real)
└─ 2×3 real variable (id: 121…604)

julia> size(atom)
(1, 1)

julia> atom = logsumexp(x; dims = 1)
logsumexp (convex; real)
└─ 2×3 real variable (id: 121…604)

julia> size(atom)
(1, 3)

julia> atom = logsumexp(x; dims = 2)
logsumexp (convex; real)
└─ 2×3 real variable (id: 121…604)

julia> size(atom)
(2, 1)
Convex.matrixfracMethod
matrixfrac(x::AbstractExpr, P::AbstractExpr)

The epigraph of $x^\top P^{-1} x$.

Examples

julia> x = Variable(2);

julia> P = Variable(2, 2);

julia> atom = matrixfrac(x, P)
matrixfrac (convex; positive)
├─ 2-element real variable (id: 139…388)
└─ 2×2 real variable (id: 126…414)

julia> size(atom)
(1, 1)
Convex.negMethod
neg(x::Convex.AbstractExpr)

The epigraph of $\max(-x, 0)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> neg(x)
max (convex; positive)
├─ Convex.NegateAtom (affine; real)
│  └─ real variable (id: 467…111)
└─ [0;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = neg(x)
max (convex; positive)
├─ Convex.NegateAtom (affine; real)
│  └─ 3-element real variable (id: 224…439)
└─ [0;;]

julia> size(atom)
(3, 1)
Convex.new_conic_form!Function
new_conic_form!(context::Context, a::AbstractExpr)

Create a new conic form for a and return it, assuming that no conic form for a has already been created, that is !haskey(context, a) as this is already checked in conic_form! which calls this function.

Convex.nuclearnormMethod
nuclearnorm(x::Convex.AbstractExpr)

The epigraph of the nuclear norm $||X||_*$, which is the sum of the singular values of $X$.

Examples

Applies to a real-valued matrix:

julia> x = Variable(2, 2);

julia> atom = nuclearnorm(x)
nuclearnorm (convex; positive)
└─ 2×2 real variable (id: 106…758)

julia> size(atom)
(1, 1)

julia> y = ComplexVariable(2, 2);

julia> atom = nuclearnorm(y)
nuclearnorm (convex; positive)
└─ 2×2 complex variable (id: 577…313)

julia> size(atom)
(1, 1)
Convex.partialtraceMethod
partialtrace(x, sys::Int, dims::Vector)

Returns the partial trace of x over the systh system, where dims is a vector of integers encoding the dimensions of each subsystem.

Convex.partialtransposeMethod
partialtranspose(x, sys::Int, dims::Vector)

Returns the partial transpose of x over the systh system, where dims is a vector of integers encoding the dimensions of each subsystem.

Convex.permutedims_matrixMethod
permutedims_matrix(dims, p)

Returns a matrix M so that for any vector v of length prod(dims), M*v == vec(permutedims(reshape(v, dims), p)).

Convex.posMethod
pos(x::Convex.AbstractExpr)

The epigraph of $\max(x, 0)$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> pos(x)
max (convex; positive)
├─ real variable (id: 467…111)
└─ [0;;]

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> atom = pos(x)
max (convex; positive)
├─ 3-element real variable (id: 154…809)
└─ [0;;]

julia> size(atom)
(3, 1)
Convex.print_tree_rstripMethod
print_tree_rstrip(io::IO, x)

Prints the results of TreePrint.print_tree(io, x) without the final newline. Used for show methods which invoke print_tree.

Convex.qol_elementwiseMethod
qol_elementwise(x::AbstractExpr, y::AbstractExpr)

The elementwise epigraph of $\frac{x^2}{y}$.

Examples

julia> x = Variable(3);

julia> y = Variable(3, Positive());

julia> atom = qol_elementwise(x, y)
qol_elem (convex; positive)
├─ 3-element real variable (id: 155…648)
└─ 3-element positive variable (id: 227…080)

julia> size(atom)
(3, 1)
Convex.quadformMethod
quadform(x::AbstractExpr, A::AbstractExpr; assume_psd=false)

Represents $x^\top A x$ where either:

  • x is a vector-valued variable and A is a positive semidefinite or negative semidefinite matrix (and in particular Hermitian or real symmetric). If assume_psd=true, then A will be assumed to be positive semidefinite. Otherwise, Convex._is_psd will be used to check if A is positive semidefinite or negative semidefinite.
  • or A is a matrix-valued variable and x is a vector.

Examples

julia> x = Variable(2);

julia> A = [1 0; 0 1]
2×2 Matrix{Int64}:
 1  0
 0  1

julia> atom = quadform(x, A)
* (convex; positive)
├─ [1;;]
└─ qol_elem (convex; positive)
   ├─ norm2 (convex; positive)
   │  └─ * (affine; real)
   │     ├─ …
   │     └─ …
   └─ [1.0;;]

julia> size(atom)
(1, 1)
julia> x = [1, 2]

julia> A = Variable(2, 2);

julia> atom = quadform(x, A)
* (affine; real)
├─ * (affine; real)
│  ├─ [1 2]
│  └─ 2×2 real variable (id: 111…794)
└─ [1; 2;;]

julia> size(atom)
(1, 1)
Convex.quadoverlinMethod
quadoverlin(x::AbstractExpr, y::AbstractExpr)

The epigraph of $\frac{||x||_2^2}{y}$.

Examples

julia> x = Variable(3);

julia> y = Variable(Positive());

julia> atom = quadoverlin(x, y)
qol (convex; positive)
├─ 3-element real variable (id: 868…883)
└─ positive variable (id: 991…712)

julia> size(atom)
(1, 1)
Convex.quantum_entropyFunction
quantum_entropy(X::AbstractExpr, m::Integer, k::Integer)

quantum_entropy returns -LinearAlgebra.tr(X*log(X)) where X is a positive semidefinite.

Note this function uses logarithm base e, not base 2, so return value is in units of nats, not bits.

Quantum entropy is concave. This function implements the semidefinite programming approximation given in the reference below. Parameters m and k control the accuracy of this approximation: m is the number of quadrature nodes to use and k the number of square-roots to take. See reference for more details.

The implementation uses the expression

\[H(X) = -tr(D_{op}(X||I))\]

where $D_{op}$ is the operator relative entropy:

\[D_{op}(X||Y) = X^{1/2}*logm(X^{1/2} Y^{-1} X^{1/2})*X^{1/2}\]

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Examples

Applies to a matrix:

julia> X = Variable(2, 2);

julia> atom = quantum_entropy(X)
quantum_entropy (concave; positive)
└─ 2×2 real variable (id: 700…694)

julia> size(atom)
(1, 1)
Convex.quantum_relative_entropyFunction
quantum_relative_entropy(
    A::AbstractExpr,
    B::AbstractExpr,
    m::Integer,
    k::Integer,
)

quantum_relative_entropy returns LinearAlgebra.tr(A*(log(A)-log(B))) where A and B are positive semidefinite matrices.

Note this function uses logarithm base e, not base 2, so return value is in units of nats, not bits.

Quantum relative entropy is convex (jointly) in (A, B). This function implements the semidefinite programming approximation given in the reference below. Parameters m and k control the accuracy of this approximation: m is the number of quadrature nodes to use and k the number of square-roots to take. See reference for more details.

Implementation uses the expression

\[D(A||B) = e'*D_{op} (A \otimes I || I \otimes B) )*e\]

where $D_{op}$ is the operator relative entropy and e = vec(Matrix(I, n, n)).

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Examples

julia> A = Variable(2, 2);

julia> B = Variable(2, 2);

julia> atom = quantum_relative_entropy(A, B)
quantum_relative_entropy (convex; positive)
├─ 2×2 real variable (id: 144…849)
└─ 2×2 real variable (id: 969…693)

julia> size(atom)
(1, 1)
Convex.rationalnormMethod
rationalnorm(x::AbstractExpr, k::Rational{Int})

The epigraph of ||x||_k.

Examples

Applies to a single matrix:

julia> x = Variable(2);

julia> atom = rationalnorm(x, 3 // 2)
rationalnorm (convex; positive)
└─ 2-element real variable (id: 182…293)

julia> size(atom)
(1, 1)
Convex.relative_entropyMethod
relative_entropy(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The epigraph of $\sum x_i*\log \frac{x_i}{y_i}$.

Examples

Applies to a single expression:

julia> x = Variable();

julia> y = Variable();

julia> relative_entropy(x, y)
relative_entropy (convex; real)
├─ real variable (id: 124…372)
└─ real variable (id: 409…346)

And element-wise to a matrix of expressions:

julia> x = Variable(3);

julia> y = Variable(3);

julia> atom = relative_entropy(x, y)
relative_entropy (convex; real)
├─ 3-element real variable (id: 906…671)
└─ 3-element real variable (id: 118…912)

julia> size(atom)
(1, 1)
Convex.rootdetMethod
Convex.rootdet(X::Convex.AbstractExpr)

The hypograph of $\det(X)^{\frac{1}{n}}$, where $n$ is the side-dimension of the square matrix $X$.

Examples

Applies to a single matrix expression:

julia> X = Variable(2, 2);

julia> atom = rootdet(X)
rootdet (concave; real)
└─ 2×2 real variable (id: 159…883)

julia> size(atom)
(1, 1)
Convex.set_value!Method
set_value!(x::AbstractVariable, v)

Sets the current value of x to v.

Convex.show_idMethod
show_id(io::IO, x::Union{AbstractVariable}; digits = 3)

Print a truncated version of the object's id.

Example

julia> x = Variable();

julia> Convex.show_id(stdout, x)
id: 163…906
Convex.sigmamaxMethod
sigmamax(x::Convex.AbstractExpr)

The epigraph of the spectral norm $||X||_2$, which is the maximum of the singular values of $X$.

Examples

Applies to a real- or complex-valued matrix:

julia> x = Variable(2, 2);

julia> atom = sigmamax(x)
opnorm (convex; positive)
└─ 2×2 real variable (id: 106…758)

julia> size(atom)
(1, 1)

julia> y = ComplexVariable(2, 2);

julia> atom = sigmamax(y)
opnorm (convex; positive)
└─ 2×2 complex variable (id: 577…313)

julia> size(atom)
(1, 1)
Convex.sign!Method
sign!(x::AbstractVariable, s::Sign)

Sets the current sign of x to s.

Convex.solve!Method
solve!(
    problem::Problem,
    optimizer_factory;
    silent::Bool = false,
    warmstart::Bool = false,
)

Solves the problem, populating problem.optval with the optimal value, as well as the values of the variables (accessed by evaluate) and constraint duals (accessed by cons.dual), where applicable. Returns the input problem.

Optional keyword arguments:

  • silent: whether or not Convex and the solver should be silent (and not emit output or logs) during the solution process. When silent=false, Convex will print the formulation time, and warn if the problem was not solved optimally.
  • warmstart (default: false): whether the solver should start the optimization from a previous optimal value (according to the current primal value of the variables in the problem, which can be set by set_value!.
Convex.squareMethod
square(x::AbstractExpr)

The epigraph of $x^2$.

Examples

Applies elementwise to a matrix

julia> x = Variable(3);

julia> atom = square(x)
qol_elem (convex; positive)
├─ 3-element real variable (id: 438…681)
└─ [1.0; 1.0; 1.0;;]

julia> size(atom)
(3, 1)
Convex.sumlargestMethod
sumlargest(x::Convex.AbstractExpr, k::Int)

Sum the k largest values of x.

Examples

Applies to a matrix:

julia> x = Variable(3, 3);

julia> atom = sumlargest(x, 2)
sumlargest (convex; real)
├─ 3×3 real variable (id: 833…482)
└─ [2;;]

julia> size(atom)
(1, 1)
Convex.sumlargesteigsMethod
sumlargesteigs(x::Convex.AbstractExpr, k::Int)

Sum the k largest eigen values of x.

Examples

Applies to a matrix:

julia> x = Variable(3, 3);

julia> atom = sumlargesteigs(x, 2)
sumlargesteigs (convex; real)
├─ 3×3 real variable (id: 833…482)
└─ [2;;]

julia> size(atom)
(1, 1)
Convex.sumsmallestMethod
sumsmallest(x::Convex.AbstractExpr, k::Int)

Sum the k smallest values of x.

Examples

Applies to a matrix:

julia> x = Variable(3, 3);

julia> atom = sumsmallest(x, 2)
Convex.NegateAtom (concave; real)
└─ sumlargest (convex; real)
   └─ Convex.NegateAtom (affine; real)
      └─ 3×3 real variable (id: 723…082)

julia> size(atom)
(1, 1)
Convex.sumsquaresMethod
sumsquares(x::AbstractExpr)

The epigraph of $||x||_2^2$.

Examples

Applies to a single matrix

julia> x = Variable(3);

julia> atom = sumsquares(x)
qol (convex; positive)
├─ 3-element real variable (id: 125…181)
└─ [1;;]

julia> size(atom)
(1, 1)
Convex.trace_logmFunction
trace_logm(
    X::Convex.AbstractExpr,
    C::AbstractMatrix,
    m::Integer = 3,
    k::Integer = 3,
)

trace_logm(X, C) returns LinearAlgebra.tr(C*logm(X)) where X and C are positive definite matrices and C is constant.

trace_logm is concave in X.

This function implements the semidefinite programming approximation given in the reference below. Parameters m and k control the accuracy of the approximation: m is the number of quadrature nodes to use and k is the number of square-roots to take. See reference for more details.

Implementation uses the expression

\[tr(C \times logm(X)) = -tr(C \times D_{op}(I||X))\]

where D_{op} is the operator relative entropy:

\[D_{op}(X||Y) = X^{1/2}*logm(X^{1/2} Y^{-1} X^{1/2})*X^{1/2}\]

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Examples

Applies to a matrix:

julia> X = Variable(2, 2);

julia> C = [1 0; 0 1];

julia> atom = trace_logm(X, C)
trace_logm (concave; real)
└─ 2×2 real variable (id: 608…362)

julia> size(atom)
(1, 1)
Convex.trace_mpowerMethod
trace_mpower(A::Convex.AbstractExpr, t::Rational, C::AbstractMatrix)

trace_mpower(A, t, C) returns LinearAlgebra.tr(C*A^t) where A and C are positive definite matrices, C is constant and t is a rational in [-1, 2].

When t is in [0, 1], trace_mpower(A, t, C) is concave in A (for fixed positive semidefinite matrix C) and convex for t in [-1, 0) or (1, 2].

Reference

Ported from CVXQUAD which is based on the paper: "Lieb's concavity theorem, matrix geometric means and semidefinite optimization" by Hamza Fawzi and James Saunderson (arXiv:1512.03401)

Examples

Applies to a matrix:

julia> A = Variable(2, 2);

julia> C = [1 0; 0 1];

julia> atom = trace_mpower(A, 1 // 2, C)
trace_mpower (concave; real)
└─ 2×2 real variable (id: 150…626)

julia> size(atom)
(1, 1)
Convex.vexity!Method
vexity!(x::AbstractVariable, v::Vexity)

Sets the current vexity of x to v. Should only be called by fix! and free!.

Convex.vexityMethod
vexity(x::AbstractVariable)

Returns the current vexity of x.

Convex.write_to_fileMethod
write_to_file(problem::Problem{Float64}, filename::String)

Write the current problem to the file at filename.

The file format is inferred from the filename extension. Supported file types depend on the model type.

Currently, Float64 is the only supported coefficient type. This may be relaxed in future if file formats support other types.

LinearAlgebra.diagFunction
LinearAlgebra.diag(x::Convex.AbstractExpr, k::Int = 0)

Return the k-th diagonnal of the matrix X as a column vector.

Examples

Applies to a single square matrix:

julia> x = Variable(2, 2);

julia> atom = diag(x, 0)
diag (affine; real)
└─ 2×2 real variable (id: 724…318)

julia> size(atom)
(2, 1)

julia> atom = diag(x, 1)
diag (affine; real)
└─ 2×2 real variable (id: 147…856)

julia> size(atom)
(1, 1)
LinearAlgebra.diagmMethod
LinearAlgebra.diagm(x::Convex.AbstractExpr)

Create a diagonal matrix out of the vector x.

Examples

julia> x = Variable(2);

julia> atom = diagm(x)
diagm (affine; real)
└─ 2-element real variable (id: 541…968)

julia> size(atom)
(2, 2)
LinearAlgebra.dotMethod
LinearAlgebra.dot(x::Convex.AbstractExpr, y::Convex.AbstractExpr)

The dot product $x \cdot y$. If x is complex, it is conjugated.

Examples

julia> x = ComplexVariable(2);

julia> y = [1, 2];

julia> atom = dot(x, y)
sum (affine; complex)
└─ .* (affine; complex)
   ├─ conj (affine; complex)
   │  └─ 2-element complex variable (id: 133…443)
   └─ [1; 2;;]

julia> size(atom)
(1, 1)
LinearAlgebra.eigmaxMethod
LinearAlgebra.eigmax(X::Convex.AbstractExpr)

The epigraph of the maximum eigen value of $X$.

Examples

Applies to a single square matrix:

julia> x = Variable(2, 2);

julia> atom = eigmax(x)
eigmin (convex; real)
└─ 2×2 real variable (id: 428…695)

julia> size(atom)
(1, 1)
LinearAlgebra.eigminMethod
LinearAlgebra.eigmin(X::Convex.AbstractExpr)

The hypograph of the minimum eigen value of $X$.

Examples

Applies to a single square matrix:

julia> x = Variable(2, 2);

julia> atom = eigmin(x)
eigmin (concave; real)
└─ 2×2 real variable (id: 428…695)

julia> size(atom)
(1, 1)
LinearAlgebra.logdetMethod
LinearAlgebra.logdet(X::Convex.AbstractExpr)

The hypograph of $\log(\det(X))$.

Examples

Applies to a single matrix expression:

julia> X = Variable(2, 2);

julia> atom = logdet(X)
logdet (concave; real)
└─ 2×2 real variable (id: 159…883)

julia> size(atom)
(1, 1)
LinearAlgebra.normFunction
norm(x::AbstractExpr, p::Real = 2)

Computes the p-norm ‖x‖ₚ = (∑ᵢ |xᵢ|^p)^(1/p) of a vector expression x.

Matrices are vectorized (i.e., norm(x) is the same as norm(vec(x)).)

The return value depends on the value of p. Specialized cases are used for p = 1, p = 2, and p = Inf.

Examples

julia> x = Variable(2);

julia> atom = norm(x, 1)
sum (convex; positive)
└─ abs (convex; positive)
   └─ 2-element real variable (id: 779…899)

julia> size(atom)
(1, 1)

julia> norm(x, 2)
norm2 (convex; positive)
└─ 2-element real variable (id: 779…899)

julia> norm(x, Inf)
maximum (convex; positive)
└─ abs (convex; positive)
   └─ 2-element real variable (id: 779…899)

julia> norm(x, 3 // 2)
rationalnorm (convex; positive)
└─ 2-element real variable (id: 779…899)
LinearAlgebra.norm2Method
LinearAlgebra.norm2(x::Convex.AbstractExpr)

The epigraph of the 2-norm $||x||_2$.

Examples

Applies to a matrix of expressions:

julia> x = Variable(3);

julia> atom = norm2(x)
norm2 (convex; positive)
└─ 3-element real variable (id: 162…975)

julia> size(atom)
(3, 1)

And to a complex:

julia> y = ComplexVariable(3);

julia> atom = norm2(y)
norm2 (convex; positive)
└─ vcat (affine; real)
   ├─ real (affine; real)
   │  └─ 3-element complex variable (id: 120…942)
   └─ imag (affine; real)
      └─ 3-element complex variable (id: 120…942)

julia> size(atom)
(1, 1)
LinearAlgebra.opnormFunction
LinearAlgebra.opnorm(x::Convex.AbstractExpr, p::Real = 2)

The epigraph of the matrix norm $||X||_p$.

Examples

Applies to a real- or complex-valued matrix:

julia> x = Variable(2, 2);

julia> atom = LinearAlgebra.opnorm(x, 1)
maximum (convex; positive)
└─ * (convex; positive)
   ├─ [1.0 1.0]
   └─ abs (convex; positive)
      └─ 2×2 real variable (id: 106…758)

julia> atom = LinearAlgebra.opnorm(x, 2)
opnorm (convex; positive)
└─ 2×2 real variable (id: 106…758)

julia> atom = LinearAlgebra.opnorm(x, Inf)
maximum (convex; positive)
└─ * (convex; positive)
    ├─ abs (convex; positive)
    │  └─ 2×2 real variable (id: 106…758)
    └─ [1.0; 1.0;;]


julia> y = ComplexVariable(2, 2);

julia> atom = maximum (convex; positive)
└─ * (convex; positive)
   ├─ abs (convex; positive)
   │  └─ 2×2 complex variable (id: 116…943)
   └─ [1.0; 1.0;;]

julia> size(atom)
(1, 1)
LinearAlgebra.trMethod
LinearAlgebra.tr(x::AbstractExpr)

The trace of the matrix x.

Examples

julia> x = Variable(2, 2);

julia> atom = tr(x)
sum (affine; real)
└─ diag (affine; real)
   └─ 2×2 real variable (id: 844…180)

julia> size(atom)
(1, 1)
Convex.TreePrint.print_treeFunction
print_tree(
    printnode::Function,
    io::IO,
    tree,
    maxdepth = 5,
    maxwidth = Inf;
    depth = 0,
    active_levels = Int[],
    charset = TreeCharSet(),
    withinds = false,
    inds = [],
    from = nothing,
    to = nothing,
    roottree = tree,
)

Usage

Prints an ASCII formatted representation of the tree to the given io object. By default all children will be printed up to a maximum level of 5, though this valud can be overriden by the maxdepth parameter. The charset to use in printing can be customized using the charset keyword argument.

Examples

julia> print_tree(STDOUT,Dict("a"=>"b","b"=>['c','d']))
Dict{String,Any}("b"=>['c','d'],"a"=>"b")
├─ b
│  ├─ c
│  └─ d
└─ a
   └─ b

julia> print_tree(STDOUT,Dict("a"=>"b","b"=>['c','d']);
        charset = TreeCharSet('+','\','|',"--"))
Dict{String,Any}("b"=>['c','d'],"a"=>"b")
+-- b
|   +-- c
|   \-- d
\-- a
   \-- b