Skip to content

Commit

Permalink
assorted fixes (#248)
Browse files Browse the repository at this point in the history
- fix compatibility issues with matrix pkg updates
- fix cran warnings
- update pkg docs to provide instructions for installing cplexAPI (fix #214)
- fix #247
- improve code coverage
- fix #218
- fix broken Urls
- update cran-comments.md
Co-authored-by: Richard Schuster <ricschuster@users.noreply.github.com>
  • Loading branch information
jeffreyhanson committed Sep 6, 2022
1 parent 9e3e825 commit 4b6a18d
Show file tree
Hide file tree
Showing 348 changed files with 2,332 additions and 2,065 deletions.
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
^appveyor\.yml$
.gitkeep
^Makefile$
^data-raw$
cran-comments.md
CRAN-RELEASE
_pkgdown.yml
Expand Down
19 changes: 10 additions & 9 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: prioritizr
Type: Package
Version: 7.2.0.8
Version: 7.2.1
Title: Systematic Conservation Prioritization in R
Description:
Systematic conservation prioritization using mixed integer linear
Expand All @@ -15,10 +15,12 @@ Description:
multiple stakeholders. To solve large-scale or complex conservation
planning problems, users should install the Gurobi optimization software
(available from <https://www.gurobi.com/>) and the 'gurobi' R package (see
Gurobi Installation Guide vignette for details). Additionally, the 'rcbc' R
package (available at <https://github.com/dirkschumacher/rcbc>) can be used
to generate solutions using the CBC optimization software
(<https://github.com/coin-or/Cbc>).
Gurobi Installation Guide vignette for details). Users can also install the
IBM CPLEX software (<https://www.ibm.com/analytics/cplex-optimizer>) and
the 'cplexAPI' R package (available at <https://github.com/cran/cplexAPI>).
Additionally, the 'rcbc' R package (available at
<https://github.com/dirkschumacher/rcbc>) can be used to generate solutions
using the CBC optimization software (<https://github.com/coin-or/Cbc>).
Authors@R:
c(person(c('Jeffrey', 'O'), 'Hanson',
email='jeffrey.hanson@uqconnect.edu.au', role = c('aut'),
Expand Down Expand Up @@ -55,7 +57,7 @@ Imports:
slam (>= 0.1-48),
igraph (>= 1.2.9),
ape (>= 5.5),
rgeos (>= 0.5-8),
geos (>= 0.2),
plyr (>= 1.8.6),
doParallel (>= 1.0.16),
magrittr (>= 2.0.1),
Expand All @@ -68,16 +70,15 @@ Suggests:
knitr (>= 1.36),
roxygen2 (>= 7.1.2),
scales (>= 1.1.1),
maptools (>= 1.1-2),
PBSmapping (>= 2.73.0),
gurobi (>= 8.0-1),
rcbc (>= 0.1.0.9001),
cplexAPI (>= 1.4.0),
lpsymphony (>= 1.17.0),
Rsymphony (>= 0.1-31),
rmarkdown (>= 2.11),
prioritizrdata (>= 0.2.4),
data.table (>= 1.14.2)
data.table (>= 1.14.2),
fields (>= 14.0)
Depends:
R (>= 3.5.0),
sp,
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ initc:
docs: man readme vigns site

data:
Rscript --slave inst/extdata/simulate_data.R
Rscript --slave inst/scripts/builtin-data.R

man:
R --slave -e "devtools::document()"
Expand Down Expand Up @@ -77,7 +77,7 @@ quickcheck:

check:
echo "\n===== R CMD CHECK =====\n" > check.log 2>&1
R --slave -e "devtools::check(build_args = '--no-build-vignettes', args = '--no-build-vignettes', run_dont_test = TRUE, vignettes = FALSE)" >> check.log 2>&1
R --slave -e "devtools::check(remote = TRUE, build_args = '--no-build-vignettes', args = '--no-build-vignettes', run_dont_test = TRUE, vignettes = FALSE)" >> check.log 2>&1
cp -R doc inst/
touch inst/doc/.gitkeep

Expand Down Expand Up @@ -106,7 +106,7 @@ install:
R --slave -e "devtools::install_local('../prioritizr')"

examples:
R --slave -e "devtools::run_examples(test = TRUE, run = TRUE);warnings()" >> examples.log
R --slave -e "devtools::run_examples(run_donttest = TRUE, run_dontrun = TRUE);warnings()" > examples.log 2>&1
rm -f Rplots.pdf

.PHONY: initc clean data docs readme contrib site test check checkwb build install man spellcheck examples purl_vigns check_vigns urlcheck
21 changes: 21 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# prioritizr 7.2.1

- Release candidate for CRAN.

# prioritizr 7.2.0.9

- Fix compatibility with upcoming _Matrix_ package version (version 1.5-0).
- Update package documentation to provide details for obtaining and installing
the _cplexAPI_ package since it has been archived on CRAN (#214).
- Fix bug that caused the `add_cbc_solver()` to throw a segfault when solving
a problem wherein the `rij_matrix(x)` has a zero amount for the last feature
in the last planning unit (#247).
- Update `simulate_data()`, `simulate_cost()` and `simulate_species()`
functions to improve performance using the _fields_ package.
- Update `boundary_matrix()` to use STR query trees by default.
- Remove _maptools_, _PBSmapping_, and _rgeos_ packages as dependencies.
This involved updating the unit tests to hard-code correct results,
updating examples to use the _sf_ package, and updating the
`boundary_matrix()` to use the _geos_ package (#218).
- Fix broken URLs in package documentation.

# prioritizr 7.2.0.8

- Update `simulate_cost()` and `simulate_species()` so that they no longer
Expand Down
29 changes: 14 additions & 15 deletions R/add_asym_connectivity_penalties.R
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ NULL
#' require(Matrix)
#'
#' # load data
#' data(sim_pu_polygons, sim_pu_zones_stack, sim_features, sim_features_zones)
#' data(sim_pu_sf, sim_pu_zones_stack, sim_features, sim_features_zones)
#'
#' # define function to rescale values between zero and one so that we
#' # can compare solutions from different connectivity matrices
Expand All @@ -99,7 +99,7 @@ NULL
#' }
#'
#' # create basic problem
#' p1 <- problem(sim_pu_polygons, sim_features, "cost") %>%
#' p1 <- problem(sim_pu_sf, sim_features, "cost") %>%
#' add_min_set_objective() %>%
#' add_relative_targets(0.2) %>%
#' add_default_solver(verbose = FALSE)
Expand All @@ -108,21 +108,21 @@ NULL
#' # adjacent planning units and, due to rivers flowing southwards
#' # through the study area, connectivity from northern planning units to
#' # southern planning units is ten times stronger than the reverse.
#' acm1 <- matrix(0, length(sim_pu_polygons), length(sim_pu_polygons))
#' acm1 <- matrix(0, nrow(sim_pu_sf), nrow(sim_pu_sf))
#' acm1 <- as(acm1, "Matrix")
#' centroids <- rgeos::gCentroid(sim_pu_polygons, byid = TRUE)
#' adjacent_units <- rgeos::gIntersects(sim_pu_polygons, byid = TRUE)
#' for (i in seq_len(length(sim_pu_polygons))) {
#' for (j in seq_len(length(sim_pu_polygons))) {
#' centroids <- sf::st_coordinates(suppressWarnings(sf::st_centroid(sim_pu_sf)))
#' adjacent_units <- sf::st_intersects(sim_pu_sf, sparse = FALSE)
#' for (i in seq_len(nrow(sim_pu_sf))) {
#' for (j in seq_len(nrow(sim_pu_sf))) {
#' # find if planning units are adjacent
#' if (adjacent_units[i, j]) {
#' # find if planning units lay north and south of each other
#' # i.e., they have the same x-coordinate
#' if (centroids@coords[i, 1] == centroids@coords[j, 1]) {
#' if (centroids@coords[i, 2] > centroids@coords[j, 2]) {
#' if (centroids[i, 1] == centroids[j, 1]) {
#' if (centroids[i, 2] > centroids[j, 2]) {
#' # if i is north of j add 10 units of connectivity
#' acm1[i, j] <- acm1[i, j] + 10
#' } else if (centroids@coords[i, 2] < centroids@coords[j, 2]) {
#' } else if (centroids[i, 2] < centroids[j, 2]) {
#' # if i is south of j add 1 unit of connectivity
#' acm1[i, j] <- acm1[i, j] + 1
#' }
Expand All @@ -131,7 +131,7 @@ NULL
#' }
#' }
#'
#' # standardize matrix values to lay between zero and one
#' # linearly re-scale matrix values to range between zero and one
#' acm1[] <- rescale(acm1[])
#'
#' # visualize asymmetric connectivity matrix
Expand Down Expand Up @@ -214,7 +214,7 @@ methods::setMethod("add_asym_connectivity_penalties",
methods::signature("ConservationProblem", "ANY", "ANY", "matrix"),
function(x, penalty, zones, data) {
add_asym_connectivity_penalties(x, penalty, zones,
methods::as(data, "dgCMatrix"))
as_Matrix(data, "dgCMatrix"))
})

#' @name add_asym_connectivity_penalties
Expand All @@ -224,7 +224,7 @@ methods::setMethod("add_asym_connectivity_penalties",
methods::signature("ConservationProblem", "ANY", "ANY", "Matrix"),
function(x, penalty, zones, data) {
add_asym_connectivity_penalties(x, penalty, zones,
methods::as(data, "dgCMatrix"))
as_Matrix(data, "dgCMatrix"))
})

#' @name add_asym_connectivity_penalties
Expand Down Expand Up @@ -308,8 +308,7 @@ methods::setMethod("add_asym_connectivity_penalties",
for (z1 in seq_len(dim(data)[3])) {
m[[z1]] <- list()
for (z2 in seq_len(dim(data)[4])) {
m[[z1]][[z2]] <-
methods::as(data[indices, indices, z1, z2], "dgCMatrix")
m[[z1]][[z2]] <- as_Matrix(data[indices, indices, z1, z2], "dgCMatrix")
}
}
# add penalties
Expand Down
5 changes: 3 additions & 2 deletions R/add_boundary_penalties.R
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,9 @@ internal_prepare_planning_unit_boundary_data <- function(x, data) {
if (inherits(data, c("matrix", "Matrix"))) {
# if it is matrix coerce to sparse matrix
bm <- data
if (!inherits(data, c("dsCMatrix", "dgCMatrix")))
bm <- methods::as(data, "dgCMatrix")
if (!inherits(data, c("dsCMatrix", "dgCMatrix"))) {
bm <- as_Matrix(data, "dgCMatrix")
}
# check that matrix properties are correct
assertthat::assert_that(
ncol(bm) == nrow(bm),
Expand Down
18 changes: 15 additions & 3 deletions R/add_cbc_solver.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ NULL
#' such as the
#' [Rtools software](https://cran.r-project.org/bin/windows/Rtools/)
#' or system libraries -- prior to installing the \pkg{rcbc} package.
#' For further details on installing this package, please consult
#' [official installation instructions for the package](https://dirkschumacher.github.io/rcbc/).
#' For further details on installing this package, please consult the
#' [online package documentation](https://dirkschumacher.github.io/rcbc/).
#'
#' @inheritSection add_gurobi_solver Start solution format
#'
Expand Down Expand Up @@ -176,11 +176,23 @@ add_cbc_solver <- function(x, gap = 0.1,
max = identical(x$modelsense(), "max"),
obj = x$obj(),
is_integer = x$vtype() == "B",
mat = x$A(),
mat = as_Matrix(x$A(), "dgTMatrix"),
col_lb = x$lb(),
col_ub = x$ub(),
row_lb = row_lb,
row_ub = row_ub)
# if needed, insert dummy row to ensure non-zero value in last rij cell
if (abs(model$mat[nrow(model$mat), ncol(model$mat)]) < 1e-300) {
model$mat <- as_Matrix(
rbind(
model$mat,
Matrix::sparseMatrix(i = 1, j = ncol(model$mat), x = 1, repr = "T")
),
"dgTMatrix"
)
model$row_lb <- c(model$row_lb, -Inf)
model$row_ub <- c(model$row_ub, Inf)
}
# add starting solution if specified
start <- self$get_data("start")
if (!is.null(start) && !is.Waiver(start)) {
Expand Down
23 changes: 12 additions & 11 deletions R/add_connectivity_penalties.R
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ NULL
#' require(Matrix)
#'
#' # load data
#' data(sim_pu_polygons, sim_pu_zones_stack, sim_features, sim_features_zones)
#' data(sim_pu_sf, sim_pu_zones_stack, sim_features, sim_features_zones)
#'
#' # define function to rescale values between zero and one so that we
#' # can compare solutions from different connectivity matrices
Expand All @@ -176,14 +176,14 @@ NULL
#' }
#'
#' # create basic problem
#' p1 <- problem(sim_pu_polygons, sim_features, "cost") %>%
#' p1 <- problem(sim_pu_sf, sim_features, "cost") %>%
#' add_min_set_objective() %>%
#' add_relative_targets(0.2) %>%
#' add_default_solver(verbose = FALSE)
#'
#' # create a symmetric connectivity matrix where the connectivity between
#' # two planning units corresponds to their shared boundary length
#' b_matrix <- boundary_matrix(sim_pu_polygons)
#' b_matrix <- boundary_matrix(sim_pu_sf)
#'
#' # standardize matrix values to lay between zero and one
#' b_matrix[] <- rescale(b_matrix[])
Expand All @@ -195,8 +195,8 @@ NULL
#' # create a symmetric connectivity matrix where the connectivity between
#' # two planning units corresponds to their spatial proximity
#' # i.e., planning units that are further apart share less connectivity
#' centroids <- rgeos::gCentroid(sim_pu_polygons, byid = TRUE)
#' d_matrix <- (1 / (as(dist(centroids@coords), "Matrix") + 1))
#' centroids <- sf::st_coordinates(suppressWarnings(sf::st_centroid(sim_pu_sf)))
#' d_matrix <- (1 / (Matrix::Matrix(as.matrix(dist(centroids))) + 1))
#'
#' # standardize matrix values to lay between zero and one
#' d_matrix[] <- rescale(d_matrix[])
Expand All @@ -216,7 +216,7 @@ NULL
#' # each planning unit and we could use connectivity penalties to identify
#' # solutions that cluster planning units together that both contain large
#' # amounts of native vegetation
#' c_matrix <- connectivity_matrix(sim_pu_polygons, "cost")
#' c_matrix <- connectivity_matrix(sim_pu_sf, "cost")
#'
#' # standardize matrix values to lay between zero and one
#' c_matrix[] <- rescale(c_matrix[])
Expand Down Expand Up @@ -402,8 +402,9 @@ methods::setGeneric("add_connectivity_penalties",
methods::setMethod("add_connectivity_penalties",
methods::signature("ConservationProblem", "ANY", "ANY", "matrix"),
function(x, penalty, zones, data) {
add_connectivity_penalties(x, penalty, zones,
methods::as(data, "dgCMatrix"))
add_connectivity_penalties(
x, penalty, zones, as_Matrix(data, "dgCMatrix")
)
})

#' @name add_connectivity_penalties
Expand All @@ -413,7 +414,7 @@ methods::setMethod("add_connectivity_penalties",
methods::signature("ConservationProblem", "ANY", "ANY", "Matrix"),
function(x, penalty, zones, data) {
add_connectivity_penalties(x, penalty, zones,
methods::as(data, "dgCMatrix"))
as_Matrix(data, "dgCMatrix"))
})

#' @name add_connectivity_penalties
Expand Down Expand Up @@ -497,7 +498,7 @@ methods::setMethod("add_connectivity_penalties",
m[[z1]] <- list()
for (z2 in seq_len(dim(data)[4])) {
m[[z1]][[z2]] <-
methods::as(data[indices, indices, z1, z2], "dgCMatrix")
as_Matrix(data[indices, indices, z1, z2], "dgCMatrix")
}
}
# add penalties
Expand All @@ -523,7 +524,7 @@ internal_add_connectivity_penalties <- function(x, penalty, data) {
# coerce to symmetric connectivity data
cm <- self$get_data("data")
cm <- lapply(cm, function(x) {
lapply(x, function(y) methods::as(Matrix::tril(y), "dgCMatrix"))
lapply(x, function(y) as_Matrix(Matrix::tril(y), "dgCMatrix"))
})
# apply penalties
rcpp_apply_connectivity_penalties(
Expand Down
6 changes: 3 additions & 3 deletions R/add_contiguity_constraints.R
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ methods::setMethod("add_contiguity_constraints",
inherits(data, c("NULL", "Matrix")))
if (!is.null(data)) {
# check argument to data if not NULL
data <- methods::as(data, "dgCMatrix")
data <- as_Matrix(data, "dgCMatrix")
assertthat::assert_that(all(data@x %in% c(0, 1)),
ncol(data) == nrow(data), number_of_total_units(x) == ncol(data),
all(is.finite(data@x)), Matrix::isSymmetric(data))
Expand Down Expand Up @@ -261,7 +261,7 @@ methods::setMethod("add_contiguity_constraints",
# create matrix
data <- adjacency_matrix(x$data$cost)
# coerce matrix to full matrix
data <- methods::as(data, "dgCMatrix")
data <- as_Matrix(data, "dgCMatrix")
# store data
self$set_data("matrix", data)
}
Expand Down Expand Up @@ -314,5 +314,5 @@ methods::setMethod("add_contiguity_constraints",
methods::signature("ConservationProblem", "ANY", "matrix"),
function(x, zones, data) {
# add constraints
add_contiguity_constraints(x, zones, methods::as(data, "dgCMatrix"))
add_contiguity_constraints(x, zones, as_Matrix(data, "dgCMatrix"))
})
26 changes: 18 additions & 8 deletions R/add_cplex_solver.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,29 @@ NULL
#' (see <https://www.ibm.com/products/ilog-cplex-optimization-studio>).
#'
#' @section Installation:
#' The pkg{cplexAPI} package is used to interface with *IBM CPLEX*. To install
#' this package, the `CPLEX_BIN` variable must be set (similar to
#' the `GUROBI_HOME` variable for the *Gurobi* software) to specify
#' the file path for the *CPLEX* software. For example, on a Linux system,
#' The \pkg{cplexAPI} package is used to interface with *IBM CPLEX* software.
#' To install the package, the *IBM CPLEX* software must be installed
#' (see <https://www.ibm.com/analytics/cplex-optimizer>). Next, the `CPLEX_BIN`
#' environmental variable must be set to specify the file path for the
#' *IBM CPLEX* software. For example, on a Linux system,
#' this variable can be specified by adding the following text to the
#' `~/.bashrc` file:
#' ```
#' export CPLEX_BIN="/opt/ibm/ILOG/CPLEX_Studio128/cplex/bin/x86-64_linux/cplex"
#' ```
#' Note that you may need to change the version
#' number in the file path (i.e., `"CPLEX_Studio128"`). For more information
#' on installing the pkg{cplexAPI} package, please see the
#' [official installation instructions for the package](https://github.com/cran/cplexAPI/blob/master/inst/INSTALL).
#' Please Note that you may need to change the version number in the file path
#' (i.e., `"CPLEX_Studio128"`). After specifying the `CPLEX_BIN`
#' environmental variable, the \pkg{cplexAPI} package can be installed.
#' Since the \pkg{cplexAPI} package is not available on the
#' the Comprehensive R Archive Network (CRAN), it must be installed from
#' [its GitHub repository](https://github.com/cran/cplexAPI). To
#' install the \pkg{cplexAPI} package, please use the following code:
#' ```
#' if (!require(remotes)) install.packages("remotes")
#' remotes::install_github("cran/cplexAPI")
#' ```
#' For further details on installing this package, please consult the
#' [installation instructions](https://github.com/cran/cplexAPI/blob/master/inst/INSTALL).
#'
#' @inherit add_gurobi_solver return
#'
Expand Down

0 comments on commit 4b6a18d

Please sign in to comment.