Commit 732a1d01 by Pierre-Henri Wuillemin

master sync'ed

parents fb972c39 2c1271b1
Pipeline #18656814 failed with stages
in 26 minutes 40 seconds
......@@ -3,6 +3,8 @@ stages:
- pyagrum
- agrum_test
- pyagrum_test
- documentation
- deployment
cache:
untracked: false
......@@ -140,3 +142,37 @@ windows_pyAgrum_test:
script:
- pip install -r wrappers/pyAgrum/testunits/requirements.txt
- python act --no-fun test release pyAgrum %ACT_OPTIONS% -t quick || python act --no-fun clean && python act --no-fun test release pyAgrum %ACT_OPTIONS% -t quick
################################################################################
# Documentation
################################################################################
agrum_master_documentation:
only:
- tags
- master@agrumery/aGrUM
tags:
- linux
- python3
- doxygen
stage: documentation
allow_failure: true
script:
- python act clean --no-fun && python act release doc aGrUM --no-fun
- cd ${CI_PROJECT_DIR}/build/release/docs/html && tar czf $(basename ${CI_COMMIT_REF_NAME}).tgz ./* && mv $(basename ${CI_COMMIT_REF_NAME}).tgz ${CI_PROJECT_DIR}
- sshpass -p "${OVH_PASSWORD}" ssh -oStrictHostKeyChecking=no ${OVH_LOGIN}@${OVH_URL} "rm -rf ~/www/aGrUM/${CI_COMMIT_REF_NAME}"
- sshpass -p "${OVH_PASSWORD}" scp -oStrictHostKeyChecking=no ${CI_PROJECT_DIR}/$(basename ${CI_COMMIT_REF_NAME}).tgz ${OVH_LOGIN}@${OVH_URL}:~/$(basename ${CI_COMMIT_REF_NAME}).tgz
- sshpass -p "${OVH_PASSWORD}" ssh -oStrictHostKeyChecking=no ${OVH_LOGIN}@${OVH_URL} "mkdir -p ~/www/aGrUM/${CI_COMMIT_REF_NAME}"
- sshpass -p "${OVH_PASSWORD}" ssh -oStrictHostKeyChecking=no ${OVH_LOGIN}@${OVH_URL} "tar xzf ~/$(basename ${CI_COMMIT_REF_NAME}).tgz -C ~/www/aGrUM/${CI_COMMIT_REF_NAME}/"
- sshpass -p "${OVH_PASSWORD}" ssh -oStrictHostKeyChecking=no ${OVH_LOGIN}@${OVH_URL} "rm -f ~/$(basename ${CI_COMMIT_REF_NAME}).tgz"
################################################################################
# Deployment
################################################################################
aGruM-Deploy:
only:
- tags
tags:
- linux
stage: deployment
script:
- curl -X POST -F token=${AGRUM_DEPLOY_TOKEN} -F ref=master https://gitlab.com/api/v4/projects/4935470/trigger/pipeline
......@@ -2,6 +2,37 @@
Welcome to aGrUM's contribution guide and thank you for helping us making aGrUM the best open source API for using Graphical Probabilistic Models.
## Reporting new issue
[Opening an issue](https://gitlab.com/agrumery/aGrUM/issues/new?issue%5Bassignee_id%5D=&issue%5Bmilestone_id%5D=) does not imply to fill the aGrUM's contribution agreement.
Please follow as much as possible this template :
> ⚠️ *One issue, One bug*
>
>(Describe your issue in detail. Provide as much as possible steps to reproduce.)
>
>#### Environment
>
>(describe your os, you CC compiler, your python version, the agrum version, etc.)
>
>#### Expected Behavior
>
>(Write what you thought would happen.)
>
>#### Actual Behavior
>
>(Write what happened. Include screenshots if needed.)
## What to contribute
You can contribute to aGrUM in the following domains:
* Code
* Documentation
* Packaging and distributing
## Before contributing
Before submitting your first contribution, please take the time to fill aGrUM's contribution agreement. We will not accept any contribution without it !
......@@ -13,14 +44,6 @@ You can find the individual agreement [here](https://gitlab.com/agrumery/aGrUM/w
We are planning to change aGrUM's licence, but don't worry aGrUM will always be Open Source. To do so, we need your agreement as one of aGrUM's contributor. There is also some legal consideration about how your contribution can be used and distributed with aGrUM. So please take your time and read the agreement before sending it to us. And if you have any question, feel free to ask us at [info@agrum.org](mailto:info@agrum.org).
## What to contribute
You can contribute to aGrUM in the following domains:
* Code
* Documentation
* Packaging and distributing
### Contributing to aGrUM's Code
Before contributing to aGrUM's code you should ask us before hand at [info@agrum.org](mailto:info@agrum.org). This will prevent you from submiting code that we won't integrate: aGrUM's is still under heavy development and some featured modules like `bayesnet` or `learning` are refactored quite often.
......
......@@ -910,8 +910,8 @@ namespace gum {
auto& elt = get(child);
if (PRMClassElement< GUM_SCALAR >::isAttribute(elt)) {
auto& attr = static_cast< PRMAttribute< GUM_SCALAR >& >(elt);
auto& old_type = slotchain->lastElt().type().variable();
auto& new_type = sc->lastElt().type().variable();
auto& old_type = slotchain->lastElt().type();
auto& new_type = sc->lastElt().type();
attr.swap(old_type, new_type);
} else {
GUM_ERROR(OperationNotAllowed, "unexpected ClassElement");
......
......@@ -27,9 +27,9 @@
#define GUM_CONTINUOUS_VARIABLE_H
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <limits>
#include <agrum/agrum.h>
#include <agrum/variables/variable.h>
......@@ -40,9 +40,10 @@ namespace gum {
* @class ContinuousVariable
* @brief Defines a continuous random variable.
*/
template < typename GUM_SCALAR = float >
template <typename GUM_SCALAR = float>
class ContinuousVariable : public Variable {
public:
// ##########################################################################
/// @name Constructors / Destructors
// ##########################################################################
......@@ -53,28 +54,29 @@ namespace gum {
/** It is possible to create ContinuousVariable with lower_bound > upper_bound.
* In this case, the min and the max are swapped.
* By default, the range of the variable is (-inf,+inf). */
ContinuousVariable(
const std::string& aName,
const std::string& aDesc,
GUM_SCALAR lower_bound = -std::numeric_limits< GUM_SCALAR >::infinity(),
GUM_SCALAR upper_bound = std::numeric_limits< GUM_SCALAR >::infinity());
ContinuousVariable ( const std::string& aName,
const std::string& aDesc,
GUM_SCALAR lower_bound =
-std::numeric_limits<GUM_SCALAR>::infinity (),
GUM_SCALAR upper_bound =
std::numeric_limits<GUM_SCALAR>::infinity () );
/// Copy Constructor.
ContinuousVariable(const ContinuousVariable< GUM_SCALAR >& from);
ContinuousVariable ( const ContinuousVariable<GUM_SCALAR>& from );
/// generalized copy constructor
template < typename TX_VAL >
ContinuousVariable(const ContinuousVariable< TX_VAL >& from);
template <typename TX_VAL>
ContinuousVariable ( const ContinuousVariable<TX_VAL>& from );
/// move constructor
ContinuousVariable(ContinuousVariable< GUM_SCALAR >&& from);
ContinuousVariable(ContinuousVariable<GUM_SCALAR>&& from );
/// destructor
virtual ~ContinuousVariable();
virtual ~ContinuousVariable ();
/// Copy Factory.
/// @return Returns a pointer on a new copy of this.
virtual ContinuousVariable< GUM_SCALAR >* clone() const;
virtual ContinuousVariable<GUM_SCALAR>* clone() const;
/// @}
......@@ -86,23 +88,23 @@ namespace gum {
/// @{
/// copy operator
ContinuousVariable< GUM_SCALAR >&
operator=(const ContinuousVariable< GUM_SCALAR >& from);
ContinuousVariable<GUM_SCALAR>&
operator= (const ContinuousVariable<GUM_SCALAR>& from );
/// generalized copy operator
template < typename TX_VAL >
ContinuousVariable< GUM_SCALAR >&
operator=(const ContinuousVariable< TX_VAL >& from);
template <typename TX_VAL>
ContinuousVariable<GUM_SCALAR>&
operator= (const ContinuousVariable<TX_VAL>& from );
/// move operator
ContinuousVariable< GUM_SCALAR >&
operator=(ContinuousVariable< GUM_SCALAR >&& from);
ContinuousVariable<GUM_SCALAR>&
operator= (ContinuousVariable<GUM_SCALAR>&& from );
/// returns the T_VAL corresponding to a string
/** @throw OutOfBounds is raised if the value does not belong to the
* domain of the variable
* @throw TypeError if the string cannot be converted into a T_VAL */
GUM_SCALAR operator[](const std::string& str) const;
GUM_SCALAR operator[] ( const std::string& str ) const;
/// @}
......@@ -114,20 +116,20 @@ namespace gum {
/// @{
/// returns the lower bound of the domain of the variable
GUM_SCALAR lowerBound() const;
GUM_SCALAR lowerBound () const;
/// returns the upper bound of the domain of the variable
GUM_SCALAR upperBound() const;
GUM_SCALAR upperBound () const;
/// updates the lower bound of the domain of the variable
/** @throw OutOfBounds is raised if the new bound is higher than the
* current upper bound. */
void setLowerBound(const GUM_SCALAR& new_bound);
void setLowerBound ( const GUM_SCALAR& new_bound );
/// updates the lower bound of the domain of the variable
/** @throw OutOfBounds is raised if the new bound is lower than the
* current lower bound */
void setUpperBound(const GUM_SCALAR& new_bound);
/** @throw OutOfBounds is raised if the new bound is lower than the
* current lower bound */
void setUpperBound ( const GUM_SCALAR& new_bound );
/// returns a string containing the value of the variable passed in argument
/**
......@@ -135,10 +137,10 @@ namespace gum {
* @throw OutOfBounds is raised if the value does not belong to the
* domain of the variable
*/
virtual std::string label(const GUM_SCALAR& value) const;
virtual std::string label ( const GUM_SCALAR& value ) const;
/// Returns true if the param belongs to the domain of the variable
bool belongs(const GUM_SCALAR& value) const;
bool belongs ( const GUM_SCALAR& value ) const;
/// returns the domain of the variable as a string
std::string domain() const;
......@@ -155,19 +157,32 @@ namespace gum {
/// @}
private:
private:
// the lower bound.
GUM_SCALAR __lower_bound;
// the upper bound.
GUM_SCALAR __upper_bound;
template <typename TX_VAL>
friend class ContinuousVariable;
};
/// for friendly displaying the content of the variable
template < typename T_VAL >
std::ostream& operator<<(std::ostream&, const ContinuousVariable< T_VAL >&);
template <typename T_VAL>
std::ostream& operator<<(std::ostream&, const ContinuousVariable<T_VAL>& );
// specialized operator[] for real numbers
template <>
float ContinuousVariable<float>::operator[] ( const std::string& str ) const;
template <>
double ContinuousVariable<double>::operator[] ( const std::string& str ) const;
} /* namespace gum */
// always include the template implementation
......
......@@ -25,6 +25,9 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <cctype>
#include <cstdlib>
#include <agrum/variables/continuousVariable.h>
namespace gum {
......@@ -32,39 +35,61 @@ namespace gum {
/// returns the GUM_SCALAR corresponding to a string, specialized for floats
template <>
INLINE float ContinuousVariable< float >::
operator[](const std::string& str) const {
INLINE float
ContinuousVariable<float>::operator[] ( const std::string& str ) const {
float value;
std::size_t pos;
try {
value = std::stof(str);
} catch (...) {
GUM_ERROR(TypeError, "cannot convert the string into a float");
value = std::stof ( str, &pos );
}
if (belongs(value))
catch ( std::invalid_argument& ) {
GUM_ERROR ( TypeError, "the value is not a number" );
}
catch ( std::out_of_range& ) {
GUM_ERROR ( OutOfBounds, "the value is too huge" );
}
// check whether there remains non-space unprocessed characters
for ( auto iter = str.begin() + pos, end = str.end (); iter != end; ++iter ) {
if ( ! std::isspace(static_cast<unsigned char>( *iter ) ) )
GUM_ERROR ( TypeError, "the value is not a number" );
}
if ( belongs ( value ) )
return value;
else
GUM_ERROR(OutOfBounds,
"the value does not delong to the domain of the variable");
GUM_ERROR ( OutOfBounds,
"the value does not delong to the domain of the variable" );
}
/// returns the GUM_SCALAR corresponding to a string, specialized for doubles
template <>
ALWAYS_INLINE double ContinuousVariable< double >::
operator[](const std::string& str) const {
INLINE double
ContinuousVariable<double>::operator[] ( const std::string& str ) const {
double value;
std::size_t pos;
try {
value = std::stod(str);
} catch (...) {
GUM_ERROR(TypeError, "cannot convert the string into a float");
value = std::stod ( str, &pos );
}
if (belongs(value))
catch ( std::invalid_argument& ) {
GUM_ERROR ( TypeError, "the value is not a number" );
}
catch ( std::out_of_range& ) {
GUM_ERROR ( OutOfBounds, "the value is too huge" );
}
// check whether there remains non-space unprocessed characters
for ( auto iter = str.begin() + pos, end = str.end (); iter != end; ++iter ) {
if ( ! std::isspace(static_cast<unsigned char>( *iter ) ) )
GUM_ERROR ( TypeError, "the value is not a number" );
}
if ( belongs ( value ) )
return value;
else
GUM_ERROR(OutOfBounds,
"the value does not delong to the domain of the variable");
GUM_ERROR ( OutOfBounds,
"the value does not delong to the domain of the variable" );
}
} /* namespace gum */
......
......@@ -24,6 +24,7 @@
* @author Christophe GONZALES and Pierre-Henri WUILLEMIN
*/
#include <utility>
#include <sstream>
#include <agrum/agrum.h>
#include <agrum/variables/continuousVariable.h>
......
/***************************************************************************
* Copyright (C) 2017 by Pierre-Henri WUILLEMIN and Christophe GONZALES *
* {prenom.nom}_at_lip6.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <sstream>
#include <string>
#include <regex>
#include <cxxtest/AgrumTestSuite.h>
#include <cxxtest/testsuite_utils.h>
#include <agrum/variables/continuousVariable.h>
namespace gum_tests {
class ContinuousVariableTestSuite : public CxxTest::TestSuite {
public:
void test_constructors () {
gum::ContinuousVariable<> var1("x1", "" );
TS_ASSERT ( var1.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var1.lowerBound () ==
-std::numeric_limits<float>::infinity () );
gum::ContinuousVariable<> var2("x2", "", -10, 10 );
TS_ASSERT ( var2.lowerBound () == -10.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
gum::ContinuousVariable<> var3( var2 );
TS_ASSERT ( var3.lowerBound () == -10.0f );
TS_ASSERT ( var3.upperBound () == 10.0f );
gum::ContinuousVariable<double> var4( var3 );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
gum::ContinuousVariable<double> var5( std::move ( var4 ) );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
gum::ContinuousVariable<double>* var6 = var5.clone ();
TS_ASSERT ( var6->lowerBound () == -10.0 );
TS_ASSERT ( var6->upperBound () == 10.0 );
delete var6;
var3 = var1;
TS_ASSERT ( var3.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var3.lowerBound () ==
-std::numeric_limits<float>::infinity () );
var3 = var5;
TS_ASSERT ( var3.lowerBound () == -10.0f );
TS_ASSERT ( var3.upperBound () == 10.0f );
var4.setUpperBound ( 5 );
var4.setLowerBound ( 0 );
TS_ASSERT ( var4.lowerBound () == 0.0 );
TS_ASSERT ( var4.upperBound () == 5.0 );
var4 = std::move ( var5 );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
}
void test_methods () {
gum::ContinuousVariable<> var1("x1", "" );
TS_ASSERT ( var1.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var1.lowerBound () ==
-std::numeric_limits<float>::infinity () );
gum::ContinuousVariable<> var2("x2", "xxx", -10, 10 );
TS_ASSERT ( var2.lowerBound () == -10.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
TS_ASSERT ( var1["44"] == 44.0f );
TS_ASSERT ( var2["4"] == 4.0f );
TS_ASSERT_THROWS(var2["44"], gum::OutOfBounds );
TS_ASSERT_THROWS(var2["4xx"], gum::TypeError );
TS_ASSERT ( var2[" \t\t4\t "] == 4.0f );
TS_ASSERT_THROWS(var2.setLowerBound ( 44.0f ), gum::OutOfBounds );
var2.setLowerBound ( 4 );
TS_ASSERT ( var2.lowerBound () == 4.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
TS_ASSERT_THROWS(var2.setUpperBound ( 2.0f ), gum::OutOfBounds );
var2.setUpperBound ( 8.5f );
TS_ASSERT ( var2.lowerBound () == 4.0f );
TS_ASSERT ( var2.upperBound () == 8.5f );
TS_ASSERT ( var2.varType () == gum::VarType::Continuous );
TS_ASSERT ( std::stof ( var2.label ( 4.5 ) ) == 4.5f );
TS_ASSERT_THROWS(var2.label ( 10.0f ), gum::OutOfBounds );
TS_ASSERT ( var2.belongs ( 5.6 ) );
TS_ASSERT ( ! var2.belongs ( 15.6 ) );
auto domain = var2.domain ();
std::string regexp = "\\[([0-9.\\-]+);([0-9.\\-]+)\\]";
std::regex reg ( regexp );
std::smatch match;
TS_ASSERT ( std::regex_match ( domain, match, reg ) );
TS_ASSERT ( std::stof ( match[1] ) == 4.0f );
TS_ASSERT ( std::stof ( match[2] ) == 8.5f );
TS_ASSERT ( var2.toString () == ( "x2" + domain ) );
TS_ASSERT ( var2.toStringWithDescription() == var2.description () + domain );
}
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment