-
Notifications
You must be signed in to change notification settings - Fork 21k
Expand file tree
/
Copy pathMeans.java
More file actions
143 lines (135 loc) · 5.12 KB
/
Means.java
File metadata and controls
143 lines (135 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package com.thealgorithms.maths;
import java.util.stream.StreamSupport;
import org.apache.commons.collections4.IterableUtils;
/**
* Utility class for computing various types of statistical means.
* <p>
* This class provides static methods to calculate different types of means
* (averages)
* from a collection of numbers. All methods accept any {@link Iterable}
* collection of
* {@link Double} values and return the computed mean as a {@link Double}.
* </p>
*
* <p>
* Supported means:
* <ul>
* <li><b>Arithmetic Mean</b>: The sum of all values divided by the count</li>
* <li><b>Geometric Mean</b>: The nth root of the product of n values</li>
* <li><b>Harmonic Mean</b>: The reciprocal of the arithmetic mean of
* reciprocals</li>
* </ul>
* </p>
*
* @see <a href="https://en.wikipedia.org/wiki/Mean">Mean (Wikipedia)</a>
* @author Punit Patel
*/
public final class Means {
private Means() {
}
/**
* Computes the arithmetic mean (average) of the given numbers.
* <p>
* The arithmetic mean is calculated as: (x₁ + x₂ + ... + xₙ) / n
* </p>
* <p>
* Example: For numbers [2, 4, 6], the arithmetic mean is (2+4+6)/3 = 4.0
* </p>
*
* @param numbers the input numbers (must not be empty)
* @return the arithmetic mean of the input numbers
* @throws IllegalArgumentException if the input is empty
* @see <a href="https://en.wikipedia.org/wiki/Arithmetic_mean">Arithmetic
* Mean</a>
*/
public static Double arithmetic(final Iterable<Double> numbers) {
checkIfNotEmpty(numbers);
double sum = StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + y);
int size = IterableUtils.size(numbers);
return sum / size;
}
/**
* Computes the geometric mean of the given numbers.
* <p>
* The geometric mean is calculated as: ⁿ√(x₁ × x₂ × ... × xₙ)
* </p>
* <p>
* Example: For numbers [2, 8], the geometric mean is √(2×8) = √16 = 4.0
* </p>
* <p>
* Note: This method may produce unexpected results for negative numbers,
* as it computes the real-valued nth root which may not exist for negative
* products.
* </p>
*
* @param numbers the input numbers (must not be empty)
* @return the geometric mean of the input numbers
* @throws IllegalArgumentException if the input is empty
* @see <a href="https://en.wikipedia.org/wiki/Geometric_mean">Geometric
* Mean</a>
*/
public static Double geometric(final Iterable<Double> numbers) {
checkIfNotEmpty(numbers);
double product = StreamSupport.stream(numbers.spliterator(), false).reduce(1d, (x, y) -> x * y);
int size = IterableUtils.size(numbers);
return Math.pow(product, 1.0 / size);
}
/**
* Computes the harmonic mean of the given numbers.
* <p>
* The harmonic mean is calculated as: n / (1/x₁ + 1/x₂ + ... + 1/xₙ)
* </p>
* <p>
* Example: For numbers [1, 2, 4], the harmonic mean is 3/(1/1 + 1/2 + 1/4) =
* 3/1.75 ≈ 1.714
* </p>
* <p>
* Note: This method will produce unexpected results if any input number is
* zero,
* as it involves computing reciprocals.
* </p>
*
* @param numbers the input numbers (must not be empty)
* @return the harmonic mean of the input numbers
* @throws IllegalArgumentException if the input is empty
* @see <a href="https://en.wikipedia.org/wiki/Harmonic_mean">Harmonic Mean</a>
*/
public static Double harmonic(final Iterable<Double> numbers) {
checkIfNotEmpty(numbers);
double sumOfReciprocals = StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + 1d / y);
int size = IterableUtils.size(numbers);
return size / sumOfReciprocals;
}
/**
* Computes the quadratic mean (root mean square) of the given numbers.
* <p>
* The quadratic mean is calculated as: √[(x₁^2 × x₂^2 × ... × xₙ^2)/n]
* </p>
* <p>
* Example: For numbers [1, 7], the quadratic mean is √[(1^2+7^2)/2] = √25 = 5.0
* </p>
*
* @param numbers the input numbers (must not be empty)
* @return the quadratic mean of the input numbers
* @throws IllegalArgumentException if the input is empty
* @see <a href="https://en.wikipedia.org/wiki/Root_mean_square">Quadratic
* Mean</a>
*/
public static Double quadratic(final Iterable<Double> numbers) {
checkIfNotEmpty(numbers);
double sumOfSquares = StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + y * y);
int size = IterableUtils.size(numbers);
return Math.pow(sumOfSquares / size, 0.5);
}
/**
* Validates that the input iterable is not empty.
*
* @param numbers the input numbers to validate
* @throws IllegalArgumentException if the input is empty
*/
private static void checkIfNotEmpty(final Iterable<Double> numbers) {
if (!numbers.iterator().hasNext()) {
throw new IllegalArgumentException("Empty list given for Mean computation.");
}
}
}