Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Mitri <[email protected]>
  • Loading branch information
pet-mit committed Nov 29, 2024
1 parent 8fccd2d commit 8684bd1
Show file tree
Hide file tree
Showing 5 changed files with 350 additions and 10 deletions.
11 changes: 4 additions & 7 deletions src/solver/optim-model-filler/ReadLinearExpressionVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ LinearExpression ReadLinearExpressionVisitor::visit(const NegationNode* node)

LinearExpression ReadLinearExpressionVisitor::visit(const VariableNode* node)
{
// TODO : throw?
return LinearExpression(0, {{node->value(), 1}});
}

Expand All @@ -101,23 +100,21 @@ LinearExpression ReadLinearExpressionVisitor::visit(const LiteralNode* node)

LinearExpression ReadLinearExpressionVisitor::visit(const PortFieldNode* node)
{
throw std::invalid_argument("Linear expressions do not handle port fields yet.");
throw std::invalid_argument("ReadLinearExpressionVisitor cannot visit PortFieldNodes");
}

LinearExpression ReadLinearExpressionVisitor::visit(const PortFieldSumNode* node)
{
throw std::invalid_argument("Linear expressions do not handle port fields yet.");
throw std::invalid_argument("ReadLinearExpressionVisitor cannot visit PortFieldSumNodes");
}

LinearExpression ReadLinearExpressionVisitor::visit(const ComponentVariableNode* node)
{
// TODO : what's the difference with VariableNode ?
throw std::invalid_argument("Not implemented.");
throw std::invalid_argument("ReadLinearExpressionVisitor cannot visit ComponentVariableNodes");
}

LinearExpression ReadLinearExpressionVisitor::visit(const ComponentParameterNode* node)
{
// TODO : what's the difference with ParameterNode ?
throw std::invalid_argument("Not implemented.");
throw std::invalid_argument("ReadLinearExpressionVisitor cannot visit ComponentParameterNodes");
}
} // namespace Antares::Optimization
2 changes: 2 additions & 0 deletions src/tests/src/solver/optim-model-filler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ target_sources(${EXECUTABLE_NAME}
test_main.cpp
test_componentFiller.cpp
test_linearExpression.cpp
test_readLinearExpressionVisitor.cpp
test_readLinearConstraintVisitor.cpp
)
target_include_directories(${EXECUTABLE_NAME}
PRIVATE
Expand Down
39 changes: 36 additions & 3 deletions src/tests/src/solver/optim-model-filler/test_linearExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
#define WIN32_LEAN_AND_MEAN

#include <boost/test/unit_test.hpp>

#include "antares/solver/optim-model-filler/LinearExpression.h"

#include <antares/solver/optim-model-filler/LinearExpression.h>
#include "../../utils/unit_test_utils.h"

using namespace Antares::Optimization;
Expand Down Expand Up @@ -112,4 +110,39 @@ BOOST_AUTO_TEST_CASE(multiply_two_linear_expressions_containing_variables__excep
checkMessage("A linear expression can't have quadratic terms."));
}

BOOST_AUTO_TEST_CASE(divide_linear_expression_by_scalar)
{
LinearExpression linearExpression(4., {{"var1", -5.}, {"var2", 6.}});
LinearExpression someScalar(-2., {});

auto product = linearExpression / someScalar;

BOOST_CHECK_EQUAL(product.scalar(), -2.);
BOOST_CHECK_EQUAL(product.coefPerVar().size(), 2);
BOOST_CHECK_EQUAL(product.coefPerVar()["var1"], 2.5);
BOOST_CHECK_EQUAL(product.coefPerVar()["var2"], -3.);
}

BOOST_AUTO_TEST_CASE(divide_scalar_by_linear_expression__exception_raised)
{
LinearExpression linearExpression(4., {{"var1", -5.}, {"var2", 6.}});
LinearExpression someScalar(-2., {});

BOOST_CHECK_EXCEPTION(someScalar / linearExpression,
std::invalid_argument,
checkMessage("A linear expression can't have a variable as a dividend."));
}

BOOST_AUTO_TEST_CASE(negate_linear_expression)
{
LinearExpression linearExpression(4., {{"var1", -5.}, {"var2", 6.}});

auto negative = linearExpression.negate();

BOOST_CHECK_EQUAL(negative.scalar(), -4.);
BOOST_CHECK_EQUAL(negative.coefPerVar().size(), 2);
BOOST_CHECK_EQUAL(negative.coefPerVar()["var1"], 5.);
BOOST_CHECK_EQUAL(negative.coefPerVar()["var2"], -6.);
}

