diff --git a/Fit/Parameters/AttLimits.cpp b/Fit/Parameters/AttLimits.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf108f4f6bb7c602bedb91ffbefdc01b0990926c --- /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 0000000000000000000000000000000000000000..7b598f4363852b92ec2896febfb046448527b166 --- /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 d7554fa7c5fa8a23356416bcd6fbbcacc0b47ea0..63ed29bc79ce542b541589baf6932fc06d0a79ed 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 0000000000000000000000000000000000000000..8b3f4d6c3a6d5f154396c22b7fb55930f2cb73fd --- /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 dd3a35e4cd13f9dcb0419832113335106c635e79..e640daa6ab6d391d697654d745abdef55ff16c0d 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 ff3aa107c8a2be2a4d642dfbb773dd8d0311eea7..89330460ea915a2828aaa7900964bbf3178dbe0d 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 198a83a398efcd0cc91b83d3cc6ce4fedcabc046..4a69cda343f483d8253e21b94c7946e6382010a5 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)"},