|
|
| 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 |
|
|
| 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 (); |
|
|
| 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 |
|
|
| 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 |