From f5d71da5fdd2023e82b10c4e58ca1991d9316e59 Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Mon, 19 Sep 2016 13:59:06 +0200 Subject: [PATCH] New AttLimits to provide coupling between RealLimits and Attributes. --- Fit/Parameters/AttLimits.cpp | 102 ++++++++++++++++++++++++++ Fit/Parameters/AttLimits.h | 58 +++++++++++++++ Fit/Parameters/Attributes.h | 1 + Tests/UnitTests/Fit/0/AttLimitsTest.h | 83 +++++++++++++++++++++ Tests/UnitTests/Fit/0/testlist.h | 1 + auto/Wrap/libBornAgainFit.py | 5 ++ auto/Wrap/libBornAgainFit_wrap.cpp | 23 ++++++ 7 files changed, 273 insertions(+) create mode 100644 Fit/Parameters/AttLimits.cpp create mode 100644 Fit/Parameters/AttLimits.h create mode 100644 Tests/UnitTests/Fit/0/AttLimitsTest.h diff --git a/Fit/Parameters/AttLimits.cpp b/Fit/Parameters/AttLimits.cpp new file mode 100644 index 00000000000..bf108f4f6bb --- /dev/null +++ b/Fit/Parameters/AttLimits.cpp @@ -0,0 +1,102 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file Fit/Parameters/AttLimits.cpp +//! @brief Implements and implements class AttLimits. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2015 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "AttLimits.h" + + +AttLimits::AttLimits() + : m_limits(RealLimits::limitless()) + , m_att_fixed(Attributes::free()) +{ + +} + +AttLimits AttLimits::lowerLimited(double bound_value) +{ + return AttLimits(RealLimits::lowerLimited(bound_value), Attributes::free()); +} + +AttLimits AttLimits::positive() +{ + return AttLimits(RealLimits::positive(), Attributes::free()); +} + +AttLimits AttLimits::nonnegative() +{ + return AttLimits(RealLimits::nonnegative(), Attributes::free()); +} + +AttLimits AttLimits::upperLimited(double bound_value) +{ + return AttLimits(RealLimits::upperLimited(bound_value), Attributes::free()); +} + +AttLimits AttLimits::limited(double left_bound_value, double right_bound_value) +{ + return AttLimits(RealLimits::limited(left_bound_value, right_bound_value), Attributes::free()); +} + +AttLimits AttLimits::fixed() +{ + return AttLimits(RealLimits::limitless(), Attributes::fixed()); +} + +bool AttLimits::isFixed() const +{ + return m_att_fixed.isFixed(); +} + +bool AttLimits::isLimited() const +{ + return m_att_fixed.isFree() && m_limits.hasLowerAndUpperLimits(); +} + +bool AttLimits::isUpperLimited() const +{ + return m_att_fixed.isFree() && !m_limits.hasLowerLimit() && m_limits.hasUpperLimit(); +} + +bool AttLimits::isLowerLimited() const +{ + return m_att_fixed.isFree() && m_limits.hasLowerLimit() && !m_limits.hasUpperLimit(); +} + +bool AttLimits::isLimitless() const +{ + return m_att_fixed.isFree() && !m_limits.hasLowerLimit() && !m_limits.hasUpperLimit(); +} + +double AttLimits::lowerLimit() const +{ + return m_limits.getLowerLimit(); +} + +double AttLimits::upperLimit() const +{ + return m_limits.getUpperLimit(); +} + +void AttLimits::setFixed(bool isFixed) +{ + m_limits.removeLimits(); + m_att_fixed.setFixed(isFixed); +} + +AttLimits::AttLimits(const RealLimits &limits, const Attributes &fixedAttr) + : m_limits(limits) + , m_att_fixed(fixedAttr) +{ + +} diff --git a/Fit/Parameters/AttLimits.h b/Fit/Parameters/AttLimits.h new file mode 100644 index 00000000000..7b598f43638 --- /dev/null +++ b/Fit/Parameters/AttLimits.h @@ -0,0 +1,58 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file Fit/Parameters/AttLimits.h +//! @brief Defines and implements class AttLimits. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2015 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef ATTLIMITS_H +#define ATTLIMITS_H + +#include "WinDllMacros.h" +#include "RealLimits.h" +#include "Attributes.h" + +//! @class AttLimits +//! @ingroup fitting +//! @brief The AttLimits class defines limited/free attribute of fit parameter. + +class BA_CORE_API_ AttLimits +{ +public: + AttLimits(); + + static AttLimits lowerLimited(double bound_value); + static AttLimits positive(); + static AttLimits nonnegative(); + static AttLimits upperLimited(double bound_value); + static AttLimits limited(double left_bound_value, double right_bound_value); + static AttLimits fixed(); + + bool isFixed() const; + bool isLimited() const; + bool isUpperLimited() const; + bool isLowerLimited() const; + bool isLimitless() const; + + double lowerLimit() const; + double upperLimit() const; + + void setFixed(bool isFixed); + +private: + AttLimits(const RealLimits &limits, const Attributes &fixedAttr); + + RealLimits m_limits; + Attributes m_att_fixed; +}; + + +#endif diff --git a/Fit/Parameters/Attributes.h b/Fit/Parameters/Attributes.h index d7554fa7c5f..63ed29bc79c 100644 --- a/Fit/Parameters/Attributes.h +++ b/Fit/Parameters/Attributes.h @@ -32,6 +32,7 @@ class BA_CORE_API_ Attributes void setFixed(bool is_fixed) { m_is_fixed = is_fixed; } bool isFixed() const { return m_is_fixed; } + bool isFree() const { return !isFixed(); } friend std::ostream& operator<<(std::ostream& ostr, const Attributes& m) { m.print(ostr); return ostr; } diff --git a/Tests/UnitTests/Fit/0/AttLimitsTest.h b/Tests/UnitTests/Fit/0/AttLimitsTest.h new file mode 100644 index 00000000000..8b3f4d6c3a6 --- /dev/null +++ b/Tests/UnitTests/Fit/0/AttLimitsTest.h @@ -0,0 +1,83 @@ +#ifndef ATTLIMITSTEST_H +#define ATTLIMITSTEST_H + +#include "AttLimits.h" +#include "gtest/gtest.h" + +class AttLimitsTest : public ::testing::Test +{ + protected: + AttLimitsTest(){} + virtual ~AttLimitsTest(){} + +}; + +TEST_F(AttLimitsTest, InitialState) +{ + AttLimits limits; + EXPECT_FALSE(limits.isFixed()); + EXPECT_FALSE(limits.isLimited()); + EXPECT_FALSE(limits.isUpperLimited()); + EXPECT_FALSE(limits.isLowerLimited()); + EXPECT_TRUE(limits.isLimitless()); +} + +TEST_F(AttLimitsTest, LowerLimited) +{ + AttLimits limits = AttLimits::lowerLimited(1.0); + EXPECT_FALSE(limits.isFixed()); + EXPECT_FALSE(limits.isLimited()); + EXPECT_FALSE(limits.isUpperLimited()); + EXPECT_TRUE(limits.isLowerLimited()); + EXPECT_FALSE(limits.isLimitless()); + EXPECT_EQ(1.0, limits.lowerLimit()); + EXPECT_EQ(0.0, limits.upperLimit()); +} + +TEST_F(AttLimitsTest, UpperLimited) +{ + AttLimits limits = AttLimits::upperLimited(1.0); + EXPECT_FALSE(limits.isFixed()); + EXPECT_FALSE(limits.isLimited()); + EXPECT_TRUE(limits.isUpperLimited()); + EXPECT_FALSE(limits.isLowerLimited()); + EXPECT_FALSE(limits.isLimitless()); + EXPECT_EQ(0.0, limits.lowerLimit()); + EXPECT_EQ(1.0, limits.upperLimit()); +} + +TEST_F(AttLimitsTest, Fixed) +{ + AttLimits limits = AttLimits::fixed(); + EXPECT_TRUE(limits.isFixed()); + EXPECT_FALSE(limits.isLimited()); + EXPECT_FALSE(limits.isUpperLimited()); + EXPECT_FALSE(limits.isLowerLimited()); + EXPECT_FALSE(limits.isLimitless()); + EXPECT_EQ(0.0, limits.lowerLimit()); + EXPECT_EQ(0.0, limits.upperLimit()); +} + +TEST_F(AttLimitsTest, Limited) +{ + AttLimits limits = AttLimits::limited(1.0, 2.0); + EXPECT_FALSE(limits.isFixed()); + EXPECT_TRUE(limits.isLimited()); + EXPECT_FALSE(limits.isUpperLimited()); + EXPECT_FALSE(limits.isLowerLimited()); + EXPECT_FALSE(limits.isLimitless()); + EXPECT_EQ(1.0, limits.lowerLimit()); + EXPECT_EQ(2.0, limits.upperLimit()); + + // making it fixed, this should remove limits + limits.setFixed(true); + EXPECT_TRUE(limits.isFixed()); + EXPECT_FALSE(limits.isLimited()); + EXPECT_FALSE(limits.isUpperLimited()); + EXPECT_FALSE(limits.isLowerLimited()); + EXPECT_FALSE(limits.isLimitless()); + EXPECT_EQ(0.0, limits.lowerLimit()); + EXPECT_EQ(0.0, limits.upperLimit()); +} + +#endif diff --git a/Tests/UnitTests/Fit/0/testlist.h b/Tests/UnitTests/Fit/0/testlist.h index dd3a35e4cd1..e640daa6ab6 100644 --- a/Tests/UnitTests/Fit/0/testlist.h +++ b/Tests/UnitTests/Fit/0/testlist.h @@ -1,5 +1,6 @@ // To renew this file, run /G/ba/dev-tools/code-tools/update-gtestlist.py <directory> +#include "AttLimitsTest.h" #include "FitObjectTest.h" #include "FitParameterLinkedTest.h" #include "FitParameterSetTest.h" diff --git a/auto/Wrap/libBornAgainFit.py b/auto/Wrap/libBornAgainFit.py index ff3aa107c8a..89330460ea9 100644 --- a/auto/Wrap/libBornAgainFit.py +++ b/auto/Wrap/libBornAgainFit.py @@ -1502,6 +1502,11 @@ class Attributes(_object): return _libBornAgainFit.Attributes_isFixed(self) + def isFree(self): + """isFree(Attributes self) -> bool""" + return _libBornAgainFit.Attributes_isFree(self) + + def __eq__(self, other): """__eq__(Attributes self, Attributes other) -> bool""" return _libBornAgainFit.Attributes___eq__(self, other) diff --git a/auto/Wrap/libBornAgainFit_wrap.cpp b/auto/Wrap/libBornAgainFit_wrap.cpp index 198a83a398e..4a69cda343f 100644 --- a/auto/Wrap/libBornAgainFit_wrap.cpp +++ b/auto/Wrap/libBornAgainFit_wrap.cpp @@ -18643,6 +18643,28 @@ fail: } +SWIGINTERN PyObject *_wrap_Attributes_isFree(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + Attributes *arg1 = (Attributes *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + bool result; + + if (!PyArg_ParseTuple(args,(char *)"O:Attributes_isFree",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Attributes, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Attributes_isFree" "', argument " "1"" of type '" "Attributes const *""'"); + } + arg1 = reinterpret_cast< Attributes * >(argp1); + result = (bool)((Attributes const *)arg1)->isFree(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Attributes___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; Attributes *arg1 = (Attributes *) 0 ; @@ -22182,6 +22204,7 @@ static PyMethodDef SwigMethods[] = { "bool Attributes::isFixed() const \n" "\n" ""}, + { (char *)"Attributes_isFree", _wrap_Attributes_isFree, METH_VARARGS, (char *)"Attributes_isFree(Attributes self) -> bool"}, { (char *)"Attributes___eq__", _wrap_Attributes___eq__, METH_VARARGS, (char *)"Attributes___eq__(Attributes self, Attributes other) -> bool"}, { (char *)"Attributes___ne__", _wrap_Attributes___ne__, METH_VARARGS, (char *)"Attributes___ne__(Attributes self, Attributes other) -> bool"}, { (char *)"delete_Attributes", _wrap_delete_Attributes, METH_VARARGS, (char *)"delete_Attributes(Attributes self)"}, -- GitLab