Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8b55806

Browse files
Merge branch 'feature/35-harmonic-mean-functions' into develop
Fixes #35
2 parents 5c7623f + bd79ce2 commit 8b55806

File tree

9 files changed

+464
-1
lines changed

9 files changed

+464
-1
lines changed

‎collection/681.dat

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function SumOfReciprocals(const A: array of Double): Double; overload;
2+
var
3+
Elem: Double;
4+
begin
5+
if System.Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create('Array is empty');
7+
Result := 0.0;
8+
for Elem in A do
9+
begin
10+
if Math.Sign(Elem) <> Math.PositiveValue then
11+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
12+
Result := Result + 1 / Elem;
13+
end;
14+
end;

‎collection/682.dat

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function SumOfReciprocals(const A: array of Integer): Double; overload;
2+
var
3+
Elem: Integer;
4+
begin
5+
if System.Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create('Array is empty');
7+
Result := 0.0;
8+
for Elem in A do
9+
begin
10+
if Elem <= 0 then
11+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
12+
Result := Result + 1 / Elem;
13+
end;
14+
end;

‎collection/683.dat

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function SumOfReciprocals(const A: array of Cardinal): Double; overload;
2+
var
3+
Elem: Cardinal;
4+
begin
5+
if System.Length(A) = 0 then
6+
raise SysUtils.EArgumentException.Create('Array is empty');
7+
Result := 0.0;
8+
for Elem in A do
9+
begin
10+
if Elem = 0 then
11+
raise SysUtils.EArgumentException.Create('Array values must be > 0');
12+
Result := Result + 1 / Elem;
13+
end;
14+
end;

‎collection/684.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function HarmonicMean(const A: array of Double): Double; overload;
2+
begin
3+
Result := System.Length(A) / SumOfReciprocals(A);
4+
end;

‎collection/685.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function HarmonicMean(const A: array of Cardinal): Double; overload;
2+
begin
3+
Result := System.Length(A) / SumOfReciprocals(A);
4+
end;

‎collection/686.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function HarmonicMean(const A: array of Integer): Double; overload;
2+
begin
3+
Result := System.Length(A) / SumOfReciprocals(A);
4+
end;

‎collection/maths.ini

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,3 +2091,78 @@ AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tes
20912091
Snip=680.dat
20922092
DelphiXE=Y
20932093
Delphi12A=Y
2094+
2095+
[SumOfReciprocals_Double]
2096+
DisplayName="SumOfReciprocals (Double overload)"
2097+
DescEx="<p>Calculates the sum of the reciprocal values of all elements of <var>Double</var> array <var>A</var>.</p><p><var>A</var> must not be empty and all its elements must be positive. <var>EArgumentException</var> is raised if either of these conditions is not satisfied.</p>"
2098+
Units=SysUtils,Math
2099+
SeeAlso=SumOfReciprocals_Integer,SumOfReciprocals_Cardinal
2100+
TestInfo=advanced
2101+
AdvancedTest.Level=unit-tests
2102+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2103+
Snip=681.dat
2104+
DelphiXE=Y
2105+
Delphi12A=Y
2106+
2107+
[SumOfReciprocals_Integer]
2108+
DisplayName="SumOfReciprocals (Integer overload)"
2109+
DescEx="<p>Calculates the sum of the reciprocal values of all elements of <var>Integer</var> array <var>A</var>.</p><p><var>A</var> must not be empty and all its elements must be positive. <var>EArgumentException</var> is raised if either of these conditions is not satisfied.</p>"
2110+
Units=SysUtils
2111+
SeeAlso=SumOfReciprocals_Integer,SumOfReciprocals_Double
2112+
TestInfo=advanced
2113+
AdvancedTest.Level=unit-tests
2114+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2115+
Snip=682.dat
2116+
DelphiXE=Y
2117+
Delphi12A=Y
2118+
2119+
[SumOfReciprocals_Cardinal]
2120+
DisplayName="SumOfReciprocals (Cardinal overload)"
2121+
DescEx="<p>Calculates the sum of the reciprocal values of all elements of <var>Cardinal</var> array <var>A</var>.</p><p><var>A</var> must not be empty and all its elements must be positive. <var>EArgumentException</var> is raised if either of these conditions is not satisfied.</p>"
2122+
Units=SysUtils
2123+
SeeAlso=SumOfReciprocals_Double,SumOfReciprocals_Cardinal
2124+
TestInfo=advanced
2125+
AdvancedTest.Level=unit-tests
2126+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2127+
Snip=683.dat
2128+
DelphiXE=Y
2129+
Delphi12A=Y
2130+
2131+
[HarmonicMean_Double]
2132+
DisplayName="HarmonicMean (Double overload)"
2133+
DescEx="<p>Returns the harmonic mean of an array of positive <var>Double</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty or if any array element is not positive.</p>"
2134+
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Harmonic_mean">Wikipedia</a> for information about the harmonic mean.</p>"
2135+
Depends=SumOfReciprocals_Double
2136+
SeeAlso=HarmonicMean_Integer,HarmonicMean_Cardinal,ArithMean_Double,GeoMean_Double
2137+
TestInfo=advanced
2138+
AdvancedTest.Level=unit-tests
2139+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2140+
Snip=684.dat
2141+
DelphiXE=Y
2142+
Delphi12A=Y
2143+
2144+
[HarmonicMean_Cardinal]
2145+
DisplayName="HarmonicMean (Cardinal overload)"
2146+
DescEx="<p>Returns the harmonic mean of an array of positive <var>Cardinal</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty or if any array element is not positive.</p>"
2147+
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Harmonic_mean">Wikipedia</a> for information about the harmonic mean.</p>"
2148+
Depends=SumOfReciprocals_Cardinal
2149+
SeeAlso=HarmonicMean_Double,HarmonicMean_Integer,ArithMean_Cardinal,GeoMean_Cardinal
2150+
TestInfo=advanced
2151+
AdvancedTest.Level=unit-tests
2152+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2153+
Snip=685.dat
2154+
DelphiXE=Y
2155+
Delphi12A=Y
2156+
2157+
[HarmonicMean_Integer]
2158+
DisplayName="HarmonicMean (Integer overload)"
2159+
DescEx="<p>Returns the harmonic mean of an array of positive <var>Integer</var> values.</p><p><var>EArgumentException</var> is raised if the array is empty or if any array element is not positive.</p>"
2160+
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Harmonic_mean">Wikipedia</a> for information about the harmonic mean.</p>"
2161+
Depends=SumOfReciprocals_Integer
2162+
SeeAlso=HarmonicMean_Cardinal,HarmonicMean_Double,ArithMean_Integer,GeoMean_Integer
2163+
TestInfo=advanced
2164+
AdvancedTest.Level=unit-tests
2165+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2166+
Snip=686.dat
2167+
DelphiXE=Y
2168+
Delphi12A=Y

‎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);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /