/* * (C) Copyright Nick Thompson 2018. * Copyright Matt Borland 2026. * 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) */ // // Module build check for the vector norms in . // Consuming the exported free functions through the boost.math module exercises // sup_norm, l1_norm, l2_norm, lp_norm, l0_pseudo_norm, hamming_distance, // total_variation and the l1/l2/lp/sup distances. Every expected value here is // mathematically certain (sums, a perfect square root, telescoping differences) // and mirrors the double/float assertions in norms_test.cpp. The // multiprecision, complex, integer and Boost.Test parts of that test are dropped. #ifndef BOOST_MATH_BUILD_MODULE #include #else import boost.math; #endif #ifndef BOOST_MATH_BUILD_MODULE #include #include #include #endif #include "math_unit_test.hpp" template void test_norms() { // sup_norm: largest magnitude. |-2| beats |1| and |0|. std::vector v {-2, 1, 0}; CHECK_ULP_CLOSE(Real(2), boost::math::tools::sup_norm(v), 1); std::array va {-2, 1, 0}; CHECK_ULP_CLOSE(Real(2), boost::math::tools::sup_norm(va), 1); // l1_norm: sum of magnitudes. std::vector ones {1, 1, 1}; CHECK_ULP_CLOSE(Real(3), boost::math::tools::l1_norm(ones), 1); // l2_norm: sqrt of the sum of squares; four ones give sqrt(4) = 2 exactly. std::vector four_ones {1, 1, 1, 1}; CHECK_ULP_CLOSE(Real(2), boost::math::tools::l2_norm(four_ones), 1); // lp_norm: a single nonzero entry reproduces its magnitude for any p. std::array u {1, 0, 0}; CHECK_ULP_CLOSE(Real(1), boost::math::tools::lp_norm(u.begin(), u.end(), 3), 2); u[0] = -8; CHECK_ULP_CLOSE(Real(8), boost::math::tools::lp_norm(u.cbegin(), u.cend(), 3), 16); // l0_pseudo_norm: count of nonzero entries. std::vector sparse {0, 0, 1}; CHECK_EQUAL(std::size_t(1), boost::math::tools::l0_pseudo_norm(sparse)); // hamming_distance: number of differing positions. std::vector h1 {1, 2, 3}; std::vector h2 {1, 2, 4}; CHECK_EQUAL(std::size_t(1), boost::math::tools::hamming_distance(h1, h2)); CHECK_EQUAL(std::size_t(0), boost::math::tools::hamming_distance(h1, h1)); // total_variation: sum of consecutive absolute differences. std::vector flat {1, 1}; CHECK_ULP_CLOSE(Real(0), boost::math::tools::total_variation(flat), 0); std::vector step {1, 2}; CHECK_ULP_CLOSE(Real(1), boost::math::tools::total_variation(step), 1); std::vector ramp {0, 1, 2, 3, 4, 5}; CHECK_ULP_CLOSE(Real(5), boost::math::tools::total_variation(ramp), 1); // l1_distance: distance from a vector to itself is zero; {1,2,3} to {1,1,1} // is 0 + 1 + 2 = 3. std::vector a {1, 2, 3}; std::vector b {1, 1, 1}; CHECK_ULP_CLOSE(Real(0), boost::math::tools::l1_distance(a, a), 0); CHECK_ULP_CLOSE(Real(3), boost::math::tools::l1_distance(a, b), 1); // l2_distance: a vector is at zero distance from itself. CHECK_ULP_CLOSE(Real(0), boost::math::tools::l2_distance(a, a), 0); // sup_distance: {1,1,1,1} to the zero vector is 1. std::vector f1 {1, 1, 1, 1}; std::vector f0 {0, 0, 0, 0}; CHECK_ULP_CLOSE(Real(0), boost::math::tools::sup_distance(f1, f1), 0); CHECK_ULP_CLOSE(Real(1), boost::math::tools::sup_distance(f1, f0), 1); // lp_distance: {1,0,0} to the zero vector is 1 for any p. std::vector p1 {1, 0, 0}; std::vector p0 {0, 0, 0}; CHECK_ULP_CLOSE(Real(0), boost::math::tools::lp_distance(p1, p1, 3), 0); CHECK_ULP_CLOSE(Real(1), boost::math::tools::lp_distance(p1, p0, 3), 2); } int main() { test_norms(); test_norms(); return boost::math::test::report_errors(); }