From 96715f487898ae4628015bfe664d5ed29a92824c Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Mon, 2 Oct 2023 17:06:32 -0700 Subject: [PATCH 1/5] Updated to OSQP release 0.6.3 See NEWS for a detailed list of fixes. --- .Rbuildignore | 3 + .travis.yml | 46 --------------- DESCRIPTION | 11 ++-- NEWS.md | 7 +++ R/osqp.R | 28 +++++---- R/params.R | 42 +++++--------- R/sparse.R | 57 +++++++++++++++++++ README.md | 6 +- configure | 2 +- .../make_fixes.R | 46 ++++++++------- man/osqp.Rd | 7 +-- man/osqpSettings.Rd | 5 +- src/Makevars | 2 +- src/Makevars.win | 2 +- src/osqp_solve_interface.cpp | 6 +- src/osqp_sources | 2 +- tests/testthat/test-params.R | 37 ++++++++++++ 17 files changed, 185 insertions(+), 124 deletions(-) delete mode 100644 .travis.yml create mode 100644 R/sparse.R rename inst/{26ce409b_fixes => 58f00bd_fixes}/make_fixes.R (57%) create mode 100644 tests/testthat/test-params.R diff --git a/.Rbuildignore b/.Rbuildignore index 57b804d..4cc0032 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -23,3 +23,6 @@ libosqp.a ^cran-comments\.md$ ^CRAN-RELEASE$ ^\.github$ +.github +src/osqp_sources/CITATION.cff +src/osqp_sources/docs \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7e729e2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -language: r - -r: - - release - - oldrel - -# Avoid using packages in the cache -# cache: packages - -os: - - linux - -sudo: required - -#fussy building for CRAN compatibility -warnings_are_errors: true -r_check_args: --as-cran - -r_binary_packages: - - Rcpp - - R6 - -r_packages: - - Matrix - - methods - -# dump the R install check log -after_script: cat ${RCHECK_DIR}/00install.out - -matrix: - include: - - os: osx - r: release - disable_homebrew: true - - os: osx - r: release - disable_homebrew: false - - os: osx - r: oldrel - disable_homebrew: true - - os: osx - r: oldrel - disable_homebrew: false - allow_failures: - - r: oldrel - os: linux diff --git a/DESCRIPTION b/DESCRIPTION index 21af430..872e177 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: osqp Title: Quadratic Programming Solver using the 'OSQP' Library -Version: 0.6.0.8 -Date: 2023-01-30 +Version: 0.6.3 +Date: 2023-10-02 Authors@R: c( person("Bartolomeo", "Stellato", role = c("aut", "ctb", "cph"), email = "bartolomeo.stellato@gmail.com"), @@ -16,10 +16,11 @@ Copyright: file COPYRIGHT Description: Provides bindings to the 'OSQP' solver. The 'OSQP' solver is a numerical optimization package or solving convex quadratic programs written in 'C' and based on the alternating direction method of multipliers. See for details. License: Apache License 2.0 | file LICENSE SystemRequirements: C++17 -Imports: Rcpp (>= 0.12.14), methods, Matrix, R6 +Imports: Rcpp (>= 0.12.14), methods, Matrix (>= 1.6.1), R6 LinkingTo: Rcpp -RoxygenNote: 7.2.1 -Collate: 'RcppExports.R' 'osqp-package.R' 'solve.R' 'osqp.R' 'params.R' +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 +Collate: 'RcppExports.R' 'osqp-package.R' 'sparse.R' 'solve.R' 'osqp.R' 'params.R' NeedsCompilation: yes Suggests: testthat Encoding: UTF-8 diff --git a/NEWS.md b/NEWS.md index af4c834..c1fbe10 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# Version 0.6.3 + +* Sync up to version [0.6.3 of OSQP release](https://github.com/osqp/osqp/releases/tag/v0.6.3) +* Fix `params.R` ([issue #18](https://github.com/osqp/osqp-r/issues/18)) +* Added `time-limit` settings parameter per [PG's code](https://github.com/osqp/osqp-r/pull/24) +* Added check for lower bounds not exceeding upper bounds ([issue 29](https://github.com/osqp/osqp-r/issues/29)) + # Version 0.6.0.8 * Fix prototype of `main` in `qdldl_sources/examplaes/example.c` diff --git a/R/osqp.R b/R/osqp.R index ed0c9fe..715ba1c 100644 --- a/R/osqp.R +++ b/R/osqp.R @@ -5,7 +5,7 @@ #' @importFrom Matrix triu #' @importFrom methods as #' @importFrom R6 R6Class -#' @param P,A sparse matrices of class dgCMatrix or coercible into such, with P positive semidefinite. +#' @param P,A sparse matrices of class dgCMatrix or coercible into such, with P positive semidefinite. (In the interest of efficiency, only the upper triangular part of P is used) #' @param q,l,u Numeric vectors, with possibly infinite elements in l and u #' @param pars list with optimization parameters, conveniently set with the function #' \code{\link{osqpSettings}}. For \code{osqpObject$UpdateSettings(newPars)} only a subset of the settings @@ -64,7 +64,7 @@ #' # Update model and solve again #' model$Update(q = q_new) #' res <- model$Solve() -#' +#' @importFrom Matrix sparseMatrix #' @export osqp = function(P=NULL, q=NULL, A=NULL, l=NULL, u=NULL, pars = osqpSettings()) { @@ -73,14 +73,17 @@ osqp = function(P=NULL, q=NULL, A=NULL, l=NULL, u=NULL, pars = osqpSettings()) { if (is.null(P)) n = length(q) - else - n = dim(P)[1] - + else { + dimP <- dim(P) + n = dim(P)[1L] + if (dimP[2L] != n) stop("P must be symmetric!") + } if (is.null(P)){ - P = sparseMatrix(integer(), integer(), x = numeric(), dims = c(n, n)) + P = Matrix::sparseMatrix(integer(), integer(), x = numeric(), dims = c(n, n)) } else { - P = triu(as(P, "dgCMatrix")) + ## P = triu(as(P, "dgCMatrix")) + P <- ensure_dtc_matrix(P) } if (is.null(q)) @@ -91,11 +94,12 @@ osqp = function(P=NULL, q=NULL, A=NULL, l=NULL, u=NULL, pars = osqpSettings()) { if (is.null(A)) { m = 0 - A = sparseMatrix(integer(), integer(), x = numeric(), dims = c(m, n)) + A = Matrix::sparseMatrix(integer(), integer(), x = numeric(), dims = c(m, n)) u = l = numeric() } else { - A = as(A, "dgCMatrix") m = nrow(A) + ## A = as(A, "dgCMatrix") + A <- ensure_dgc_matrix(A) if (is.null(u)) u = rep_len(Inf, m) else @@ -107,11 +111,11 @@ osqp = function(P=NULL, q=NULL, A=NULL, l=NULL, u=NULL, pars = osqpSettings()) { l = as.numeric(l) } - stopifnot(dim(P) == c(n, n), - length(q) == n, + stopifnot(length(q) == n, dim(A) == c(m, n), length(l) == m, - length(u) == m) + length(u) == m, + l <= u) R6Class("osqp_model", public = diff --git a/R/params.R b/R/params.R index 472d879..66923eb 100644 --- a/R/params.R +++ b/R/params.R @@ -24,6 +24,7 @@ #' @param adaptive_rho_interval Number of iterations between rho adaptations rho. If 0, it is automatic #' @param adaptive_rho_tolerance Tolerance X for adapting rho. The new rho has to be X times larger or 1/X times smaller than the current one to trigger a new factorization #' @param adaptive_rho_fraction Interval for adapting rho (fraction of the setup time) +#' @param time_limit run time limit with 0 indicating no limit #' @export osqpSettings = function(rho = 0.1, sigma = 1e-06, max_iter = 4000L, eps_abs = 0.001, eps_rel = 0.001, eps_prim_inf = 1e-04, eps_dual_inf = 1e-04, @@ -31,32 +32,19 @@ osqpSettings = function(rho = 0.1, sigma = 1e-06, max_iter = 4000L, eps_abs = 0. delta = 1e-06, polish = FALSE, polish_refine_iter = 3L, verbose = TRUE, scaled_termination = FALSE, check_termination = 25L, warm_start = TRUE, scaling = 10L, adaptive_rho = 1L, adaptive_rho_interval = 0L, - adaptive_rho_tolerance = 5, adaptive_rho_fraction = 0.4) { - inpars = as.list(match.call())[-1] - pars = sapply(simplify = FALSE, USE.NAMES = TRUE, names(inpars), function(nm) { - checkpar(inpars[[nm]], defaultOsqpSettings[[nm]]) - }) - pars -} - - - -defaultOsqpSettings = list(rho = 0.1, sigma = 1e-06, max_iter = 4000L, eps_abs = 0.001, - eps_rel = 0.001, eps_prim_inf = 1e-04, eps_dual_inf = 1e-04, - alpha = 1.6, linsys_solver = c(QDLDL_SOLVER=0L), - delta = 1e-06, polish = FALSE, polish_refine_iter = 3L, verbose = TRUE, - scaled_termination = FALSE, check_termination = 25L, warm_start = TRUE, - scaling = 10L, adaptive_rho = 1L, adaptive_rho_interval = 0L, - adaptive_rho_tolerance = 5, adaptive_rho_fraction = 0.4) - - -checkpar = function(l, r) { + adaptive_rho_tolerance = 5, adaptive_rho_fraction = 0.4, time_limit = 0.0) { + given_args <- as.list(environment()) ## all params with current values + call_arg_names <- names(match.call()[-1]) ## lose the function name at index 1 + default_args <- formals() ## this is the default list of arg values + given_args <- given_args[call_arg_names] ## restrict to specified args - l = switch(typeof(r), - integer=as.integer(l), - double=as.numeric(l), - logical=as.logical(l)) - if(length(l) != 1 || is.na(l)) - return (r) - l + for (name in call_arg_names) { + given <- given_args[[name]] + if (length(given) != 1 || is.na(given)) { + given_args[[name]] <- default_args[[name]] ## force default + } else { + storage.mode(given_args[[name]]) <- storage.mode(eval(default_args[[name]])) #eval default arg + } + } + given_args } diff --git a/R/sparse.R b/R/sparse.R new file mode 100644 index 0000000..a6a1f9c --- /dev/null +++ b/R/sparse.R @@ -0,0 +1,57 @@ +## Created by @naras to address coercion considerations with Matrix package +## +## Inspired by Rsymphony package from +## Kurt Hornik and Stefan Theussl and Reinhard Harter +## + +#' Ensure that a matrix is column-sparse format (class `dgCMatrix`) +#' @param m a C sparse matrix or coercible object such as a matrix or simple triplet matrix +#' @return a sparse matrix of class `dgCMatrix` +#' @importFrom Matrix sparseMatrix +#' @importFrom methods as +#' @noRd +ensure_dgc_matrix <- function(m) { + if (inherits(m, "dgCMatrix")) { + m + } else if (inherits(m, "matrix")) { + Matrix::.m2sparse(m, "dgCMatrix") + } else if(inherits(m, "simple_triplet_matrix")) { ## e.g. from package slam + ## The matrix method assumes that indices for non-zero entries are + ## in row-major order, but the simple_triplet_matrix() constructor + ## currently does not canonicalize accordingly ... + ind <- order(m$j, m$i) + Matrix::sparseMatrix(p = c(0L, cumsum(tabulate(m$j[ind], m$ncol))), + i = m$i[ind] - 1L, + values = m$v[ind], dims = dim(m), index1 = FALSE) + } else { + ## Resort to brute force + as(as(as(m, "CsparseMatrix"), "generalMatrix"), "dMatrix") + } +} + +#' Ensure that a matrix is column-sparse format upper triangular (class `dtCMatrix`) +#' @param m a C sparse upper triangular matrix or coercible object such as a matrix or simple triplet matrix +#' @return a sparse matrix of class `dgCMatrix` +#' @importFrom Matrix sparseMatrix triu +#' @importFrom methods as +#' @noRd +ensure_dtc_matrix <- function(m) { + if (inherits(m, "dgCMatrix")) { + m + } else if (inherits(m, "matrix")) { + Matrix::.m2sparse(m, "dtCMatrix") + } else if(inherits(m, "simple_triplet_matrix")) { ## e.g. from package slam + ind <- which(m$i <= m$j) + x <- list(i = m$i[ind] + 1L, j = m$j[ind] + 1L) ##make it 1-based + values <- m$v[ind] + ind <- order(x$j, x$i) ## may not be needed + Matrix::sparseMatrix(p = c(0L, cumsum(tabulate(x$j[ind], m$ncol))), + i = x$i[ind] - 1L, + values = values, + dims = dim(x), index1 = FALSE, + triangular = TRUE) + } else { + ## Resort to brute force + Matrix::triu(as(as(as(m, "CsparseMatrix"), "generalMatrix"), "dMatrix")) + } +} diff --git a/README.md b/README.md index 6b6333a..dc0d883 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ # R interface for OSQP - - - - [![R-CMD-check](https://github.com/osqp/osqp-r/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/osqp/osqp-r/actions/workflows/R-CMD-check.yaml) +[![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/osqp)](https://cran.r-project.org/package=osqp) +[![](https://cranlogs.r-pkg.org/badges/osqp)](https://CRAN.R-project.org/package=osqp) Provides R-bindings to [OSQP](https://osqp.org/): the Operator diff --git a/configure b/configure index 3cc439d..c727d45 100755 --- a/configure +++ b/configure @@ -26,7 +26,7 @@ LDFLAGS=`"${R_HOME}/bin/R" CMD config LDFLAGS` if [ -x "$(command -v cmake)" ]; then echo "Making fixes to osqp_sources for CRAN" - (cd src && ${R_HOME}/bin/Rscript ../inst/26ce409b_fixes/make_fixes.R) + (cd src && ${R_HOME}/bin/Rscript ../inst/58f00bd_fixes/make_fixes.R) echo "-- Trying to build libosqp.a via cmake ..." cd src/osqp_sources mkdir -p build diff --git a/inst/26ce409b_fixes/make_fixes.R b/inst/58f00bd_fixes/make_fixes.R similarity index 57% rename from inst/26ce409b_fixes/make_fixes.R rename to inst/58f00bd_fixes/make_fixes.R index 4098063..09de8f0 100644 --- a/inst/26ce409b_fixes/make_fixes.R +++ b/inst/58f00bd_fixes/make_fixes.R @@ -7,7 +7,7 @@ #' @param path relative file path of source #' @param line_no line numbers to be replaced (integer vector) #' @param replacement the corresponding replacements (character vector) -#' @param comment_prefix the comment prefix, default C/C++ +#' @param comment_prefix the comment prefix, default C/C++ replace_lines <- function(path, line_no, replacement, comment_prefix = "//") { stopifnot(length(line_no) == length(replacement)) FIXED_FLAG <- paste(comment_prefix, "CRAN FIXES DONE") @@ -20,24 +20,24 @@ replace_lines <- function(path, line_no, replacement, comment_prefix = "//") { } invisible(TRUE) } - - -# Fix pardiso_interface.c -replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_interface.c", - line_no = 35, - replacement = "c_int mkl_get_max_threads(void);") - -# Fix pardiso_loader.h -replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_loader.h", - line_no = 22, - replacement = "c_int lh_unload_pardiso(void);") - -# Fix pardiso_loader.c -replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_loader.c", - line_no = c(25, 58, 90), - replacement = c("typedef int (*mkl_get_mt_t)(void);", - "c_int mkl_get_max_threads(void) {", - "c_int lh_unload_pardiso(void) {")) + + +## # Fix pardiso_interface.c +## replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_interface.c", +## line_no = 35, +## replacement = "c_int mkl_get_max_threads(void);") + +## # Fix pardiso_loader.h +## replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_loader.h", +## line_no = 22, +## replacement = "c_int lh_unload_pardiso(void);") + +## # Fix pardiso_loader.c +## replace_lines(path = "osqp_sources/lin_sys/direct/pardiso/pardiso_loader.c", +## line_no = c(25, 58, 90), +## replacement = c("typedef int (*mkl_get_mt_t)(void);", +## "c_int mkl_get_max_threads(void) {", +## "c_int lh_unload_pardiso(void) {")) # Fix example.c replace_lines(path = "osqp_sources/lin_sys/direct/qdldl/qdldl_sources/examples/example.c", line_no = 17, @@ -47,7 +47,13 @@ replace_lines(path = "osqp_sources/lin_sys/direct/qdldl/qdldl_sources/examples/e file.rename(from = "osqp_sources/include/proj.h", to = "osqp_sources/include/osqp_proj.h") ## Fix CMakeLists.txt -replace_lines("osqp_sources/include/CMakeLists.txt", 11, ' "${CMAKE_CURRENT_SOURCE_DIR}/osqp_proj.h"', +replace_lines("osqp_sources/CMakeLists.txt", 2, 'cmake_minimum_required (VERSION 3.5)', + comment_prefix = "#") + +replace_lines("osqp_sources/include/CMakeLists.txt", 12, ' "${CMAKE_CURRENT_SOURCE_DIR}/osqp_proj.h"', + comment_prefix = "#") + +replace_lines("osqp_sources/lin_sys/direct/qdldl/qdldl_sources/CMakeLists.txt", 2, 'cmake_minimum_required (VERSION 3.5)', comment_prefix = "#") ## Fix auxil.c diff --git a/man/osqp.Rd b/man/osqp.Rd index aa47adc..c7ac3e0 100644 --- a/man/osqp.Rd +++ b/man/osqp.Rd @@ -7,7 +7,7 @@ osqp(P = NULL, q = NULL, A = NULL, l = NULL, u = NULL, pars = osqpSettings()) } \arguments{ -\item{P, A}{sparse matrices of class dgCMatrix or coercible into such, with P positive semidefinite.} +\item{P, A}{sparse matrices of class dgCMatrix or coercible into such, with P positive semidefinite. (In the interest of efficiency, only the upper triangular part of P is used)} \item{q, l, u}{Numeric vectors, with possibly infinite elements in l and u} @@ -48,8 +48,8 @@ print(model) \section{Method Arguments}{ \describe{ - \item{element}{a string with the name of one of the matrices / vectors of the problem} - \item{newPars}{list with optimization parameters} +\item{element}{a string with the name of one of the matrices / vectors of the problem} +\item{newPars}{list with optimization parameters} } } @@ -79,7 +79,6 @@ q_new <- c(10., 20.) # Update model and solve again model$Update(q = q_new) res <- model$Solve() - } \seealso{ \code{\link{solve_osqp}} diff --git a/man/osqpSettings.Rd b/man/osqpSettings.Rd index 5a7aaae..dba1a02 100644 --- a/man/osqpSettings.Rd +++ b/man/osqpSettings.Rd @@ -25,7 +25,8 @@ osqpSettings( adaptive_rho = 1L, adaptive_rho_interval = 0L, adaptive_rho_tolerance = 5, - adaptive_rho_fraction = 0.4 + adaptive_rho_fraction = 0.4, + time_limit = 0 ) } \arguments{ @@ -70,6 +71,8 @@ osqpSettings( \item{adaptive_rho_tolerance}{Tolerance X for adapting rho. The new rho has to be X times larger or 1/X times smaller than the current one to trigger a new factorization} \item{adaptive_rho_fraction}{Interval for adapting rho (fraction of the setup time)} + +\item{time_limit}{run time limit with 0 indicating no limit} } \description{ For further details please consult the OSQP documentation: diff --git a/src/Makevars b/src/Makevars index 5d1017f..c652fbe 100644 --- a/src/Makevars +++ b/src/Makevars @@ -7,7 +7,7 @@ OSQP_FLAGS=-DR_LANG=TRUE PKG_CXXFLAGS=-I$(OSQP_INCLUDE_TARGET_DIR) PKG_LIBS=-L$(OSQP_LIB_TARGET_DIR) -losqp -FIXES_SCRIPT=../inst/26ce409b_fixes/make_fixes.R +FIXES_SCRIPT=../inst/58f00bd_fixes/make_fixes.R ROBJECTS=osqp_solve_interface.o RcppExports.o OBJECTS=$(ROBJECTS) diff --git a/src/Makevars.win b/src/Makevars.win index 4bcb825..2228d4e 100644 --- a/src/Makevars.win +++ b/src/Makevars.win @@ -7,7 +7,7 @@ OSQP_FLAGS=-DR_LANG=TRUE PKG_CXXFLAGS=-I$(OSQP_INCLUDE_TARGET_DIR) PKG_LIBS=-L$(OSQP_LIB_TARGET_DIR) -losqp -FIXES_SCRIPT=../inst/26ce409b_fixes/make_fixes.R +FIXES_SCRIPT=../inst/58f00bd_fixes/make_fixes.R ROBJECTS=osqp_solve_interface.o RcppExports.o OBJECTS=$(ROBJECTS) diff --git a/src/osqp_solve_interface.cpp b/src/osqp_solve_interface.cpp index 59ab178..f85b288 100644 --- a/src/osqp_solve_interface.cpp +++ b/src/osqp_solve_interface.cpp @@ -163,8 +163,10 @@ List osqpGetParams(SEXP workPtr) _("adaptive_rho") = work->settings->adaptive_rho, _("adaptive_rho_interval") = work->settings->adaptive_rho_interval, _("adaptive_rho_tolerance") = work->settings->adaptive_rho_tolerance); - + + // 20 is the limit for the above construct, so adding others below. Inefficient! res.push_back(work->settings->adaptive_rho_fraction, "adaptive_rho_fraction"); + res.push_back(work->settings->time_limit, "time_limit"); return res; } @@ -329,6 +331,8 @@ void translateSettings(OSQPSettings* settings, const List& pars) settings->scaled_termination = as(pars[i]); else if (nm == "warm_start") settings->warm_start = as(pars[i]); + else if (nm == "time_limit") + settings->time_limit = as(pars[i]); } return; diff --git a/src/osqp_sources b/src/osqp_sources index 26ce409..0dd00a5 160000 --- a/src/osqp_sources +++ b/src/osqp_sources @@ -1 +1 @@ -Subproject commit 26ce409bf87c635d61c7cbb1f7fce2d9d68641b0 +Subproject commit 0dd00a578cf1c2691c5c379965d504c75bf6cfad diff --git a/tests/testthat/test-params.R b/tests/testthat/test-params.R new file mode 100644 index 0000000..bb17d69 --- /dev/null +++ b/tests/testthat/test-params.R @@ -0,0 +1,37 @@ + + +context("Parameter settings") + +test_that("Parameter settings and types work", { + ## https://github.com/osqp/osqp-r/issues/17 + max_iter <- 1000.0 + eps <- 1e-5 + settings <- osqp::osqpSettings(max_iter = max_iter, eps_abs = eps) + expect_identical(settings, list(max_iter = 1000L, eps_abs = 1e-5)) +}) + + +test_that("Lower bounds can't exceed upper bounds etc.", { + ## https://github.com/osqp/osqp-r/issues/29 + P <- Matrix::Matrix(c(11., 0., 0., 0.), 2, 2, sparse = TRUE) + q <- c(3., 4.) + A <- Matrix::Matrix(c(-1., 0., -1., 2., 3., 0., -1., -3., 5., 4.) , 5, 2, sparse = TRUE) + u <- c(0., 0., -15., 100., 80) + l <- u + 1 + settings <- osqpSettings(verbose = TRUE) + # Solve with OSQP. + ## Should throw error, but not crash as it is now caught at the R level, not deep in C++ + expect_error(solve_osqp(P, q, A, l, u, settings)) +}) + + +test_that("Time limit setting works", { + P <- 2 * matrix(c(0.25^2, .04, -.005, .04, .45^2, -.01, -.005, -.01, .05^2), nrow = 3) + A <- matrix(c(1, 21, 1, 0, 0, 1, 30, 0, 1, 0, 1, 8, 0, 0, 1), nrow = 5) + l <- c(1, 18, 0, 0, 0) + u <- c(1, rep(Inf, 4)) + res <- solve_osqp(P = P, A = A, l = l, u = u, pars = osqpSettings(time_limit = 1e-10)) + expect_equal(res$info$status, "run time limit reached") ## runtime limit reached +}) + + From 4d198e8e6e48291666fb8ce31d2a75843ca9b8b9 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Mon, 2 Oct 2023 20:59:13 -0700 Subject: [PATCH 2/5] Update qdldl_types_R.h --- src/qdldl_types_R.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/qdldl_types_R.h b/src/qdldl_types_R.h index 5ed7eba..a580add 100644 --- a/src/qdldl_types_R.h +++ b/src/qdldl_types_R.h @@ -5,17 +5,16 @@ extern "C" { # endif /* ifdef __cplusplus */ +#include //for the QDLDL_INT_TYPE_MAX + // QDLDL integer and float types typedef long long QDLDL_int; /* for indices */ typedef double QDLDL_float; /* for numerical values */ +typedef unsigned char QDLDL_bool; /* for boolean values */ -// Use bool for logical type if available -#if __STDC_VERSION__ >= 199901L -typedef _Bool QDLDL_bool; -#else -typedef int QDLDL_bool; -#endif +//Maximum value of the signed type QDLDL_int. +#define QDLDL_INT_MAX LLONG_MAX # ifdef __cplusplus } From 639bd5ed1f585e88774f8f4c320939ca36f4e280 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Mon, 2 Oct 2023 21:18:14 -0700 Subject: [PATCH 3/5] Update DESCRIPTION --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index 872e177..3c48448 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,4 +24,5 @@ Collate: 'RcppExports.R' 'osqp-package.R' 'sparse.R' 'solve.R' 'osqp.R' 'params. NeedsCompilation: yes Suggests: testthat Encoding: UTF-8 +BugReports: https://github.com/osqp/osqp-r/issues URL: https://osqp.org From 8f4fa3e7a42e434c767d989e74cb4c34af94ad18 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 3 Oct 2023 07:01:10 -0700 Subject: [PATCH 4/5] Update .Rbuildignore --- .Rbuildignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index 4cc0032..1332eed 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -25,4 +25,5 @@ libosqp.a ^\.github$ .github src/osqp_sources/CITATION.cff -src/osqp_sources/docs \ No newline at end of file +src/osqp_sources/docs +src/osqp_sources/tests From 18b0dbeec6fcdd96b2189604637488f74286edb6 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 3 Oct 2023 07:14:06 -0700 Subject: [PATCH 5/5] Update .Rbuildignore --- .Rbuildignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index 1332eed..bfdc737 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -26,4 +26,7 @@ libosqp.a .github src/osqp_sources/CITATION.cff src/osqp_sources/docs +src/osqp_sources/site src/osqp_sources/tests +src/osqp_sources/lin_sys/direct/qdldl/qdldl_sources/tests +