LCOV - code coverage report
Current view: top level - src/utils/distribution - Distribution_Parameterized.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 79.7 % 79 63
Test Date: 2025-12-06 15:35:27 Functions: 92.3 % 13 12

            Line data    Source code
       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      3357919 : Distribution_Parameterized::Distribution_Parameterized(const std::string& description) :
      38      6715838 :     Distribution("") {
      39      3357919 :     myParameter = {0., 0.};
      40      3357919 :     parse(description, true);
      41      3357919 : }
      42              : 
      43              : 
      44          269 : Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation) :
      45          269 :     Distribution(id) {
      46          269 :     myParameter.push_back(mean);
      47          269 :     myParameter.push_back(deviation);
      48          269 : }
      49              : 
      50              : 
      51       677490 : Distribution_Parameterized::Distribution_Parameterized(const std::string& id, double mean, double deviation, double min, double max) :
      52       677490 :     Distribution(id) {
      53       677490 :     myParameter.push_back(mean);
      54       677490 :     myParameter.push_back(deviation);
      55       677490 :     myParameter.push_back(min);
      56       677490 :     myParameter.push_back(max);
      57       677490 : }
      58              : 
      59              : 
      60      4329691 : Distribution_Parameterized::~Distribution_Parameterized() {}
      61              : 
      62              : 
      63              : void
      64      3360370 : Distribution_Parameterized::parse(const std::string& description, const bool hardFail) {
      65              :     try {
      66      3360370 :         const std::string distName = description.substr(0, description.find('('));
      67      3360370 :         if (distName == "norm" || distName == "normc") {
      68          523 :             const std::vector<std::string> params = StringTokenizer(description.substr(distName.size() + 1, description.size() - distName.size() - 2), ',').getVector();
      69          523 :             myParameter.resize(params.size());
      70              :             std::transform(params.begin(), params.end(), myParameter.begin(), StringUtils::toDouble);
      71          523 :             setID(distName);
      72          523 :         } else {
      73      3359847 :             myParameter[0] = StringUtils::toDouble(description);
      74              :         }
      75      3360370 :         if (myParameter.size() == 1) {
      76            4 :             myParameter.push_back(0.);
      77              :         }
      78            0 :     } catch (...) {
      79              :         // set default distribution parameterized
      80            0 :         myParameter = {0., 0.};
      81            0 :         if (hardFail) {
      82            0 :             throw ProcessError(TL("Invalid format of distribution parameterized"));
      83              :         } else {
      84            0 :             WRITE_ERROR(TL("Invalid format of distribution parameterized"));
      85              :         }
      86            0 :     }
      87      3360370 : }
      88              : 
      89              : 
      90              : bool
      91            0 : Distribution_Parameterized::isValidDescription(const std::string& description) {
      92              :     try {
      93            0 :         Distribution_Parameterized dummy(description);
      94            0 :         const std::string error = dummy.isValid();
      95            0 :         if (error == "") {
      96              :             return true;
      97              :         }
      98            0 :         WRITE_ERROR(error);
      99            0 :     } catch (...) {
     100            0 :         WRITE_ERROR(TL("Invalid format of distribution parameterized"));
     101            0 :     }
     102              :     return false;
     103              : }
     104              : 
     105              : 
     106              : double
     107      9110473 : Distribution_Parameterized::sample(SumoRNG* which) const {
     108      9110473 :     if (myParameter[1] <= 0.) {
     109      5513034 :         return myParameter[0];
     110              :     }
     111      3597439 :     double val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
     112      3597439 :     if (myParameter.size() > 2) {
     113      3597365 :         const double min = myParameter[2];
     114      3597365 :         const double max = getMax();
     115      3628980 :         while (val < min || val > max) {
     116        31615 :             val = RandHelper::randNorm(myParameter[0], myParameter[1], which);
     117              :         }
     118              :     }
     119              :     return val;
     120              : }
     121              : 
     122              : 
     123              : double
     124      7867373 : Distribution_Parameterized::getMax() const {
     125      7867373 :     if (myParameter[1] <= 0.) {
     126      4227589 :         return myParameter[0];
     127              :     }
     128      3639784 :     return myParameter.size() > 3 ? myParameter[3] : std::numeric_limits<double>::infinity();
     129              : }
     130              : 
     131              : 
     132              : double
     133        20142 : Distribution_Parameterized::getMin() const {
     134        20142 :     if (myParameter[1] <= 0.) {
     135            5 :         return myParameter[0];
     136              :     }
     137        20137 :     return myParameter.size() > 2 ? myParameter[2] : -std::numeric_limits<double>::infinity();
     138              : }
     139              : 
     140              : 
     141              : void
     142       498148 : Distribution_Parameterized::setParameter(const int index, const double value) {
     143       498148 :     myParameter[index] = value;
     144       498148 : }
     145              : 
     146              : 
     147              : std::string
     148          462 : Distribution_Parameterized::toStr(std::streamsize accuracy) const {
     149          462 :     if (myParameter[1] < 0) {
     150              :         // only write simple speedFactor
     151          104 :         return toString(myParameter[0]);
     152              :     } else {
     153              :         return (myParameter[1] == 0.
     154          776 :                 ? myID + "(" + toString(myParameter[0], accuracy) + "," + toString(myParameter[1], accuracy) + ")"
     155         1750 :                 : myID + "(" + joinToString(myParameter, ",", accuracy) + ")");
     156              :     }
     157              : }
     158              : 
     159              : 
     160              : const std::string
     161      3420523 : Distribution_Parameterized::isValid() const {
     162      3420523 :     if (myParameter[1] > 0.) {
     163         6133 :         if (getMin() > getMax()) {
     164            0 :             return TLF("minimum value % larger than maximum %", getMin(), getMax());
     165              :         }
     166         6133 :         if (getMin() > myParameter[0] + 3 * myParameter[1]) {
     167            0 :             return TLF("minimum value % too large for distribution with mean % and deviation %", myParameter[2], myParameter[0], myParameter[1]);
     168              :         }
     169         6133 :         if (getMax() < myParameter[0] - 3 * myParameter[1]) {
     170           26 :             return TLF("maximum value % too small for distribution with mean % and deviation %", myParameter[3], myParameter[0], myParameter[1]);
     171              :         }
     172         6120 :         if (myParameter.size() > 3 && myParameter[3] - myParameter[2] < NUMERICAL_EPS * myParameter[1]) {
     173           12 :             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      3420504 :     return "";
     177              : }
     178              : 
     179              : 
     180              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1