From ef60681b1d043cd4fc0d5d3f2496d3f540c425c8 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 21 Sep 2026 02:07:44 +0200 Subject: [PATCH] Parameters: cover logarithmic scale conversions this feature relies on the common logarithmic math, yet with the additional twist that decibels need an additional factor of 10... --- src/lib/par/scale.hpp | 2 +- tests/lib/par/parameter-scale-test.cpp | 45 ++++++++++++++++++++++++-- wiki/thinkPad.ichthyo.mm | 29 +++++++++++++++-- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/lib/par/scale.hpp b/src/lib/par/scale.hpp index ff30ec83f..4d6303107 100644 --- a/src/lib/par/scale.hpp +++ b/src/lib/par/scale.hpp @@ -277,7 +277,7 @@ namespace par { { case NAT: return std::exp (WorkType(value)); case BIN: return std::exp2 (WorkType(value)); - case DEC: return std::pow (10, value/10.0); + case DEC: return std::pow (WorkType(10), WorkType(value/10.0)); default: throw err::Logic{_Fmt{"Attempt to compute exponential " "from a non-logarithmic value with metric %d"} diff --git a/tests/lib/par/parameter-scale-test.cpp b/tests/lib/par/parameter-scale-test.cpp index 19b4f905b..bafc620f1 100644 --- a/tests/lib/par/parameter-scale-test.cpp +++ b/tests/lib/par/parameter-scale-test.cpp @@ -116,7 +116,7 @@ namespace test{ /** @test Scales can be configured to wrap cyclically, e.g. for angles. * - demonstrate an unsigned angle scale with short precision * - demonstrate a high-resolution scale symmetric to zero - * @todo WIP 9/26 ✔define ⟶ 🔁 implement + * @todo WIP 9/26 ✔define ⟶ ✔ implement */ void verify_cyclicScale() @@ -158,7 +158,21 @@ namespace test{ /** @test Base value and data feeds from differing Scales can be joined together - * @todo WIP 9/26 🔁 define ⟶ implement + * - when the target scale defines limits (or is cyclic), + * this conforming is applied after all conversions + * - a feed can be marked as "factor", in which case + * the feed is multiplied to the target rather than added + * - even scales with integral type can carry log meaning + * - suitable intermediary types used for good precision, + * and especially to avoid wrapping signed into unsigned + * - the supported logarithmic flavours are accommodated, + * possibly converting the base of the logarithm accordingly + * - the factor 10 inherent to decibels is applied / removed + * before combining decibel values with other logarithms + * - applying a linear factor to a logarithmic scale is + * transformed into an addition in the logarithmic domain + * - adding a linear offset to a logarithmic scale is rejected + * @todo WIP 9/26 🔁 define ⟶ ✔ implement */ void verify_valueJoining() @@ -183,6 +197,33 @@ namespace test{ // Note: number promotion rules of C++ would backfire nastily here... CHECK (short(-3) * uint64_t(2) > numeric_limits::max()); CHECK (short(-6) == sscale.join (-3, uint64_t(2), uscale)); + + //---floating-point logarithmic scale conversions--- + // + Scale fscale = {.metric = NAT}; + Scale feed_dB = {.metric = DEC}; + CHECK (roughEQ (fscale.join (0, float(20), feed_dB) , log(100.0f) )); // dB ⟼ natural logarithm; note 10dB ≙ factor 10 * lg(10) value divided / 10 + + fscale.metric = DEC; + CHECK (roughEQ (fscale.join (0, float(20), feed_dB) , 20.0f )); // dB ⟼ dB just passed-through and then added to value ≔ 0.0 + + feedScale.metric = BIN; + CHECK (roughEQ (fscale.join (0, int64_t(-3), feedScale), log10(1.0f/8)*10)); // binary log (given as int value) ⟼ dB + + fscale.metric = LIN; + CHECK (roughEQ (fscale.join (1, int64_t(-3), feedScale), 1.0f/8 )); // binary log applied as factor to a linear scale + + fscale.metric = BIN; + feedScale.metric = LIN; + feedScale.neutral = 1; + CHECK (feedScale.isFactor()); + CHECK (fscale.isLogarithmic()); + CHECK (1 + 3 == fscale.join (1, int64_t(8), feedScale)); // feed factor 8 ⟼ to binary logarithmic fscale (8 ≡ 2^3) and added there + + feedScale.neutral = 0; + CHECK (not feedScale.isFactor()); + VERIFY_FAIL ("adding a non-logarithmic data feed on top of a logarithmic base value" + , fscale.join (1, int64_t(8), feedScale)); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index b0ccb82a3..c0d22dd37 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -87251,8 +87251,8 @@ Prop.1: dist%3 1 2 0 1 2 0 - - + + @@ -87263,6 +87263,31 @@ Prop.1: dist%3 1 2 0 1 2 0 + + + + + + + + + + + +

+ ...und dieses Herausdividieren falte ich trickreich in den log-Basis-Konvertierungsfaktor. +

+

+ Überraschung: die Logarithmen-Matematik funktioniert ... aber das dumme Mensch braucht endlos um zu kapieren daß die Beispielwerte stimmen +

+ + +
+
+ + + +