[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_;}