class SparseVectorSummarizer extends BaseVectorSummarizer {

    @Override
    public BaseVectorSummarizer visit(Vector vec) {
        SparseVector sv;

        if (vec instanceof DenseVector) {
            DenseVector dv = (DenseVector) vec;
            int[] indices = new int[dv.size()];
            for (int i = 0; i < dv.size(); i++) {
                indices[i] = i;
            }

            sv = new SparseVector(dv.size(), indices, dv.getData());
        } else {
            sv = (SparseVector) vec;
        }

        count++;

        this.colNum = Math.max(this.colNum, sv.size());

        if (sv.numberOfValues() != 0) {

            //max index + 1 for size.
            VectorIterator iter = sv.iterator();
            while (iter.hasNext()) {
                int index = iter.getIndex();
                double value = iter.getValue();

                if (cols.containsKey(index)) {
                    cols.get(index).visit(value);
                } else {
                    VectorStatCol statCol = new VectorStatCol();
                    statCol.visit(value);
                    cols.put(index, statCol);
                }
                iter.next();
            }

            if (calculateOuterProduct) {
                int size = sv.getIndices()[sv.getIndices().length - 1] + 1;

                if (outerProduct == null) {
                    outerProduct = DenseMatrix.zeros(size, size);
                } else {
                    if (size > outerProduct.numRows()) {
                        DenseMatrix dpNew = DenseMatrix.zeros(size, size);
                        if (outerProduct != null) {
                            outerProduct = VectorSummarizerUtil.plusEqual(dpNew, outerProduct);
                        }
                    }
                }
                for (int i = 0; i < sv.getIndices().length; i++) {
                    double val = sv.getValues()[i];
                    int iIdx = sv.getIndices()[i];
                    for (int j = 0; j < sv.getIndices().length; j++) {
                        outerProduct.add(iIdx, sv.getIndices()[j], val * sv.getValues()[j]);
                    }
                }
            }
        }
        return this;
    }

    public  SparseVectorSummarizer();
    public  SparseVectorSummarizer(boolean calculateOuterProduction);

}