Skip to content

Commit de93cd7

Browse files
committed
extract functionality
1 parent 1aabcd5 commit de93cd7

File tree

4 files changed

+112
-29
lines changed

4 files changed

+112
-29
lines changed

commons/util/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
exports net.automatalib.common.util.io;
4646
exports net.automatalib.common.util.lib;
4747
exports net.automatalib.common.util.mapping;
48+
exports net.automatalib.common.util.math;
4849
exports net.automatalib.common.util.nid;
4950
exports net.automatalib.common.util.process;
5051
exports net.automatalib.common.util.random;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* Copyright (C) 2013-2024 TU Dortmund University
2+
* This file is part of AutomataLib, http://www.automatalib.net/.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package net.automatalib.common.util.math;
17+
18+
/**
19+
* Utility class for mathematical computations.
20+
*/
21+
public final class MathUtil {
22+
23+
private MathUtil() {
24+
// prevent instantiation
25+
}
26+
27+
/**
28+
* Computes the binomial coefficient n over k using Pascal's triangle. If the binomial coefficient exceeds the
29+
* maximum number representable by a long, this methods returns {@link Long#MAX_VALUE} instead.
30+
*
31+
* @param n
32+
* the value for n
33+
* @param k
34+
* the value for k
35+
*
36+
* @return the binomial coefficient n over k
37+
*/
38+
public static long binomial(int n, int k) {
39+
40+
if (k < 0 || n < k) {
41+
throw new IllegalArgumentException("Illegal values for n and k");
42+
}
43+
44+
// abuse symmetry
45+
final int effectiveK = Math.min(k, n - k);
46+
47+
// pascal's triangle using a one dimensional storage
48+
final int dimN = n + 1;
49+
final int dimK = effectiveK + 1;
50+
final long[] tmp = new long[dimN * dimK];
51+
52+
try {
53+
for (int i = 0; i <= n; i++) {
54+
final int min = Math.min(i, effectiveK);
55+
for (int j = 0; j <= min; j++) {
56+
if (j == 0 || j == i) {
57+
// tmp[i][j] = 1
58+
tmp[i * dimK + j] = 1;
59+
} else {
60+
// tmp[i][j] = tmp[i-1][j-1] + tmp[i-1][k]
61+
tmp[i * dimK + j] = Math.addExact(tmp[(i - 1) * dimK + j - 1], tmp[(i - 1) * dimK + j]);
62+
}
63+
}
64+
}
65+
66+
// tmp[n][k]
67+
return tmp[n * dimK + effectiveK];
68+
} catch (ArithmeticException ae) {
69+
return Long.MAX_VALUE;
70+
}
71+
}
72+
73+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Copyright (C) 2013-2024 TU Dortmund University
2+
* This file is part of AutomataLib, http://www.automatalib.net/.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package net.automatalib.common.util.math;
17+
18+
import org.testng.Assert;
19+
import org.testng.annotations.Test;
20+
21+
public class MathUtilTest {
22+
23+
@Test
24+
public void testBinom() {
25+
Assert.assertThrows(IllegalArgumentException.class, () -> MathUtil.binomial(5, -1));
26+
Assert.assertEquals(MathUtil.binomial(5, 0), 1);
27+
Assert.assertEquals(MathUtil.binomial(5, 1), 5);
28+
Assert.assertEquals(MathUtil.binomial(5, 2), 10);
29+
Assert.assertEquals(MathUtil.binomial(5, 3), 10);
30+
Assert.assertEquals(MathUtil.binomial(5, 4), 5);
31+
Assert.assertEquals(MathUtil.binomial(5, 5), 1);
32+
Assert.assertThrows(IllegalArgumentException.class, () -> MathUtil.binomial(5, 6));
33+
34+
Assert.assertEquals(MathUtil.binomial(70, 35), Long.MAX_VALUE);
35+
}
36+
}

util/src/main/java/net/automatalib/util/automaton/ads/ADSUtil.java

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import net.automatalib.automaton.transducer.MealyMachine;
2424
import net.automatalib.common.util.Pair;
25+
import net.automatalib.common.util.math.MathUtil;
2526
import net.automatalib.graph.ads.ADSNode;
2627
import net.automatalib.graph.ads.impl.ADSSymbolNode;
2728
import net.automatalib.word.Word;
@@ -149,34 +150,6 @@ public static long computeMaximumSplittingWordLength(int n, int i, int m) {
149150
return n;
150151
}
151152

152-
return binomial(n, i) - binomial(m - 1, i - 1) - 1;
153+
return MathUtil.binomial(n, i) - MathUtil.binomial(m - 1, i - 1) - 1;
153154
}
154-
155-
private static long binomial(int n, int k) {
156-
157-
// abuse symmetry
158-
final int effectiveK = Math.min(k, n - k);
159-
160-
// pascal's triangle using a one dimensional storage
161-
final int dimN = n + 1;
162-
final int dimK = effectiveK + 1;
163-
final long[] tmp = new long[dimN * dimK];
164-
165-
for (int i = 0; i <= n; i++) {
166-
final int min = Math.min(i, effectiveK);
167-
for (int j = 0; j <= min; j++) {
168-
if (j == 0 || j == i) {
169-
// tmp[i][j] = 1
170-
tmp[i * dimK + j] = 1;
171-
} else {
172-
// tmp[i][j] = tmp[i-1][j-1] + tmp[i-1][k]
173-
tmp[i * dimK + j] = tmp[(i - 1) * dimK + j - 1] + tmp[(i - 1) * dimK + j];
174-
}
175-
}
176-
}
177-
178-
// tmp[n][k]
179-
return tmp[n * dimK + effectiveK];
180-
}
181-
182155
}

0 commit comments

Comments
 (0)