lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 3d3e2b6 4/4: Improve efficiency


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 3d3e2b6 4/4: Improve efficiency
Date: Mon, 19 Mar 2018 16:43:03 -0400 (EDT)

branch: master
commit 3d3e2b67916c72c7446f140f2f986456b1164b1e
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Improve efficiency
    
    Ascertaining the extrema of all vectors, and then determining a scaling
    factor suitable for the extrema extremorum, is more efficient than
    determining distinct factors for each of several groups of vectors and
    then selecting the highest such factor.
    
    The change to 'bourn_cast_test.cpp' is voodoo that prevents a unit-test
    failure; it will be discussed soon on the mailing list.
---
 bourn_cast_test.cpp |  4 ++--
 ledger.cpp          | 10 ++++++----
 ledger_base.cpp     | 16 ++++++----------
 ledger_base.hpp     |  3 ++-
 miscellany.hpp      | 15 +++++++++++++++
 5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/bourn_cast_test.cpp b/bourn_cast_test.cpp
index ed360bb..96687e6 100644
--- a/bourn_cast_test.cpp
+++ b/bourn_cast_test.cpp
@@ -653,7 +653,7 @@ void mete_static()
         {
         z = static_cast<To>(j);
         }
-    stifle_warning_for_unused_variable(z);
+    (void)&z;
 }
 
 /// Speed test: convert one million times, using bourn_cast.
@@ -670,7 +670,7 @@ void mete_bourn()
         {
         z = bourn_cast<To>(j);
         }
-    stifle_warning_for_unused_variable(z);
+    (void)&z;
 }
 
 void assay_speed()
diff --git a/ledger.cpp b/ledger.cpp
index 86f06f7..3925fba 100644
--- a/ledger.cpp
+++ b/ledger.cpp
@@ -31,6 +31,7 @@
 #include "ledger_variant.hpp"
 #include "map_lookup.hpp"
 #include "mc_enum_types_aux.hpp"        // mc_str()
+#include "miscellany.hpp"               // minmax, scale_power()
 
 #include <algorithm>
 #include <ostream>
@@ -315,16 +316,17 @@ int Ledger::GetMaxLength() const
 // largest absolute value of any number in any column of every subledger.
 void Ledger::AutoScale()
 {
-    int const max_power = 9;
-
-    int k = ledger_invariant_->DetermineScalePower(max_power);
+    minmax<double> extrema = ledger_invariant_->scalable_extrema();
 
     ledger_map_t& l_map_rep = ledger_map_->held_;
     for(auto const& i : l_map_rep)
         {
-        k = std::max(k, i.second.DetermineScalePower(max_power));
+        extrema.subsume(i.second.scalable_extrema());
         }
 
+    int const max_power = 9;
+    int const k = scale_power(max_power, extrema.minimum(), extrema.maximum());
+
     ledger_invariant_->ApplyScaleFactor(k);
 
     for(auto& i : l_map_rep)
diff --git a/ledger_base.cpp b/ledger_base.cpp
index 9ced737..cd4bf08 100644
--- a/ledger_base.cpp
+++ b/ledger_base.cpp
@@ -27,7 +27,6 @@
 #include "assert_lmi.hpp"
 #include "crc32.hpp"
 #include "et_vector.hpp"
-#include "miscellany.hpp"               // minmax, scale_power()
 #include "stl_extensions.hpp"           // nonstd::power()
 #include "value_cast.hpp"
 
@@ -304,21 +303,18 @@ LedgerBase& LedgerBase::PlusEq
     return *this;
 }
 
-/// Triple-power-of-ten scaling to keep ledger extremum < 10^max_power.
+/// Return highest and lowest scalable values.
 
-int LedgerBase::DetermineScalePower(int max_power) const
+minmax<double> LedgerBase::scalable_extrema() const
 {
-    double min_value = 0.0;
-    double max_value = 0.0;
+    minmax<double> extrema;
 
     for(auto const& i : ScalableVectors)
         {
-        minmax<double> extrema(*i.second);
-        min_value = std::min(min_value, extrema.minimum());
-        max_value = std::max(max_value, extrema.maximum());
+        extrema.subsume(minmax<double>(*i.second));
         }
 
-    return scale_power(max_power, min_value, max_value);
+    return extrema;
 }
 
 namespace
@@ -340,7 +336,7 @@ namespace
         }
 } // Unnamed namespace.
 
-/// Scale all scalable vectors by 10^-DetermineScalePower().
+/// Scale all scalable vectors by a decimal power.
 ///
 /// Scale only designated columns (vectors). Interest-rate columns,
 /// e.g., are not scaled because they aren't denominated in dollars.
diff --git a/ledger_base.hpp b/ledger_base.hpp
index 98b7322..2fe15a2 100644
--- a/ledger_base.hpp
+++ b/ledger_base.hpp
@@ -24,6 +24,7 @@
 
 #include "config.hpp"
 
+#include "miscellany.hpp"               // minmax
 #include "so_attributes.hpp"
 
 #include <algorithm>                    // copy()
@@ -176,7 +177,7 @@ class LMI_SO LedgerBase
 
     void               ApplyScaleFactor(int decimal_power);
 
-    int                DetermineScalePower(int max_power) const;
+    minmax<double>     scalable_extrema() const;
     std::string const& ScaleUnit() const;
 // PDF !! expunge
     int                ScalePower() const;
diff --git a/miscellany.hpp b/miscellany.hpp
index 15bc360..232137e 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -33,6 +33,7 @@
 #include <cstdio>                       // EOF
 #include <ios>
 #include <iterator>                     // distance()
+#include <limits>                       // numeric_limits
 #include <string>
 #include <utility>
 #include <vector>
@@ -68,11 +69,19 @@ bool files_are_identical(std::string const&, std::string 
const&);
 /// Heterogeneous relational operators are necessarily free functions.
 ///
 /// Implicitly-declared special member functions do the right thing.
+///
+/// SOMEDAY !! Make this usable with other containers than vector.
 
 template<typename T>
 class minmax
 {
   public:
+    minmax()
+        :minimum_(std::numeric_limits<T>::max())
+        ,maximum_(std::numeric_limits<T>::min())
+        {
+        }
+
     explicit minmax(std::vector<T> const& v)
         {
         auto const& extrema = std::minmax_element(v.begin(), v.end());
@@ -80,6 +89,12 @@ class minmax
         maximum_ = *extrema.second;
         }
 
+    void subsume(minmax<T> const& z)
+        {
+        minimum_ = std::min(minimum_, z.minimum_);
+        maximum_ = std::max(maximum_, z.maximum_);
+        }
+
     T minimum() const {return minimum_;}
     T maximum() const {return maximum_;}
 



reply via email to

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