lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 14ee3ed 5/5: Add and test some useful reducti


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 14ee3ed 5/5: Add and test some useful reductions
Date: Sun, 21 Mar 2021 21:10:53 -0400 (EDT)

branch: master
commit 14ee3ed571facdc3f14aa7c31edde0c9e07b7625
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Add and test some useful reductions
---
 et_vector.hpp      | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 et_vector_test.cpp | 49 ++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+)

diff --git a/et_vector.hpp b/et_vector.hpp
index cd4db2f..c6c501d 100644
--- a/et_vector.hpp
+++ b/et_vector.hpp
@@ -48,6 +48,8 @@
 #include "et_vector_redirect.hpp"
 #include "ssize_lmi.hpp"
 
+#include <algorithm>                    // max(), min()
+#include <cmath>                        // INFINITY
 #include <sstream>
 #include <stdexcept>
 #include <vector>
@@ -204,4 +206,76 @@ inline std::vector<T>& operator<<=(std::vector<T>& t, 
Expression<X> const& x)
     return t = Eval(x);
 }
 
+/// AND-reduction, like APL's "and slash". (Short-circuiting.)
+
+template<typename X>
+inline bool AllOf(Expression<X> const& x)
+{
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        if(!forEach(x, EvalLeaf1(i), OpCombine())) {return false;}
+        }
+    return true;
+}
+
+/// OR-reduction, like APL's "or slash". (Short-circuiting.)
+
+template<typename X>
+inline bool AnyOf(Expression<X> const& x)
+{
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        if(forEach(x, EvalLeaf1(i), OpCombine())) {return true;}
+        }
+    return false;
+}
+
+template<typename X>
+inline auto SumOf(Expression<X> const& x)
+{
+    using Deduced = decltype(forEach(x, EvalLeaf1(0), OpCombine()));
+    Deduced z(0);
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        z += forEach(x, EvalLeaf1(i), OpCombine());
+        }
+    return z;
+}
+
+template<typename X>
+inline auto ProductOf(Expression<X> const& x)
+{
+    using Deduced = decltype(forEach(x, EvalLeaf1(0), OpCombine()));
+    Deduced z(1);
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        z *= forEach(x, EvalLeaf1(i), OpCombine());
+        }
+    return z;
+}
+
+template<typename X>
+inline auto MaxOf(Expression<X> const& x)
+{
+    using Deduced = decltype(forEach(x, EvalLeaf1(0), OpCombine()));
+    Deduced z(-INFINITY);
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        z = std::max(z, forEach(x, EvalLeaf1(i), OpCombine()));
+        }
+    return z;
+}
+
+template<typename X>
+inline auto MinOf(Expression<X> const& x)
+{
+    using Deduced = decltype(forEach(x, EvalLeaf1(0), OpCombine()));
+    Deduced z(INFINITY);
+    for(int i = 0, n = Rho(x); i < n; ++i)
+        {
+        z = std::min(z, forEach(x, EvalLeaf1(i), OpCombine()));
+        }
+    return z;
+}
+
 #endif // et_vector_hpp
diff --git a/et_vector_test.cpp b/et_vector_test.cpp
index 881ca3d..71815f0 100644
--- a/et_vector_test.cpp
+++ b/et_vector_test.cpp
@@ -151,5 +151,54 @@ int test_main(int, char*[])
     LMI_TEST(r2 == v4);
     }
 
+    // Test reductions.
+    //
+    // Unary '+' is not defined for std::vector, but it is for PETE
+    // expressions, so '+v' converts a std::vector 'v' into a PETE
+    // expression.
+    {
+    std::vector<double> v0 = { 0.0, 0.0, 0.0};
+    std::vector<double> v1 = { 0.0, 1.0, 0.0};
+    std::vector<double> v2 = { 1.0, 1.0, 1.0};
+    std::vector<double> v3 = {-1.0, 0.0, 6.5};
+    std::vector<double> v4 = {-1.0, 4.0, 6.5};
+
+    LMI_TEST(false == AllOf(+v0));
+    LMI_TEST(false == AllOf(+v1));
+    LMI_TEST(true  == AllOf(+v2));
+    LMI_TEST(false == AllOf(+v3));
+    LMI_TEST(true  == AllOf(+v4));
+
+    LMI_TEST(false == AnyOf(+v0));
+    LMI_TEST(true  == AnyOf(+v1));
+    LMI_TEST(true  == AnyOf(+v2));
+    LMI_TEST(true  == AnyOf(+v3));
+    LMI_TEST(true  == AnyOf(+v4));
+
+    LMI_TEST_EQUAL( 0.0, SumOf(+v0));
+    LMI_TEST_EQUAL( 1.0, SumOf(+v1));
+    LMI_TEST_EQUAL( 3.0, SumOf(+v2));
+    LMI_TEST_EQUAL( 5.5, SumOf(+v3));
+    LMI_TEST_EQUAL( 9.5, SumOf(+v4));
+
+    LMI_TEST_EQUAL(  0.0, ProductOf(+v0));
+    LMI_TEST_EQUAL(  0.0, ProductOf(+v1));
+    LMI_TEST_EQUAL(  1.0, ProductOf(+v2));
+    LMI_TEST_EQUAL(  0.0, ProductOf(+v3));
+    LMI_TEST_EQUAL(-26.0, ProductOf(+v4));
+
+    LMI_TEST_EQUAL( 0.0, MaxOf(+v0));
+    LMI_TEST_EQUAL( 1.0, MaxOf(+v1));
+    LMI_TEST_EQUAL( 1.0, MaxOf(+v2));
+    LMI_TEST_EQUAL( 6.5, MaxOf(+v3));
+    LMI_TEST_EQUAL( 6.5, MaxOf(+v4));
+
+    LMI_TEST_EQUAL( 0.0, MinOf(+v0));
+    LMI_TEST_EQUAL( 0.0, MinOf(+v1));
+    LMI_TEST_EQUAL( 1.0, MinOf(+v2));
+    LMI_TEST_EQUAL(-1.0, MinOf(+v3));
+    LMI_TEST_EQUAL(-1.0, MinOf(+v4));
+    }
+
     return 0;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]