Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/distribution/Distribution_Parameterized.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file Distribution_Parameterized.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Michael Behrisch
17
/// @date Sept 2002
18
///
19
// A distribution described by parameters such as the mean value and std-dev
20
/****************************************************************************/
21
#include <config.h>
22
23
#include <cassert>
24
#include <utils/common/RandHelper.h>
25
#include <utils/common/StringTokenizer.h>
26
#include <utils/common/ToString.h>
27
#include <utils/common/StringUtils.h>
28
#include <utils/common/MsgHandler.h>
29
30
#include "Distribution_Parameterized.h"
31
32
33
// ===========================================================================
34
// method definitions
35
// ===========================================================================
36
/// @brief Constructor for any temporary distribution parsed directly from the description
37
Distribution_Parameterized::Distribution_Parameterized(const std::string& description) :
38
Distribution("") {
39
myParameter = {0., 0.};
40
parse(description, true);
41
}
42
43
44
Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation) :
45
Distribution(id) {
46
myParameter.push_back(mean);
47
myParameter.push_back(deviation);
48
}
49
50
51
Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation, double min, double max) :
52
Distribution(id) {
53
myParameter.push_back(mean);
54
myParameter.push_back(deviation);
55
myParameter.push_back(min);
56
myParameter.push_back(max);
57
}
58
59
60
Distribution_Parameterized::~Distribution_Parameterized() {}
61
62
63
void
64
Distribution_Parameterized::parse(const std::string& description, const bool hardFail) {
65
try {
66
const std::string distName = description.substr(0, description.find('('));
67
if (distName == "norm" || distName == "normc") {
68
const std::vector<std::string> params = StringTokenizer(description.substr(distName.size() + 1, description.size() - distName.size() - 2), ',').getVector();
69
myParameter.resize(params.size());
70
std::transform(params.begin(), params.end(), myParameter.begin(), StringUtils::toDouble);
71
setID(distName);
72
} else {
73
myParameter[0] = StringUtils::toDouble(description);
74
}
75
if (myParameter.size() == 1) {
76
myParameter.push_back(0.);
77
}
78
} catch (...) {
79
// set default distribution parameterized
80
myParameter = {0., 0.};
81
if (hardFail) {
82
throw ProcessError(TL("Invalid format of distribution parameterized"));
83
} else {
84
WRITE_ERROR(TL("Invalid format of distribution parameterized"));
85
}
86
}
87
}
88
89
90
bool
91
Distribution_Parameterized::isValidDescription(const std::string& description) {
92
try {
93
Distribution_Parameterized dummy(description);
94
const std::string error = dummy.isValid();
95
if (error == "") {
96
return true;
97
}
98
WRITE_ERROR(error);
99
} catch (...) {
100
WRITE_ERROR(TL("Invalid format of distribution parameterized"));
101
}
102
return false;
103
}
104
105
106
double
107
Distribution_Parameterized::sample(SumoRNG* which) const {
108
if (myParameter[1] <= 0.) {
109
return myParameter[0];
110
}
111
double val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
112
if (myParameter.size() > 2) {
113
const double min = myParameter[2];
114
const double max = getMax();
115
while (val < min || val > max) {
116
val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
117
}
118
}
119
return val;
120
}
121
122
123
double
124
Distribution_Parameterized::getMax() const {
125
if (myParameter[1] <= 0.) {
126
return myParameter[0];
127
}
128
return myParameter.size() > 3 ? myParameter[3] : std::numeric_limits<double>::infinity();
129
}
130
131
132
double
133
Distribution_Parameterized::getMin() const {
134
if (myParameter[1] <= 0.) {
135
return myParameter[0];
136
}
137
return myParameter.size() > 2 ? myParameter[2] : -std::numeric_limits<double>::infinity();
138
}
139
140
141
void
142
Distribution_Parameterized::setParameter(const int index, const double value) {
143
myParameter[index] = value;
144
}
145
146
147
std::string
148
Distribution_Parameterized::toStr(std::streamsize accuracy) const {
149
if (myParameter[1] < 0) {
150
// only write simple speedFactor
151
return toString(myParameter[0]);
152
} else {
153
return (myParameter[1] == 0.
154
? myID + "(" + toString(myParameter[0], accuracy) + "," + toString(myParameter[1], accuracy) + ")"
155
: myID + "(" + joinToString(myParameter, ",", accuracy) + ")");
156
}
157
}
158
159
160
const std::string
161
Distribution_Parameterized::isValid() const {
162
if (myParameter[1] > 0.) {
163
if (getMin() > getMax()) {
164
return TLF("minimum value % larger than maximum %", getMin(), getMax());
165
}
166
if (getMin() > myParameter[0] + 3 * myParameter[1]) {
167
return TLF("minimum value % too large for distribution with mean % and deviation %", myParameter[2], myParameter[0], myParameter[1]);
168
}
169
if (getMax() < myParameter[0] - 3 * myParameter[1]) {
170
return TLF("maximum value % too small for distribution with mean % and deviation %", myParameter[3], myParameter[0], myParameter[1]);
171
}
172
if (myParameter.size() > 3 && myParameter[3] - myParameter[2] < NUMERICAL_EPS * myParameter[1]) {
173
return TLF("maximum value % and minimum value % too close for distribution with mean % and deviation %", myParameter[3], myParameter[2], myParameter[0], myParameter[1]);
174
}
175
}
176
return "";
177
}
178
179
180
/****************************************************************************/
181
182