Skip to content

Commit

Permalink
Implemented NegativeMaxParameter and NegativeMinParameter
Browse files Browse the repository at this point in the history
  • Loading branch information
s-simoncelli committed Dec 18, 2023
1 parent 1f4c756 commit a541e77
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 1 deletion.
5 changes: 5 additions & 0 deletions pywr-core/src/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ mod interpolated;
mod max;
mod min;
mod negative;
mod negativemax;
mod negativemin;
mod offset;
mod polynomial;
mod profiles;
Expand All @@ -22,6 +24,7 @@ mod rhai;
pub mod simple_wasm;
mod threshold;
mod vector;
mod flow;

use std::any::Any;
// Re-imports
Expand Down Expand Up @@ -50,6 +53,8 @@ pub use interpolated::InterpolatedParameter;
pub use max::MaxParameter;
pub use min::MinParameter;
pub use negative::NegativeParameter;
pub use negativemax::NegativeMaxParameter;
pub use negativemin::NegativeMinParameter;
pub use offset::OffsetParameter;
pub use polynomial::Polynomial1DParameter;
pub use profiles::{
Expand Down
45 changes: 45 additions & 0 deletions pywr-core/src/parameters/negativemax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::metric::Metric;
use crate::model::Model;
use crate::parameters::{Parameter, ParameterMeta};
use crate::scenario::ScenarioIndex;
use std::any::Any;

use crate::state::State;
use crate::timestep::Timestep;
use crate::PywrError;

pub struct NegativeMaxParameter {
meta: ParameterMeta,
metric: Metric,
threshold: f64,
}

impl NegativeMaxParameter {
pub fn new(name: &str, metric: Metric, threshold: f64) -> Self {
Self {
meta: ParameterMeta::new(name),
metric,
threshold,
}
}
}

impl Parameter for NegativeMaxParameter {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn meta(&self) -> &ParameterMeta {
&self.meta
}
fn compute(
&self,
_timestep: &Timestep,
_scenario_index: &ScenarioIndex,
model: &Model,
state: &State,
_internal_state: &mut Option<Box<dyn Any + Send>>,
) -> Result<f64, PywrError> {
let x = -self.metric.get_value(model, state)?;
Ok(x.max(self.threshold))
}
}
45 changes: 45 additions & 0 deletions pywr-core/src/parameters/negativemin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::metric::Metric;
use crate::model::Model;
use crate::parameters::{Parameter, ParameterMeta};
use crate::scenario::ScenarioIndex;
use std::any::Any;

use crate::state::State;
use crate::timestep::Timestep;
use crate::PywrError;

pub struct NegativeMinParameter {
meta: ParameterMeta,
metric: Metric,
threshold: f64,
}

impl NegativeMinParameter {
pub fn new(name: &str, metric: Metric, threshold: f64) -> Self {
Self {
meta: ParameterMeta::new(name),
metric,
threshold,
}
}
}

impl Parameter for NegativeMinParameter {
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn meta(&self) -> &ParameterMeta {
&self.meta
}
fn compute(
&self,
_timestep: &Timestep,
_scenario_index: &ScenarioIndex,
model: &Model,
state: &State,
_internal_state: &mut Option<Box<dyn Any + Send>>,
) -> Result<f64, PywrError> {
let x = -self.metric.get_value(model, state)?;
Ok(x.min(self.threshold))
}
}
100 changes: 100 additions & 0 deletions pywr-schema/src/parameters/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,103 @@ impl TryFromV1Parameter<NegativeParameterV1> for NegativeParameter {
Ok(p)
}
}

/// This parameter takes the maximum of the negative of a Parameter and a constant value (threshold).
///
/// # Arguments
///
/// * `parameter` - The parameter to compare with the float.
/// * `threshold` - The threshold value to compare against the given parameter. Default to 0.0.
///
/// # Examples
///
/// ```json
/// {
/// "type": "NegativeMax",
/// "parameter": {
/// "type": "MonthlyProfile",
/// "values": [-1, -4, 5, 9, 1, 5, 10, 8, 11, 9, 11 ,12]
/// },
/// "threshold": 2
/// }
/// ```
/// In January this parameter returns 2, in February 4.
///
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
pub struct NegativeMaxParameter {
#[serde(flatten)]
pub meta: ParameterMeta,
pub parameter: DynamicFloatValue,
pub threshold: Option<f64>,
}

