1

Let's say I have an ojAlgo-array defined like this

ArrayAnyD<Double> regularArray = ArrayAnyD.PRIMITIVE64.make(10);
regularArray.loopAll((final long[] ref) -> regularArray.set(ref, ref[0]*ref[0]));

which just contains the squares of the numbers from 0 to 9, and some indexes:

long[] idxs = {1, 3, 4, 7, 9}

Now, I'd like to do something akin to

slicedArray = regularArray[idxs]

which should give me another Array containing 1.0, 9.0, 16.0, 49.0, 81.0. How would I do that with ojAlgo?

  • regularArray.get(idxs) only gives me the first value.
  • regularArray.sliceSet(idxs, 0) returns all values from the first one onwards and ignores the following indexes.

I suspect I'd need to use some form of regularArray.loop or .loopAll, but I'm not sure how to make it work

PebNischl
  • 163
  • 5
  • There's no way to do that directly. You have to, manually, create a copy. You can't slice using arbitrary indices. Slicing needs to be structured somehow (uniform stride between the indices). – apete Apr 27 '22 at 14:15
  • 1
    You created a 1-dimensional ArrayAnyD? How many dimension do you need? If you use matrices instead of arrays, you can create them as row or column vectors. These then have methods like rows(int[]) and columns(int[]) that works the way you want. – apete Apr 27 '22 at 14:35
  • @apete This was just meant as a sized down example, maybe I shouldn't have minimized it that much. In reality I'd need up to three dimensions (nx3x3), where n can be as much as a million or more. I might be able to rewrite my routines to flatten the three dimensions into two so that a matrix would be possible in theory (although I'd _really_ prefer to avoid that), but I'm sceptical about the size. In the introduction of ojAlgo, it says that Arrays are advantageous for larger sizes. – PebNischl Apr 28 '22 at 07:36
  • Don't understand your use case. Maybe start a discussion over at GitHub: https://github.com/optimatika/ojAlgo/discussions – apete Apr 28 '22 at 07:51
  • 1
    If that huge array is actually a "collection" of 3x3 matrices, then it is better to define the array as 3x3xn rather than nx3x3. That way the matrices are contiguous, and can be a iterated over using array.matrices(); – apete Apr 28 '22 at 07:57

1 Answers1

1

Here's some of what you can do:

ArrayAnyD<Double> array = ArrayAnyD.PRIMITIVE64.make(3, 3, n);

MatrixView<Double> matrices = array.matrices();

// A MatrixView is Iterable,
// but you can also go directly to the matrix you want

matrices.goToMatrix(78);

// Specific rows and columns
Access2D<Double> select = matrices.select(new int[] { 1, 2 }, new int[] { 0 });

Access2D<Double> rows = matrices.rows(1, 2); // All columns

Access2D<Double> columns = matrices.columns(0); // All rows

double value10 = matrices.doubleValue(1, 0);
double value20 = matrices.doubleValue(2, 0);

matrices.goToMatrix(99); // ...

To do all of that (exactly that way) you need v51.3.0-SNAPSHOT or later.

apete
  • 1,250
  • 1
  • 10
  • 16