Fractional Optimization

Author

CVXPY Developers and Balasubramanian Narasimhan

Introduction

This example shows how to solve a simple concave fractional problem, in which the objective is to maximize the ratio of a nonnegative concave function and a positive convex function. Concave fractional problems are quasiconvex programs (QCPs). They can be specified using disciplined quasiconvex programming (DQCP), and hence can be solved using CVXR.

Problem Formulation

Our goal is to maximize the function

xexp(x).

This function is not concave, but it is quasiconcave, as can be seen by inspecting its graph.

x_vals <- seq(0, 10, length.out = 200)
y_vals <- sqrt(x_vals) / exp(x_vals)
ggplot(data.frame(x = x_vals, y = y_vals), aes(x, y)) +
    geom_line(color = "blue") +
    labs(x = "x", y = expression(sqrt(x) / exp(x)),
         title = "Concave Fractional Function") +
    theme_minimal()

Solving with DQCP

The below code specifies and solves the QCP using DQCP. The concave fractional function is DQCP-compliant because the ratio atom is quasiconcave (actually quasilinear), increasing in the numerator when the denominator is positive, and decreasing in the denominator when the numerator is nonnegative.

x <- Variable()
concave_fractional_fn <- sqrt(x) / exp(x)
problem <- Problem(Maximize(concave_fractional_fn))
cat("Is DQCP?", is_dqcp(problem), "\n")
result <- psolve(problem, qcp = TRUE)
check_solver_status(problem)
cat("Optimal value:", result, "\n")
cat("x:", value(x), "\n")
Is DQCP? TRUE 
Optimal value: 0.4288819 
x: 0.5001326 

The optimal value of x is approximately 0.5, which corresponds to the peak of the function x/exp(x). We can verify this analytically: setting the derivative to zero,

ddx(xexp(x))=12xexp(x)xexp(x)1=12x2xexp(x)=0,

gives x=1/2.

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] ggplot2_4.0.2   CVXR_1.8.0.9207

loaded via a namespace (and not attached):
 [1] gmp_0.7-5.1        generics_0.1.4     clarabel_0.11.2    slam_0.1-55       
 [5] lattice_0.22-9     digest_0.6.39      magrittr_2.0.4     evaluate_1.0.5    
 [9] grid_4.5.2         RColorBrewer_1.1-3 fastmap_1.2.0      rprojroot_2.1.1   
[13] jsonlite_2.0.0     Matrix_1.7-4       ECOSolveR_0.6.1    backports_1.5.0   
[17] scs_3.2.7          Rmosek_11.1.1      scales_1.4.0       codetools_0.2-20  
[21] cli_3.6.5          rlang_1.1.7        Rglpk_0.6-5.1      withr_3.0.2       
[25] yaml_2.3.12        otel_0.2.0         tools_4.5.2        osqp_1.0.0        
[29] Rcplex_0.3-8       checkmate_2.3.4    dplyr_1.2.0        here_1.0.2        
[33] gurobi_13.0-1      vctrs_0.7.1        R6_2.6.1           lifecycle_1.0.5   
[37] htmlwidgets_1.6.4  pkgconfig_2.0.3    cccp_0.3-3         pillar_1.11.1     
[41] gtable_0.3.6       glue_1.8.0         Rcpp_1.1.1         xfun_0.56         
[45] tibble_3.3.1       tidyselect_1.2.1   knitr_1.51         dichromat_2.0-0.1 
[49] highs_1.12.0-3     farver_2.1.2       htmltools_0.5.9    rmarkdown_2.30    
[53] labeling_0.4.3     piqp_0.6.2         compiler_4.5.2     S7_0.2.1          

References

  • Agrawal, A., Boyd, S. (2020). Disciplined Quasiconvex Programming. Optimization Letters, 14, 1643–1657.