From d5c4d45abb8ce18bd5fddca16a417dbd18c4fbb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mayo=20R=C3=B6ttger?= <mayo@debian> Date: Fri, 7 Aug 2020 11:55:52 +0200 Subject: [PATCH] Version 1.3.0. Added new function to check availability of newer COIN-OR Clp functions --- DESCRIPTION | 8 +++--- NAMESPACE | 3 ++- R/clpAPI.R | 13 +++++++++- configure | 18 +++++++------- configure.ac | 2 +- inst/NEWS.Rd | 8 ++++++ man/isAvailableFuncCLP.Rd | 46 +++++++++++++++++++++++++++++++++++ man/modifyCoefficientCLP.Rd | 4 +-- src/clpAPI.c | 47 +++++++++++++++++++++++++++++++++++- src/clpAPI.h | 3 +++ src/config.h | 4 +-- src/init.c | 1 + src/symbols.rds | Bin 1872 -> 1906 bytes 13 files changed, 136 insertions(+), 21 deletions(-) create mode 100755 man/isAvailableFuncCLP.Rd mode change 100755 => 100644 src/config.h diff --git a/DESCRIPTION b/DESCRIPTION index 5873fcf..2eaa2d7 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: clpAPI Type: Package Title: R Interface to C API of COIN-or Clp -Version: 1.2.13 -Date: 2020-02-13 +Version: 1.3.0 +Date: 2020-08-07 Authors@R: c(person("Mayo", "Roettger", role = "cre", email = "mayo.roettger@hhu.de"), person("Gabriel", "Gelius-Dietrich", role = c("aut"), email = "geliudie@uni-duesseldorf.de"), person(c("C.", "Jonathan"), "Fritzemeier", role = "ctb", email = "clausjonathan.fritzemeier@uni-duesseldorf.de")) @@ -13,9 +13,9 @@ SystemRequirements: COIN-OR Clp (>= 1.12.0) License: GPL-3 | file LICENSE LazyLoad: yes Collate: generics.R clp_ptrClass.R clp.R clpAPI.R zzz.R -Packaged: 2020-02-13 10:47:00 UTC; mayo +Packaged: 2020-08-07 10:38:00 UTC; mayo Author: Mayo Roettger [cre], Gabriel Gelius-Dietrich [aut], C. Jonathan Fritzemeier [ctb] Maintainer: Mayo Roettger <mayo.roettger@hhu.de> NeedsCompilation: yes Repository: CRAN -Date/Publication: 2020-02-13 11:47:00 +Date/Publication: 2020-08-07 11:38:00 diff --git a/NAMESPACE b/NAMESPACE index c66a323..c315a02 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -80,6 +80,7 @@ versionCLP, setRowNameCLP, setColNameCLP, writeMPSCLP, -modifyCoefficientCLP +modifyCoefficientCLP, +isAvailableFuncCLP ) diff --git a/R/clpAPI.R b/R/clpAPI.R index bbd4b1b..e563fab 100755 --- a/R/clpAPI.R +++ b/R/clpAPI.R @@ -936,7 +936,7 @@ writeMPSCLP <- function(lp, fname, formatType = 0, numberAcross = 1, objSense = as.integer(formatType), as.integer(numberAcross), as.numeric(objSense) - ) + ) return(check) @@ -960,3 +960,14 @@ modifyCoefficientCLP <- function(lp, i, j, el, keepZero = TRUE) { } + +# Function to check availability of Clp-1.17.2 functions # +#------------------------------------------------------------------------------# + +isAvailableFuncCLP <- function(funcname) { + check <- .Call("isAvailableFunc", PACKAGE = "clpAPI", + as.character(funcname) + ) + + return(check) +} diff --git a/configure b/configure index 02f3c3f..5f15914 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for clpAPI 1.2.13. +# Generated by GNU Autoconf 2.69 for clpAPI 1.3.0. # # Report bugs to <mayo.roettger@hhu.de>. # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='clpAPI' PACKAGE_TARNAME='clpapi' -PACKAGE_VERSION='1.2.13' -PACKAGE_STRING='clpAPI 1.2.13' +PACKAGE_VERSION='1.3.0' +PACKAGE_STRING='clpAPI 1.3.0' PACKAGE_BUGREPORT='mayo.roettger@hhu.de' PACKAGE_URL='' @@ -1242,7 +1242,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures clpAPI 1.2.13 to adapt to many kinds of systems. +\`configure' configures clpAPI 1.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1304,7 +1304,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of clpAPI 1.2.13:";; + short | recursive ) echo "Configuration of clpAPI 1.3.0:";; esac cat <<\_ACEOF @@ -1392,7 +1392,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -clpAPI configure 1.2.13 +clpAPI configure 1.3.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1694,7 +1694,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by clpAPI $as_me 1.2.13, which was +It was created by clpAPI $as_me 1.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4251,7 +4251,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by clpAPI $as_me 1.2.13, which was +This file was extended by clpAPI $as_me 1.3.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4313,7 +4313,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -clpAPI config.status 1.2.13 +clpAPI config.status 1.3.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index c9ec3eb..b459b47 100755 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([clpAPI], [1.2.13], [mayo.roettger@hhu.de]) +AC_INIT([clpAPI], [1.3.0], [mayo.roettger@hhu.de]) dnl # -------------------------------------------------------------------- dnl # template config.h.in diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 3743e46..a9cf183 100755 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,14 @@ \name{NEWS} \title{clpAPI News} \encoding{UTF-8} +% ---------------------------------------------------------------------------- % +\section{Changes in version 1.3.0 2020-08-07}{ + \itemize{ + \item Added function \code{isAvailableFuncCLP}, to check if newer API + functions are available. + } +} + % ---------------------------------------------------------------------------- % \section{Changes in version 1.2.13 2020-02-13}{ \itemize{ diff --git a/man/isAvailableFuncCLP.Rd b/man/isAvailableFuncCLP.Rd new file mode 100755 index 0000000..35b8b1e --- /dev/null +++ b/man/isAvailableFuncCLP.Rd @@ -0,0 +1,46 @@ +\name{isAvailableFuncCLP} +\alias{isAvailableFuncCLP} + +\title{ + Check if some newer functions relying on CLP version >= 1.17.2 are available +} + +\description{ + Checks if functions like \code{setRowNameCLP}, \code{setColNameCLP}, + \code{writeMpsCLP}, and \code{modifyCoefficientCLP} are available. +} + +\usage{ + isAvailableFuncCLP(funcname) +} + +\arguments{ + \item{funcname}{ + The name of the function. + } +} + +\details{ + Some functions of the API require that the package was build against + CLP version >= 1.17.2, otherwise they will be dummy functions. + These functions are \code{setRowNameCLP}, \code{setColNameCLP}, + \code{writeMpsCLP}, and \code{modifyCoefficientCLP}. This function + tests, if these functions are available. +} + +\value{ + TRUE, if the respective function is available, + returns FALSE, if it is not. If the funcname + does not match one of the mentioned functions, it + returns FALSE. +} + +\author{ + Mayo Roettger <mayo.roettger@hhu.de> + + Maintainer: Mayo Roettger <mayo.roettger@hhu.de> +} + + +\keyword{ optimize } + diff --git a/man/modifyCoefficientCLP.Rd b/man/modifyCoefficientCLP.Rd index 6000036..d1851be 100755 --- a/man/modifyCoefficientCLP.Rd +++ b/man/modifyCoefficientCLP.Rd @@ -23,10 +23,10 @@ problem object. } \item{i}{ - Row index. + Row index (starts with 0). } \item{j}{ - Column index. + Column index (starts with 0). } \item{el}{ Coefficient to set. diff --git a/src/clpAPI.c b/src/clpAPI.c index ac23014..53aa606 100755 --- a/src/clpAPI.c +++ b/src/clpAPI.c @@ -1371,26 +1371,71 @@ SEXP modifyCoefficient(SEXP lp, SEXP row, SEXP column, SEXP newElement, SEXP kee return out; } +/* -------------------------------------------------------------------------- */ +/* check for functionality of new clp functions */ +SEXP isAvailableFunc(SEXP funcname) { + + SEXP out = R_NilValue; + + const char *rfuncname = CHAR(STRING_ELT(funcname, 0)); + + if (strcmp(rfuncname,"setRowNameCLP") == 0) { + out = Rf_ScalarLogical(1); + } else if (strcmp(rfuncname,"setColNameCLP") == 0) { + out = Rf_ScalarLogical(1); + } else if (strcmp(rfuncname,"writeMpsCLP") == 0) { + out = Rf_ScalarLogical(1); + } else if (strcmp(rfuncname,"modifyCoefficientCLP") == 0) { + out = Rf_ScalarLogical(1); + } + + return out; +} + #else /* not CLP_EXT1_17_2 */ +/* dummy function */ SEXP setRowName(SEXP lp, SEXP i, SEXP rname) { SEXP out = R_NilValue; return out; } +/* dummy function */ SEXP setColName(SEXP lp, SEXP j, SEXP cname) { SEXP out = R_NilValue; return out; } +/* dummy function */ SEXP writeMps(SEXP lp, SEXP filename, SEXP formatType, SEXP numberAcross, SEXP objSense) { - SEXP out = R_NilValue; + SEXP out = Rf_ScalarInteger(1); return out; } +/* dummy function */ SEXP modifyCoefficient(SEXP lp, SEXP row, SEXP column, SEXP newElement, SEXP keepZero) { SEXP out = R_NilValue; return out; } +/* check for functionality of new clp functions */ +SEXP isAvailableFunc(SEXP funcname) { + + SEXP out = R_NilValue; + + const char *rfuncname = CHAR(STRING_ELT(funcname, 0)); + + if (strcmp(rfuncname,"setRowNameCLP") == 0) { + out = Rf_ScalarLogical(0); + } else if (strcmp(rfuncname,"setColNameCLP") == 0) { + out = Rf_ScalarLogical(0); + } else if (strcmp(rfuncname,"writeMpsCLP") == 0) { + out = Rf_ScalarLogical(0); + } else if (strcmp(rfuncname,"modifyCoefficientCLP") == 0) { + out = Rf_ScalarLogical(0); + } + + return out; +} + #endif /* HAVE_CLP_EXT1_17_2 */ diff --git a/src/clpAPI.h b/src/clpAPI.h index bea917f..fb46e4f 100755 --- a/src/clpAPI.h +++ b/src/clpAPI.h @@ -253,3 +253,6 @@ SEXP writeMps(SEXP lp, SEXP filename, SEXP formatType, SEXP numberAcross, SEXP o /* Change matrix coefficients */ SEXP modifyCoefficient(SEXP lp, SEXP row, SEXP column, SEXP newElement, SEXP keepZero); /* ------------------------------------------------ */ + +/* check for functionality of new clp functions */ +SEXP isAvailableFunc(SEXP funcname); diff --git a/src/config.h b/src/config.h old mode 100755 new mode 100644 index adcbc6f..c9b4503 --- a/src/config.h +++ b/src/config.h @@ -41,7 +41,7 @@ #define PACKAGE_NAME "clpAPI" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "clpAPI 1.2.10" +#define PACKAGE_STRING "clpAPI 1.2.13" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "clpapi" @@ -50,7 +50,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.10" +#define PACKAGE_VERSION "1.2.13" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/src/init.c b/src/init.c index a3213a7..60b4205 100755 --- a/src/init.c +++ b/src/init.c @@ -101,6 +101,7 @@ static const R_CallMethodDef callMethods[] = { {"setColName", (DL_FUNC) &setColName, 3}, {"writeMps", (DL_FUNC) &writeMps, 5}, {"modifyCoefficient", (DL_FUNC) &modifyCoefficient, 5}, + {"isAvailableFunc", (DL_FUNC) &isAvailableFunc, 1}, {NULL, NULL, 0} }; diff --git a/src/symbols.rds b/src/symbols.rds index 63efcff60f9a0b315602bd76b01b3e8f084b55b6..c86af8080fd5a918a13a4edc917f0d8a0ce216ca 100755 GIT binary patch literal 1906 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 literal 1872 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 C`m3Y> -- GitLab