Path: blob/main/src/utils/distribution/Distribution_Parameterized.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file Distribution_Parameterized.cpp14/// @author Daniel Krajzewicz15/// @author Michael Behrisch16/// @date Sept 200217///18// A distribution described by parameters such as the mean value and std-dev19/****************************************************************************/20#include <config.h>2122#include <cassert>23#include <utils/common/RandHelper.h>24#include <utils/common/StringTokenizer.h>25#include <utils/common/ToString.h>26#include <utils/common/StringUtils.h>27#include <utils/common/MsgHandler.h>2829#include "Distribution_Parameterized.h"303132// ===========================================================================33// method definitions34// ===========================================================================35/// @brief Constructor for any temporary distribution parsed directly from the description36Distribution_Parameterized::Distribution_Parameterized(const std::string& description) :37Distribution("") {38myParameter = {0., 0.};39parse(description, true);40}414243Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation) :44Distribution(id) {45myParameter.push_back(mean);46myParameter.push_back(deviation);47}484950Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation, double min, double max) :51Distribution(id) {52myParameter.push_back(mean);53myParameter.push_back(deviation);54myParameter.push_back(min);55myParameter.push_back(max);56}575859Distribution_Parameterized::~Distribution_Parameterized() {}606162void63Distribution_Parameterized::parse(const std::string& description, const bool hardFail) {64try {65const std::string distName = description.substr(0, description.find('('));66if (distName == "norm" || distName == "normc") {67const std::vector<std::string> params = StringTokenizer(description.substr(distName.size() + 1, description.size() - distName.size() - 2), ',').getVector();68myParameter.resize(params.size());69std::transform(params.begin(), params.end(), myParameter.begin(), StringUtils::toDouble);70setID(distName);71} else {72myParameter[0] = StringUtils::toDouble(description);73}74if (myParameter.size() == 1) {75myParameter.push_back(0.);76}77} catch (...) {78// set default distribution parameterized79myParameter = {0., 0.};80if (hardFail) {81throw ProcessError(TL("Invalid format of distribution parameterized"));82} else {83WRITE_ERROR(TL("Invalid format of distribution parameterized"));84}85}86}878889bool90Distribution_Parameterized::isValidDescription(const std::string& description) {91try {92Distribution_Parameterized dummy(description);93const std::string error = dummy.isValid();94if (error == "") {95return true;96}97WRITE_ERROR(error);98} catch (...) {99WRITE_ERROR(TL("Invalid format of distribution parameterized"));100}101return false;102}103104105double106Distribution_Parameterized::sample(SumoRNG* which) const {107if (myParameter[1] <= 0.) {108return myParameter[0];109}110double val = RandHelper::randNorm(myParameter[0], myParameter[1], which);111if (myParameter.size() > 2) {112const double min = myParameter[2];113const double max = getMax();114while (val < min || val > max) {115val = RandHelper::randNorm(myParameter[0], myParameter[1], which);116}117}118return val;119}120121122double123Distribution_Parameterized::getMax() const {124if (myParameter[1] <= 0.) {125return myParameter[0];126}127return myParameter.size() > 3 ? myParameter[3] : std::numeric_limits<double>::infinity();128}129130131double132Distribution_Parameterized::getMin() const {133if (myParameter[1] <= 0.) {134return myParameter[0];135}136return myParameter.size() > 2 ? myParameter[2] : -std::numeric_limits<double>::infinity();137}138139140void141Distribution_Parameterized::setParameter(const int index, const double value) {142myParameter[index] = value;143}144145146std::string147Distribution_Parameterized::toStr(std::streamsize accuracy) const {148if (myParameter[1] < 0) {149// only write simple speedFactor150return toString(myParameter[0]);151} else {152return (myParameter[1] == 0.153? myID + "(" + toString(myParameter[0], accuracy) + "," + toString(myParameter[1], accuracy) + ")"154: myID + "(" + joinToString(myParameter, ",", accuracy) + ")");155}156}157158159const std::string160Distribution_Parameterized::isValid() const {161if (myParameter[1] > 0.) {162if (getMin() > getMax()) {163return TLF("minimum value % larger than maximum %", getMin(), getMax());164}165if (getMin() > myParameter[0] + 3 * myParameter[1]) {166return TLF("minimum value % too large for distribution with mean % and deviation %", myParameter[2], myParameter[0], myParameter[1]);167}168if (getMax() < myParameter[0] - 3 * myParameter[1]) {169return TLF("maximum value % too small for distribution with mean % and deviation %", myParameter[3], myParameter[0], myParameter[1]);170}171if (myParameter.size() > 3 && myParameter[3] - myParameter[2] < NUMERICAL_EPS * myParameter[1]) {172return TLF("maximum value % and minimum value % too close for distribution with mean % and deviation %", myParameter[3], myParameter[2], myParameter[0], myParameter[1]);173}174}175return "";176}177178179/****************************************************************************/180181182