@@ -60,6 +60,10 @@ TestMathsCatSnippets = class(TTestCase)
6060 procedure TestSumOfReciprocals_Cardinal_ExceptNonPositive ;
6161 procedure TestSumOfReciprocals_Integer_ExceptEmpty ;
6262 procedure TestSumOfReciprocals_Integer_ExceptNonPositive ;
63+ procedure TestWeightedHarmonicMean_Double_ExceptEmpty ;
64+ procedure TestWeightedHarmonicMean_Double_ExceptDiffSizeArrays ;
65+ procedure TestWeightedHarmonicMean_Double_ExceptNegativeWeights ;
66+ procedure TestWeightedHarmonicMean_Double_ExceptZeroWeights ;
6367 function EqualArrays (const Left, Right: TBytes): Boolean; overload;
6468 function EqualArrays (const Left, Right: array of Double;
6569 Fudge: Double = 0.0 ): Boolean; overload;
@@ -129,7 +133,7 @@ TestMathsCatSnippets = class(TTestCase)
129133 procedure TestMinMaxOfArray_Integer ; // required by Rescale & RangeOf
130134 procedure TestMinMaxOfArray_Double ; // required by Rescale & RangeOf
131135 procedure TestNormaliseByWeight_Cardinal ;
132- procedure TestNormaliseByWeight_Double ;
136+ procedure TestNormaliseByWeight_Double ; // required by WeightedGeoMean & WeightedHarmonicMean
133137 procedure TestRescaleRange_Integer ;
134138 procedure TestRescaleRange_Double ;
135139 procedure TestRangeOf_Integer ;
@@ -146,6 +150,9 @@ TestMathsCatSnippets = class(TTestCase)
146150 procedure TestHarmonicMean_Double ;
147151 procedure TestHarmonicMean_Cardinal ;
148152 procedure TestHarmonicMean_Integer ;
153+ procedure TestWeightedHarmonicMean_Double ; // required by Integer & Cardinal overloads
154+ procedure TestWeightedHarmonicMean_Cardinal ;
155+ procedure TestWeightedHarmonicMean_Integer ;
149156 end ;
150157
151158implementation
@@ -2343,6 +2350,126 @@ procedure TestMathsCatSnippets.TestWeightedGeoMean_Integer;
23432350 // suffice.
23442351end ;
23452352
2353+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Cardinal ;
2354+ const
2355+ Fudge = 0.00001 ;
2356+ AA: array [0 ..1 ] of Cardinal = (1 , 1 );
2357+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2358+ AB: array [0 ..0 ] of Cardinal = (3 );
2359+ WB: array [0 ..0 ] of Double = (5.0 );
2360+ AC: array [0 ..5 ] of Cardinal = (12 , 56 , 1 , 3 , 12 , 19 );
2361+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2362+ AD: array [11 ..14 ] of Cardinal = (10001 , 20002 , 30003 , 40004 );
2363+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2364+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2365+ EA = 1.0 ;
2366+ EB = 3.0 ;
2367+ EC = 4.05027 ;
2368+ ED = 19201.92 ;
2369+ begin
2370+ CheckTrue(SameValue(EA, WeightedHarmonicMean(AA, WA), Fudge), ' A' );
2371+ CheckTrue(SameValue(EB, WeightedHarmonicMean(AB, WB), Fudge), ' B' );
2372+ CheckTrue(SameValue(EC, WeightedHarmonicMean(AC, WC), Fudge), ' C' );
2373+ CheckTrue(SameValue(ED, WeightedHarmonicMean(AD, WD), Fudge), ' D' );
2374+ // Exceptions not checked: WeightedHarmonicMean Cardinal overload calls Double
2375+ // overload which raises execptions. So tests of Double overload exceptions
2376+ // suffice.
2377+ end ;
2378+
2379+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Double ;
2380+ const
2381+ Fudge = 0.00001 ;
2382+ AA: array [0 ..1 ] of Double = (1.0 , 1.0 );
2383+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2384+ AB: array [0 ..0 ] of Double = (PI);
2385+ WB: array [0 ..0 ] of Double = (5.0 );
2386+ AC: array [0 ..5 ] of Double = (12.42 , 56.47 , 0.1 , 3.0 , 12.42 , 18.678 );
2387+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2388+ AD: array [11 ..14 ] of Double = (0.000001 , 0.000002 , 0.000003 , 0.000004 );
2389+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2390+ AE: array [0 ..5 ] of Cardinal = (12 , 56 , 1 , 3 , 12 , 19 );
2391+ WE: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2392+ AF: array [11 ..14 ] of Cardinal = (10001 , 20002 , 30003 , 40004 );
2393+ WF: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2394+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2395+ EA = 1.0 ;
2396+ EB = PI;
2397+ EC = 0.65272 ;
2398+ ED = 1.92e-6 ;
2399+ EE = 4.05027 ;
2400+ EF = 19201.92 ;
2401+ begin
2402+ CheckTrue(SameValue(EA, WeightedHarmonicMean(AA, WA), Fudge), ' A' );
2403+ CheckTrue(SameValue(EB, WeightedHarmonicMean(AB, WB), Fudge), ' B' );
2404+ CheckTrue(SameValue(EC, WeightedHarmonicMean(AC, WC), Fudge), ' C' );
2405+ CheckTrue(SameValue(ED, WeightedHarmonicMean(AD, WD), Fudge), ' D' );
2406+ CheckTrue(SameValue(EE, WeightedHarmonicMean(AE, WE), Fudge), ' E' );
2407+ CheckTrue(SameValue(EF, WeightedHarmonicMean(AF, WF), Fudge), ' F' );
2408+
2409+ CheckException(TestWeightedHarmonicMean_Double_ExceptEmpty, EArgumentException, ' Empty array' );
2410+ CheckException(TestWeightedHarmonicMean_Double_ExceptDiffSizeArrays, EArgumentException, ' Different size arrays' );
2411+ CheckException(TestWeightedHarmonicMean_Double_ExceptNegativeWeights, EArgumentException, ' Negative weights' );
2412+ CheckException(TestWeightedHarmonicMean_Double_ExceptZeroWeights, EArgumentException, ' Weights sum to zero' );
2413+ end ;
2414+
2415+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Double_ExceptDiffSizeArrays ;
2416+ const
2417+ A: array [1 ..2 ] of Double = (1.0 , 2.0 );
2418+ W: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2419+ begin
2420+ WeightedHarmonicMean(A, W);
2421+ end ;
2422+
2423+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Double_ExceptEmpty ;
2424+ var
2425+ A: array of Double;
2426+ begin
2427+ SetLength(A, 0 );
2428+ WeightedHarmonicMean(A, A);
2429+ end ;
2430+
2431+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Double_ExceptNegativeWeights ;
2432+ const
2433+ A: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2434+ W: array [1 ..3 ] of Double = (1.0 , -2.0 , 3.0 );
2435+ begin
2436+ WeightedHarmonicMean(A, W);
2437+ end ;
2438+
2439+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Double_ExceptZeroWeights ;
2440+ const
2441+ A: array [1 ..3 ] of Double = (1.0 , 2.0 , 3.0 );
2442+ W: array [1 ..3 ] of Double = (0.0 , 0.0 , 0.0 );
2443+ begin
2444+ WeightedHarmonicMean(A, W);
2445+ end ;
2446+
2447+ procedure TestMathsCatSnippets.TestWeightedHarmonicMean_Integer ;
2448+ const
2449+ Fudge = 0.00001 ;
2450+ AA: array [0 ..1 ] of Integer = (1 , 1 );
2451+ WA: array [0 ..1 ] of Double = (0.25 , 0.75 );
2452+ AB: array [0 ..0 ] of Integer = (3 );
2453+ WB: array [0 ..0 ] of Double = (5.0 );
2454+ AC: array [0 ..5 ] of Integer = (12 , 56 , 1 , 3 , 12 , 19 );
2455+ WC: array [0 ..5 ] of Double = (1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 );
2456+ AD: array [11 ..14 ] of Integer = (10001 , 20002 , 30003 , 40004 );
2457+ WD: array [9 ..12 ] of Double = (1.0 , 1.0 , 1.0 , 1.0 );
2458+ // Expected results calculated using https://www.dcode.fr/weighted-mean
2459+ EA = 1.0 ;
2460+ EB = 3.0 ;
2461+ EC = 4.05027 ;
2462+ ED = 19201.92 ;
2463+ begin
2464+ CheckTrue(SameValue(EA, WeightedHarmonicMean(AA, WA), Fudge), ' A' );
2465+ CheckTrue(SameValue(EB, WeightedHarmonicMean(AB, WB), Fudge), ' B' );
2466+ CheckTrue(SameValue(EC, WeightedHarmonicMean(AC, WC), Fudge), ' C' );
2467+ CheckTrue(SameValue(ED, WeightedHarmonicMean(AD, WD), Fudge), ' D' );
2468+ // Exceptions not checked: WeightedHarmonicMean Integer overload calls Double
2469+ // overload which raises execptions. So tests of Double overload exceptions
2470+ // suffice.
2471+ end ;
2472+
23462473initialization
23472474 // Register any test cases with the test runner
23482475 RegisterTest(TestMathsCatSnippets.Suite);
0 commit comments