Skip to content
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

[ANT-2749] Support time dependency #2622

Open
wants to merge 73 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
2dd533f
[skip ci]
a-zakir Feb 5, 2025
92a71ee
[skip ci]
a-zakir Feb 10, 2025
472d1af
[skip ci]
a-zakir Feb 10, 2025
6b6ba55
[skip ci]
a-zakir Feb 10, 2025
033c8ac
update
a-zakir Feb 10, 2025
a9163be
update
a-zakir Feb 10, 2025
f7f2bed
resolve conflicts
a-zakir Feb 11, 2025
a8b2b3a
remove old file
a-zakir Feb 11, 2025
f857e77
update logic
a-zakir Feb 11, 2025
b8aa133
case systemParam is different from component's
a-zakir Feb 11, 2025
a7607d9
handling: Parameter is declared constant in time and scenario in libr…
a-zakir Feb 11, 2025
4dd5d13
Merge branch 'develop' into feature/ANT-2749
a-zakir Feb 11, 2025
5d1a4df
update
a-zakir Feb 11, 2025
978835f
Merge branch 'feature/ANT-2749' of https://github.com/AntaresSimulato…
a-zakir Feb 11, 2025
e5f46e2
update
a-zakir Feb 11, 2025
f525e79
update
a-zakir Feb 11, 2025
da99fd0
for ubuntu
a-zakir Feb 11, 2025
cd1eb27
format
a-zakir Feb 11, 2025
2d5e9de
update
a-zakir Feb 13, 2025
fe2ab99
update
a-zakir Feb 13, 2025
73acedb
update
a-zakir Feb 13, 2025
e5a0fd8
update
a-zakir Feb 13, 2025
b6c0ce5
update
a-zakir Feb 13, 2025
b427b41
update
a-zakir Feb 13, 2025
0c4f1bc
update
a-zakir Feb 13, 2025
48abf37
Add tests for time-series handling (#2637)
pet-mit Feb 13, 2025
294b664
update
a-zakir Feb 13, 2025
2df98fa
update
a-zakir Feb 13, 2025
a959033
update
a-zakir Feb 13, 2025
e2b288c
Feature/ant 2749 some improvement (#2638)
a-zakir Feb 14, 2025
d99c9c4
remove unused methods
a-zakir Feb 14, 2025
1216b8a
update optim api (#2642)
a-zakir Feb 14, 2025
7d940df
Merge branch 'develop' into feature/ANT-2749
pet-mit Feb 17, 2025
f31e5f8
add test 1_2
a-zakir Feb 17, 2025
1069eea
add test 1_3
a-zakir Feb 17, 2025
dd3e3a1
run new tests
a-zakir Feb 17, 2025
baa60e8
new test
a-zakir Feb 17, 2025
d82c618
add new test
a-zakir Feb 17, 2025
72e64ea
update modeler cucumber tests
a-zakir Feb 17, 2025
1efcb6f
print
a-zakir Feb 17, 2025
1a0c1b1
print
a-zakir Feb 17, 2025
3dd7e3b
upt
a-zakir Feb 17, 2025
069e56d
upt
a-zakir Feb 18, 2025
76f8cc0
add 1_5
a-zakir Feb 18, 2025
8a38873
use Sirius
a-zakir Feb 18, 2025
f062dea
add 1_7
a-zakir Feb 18, 2025
f695540
enable cucumber tests
a-zakir Feb 18, 2025
d7f4d21
update
a-zakir Feb 18, 2025
d64ae88
update
a-zakir Feb 18, 2025
769d269
update
a-zakir Feb 18, 2025
9c31d0d
update
a-zakir Feb 18, 2025
c751624
update
a-zakir Feb 18, 2025
a087843
update
a-zakir Feb 18, 2025
65ded29
add UT
a-zakir Feb 19, 2025
c48c256
add UT
a-zakir Feb 19, 2025
5a9cb6c
rename negate -> operator-
a-zakir Feb 19, 2025
d950bc8
fix test
a-zakir Feb 19, 2025
b056139
add UT
a-zakir Feb 19, 2025
c2bfe50
add UT
a-zakir Feb 19, 2025
eb1af02
update
a-zakir Feb 19, 2025
5fdd9f9
Avoid copying a large map (#2646)
flomnes Feb 19, 2025
8726a5b
Merge branch 'develop' into feature/ANT-2749
a-zakir Feb 19, 2025
4e2f9c7
update
a-zakir Feb 19, 2025
8372c19
update
a-zakir Feb 19, 2025
6137778
update
a-zakir Feb 19, 2025
1638068
update
a-zakir Feb 19, 2025
d9efc2a
format
a-zakir Feb 19, 2025
aede3e5
r
a-zakir Feb 19, 2025
eca7fda
r
a-zakir Feb 19, 2025
fd94a20
Merge branch 'develop' into feature/ANT-2749
a-zakir Feb 19, 2025
cdabd9e
r
a-zakir Feb 20, 2025
6e2de9a
r
a-zakir Feb 20, 2025
d78c8c2
Merge branch 'develop' into feature/ANT-2749
a-zakir Feb 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/expressions/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ target_link_libraries(expressions
PUBLIC
Boost::headers
Antares::logs
#TODO i need LinearProblemData
linear-problem-api
)


Expand Down
197 changes: 179 additions & 18 deletions src/expressions/include/antares/expressions/visitors/EvalVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@
*/
#pragma once

#include <cmath>

#include <antares/expressions/visitors/EvaluationContext.h>
#include <antares/optimisation/linear-problem-api/ILinearProblemData.h>
#include "antares/expressions/visitors/NodeVisitor.h"

namespace Antares::Optimisation::LinearProblemApi
{
struct DataSeriesKeys;
}

namespace Antares::Expressions::Visitors
{

Expand All @@ -37,42 +45,195 @@ class EvalVisitorNotImplemented: public std::invalid_argument
public:
EvalVisitorNotImplemented(const std::string& visitor, const std::string& node);
};
enum class EvaluationResultType : bool
{
CONSTANT = true,
NOTCONSTANT = false
};

class EvaluationResult
{
public:
explicit EvaluationResult(double value);

explicit EvaluationResult(const std::vector<double>& values);

EvaluationResult operator+(const EvaluationResult& right) const
{
return applyOperator(right, std::plus<>());
}

EvaluationResult operator-(const EvaluationResult& right) const
{
return applyOperator(right, std::minus<>());
}

EvaluationResult operator*(const EvaluationResult& right) const
{
return applyOperator(right, std::multiplies<>());
}

struct SafeDivides
{
double operator()(double lhs, double rhs) const
{
// if (rhs == 0.0)
// {
// throw std::runtime_error("Division by zero in EvaluationResult.");
// }
double result{0.};
try
{
result = lhs / rhs;

if (!std::isfinite(result))
{
throw EvalVisitorDivisionException(lhs, rhs, "is not a finite number");
}
}
catch (const std::exception& ex)
{
throw EvalVisitorDivisionException(lhs, rhs, ex.what());
}

return result;
}
};

EvaluationResult operator/(const EvaluationResult& right) const
{
// return applyOperator(right, std::divides<>());
return applyOperator(right, SafeDivides{});
}

EvaluationResult operator-() const
{
return applyUnaryOperator(std::negate<>());
}

[[nodiscard]] double value() const
{
return value_;
}

[[nodiscard]] std::vector<double> values() const
{
return values_;
}

[[nodiscard]] EvaluationResultType getEvaluationResultType() const
{
return evaluationResultType;
}

private:
double value_ = 0.;
std::vector<double> values_ = {};
EvaluationResultType evaluationResultType;

template<typename Op>
EvaluationResult applyOperator(const EvaluationResult& right, Op op) const;
template<typename Op>
EvaluationResult applyUnaryOperator(Op op) const;
};

template<typename Op>
EvaluationResult EvaluationResult::applyOperator(const EvaluationResult& right, Op op) const
{
EvaluationResult result(0.0);

if (evaluationResultType == EvaluationResultType::CONSTANT
&& right.evaluationResultType == EvaluationResultType::CONSTANT)
{
result.value_ = op(value_, right.value_);
}
else if (evaluationResultType == EvaluationResultType::CONSTANT)
{
result.values_ = right.values_;
for (double& v: result.values_)
{
v = op(value_, v);
}
}
else if (right.evaluationResultType == EvaluationResultType::CONSTANT)
{
result.values_ = values_;
for (double& v: result.values_)
{
v = op(v, right.value_);
}
}
else if (values_.size() == right.values_.size())
{
result.values_ = values_;
for (size_t i = 0; i < values_.size(); ++i)
{
result.values_[i] = op(values_[i], right.values_[i]);
}
}

return result;
}

template<typename Op>
EvaluationResult EvaluationResult::applyUnaryOperator(Op op) const
{
EvaluationResult result(0.0);

if (evaluationResultType == EvaluationResultType::CONSTANT)
{
result.value_ = op(value_);
}
else
{
result.values_ = values_;
for (double& v: result.values_)
{
v = op(v);
}
}

return result;
}

/**
* @brief Represents a visitor for evaluating expressions within a given context.
*/
class EvalVisitor: public NodeVisitor<double>
class EvalVisitor: public NodeVisitor<EvaluationResult>
{
public:
/**
* @brief Default constructor, creates an evaluation visitor with no context.
*/
EvalVisitor() = default; // No context (variables / parameters)
// EvalVisitor() = default; // No context (variables / parameters)

/**
* @brief Constructs an evaluation visitor with the specified context.
*
* @param context The evaluation context.
* @param dataSeriesKeys
*/
explicit EvalVisitor(EvaluationContext context);
explicit EvalVisitor(EvaluationContext context,
Optimisation::LinearProblemApi::DataSeriesKeys dataSeriesKeys);
std::string name() const override;

private:
const EvaluationContext context_;
double visit(const Nodes::SumNode* node) override;
double visit(const Nodes::SubtractionNode* node) override;
double visit(const Nodes::MultiplicationNode* node) override;
double visit(const Nodes::DivisionNode* node) override;
double visit(const Nodes::EqualNode* node) override;
double visit(const Nodes::LessThanOrEqualNode* node) override;
double visit(const Nodes::GreaterThanOrEqualNode* node) override;
double visit(const Nodes::NegationNode* node) override;
double visit(const Nodes::VariableNode* node) override;
double visit(const Nodes::ParameterNode* node) override;
double visit(const Nodes::LiteralNode* node) override;
double visit(const Nodes::PortFieldNode* node) override;
double visit(const Nodes::PortFieldSumNode* node) override;
double visit(const Nodes::ComponentVariableNode* node) override;
double visit(const Nodes::ComponentParameterNode* node) override;
Optimisation::LinearProblemApi::DataSeriesKeys dataSeriesKeys_;
EvaluationResult visit(const Nodes::SumNode* node) override;
EvaluationResult visit(const Nodes::SubtractionNode* node) override;
EvaluationResult visit(const Nodes::MultiplicationNode* node) override;
EvaluationResult visit(const Nodes::DivisionNode* node) override;
EvaluationResult visit(const Nodes::EqualNode* node) override;
EvaluationResult visit(const Nodes::LessThanOrEqualNode* node) override;
EvaluationResult visit(const Nodes::GreaterThanOrEqualNode* node) override;
EvaluationResult visit(const Nodes::NegationNode* node) override;
EvaluationResult visit(const Nodes::VariableNode* node) override;
EvaluationResult visit(const Nodes::ParameterNode* node) override;
EvaluationResult visit(const Nodes::LiteralNode* node) override;
EvaluationResult visit(const Nodes::PortFieldNode* node) override;
EvaluationResult visit(const Nodes::PortFieldSumNode* node) override;
EvaluationResult visit(const Nodes::ComponentVariableNode* node) override;
EvaluationResult visit(const Nodes::ComponentParameterNode* node) override;
};
} // namespace Antares::Expressions::Visitors
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#include <map>
#include <string>
#include <vector>

namespace Antares::Optimisation::LinearProblemApi
{
class ILinearProblemData;
}

namespace Antares::Expressions::Visitors
{
enum class ParameterType : unsigned int
{
CONSTANT = 0,
TIMESERIE = 1
};

// TODO this struct is exactly the same as the one in system.h
struct ContextParameter
{
std::string id;
ParameterType type;
std::string value;
};

/**
* @brief Represents the context for evaluating expressions.
*
Expand All @@ -17,16 +37,17 @@ class EvaluationContext
* @brief Default constructor, creates an evaluation context without parameter and variable
* values.
*/
EvaluationContext() = default;
// EvaluationContext() = default;
/**
* @brief Constructs an evaluation context with the specified parameter and variable
* values.
*
* @param parameters parameter values.
* @param constant_parameters parameter values.
* @param variables variable values.
*/
explicit EvaluationContext(std::map<std::string, double> parameters,
std::map<std::string, double> variables);
explicit EvaluationContext(std::map<std::string, ContextParameter> system_parameters,
std::map<std::string, double> variables,
Optimisation::LinearProblemApi::ILinearProblemData& data);

/**
* @brief Retrieves the value of a variable.
Expand All @@ -44,18 +65,31 @@ class EvaluationContext
* @return The value of the parameter.
* @throws std::out_of_range If the parameter is not found.
*/
double getParameterValue(const std::string& key) const;
double getSystemParameterValueAsDouble(const std::string& key) const;
std::string getSystemParameterValue(const std::string& key) const;

std::vector<double> getParameterValue(const std::string& key,
const std::string& scenarioGroup,
const unsigned scenario) const;
double getParameterValue(const std::string& key,
const std::string& scenarioGroup,
const unsigned scenario,
unsigned int hour) const;

ParameterType getParameterType(const std::string& key) const;
ContextParameter getParameter(const std::string& key) const;

private:
/**
* @brief A map storing parameter values.
*/
std::map<std::string, double> parameters_;
std::map<std::string, ContextParameter> system_parameters_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class isn't supposed to know what a system is. maybe some name like this?

Suggested change
std::map<std::string, ContextParameter> system_parameters_;
std::map<std::string, ContextParameter> parameters_types_and_values_;


/**
* @brief A map storing variable values.
*/
std::map<std::string, double> variables_;
Optimisation::LinearProblemApi::ILinearProblemData& data_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of usage makes me think that we should move & rename ILinearProblemData to something more generic, to imply that it is independent from LinearProblem. But it's not in the scope of this PR.

};

} // namespace Antares::Expressions::Visitors
Loading
Loading