File indexing completed on 2025-07-03 08:18:17
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, "Computed scale (%1%) is <= 0!" " Was the complement intended?", result, Policy());
0084 }
0085 return result;
0086 }
0087
0088 template <class Dist>
0089 inline
0090 typename Dist::value_type find_scale(
0091 typename Dist::value_type z,
0092
0093 typename Dist::value_type p,
0094 typename Dist::value_type location)
0095 {
0096 return (find_scale<Dist>(z, p, location, policies::policy<>()));
0097 }
0098
0099 template <class Dist, class Real1, class Real2, class Real3, class Policy>
0100 inline typename Dist::value_type find_scale(
0101 complemented4_type<Real1, Real2, Real3, Policy> const& c)
0102 {
0103
0104
0105
0106
0107
0108
0109
0110 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
0111 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
0112 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
0113
0114
0115
0116 typename Dist::value_type q = c.param1;
0117 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
0118 {
0119 return policies::raise_domain_error<typename Dist::value_type>(
0120 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3);
0121 }
0122 typename Dist::value_type z = c.dist;
0123 if(!(boost::math::isfinite)(z))
0124 {
0125 return policies::raise_domain_error<typename Dist::value_type>(
0126 function, "find_scale z parameter was %1%, but must be finite!", z, c.param3);
0127 }
0128 typename Dist::value_type location = c.param2;
0129 if(!(boost::math::isfinite)(location))
0130 {
0131 return policies::raise_domain_error<typename Dist::value_type>(
0132 function, "find_scale location parameter was %1%, but must be finite!", location, c.param3);
0133 }
0134
0135 typename Dist::value_type result =
0136 (c.dist - c.param2)
0137 / quantile(complement(Dist(), c.param1));
0138
0139 if (result <= 0)
0140 {
0141 policies::raise_evaluation_error<typename Dist::value_type>(function, "Computed scale (%1%) is <= 0!" " Was the complement intended?", result, Policy());
0142 }
0143 return result;
0144 }
0145
0146
0147
0148
0149 template <class Dist, class Real1, class Real2, class Real3>
0150 inline typename Dist::value_type find_scale(
0151 complemented3_type<Real1, Real2, Real3> const& c)
0152 {
0153
0154
0155
0156
0157
0158
0159
0160 static_assert(::boost::math::tools::is_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a distribution.");
0161 static_assert(::boost::math::tools::is_scaled_distribution<Dist>::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution.");
0162 static const char* function = "boost::math::find_scale<Dist, Policy>(complement(%1%, %1%, %1%, Policy))";
0163
0164
0165
0166 typename Dist::value_type q = c.param1;
0167 if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1))
0168 {
0169 return policies::raise_domain_error<typename Dist::value_type>(
0170 function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>());
0171 }
0172 typename Dist::value_type z = c.dist;
0173 if(!(boost::math::isfinite)(z))
0174 {
0175 return policies::raise_domain_error<typename Dist::value_type>(
0176 function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>());
0177 }
0178 typename Dist::value_type location = c.param2;
0179 if(!(boost::math::isfinite)(location))
0180 {
0181 return policies::raise_domain_error<typename Dist::value_type>(
0182 function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>());
0183 }
0184
0185 typename Dist::value_type result =
0186 (z - location)
0187 / quantile(complement(Dist(), q));
0188
0189 if (result <= 0)
0190 {
0191 policies::raise_evaluation_error<typename Dist::value_type>(function, "Computed scale (%1%) is <= 0!" " Was the complement intended?",
0192 result, policies::policy<>());
0193 }
0194 return result;
0195 }
0196
0197 }
0198 }
0199
0200 #endif