test_that("scenarios compute changes and detect rebound", { sc <- data.frame(scenario = c("drip", "drip+exp", "solar"), crop = c("sugarcane", "sugarcane", NA), water_change = c(-0.3, -0.3, 0), area_change = c(0, 0.8, 0), renewable = c(NA, NA, 1)) ns <- nexus_scenarios(district_nexus, sc, grid_factor = 1) d <- district_nexus expect_equal(ns$change$water[ns$change$scenario == "drip"], -0.3 * 2000 * 20000) expect_false(ns$rebound[["drip"]]) expect_true(ns$rebound[["drip+exp"]]) expect_equal(ns$summary$emissions_t[ns$summary$scenario == "solar"], 0) expect_equal(ns$summary$emissions_t[1], sum(d$area * d$energy) / 1000) expect_output(print(ns), "Rebound") expect_error(nexus_scenarios(district_nexus, data.frame(scenario = "x", crop = "kiwi"))) }) test_that("LP matches a known solution and shadow prices", { # max 3x + 5y s.t. x <= 4, 2y <= 12, 3x + 2y <= 18 (classic example) d <- data.frame(crop = c("x", "y"), yield = c(3, 5), price = 1, cost = 0, water = c(0, 2), energy = c(3, 2)) na <- nexus_allocation(d, land = Inf, water_limit = 12, energy_limit = 18, extra = list(xcap = list(use = c(1, 0), limit = 4))) expect_equal(na$plan$optimal_area, c(2, 6)) expect_equal(na$objective[["optimal"]], 36) sp <- setNames(na$resources$shadow_price, na$resources$resource) expect_equal(sp[["water"]], 1.5) expect_equal(sp[["energy"]], 1) expect_equal(sp[["xcap"]], 0) }) test_that("allocation respects bounds and limits", { na <- nexus_allocation(district_nexus, land = 10000, water_limit = 6e7, energy_limit = 1.2e7) x <- na$plan$optimal_area d <- district_nexus expect_true(all(x >= d$min_area - 1e-6 & x <= d$max_area + 1e-6)) r <- na$resources expect_true(all(r$use <= r$limit + 1e-6)) # relaxing a binding constraint by one unit raises the objective by its # shadow price na2 <- nexus_allocation(district_nexus, land = 10000, water_limit = 6e7 + 1, energy_limit = 1.2e7) expect_equal(na2$objective[["optimal"]] - na$objective[["optimal"]], r$shadow_price[r$resource == "water"], tolerance = 1e-4) fo <- nexus_allocation(district_nexus, land = 10000, objective = "food") expect_gt(fo$objective[["optimal"]], 0) expect_error(nexus_allocation(district_nexus, land = 100)) expect_output(print(na), "Resources") }) test_that("trade-off classification works", { set.seed(1) x <- rnorm(30) d <- data.frame(a = x, b = x + rnorm(30, 0, 0.1), c = -x + rnorm(30, 0, 0.1), z = rnorm(30)) t <- nexus_tradeoffs(d, c("a", "b", "c", "z"), c(TRUE, TRUE, TRUE, TRUE)) rel <- setNames(t$pairs$relation, paste(t$pairs$indicator_1, t$pairs$indicator_2)) expect_equal(rel[["a b"]], "synergy") expect_equal(rel[["a c"]], "trade-off") t2 <- nexus_tradeoffs(d, c("a", "c"), c(TRUE, FALSE)) expect_equal(t2$pairs$relation, "synergy") expect_error(nexus_tradeoffs(d, "a", TRUE)) expect_output(print(t), "synergy") })