Deniz Uğur
2020-May-13 23:18 UTC
[R] gdistance::accCost fails when nrows is bigger than 90
Hello all, It has been only 2 days since I started using R and I was trying movecost library. Before explaining the unexpected behavior I should say that I?m calling R function from Python using rpy2 package. That shouldn?t be an issue because everything works as expected when a matrix of size 100x90 is given. Okay now, basically I?m converting an 2D matrix to RasterLayer with appropriate CRS and extent properties then transfer it to R runtime. A modified version of Tobler?s hiking function is applied then a shortest-path is calculated. This procedure works for a matrix with column size anywhere between 1 and memory?s limit. However if row size of the matrix exceeds 90 then function is halted on gdistance::accCost saying that: "At structural_properties.c:5313 : cannot run Bellman-Ford algorithm, Negative loop detected while calculating shortest paths? It?s very interesting issue because I have explicitly tried ?88, 89, 90, 91 and it halted on +90 I?ve created a gist in case you want to try the application on your computer. Also I?ve included a clean version of the R script I was using bellow. Thank you. https://gist.github.com/DenizUgur/01e18edd03321f3d3928c3afb2bd7145 <https://gist.github.com/DenizUgur/01e18edd03321f3d3928c3afb2bd7145> movecost <- function (dtm, origin, destin, time="s") { altDiff <- function(x){x[2] - x[1]} hd <- gdistance::transition(dtm, altDiff, 8, symm=FALSE) slope <- gdistance::geoCorrection(hd) cost_function <- function(x){ ifelse(x[adj] > 0, 1.3 * exp(-3.5 * abs(x[adj] + 0.05)), 5.3 * exp(-3.5 * abs(x[adj] + 0.05))) } adj <- raster::adjacent(dtm, cells=1:ncell(dtm), pairs=TRUE, directions=8) speed <- slope speed[adj] <- cost_function(slope) speed <- speed * 0.278 Conductance <- gdistance::geoCorrection(speed) accum_final <- gdistance::accCost(Conductance, sp::coordinates(origin)) accum_final <- raster::mask(accum_final, dtm) sPath <- gdistance::shortestPath(Conductance, sp::coordinates(origin), sp::coordinates(destin), output="SpatialLines") sPath$length <- rgeos::gLength(sPath, byid=TRUE) destin$cost <- raster::extract(accum_final, destin) results <- list("accumulated.cost.raster"=accum_final, "LCPs"=sPath, "dest.loc.w.cost"=destin) } [[alternative HTML version deleted]]
Referring to my mail bellow, this situation is not a expected behavior. Do you think that this is because of a fault in my codes or some bug in gdistance? What could be the problem? Thank you for your consideration. ---------- Forwarded message --------- From: Deniz U?ur <deniz343 at gmail.com> Date: Thu, May 14, 2020, 02:18 Subject: gdistance::accCost fails when nrows is bigger than 90 To: <r-help at r-project.org> Hello all, It has been only 2 days since I started using R and I was trying movecost library. Before explaining the unexpected behavior I should say that I?m calling R function from Python using rpy2 package. That shouldn?t be an issue because everything works as expected when a matrix of size 100x90 is given. Okay now, basically I?m converting an 2D matrix to RasterLayer with appropriate CRS and extent properties then transfer it to R runtime. A modified version of Tobler?s hiking function is applied then a shortest-path is calculated. This procedure works for a matrix with column size anywhere between 1 and memory?s limit. However if row size of the matrix exceeds 90 then function is halted on gdistance::accCost saying that: "At structural_properties.c:5313 : cannot run Bellman-Ford algorithm, Negative loop detected while calculating shortest paths? It?s very interesting issue because I have explicitly tried ?88, 89, 90, 91 and it halted on +90 I?ve created a gist in case you want to try the application on your computer. Also I?ve included a clean version of the R script I was using bellow. Thank you. https://gist.github.com/DenizUgur/01e18edd03321f3d3928c3afb2bd7145 movecost <- function (dtm, origin, destin, time="s") { altDiff <- function(x){x[2] - x[1]} hd <- gdistance::transition(dtm, altDiff, 8, symm=FALSE) slope <- gdistance::geoCorrection(hd) cost_function <- function(x){ ifelse(x[adj] > 0, 1.3 * exp(-3.5 * abs(x[adj] + 0.05)), 5.3 * exp(-3.5 * abs(x[adj] + 0.05))) } adj <- raster::adjacent(dtm, cells=1:ncell(dtm), pairs=TRUE, directions=8) speed <- slope speed[adj] <- cost_function(slope) speed <- speed * 0.278 Conductance <- gdistance::geoCorrection(speed) accum_final <- gdistance::accCost(Conductance, sp::coordinates(origin)) accum_final <- raster::mask(accum_final, dtm) sPath <- gdistance::shortestPath(Conductance, sp::coordinates(origin), sp:: coordinates(destin), output="SpatialLines") sPath$length <- rgeos::gLength(sPath, byid=TRUE) destin$cost <- raster::extract(accum_final, destin) results <- list("accumulated.cost.raster"=accum_final, "LCPs"=sPath, "dest.loc.w.cost"=destin) } [[alternative HTML version deleted]]