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;
  }
@Test
  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);
      }
    }
  }