n <- 5 # number of transmitters and receivers
sigma <- rep(0.5, n) # noise power at the receiver i
p_min <- rep(0.1, n) # minimum power at the transmitter i
p_max <- rep(5, n) # maximum power at the transmitter i
sinr_min <- 0.2 # threshold SINR for each receiver
# Path gain matrix
G <- matrix(
c(1.0, 0.1, 0.2, 0.1, 0.05,
0.1, 1.0, 0.1, 0.1, 0.05,
0.2, 0.1, 1.0, 0.2, 0.2,
0.1, 0.1, 0.2, 1.0, 0.1,
0.05, 0.05, 0.2, 0.1, 1.0),
nrow = 5, ncol = 5, byrow = TRUE
)Power Control
Introduction
This example is adapted from Boyd, Kim, Vandenberghe, and Hassibi, “A Tutorial on Geometric Programming.”
The problem data is adapted from the corresponding example in CVX’s example library (Almir Mutapcic).
This example formulates and solves a power control problem for communication systems, in which the goal is to minimize the total transmitter power across
The power received from transmitter
The transmitters and receivers are constrained to have a minimum SINR
Problem Data
Problem Formulation
p <- Variable(n, pos = TRUE)
objective <- Minimize(sum_entries(p))
## For each receiver, compute interference-plus-noise and inverse SINR
inverse_sinr <- lapply(1:n, function(i) {
## Interference from all other transmitters
others <- setdiff(1:n, i)
interf <- Reduce(`+`, lapply(others, function(k) G[i, k] * p[k]))
S_i <- sigma[i] + interf
## Inverse SINR = (noise + interference) / signal
S_i / (G[i, i] * p[i])
})
sinr_constraints <- lapply(inverse_sinr, function(inv) inv <= 1 / sinr_min)
constraints <- c(list(p >= p_min, p <= p_max), sinr_constraints)
problem <- Problem(objective, constraints)
cat("Is problem DGP?", is_dgp(problem), "\n")Is problem DGP? TRUE
Solution
result <- psolve(problem, gp = TRUE)
check_solver_status(problem)
cat("Optimal total power:", result, "\n")
cat("Optimal power levels:", value(p), "\n")Optimal total power: 0.5534431
Optimal power levels: 0.1100843 0.1078223 0.1153666 0.1111531 0.1090168
We can verify that all the SINR constraints are active at the optimal solution. The inverse SINR values should all be equal to
for (i in 1:n) {
cat("Inverse SINR for receiver", i, ":", value(inverse_sinr[[i]]), "\n")
}Inverse SINR for receiver 1 : 5
Inverse SINR for receiver 2 : 5
Inverse SINR for receiver 3 : 5
Inverse SINR for receiver 4 : 5
Inverse SINR for receiver 5 : 5
Session Info
R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.3
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 datasets utils methods base
other attached packages:
[1] CVXR_1.8.0.9207
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 backports_1.5.0
[17] Rcplex_0.3-8 Rmosek_11.1.1 rprojroot_2.1.1 htmltools_0.5.9
[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
- Boyd, S., Kim, S.-J., Vandenberghe, L., Hassibi, A. (2007). A Tutorial on Geometric Programming. Optimization and Engineering, 8(1), 67–127.