From 01bb0b94247a4e645b8708d5e7cca33aab9eae06 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <dmitri.naumov@ufz.de>
Date: Mon, 21 Oct 2024 11:58:59 +0200
Subject: [PATCH] [MaL] Use ranges in the cubic roots code

---
 MathLib/Nonlinear/CubicRoots.h | 44 +++++++++++++++-------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/MathLib/Nonlinear/CubicRoots.h b/MathLib/Nonlinear/CubicRoots.h
index be4b0474bb0..e8d36201d1a 100644
--- a/MathLib/Nonlinear/CubicRoots.h
+++ b/MathLib/Nonlinear/CubicRoots.h
@@ -11,6 +11,10 @@
 
 #include <algorithm>
 #include <limits>
+#include <range/v3/algorithm/min.hpp>
+#include <range/v3/algorithm/sort.hpp>
+#include <range/v3/range/conversion.hpp>
+#include <range/v3/view/filter.hpp>
 #include <vector>
 
 #include "BaseLib/Error.h"
@@ -34,44 +38,34 @@ public:
     std::vector<double> solve()
     {
         // Solve using Boost's cubic_roots
-        auto roots = boost::math::tools::cubic_roots<double>(a_, b_, c_, d_);
+        std::array<double, 3> const roots =
+            boost::math::tools::cubic_roots<double>(a_, b_, c_, d_);
 
-        // Sort array
-        std::sort(roots.begin(), roots.end());
+        std::vector<double> filtered_roots =
+            ranges::views::ref(roots) |
+            ranges::views::filter([](double const root)
+                                  { return !std::isnan(root); }) |
+            ranges::to<std::vector>();
+        ranges::sort(filtered_roots);
 
-        std::vector<double> roots_vector;
-        for (const auto& root : roots)
-        {
-            if (!std::isnan(root))
-            {
-                roots_vector.push_back(root);
-            }
-        }
-        return roots_vector;
+        return filtered_roots;
     }
 
     // Method that returns the smallest positive real root
     double smallestPositiveRealRoot()
     {
-        auto roots = solve();
-        double min_positive_root = std::numeric_limits<double>::infinity();
+        std::vector<double> const roots = solve();
 
-        // Find the smallest positive real root
-        for (const auto& root : roots)
-        {
-            if (root > 0 && root < min_positive_root)
-            {
-                min_positive_root = root;
-            }
-        }
+        auto positive_roots =
+            roots | ranges::views::filter([](double root) { return root > 0; });
 
-        // If no positive root was found, return NaN
-        if (min_positive_root == std::numeric_limits<double>::infinity())
+        // If no positive root exists, return NaN
+        if (ranges::empty(positive_roots))
         {
             return std::numeric_limits<double>::quiet_NaN();
         }
 
-        return min_positive_root;
+        return ranges::min(positive_roots);
     }
 
 private:
-- 
GitLab