Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/statistics/univariate_statistics.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ Compute the mode(s) of a data set:

/Nota bene/: The input data must be sorted in order to pass a forward iterator. If data is not sorted random access iterators are required for a call to `std::sort`.
Data containing a NaN have no mode, and a `std::domain_error` is thrown.
If exceptions are disabled, no mode is written.

[heading References]

Expand Down
8 changes: 5 additions & 3 deletions include/boost/math/statistics/detail/single_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,14 @@ template<typename ForwardIterator>
bool mode_has_nan(ForwardIterator first, ForwardIterator last)
{
using Z = typename std::iterator_traits<ForwardIterator>::value_type;
if (std::any_of(first, last, [](const Z& z) { return !(z == z); }))
const bool has_nan = std::any_of(first, last, [](const Z& z) { return !(z == z); });
#ifndef BOOST_MATH_NO_EXCEPTIONS
if (has_nan)
{
BOOST_MATH_THROW_EXCEPTION(std::domain_error("The mode is undefined for data containing a NaN."))
return true;
}
return false;
#endif
return has_nan;
}

template<typename ForwardIterator, typename OutputIterator>
Expand Down
2 changes: 2 additions & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,7 @@ test-suite misc :
/boost/test//boost_unit_test_framework ]
[ run test_ulp.cpp /boost/test//boost_unit_test_framework ]
[ run git_issue_1419.cpp ]
[ run git_issue_1621.cpp ]
[ compile-fail git_issue_1421.cpp ]

# [ run __temporary_test.cpp test_instances//test_instances : : : <test-info>always_show_run_output <pch>off ]
Expand Down Expand Up @@ -2004,6 +2005,7 @@ alias no_eh_tests :
#test_tools_ulps_plot_incl
#test_tools_ulps_heatmap_incl
test_tools_workaround_incl
git_issue_1621
;

explicit no_eh_tests ;
Expand Down
29 changes: 29 additions & 0 deletions test/git_issue_1621.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2026 Shen-Ta Hsieh
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See: https://github.com/boostorg/math/issues/1621

#include <boost/math/statistics/univariate_statistics.hpp>
#include <boost/core/lightweight_test.hpp>
#include <iterator>
#include <limits>
#include <stdexcept>
#include <vector>

int main()
{
std::vector<double> v {1.0, 2.0, 2.0, std::numeric_limits<double>::quiet_NaN()};
std::vector<double> modes;

// Without exceptions, data that contain a NaN give no mode, and boost::throw_exception is not called
#ifndef BOOST_MATH_NO_EXCEPTIONS
BOOST_TEST_THROWS(boost::math::statistics::mode(v.begin(), v.end(), std::back_inserter(modes)), std::domain_error);
#else
boost::math::statistics::mode(v.begin(), v.end(), std::back_inserter(modes));
#endif
BOOST_TEST(modes.empty());

return boost::report_errors();
}
Loading