diff --git a/NEWS.md b/NEWS.md index ef905da..05aebb3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,5 +2,5 @@ ## Added * Adds `apus` object with the functions `addField`, `trainModel` and `optimizeFertilizerChoice` -* Adds for the cost function module 1,5 and 6 +* Adds for the cost function module 1,4, 5 and 6 * Adds default table for `cultivations`, `fertilizers`, `parameters` and `fines` diff --git a/R/model.R b/R/model.R index a29128d..5c23a92 100644 --- a/R/model.R +++ b/R/model.R @@ -168,6 +168,10 @@ calculateCost <- function(doses, fields, fertilizers, fines, reduce_batches = TR module1 <- calculateCostModule1(doses, fields, fertilizers) + # Module 4: Cost of applying fertilizers ---------------------------------- + module4 <- calculateCostModule4(doses, fields, fertilizers) + + # Module 5: Revenue from harvested crops ---------------------------------- module5 <- calculateRevenueModule5(doses, fields, fertilizers) @@ -177,7 +181,7 @@ calculateCost <- function(doses, fields, fertilizers, fines, reduce_batches = TR # Combine the modules ----------------------------------------------------- - cost <- torch::torch_zeros(dim(module1)) + module1 - module5 + module6 + cost <- torch::torch_zeros(dim(module1)) + module1 + module4 - module5 + module6 # Convert to € / ha ------------------------------------------------------- @@ -215,6 +219,35 @@ calculateCostModule1 <- function(doses, fields, fertilizers) { return(module1) } +# Module 4: Cost of applying fertilizers ----------------------------------- +calculateCostModule4 <- function(doses, fields, fertilizers) { + + # Sum dose per fertilizer per field -------------------------------------- + fields.b_area <- torch::torch_unsqueeze(fields[,,1], -1) + fields.fertilizers.dose <- fields.b_area * doses + + + # Calculate number of applications per field ------------------------------ + fertilizers.p_app_capacity <- fertilizers[,,10] + fields.fertilizers.p_app_capacity <- torch::torch_unsqueeze(fertilizers.p_app_capacity, 2) + fields.fertilizers.p_app_capacity <- torch::torch_repeat_interleave(fields.fertilizers.p_app_capacity, repeats = dim(fields.fertilizers.dose)[2], dim =2) + fields.fertilizers.applications <- torch::torch_ceil(fields.fertilizers.dose / fields.fertilizers.p_app_capacity) + + + # Calculate cost of applications ------------------------------------------- + fertilizers.p_app_cost <- fertilizers[,,9] + fields.fertilizers.p_app_cost <- torch::torch_unsqueeze(fertilizers.p_app_cost, 2) + fields.fertilizers.p_app_cost <- torch::torch_repeat_interleave(fields.fertilizers.p_app_cost, repeats = dim(fields.fertilizers.dose)[2], dim =2) + fields.fertilizers.cost <- fields.fertilizers.applications * fields.fertilizers.p_app_cost + + + # Sum cost for farm ------------------------------------------------------- + fields.cost <- torch::torch_sum(fields.fertilizers.cost, dim = 3L) + module4 <- torch::torch_sum(fields.cost, dim = 2L) + + return(module4) +} + # Module 5: Revenue from harvested crops ------------------------------------ calculateRevenueModule5 <- function(doses, fields, fertilizers) { diff --git a/README.md b/README.md index 379aae3..17c6975 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ For the v1 version of `apus` we plan to develop to following features: * [x] Include cost function for module 1: Purchase of fertilizers * [ ] Include cost function for module 2: Disposal of manure * [ ] Include cost function for module 3: Cost of storing fertilizers -* [ ] Include cost function for module 4: Cost of applying fertilizers +* [x] Include cost function for module 4: Cost of applying fertilizers * [x] Include cost function for module 5: Revenue of harvest * [x] Include cost function for module 6: Penalties in case of exceeding legal limits * [ ] Include cost function for module 7: Cost of greenhouse gas emissions diff --git a/data-raw/fertilizers.R b/data-raw/fertilizers.R index 1bbeb3a..0a62fbd 100644 --- a/data-raw/fertilizers.R +++ b/data-raw/fertilizers.R @@ -19,6 +19,9 @@ fertilizers[p_type_compost == TRUE, p_p_wcl := 0.25] fertilizers[p_name_nl == 'Champost', p_p_wcl := 0.75] fertilizers[p_name_nl == 'Rundvee vaste mest', p_p_wcl := 0.75] +fertilizers[, p_app_cost := 100] +fertilizers[, p_app_capacity := 15000] +fertilizers[p_type_artificial ==TRUE, p_app_capacity := 1000] # Export table ------------------------------------------------------------ usethis::use_data(fertilizers, overwrite = TRUE, version = 3, compress = 'xz') diff --git a/data/fertilizers.rda b/data/fertilizers.rda index 5b860b7..c1fd51f 100644 Binary files a/data/fertilizers.rda and b/data/fertilizers.rda differ diff --git a/man/fertilizers.Rd b/man/fertilizers.Rd index 938d509..56c8e8f 100644 --- a/man/fertilizers.Rd +++ b/man/fertilizers.Rd @@ -5,7 +5,7 @@ \alias{fertilizers} \title{Fertilizers table} \format{ -An object of class \code{data.table} (inherits from \code{data.frame}) with 47 rows and 46 columns. +An object of class \code{data.table} (inherits from \code{data.frame}) with 47 rows and 48 columns. } \usage{ fertilizers diff --git a/tests/testthat/test-002-model.R b/tests/testthat/test-002-model.R index 4f92774..cb13625 100644 --- a/tests/testthat/test-002-model.R +++ b/tests/testthat/test-002-model.R @@ -36,6 +36,14 @@ test_that("Calculate cost for module 1: Purchase of fertilizers", { expect_length(as.numeric(module1), farms_count) }) + +module4 <- calculateCostModule4(doses, fields, fertilizers) + +test_that("Calculate cost for module 4: Cost of applying fertilizers", { + expect_contains(class(module4), 'torch_tensor') + expect_length(as.numeric(module4), farms_count) +}) + module5 <- calculateRevenueModule5(doses, fields, fertilizers) test_that("Calculate revenue for module 5: Revenue of harvested crops", {