Skip to content

Commit bd79ce2

Browse files
committed
Add tests for 6 new Maths routines
Added unit tests to TestUMathsCatSnippets for all overloads of the SumOfReciprocals and HarmonicMean functions. Regenerated UMathsCatSnippets using CodeSnip to include the new routines.
1 parent 1a3e56e commit bd79ce2

File tree

2 files changed

+335
-1
lines changed

2 files changed

+335
-1
lines changed

tests/Cat-Maths/TestUMathsCatSnippets.pas

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ TestMathsCatSnippets = class(TTestCase)
5454
procedure TestGeoMean_Cardinal_ExceptNotPositive;
5555
procedure TestGeoMean_Double_ExceptNotPositive;
5656
procedure TestGeoMean_Integer_ExceptNotPositive;
57+
procedure TestSumOfReciprocals_Double_ExceptEmpty;
58+
procedure TestSumOfReciprocals_Double_ExceptNonPositive;
59+
procedure TestSumOfReciprocals_Cardinal_ExceptEmpty;
60+
procedure TestSumOfReciprocals_Cardinal_ExceptNonPositive;
61+
procedure TestSumOfReciprocals_Integer_ExceptEmpty;
62+
procedure TestSumOfReciprocals_Integer_ExceptNonPositive;
5763
function EqualArrays(const Left, Right: TBytes): Boolean; overload;
5864
function EqualArrays(const Left, Right: array of Double;
5965
Fudge: Double = 0.0): Boolean; overload;
@@ -134,6 +140,12 @@ TestMathsCatSnippets = class(TTestCase)
134140
procedure TestWeightedGeoMean_Double; // required by Cardinal & Integer overloads
135141
procedure TestWeightedGeoMean_Cardinal;
136142
procedure TestWeightedGeoMean_Integer;
143+
procedure TestSumOfReciprocals_Double; // required by HarmonicMean
144+
procedure TestSumOfReciprocals_Cardinal; // required by HarmonicMean
145+
procedure TestSumOfReciprocals_Integer; // required by HarmonicMean
146+
procedure TestHarmonicMean_Double;
147+
procedure TestHarmonicMean_Cardinal;
148+
procedure TestHarmonicMean_Integer;
137149
end;
138150

139151
implementation
@@ -741,6 +753,81 @@ procedure TestMathsCatSnippets.TestGeoMean_Integer_ExceptNotPositive;
741753
GeoMean(A);
742754
end;
743755

