From 78b1c4225823dd4e47eba1b35d893757132cc671 Mon Sep 17 00:00:00 2001 From: Jason Harvey Date: Fri, 27 Sep 2024 08:21:04 -0500 Subject: [PATCH] (#115) add float limitRange function, update models --- .../Converter/GunnsElectConverterInput.cpp | 3 +- .../Converter/GunnsElectConverterOutput.cpp | 6 +- .../resistive/GunnsElectricalResistor.cpp | 2 +- ms-utils/math/MsMath.hh | 24 ++++++++ ms-utils/math/test/UtMath.cpp | 59 +++++++++++++++---- ms-utils/math/test/UtMath.hh | 5 +- 6 files changed, 78 insertions(+), 21 deletions(-) diff --git a/aspects/electrical/Converter/GunnsElectConverterInput.cpp b/aspects/electrical/Converter/GunnsElectConverterInput.cpp index 1594b603..1c0e67c6 100755 --- a/aspects/electrical/Converter/GunnsElectConverterInput.cpp +++ b/aspects/electrical/Converter/GunnsElectConverterInput.cpp @@ -457,8 +457,7 @@ GunnsBasicLink::SolutionResult GunnsElectConverterInput::confirmSolutionAcceptab } else { /// - Sensors are optional; if a sensor exists then the trip uses its sensed value of the /// truth parameter, otherwise the trip looks directly at the truth parameter. - float sensedVin = static_cast( - MsMath::limitRange(static_cast(-FLT_MAX), mPotentialVector[0], static_cast(FLT_MAX))); + float sensedVin = MsMath::limitRange(-FLT_MAX, static_cast(mPotentialVector[0]), FLT_MAX); /// - Note that since we step the sensors without a time-step, its drift malfunction isn't /// integrated. This is because we don't have the time-step in this function, and we must diff --git a/aspects/electrical/Converter/GunnsElectConverterOutput.cpp b/aspects/electrical/Converter/GunnsElectConverterOutput.cpp index f46cc6c6..c19799d4 100755 --- a/aspects/electrical/Converter/GunnsElectConverterOutput.cpp +++ b/aspects/electrical/Converter/GunnsElectConverterOutput.cpp @@ -530,10 +530,8 @@ GunnsBasicLink::SolutionResult GunnsElectConverterOutput::confirmSolutionAccepta /// - Sensors are optional; if a sensor exists then the trip uses its sensed value of /// the truth parameter, otherwise the trip looks directly at the truth parameter. - float sensedVout = static_cast( - MsMath::limitRange(static_cast(-FLT_MAX), mPotentialVector[0], static_cast(FLT_MAX))); - float sensedIout = static_cast( - MsMath::limitRange(static_cast(-FLT_MAX), mFlux, static_cast(FLT_MAX))); + float sensedVout = MsMath::limitRange(-FLT_MAX, static_cast(mPotentialVector[0]), FLT_MAX); + float sensedIout = MsMath::limitRange(-FLT_MAX, static_cast(mFlux), FLT_MAX); /// - Note that since we step the sensors without a time-step, its drift malfunction /// isn't integrated. This is because we don't have the time-step in this function, diff --git a/aspects/electrical/resistive/GunnsElectricalResistor.cpp b/aspects/electrical/resistive/GunnsElectricalResistor.cpp index 572b2247..e06da78a 100644 --- a/aspects/electrical/resistive/GunnsElectricalResistor.cpp +++ b/aspects/electrical/resistive/GunnsElectricalResistor.cpp @@ -177,7 +177,7 @@ void GunnsElectricalResistor::validate() const } /// - Throw an exception if electrical efficiency <= 0 or electrical efficiency >= 1. - if (!MsMath::isInRange(static_cast(FLT_EPSILON), mElectricalEfficiency, 1.0 - static_cast(FLT_EPSILON))) { + if (!MsMath::isInRange(FLT_EPSILON, static_cast(mElectricalEfficiency), 1.0 - FLT_EPSILON)) { GUNNS_ERROR(TsInitializationException, "Invalid Configuration Data", "Electrical Efficiency outside valid range (0-1)."); } } diff --git a/ms-utils/math/MsMath.hh b/ms-utils/math/MsMath.hh index 04a3e6b2..dc57aa93 100755 --- a/ms-utils/math/MsMath.hh +++ b/ms-utils/math/MsMath.hh @@ -72,6 +72,8 @@ class MsMath static double protectedDiv(const double num, const double den, const double threshold = DBL_EPSILON, const double retval = 0.0); /// @brief Limits the value of a double argument to a specified range (lower <= x <= upper). static double limitRange(const double lower, const double x, const double upper); + /// @brief Limits the value of a float argument to a specified range (lower <= x <= upper). + static float limitRange(const float lower, const float x, const float upper); /// @brief Limits the value of an integer argument to a specified range (lower <= x <= upper). static int limitRange(const int lower, const int x, const int upper); /// @brief Is the double input within specified range (lower <= x <= upper)? @@ -409,6 +411,28 @@ inline double MsMath::limitRange(const double lower, const double x, const doubl return std::max(std::min(x, upper), lower); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @param[in] lower (--) Lower limit of range. +/// @param[in] x (--) Input argument to be limited. +/// @param[in] upper (--) Upper limit of range. +/// +/// @return float (--) The value limited to the specified range. +/// +/// @warning If lower > upper, then lower is returned without complaint, so don't do that. +/// +/// @details Limits the value of a float argument to the specified range (lower <= x <= upper). +/// \verbatim +/// _ +/// | lower, x < lower +/// result = | x, lower <= x <= upper +/// |_ upper, x > upper +/// \endverbatim +//////////////////////////////////////////////////////////////////////////////////////////////////// +inline float MsMath::limitRange(const float lower, const float x, const float upper) +{ + return std::max(std::min(x, upper), lower); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /// @param[in] lower (--) Lower limit of range. /// @param[in] x (--) Input argument to be limited. diff --git a/ms-utils/math/test/UtMath.cpp b/ms-utils/math/test/UtMath.cpp index 2c9f0423..1db91bae 100644 --- a/ms-utils/math/test/UtMath.cpp +++ b/ms-utils/math/test/UtMath.cpp @@ -1,10 +1,7 @@ -/************************** TRICK HEADER *********************************************************** +/* @copyright Copyright 2024 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. - - LIBRARY DEPENDENCY: - () -***************************************************************************************************/ +*/ #include @@ -666,12 +663,48 @@ void UtMath::testLimitRangeDouble() std::cout << "Pass"; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @details Tests the method for range limiting floats. +//////////////////////////////////////////////////////////////////////////////////////////////////// +void UtMath::testLimitRangeFloat() +{ + std::cout << "\n.Math Test 12: Limit Range Float Tests......................................"; + + /// @test for argument well within range + float expected = 1.0F; + float returned = MsMath::limitRange(0.0F, 1.0F, 2.0F); + CPPUNIT_ASSERT(expected == returned); + + /// @test for argument at lower limit + returned = MsMath::limitRange(1.0F, 1.0F, 2.0F); + CPPUNIT_ASSERT(expected == returned); + + /// @test for argument below lower limit + returned = MsMath::limitRange(1.0F, 0.0F, 2.0F); + CPPUNIT_ASSERT(expected == returned); + + /// @test for argument at upper limit + returned = MsMath::limitRange(0.0F, 1.0F, 1.0F); + CPPUNIT_ASSERT(expected == returned); + + /// @test for argument above upper limit + returned = MsMath::limitRange(0.0F, 2.0F, 1.0F); + CPPUNIT_ASSERT(expected == returned); + + /// @test for upper < lower + expected = 2.0F; + returned = MsMath::limitRange(2.0F, 1.0F, 0.0F); + CPPUNIT_ASSERT(expected == returned); + + std::cout << "Pass"; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// /// @details Tests the method for range limiting integers. //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testLimitRangeInt() { - std::cout << "\n.Math Test 12: Limit Range Integer Tests...................................."; + std::cout << "\n.Math Test 13: Limit Range Integer Tests...................................."; /// @test for argument well within range double expected = 1.0; @@ -711,7 +744,7 @@ void UtMath::testLimitRangeInt() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testIsInRangeDouble() { - std::cout << "\n.Math Test 13: Is In Range Double Tests....................................."; + std::cout << "\n.Math Test 14: Is In Range Double Tests....................................."; /// @test for argument well within range CPPUNIT_ASSERT(MsMath::isInRange(0.0, 1.0, 2.0)); @@ -740,7 +773,7 @@ void UtMath::testIsInRangeDouble() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testIsInRangeInt() { - std::cout << "\n.Math Test 14: Is In Range Integer Tests...................................."; + std::cout << "\n.Math Test 15: Is In Range Integer Tests...................................."; /// @test for argument well within range CPPUNIT_ASSERT(MsMath::isInRange(0, 1, 2)); @@ -769,7 +802,7 @@ void UtMath::testIsInRangeInt() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testInnerLimitDouble() { - std::cout << "\n.Math Test 15: Inner Limit Double Tests....................................."; + std::cout << "\n.Math Test 16: Inner Limit Double Tests....................................."; /// @test for argument well below lower limit double expected = -1.0; @@ -824,7 +857,7 @@ void UtMath::testInnerLimitDouble() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testInnerLimitInt() { - std::cout << "\n.Math Test 16: Inner Limit Integer Tests...................................."; + std::cout << "\n.Math Test 17: Inner Limit Integer Tests...................................."; /// @test for argument well below lower limit int expected = -1; @@ -869,7 +902,7 @@ void UtMath::testInnerLimitInt() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testRounding() { - std::cout << "\n.Math Test 17: Rounding Tests..............................................."; + std::cout << "\n.Math Test 18: Rounding Tests..............................................."; /// @test for argument exactly equal to integer int expected = 1; @@ -911,7 +944,7 @@ void UtMath::testRounding() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testQuantize() { - std::cout << "\n.Math Test 18: Quantize Tests..............................................."; + std::cout << "\n.Math Test 19: Quantize Tests..............................................."; double arg = 3.14159; double expected = 3.0; @@ -998,7 +1031,7 @@ void UtMath::testQuantize() //////////////////////////////////////////////////////////////////////////////////////////////////// void UtMath::testFastPow() { - std::cout << "\n.Math Test 19: fastPow Tests................................................"; + std::cout << "\n.Math Test 20: fastPow Tests................................................"; double base = 0.0; double exp = 1.25; diff --git a/ms-utils/math/test/UtMath.hh b/ms-utils/math/test/UtMath.hh index 0ceace57..c86b9a5b 100644 --- a/ms-utils/math/test/UtMath.hh +++ b/ms-utils/math/test/UtMath.hh @@ -5,7 +5,7 @@ /// @defgroup UT_TSM_UTILITIES_MATH_MATH MsMath Unit Tests /// @ingroup UT_TSM_UTILITIES_MATH /// -/// @copyright Copyright 2019 United States Government as represented by the Administrator of the +/// @copyright Copyright 2024 United States Government as represented by the Administrator of the /// National Aeronautics and Space Administration. All Rights Reserved. /// /// @details Unit Tests for the Math class. @@ -54,6 +54,8 @@ class UtMath : public CppUnit::TestFixture void testprotectedDiv(); /// @brief Test double limitRange method. void testLimitRangeDouble(); + /// @brief Test float limitRange method. + void testLimitRangeFloat(); /// @brief Test int limitRange method. void testLimitRangeInt(); /// @brief Test double isInRange method. @@ -83,6 +85,7 @@ class UtMath : public CppUnit::TestFixture CPPUNIT_TEST(testProtectedLog); CPPUNIT_TEST(testprotectedDiv); CPPUNIT_TEST(testLimitRangeDouble); + CPPUNIT_TEST(testLimitRangeFloat); CPPUNIT_TEST(testLimitRangeInt); CPPUNIT_TEST(testIsInRangeDouble); CPPUNIT_TEST(testIsInRangeInt);