public <T extends RealType<T>> double computeAverage(final Iterable<T> input) {
    final RealSum realSum = new RealSum();
    long count = 0;

    for (final T type : input) {
      count++;
      realSum.add(type.getRealDouble());
    }

    return realSum.getSum() / count;
  }
  private static final void incompatibleLoop(
      final Cursor<FloatType> psiCursor,
      final ArrayList<RandomAccess<FloatType>> randomAccessWeights,
      final ArrayList<RandomAccess<FloatType>> randomAccessImgs,
      final RealSum realSum,
      final int m) {
    final FloatType p = psiCursor.next();
    double sum = 0;
    double sumW = 0;

    for (int j = 0; j < m; ++j) {
      final RandomAccess<FloatType> randomAccessWeight = randomAccessWeights.get(j);
      final RandomAccess<FloatType> randomAccessImg = randomAccessImgs.get(j);

      randomAccessWeight.setPosition(psiCursor);
      randomAccessImg.setPosition(psiCursor);

      final double w = randomAccessWeight.get().get();
      final double i = randomAccessImg.get().get();

      sum += i * w;
      sumW += w;
    }

    if (sumW > 0) {
      final double i = sum / sumW;
      realSum.add(i);
      p.set((float) i);
    }
  }
  private static final void compatibleLoop(
      final Cursor<FloatType> psiCursor,
      final ArrayList<Cursor<FloatType>> cursorWeights,
      final ArrayList<Cursor<FloatType>> cursorImgs,
      final RealSum realSum,
      final int m) {
    double sum = 0;
    double sumW = 0;

    for (int j = 0; j < m; ++j) {
      final double w = cursorWeights.get(j).next().get();
      final double i = cursorImgs.get(j).next().get();

      sum += i * w;
      sumW += w;
    }

    if (sumW > 0) {
      final double i = sum / sumW;
      realSum.add(i);
      psiCursor.next().set((float) i);
    } else {
      psiCursor.fwd();
    }
  }