756+
procedure TestMathsCatSnippets.TestHarmonicMean_Cardinal;
757+
const
758+
// Expected results calculated using https://www.dcode.fr/mean
759+
Fudge = 0.00000001;
760+
AA: array [1..4] of Cardinal = (1, 2, 34, 789);
761+
EA = 2.61321903463;
762+
AB: array [1..1] of Cardinal = (12);
763+
EB = 12.0000000000;
764+
AC: array [1..2] of Cardinal = (42, 56);
765+
EC = 48.0000000000;
766+
AD: array [1..6] of Cardinal = (1, 7, 3, 5, 1, 2);
767+
ED = 1.88905547226;
768+
AE: array [1..6] of Cardinal = (1000, 2000, 3000, 4000, 5000, 6000);
769+
EE = 2448.97959184;
770+
begin
771+
CheckTrue(SameValue(EA, HarmonicMean(AA), Fudge), 'A');
772+
CheckTrue(SameValue(EB, HarmonicMean(AB), Fudge), 'B');
773+
CheckTrue(SameValue(EC, HarmonicMean(AC), Fudge), 'C');
774+
CheckTrue(SameValue(ED, HarmonicMean(AD), Fudge), 'D');
775+
CheckTrue(SameValue(EE, HarmonicMean(AE), Fudge), 'E');
776+
// Exceptions not tested: all exceptions are raised by SumOfReciprocals which
777+
// is called by HarmonicMean. Those exceptions have been tested when testing
778+
// SumOfReciprocals
779+
end;
780+
781+
procedure TestMathsCatSnippets.TestHarmonicMean_Double;
782+
const
783+
// Expected results calculated using https://www.dcode.fr/mean
784+
Fudge = 0.00000001;
785+
AA: array [1..4] of Double = (0.1, 2.4573648, 34.0, 789.567);
786+
EA = 0.383229190511;
787+
AB: array [1..1] of Double = (12.78);
788+
EB = 12.7800000000;
789+
AC: array [1..2] of Double = (42.567987, 56.9837593);
790+
EC = 48.7321220420;
791+
AD: array [1..6] of Double = (1.0, 0.7, 0.3, 0.5, 0.1, 0.2);
792+
ED = 0.26359832636;
793+
AE: array [1..6] of Double = (0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006);
794+
EE = 0.00024489796;
795+
begin
796+
CheckTrue(SameValue(EA, HarmonicMean(AA), Fudge), 'A');
797+
CheckTrue(SameValue(EB, HarmonicMean(AB), Fudge), 'B');
798+
CheckTrue(SameValue(EC, HarmonicMean(AC), Fudge), 'C');
799+
CheckTrue(SameValue(ED, HarmonicMean(AD), Fudge), 'D');
800+
CheckTrue(SameValue(EE, HarmonicMean(AE), Fudge), 'E');
801+
// Exceptions not tested: all exceptions are raised by SumOfReciprocals which
802+
// is called by HarmonicMean. Those exceptions have been tested when testing
803+
// SumOfReciprocals
804+
end;
805+
806+
procedure TestMathsCatSnippets.TestHarmonicMean_Integer;
807+
const
808+
// Expected results calculated using https://www.dcode.fr/mean
809+
Fudge = 0.00000001;
810+
AA: array [1..4] of Integer = (1, 2, 34, 789);
811+
EA = 2.61321903463;
812+
AB: array [1..1] of Integer = (12);
813+
EB = 12.0000000000;
814+
AC: array [1..2] of Integer = (42, 56);
815+
EC = 48.0000000000;
816+
AD: array [1..6] of Integer = (1, 7, 3, 5, 1, 2);
817+
ED = 1.88905547226;
818+
AE: array [1..6] of Integer = (1000, 2000, 3000, 4000, 5000, 6000);
819+
EE = 2448.97959184;
820+
begin
821+
CheckTrue(SameValue(EA, HarmonicMean(AA), Fudge), 'A');
822+
CheckTrue(SameValue(EB, HarmonicMean(AB), Fudge), 'B');
823+
CheckTrue(SameValue(EC, HarmonicMean(AC), Fudge), 'C');
824+
CheckTrue(SameValue(ED, HarmonicMean(AD), Fudge), 'D');
825+
CheckTrue(SameValue(EE, HarmonicMean(AE), Fudge), 'E');
826+
// Exceptions not tested: all exceptions are raised by SumOfReciprocals which
827+
// is called by HarmonicMean. Those exceptions have been tested when testing
828+
// SumOfReciprocals
829+
end;
830+
744831
procedure TestMathsCatSnippets.TestIsNarcissistic;
745832
const
746833
NarcNumsBase10: array[1..25] of Integer = (
@@ -1956,6 +2043,117 @@ procedure TestMathsCatSnippets.TestSumOfLogs_UInt64_Except_NonPositive;
19562043
SumOfLogs(Bad);
19572044
end;
19582045

2046+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Cardinal;
2047+
const
2048+
// Expected values calculated on Windows Calc
2049+
Fudge = 0.00000001;
2050+
AA: array [1..4] of Cardinal = (1, 2, 34, 790);
2051+
EA = 1.530677587491;
2052+
AB: array [1..1] of Cardinal = (13);
2053+
EB = 0.076923076923;
2054+
AC: array [1..2] of Cardinal = (43, 57);
2055+
EC = 0.040799673603;
2056+
AD: array [1..6] of Cardinal = (1, 2, 3, 2, 1, 2);
2057+
ED = 3.833333333333;
2058+
begin
2059+
CheckTrue(SameValue(EA, SumOfReciprocals(AA), Fudge), 'A');
2060+
CheckTrue(SameValue(EB, SumOfReciprocals(AB), Fudge), 'B');
2061+
CheckTrue(SameValue(EC, SumOfReciprocals(AC), Fudge), 'C');
2062+
CheckTrue(SameValue(ED, SumOfReciprocals(AD), Fudge), 'D');
2063+
CheckException(TestSumOfReciprocals_Cardinal_ExceptEmpty, EArgumentException, 'Empty array');
2064+
CheckException(TestSumOfReciprocals_Cardinal_ExceptNonPositive, EArgumentException, 'Non-positive array values');
2065+
end;
2066+
2067+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Cardinal_ExceptEmpty;
2068+
var
2069+
A: array of Cardinal;
2070+
begin
2071+
SetLength(A, 0);
2072+
SumOfReciprocals(A);
2073+
end;
2074+
2075+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Cardinal_ExceptNonPositive;
2076+
const
2077+
A: array [1..3] of Cardinal = (42, 56, 0);
2078+
begin
2079+
SumOfReciprocals(A);
2080+
end;
2081+
2082+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Double;
2083+
const
2084+
// Expected values calculated on Windows Calc
2085+
Fudge = 0.00000001;
2086+
AA: array [1..4] of Double = (0.1, 2.4573648, 34.0, 789.567);
2087+
EA = 10.43761826877;
2088+
AB: array [1..1] of Double = (12.78);
2089+
EB = 0.078247261345;
2090+
AC: array [1..2] of Double = (42.567987, 56.9837593);
2091+
EC = 0.041040691769;
2092+
AD: array [1..6] of Double = (1.0, 0.7, 0.3, 0.5, 0.1, 0.2);
2093+
ED = 22.76190476190;
2094+
AE: array [1..6] of Double = (0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006);
2095+
EE = 24500.00000000;
2096+
begin
2097+
CheckTrue(SameValue(EA, SumOfReciprocals(AA), Fudge), 'A');
2098+
CheckTrue(SameValue(EB, SumOfReciprocals(AB), Fudge), 'B');
2099+
CheckTrue(SameValue(EC, SumOfReciprocals(AC), Fudge), 'C');
2100+
CheckTrue(SameValue(ED, SumOfReciprocals(AD), Fudge), 'D');
2101+
CheckTrue(SameValue(EE, SumOfReciprocals(AE), Fudge), 'E');
2102+
CheckException(TestSumOfReciprocals_Double_ExceptEmpty, EArgumentException, 'Empty array');
2103+
CheckException(TestSumOfReciprocals_Double_ExceptNonPositive, EArgumentException, 'Non-positive array values');
2104+
end;
2105+
2106+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Double_ExceptEmpty;
2107+
var
2108+
A: array of Double;
2109+
begin
2110+
SetLength(A, 0);
2111+
SumOfReciprocals(A);
2112+
end;
2113+
2114+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Double_ExceptNonPositive;
2115+
const
2116+
A: array [1..3] of Double = (42.2, 56.2, 0.0);
2117+
begin
2118+
SumOfReciprocals(A);
2119+
end;
2120+
2121+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Integer;
2122+
const
2123+
// Expected values calculated on Windows Calc
2124+
Fudge = 0.00000001;
2125+
AA: array [1..4] of Integer = (1, 2, 34, 790);
2126+
EA = 1.530677587491;
2127+
AB: array [1..1] of Integer = (13);
2128+
EB = 0.076923076923;
2129+
AC: array [1..2] of Integer = (43, 57);
2130+
EC = 0.040799673603;
2131+
AD: array [1..6] of Integer = (1, 2, 3, 2, 1, 2);
2132+
ED = 3.833333333333;
2133+
begin
2134+
CheckTrue(SameValue(EA, SumOfReciprocals(AA), Fudge), 'A');
2135+
CheckTrue(SameValue(EB, SumOfReciprocals(AB), Fudge), 'B');
2136+
CheckTrue(SameValue(EC, SumOfReciprocals(AC), Fudge), 'C');
2137+
CheckTrue(SameValue(ED, SumOfReciprocals(AD), Fudge), 'D');
2138+
CheckException(TestSumOfReciprocals_Integer_ExceptEmpty, EArgumentException, 'Empty array');
2139+
CheckException(TestSumOfReciprocals_Integer_ExceptNonPositive, EArgumentException, 'Non-positive array values');
2140+
end;
2141+
2142+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Integer_ExceptEmpty;
2143+
var
2144+
A: array of Integer;
2145+
begin
2146+
SetLength(A, 0);
2147+
SumOfReciprocals(A);
2148+
end;
2149+
2150+
procedure TestMathsCatSnippets.TestSumOfReciprocals_Integer_ExceptNonPositive;
2151+
const
2152+
A: array [1..3] of Integer = (42, -56, 12);
2153+
begin
2154+
SumOfReciprocals(A);
2155+
end;
2156+
19592157
procedure TestMathsCatSnippets.TestWeightedArithMean_Cardinal;
19602158
const
19612159
A: array[1..3] of Cardinal = (12, 6, 3);

tests/Cat-Maths/UMathsCatSnippets.pas

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* The unit is copyright © 2005-2024 by Peter Johnson & Contributors and is
77
* licensed under the MIT License (https://opensource.org/licenses/MIT).
88
*
9-
* Generated on : Mon, 13 Jan 2025 15:37:17 GMT.
9+
* Generated on : Mon, 13 Jan 2025 17:37:20 GMT.
1010
* Generated by : DelphiDabbler CodeSnip Release 4.24.0.
1111
*
1212
* The latest version of CodeSnip is available from the CodeSnip GitHub project
@@ -211,6 +211,27 @@ function GeoMean(const A: array of Double): Double; overload;
211211
}
212212
function GeoMean(const A: array of Integer): Double; overload;
213213

214+
{
215+
Returns the harmonic mean of an array of positive Cardinal values.
216+
EArgumentException is raised if the array is empty or if any array element is
217+
not positive.
218+
}
219+
function HarmonicMean(const A: array of Cardinal): Double; overload;
220+
221+
{
222+
Returns the harmonic mean of an array of positive Double values.
223+
EArgumentException is raised if the array is empty or if any array element is
224+
not positive.
225+
}
226+
function HarmonicMean(const A: array of Double): Double; overload;
227+
228+
{
229+
Returns the harmonic mean of an array of positive Integer values.
230+
EArgumentException is raised if the array is empty or if any array element is
231+
not positive.
232+
}
233+
function HarmonicMean(const A: array of Integer): Double; overload;
234+
214235
{
215236
Checks if the absolute value of integer N is a narcissistic number in base
216237
Base.
@@ -681,6 +702,29 @@ function SumOfLogs(const A: array of Single): Single; overload;
681702
}
682703
function SumOfLogs(const A: array of UInt64): Extended; overload;
683704

705+
{
706+
Calculates the sum of the reciprocal values of all elements of Cardinal array
707+
A.
708+
A must not be empty and all its elements must be positive. EArgumentException
709+
is raised if either of these conditions is not satisfied.
710+
}
711+
function SumOfReciprocals(const A: array of Cardinal): Double; overload;
712+
713+
{
714+
Calculates the sum of the reciprocal values of all elements of Double array A.
715+
A must not be empty and all its elements must be positive. EArgumentException
716+
is raised if either of these conditions is not satisfied.
717+
}
718+
function SumOfReciprocals(const A: array of Double): Double; overload;
719+
720+
{
721+
Calculates the sum of the reciprocal values of all elements of Integer array
722+
A.
723+
A must not be empty and all its elements must be positive. EArgumentException
724+
is raised if either of these conditions is not satisfied.
725+
}
726+
function SumOfReciprocals(const A: array of Integer): Double; overload;
727+
684728
{
685729
Calculates and returns the weighted average of the Cardinal elements of array
686730
Values where each element is weighted by the corresponding element in the
@@ -1300,6 +1344,36 @@ function GeoMean(const A: array of Integer): Double; overload;
13001344
Result := System.Exp(SumOfLogs(A) / System.Length(A));
13011345
end;
13021346

1347+
{
1348+
Returns the harmonic mean of an array of positive Cardinal values.
1349+
EArgumentException is raised if the array is empty or if any array element is
1350+
not positive.
1351+
}
1352+
function HarmonicMean(const A: array of Cardinal): Double; overload;
1353+
begin
1354+
Result := System.Length(A) / SumOfReciprocals(A);
1355+
end;
1356+
1357+
{
1358+
Returns the harmonic mean of an array of positive Double values.
1359+
EArgumentException is raised if the array is empty or if any array element is
1360+
not positive.
1361+
}
1362+
function HarmonicMean(const A: array of Double): Double; overload;
1363+
begin
1364+
Result := System.Length(A) / SumOfReciprocals(A);
1365+
end;
1366+
1367+
{
1368+
Returns the harmonic mean of an array of positive Integer values.
1369+
EArgumentException is raised if the array is empty or if any array element is
1370+
not positive.
1371+
}
1372+
function HarmonicMean(const A: array of Integer): Double; overload;
1373+
begin
1374+
Result := System.Length(A) / SumOfReciprocals(A);
1375+
end;
1376+
13031377
{
13041378
Checks if the absolute value of integer N is a narcissistic number in base
13051379
Base.
@@ -2629,6 +2703,68 @@ function SumOfLogs(const A: array of UInt64): Extended; overload;
26292703
end;
26302704
end;
26312705

2706+
{
2707+
Calculates the sum of the reciprocal values of all elements of Cardinal array
2708+
A.
2709+
A must not be empty and all its elements must be positive. EArgumentException
2710+
is raised if either of these conditions is not satisfied.
2711+
}
2712+
function SumOfReciprocals(const A: array of Cardinal): Double; overload;
2713+
var
2714+
Elem: Cardinal;
2715+
begin
2716+
if System.Length(A) = 0 then
2717+
raise SysUtils.EArgumentException.Create('Array is empty');
2718+
Result := 0.0;
2719+
for Elem in A do
2720+
begin
2721+
if Elem = 0 then
2722+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
2723+
Result := Result + 1 / Elem;
2724+
end;
2725+
end;
2726+
2727+
{
2728+
Calculates the sum of the reciprocal values of all elements of Double array A.
2729+
A must not be empty and all its elements must be positive. EArgumentException
2730+
is raised if either of these conditions is not satisfied.
2731+
}
2732+
function SumOfReciprocals(const A: array of Double): Double; overload;
2733+
var
2734+
Elem: Double;
2735+
begin
2736+
if System.Length(A) = 0 then
2737+
raise SysUtils.EArgumentException.Create('Array is empty');
2738+
Result := 0.0;
2739+
for Elem in A do
2740+
begin
2741+
if Math.Sign(Elem) <> Math.PositiveValue then
2742+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
2743+
Result := Result + 1 / Elem;
2744+
end;
2745+
end;
2746+
2747+
{
2748+
Calculates the sum of the reciprocal values of all elements of Integer array
2749+
A.
2750+
A must not be empty and all its elements must be positive. EArgumentException
2751+
is raised if either of these conditions is not satisfied.
2752+
}
2753+
function SumOfReciprocals(const A: array of Integer): Double; overload;
2754+
var
2755+
Elem: Integer;
2756+
begin
2757+
if System.Length(A) = 0 then
2758+
raise SysUtils.EArgumentException.Create('Array is empty');
2759+
Result := 0.0;
2760+
for Elem in A do
2761+
begin
2762+
if Elem <= 0 then
2763+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
2764+
Result := Result + 1 / Elem;
2765+
end;
2766+
end;
2767+
26322768
{
26332769
Calculates and returns the weighted average of the Cardinal elements of array
26342770
Values where each element is weighted by the corresponding element in the

0 commit comments

Comments
 (0)