From bc1815e4d33d87d7414d07c96e1a5f5b2f962872 Mon Sep 17 00:00:00 2001 From: Sam Stern Date: Fri, 18 Aug 2023 19:07:48 -0400 Subject: [PATCH 1/6] Added geometric mean --- src/Data/Quantity/Math.purs | 5 +++++ src/Quantities.purs | 2 +- test/Main.purs | 7 ++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index 4df1f1a..a89ba1a 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -38,6 +38,7 @@ module Data.Quantity.Math , min2 , min , mean + , geomean , modulo , round , gamma @@ -177,6 +178,10 @@ mean ∷ NonEmptyList Quantity → Result mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) +geomean ∷ NonEmptyList Quantity → Result +geomean xs = (pow (_ (1 ⊘ n))) <$> foldM (⊗) (head xs) (tail xs) + where + n = scalar' (Decimal.fromInt (length xs)) modulo ∷ Quantity → Quantity → Result modulo = lift2 Decimal.modulo diff --git a/src/Quantities.purs b/src/Quantities.purs index 15fc95b..d3ea318 100644 --- a/src/Quantities.purs +++ b/src/Quantities.purs @@ -26,7 +26,7 @@ import Data.Quantity (ConversionError(..), Quantity, abs, approximatelyEqual, as sqrt, toScalar, toScalar', toStandard, (.*), (⊕), (⊖), (⊗), (⊘)) as DQ import Data.Quantity.Math (acos, acosh, acot, acoth, acsc, acsch, asec, asech, asin, asinh, atan, atan2, atanh, ceil, cos, cosh, cot, coth, csc, csch, e, exp, factorial, - floor, gamma, ln, log10, max, max2, mean, min, min2, modulo, pi, round, + floor, gamma, ln, log10, max, max2, mean, geomean, min, min2, modulo, pi, round, sec, sech, sin, sinh, tan, tanh, tau, phi) as DQM import Data.Quantity.Physics (avogadroConstant, electronCharge, electronMass, g0, gravitationalConstant, kB, planckConstant, protonMass, diff --git a/test/Main.purs b/test/Main.purs index bfaa95c..cd47c85 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -36,7 +36,7 @@ import Data.Quantity (Quantity, (.*), prettyPrint, (⊕), (⊖), (⊗), (⊘), errorMessage, showResult, qNegate, isFinite, ConversionError(..)) import Data.Quantity as Q -import Data.Quantity.Math (sin, asin, pi, modulo, max, min, mean, atan2) +import Data.Quantity.Math (sin, asin, pi, modulo, max, min, mean, geomean, atan2) import Effect (Effect) @@ -511,6 +511,7 @@ main = runTest do : (-1.0 .* inch) : Nil let qs3 = NonEmptyList $ (4.2 .* second) :| Nil + let qs4 = NonEmptyList $ scalar (3.0) :| scalar 4.0 : scalar 2.0 : Nil test "max" do equal (Right $ scalar 4.0) (max qs1) @@ -526,7 +527,11 @@ main = runTest do equal (Right $ scalar 1.0) (mean qs1) equal (Right $ 1.0 .* meter) (mean qs2) equal (Right $ 4.2 .* second) (mean qs3) + test "geomean" do + + equal (Right $ 4.2 .* second) (geomean qs3) + equal (Right $ scalar 2.9) (geomean qs4) suite "Consistency checks" do test "Data.Units.SI.Derived" do -- See: https://en.wikipedia.org/wiki/International_System_of_Units#Derived_units From 9385b3d7312c876b26973c82876f5dcec882df04 Mon Sep 17 00:00:00 2001 From: Sam Stern Date: Fri, 18 Aug 2023 19:23:25 -0400 Subject: [PATCH 2/6] Fixed name issues, added type issues --- src/Data/Quantity/Math.purs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index a89ba1a..d9ab46c 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -56,7 +56,7 @@ import Data.Foldable (foldM) import Data.Decimal (Decimal) import Data.Either (Either) import Data.Quantity (Quantity, ConversionError, derivedUnit, asValueIn', - scalar', quantity', toScalar', (⊘), (⊕), (.*)) + scalar', quantity', toScalar', (⊗), (⊘), (⊕), (.*), pow) type Result = Either ConversionError Quantity @@ -179,7 +179,7 @@ mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) geomean ∷ NonEmptyList Quantity → Result -geomean xs = (pow (_ (1 ⊘ n))) <$> foldM (⊗) (head xs) (tail xs) +geomean xs = (_ `pow` (1.0 ⊘ n)) <$> foldM (⊗) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) From 32a96384ba52f3a9c2fab120fa480b100c749611 Mon Sep 17 00:00:00 2001 From: Sam Stern Date: Fri, 18 Aug 2023 19:45:12 -0400 Subject: [PATCH 3/6] This should work but doesn't --- src/Data/Quantity/Math.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index d9ab46c..4ce44d9 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -179,7 +179,7 @@ mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) geomean ∷ NonEmptyList Quantity → Result -geomean xs = (_ `pow` (1.0 ⊘ n)) <$> foldM (⊗) (head xs) (tail xs) +geomean xs = (_ `pow` ((scalar' one) ⊘ n)) <$> foldM (⊗) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) From 4888c70c4870b6982bfdf9243c1a3fa03dc988cf Mon Sep 17 00:00:00 2001 From: Sam Stern Date: Fri, 18 Aug 2023 19:58:28 -0400 Subject: [PATCH 4/6] Fixed type issues in geomean, type issues remain in tests --- src/Data/Quantity/Math.purs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index 4ce44d9..7f353fe 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -57,7 +57,7 @@ import Data.Decimal (Decimal) import Data.Either (Either) import Data.Quantity (Quantity, ConversionError, derivedUnit, asValueIn', scalar', quantity', toScalar', (⊗), (⊘), (⊕), (.*), pow) - +import Data.Int (toNumber) type Result = Either ConversionError Quantity lift ∷ (Decimal → Decimal) → Quantity → Result @@ -178,10 +178,11 @@ mean ∷ NonEmptyList Quantity → Result mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) where n = scalar' (Decimal.fromInt (length xs)) + geomean ∷ NonEmptyList Quantity → Result -geomean xs = (_ `pow` ((scalar' one) ⊘ n)) <$> foldM (⊗) (head xs) (tail xs) +geomean xs = (_ `pow` ( one / n)) <$> foldM (⊗) (head xs) (tail xs) where - n = scalar' (Decimal.fromInt (length xs)) + n = Decimal.fromInt (length xs) modulo ∷ Quantity → Quantity → Result modulo = lift2 Decimal.modulo From c35c7e4bac6d69b2f26558af5676089164388823 Mon Sep 17 00:00:00 2001 From: Sam Stern Date: Fri, 18 Aug 2023 20:06:53 -0400 Subject: [PATCH 5/6] Added a bit of cleanup, but it still doesn't work --- src/Data/Quantity/Math.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index 7f353fe..ccdad15 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -180,7 +180,7 @@ mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) n = scalar' (Decimal.fromInt (length xs)) geomean ∷ NonEmptyList Quantity → Result -geomean xs = (_ `pow` ( one / n)) <$> foldM (⊗) (head xs) (tail xs) +geomean xs = (_ `pow` (Decimal.recip n)) <$> foldM (⊗) (head xs) (tail xs) where n = Decimal.fromInt (length xs) From 75659c6298054fdc323b99955220300db2abfc91 Mon Sep 17 00:00:00 2001 From: sternj Date: Tue, 22 Aug 2023 11:48:34 -0400 Subject: [PATCH 6/6] Update src/Data/Quantity/Math.purs Co-authored-by: David Peter --- src/Data/Quantity/Math.purs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Quantity/Math.purs b/src/Data/Quantity/Math.purs index ccdad15..8dfc1c9 100644 --- a/src/Data/Quantity/Math.purs +++ b/src/Data/Quantity/Math.purs @@ -180,7 +180,7 @@ mean xs = (_ ⊘ n) <$> foldM (⊕) (head xs) (tail xs) n = scalar' (Decimal.fromInt (length xs)) geomean ∷ NonEmptyList Quantity → Result -geomean xs = (_ `pow` (Decimal.recip n)) <$> foldM (⊗) (head xs) (tail xs) +geomean xs = (_ `pow` (Decimal.fromInt 1 / n)) <$> foldM (⊗) (head xs) (tail xs) where n = Decimal.fromInt (length xs)