SCS.jl is a wrapper for the SCS splitting cone solver.
SCS can solve linear programs, second-order cone programs, semidefinite programs, exponential cone programs, and power cone programs.
This wrapper is maintained by the JuMP community and is not a project of the SCS developers.
If you need help, please ask a question on the JuMP community forum.
If you have a reproducible example of a bug, please open a GitHub issue.
SCS.jl is licensed under the MIT License.
The underlying solver, cvxgrp/scs, is licensed under the MIT License.
Install SCS.jl using the Julia package manager:
import Pkg
Pkg.add("SCS")In addition to installing the SCS.jl package, this will also download and
install the SCS binaries. (You do not need to install SCS separately.)
To use a custom binary, read the Custom solver binaries section of the JuMP documentation.
This example shows how we can model a simple knapsack problem with Convex and use SCS to solve it.
using Convex, SCS
items = [:Gold, :Silver, :Bronze]
values = [5.0, 3.0, 1.0]
weights = [2.0, 1.5, 0.3]
# Define a variable of size 3, each index representing an item
x = Variable(3)
p = maximize(x' * values, 0 <= x, x <= 1, x' * weights <= 3)
solve!(p, SCS.Optimizer)
println([items x.value])
# [:Gold 0.9999971880377178
# :Silver 0.46667637765641057
# :Bronze 0.9999998036351865]This example shows how we can model a simple knapsack problem with JuMP and use SCS to solve it.
using JuMP, SCS
items = [:Gold, :Silver, :Bronze]
values = Dict(:Gold => 5.0, :Silver => 3.0, :Bronze => 1.0)
weight = Dict(:Gold => 2.0, :Silver => 1.5, :Bronze => 0.3)
model = Model(SCS.Optimizer)
@variable(model, 0 <= take[items] <= 1) # Define a variable for each item
@objective(model, Max, sum(values[item] * take[item] for item in items))
@constraint(model, sum(weight[item] * take[item] for item in items) <= 3)
optimize!(model)
println(value.(take))
# 1-dimensional DenseAxisArray{Float64,1,...} with index sets:
# Dimension 1, Symbol[:Gold, :Silver, :Bronze]
# And data, a 3-element Array{Float64,1}:
# 1.0000002002226671
# 0.4666659513182934
# 1.0000007732744878The SCS optimizer supports the following constraints and attributes.
List of supported objective functions:
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}}
List of supported variable types:
List of supported constraint types:
MOI.VectorAffineFunction{Float64}inMOI.DualExponentialConeMOI.VectorAffineFunction{Float64}inMOI.DualPowerCone{Float64}MOI.VectorAffineFunction{Float64}inMOI.ExponentialConeMOI.VectorAffineFunction{Float64}inMOI.NonnegativesMOI.VectorAffineFunction{Float64}inMOI.PowerCone{Float64}MOI.VectorAffineFunction{Float64}inMOI.SecondOrderConeMOI.VectorAffineFunction{Float64}inMOI.ZerosMOI.VectorAffineFunction{Float64}inSCS.ScaledComplexPSDConeMOI.VectorAffineFunction{Float64}inSCS.ScaledPSDCone
List of supported model attributes:
All SCS solver options can be set through Convex.jl or MathOptInterface.jl.
For example:
model = Model(optimizer_with_attributes(SCS.Optimizer, "max_iters" => 10))
# via MathOptInterface:
optimizer = SCS.Optimizer()
MOI.set(optimizer, MOI.RawOptimizerAttribute("max_iters"), 10)
MOI.set(optimizer, MOI.RawOptimizerAttribute("verbose"), 0)Common options are:
max_iters: the maximum number of iterations to takeverbose: turn printing on (1) or off (0) See theglbopts.hheader for other options.
SCS uses a linear solver internally, see
this section
of SCS documentation. SCS.jl ships with the following linear solvers:
SCS.DirectSolver(sparse direct, the default)SCS.IndirectSolver(sparse indirect, by conjugate gradient)
To select the linear solver, set the linear_solver option, or pass the solver
as the first argument when using scs_solve directly (see the low-level wrapper
section below). For example:
using JuMP, SCS
model = Model(SCS.Optimizer)
set_attribute(model, "linear_solver", SCS.IndirectSolver)SCS.jl v2.0 introduced a breaking change. You now need to use SCS_MKL_jll
instead of MKL_jll.
To enable the MKL Pardiso (direct sparse) solver one needs to install and load
SCS_MKL_jll.
julia> import Pkg; Pkg.add("SCS_MKL_jll");
julia> using SCS, SCS_MKL_jll
julia> using SCS
julia> SCS.is_available(SCS.MKLDirectSolver)
trueThe MKLDirectSolver is available on Linux x86_64 platform only.
SCS.jl v2.0 introduced a breaking change. You now need to use SCS_GPU_jll
instead of CUDA_jll.
To enable the indirect linear solver on GPU one needs to install and load
SCS_GPU_jll.
julia> import Pkg; Pkg.add("SCS_GPU_jll");
julia> using SCS, SCS_GPU_jll
julia> SCS.is_available(SCS.GpuIndirectSolver)
trueThe GpuIndirectSolver is available on Linux x86_64 platform only.
With Julia v1.10 or later, SCS is compiled with
libblastrampoline
(LBT), a library that can change between BLAS and LAPACK backends at runtime.
The default BLAS and LAPACK backend is OpenBLAS,
and we rely on the Julia artifact OpenBLAS32_jll.jl if no backend is loaded
before using SCS.
Using LBT, we can also switch dynamically to other BLAS backends such as Intel MKL, BLIS, and Apple Accelerate. Because SCS relies heavily on BLAS and LAPACK routines, using an optimized backend for a particular platform can improve the performance.
If you have MKL.jl installed,
switch to MKL by adding using MKL to your code:
using MKL
using SCSIf you are using macOS ≥ v13.4 and you have AppleAccelerate.jl installed, add using AppleAccelerate to your code:
using AppleAccelerate
using SCSSCS.jl provides a low-level interface to solve a problem directly, without interfacing through MathOptInterface.
This is an advanced interface with a risk of incorrect usage. For new users, we recommend that you use the JuMP or Convex interfaces instead.
SCS solves a problem of the form:
minimize 1/2 * x' * P * x + c' * x
subject to A * x + s = b
s in K
where K is a product cone of:
- zero cone
- positive orthant
{ x | x ≥ 0 } - box cone
{ (t,x) | t*l ≤ x ≤ t*u } - second-order cone (SOC)
{ (t,x) | ||x||_2 ≤ t } - positive semi-definite (PSD) cone
{ X ∈ ℝⁿˣⁿ | X is psd } - complex positive semi-definite cone
{ X ∈ ℂⁿˣⁿ | X is psd } - exponential cone
{ (x,y,z) | y e^(x/y) ≤ z, y > 0 } - power cone
{ (x,y,z) | x^a * y^(1-a) ≥ |z|, x ≥ 0, y ≥ 0 } - dual power cone
{ (u,v,w) | (u/a)^a * (v/(1-a))^(1-a) ≥ |w|, u ≥ 0, v ≥ 0 }.
To solve this problem with SCS, call SCS.scs_solve; see the docstring for
details.