Skip to content

Commit a96ad84

Browse files
authored
Add different types of Mean (TheAlgorithms#4339)
1 parent cfdbc41 commit a96ad84

File tree

3 files changed

+132
-2
lines changed

3 files changed

+132
-2
lines changed

pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>com.thealgorithms</groupId>
77
<artifactId>Java</artifactId>
@@ -52,6 +52,11 @@
5252
<artifactId>commons-lang3</artifactId>
5353
<version>3.12.0</version>
5454
</dependency>
55+
<dependency>
56+
<groupId>org.apache.commons</groupId>
57+
<artifactId>commons-collections4</artifactId>
58+
<version>4.4</version>
59+
</dependency>
5560
</dependencies>
5661

5762
<build>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.thealgorithms.maths;
2+
3+
import java.util.stream.StreamSupport;
4+
import org.apache.commons.collections4.IterableUtils;
5+
6+
/**
7+
* https://en.wikipedia.org/wiki/Mean
8+
* <p>
9+
* by: Punit Patel
10+
*/
11+
public final class Means {
12+
13+
private Means() {
14+
}
15+
16+
/**
17+
* @brief computes the [Arithmetic Mean](https://en.wikipedia.org/wiki/Arithmetic_mean) of the input
18+
* @param numbers the input numbers
19+
* @throws IllegalArgumentException empty input
20+
* @return the arithmetic mean of the input numbers
21+
*/
22+
public static Double arithmetic(final Iterable<Double> numbers) {
23+
checkIfNotEmpty(numbers);
24+
return StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x + y).get() / IterableUtils.size(numbers);
25+
}
26+
27+
/**
28+
* @brief computes the [Geometric Mean](https://en.wikipedia.org/wiki/Geometric_mean) of the input
29+
* @param numbers the input numbers
30+
* @throws IllegalArgumentException empty input
31+
* @return the geometric mean of the input numbers
32+
*/
33+
public static Double geometric(final Iterable<Double> numbers) {
34+
checkIfNotEmpty(numbers);
35+
return Math.pow(StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x * y).get(), 1d / IterableUtils.size(numbers));
36+
}
37+
38+
/**
39+
* @brief computes the [Harmonic Mean](https://en.wikipedia.org/wiki/Harmonic_mean) of the input
40+
* @param numbers the input numbers
41+
* @throws IllegalArgumentException empty input
42+
* @return the harmonic mean of the input numbers
43+
*/
44+
public static Double harmonic(final Iterable<Double> numbers) {
45+
checkIfNotEmpty(numbers);
46+
return IterableUtils.size(numbers) / StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + 1d / y);
47+
}
48+
49+
private static void checkIfNotEmpty(final Iterable<Double> numbers) {
50+
if (!numbers.iterator().hasNext()) {
51+
throw new IllegalArgumentException("Emtpy list given for Mean computation.");
52+
}
53+
}
54+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import java.util.ArrayList;
6+
import java.util.LinkedHashSet;
7+
import java.util.LinkedList;
8+
import java.util.List;
9+
import java.util.Set;
10+
import java.util.Vector;
11+
import org.assertj.core.util.Lists;
12+
import org.assertj.core.util.Sets;
13+
import org.junit.jupiter.api.Test;
14+
15+
class MeansTest {
16+
17+
@Test
18+
void arithmeticMeanZeroNumbers() throws IllegalArgumentException {
19+
List<Double> numbers = new ArrayList<>();
20+
assertThrows(IllegalArgumentException.class, () -> Means.arithmetic(numbers));
21+
}
22+
23+
@Test
24+
void geometricMeanZeroNumbers() throws IllegalArgumentException {
25+
List<Double> numbers = new ArrayList<>();
26+
assertThrows(IllegalArgumentException.class, () -> Means.geometric(numbers));
27+
}
28+
29+
@Test
30+
void harmonicMeanZeroNumbers() throws IllegalArgumentException {
31+
List<Double> numbers = new ArrayList<>();
32+
assertThrows(IllegalArgumentException.class, () -> Means.harmonic(numbers));
33+
}
34+
35+
@Test
36+
void arithmeticMeanSingleNumber() {
37+
List<Double> numbers = Lists.newArrayList(2.5);
38+
assertEquals(2.5, Means.arithmetic(numbers));
39+
}
40+
41+
@Test
42+
void geometricMeanSingleNumber() {
43+
Set<Double> numbers = Sets.newHashSet(Lists.newArrayList(2.5));
44+
assertEquals(2.5, Means.geometric(numbers));
45+
}
46+
47+
@Test
48+
void harmonicMeanSingleNumber() {
49+
LinkedHashSet<Double> numbers = Sets.newLinkedHashSet(2.5);
50+
assertEquals(2.5, Means.harmonic(numbers));
51+
}
52+
53+
@Test
54+
void arithmeticMeanMultipleNumbers() {
55+
Set<Double> numbers = Sets.newTreeSet(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5);
56+
assertEquals(44, Means.arithmetic(numbers));
57+
}
58+
59+
@Test
60+
void geometricMeanMultipleNumbers() {
61+
LinkedList<Double> numbers = new LinkedList<>() {};
62+
numbers.addAll(Lists.newArrayList(1d, 2d, 3d, 4d, 5d, 6d, 1.25));
63+
assertEquals(2.6426195539300585, Means.geometric(numbers));
64+
}
65+
66+
@Test
67+
void harmonicMeanMultipleNumbers() {
68+
Vector<Double> numbers = new Vector<>(Lists.newArrayList(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5));
69+
assertEquals(4.6697322801074135, Means.harmonic(numbers));
70+
}
71+
}

0 commit comments

Comments
 (0)