Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
Distribution_Parameterized.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
19// A distribution described by parameters such as the mean value and std-dev
20/****************************************************************************/
21#include <config.h>
22
23#include <cassert>
29
31
32
33// ===========================================================================
34// method definitions
35// ===========================================================================
36
40
43 Distribution("") {
44 myParameter = {0., 0.};
45 parse(description, true);
46}
47
48
49Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation) :
50 Distribution(id) {
51 myParameter.push_back(mean);
52 myParameter.push_back(deviation);
53}
54
55
56Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation, double min, double max) :
57 Distribution(id) {
58 myParameter.push_back(mean);
59 myParameter.push_back(deviation);
60 myParameter.push_back(min);
61 myParameter.push_back(max);
62}
63
64
66
67
68void
69Distribution_Parameterized::parse(const std::string& description, const bool hardFail) {
70 try {
71 const std::string distName = description.substr(0, description.find('('));
72 if (distName == "norm" || distName == "normc") {
73 const std::vector<std::string> params = StringTokenizer(description.substr(distName.size() + 1, description.size() - distName.size() - 2), ',').getVector();
74 myParameter.resize(params.size());
75 std::transform(params.begin(), params.end(), myParameter.begin(), StringUtils::toDoubleAllowTime);
76 setID(distName);
77 } else {
79 }
80 if (myParameter.size() == 1) {
81 myParameter.push_back(0.);
82 }
83 } catch (...) {
84 // set default distribution parameterized
85 myParameter = {0., 0.};
86 if (hardFail) {
87 throw ProcessError(TL("Invalid format of distribution parameterized"));
88 } else {
89 WRITE_ERROR(TL("Invalid format of distribution parameterized"));
90 }
91 }
92}
93
94
95bool
96Distribution_Parameterized::isValidDescription(const std::string& description, std::string& error) {
97 try {
98 Distribution_Parameterized dummy(description);
99 error = dummy.isValid();
100 if (error == "") {
101 return true;
102 }
103 } catch (...) {
104 error = TL("Invalid format of distribution parameterized");
105 }
106 return false;
107}
108
109
110double
112 if (myParameter.empty()) {
113 throw ProcessError(TL("Attempted to sample from dummy distribution"));
114 }
115 if (myParameter[1] <= 0.) {
116 return myParameter[0];
117 }
118 double val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
119 if (myParameter.size() > 2) {
120 const double min = myParameter[2];
121 const double max = getMax();
122 while (val < min || val > max) {
123 val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
124 }
125 }
126 return val;
127}
128
129
130double
132 if (myParameter.empty()) {
133 return std::numeric_limits<double>::infinity();
134 }
135 if (myParameter[1] <= 0.) {
136 return myParameter[0];
137 }
138 return myParameter.size() > 3 ? myParameter[3] : std::numeric_limits<double>::infinity();
139}
140
141
142double
144 if (myParameter.empty()) {
145 return -std::numeric_limits<double>::infinity();
146 }
147 if (myParameter[1] <= 0.) {
148 return myParameter[0];
149 }
150 return myParameter.size() > 2 ? myParameter[2] : -std::numeric_limits<double>::infinity();
151}
152
153
154void
155Distribution_Parameterized::setParameter(const int index, const double value) {
156 if (index >= (int)myParameter.size()) {
157 throw ProcessError(TLF("Attempted to set parameter index % of distribut '%' with % parameters", index, myID, myParameter.size()));
158 }
159 myParameter[index] = value;
160}
161
162
163std::string
164Distribution_Parameterized::toStr(std::streamsize accuracy) const {
165 if (myParameter.empty()) {
166 return "";
167 } else if (myParameter[1] < 0) {
168 // only write simple speedFactor
169 return toString(myParameter[0]);
170 } else {
171 return (myParameter[1] == 0.
172 ? myID + "(" + toString(myParameter[0], accuracy) + "," + toString(myParameter[1], accuracy) + ")"
173 : myID + "(" + joinToString(myParameter, ",", accuracy) + ")");
174 }
175}
176
177
178const std::string
180 if (myParameter.empty()) {
181 return "Dummy Distribution (invalid)";
182 } else if (myParameter.size() >= 2 && myParameter[1] > 0.) {
183 if (getMin() > getMax()) {
184 return TLF("minimum value % larger than maximum %", getMin(), getMax());
185 }
186 if (getMin() > myParameter[0] + 3 * myParameter[1]) {
187 return TLF("minimum value % too large for distribution with mean % and deviation %", myParameter[2], myParameter[0], myParameter[1]);
188 }
189 if (getMax() < myParameter[0] - 3 * myParameter[1]) {
190 return TLF("maximum value % too small for distribution with mean % and deviation %", myParameter[3], myParameter[0], myParameter[1]);
191 }
192 if (myParameter.size() > 3 && myParameter[3] - myParameter[2] < NUMERICAL_EPS * myParameter[1]) {
193 return TLF("maximum value % and minimum value % too close for distribution with mean % and deviation %", myParameter[3], myParameter[2], myParameter[0], myParameter[1]);
194 }
195 }
196 return "";
197}
198
199
200/****************************************************************************/
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:314
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
void parse(const std::string &description, const bool hardFail)
Overwrite by parsable distribution description.
virtual ~Distribution_Parameterized()
Destructor.
double getMax() const
Returns the maximum value of this distribution.
double getMin() const
Returns the minimum value of this distribution.
Distribution_Parameterized()
Dummy Constructor for a default distribution.
void setParameter(const int index, const double value)
Set a parameter of this distribution.
std::string toStr(std::streamsize accuracy) const
Returns the string representation of this distribution.
static bool isValidDescription(const std::string &description, std::string &error)
validate input description
const std::string isValid() const
check whether the distribution is valid
std::vector< double > myParameter
The distribution's parameters.
double sample(SumoRNG *which=nullptr) const
Draw a sample of the distribution using the given RNG.
std::string myID
The name of the object.
Definition Named.h:124
virtual void setID(const std::string &newID)
resets the id
Definition Named.h:81
static double randNorm(double mean, double variance, SumoRNG *rng=nullptr)
Access to a random number from a normal distribution.
std::vector< std::string > getVector()
return vector of strings
static double toDoubleAllowTime(const std::string &sData)
converts a string into a double value. Values in human-readable-time format (see string2time) are per...