blob: 576aa58b15750560e06a6fa9d5be5425de7d2168 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.raid;
import java.util.Random;
import java.util.Set;
import java.util.HashSet;
import junit.framework.TestCase;
public class TestGaloisField extends TestCase {
final int TEST_TIMES = 10000;
final Random RAND = new Random();
final static GaloisField GF = GaloisField.getInstance();
private int randGF() {
return 0x000000FF & RAND.nextInt(GF.getFieldSize());
}
private int[] randGFPoly(int len) {
int[] result = new int[len];
for (int i = 0; i < len; i++) {
result[i] = randGF();
}
return result;
}
public void testGetInstance() {
GaloisField gf1 = GaloisField.getInstance(256, 285);
GaloisField gf2 = GaloisField.getInstance();
GaloisField gf3 = GaloisField.getInstance(128, 137);
GaloisField gf4 = GaloisField.getInstance(128, 137);
GaloisField gf5 = GaloisField.getInstance(512, 529);
GaloisField gf6 = GaloisField.getInstance(512, 529);
assertTrue(gf1 == gf2);
assertTrue(gf3 == gf4);
assertTrue(gf5 == gf6);
}
public void testDistributivity() {
for (int i = 0; i < TEST_TIMES; i++) {
int a = RAND.nextInt(GF.getFieldSize());
int b = RAND.nextInt(GF.getFieldSize());
int c = RAND.nextInt(GF.getFieldSize());
int result1 = GF.multiply(a, GF.add(b, c));
int result2 = GF.add(GF.multiply(a, b), GF.multiply(a, c));
assertTrue("Distributivity test #" + i + " failed: " + a + ", " + b + ", "
+ c, result1 == result2);
}
}
public void testDevision() {
for (int i = 0; i < TEST_TIMES; i++) {
int a = RAND.nextInt(GF.getFieldSize());
int b = RAND.nextInt(GF.getFieldSize());
if (b == 0) {
continue;
}
int c = GF.divide(a, b);
assertTrue("Division test #" + i + " failed: " + a + "/" + b + " = " + c,
a == GF.multiply(c, b));
}
}
public void testPower() {
for (int i = 0; i < TEST_TIMES; i++) {
int a = randGF();
int n = RAND.nextInt(10);
int result1 = GF.power(a, n);
int result2 = 1;
for (int j = 0; j < n; j++) {
result2 = GF.multiply(result2, a);
}
assert(result1 == result2);
}
}
public void testPolynomialDistributivity() {
final int TEST_LEN = 15;
for (int i = 0; i < TEST_TIMES; i++) {
int[] a = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int[] b = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int[] c = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int[] result1 = GF.multiply(a, GF.add(b, c));
int[] result2 = GF.add(GF.multiply(a, b), GF.multiply(a, c));
assertTrue("Distributivity test on polynomials failed",
java.util.Arrays.equals(result1, result2));
}
}
public void testSubstitute() {
final int TEST_LEN = 15;
for (int i = 0; i < TEST_TIMES; i++) {
int[] a = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int[] b = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int[] c = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
int x = randGF();
// (a * b * c)(x)
int result1 = GF.substitute(GF.multiply(GF.multiply(a, b), c), x);
// a(x) * b(x) * c(x)
int result2 =
GF.multiply(GF.multiply(GF.substitute(a, x), GF.substitute(b, x)),
GF.substitute(c, x));
assertTrue("Substitute test on polynomial failed",
result1 == result2);
}
}
public void testSolveVandermondeSystem() {
final int TEST_LEN = 15;
for (int i = 0; i < TEST_TIMES; i++) {
int[] z = randGFPoly(RAND.nextInt(TEST_LEN - 1) + 1);
// generate distinct values for x
int[] x = new int[z.length];
Set<Integer> s = new HashSet<Integer>();
while (s.size() != z.length) {
s.add(randGF());
}
int t = 0;
for (int v : s) {
x[t++] = v;
}
// compute the output for the Vandermonde system
int[] y = new int[x.length];
for (int j = 0; j < x.length; j++) {
y[j] = 0;
for (int k = 0; k < x.length; k++) {
//y[j] = y[j] + z[k] * pow(x[k], j);
y[j] = GF.add(y[j], GF.multiply(GF.power(x[k], j), z[k]));
}
}
GF.solveVandermondeSystem(x, y);
assertTrue("Solving Vandermonde system failed",
java.util.Arrays.equals(y, z));
}
}
public void testRemainder() {
final int TEST_LEN = 15;
for (int i = 0; i < TEST_TIMES; i++) {
int[] quotient = null;
int[] divisor = null;
int[] remainder = null;
int[] dividend = null;
while (true) {
quotient = randGFPoly(RAND.nextInt(TEST_LEN - 3) + 3);
divisor = randGFPoly(RAND.nextInt(quotient.length - 2) + 2);
remainder = randGFPoly(RAND.nextInt(divisor.length - 1) + 1);
dividend = GF.add(remainder, GF.multiply(quotient, divisor));
if (quotient[quotient.length - 1] != 0 &&
divisor[divisor.length - 1] != 0 &&
remainder[remainder.length - 1] != 0) {
// make sure all the leading terms are not zero
break;
}
}
GF.remainder(dividend, divisor);
for (int j = 0; j < remainder.length; j++) {
assertTrue("Distributivity test on polynomials failed",
dividend[j] == remainder[j]);
}
}
}
}