-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add module 5: Penalty in case of exceeding legal limit #1
Changes from all commits
1b5b477
aac33fb
24dab1c
80e4cc1
79ecbaf
a27c34b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ Imports: | |
R6, | ||
torch | ||
Suggests: | ||
devtools, | ||
testthat (>= 3.0.0) | ||
Config/testthat/edition: 3 | ||
Depends: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
#' @param farms (data.table) | ||
#' @param cultivations (data.table) | ||
#' @param fertilizers (data.table) | ||
#' @param fines (data.table) | ||
#' @param fields_max (integer) | ||
#' @param device (character) | ||
#' | ||
|
@@ -15,7 +16,7 @@ | |
#' @import torch | ||
#' | ||
#'@export | ||
createApusDataset <- function(farms = NULL, cultivations, fertilizers, fields_max, device) { | ||
createApusDataset <- function(farms = NULL, cultivations, fertilizers, fines, fields_max, device) { | ||
|
||
transformfieldsToTensor = createSyntheticfields = code = fields_count = self = NULL | ||
size = value_max = value_min = p_price = p_stored = b_id_farm = b_id_field = NULL | ||
|
@@ -27,7 +28,7 @@ createApusDataset <- function(farms = NULL, cultivations, fertilizers, fields_ma | |
apus_dataset <- torch::dataset( | ||
name = "apus_dataset", | ||
|
||
initialize = function(farms = NULL, cultivations, fertilizers, fields_max, device) { | ||
initialize = function(farms = NULL, cultivations, fertilizers, fines, fields_max, device) { | ||
|
||
# Check arguments ----------------------------------------------------- | ||
# TODO | ||
|
@@ -45,11 +46,14 @@ createApusDataset <- function(farms = NULL, cultivations, fertilizers, fields_ma | |
self$farms_count <- 100 | ||
} | ||
|
||
fines <- dcast(fines, . ~ norm, value.var = 'fine')[, 2:4] | ||
self$fines <- torch::torch_tensor(as.matrix(fines), device = device) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not better to use mget(colnames) ? |
||
|
||
# Set temporary | ||
fertilizers[, p_stored := 0] | ||
fertilizers[, p_price := 1] | ||
|
||
fertilizers <- fertilizers[, c('p_stored', 'p_price', 'p_n_rt', 'p_n_wc', 'p_p_rt', 'p_k_rt')] | ||
fertilizers <- fertilizers[, c('p_stored', 'p_price', 'p_n_rt', 'p_n_wc', 'p_p_rt', 'p_k_rt', 'p_type_manure', 'p_p_wcl')] | ||
|
||
self$fertilizers <- torch::torch_tensor(as.matrix(fertilizers), device = device) | ||
}, | ||
|
@@ -63,7 +67,7 @@ createApusDataset <- function(farms = NULL, cultivations, fertilizers, fields_ma | |
} | ||
t.fields <- transformFieldsToTensor(farms, self$device) | ||
|
||
return(list(fields = t.fields, fertilizers = self$fertilizers)) | ||
return(list(fields = t.fields, fertilizers = self$fertilizers, fines = self$fines)) | ||
}, | ||
|
||
.length = function() { | ||
|
@@ -73,7 +77,7 @@ createApusDataset <- function(farms = NULL, cultivations, fertilizers, fields_ma | |
|
||
|
||
# Create torch dataset for apus ------------------------------------------- | ||
dataset <- apus_dataset(farms = farms, cultivations = cultivations, fertilizers = fertilizers, fields_max = fields_max, device = device) | ||
dataset <- apus_dataset(farms = farms, cultivations = cultivations, fertilizers = fertilizers, fines = fines, fields_max = fields_max, device = device) | ||
|
||
return(dataset) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,14 +106,14 @@ createApusModel <- function(dataset.train, dataset.valid, width = 12, layers = 1 | |
|
||
cli::cli_progress_bar(paste0('Training model [', epoch, '/', epochs, ']'), total = dl.train$.length()) | ||
|
||
# For testing | ||
# For developing | ||
# b <- dl.train$.iter() | ||
# b <- b$.next() | ||
|
||
# Forward pass | ||
optimizer$zero_grad() | ||
doses <- model(b$fields, b$fertilizers) | ||
cost <- calculateCost(doses, b$fields, b$fertilizers) | ||
cost <- calculateCost(doses, b$fields, b$fertilizers, b$fines) | ||
|
||
# Backward pass | ||
cost$backward() | ||
|
@@ -133,13 +133,13 @@ createApusModel <- function(dataset.train, dataset.valid, width = 12, layers = 1 | |
|
||
cli::cli_progress_bar(paste0('Validating model [', epoch, '/', epochs, ']'), total = dl.valid$.length()) | ||
|
||
# For testing | ||
# For developing | ||
# b <- dl.valid$.iter() | ||
# b <- b$.next() | ||
|
||
# Forward pass | ||
doses <- model(b$fields, b$fertilizers) | ||
cost <- calculateCost(doses, b$fields, b$fertilizers) | ||
cost <- calculateCost(doses, b$fields, b$fertilizers, b$fines) | ||
|
||
losses.validation <- c(losses.validation, cost$item()) | ||
|
||
|
@@ -157,7 +157,7 @@ createApusModel <- function(dataset.train, dataset.valid, width = 12, layers = 1 | |
return(model) | ||
} | ||
|
||
calculateCost <- function(doses, fields, fertilizers, reduce_batches = TRUE) { | ||
calculateCost <- function(doses, fields, fertilizers, fines, reduce_batches = TRUE) { | ||
|
||
|
||
# Check arguments --------------------------------------------------------- | ||
|
@@ -168,12 +168,16 @@ calculateCost <- function(doses, fields, fertilizers, reduce_batches = TRUE) { | |
module1 <- calculateCostModule1(doses, fields, fertilizers) | ||
|
||
|
||
# Module 4: Revenue from harvested crops ---------------------------------- | ||
module4 <- calculateRevenueModule4(doses, fields, fertilizers) | ||
# Module 5: Revenue from harvested crops ---------------------------------- | ||
module5 <- calculateRevenueModule5(doses, fields, fertilizers) | ||
|
||
|
||
# Module 6: Penalty for exceeding legal limit ----------------------------- | ||
module6 <- calculatePenaltyModule6(doses, fields, fertilizers, fines) | ||
|
||
|
||
# Combine the modules ----------------------------------------------------- | ||
cost <- torch::torch_zeros(dim(module1)) + module1 - module4 | ||
cost <- torch::torch_zeros(dim(module1)) + module1 - module5 + module6 | ||
|
||
|
||
# Convert to € / ha ------------------------------------------------------- | ||
|
@@ -211,8 +215,8 @@ calculateCostModule1 <- function(doses, fields, fertilizers) { | |
return(module1) | ||
} | ||
|
||
# Module 4: Revenue from harvested crops ------------------------------------ | ||
calculateRevenueModule4 <- function(doses, fields, fertilizers) { | ||
# Module 5: Revenue from harvested crops ------------------------------------ | ||
calculateRevenueModule5 <- function(doses, fields, fertilizers) { | ||
|
||
# Calculate N dose per fields | ||
fertilizers.p_n_rt <- fertilizers[,,3] | ||
|
@@ -268,9 +272,71 @@ calculateRevenueModule4 <- function(doses, fields, fertilizers) { | |
fields.b_area <- fields[,,1] | ||
fields.b_lu_yield <- fields[,,8] | ||
fields.b_lu_price <- fields[,,9] | ||
module4 <- fields.b_area * fields.b_lu_yield * fields.b_lu_price * fields.d_realized | ||
module4 <- torch::torch_sum(module4, dim = 2L) | ||
module5 <- fields.b_area * fields.b_lu_yield * fields.b_lu_price * fields.d_realized | ||
module5 <- torch::torch_sum(module5, dim = 2L) | ||
|
||
return(module4) | ||
return(module5) | ||
} | ||
|
||
# Module 6: Penalties in case of exceeding legal limits ----------------------- | ||
calculatePenaltyModule6 <- function(doses, fields, fertilizers, fines) { | ||
|
||
# Calculate d_n_norm_man per field | ||
fertilizers.p_n_rt <- fertilizers[,,3] | ||
fertilizers.p_type_manure <- fertilizers[,,7] | ||
fertilizers.p_n_manure <- fertilizers.p_n_rt * fertilizers.p_type_manure | ||
fertilizers.p_n_manure <- torch::torch_unsqueeze(fertilizers.p_n_manure, 2) | ||
fertilizers.p_n_manure <- torch::torch_repeat_interleave(fertilizers.p_n_manure, repeats = dim(doses)[2], dim =2) | ||
fields.fertilizers.dose.n_manure <- doses * fertilizers.p_n_manure | ||
fields.dose.n_manure <- torch::torch_sum(fields.fertilizers.dose.n_manure, dim = 3) | ||
farms.dose.n_manure <- torch::torch_sum(fields.dose.n_manure, dim = 2) | ||
|
||
fields.d_n_norm_man <- fields[,,6] | ||
fields.b_area <- fields[,,1] | ||
fine.d_n_norm_man <- fines[,1,2] | ||
farms.d_n_norm_man <- torch::torch_sum(fields.b_area * fields.d_n_norm_man, dim = 2L) | ||
farms.exceeding.d_n_norm_man <- torch::torch_relu(farms.dose.n_manure - farms.d_n_norm_man) | ||
farms.penalty.d_n_norm_man <- farms.exceeding.d_n_norm_man * fine.d_n_norm_man | ||
|
||
# Calculate d_n_norm per field | ||
fertilizers.p_n_rt <- fertilizers[,,3] | ||
fertilizers.p_n_wc <- fertilizers[,,4] # TODO Replace with p_n_wcl | ||
fertilizers.p_n_workable <- fertilizers.p_n_rt * fertilizers.p_n_wc | ||
fertilizers.p_n_workable <- torch::torch_unsqueeze(fertilizers.p_n_workable, 2) | ||
fertilizers.p_n_workable <- torch::torch_repeat_interleave(fertilizers.p_n_workable, repeats = dim(doses)[2], dim =2) | ||
fields.fertilizers.dose.n_workable <- doses * fertilizers.p_n_workable | ||
fields.dose.n_workable <- torch::torch_sum(fields.fertilizers.dose.n_workable, dim = 3) | ||
farms.dose.n_workable <- torch::torch_sum( fields.dose.n_workable , dim = 2) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. workable is a bad translation of "werkzaam". For now ok, but for transparency replace by nitrogen fertilizer replacement value (nfrv) or effective nitrogen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and for later update, distinguish between the norms given by government and by the agronomic ones. |
||
fields.d_n_norm <- fields[,,5] | ||
fields.b_area <- fields[,,1] | ||
fine.d_n_norm <- fines[,1,1] | ||
farms.d_n_norm <- torch::torch_sum(fields.b_area * fields.d_n_norm, dim = 2L) | ||
farms.exceeding.d_n_norm <- torch::torch_relu(farms.dose.n_workable - farms.d_n_norm) | ||
farms.penalty.d_n_norm <- farms.exceeding.d_n_norm * fine.d_n_norm | ||
|
||
# Calculate d_p_norm per field | ||
fertilizers.p_p_rt <- fertilizers[,,5] | ||
fertilizers.p_p_wcl <- fertilizers[,,8] | ||
fertilizers.p_p_legal <- fertilizers.p_p_rt * fertilizers.p_p_wcl | ||
fertilizers.p_p_legal <- torch::torch_unsqueeze(fertilizers.p_p_legal, 2) | ||
fertilizers.p_p_legal <- torch::torch_repeat_interleave(fertilizers.p_p_legal, repeats = dim(doses)[2], dim =2) | ||
fields.fertilizers.dose.p_legal <- doses * fertilizers.p_p_legal | ||
fields.dose.p_legal <- torch::torch_sum(fields.fertilizers.dose.p_legal, dim = 3) | ||
farms.dose.p_legal <- torch::torch_sum( fields.dose.p_legal, dim = 2) | ||
|
||
fields.d_p_norm <- fields[,,7] | ||
fields.b_area <- fields[,,1] | ||
fine.d_p_norm <- fines[,1,3] | ||
farms.d_p_norm <- torch::torch_sum(fields.b_area * fields.d_p_norm, dim = 2L) | ||
farms.exceeding.d_p_norm <- torch::torch_relu(farms.dose.p_legal - farms.d_p_norm) | ||
farms.penalty.d_p_norm <- farms.exceeding.d_p_norm * fine.d_p_norm | ||
|
||
|
||
# Combine the penalties | ||
module6 <- farms.penalty.d_n_norm_man + farms.penalty.d_n_norm + farms.penalty.d_p_norm | ||
|
||
return(module6) | ||
} | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add in brackets behind the number the main topic/issue of the module