impl NegativeMaxParameter {
pub fn node_references(&self) -> HashMap<&str, &str> {
HashMap::new()
}

pub fn add_to_model(
&self,
model: &mut pywr_core::model::Model,
tables: &LoadedTableCollection,
data_path: Option<&Path>,
) -> Result<ParameterIndex, SchemaError> {
let idx = self.parameter.load(model, tables, data_path)?;
let threshold = self.threshold.unwrap_or(0.0);

let p = pywr_core::parameters::NegativeMaxParameter::new(&self.meta.name, idx, threshold);
Ok(model.add_parameter(Box::new(p))?)
}
}

// TODO NegativeMaxParameter from v1

/// This parameter takes the minimum of the negative of a Parameter and a constant value (threshold).
///
/// # Arguments
///
/// * `parameter` - The parameter to compare with the float.
/// * `threshold` - The threshold value to compare against the given parameter. Default to 0.0.
///
/// # Examples
///
/// ```json
/// {
/// "type": "NegativeMin",
/// "parameter": {
/// "type": "MonthlyProfile",
/// "values": [-1, -4, 5, 9, 1, 5, 10, 8, 11, 9, 11 ,12]
/// },
/// "threshold": 2
/// }
/// ```
/// In January this parameter returns 1, in February 2.
///
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
pub struct NegativeMinParameter {
#[serde(flatten)]
pub meta: ParameterMeta,
pub parameter: DynamicFloatValue,
pub threshold: Option<f64>,
}

impl NegativeMinParameter {
pub fn node_references(&self) -> HashMap<&str, &str> {
HashMap::new()
}

pub fn add_to_model(
&self,
model: &mut pywr_core::model::Model,
tables: &LoadedTableCollection,
data_path: Option<&Path>,
) -> Result<ParameterIndex, SchemaError> {
let idx = self.parameter.load(model, tables, data_path)?;
let threshold = self.threshold.unwrap_or(0.0);

let p = pywr_core::parameters::NegativeMinParameter::new(&self.meta.name, idx, threshold);
Ok(model.add_parameter(Box::new(p))?)
}
}

// TODO NegativeMinParameter from v1
13 changes: 12 additions & 1 deletion pywr-schema/src/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ pub use super::parameters::control_curves::{
ControlCurvePiecewiseInterpolatedParameter,
};
pub use super::parameters::core::{
ActivationFunction, ConstantParameter, MaxParameter, MinParameter, NegativeParameter, VariableSettings,
ActivationFunction, ConstantParameter, MaxParameter, MinParameter, NegativeMaxParameter, NegativeMinParameter,
NegativeParameter, VariableSettings,
};
pub use super::parameters::delay::DelayParameter;
pub use super::parameters::discount_factor::DiscountFactorParameter;
Expand Down Expand Up @@ -157,6 +158,8 @@ pub enum Parameter {
Max(MaxParameter),
Min(MinParameter),
Negative(NegativeParameter),
NegativeMax(NegativeMaxParameter),
NegativeMin(NegativeMinParameter),
Polynomial1D(Polynomial1DParameter),
ParameterThreshold(ParameterThresholdParameter),
TablesArray(TablesArrayParameter),
Expand Down Expand Up @@ -199,6 +202,8 @@ impl Parameter {
Self::DiscountFactor(p) => p.meta.name.as_str(),
Self::Interpolated(p) => p.meta.name.as_str(),
Self::RbfProfile(p) => p.meta.name.as_str(),
Self::NegativeMax(p) => p.meta.name.as_str(),
Self::NegativeMin(p) => p.meta.name.as_str(),
}
}

Expand Down Expand Up @@ -232,6 +237,8 @@ impl Parameter {
Self::DiscountFactor(p) => p.node_references(),
Self::Interpolated(p) => p.node_references(),
Self::RbfProfile(p) => p.node_references(),
Self::NegativeMax(p) => p.node_references(),
Self::NegativeMin(p) => p.node_references(),
}
}

Expand Down Expand Up @@ -282,6 +289,8 @@ impl Parameter {
Self::DiscountFactor(_) => "DiscountFactor",
Self::Interpolated(_) => "Interpolated",
Self::RbfProfile(_) => "RbfProfile",
Self::NegativeMax(_) => "NegativeMax",
Self::NegativeMin(_) => "NegativeMin",
}
}

Expand Down Expand Up @@ -320,6 +329,8 @@ impl Parameter {
Self::DiscountFactor(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::Interpolated(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::RbfProfile(p) => ParameterType::Parameter(p.add_to_model(model)?),
Self::NegativeMax(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
Self::NegativeMin(p) => ParameterType::Parameter(p.add_to_model(model, tables, data_path)?),
};

Ok(ty)
Expand Down

0 comments on commit a541e77

Please sign in to comment.