@@ -44,6 +44,16 @@ TestMathsCatSnippets = class(TTestCase)
4444 procedure TestRescaleRange_Double_ExceptAllValuesSame ;
4545 procedure TestRangeOf_Double_ExceptEmpty ;
4646 procedure TestRangeOf_Integer_ExceptEmpty ;
47+ procedure TestWeightedGeoMean_Double_ExceptEmpty ;
48+ procedure TestWeightedGeoMean_Double_ExceptDiffSizeArrays ;
49+ procedure TestWeightedGeoMean_Double_ExceptNegativeWeights ;
50+ procedure TestWeightedGeoMean_Double_ExceptZeroWeights ;
51+ procedure TestGeoMean_Cardinal_ExceptEmpty ;
52+ procedure TestGeoMean_Double_ExceptEmpty ;
53+ procedure TestGeoMean_Integer_ExceptEmpty ;
54+ procedure TestGeoMean_Cardinal_ExceptNotPositive ;
55+ procedure TestGeoMean_Double_ExceptNotPositive ;
56+ procedure TestGeoMean_Integer_ExceptNotPositive ;
4757 function EqualArrays (const Left, Right: TBytes): Boolean; overload;
4858 function EqualArrays (const Left, Right: array of Double;
4959 Fudge: Double = 0.0 ): Boolean; overload;
@@ -118,6 +128,12 @@ TestMathsCatSnippets = class(TTestCase)
118128 procedure TestRescaleRange_Double ;
119129 procedure TestRangeOf_Integer ;
120130 procedure TestRangeOf_Double ;
131+ procedure TestGeoMean_Cardinal ;
132+ procedure TestGeoMean_Double ;
133+ procedure TestGeoMean_Integer ;
134+ procedure TestWeightedGeoMean_Double ; // required by Cardinal & Integer overloads
135+ procedure TestWeightedGeoMean_Cardinal ;
136+ procedure TestWeightedGeoMean_Integer ;
121137 end ;
122138
123139implementation
@@ -614,6 +630,117 @@ procedure TestMathsCatSnippets.TestGCD2;
614630 CheckEquals(10 , GCD2(10 , -10 ), ' GCD2(10, -10)' );
615631end ;
616632
633+ procedure TestMathsCatSnippets.TestGeoMean_Cardinal ;
634+ const
635+ Fudge = 0.00000001 ;
636+ AA: array [0 ..2 ] of Cardinal = (1 , 1 , 1 );
637+ AB: array [0 ..0 ] of Cardinal = (3 );
638+ AC: array [0 ..5 ] of Cardinal = (12 , 56 , 1 , 3 , 12 , 19 );
639+ AD: array [11 ..14 ] of Cardinal = (1000000 , 2222222 , 3333333 , 4444444 );
640+ // Expected results calculated using
641+ // https://www.gigacalculator.com/calculators/geometric-mean-calculator.php
642+ EA = 1.0 ;
643+ EB = 3.0 ;
644+ EC = 8.784914973781 ;
645+ ED = 2395360.566768502351 ;
646+ begin
647+ CheckTrue(Math.SameValue(EA, GeoMean(AA), Fudge), ' A' );
648+ CheckTrue(Math.SameValue(EB, GeoMean(AB), Fudge), ' B' );
649+ CheckTrue(Math.SameValue(EC, GeoMean(AC), Fudge), ' C' );
650+ CheckTrue(Math.SameValue(ED, GeoMean(AD), Fudge), ' D' );
651+ CheckException(TestGeoMean_Cardinal_ExceptEmpty, EArgumentException, ' Empty array' );
652+ CheckException(TestGeoMean_Cardinal_ExceptNotPositive, EArgumentOutOfRangeException, ' Non-positive values' );
653+ end ;
654+
655+ procedure TestMathsCatSnippets.TestGeoMean_Cardinal_ExceptEmpty ;
656+ var
657+ A: array of Cardinal;
658+ begin
659+ SetLength(A, 0 );
660+ GeoMean(A);
661+ end ;
662+
663+ procedure TestMathsCatSnippets.TestGeoMean_Cardinal_ExceptNotPositive ;
664+ const
665+ A: array [1 ..4 ] of Cardinal = (1 , 4 , 0 , 7 );
666+ begin
667+ GeoMean(A);
668+ end ;
669+
670+ procedure TestMathsCatSnippets.TestGeoMean_Double ;
671+ const
672+ Fudge = 0.00000000001 ;
673+ AA: array [0 ..1 ] of Double = (1.0 , 1.0 );
674+ AB: array [0 ..0 ] of Double = (PI);
675+ AC: array [0 ..5 ] of Double = (12.42 , 56.47 , 0.1 , 3.0 , 12.42 , 18.678 );
676+ AD: array [11 ..14 ] of Double = (0.000001 , 0.000002 , 0.000003 , 0.000004 );
677+ // Expected results calculated using
678+ // https://www.gigacalculator.com/calculators/geometric-mean-calculator.php
679+ EA = 1.0 ;
680+ EB = PI;
681+ EC = 6.045312664207 ;
682+ ED = 0.000002213364 ;
683+ begin
684+ CheckTrue(Math.SameValue(EA, GeoMean(AA), Fudge), ' A' );
685+ CheckTrue(Math.SameValue(EB, GeoMean(AB), Fudge), ' B' );
686+ CheckTrue(Math.SameValue(EC, GeoMean(AC), Fudge), ' C' );
687+ CheckTrue(Math.SameValue(ED, GeoMean(AD), Fudge), ' D' );
688+ CheckException(TestGeoMean_Double_ExceptEmpty, EArgumentException, ' Empty array' );
689+ CheckException(TestGeoMean_Double_ExceptNotPositive, EArgumentOutOfRangeException, ' Non-positive values' );
690+ end ;
691+
692+ procedure TestMathsCatSnippets.TestGeoMean_Double_ExceptEmpty ;
693+ var
694+ A: array of Double;
695+ begin
696+ SetLength(A, 0 );
697+ GeoMean(A);
698+ end ;
699+
700+ procedure TestMathsCatSnippets.TestGeoMean_Double_ExceptNotPositive ;
701+ const
702+ A: array [0 ..3 ] of Double = (1.4 , 4.6 , -12.0 , 7.8 );
703+ begin
704+ GeoMean(A);
705+ end ;
706+
707+ procedure TestMathsCatSnippets.TestGeoMean_Integer ;
708+ const
709+ Fudge = 0.00000001 ;
710+ AA: array [0 ..2 ] of Integer = (1 , 1 , 1 );
711+ AB: array [0 ..0 ] of Integer = (3 );
712+ AC: array [0 ..5 ] of Integer = (12 , 56 , 1 , 3 , 12 , 19 );
713+ AD: array [11 ..14 ] of Integer = (1000000 , 2222222 , 3333333 , 4444444 );
714+ // Expected results calculated using
715+ // https://www.gigacalculator.com/calculators/geometric-mean-calculator.php
716+ EA = 1.0 ;
717+ EB = 3.0 ;
718+ EC = 8.784914973781 ;
719+ ED = 2395360.566768502351 ;
720+ begin
721+ CheckTrue(Math.SameValue(EA, GeoMean(AA), Fudge), ' A' );
722+ CheckTrue(Math.SameValue(EB, GeoMean(AB), Fudge), ' B' );
723+ CheckTrue(Math.SameValue(EC, GeoMean(AC), Fudge), ' C' );
724+ CheckTrue(Math.SameValue(ED, GeoMean(AD), Fudge), ' D' );
725+ CheckException(TestGeoMean_Integer_ExceptEmpty, EArgumentException, ' Empty array' );
726+ CheckException(TestGeoMean_Integer_ExceptNotPositive, EArgumentOutOfRangeException, ' Non-positive values' );
727+ end ;
728+
729+ procedure TestMathsCatSnippets.TestGeoMean_Integer_ExceptEmpty ;
730+ var
731+ A: array of Integer;
732+ begin
733+ SetLength(A, 0 );
734+ GeoMean(A);
735+ end ;
736+
737+ procedure TestMathsCatSnippets.TestGeoMean_Integer_ExceptNotPositive ;
738+ const
739+ A: array [0 ..3 ] of Integer = (1 , 4 , -2 , 7 );
740+ begin
741+ GeoMean(A);
742+ end ;
743+
617744procedure TestMathsCatSnippets.TestIsNarcissistic ;
618745const
619746 NarcNumsBase10: array [1 ..25 ] of Integer = (
@@ -1907,6 +2034,117 @@ procedure TestMathsCatSnippets.TestWeightedArithMean_Integer;
19072034 CheckTrue(Math.SameValue(E, WeightedArithMean(A, W)));
19082035end ;
19092036
2037+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Cardinal ;
2038+ const
2039+ Fudge = 0.00001 ;
2040+ AA: array [0 ..1 ] of Cardinal = (1 , 1 );
2041+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2042+ AB: array [0 ..0 ] of Cardinal = (3 );
2043+ WB: array [0 ..0 ] of Double = (5.0 );
2044+ AC: array [0 ..5 ] of Cardinal = (12 , 56 , 1 , 3 , 12 , 19 );
2045+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2046+ AD: array [11 ..14 ] of Cardinal = (10001 , 20002 , 30003 , 40004 );
2047+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2048+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2049+ EA = 1.0 ;
2050+ EB = 3.0 ;
2051+ EC = 8.53238 ;
2052+ ED = 22135.851757845830 ;
2053+ begin
2054+ CheckTrue(Math.SameValue(EA, WeightedGeoMean(AA, WA), Fudge), ' A' );
2055+ CheckTrue(Math.SameValue(EB, WeightedGeoMean(AB, WB), Fudge), ' B' );
2056+ CheckTrue(Math.SameValue(EC, WeightedGeoMean(AC, WC), Fudge), ' C' );
2057+ CheckTrue(Math.SameValue(ED, WeightedGeoMean(AD, WD), Fudge), ' D' );
2058+ // Exceptions not checked: WeightedGeoMean Cardinal overload calls Double
2059+ // overload which raises execptions. So tests of Double overload exceptions
2060+ // suffice.
2061+ end ;
2062+
2063+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Double ;
2064+ const
2065+ Fudge = 0.00001 ;
2066+ AA: array [0 ..1 ] of Double = (1.0 , 1.0 );
2067+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2068+ AB: array [0 ..0 ] of Double = (PI);
2069+ WB: array [0 ..0 ] of Double = (5.0 );
2070+ AC: array [0 ..5 ] of Double = (12.42 , 56.47 , 0.1 , 3.0 , 12.42 , 18.678 );
2071+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2072+ AD: array [11 ..14 ] of Double = (0.000001 , 0.000002 , 0.000003 , 0.000004 );
2073+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2074+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2075+ EA = 1.0 ;
2076+ EB = PI;
2077+ EC = 6.17599 ;
2078+ ED = 2.2133638394006e-6 ;
2079+ begin
2080+ CheckTrue(Math.SameValue(EA, WeightedGeoMean(AA, WA), Fudge), ' A' );
2081+ CheckTrue(Math.SameValue(EB, WeightedGeoMean(AB, WB), Fudge), ' B' );
2082+ CheckTrue(Math.SameValue(EC, WeightedGeoMean(AC, WC), Fudge), ' C' );
2083+ CheckTrue(Math.SameValue(ED, WeightedGeoMean(AD, WD), Fudge), ' D' );
2084+ CheckException(TestWeightedGeoMean_Double_ExceptEmpty, EArgumentException, ' Empty array' );
2085+ CheckException(TestWeightedGeoMean_Double_ExceptDiffSizeArrays, EArgumentException, ' Different size arrays' );
2086+ CheckException(TestWeightedGeoMean_Double_ExceptNegativeWeights, EArgumentException, ' Negative weights' );
2087+ CheckException(TestWeightedGeoMean_Double_ExceptZeroWeights, EArgumentException, ' Weights sum to zero' );
2088+ end ;
2089+
2090+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Double_ExceptDiffSizeArrays ;
2091+ const
2092+ A: array [1 ..2 ] of Double = (1.0 , 2.0 );
2093+ W: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2094+ begin
2095+ WeightedGeoMean(A, W);
2096+ end ;
2097+
2098+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Double_ExceptEmpty ;
2099+ var
2100+ A: array of Double;
2101+ begin
2102+ SetLength(A, 0 );
2103+ WeightedGeoMean(A, A);
2104+ end ;
2105+
2106+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Double_ExceptNegativeWeights ;
2107+ const
2108+ A: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2109+ W: array [1 ..3 ] of Double = (1.0 , -2.0 , 3.0 );
2110+ begin
2111+ WeightedGeoMean(A, W);
2112+ end ;
2113+
2114+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Double_ExceptZeroWeights ;
2115+ const
2116+ A: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2117+ W: array [1 ..3 ] of Double = (0.0 , 0.0 , 0.0 );
2118+ begin
2119+ WeightedGeoMean(A, W);
2120+ end ;
2121+
2122+ procedure TestMathsCatSnippets.TestWeightedGeoMean_Integer ;
2123+ const
2124+ Fudge = 0.00001 ;
2125+ AA: array [0 ..1 ] of Integer = (1 , 1 );
2126+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2127+ AB: array [0 ..0 ] of Integer = (3 );
2128+ WB: array [0 ..0 ] of Double = (5.0 );
2129+ AC: array [0 ..5 ] of Integer = (12 , 56 , 1 , 3 , 12 , 19 );
2130+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2131+ AD: array [11 ..14 ] of Integer = (10001 , 20002 , 30003 , 40004 );
2132+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2133+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2134+ EA = 1.0 ;
2135+ EB = 3.0 ;
2136+ EC = 8.53238 ;
2137+ ED = 22135.851757845830 ;
2138+ begin
2139+ CheckTrue(Math.SameValue(EA, WeightedGeoMean(AA, WA), Fudge), ' A' );
2140+ CheckTrue(Math.SameValue(EB, WeightedGeoMean(AB, WB), Fudge), ' B' );
2141+ CheckTrue(Math.SameValue(EC, WeightedGeoMean(AC, WC), Fudge), ' C' );
2142+ CheckTrue(Math.SameValue(ED, WeightedGeoMean(AD, WD), Fudge), ' D' );
2143+ // Exceptions not checked: WeightedGeoMean Integer overload calls Double
2144+ // overload which raises execptions. So tests of Double overload exceptions
2145+ // suffice.
2146+ end ;
2147+
19102148initialization
19112149 // Register any test cases with the test runner
19122150 RegisterTest(TestMathsCatSnippets.Suite);
0 commit comments