Summation implements Container<Summation>, Combinable<Summation> { public Summation[] partition(final int nParts) { final Summation[] parts = new Summation[nParts]; final long steps = (E.limit - E.value)/E.delta + 1; long prevN = N.value; long prevE = E.value; for(int i = 1; i < parts.length; i++) { final long k = (i * steps)/parts.length; final long currN = N.skip(k); final long currE = E.skip(k); parts[i - 1] = new Summation( new ArithmeticProgression(N.symbol, prevN, N.delta, currN), new ArithmeticProgression(E.symbol, prevE, E.delta, currE)); prevN = currN; prevE = currE; } parts[parts.length - 1] = new Summation( new ArithmeticProgression(N.symbol, prevN, N.delta, N.limit), new ArithmeticProgression(E.symbol, prevE, E.delta, E.limit)); return parts; } Summation(ArithmeticProgression N, ArithmeticProgression E);   Summation(long valueN, long deltaN, 
            long valueE, long deltaE, long limitE);   Summation(long valueN, long deltaN, long limitN, 
            long valueE, long deltaE, long limitE); @Override Summation getElement(); Double getValue(); void setValue(double v); @Override String toString(); @Override boolean equals(Object obj); @Override int hashCode(); static Summation valueOf(final String s); double compute(); @Override int compareTo(Summation that); @Override Summation combine(Summation that); List<Summation> remainingTerms(List<T> sorted); boolean contains(Summation that); Summation[] partition(final int nParts); final ArithmeticProgression N; final ArithmeticProgression E; }
@Test 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())); runTestSubtract(sigma, diff); } } }