From 4690ac1fafd6cd5726d7f325f7fc2e8b4039562f Mon Sep 17 00:00:00 2001 From: TimQu Date: Wed, 28 Feb 2018 16:57:16 +0100 Subject: [PATCH] Adding MultiplierTest --- .../storm/solver/LinearEquationSolverTest.cpp | 33 +---- .../solver/MinMaxLinearEquationSolverTest.cpp | 62 +++------ src/test/storm/solver/MultiplierTest.cpp | 123 ++++++++++++++++++ 3 files changed, 142 insertions(+), 76 deletions(-) create mode 100644 src/test/storm/solver/MultiplierTest.cpp diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index f1ef97220..3b5386c1f 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -32,14 +32,14 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundPower); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber("1e-6")); return env; } }; - class NativeDoubleQuickSoundPowerEnvironment { + class NativeDoubleIntervalIterationEnvironment { public: typedef double ValueType; static const bool isExact = false; @@ -47,7 +47,7 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::QuickPower); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::IntervalIteration); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber("1e-6")); return env; @@ -294,7 +294,7 @@ namespace { typedef ::testing::Types< NativeDoublePowerEnvironment, NativeDoubleSoundPowerEnvironment, - NativeDoubleQuickSoundPowerEnvironment, + NativeDoubleIntervalIterationEnvironment, NativeDoubleJacobiEnvironment, NativeDoubleGaussSeidelEnvironment, NativeDoubleSorEnvironment, @@ -353,29 +353,4 @@ namespace { EXPECT_NEAR(x[1], this->parseNumber("457/9"), this->precision()); EXPECT_NEAR(x[2], this->parseNumber("875/18"), this->precision()); } - - TYPED_TEST(LinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder builder); - storm::storage::SparseMatrixBuilder builder; - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); - - storm::storage::SparseMatrix A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector x(5); - x[4] = this->parseNumber("1"); - - auto factory = storm::solver::GeneralLinearEquationSolverFactory(); - auto solver = factory.create(this->env(), A); - ASSERT_NO_THROW(solver->repeatedMultiply(x, nullptr, 4)); - EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); - } } \ No newline at end of file diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index e34cf6a31..707b6ba4c 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -29,7 +29,20 @@ namespace { static const bool isExact = false; static storm::Environment createEnvironment() { storm::Environment env; - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().setForceSoundness(true); + env.solver().minMax().setPrecision(storm::utility::convertNumber(1e-6)); + return env; + } + }; + + class DoubleIntervalIterationEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::IntervalIteration); env.solver().setForceSoundness(true); env.solver().minMax().setPrecision(storm::utility::convertNumber(1e-6)); return env; @@ -110,6 +123,7 @@ namespace { typedef ::testing::Types< DoubleViEnvironment, DoubleSoundViEnvironment, + DoubleIntervalIterationEnvironment, DoubleTopologicalViEnvironment, DoubleTopologicalCudaViEnvironment, DoublePIEnvironment, @@ -145,52 +159,6 @@ namespace { ASSERT_NO_THROW(solver->solveEquations(this->env(), storm::OptimizationDirection::Maximize, x, b)); EXPECT_NEAR(x[0], this->parseNumber("0.99"), this->precision()); } - - TYPED_TEST(MinMaxLinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - - storm::storage::SparseMatrixBuilder builder(0, 0, 0, false, true); - ASSERT_NO_THROW(builder.newRowGroup(0)); - ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); - ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); - ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.newRowGroup(2)); - ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.newRowGroup(3)); - ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); - - storm::storage::SparseMatrix A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; - std::vector x; - - auto factory = storm::solver::GeneralMinMaxLinearEquationSolverFactory(); - auto solver = factory.create(this->env(), A); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); - EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); - } - } diff --git a/src/test/storm/solver/MultiplierTest.cpp b/src/test/storm/solver/MultiplierTest.cpp new file mode 100644 index 000000000..62a1a7c0c --- /dev/null +++ b/src/test/storm/solver/MultiplierTest.cpp @@ -0,0 +1,123 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "test/storm_gtest.h" + +#include "storm/storage/SparseMatrix.h" +#include "storm/solver/Multiplier.h" +#include "storm/environment/solver/MultiplierEnvironment.h" + +#include "storm/utility/vector.h" +namespace { + + class NativeEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Native); + return env; + } + }; + + class GmmxxEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Gmmxx); + return env; + } + }; + + template + class MultiplierTest : public ::testing::Test { + public: + typedef typename TestType::ValueType ValueType; + MultiplierTest() : _environment(TestType::createEnvironment()) {} + storm::Environment const& env() const { return _environment; } + ValueType precision() const { return TestType::isExact ? parseNumber("0") : parseNumber("1e-15");} + ValueType parseNumber(std::string const& input) const { return storm::utility::convertNumber(input);} + private: + storm::Environment _environment; + }; + + typedef ::testing::Types< + NativeEnvironment, + GmmxxEnvironment + > TestingTypes; + + TYPED_TEST_CASE(MultiplierTest, TestingTypes); + + TYPED_TEST(MultiplierTest, repeatedMultiplyTest) { + typedef typename TestFixture::ValueType ValueType; + ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder builder); + storm::storage::SparseMatrixBuilder builder; + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); + + storm::storage::SparseMatrix A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector x(5); + x[4] = this->parseNumber("1"); + + auto factory = storm::solver::MultiplierFactory(); + auto multiplier = factory.create(this->env(), A); + ASSERT_NO_THROW(multiplier->repeatedMultiply(this->env(), x, nullptr, 4)); + EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); + } + + TYPED_TEST(MultiplierTest, repeatedMultiplyAndReduceTest) { + typedef typename TestFixture::ValueType ValueType; + + storm::storage::SparseMatrixBuilder builder(0, 0, 0, false, true); + ASSERT_NO_THROW(builder.newRowGroup(0)); + ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); + ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); + ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.newRowGroup(2)); + ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.newRowGroup(3)); + ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); + + storm::storage::SparseMatrix A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; + std::vector x; + + auto factory = storm::solver::MultiplierFactory(); + auto multiplier = factory.create(this->env(), A); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); + EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); + } + +} \ No newline at end of file