2

I have a SparseArray and need to obtain the sum of all its elements

I'm currently doing a dot product of the array with a same-sized array filled with ones, but I feel there should be something more straightforward (and efficient?)

Can't find a proper method here: https://javadoc.scijava.org/ojAlgo/org/ojalgo/array/SparseArray.html

I have:

SparseArray<Double> lhCounts = SparseArray.factory(Primitive64Array.FACTORY, dim).make();

then do some operations with it, and finally want some method that returns the sum of all elements, something like:

array_sum = lhCounts.sum();
glicerico
  • 690
  • 4
  • 20

1 Answers1

2

That class in primarily used as a delegate to other implementation, but it's perfectly fine to use it directly. Probably the most direct solution in this case is to do:

    array_sum = lhCounts.nonzeros().stream().mapToDouble(nz -> nz.doubleValue()).sum();

There is also the possibility to create an Array1D instead. It has a richer api. Then you can do it this way:

    Array1D<Double> lhCounts1D = Array1D.PRIMITIVE64.makeSparse(dim);
    array_sum = lhCounts1D.aggregateAll(Aggregator.SUM);

The nonzeros-stream is also available in this case

    array_sum = lhCounts1D.nonzeros().stream().mapToDouble(nz -> nz.doubleValue()).sum();

and if that "array" is actually something 2-D or N-D you can create an Array2D or ArrayAnyD instead.

    Array2D<Double> lhCounts2D = Array2D.PRIMITIVE64.makeSparse(dim, dim);
    ArrayAnyD<Double> lhCountsAnyD = ArrayAnyD.PRIMITIVE64.makeSparse(dim, dim, dim, dim);

The Array1D, Array2D and ArrayAnyD api:s were designed for dense structures. The ability to instantiate them as sparse was added at a later point. Some things you can do with them may not be very efficient in the sparse case. You can even do plain stupid things like hugeSparseArray.fillAll(1.0);

apete
  • 1,250
  • 1
  • 10
  • 16
  • The proposed SparseArray solution gives me the error: ```Error:(85, 55) java: method stream in interface org.ojalgo.structure.ElementView1D cannot be applied to given types; required: boolean found: no arguments reason: actual and formal argument lists differ in length ``` – glicerico Sep 14 '19 at 09:06
  • The Array1D solution works fine :) I do use SparseStore 2D arrays elsewhere in the code, so do you say it's more convenient to use Array2D's sparse abilities? Is performance comparable? – glicerico Sep 14 '19 at 09:12
  • 1
    If you found a problem then open an issue at GitHub with a supplied example that demonstrates the problem. Generally I'd say the Array1D and Array2D alternatives are more convenient and comparable in performance. – apete Sep 14 '19 at 12:23