packages/engine/scram-node/src/expression.cc
Implementation of the expression base class.
Namespaces
| Name |
|---|
| scram |
| scram::mef |
| scram::mef::detail |
Source code
cpp
/*
* Copyright (C) 2014-2018 Olzhas Rakhimov
* Copyright (C) 2023 OpenPRA ORG Inc.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "expression.h"
#include <sstream>
#include <string>
#include "error.h"
#include "ext/algorithm.h"
namespace scram::mef {
Expression::Expression(std::vector<Expression*> args)
: args_(std::move(args)), sampled_value_(0), sampled_(false) {}
double Expression::Sample() noexcept {
if (!sampled_) {
sampled_ = true;
sampled_value_ = this->DoSample();
}
return sampled_value_;
}
void Expression::Reset() noexcept {
if (!sampled_)
return;
sampled_ = false;
for (Expression* arg : args_)
arg->Reset();
}
bool Expression::IsDeviate() noexcept {
return ext::any_of(args_, [](Expression* arg) { return arg->IsDeviate(); });
}
namespace detail {
void EnsureMultivariateArgs(std::vector<Expression*> args) {
if (args.size() < 2)
SCRAM_THROW(ValidityError("Expression requires 2 or more arguments."))
<< errinfo_value(std::to_string(args.size()));
}
} // namespace detail
namespace { // Interval to string.
std::string ToString(const Interval& interval) {
std::stringstream ss;
ss << interval;
return ss.str();
}
} // namespace
void EnsureProbability(Expression* expression, const char* type) {
double value = expression->value();
if (value < 0 || value > 1)
SCRAM_THROW(DomainError("Invalid " + std::string(type) + " value"))
<< errinfo_value(std::to_string(value));
Interval interval = expression->interval();
if (IsProbability(interval) == false)
SCRAM_THROW(DomainError("Invalid " + std::string(type) + " sample domain"))
<< errinfo_value(ToString(interval));
}
void EnsurePositive(Expression* expression, const char* description) {
using namespace std::string_literals; // NOLINT
double value = expression->value();
if (value <= 0)
SCRAM_THROW(DomainError(description + " argument value must be positive."s))
<< errinfo_value(std::to_string(value));
Interval interval = expression->interval();
if (IsPositive(interval) == false)
SCRAM_THROW(
DomainError(description + " argument sample domain must be positive."s))
<< errinfo_value(ToString(interval));
}
void EnsureNonNegative(Expression* expression, const char* description) {
using namespace std::string_literals; // NOLINT
double value = expression->value();
if (value < 0)
SCRAM_THROW(
DomainError(description + " argument value cannot be negative."s))
<< errinfo_value(std::to_string(value));
Interval interval = expression->interval();
if (IsNonNegative(interval) == false)
SCRAM_THROW(DomainError(description +
" argument sample cannot have negative values."s))
<< errinfo_value(ToString(interval));
}
void EnsureWithin(Expression* expression, const Interval& interval,
const char* type) {
double arg_value = expression->value();
if (!Contains(interval, arg_value)) {
std::stringstream ss;
ss << type << " argument value must be in " << interval << ".";
SCRAM_THROW(DomainError(ss.str()))
<< errinfo_value(std::to_string(arg_value));
}
Interval arg_interval = expression->interval();
if (!boost::icl::within(arg_interval, interval)) {
std::stringstream ss;
ss << type << " argument sample domain must be in " << interval << ".";
SCRAM_THROW(DomainError(ss.str())) << errinfo_value(ToString(arg_interval));
}
}
} // namespace scram::mefUpdated on 2025-11-11 at 16:51:08 +0000