BOOST_AUTO_TEST_SUITE_END()
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright 2007-2024, RTE (https://www.rte-france.com)
* See AUTHORS.txt
* SPDX-License-Identifier: MPL-2.0
* This file is part of Antares-Simulator,
* Adequacy and Performance assessment for interconnected energy networks.
*
* Antares_Simulator is free software: you can redistribute it and/or modify
* it under the terms of the Mozilla Public Licence 2.0 as published by
* the Mozilla Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Antares_Simulator is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Mozilla Public Licence 2.0 for more details.
*
* You should have received a copy of the Mozilla Public Licence 2.0
* along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
*/

#define WIN32_LEAN_AND_MEAN

#include <boost/test/unit_test.hpp>

#include <antares/solver/expressions/Registry.hxx>
#include <antares/solver/expressions/nodes/ExpressionsNodes.h>
#include <antares/solver/optim-model-filler/ReadLinearConstraintVisitor.h>

#include "../../utils/unit_test_utils.h"

using namespace Antares::Solver;
using namespace Antares::Solver::Nodes;
using namespace Antares::Solver::Visitors;

using namespace Antares::Optimization;

BOOST_AUTO_TEST_SUITE(_read_linear_constraint_visitor_)

BOOST_AUTO_TEST_CASE(test_name)
{
ReadLinearConstraintVisitor visitor;
BOOST_CHECK_EQUAL(visitor.name(), "ReadLinearConstraintVisitor");
}

BOOST_FIXTURE_TEST_CASE(test_visit_equal_node, Registry<Node>)
{
// 5 + var1 = var2 + 3 * var1 - param1(9) ==> -2 * var1 - var2 = -14
Node* lhs = create<SumNode>(create<LiteralNode>(5.), create<VariableNode>("var1"));
Node* rhs = create<SumNode>(create<VariableNode>("var2"),
create<MultiplicationNode>(create<LiteralNode>(3.),
create<VariableNode>("var1")),
create<NegationNode>(create<ParameterNode>("param1")));
Node* node = create<EqualNode>(lhs, rhs);
EvaluationContext context({{"param1", 9.}}, {});
ReadLinearConstraintVisitor visitor(context);
auto constraint = visitor.dispatch(node);
BOOST_CHECK_EQUAL(constraint.lb, -14.);
BOOST_CHECK_EQUAL(constraint.ub, -14.);
BOOST_CHECK_EQUAL(constraint.coef_per_var.size(), 2);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var1"], -2);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var2"], -1);
}

BOOST_FIXTURE_TEST_CASE(test_visit_less_than_or_equal_node, Registry<Node>)
{
// -9 + var3 <= var1 + 5 * var2 - param1(10) ==> - var1 - 5 * var2 + var3 <= -1
Node* lhs = create<SumNode>(create<LiteralNode>(-9.), create<VariableNode>("var3"));
Node* rhs = create<SumNode>(create<VariableNode>("var1"),
create<MultiplicationNode>(create<LiteralNode>(5.),
create<VariableNode>("var2")),
create<NegationNode>(create<ParameterNode>("param1")));
Node* node = create<LessThanOrEqualNode>(lhs, rhs);
EvaluationContext context({{"param1", 10.}}, {});
ReadLinearConstraintVisitor visitor(context);
auto constraint = visitor.dispatch(node);
BOOST_CHECK_EQUAL(constraint.lb, -std::numeric_limits<double>::infinity());
BOOST_CHECK_EQUAL(constraint.ub, -1.);
BOOST_CHECK_EQUAL(constraint.coef_per_var.size(), 3);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var1"], -1);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var2"], -5);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var3"], 1);
}

BOOST_FIXTURE_TEST_CASE(test_visit_greater_than_or_equal_node, Registry<Node>)
{
// 5 + var1 >= var2 + 3 * var1 - param1(9) ==> -2 * var1 - var2 >= -14
Node* lhs = create<SumNode>(create<LiteralNode>(5.), create<VariableNode>("var1"));
Node* rhs = create<SumNode>(create<VariableNode>("var2"),
create<MultiplicationNode>(create<LiteralNode>(3.),
create<VariableNode>("var1")),
create<NegationNode>(create<ParameterNode>("param1")));
Node* node = create<GreaterThanOrEqualNode>(lhs, rhs);
EvaluationContext context({{"param1", 9.}}, {});
ReadLinearConstraintVisitor visitor(context);
auto constraint = visitor.dispatch(node);
BOOST_CHECK_EQUAL(constraint.lb, -14);
BOOST_CHECK_EQUAL(constraint.ub, std::numeric_limits<double>::infinity());
BOOST_CHECK_EQUAL(constraint.coef_per_var.size(), 2);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var1"], -2);
BOOST_CHECK_EQUAL(constraint.coef_per_var["var2"], -1);
}

BOOST_FIXTURE_TEST_CASE(test_visit_illegal_node, Registry<Node>)
{
auto lit = create<LiteralNode>(5.);
std::vector<Node*> illegal_nodes = {create<SumNode>(),
create<SubtractionNode>(lit, lit),
create<MultiplicationNode>(lit, lit),
create<DivisionNode>(lit, lit),
create<NegationNode>(lit),
create<VariableNode>("var"),
create<ParameterNode>("param"),
create<LiteralNode>(5.),
create<PortFieldNode>("port", "field"),
create<PortFieldSumNode>("port", "field"),
create<ComponentVariableNode>("x", "y"),
create<ComponentParameterNode>("x", "y")};

for (Node* node: illegal_nodes)
{
ReadLinearConstraintVisitor visitor;
BOOST_CHECK_EXCEPTION(visitor.dispatch(node),
std::invalid_argument,
checkMessage("Root node of a constraint must be a comparator."));
}
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 8684bd1

Please sign in to comment.