File indexing completed on 2025-01-18 09:39:40
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_STATS_FIND_SCALE_HPP
0009 #define BOOST_STATS_FIND_SCALE_HPP
0010
0011 #include <boost/math/distributions/fwd.hpp> // for all distribution signatures.
0012 #include <boost/math/distributions/complement.hpp>
0013 #include <boost/math/policies/policy.hpp>
0014
0015 #include <boost/math/tools/traits.hpp>
0016 #include <boost/math/tools/assert.hpp>
0017 #include <boost/math/special_functions/fpclassify.hpp>
0018 #include <boost/math/policies/error_handling.hpp>
0019
0020
0021
0022 namespace boost
0023 {
0024 namespace math
0025 {
0026
0027
0028
0029
0030
0031
0032 template <class Dist, class Policy>
0033 inline
0034 typename Dist::value_type find_scale(
0035 typename Dist::value_type z,
0036
0037 typename Dist::value_type p,
0038 typename Dist::value_type location,
0039 const Policy& pol
0040 )
0041 {
0042 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
0043 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
0044 static const char* function = "boost::math::find_scale<Dist, Policy>(%1%, %1%, %1%, Policy)";
0045
0046 if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1))
0047 {
0048 return policies::raise_domain_error<typename Dist::value_type>(
0049 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol);
0050 }
0051 if(!(boost::math::isfinite)(z))
0052 {
0053 return policies::raise_domain_error<typename Dist::value_type>(
0054 function, "find_scale z parameter was %1%, but must be finite!", z, pol);
0055 }
0056 if(!(boost::math::isfinite)(location))
0057 {
0058 return policies::raise_domain_error<typename Dist::value_type>(
0059 function, "find_scale location parameter was %1%, but must be finite!", location, pol);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 typename Dist::value_type result =
0078 (z - location)
0079 / quantile(Dist(), p);
0080
0081 if (result <= 0)
0082 {
0083 policies::raise_evaluation_error<typename Dist::value_type>(function,
0084 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
0085 result, Policy());
0086 }
0087 return result;
0088 }
0089
0090 template <class Dist>
0091 inline
0092 typename Dist::value_type find_scale(
0093 typename Dist::value_type z,
0094
0095 typename Dist::value_type p,
0096 typename Dist::value_type location)
0097 {
0098 return (find_scale<Dist>(z, p, location, policies::policy<>()));
0099 }
0100
0101 template <class Dist, class Real1, class Real2, class Real3, class Policy>
0102 inline typename Dist::value_type find_scale(
0103 complemented4_type<Real1, Real2, Real3, Policy> const& c)
0104 {
0105
0106
0107
0108
0109
0110
0111
0112 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
0113 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
0114 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
0115
0116
0117
0118 typename Dist::value_type q = c.param1;
0119 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
0120 {
0121 return policies::raise_domain_error<typename Dist::value_type>(
0122 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3);
0123 }
0124 typename Dist::value_type z = c.dist;
0125 if(!(boost::math::isfinite)(z))
0126 {
0127 return policies::raise_domain_error<typename Dist::value_type>(
0128 function, "find_scale z parameter was %1%, but must be finite!", z, c.param3);
0129 }
0130 typename Dist::value_type location = c.param2;
0131 if(!(boost::math::isfinite)(location))
0132 {
0133 return policies::raise_domain_error<typename Dist::value_type>(
0134 function, "find_scale location parameter was %1%, but must be finite!", location, c.param3);
0135 }
0136
0137 typename Dist::value_type result =
0138 (c.dist - c.param2)
0139 / quantile(complement(Dist(), c.param1));
0140
0141 if (result <= 0)
0142 {
0143 policies::raise_evaluation_error<typename Dist::value_type>(function,
0144 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
0145 result, Policy());
0146 }
0147 return result;
0148 }
0149
0150
0151
0152
0153 template <class Dist, class Real1, class Real2, class Real3>
0154 inline typename Dist::value_type find_scale(
0155 complemented3_type<Real1, Real2, Real3> const& c)
0156 {
0157
0158
0159
0160
0161
0162
0163
0164 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
0165 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
0166 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
0167
0168
0169
0170 typename Dist::value_type q = c.param1;
0171 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
0172 {
0173 return policies::raise_domain_error<typename Dist::value_type>(
0174 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>());
0175 }
0176 typename Dist::value_type z = c.dist;
0177 if(!(boost::math::isfinite)(z))
0178 {
0179 return policies::raise_domain_error<typename Dist::value_type>(
0180 function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>());
0181 }
0182 typename Dist::value_type location = c.param2;
0183 if(!(boost::math::isfinite)(location))
0184 {
0185 return policies::raise_domain_error<typename Dist::value_type>(
0186 function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>());
0187 }
0188
0189 typename Dist::value_type result =
0190 (z - location)
0191 / quantile(complement(Dist(), q));
0192
0193 if (result <= 0)
0194 {
0195 policies::raise_evaluation_error<typename Dist::value_type>(function,
0196 "Computed scale (%1%) is <= 0!" " Was the complement intended?",
0197 result, policies::policy<>());
0198 }
0199 return result;
0200 }
0201
0202 }
0203 }
0204
0205 #endif