@@ -719,11 +719,6 @@ namespace boost
719719 return result;
720720 }
721721
722- #if 0
723- //
724- // This code is disabled, since there can be multiple answers to the
725- // question, and it's not clear how to find the "right" one.
726- //
727722 template <class RealType , class Policy >
728723 struct t_degrees_of_freedom_finder
729724 {
@@ -749,13 +744,19 @@ namespace boost
749744 inline RealType find_t_degrees_of_freedom (
750745 RealType delta, RealType x, RealType p, RealType q, const Policy& pol)
751746 {
747+ using std::fabs;
752748 const char * function = " non_central_t<%1%>::find_degrees_of_freedom" ;
753749 if ((p == 0 ) || (q == 0 ))
754750 {
755751 //
756- // Can't a thing if one of p and q is zero:
752+ // Can't find a thing if one of p and q is zero:
757753 //
758- return policies::raise_evaluation_error<RealType>(function, "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%", // LCOV_EXCL_LINE
754+ return policies::raise_evaluation_error<RealType>(function, " Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%" ,
755+ RealType (std::numeric_limits<RealType>::quiet_NaN ()), Policy ()); // LCOV_EXCL_LINE
756+ }
757+ if (fabs (x) < tools::epsilon<RealType>())
758+ {
759+ return policies::raise_evaluation_error<RealType>(function, " Can't find degrees of freedom when the abscissa value is very close to zero as all degrees of freedom generate the same CDF at x=0: try again further out in the tails!!" ,
759760 RealType (std::numeric_limits<RealType>::quiet_NaN ()), Policy ()); // LCOV_EXCL_LINE
760761 }
761762 t_degrees_of_freedom_finder<RealType, Policy> f (delta, x, p < q ? p : q, p < q ? false : true );
@@ -766,7 +767,7 @@ namespace boost
766767 //
767768 RealType guess = 200 ;
768769 std::pair<RealType, RealType> ir = tools::bracket_and_solve_root (
769- f, guess, RealType(2), false, tol, max_iter, pol);
770+ f, guess, RealType (2 ), x < 0 ? false : true , tol, max_iter, pol);
770771 RealType result = ir.first + (ir.second - ir.first ) / 2 ;
771772 if (max_iter >= policies::get_max_root_iterations<Policy>())
772773 {
@@ -819,9 +820,9 @@ namespace boost
819820 //
820821 RealType guess;
821822 if (f (0 ) < 0 )
822- guess = 1;
823- else
824823 guess = -1 ;
824+ else
825+ guess = 1 ;
825826 std::pair<RealType, RealType> ir = tools::bracket_and_solve_root (
826827 f, guess, RealType (2 ), false , tol, max_iter, pol);
827828 RealType result = ir.first + (ir.second - ir.first ) / 2 ;
@@ -832,7 +833,6 @@ namespace boost
832833 }
833834 return result;
834835 }
835- #endif
836836 } // namespace detail ======================================================================
837837
838838 template <class RealType = double , class Policy = policies::policy<> >
@@ -864,26 +864,22 @@ namespace boost
864864 { // Private data getter function.
865865 return ncp;
866866 }
867- #if 0
868- //
869- // This code is disabled, since there can be multiple answers to the
870- // question, and it's not clear how to find the "right" one.
871- //
867+
872868 static RealType find_degrees_of_freedom (RealType delta, RealType x, RealType p)
873869 {
874870 const char * function = " non_central_t<%1%>::find_degrees_of_freedom" ;
875- typedef typename policies::evaluation<RealType, Policy>::type value_type ;
871+ typedef typename policies::evaluation<RealType, Policy>::type eval_type ;
876872 typedef typename policies::normalise<
877873 Policy,
878874 policies::promote_float<false >,
879875 policies::promote_double<false >,
880876 policies::discrete_quantile<>,
881877 policies::assert_undefined<> >::type forwarding_policy;
882- value_type result = detail::find_t_degrees_of_freedom(
883- static_cast<value_type >(delta),
884- static_cast<value_type >(x),
885- static_cast<value_type >(p),
886- static_cast<value_type >(1-p),
878+ eval_type result = detail::find_t_degrees_of_freedom (
879+ static_cast <eval_type >(delta),
880+ static_cast <eval_type >(x),
881+ static_cast <eval_type >(p),
882+ static_cast <eval_type >(1 -p),
887883 forwarding_policy ());
888884 return policies::checked_narrowing_cast<RealType, forwarding_policy>(
889885 result,
@@ -893,18 +889,18 @@ namespace boost
893889 static RealType find_degrees_of_freedom (const complemented3_type<A,B,C>& c)
894890 {
895891 const char * function = " non_central_t<%1%>::find_degrees_of_freedom" ;
896- typedef typename policies::evaluation<RealType, Policy>::type value_type ;
892+ typedef typename policies::evaluation<RealType, Policy>::type eval_type ;
897893 typedef typename policies::normalise<
898894 Policy,
899895 policies::promote_float<false >,
900896 policies::promote_double<false >,
901897 policies::discrete_quantile<>,
902898 policies::assert_undefined<> >::type forwarding_policy;
903- value_type result = detail::find_t_degrees_of_freedom(
904- static_cast<value_type >(c.dist),
905- static_cast<value_type >(c.param1),
906- static_cast<value_type >(1-c.param2),
907- static_cast<value_type >(c.param2),
899+ eval_type result = detail::find_t_degrees_of_freedom (
900+ static_cast <eval_type >(c.dist ),
901+ static_cast <eval_type >(c.param1 ),
902+ static_cast <eval_type >(1 -c.param2 ),
903+ static_cast <eval_type >(c.param2 ),
908904 forwarding_policy ());
909905 return policies::checked_narrowing_cast<RealType, forwarding_policy>(
910906 result,
@@ -913,18 +909,18 @@ namespace boost
913909 static RealType find_non_centrality (RealType v, RealType x, RealType p)
914910 {
915911 const char * function = " non_central_t<%1%>::find_t_non_centrality" ;
916- typedef typename policies::evaluation<RealType, Policy>::type value_type ;
912+ typedef typename policies::evaluation<RealType, Policy>::type eval_type ;
917913 typedef typename policies::normalise<
918914 Policy,
919915 policies::promote_float<false >,
920916 policies::promote_double<false >,
921917 policies::discrete_quantile<>,
922918 policies::assert_undefined<> >::type forwarding_policy;
923- value_type result = detail::find_t_non_centrality(
924- static_cast<value_type >(v),
925- static_cast<value_type >(x),
926- static_cast<value_type >(p),
927- static_cast<value_type >(1-p),
919+ eval_type result = detail::find_t_non_centrality (
920+ static_cast <eval_type >(v),
921+ static_cast <eval_type >(x),
922+ static_cast <eval_type >(p),
923+ static_cast <eval_type >(1 -p),
928924 forwarding_policy ());
929925 return policies::checked_narrowing_cast<RealType, forwarding_policy>(
930926 result,
@@ -934,24 +930,23 @@ namespace boost
934930 static RealType find_non_centrality (const complemented3_type<A,B,C>& c)
935931 {
936932 const char * function = " non_central_t<%1%>::find_t_non_centrality" ;
937- typedef typename policies::evaluation<RealType, Policy>::type value_type ;
933+ typedef typename policies::evaluation<RealType, Policy>::type eval_type ;
938934 typedef typename policies::normalise<
939935 Policy,
940936 policies::promote_float<false >,
941937 policies::promote_double<false >,
942938 policies::discrete_quantile<>,
943939 policies::assert_undefined<> >::type forwarding_policy;
944- value_type result = detail::find_t_non_centrality(
945- static_cast<value_type >(c.dist),
946- static_cast<value_type >(c.param1),
947- static_cast<value_type >(1-c.param2),
948- static_cast<value_type >(c.param2),
940+ eval_type result = detail::find_t_non_centrality (
941+ static_cast <eval_type >(c.dist ),
942+ static_cast <eval_type >(c.param1 ),
943+ static_cast <eval_type >(1 -c.param2 ),
944+ static_cast <eval_type >(c.param2 ),
949945 forwarding_policy ());
950946 return policies::checked_narrowing_cast<RealType, forwarding_policy>(
951947 result,
952948 function);
953949 }
954- #endif
955950 private:
956951 // Data member, initialized by constructor.
957952 RealType v; // degrees of freedom
0 commit comments