View | Details | Raw Unified | Return to bug 2725
Collapse All | Expand All

(-)a/src/core/model/random-variable-stream.cc (-38 / +8 lines)
 Lines 36-41    Link Here 
36
#include "unused.h"
36
#include "unused.h"
37
#include <cmath>
37
#include <cmath>
38
#include <iostream>
38
#include <iostream>
39
#include <algorithm>
39
40
40
/**
41
/**
41
 * \file
42
 * \file
 Lines 1574-1581    Link Here 
1574
EmpiricalRandomVariable::GetValue (void)
1575
EmpiricalRandomVariable::GetValue (void)
1575
{
1576
{
1576
  NS_LOG_FUNCTION (this);
1577
  NS_LOG_FUNCTION (this);
1577
  // Return a value from the empirical distribution
1578
1578
  // This code based (loosely) on code by Bruce Mah (Thanks Bruce!)
1579
  if (!m_validated)
1579
  if (!m_validated)
1580
    {
1580
    {
1581
      Validate ();
1581
      Validate ();
 Lines 1588-1623    Link Here 
1588
      r = (1 - r);
1588
      r = (1 - r);
1589
    }
1589
    }
1590
1590
1591
  if (r <= m_emp.front ().cdf)
1592
    {
1593
      return m_emp.front ().value; // Less than first
1594
    }
1595
  if (r >= m_emp.back ().cdf)
1596
    {
1597
      return m_emp.back ().value;  // Greater than last
1598
    }
1599
  // Binary search
1591
  // Binary search
1600
  std::vector<ValueCDF>::size_type bottom = 0;
1592
  auto bound = std::upper_bound (m_emp.begin (), m_emp.end (), r,
1601
  std::vector<ValueCDF>::size_type top = m_emp.size () - 1;
1593
                                 [] (double p, ValueCDF &it)
1602
  while (1)
1594
                                   {
1603
    {
1595
                                     return p < it.cdf;
1604
      std::vector<ValueCDF>::size_type c = (top + bottom) / 2;
1596
                                   });
1605
      if (r >= m_emp[c].cdf && r < m_emp[c + 1].cdf)
1597
  return bound->value;
1606
        { // Found it
1607
          return Interpolate (m_emp[c].cdf, m_emp[c + 1].cdf,
1608
                              m_emp[c].value, m_emp[c + 1].value,
1609
                              r);
1610
        }
1611
      // Not here, adjust bounds
1612
      if (r < m_emp[c].cdf)
1613
        {
1614
          top    = c - 1;
1615
        }
1616
      else
1617
        {
1618
          bottom = c + 1;
1619
        }
1620
    }
1621
}
1598
}
1622
1599
1623
uint32_t 
1600
uint32_t 
 Lines 1663-1673    Link Here 
1663
  m_validated = true;
1640
  m_validated = true;
1664
}
1641
}
1665
1642
1666
double EmpiricalRandomVariable::Interpolate (double c1, double c2,
1667
                                           double v1, double v2, double r)
1668
{ // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2)
1669
  NS_LOG_FUNCTION (this << c1 << c2 << v1 << v2 << r);
1670
  return (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1));
1671
}
1672
1673
} // namespace ns3
1643
} // namespace ns3
(-)a/src/core/model/random-variable-stream.h (-14 / +1 lines)
 Lines 2523-2542    Link Here 
2523
   * It is a fatal error to fail validation.
2523
   * It is a fatal error to fail validation.
2524
   */
2524
   */
2525
  virtual void Validate ();
2525
  virtual void Validate ();
2526
  /**
2526
2527
   * Linear nterpolation between two points on the CDF to estimate
2528
   * the value at \p r.
2529
   *
2530
   * \param [in] c1 The first argument value.
2531
   * \param [in] c2 The secong argument value.
2532
   * \param [in] v1 The first CDF value.
2533
   * \param [in] v2 The secong CDF value.
2534
   * \param [in] r  The argument value to interpolate to.
2535
   * \returns The interpolated CDF at \p r.
2536
   */
2537
  virtual double Interpolate (double c1, double c2,
2538
                              double v1, double v2, double r);
2539
  
2540
  /** \c true once the CDF has been validated. */
2527
  /** \c true once the CDF has been validated. */
2541
  bool m_validated;
2528
  bool m_validated;
2542
  /** The vector of CDF points. */
2529
  /** The vector of CDF points. */

Return to bug 2725