36 #include "random-variable.h" |
35 #include "random-variable.h" |
37 #include "rng-seed-manager.h" |
36 #include "rng-seed-manager.h" |
38 #include "rng-stream.h" |
37 #include "rng-stream.h" |
39 #include "fatal-error.h" |
38 #include "fatal-error.h" |
40 |
39 |
41 using namespace std; |
|
42 |
40 |
43 namespace ns3 { |
41 namespace ns3 { |
44 |
42 |
45 // ----------------------------------------------------------------------------- |
43 // ----------------------------------------------------------------------------- |
46 // ----------------------------------------------------------------------------- |
44 // ----------------------------------------------------------------------------- |
543 double ExponentialVariableImpl::GetValue () |
541 double ExponentialVariableImpl::GetValue () |
544 { |
542 { |
545 RngStream *generator = GetStream (); |
543 RngStream *generator = GetStream (); |
546 while (1) |
544 while (1) |
547 { |
545 { |
548 double r = -m_mean*log (generator->RandU01 ()); |
546 double r = -m_mean*std::log (generator->RandU01 ()); |
549 if (m_bound == 0 || r <= m_bound) |
547 if (m_bound == 0 || r <= m_bound) |
550 { |
548 { |
551 return r; |
549 return r; |
552 } |
550 } |
553 // otherwise, try again |
551 // otherwise, try again |
704 double ParetoVariableImpl::GetValue () |
702 double ParetoVariableImpl::GetValue () |
705 { |
703 { |
706 RngStream *generator = GetStream (); |
704 RngStream *generator = GetStream (); |
707 while (1) |
705 while (1) |
708 { |
706 { |
709 double r = (m_scale * ( 1.0 / pow (generator->RandU01 (), 1.0 / m_shape))); |
707 double r = (m_scale * ( 1.0 / std::pow (generator->RandU01 (), 1.0 / m_shape))); |
710 if (m_bound == 0 || r <= m_bound) |
708 if (m_bound == 0 || r <= m_bound) |
711 { |
709 { |
712 return r; |
710 return r; |
713 } |
711 } |
714 // otherwise, try again |
712 // otherwise, try again |
836 { |
834 { |
837 RngStream *generator = GetStream (); |
835 RngStream *generator = GetStream (); |
838 double exponent = 1.0 / m_alpha; |
836 double exponent = 1.0 / m_alpha; |
839 while (1) |
837 while (1) |
840 { |
838 { |
841 double r = m_mean * pow ( -log (generator->RandU01 ()), exponent); |
839 double r = m_mean * std::pow ( -std::log (generator->RandU01 ()), exponent); |
842 if (m_bound == 0 || r <= m_bound) |
840 if (m_bound == 0 || r <= m_bound) |
843 { |
841 { |
844 return r; |
842 return r; |
845 } |
843 } |
846 // otherwise, try again |
844 // otherwise, try again |
956 double v1 = 2 * u1 - 1; |
954 double v1 = 2 * u1 - 1; |
957 double v2 = 2 * u2 - 1; |
955 double v2 = 2 * u2 - 1; |
958 double w = v1 * v1 + v2 * v2; |
956 double w = v1 * v1 + v2 * v2; |
959 if (w <= 1.0) |
957 if (w <= 1.0) |
960 { // Got good pair |
958 { // Got good pair |
961 double y = sqrt ((-2 * log (w)) / w); |
959 double y = std::sqrt ((-2 * std::log (w)) / w); |
962 m_next = m_mean + v2 * y * sqrt (m_variance); |
960 m_next = m_mean + v2 * y * std::sqrt (m_variance); |
963 // if next is in bounds, it is valid |
961 // if next is in bounds, it is valid |
964 m_nextValid = fabs (m_next - m_mean) <= m_bound; |
962 m_nextValid = std::fabs (m_next - m_mean) <= m_bound; |
965 double x1 = m_mean + v1 * y * sqrt (m_variance); |
963 double x1 = m_mean + v1 * y * std::sqrt (m_variance); |
966 // if x1 is in bounds, return it |
964 // if x1 is in bounds, return it |
967 if (fabs (x1 - m_mean) <= m_bound) |
965 if (std::fabs (x1 - m_mean) <= m_bound) |
968 { |
966 { |
969 return x1; |
967 return x1; |
970 } |
968 } |
971 // otherwise try and return m_next if it is valid |
969 // otherwise try and return m_next if it is valid |
972 else if (m_nextValid) |
970 else if (m_nextValid) |
1154 for (std::vector<ValueCDF>::size_type i = 0; i < emp.size (); ++i) |
1152 for (std::vector<ValueCDF>::size_type i = 0; i < emp.size (); ++i) |
1155 { |
1153 { |
1156 ValueCDF& current = emp[i]; |
1154 ValueCDF& current = emp[i]; |
1157 if (current.value < prior.value || current.cdf < prior.cdf) |
1155 if (current.value < prior.value || current.cdf < prior.cdf) |
1158 { // Error |
1156 { // Error |
1159 cerr << "Empirical Dist error," |
1157 std::cerr << "Empirical Dist error," |
1160 << " current value " << current.value |
1158 << " current value " << current.value |
1161 << " prior value " << prior.value |
1159 << " prior value " << prior.value |
1162 << " current cdf " << current.cdf |
1160 << " current cdf " << current.cdf |
1163 << " prior cdf " << prior.cdf << endl; |
1161 << " prior cdf " << prior.cdf << std::endl; |
1164 NS_FATAL_ERROR ("Empirical Dist error"); |
1162 NS_FATAL_ERROR ("Empirical Dist error"); |
1165 } |
1163 } |
1166 prior = current; |
1164 prior = current; |
1167 } |
1165 } |
1168 validated = true; |
1166 validated = true; |
1224 } |
1222 } |
1225 |
1223 |
1226 double IntEmpiricalVariableImpl::Interpolate (double c1, double c2, |
1224 double IntEmpiricalVariableImpl::Interpolate (double c1, double c2, |
1227 double v1, double v2, double r) |
1225 double v1, double v2, double r) |
1228 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
1226 { // Interpolate random value in range [v1..v2) based on [c1 .. r .. c2) |
1229 return ceil (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
1227 return std::ceil (v1 + ((v2 - v1) / (c2 - c1)) * (r - c1)); |
1230 } |
1228 } |
1231 |
1229 |
1232 IntEmpiricalVariable::IntEmpiricalVariable () |
1230 IntEmpiricalVariable::IntEmpiricalVariable () |
1233 : EmpiricalVariable (IntEmpiricalVariableImpl ()) |
1231 : EmpiricalVariable (IntEmpiricalVariableImpl ()) |
1234 { |
1232 { |
1373 /* see if it is in the unit circle */ |
1371 /* see if it is in the unit circle */ |
1374 r2 = u * u + v * v; |
1372 r2 = u * u + v * v; |
1375 } |
1373 } |
1376 while (r2 > 1.0 || r2 == 0); |
1374 while (r2 > 1.0 || r2 == 0); |
1377 |
1375 |
1378 normal = u * sqrt (-2.0 * log (r2) / r2); |
1376 normal = u * std::sqrt (-2.0 * std::log (r2) / r2); |
1379 |
1377 |
1380 z = exp (m_sigma * normal + m_mu); |
1378 z = std::exp (m_sigma * normal + m_mu); |
1381 |
1379 |
1382 return z; |
1380 return z; |
1383 } |
1381 } |
1384 |
1382 |
1385 LogNormalVariable::LogNormalVariable (double mu, double sigma) |
1383 LogNormalVariable::LogNormalVariable (double mu, double sigma) |
1458 RngStream *generator = GetStream (); |
1456 RngStream *generator = GetStream (); |
1459 |
1457 |
1460 if (alpha < 1) |
1458 if (alpha < 1) |
1461 { |
1459 { |
1462 double u = generator->RandU01 (); |
1460 double u = generator->RandU01 (); |
1463 return GetValue (1.0 + alpha, beta) * pow (u, 1.0 / alpha); |
1461 return GetValue (1.0 + alpha, beta) * std::pow (u, 1.0 / alpha); |
1464 } |
1462 } |
1465 |
1463 |
1466 double x, v, u; |
1464 double x, v, u; |
1467 double d = alpha - 1.0 / 3.0; |
1465 double d = alpha - 1.0 / 3.0; |
1468 double c = (1.0 / 3.0) / sqrt (d); |
1466 double c = (1.0 / 3.0) / std::sqrt (d); |
1469 |
1467 |
1470 while (1) |
1468 while (1) |
1471 { |
1469 { |
1472 do |
1470 do |
1473 { |
1471 { |
1670 { |
1668 { |
1671 RngStream *generator = GetStream (); |
1669 RngStream *generator = GetStream (); |
1672 double u = generator->RandU01 (); |
1670 double u = generator->RandU01 (); |
1673 if (u <= (m_mode - m_min) / (m_max - m_min) ) |
1671 if (u <= (m_mode - m_min) / (m_max - m_min) ) |
1674 { |
1672 { |
1675 return m_min + sqrt (u * (m_max - m_min) * (m_mode - m_min) ); |
1673 return m_min + std::sqrt (u * (m_max - m_min) * (m_mode - m_min) ); |
1676 } |
1674 } |
1677 else |
1675 else |
1678 { |
1676 { |
1679 return m_max - sqrt ( (1 - u) * (m_max - m_min) * (m_max - m_mode) ); |
1677 return m_max - std::sqrt ( (1 - u) * (m_max - m_min) * (m_max - m_mode) ); |
1680 } |
1678 } |
1681 } |
1679 } |
1682 |
1680 |
1683 RandomVariableBase* TriangularVariableImpl::Copy () const |
1681 RandomVariableBase* TriangularVariableImpl::Copy () const |
1684 { |
1682 { |
1813 return new ZetaVariableImpl (m_alpha); |
1811 return new ZetaVariableImpl (m_alpha); |
1814 } |
1812 } |
1815 |
1813 |
1816 ZetaVariableImpl::ZetaVariableImpl () |
1814 ZetaVariableImpl::ZetaVariableImpl () |
1817 : m_alpha (3.14), |
1815 : m_alpha (3.14), |
1818 m_b (pow (2.0, 2.14)) |
1816 m_b (std::pow (2.0, 2.14)) |
1819 { |
1817 { |
1820 } |
1818 } |
1821 |
1819 |
1822 |
1820 |
1823 ZetaVariableImpl::ZetaVariableImpl (double alpha) |
1821 ZetaVariableImpl::ZetaVariableImpl (double alpha) |
1824 : m_alpha (alpha), |
1822 : m_alpha (alpha), |
1825 m_b (pow (2.0, alpha - 1.0)) |
1823 m_b (std::pow (2.0, alpha - 1.0)) |
1826 { |
1824 { |
1827 } |
1825 } |
1828 |
1826 |
1829 /* |
1827 /* |
1830 The code for the following generator functions is borrowed from: |
1828 The code for the following generator functions is borrowed from: |
1842 |
1840 |
1843 do |
1841 do |
1844 { |
1842 { |
1845 u = generator->RandU01 (); |
1843 u = generator->RandU01 (); |
1846 v = generator->RandU01 (); |
1844 v = generator->RandU01 (); |
1847 X = floor (pow (u, -1.0 / (m_alpha - 1.0))); |
1845 X = floor (std::pow (u, -1.0 / (m_alpha - 1.0))); |
1848 T = pow (1.0 + 1.0 / X, m_alpha - 1.0); |
1846 T = std::pow (1.0 + 1.0 / X, m_alpha - 1.0); |
1849 test = v * X * (T - 1.0) / (m_b - 1.0); |
1847 test = v * X * (T - 1.0) / (m_b - 1.0); |
1850 } |
1848 } |
1851 while ( test > (T / m_b) ); |
1849 while ( test > (T / m_b) ); |
1852 |
1850 |
1853 return X; |
1851 return X; |
1907 } |
1905 } |
1908 std::string type = value.substr (0, tmp); |
1906 std::string type = value.substr (0, tmp); |
1909 value = value.substr (tmp + 1, value.npos); |
1907 value = value.substr (tmp + 1, value.npos); |
1910 if (type == "Constant") |
1908 if (type == "Constant") |
1911 { |
1909 { |
1912 istringstream iss (value); |
1910 std::istringstream iss (value); |
1913 double constant; |
1911 double constant; |
1914 iss >> constant; |
1912 iss >> constant; |
1915 var = ConstantVariable (constant); |
1913 var = ConstantVariable (constant); |
1916 } |
1914 } |
1917 else if (type == "Uniform") |
1915 else if (type == "Uniform") |
1925 tmp = value.find (":"); |
1923 tmp = value.find (":"); |
1926 if (tmp == value.npos) |
1924 if (tmp == value.npos) |
1927 { |
1925 { |
1928 NS_FATAL_ERROR ("bad Uniform value: " << value); |
1926 NS_FATAL_ERROR ("bad Uniform value: " << value); |
1929 } |
1927 } |
1930 istringstream issA (value.substr (0, tmp)); |
1928 std::istringstream issA (value.substr (0, tmp)); |
1931 istringstream issB (value.substr (tmp + 1, value.npos)); |
1929 std::istringstream issB (value.substr (tmp + 1, value.npos)); |
1932 double a, b; |
1930 double a, b; |
1933 issA >> a; |
1931 issA >> a; |
1934 issB >> b; |
1932 issB >> b; |
1935 var = UniformVariable (a, b); |
1933 var = UniformVariable (a, b); |
1936 } |
1934 } |
1951 std::string::size_type tmp2; |
1949 std::string::size_type tmp2; |
1952 std::string sub = value.substr (tmp + 1, value.npos); |
1950 std::string sub = value.substr (tmp + 1, value.npos); |
1953 tmp2 = sub.find (":"); |
1951 tmp2 = sub.find (":"); |
1954 if (tmp2 == value.npos) |
1952 if (tmp2 == value.npos) |
1955 { |
1953 { |
1956 istringstream issA (value.substr (0, tmp)); |
1954 std::istringstream issA (value.substr (0, tmp)); |
1957 istringstream issB (sub); |
1955 std::istringstream issB (sub); |
1958 double a, b; |
1956 double a, b; |
1959 issA >> a; |
1957 issA >> a; |
1960 issB >> b; |
1958 issB >> b; |
1961 var = NormalVariable (a, b); |
1959 var = NormalVariable (a, b); |
1962 } |
1960 } |
1963 else |
1961 else |
1964 { |
1962 { |
1965 istringstream issA (value.substr (0, tmp)); |
1963 std::istringstream issA (value.substr (0, tmp)); |
1966 istringstream issB (sub.substr (0, tmp2)); |
1964 std::istringstream issB (sub.substr (0, tmp2)); |
1967 istringstream issC (sub.substr (tmp2 + 1, value.npos)); |
1965 std::istringstream issC (sub.substr (tmp2 + 1, value.npos)); |
1968 double a, b, c; |
1966 double a, b, c; |
1969 issA >> a; |
1967 issA >> a; |
1970 issB >> b; |
1968 issB >> b; |
1971 issC >> c; |
1969 issC >> c; |
1972 var = NormalVariable (a, b, c); |
1970 var = NormalVariable (a, b, c); |