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 a109a8c

Browse files
Merge branch 'feature/47-weighted-harmonic-mean' into develop
Fixes #47
2 parents 8b55806 + ab5cc42 commit a109a8c

File tree

6 files changed

+337
-11
lines changed

6 files changed

+337
-11
lines changed

‎collection/687.dat

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function WeightedHarmonicMean(const Values: array of Double;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
Sum: Double;
5+
Idx: Integer;
6+
NormalisedWeights: Types.TDoubleDynArray;
7+
begin
8+
if System.Length(Values) = 0 then
9+
raise SysUtils.EArgumentException.Create('Array of values is empty');
10+
if System.Length(Values) <> System.Length(Weights) then
11+
raise SysUtils.EArgumentException.Create(
12+
'Number of values and number of weights must be the same'
13+
);
14+
NormalisedWeights := NormaliseByWeight(Weights);
15+
Sum := 0.0;
16+
for Idx := 0 to Pred(System.Length(Values)) do
17+
Sum := Sum + NormalisedWeights[Idx] / Values[Idx];
18+
Result := 1.0 / Sum;
19+
end;

‎collection/688.dat

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function WeightedHarmonicMean(const Values: array of Cardinal;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
Idx: Integer;
5+
FloatValues: Types.TDoubleDynArray;
6+
begin
7+
System.Setlength(FloatValues, System.Length(Values));
8+
for Idx := 0 to Pred(System.Length(Values)) do
9+
FloatValues[Idx] := Values[Idx];
10+
Result := WeightedHarmonicMean(FloatValues, Weights);
11+
end;

‎collection/689.dat

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function WeightedHarmonicMean(const Values: array of Integer;
2+
const Weights: array of Double): Double; overload;
3+
var
4+
Idx: Integer;
5+
FloatValues: Types.TDoubleDynArray;
6+
begin
7+
System.Setlength(FloatValues, System.Length(Values));
8+
for Idx := 0 to Pred(System.Length(Values)) do
9+
FloatValues[Idx] := Values[Idx];
10+
Result := WeightedHarmonicMean(FloatValues, Weights);
11+
end;

‎collection/maths.ini

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,7 +2052,7 @@ Delphi12A=Y
20522052

20532053
[WeightedGeoMean_Double]
20542054
DisplayName="WeightedGeoMean (Double overload)"
2055-
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Value</var> of positive <var>Double</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2055+
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Values</var> of positive <var>Double</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
20562056
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Weighted_geometric_mean">Wikipedia</a> for information about the weighted geometric mean.</p>"
20572057
Units=SysUtils,Types
20582058
Depends=NormaliseByWeight_Double
@@ -2066,7 +2066,7 @@ Delphi12A=Y
20662066

20672067
[WeightedGeoMean_Cardinal]
20682068
DisplayName="WeightedGeoMean (Cardinal overload)"
2069-
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Value</var> of positive <var>Cardinal</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2069+
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Values</var> of positive <var>Cardinal</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
20702070
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Weighted_geometric_mean">Wikipedia</a> for information about the weighted geometric mean.</p>"
20712071
Units=Types
20722072
Depends=WeightedGeoMean_Double
@@ -2080,7 +2080,7 @@ Delphi12A=Y
20802080

20812081
[WeightedGeoMean_Integer]
20822082
DisplayName="WeightedGeoMean (Integer overload)"
2083-
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Value</var> of positive <var>Integer</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2083+
DescEx="<p>Calculates and returns the weighted geometric mean of the array <var>Values</var> of positive <var>Integer</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
20842084
Extra="<p>See <a href="https://en.m.wikipedia.org/wiki/Weighted_geometric_mean">Wikipedia</a> for information about the weighted geometric mean.</p>"
20852085
Units=Types
20862086
Depends=WeightedGeoMean_Double
@@ -2166,3 +2166,48 @@ AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tes
21662166
Snip=686.dat
21672167
DelphiXE=Y
21682168
Delphi12A=Y
2169+
2170+
[WeightedHarmonicMean_Double]
2171+
DisplayName="WeightedHarmonicMean (Double overload)"
2172+
DescEx="<p>Calculates and returns the weighted harmonic mean of the array <var>Values</var> of positive <var>Double</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2173+
Extra="<p>See <a href="https://en.wikipedia.org/wiki/Harmonic_mean#Weighted_harmonic_mean">Wikipedia</a> for information about the weighted harmonic mean.</p>"
2174+
Kind=routine
2175+
Units=SysUtils,Types
2176+
Depends=NormaliseByWeight_Double
2177+
SeeAlso=HarmonicMean_Double,WeightedHarmonicMean_Cardinal,WeightedHarmonicMean_Integer,WeightedArithMean_Double,WeightedGeoMean_Double
2178+
TestInfo=advanced
2179+
AdvancedTest.Level=unit-tests
2180+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2181+
Snip=687.dat
2182+
DelphiXE=Y
2183+
Delphi12A=Y
2184+
2185+
[WeightedHarmonicMean_Cardinal]
2186+
DisplayName="WeightedHarmonicMean (Cardinal overload)"
2187+
DescEx="<p>Calculates and returns the weighted harmonic mean of the array <var>Values</var> of positive <var>Cardinal</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2188+
Extra="<p>See <a href="https://en.wikipedia.org/wiki/Harmonic_mean#Weighted_harmonic_mean">Wikipedia</a> for information about the weighted harmonic mean.</p>"
2189+
Kind=routine
2190+
Units=Types
2191+
Depends=WeightedHarmonicMean_Double
2192+
SeeAlso=HarmonicMean_Cardinal,WeightedHarmonicMean_Double,WeightedHarmonicMean_Integer,WeightedArithMean_Cardinal,WeightedGeoMean_Cardinal
2193+
TestInfo=advanced
2194+
AdvancedTest.Level=unit-tests
2195+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2196+
Snip=688.dat
2197+
DelphiXE=Y
2198+
Delphi12A=Y
2199+
2200+
[WeightedHarmonicMean_Integer]
2201+
DisplayName="WeightedHarmonicMean (Integer overload)"
2202+
DescEx="<p>Calculates and returns the weighted harmonic mean of the array <var>Values</var> of positive <var>Integer</var> values where each element is weighted by the corresponding element in the array <var>Weights</var>.</p><p>An <var>EArgumentException</var> exception is raised if any of the following pre-conditions are not met: <var>Values</var> must be non-empty; all elements of <var>Values</var> must be positive; <var>Values</var> &amp; <var>Weights</var> must have the same number of elements; all elements of <var>Weights</var> must be non-negative, with at least one element being non-zero.</p>"
2203+
Extra="<p>See <a href="https://en.wikipedia.org/wiki/Harmonic_mean#Weighted_harmonic_mean">Wikipedia</a> for information about the weighted harmonic mean.</p>"
2204+
Kind=routine
2205+
Units=Types
2206+
Depends=WeightedHarmonicMean_Double
2207+
SeeAlso=HarmonicMean_Integer,WeightedHarmonicMean_Double,WeightedHarmonicMean_Cardinal,WeightedArithMean_Integer,WeightedGeoMean_Integer
2208+
TestInfo=advanced
2209+
AdvancedTest.Level=unit-tests
2210+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-Maths"
2211+
Snip=689.dat
2212+
DelphiXE=Y
2213+
Delphi12A=Y

‎tests/Cat-Maths/TestUMathsCatSnippets.pas

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

151158
implementation
@@ -2343,6 +2350,126 @@ procedure TestMathsCatSnippets.TestWeightedGeoMean_Integer;
23432350
// suffice.
23442351
end;
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+
23462473
initialization
23472474
// Register any test cases with the test runner
23482475
RegisterTest(TestMathsCatSnippets.Suite);

0 commit comments

Comments
(0)

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