/** * 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.examples.pi.math; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import org.apache.hadoop.examples.pi.Container; import org.apache.hadoop.examples.pi.Util; import org.apache.hadoop.examples.pi.Util.Timer; import org.apache.hadoop.examples.pi.math.TestModular.Montgomery2; public class TestSummation extends junit.framework.TestCase { static final Random RANDOM = new Random(); static final BigInteger TWO = BigInteger.valueOf(2); private static Summation2 newSummation(final long base, final long range, final long delta) { final ArithmeticProgression N = new ArithmeticProgression('n', base+3, delta, base+3+range); final ArithmeticProgression E = new ArithmeticProgression('e', base+range, -delta, base); return new Summation2(N, E); } private static void runTestSubtract(Summation sigma, List<Summation> diff) { // Util.out.println("diff=" + diff); List<Container<Summation>> tmp = new ArrayList<Container<Summation>>(diff.size()); for(Summation s : diff) tmp.add(s); final List<Summation> a = sigma.remainingTerms(tmp); // Util.out.println("a =" + a); a.addAll(diff); for(Summation s : a) s.compute(); final List<Summation> combined = Util.combine(a); // Util.out.println("combined=" + combined); assertEquals(1, combined.size()); assertEquals(sigma, combined.get(0)); } public void testSubtract() { final Summation sigma = newSummation(3, 10000, 20); final int size = 10; final List<Summation> parts = Arrays.asList(sigma.partition(size)); Collections.sort(parts); runTestSubtract(sigma, new ArrayList<Summation>()); runTestSubtract(sigma, parts); for(int n = 1; n < size; n++) { for(int j = 0; j < 10; j++) { final List<Summation> diff = new ArrayList<Summation>(parts); for(int i = 0; i < n; i++) diff.remove(RANDOM.nextInt(diff.size())); /// Collections.sort(diff); runTestSubtract(sigma, diff); } } } static class Summation2 extends Summation { Summation2(ArithmeticProgression N, ArithmeticProgression E) { super(N, E); } final Montgomery2 m2 = new Montgomery2(); double compute_montgomery2() { long e = E.value; long n = N.value; double s = 0; for(; e > E.limit; e += E.delta) { m2.set(n); s = Modular.addMod(s, m2.mod2(e)/(double)n); n += N.delta; } return s; } double compute_modBigInteger() { long e = E.value; long n = N.value; double s = 0; for(; e > E.limit; e += E.delta) { s = Modular.addMod(s, TestModular.modBigInteger(e, n)/(double)n); n += N.delta; } return s; } double compute_modPow() { long e = E.value; long n = N.value; double s = 0; for(; e > E.limit; e += E.delta) { s = Modular.addMod(s, TWO.modPow(BigInteger.valueOf(e), BigInteger.valueOf(n)).doubleValue()/n); n += N.delta; } return s; } } private static void computeBenchmarks(final Summation2 sigma) { final Timer t = new Timer(false); t.tick("sigma=" + sigma); final double value = sigma.compute(); t.tick("compute=" + value); assertEquals(value, sigma.compute_modular()); t.tick("compute_modular"); assertEquals(value, sigma.compute_montgomery()); t.tick("compute_montgomery"); assertEquals(value, sigma.compute_montgomery2()); t.tick("compute_montgomery2"); assertEquals(value, sigma.compute_modBigInteger()); t.tick("compute_modBigInteger"); assertEquals(value, sigma.compute_modPow()); t.tick("compute_modPow"); } /** Benchmarks */ public static void main(String[] args) { final long delta = 1L << 4; final long range = 1L << 20; for(int i = 20; i < 40; i += 2) computeBenchmarks(newSummation(1L << i, range, delta)); } }