|
| 1 | +/* |
| 2 | + * (C) Copyright 1996- ECMWF. |
| 3 | + * |
| 4 | + * This software is licensed under the terms of the Apache Licence Version 2.0 |
| 5 | + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. |
| 6 | + * |
| 7 | + * In applying this licence, ECMWF does not waive the privileges and immunities |
| 8 | + * granted to it by virtue of its status as an intergovernmental organisation nor |
| 9 | + * does it submit to any jurisdiction. |
| 10 | + */ |
| 11 | + |
| 12 | + |
| 13 | +#include "eckit/geo/util.h" |
| 14 | +#include "eckit/maths/FloatingPointExceptions.h" |
| 15 | +#include "eckit/testing/Test.h" |
| 16 | +#include "eckit/types/FloatCompare.h" |
| 17 | + |
| 18 | + |
| 19 | +#define EXPECT_APPROX(a, b) EXPECT(::eckit::types::is_approximately_equal<double>((a), (b), 1e-6)) |
| 20 | + |
| 21 | + |
| 22 | +namespace eckit::geo::test { |
| 23 | + |
| 24 | + |
| 25 | +/** |
| 26 | + * This case verifies that Floating Point Exceptions (FPEs) don't trigger for the functions: |
| 27 | + * - eckit::geo::util::gaussian_latitudes |
| 28 | + * - eckit::geo::util::gaussian_quadrature_weights |
| 29 | + * |
| 30 | + * FPE trapping is enabled to ensure any FPE-triggering operations are caught. |
| 31 | + * @see ECKIT-674 |
| 32 | + */ |
| 33 | +CASE("gaussian_latitudes") { |
| 34 | + const auto& lats_1 = geo::util::gaussian_latitudes(1, true); |
| 35 | + |
| 36 | + EXPECT(lats_1.size() == 2); |
| 37 | + EXPECT_APPROX(lats_1.front(), -35.264390); |
| 38 | + EXPECT_APPROX(lats_1.front(), -lats_1.back()); |
| 39 | + |
| 40 | + const auto& lats_2 = geo::util::gaussian_latitudes(80, false); |
| 41 | + |
| 42 | + EXPECT(lats_2.size() == 2 * 80); |
| 43 | + EXPECT_APPROX(lats_2.front(), 89.141519); |
| 44 | + EXPECT_APPROX(lats_2.front(), -lats_2.back()); |
| 45 | +} |
| 46 | + |
| 47 | + |
| 48 | +CASE("gaussian_quadrature_weights") { |
| 49 | + const auto& quad_1 = geo::util::gaussian_quadrature_weights(1); |
| 50 | + |
| 51 | + EXPECT(quad_1.size() == 2); |
| 52 | + EXPECT_APPROX(quad_1.front(), 0.5); |
| 53 | + EXPECT_APPROX(quad_1.front(), quad_1.back()); |
| 54 | + |
| 55 | + const auto& quad_2 = geo::util::gaussian_quadrature_weights(80); |
| 56 | + |
| 57 | + EXPECT(quad_2.size() == 2 * 80); |
| 58 | + EXPECT_APPROX(quad_2.front(), 0.000144); |
| 59 | + EXPECT_APPROX(quad_2.front(), quad_2.back()); |
| 60 | +} |
| 61 | + |
| 62 | + |
| 63 | +} // namespace eckit::geo::test |
| 64 | + |
| 65 | + |
| 66 | +int main(int argc, char** argv) { |
| 67 | + eckit::maths::FloatingPointExceptions::enable_floating_point_exceptions(); |
| 68 | + |
| 69 | + return eckit::testing::run_tests(argc, argv); |
| 70 | +} |
0 commit comments