This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git
The following commit(s) were added to refs/heads/master by this push:
new c0a84684 Optimise harmonic sum
c0a84684 is described below
commit c0a84684234f8b8019a437e18483ca315f6b994d
Author: Alex Herbert <[email protected]>
AuthorDate: Mon Aug 31 08:58:25 2026 +0100
Optimise harmonic sum
---
.../statistics/distribution/ZipfDistribution.java | 45 ++++++++++++++++++----
1 file changed, 37 insertions(+), 8 deletions(-)
diff --git
a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZipfDistribution.java
b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZipfDistribution.java
index 49d0ae0f..315e76c8 100644
---
a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZipfDistribution.java
+++
b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ZipfDistribution.java
@@ -72,7 +72,7 @@ public final class ZipfDistribution extends
AbstractDiscreteDistribution {
double exponent) {
this.numberOfElements = numberOfElements;
this.exponent = exponent;
- this.nthHarmonic = generalizedHarmonic(1, numberOfElements, exponent);
+ this.nthHarmonic = generalizedHarmonic(numberOfElements, exponent);
logNthHarmonic = Math.log(nthHarmonic);
}
@@ -151,7 +151,7 @@ public final class ZipfDistribution extends
AbstractDiscreteDistribution {
return 1;
}
- return generalizedHarmonic(1, x, exponent) / nthHarmonic;
+ return generalizedHarmonic(x, exponent) / nthHarmonic;
}
/** {@inheritDoc} */
@@ -239,6 +239,31 @@ public final class ZipfDistribution extends
AbstractDiscreteDistribution {
return h;
}
+ /**
+ * Calculates the {@code n}-th generalized harmonic number.
+ *
+ * <pre>
+ * 1
+ * sum ----- for k in [1, n]
+ * k^m
+ * </pre>
+ *
+ * <p>Assumes {@code exponent > 0} to arrange the terms to sum from small
to large.
+ *
+ * @param n Last term in the series to calculate.
+ * @param m Exponent (special case {@code m = 1} is the harmonic series).
+ * @return the sum
+ */
+ private static double generalizedHarmonic(final int n, final double m) {
+ double value = 0;
+ // Sum small to large
+ for (int k = n; k >= 2; k--) {
+ value += Math.pow(k, -m);
+ }
+ // 1^-m = 1
+ return value + 1.0;
+ }
+
/**
* Calculates the sum of terms of the
* <a href="https://mathworld.wolfram.com/HarmonicSeries.html">Harmonic
@@ -269,7 +294,7 @@ public final class ZipfDistribution extends
AbstractDiscreteDistribution {
}
/**
- * Calculates the Nth generalized harmonic number.
+ * Calculates the {@code n}-th generalized harmonic number.
*
* <p>Checks the value of the {@code exponent} to arrange the terms to sum
from from small to large.
*
@@ -278,17 +303,21 @@ public final class ZipfDistribution extends
AbstractDiscreteDistribution {
* @return the n<sup>th</sup> generalized harmonic number.
*/
private static double generalizedHarmonicAscendingSum(final int n, final
double m) {
- double value = 0;
- // Sum small to large
- // If m < 0 then sum ascending, otherwise descending
+ double value;
+ // Sum small to large.
+ // If m < 0 then sum ascending, otherwise descending.
+ // Note: 1^-m = 1
if (m < 0) {
- for (int k = 1; k <= n; k++) {
+ value = 1.0;
+ for (int k = 2; k <= n; k++) {
value += Math.pow(k, -m);
}
} else {
- for (int k = n; k >= 1; k--) {
+ value = 0;
+ for (int k = n; k >= 2; k--) {
value += Math.pow(k, -m);
}
+ value += 1.0;
}
return value;
}