Second-Order Cone Program

Author

Anqi Fu and Balasubramanian Narasimhan

Introduction

A second-order cone program (SOCP) is an optimization problem of the form

minimizefTxsubject toAix+bi2ciTx+di,i=1,,mFx=g,

where xRn is the optimization variable and fRn, AiRni×n, biRni, ciRn, diR, FRp×n, and gRp are problem data.

An example of an SOCP is the robust linear program

minimizecTxsubject to(ai+ui)Txbi for all ui21,i=1,,m,

where the problem data ai are known within an 2-norm ball of radius one. The robust linear program can be rewritten as the SOCP

minimizecTxsubject toaiTx+x2bi,i=1,,m,

When we solve a SOCP, in addition to a solution x, we obtain a dual solution λi corresponding to each second-order cone constraint. A non-zero λi indicates that the constraint Aix+bi2ciTx+di holds with equality for x and suggests that changing di would change the optimal value.

Example

In the following code, we solve a SOCP with CVXR. The second-order cone constraint Ax+b2t is expressed as norm2(A %*% x + b) <= t in CVXR.

## Problem dimensions
set.seed(2)
m <- 3    # number of SOC constraints
n <- 10   # number of variables
p <- 5    # number of equality constraints
n_i <- 5  # rows per SOC constraint

## A feasible point used to construct the problem data
x0 <- rnorm(n)
f <- rnorm(n)

## Generate random data for each SOC constraint
soc_data <- lapply(1:m, function(i) {
    Ai <- matrix(rnorm(n_i * n), nrow = n_i)
    bi <- rnorm(n_i)
    ci <- rnorm(n)
    ## Choose d_i so that x0 is feasible: ||A_i x0 + b_i||_2 <= c_i'x0 + d_i
    di <- norm(Ai %*% x0 + bi, type = "2") - sum(ci * x0)
    list(A = Ai, b = bi, c = ci, d = di)
})

## Equality constraint: F x = g with g = F x0 so x0 is feasible
F_mat <- matrix(rnorm(p * n), nrow = p)
g <- F_mat %*% x0

## Define and solve the CVXR problem
x <- Variable(n)
soc_constraints <- lapply(soc_data, function(s) {
    norm2(s$A %*% x + s$b) <= sum(s$c * x) + s$d
})
Warning: `norm2()` is deprecated. Use `p_norm(x, 2)` instead.
This warning is displayed once per session.
prob <- Problem(Minimize(t(f) %*% x),
                constraints = c(soc_constraints, list(F_mat %*% x == g)))
result <- psolve(prob)
check_solver_status(prob)
## Print result
cat(sprintf("The optimal value is %f\n", result))
cat("A solution x is\n")
print(value(x))
for (i in 1:m) {
    cat(sprintf("SOC constraint %d dual variable solution\n", i))
    print(dual_value(soc_constraints[[i]]))
}
The optimal value is -120.464973
A solution x is
            [,1]
 [1,] -31.037523
 [2,]  28.606756
 [3,] -22.197659
 [4,]   2.210524
 [5,] -30.300881
 [6,]   2.724953
 [7,]  10.617886
 [8,]  82.395792
 [9,] -87.680423
[10,] -11.980917
SOC constraint 1 dual variable solution
[1] 2.90497
SOC constraint 2 dual variable solution
[1] 11.61755
SOC constraint 3 dual variable solution
[1] 2.153939e-09

Session Info

R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.3.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/Los_Angeles
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] CVXR_1.8.1

loaded via a namespace (and not attached):
 [1] slam_0.1-55       cli_3.6.5         knitr_1.51        ECOSolveR_0.6.1  
 [5] rlang_1.1.7       xfun_0.56         clarabel_0.11.2   otel_0.2.0       
 [9] gurobi_13.0-1     Rglpk_0.6-5.1     highs_1.12.0-3    cccp_0.3-3       
[13] scs_3.2.7         S7_0.2.1          jsonlite_2.0.0    Rcplex_0.3-8     
[17] backports_1.5.0   rprojroot_2.1.1   htmltools_0.5.9   Rmosek_11.1.1    
[21] gmp_0.7-5.1       piqp_0.6.2        rmarkdown_2.30    grid_4.5.2       
[25] evaluate_1.0.5    fastmap_1.2.0     yaml_2.3.12       compiler_4.5.2   
[29] codetools_0.2-20  htmlwidgets_1.6.4 Rcpp_1.1.1        here_1.0.2       
[33] osqp_1.0.0        lattice_0.22-9    digest_0.6.39     checkmate_2.3.4  
[37] Matrix_1.7-4      tools_4.5.2      

References