/** * Returns the selection array or vector. * * <p>The selSizes array contains sizes of the selectors (number of elements that will be * returned by it). The idx array contains the indices returned by the selectors (that is the * indices used to compute the source offset). * * <p>The selIdx array contains the position in the selector (when this is equal to the selector * size the selector has overflown). */ public Object execute(RArray source, boolean drop, int exact) throws UnexpectedResultException { int[] sourceDim = source.dimensions(); boolean mayHaveNA = Selector.initialize(offsets, selectorVals, sourceDim, selSizes, ast); int[] destDim = Selector.calculateDestinationDimensions(selSizes, !subset || drop); int destSize = Selector.calculateSizeFromSelectorSizes(selSizes); RArray dest = Utils.createArray(source, destSize, destDim, null, null); // drop attributes if (destSize == 0) { return dest; } int offset = 0; for (; ; ) { int sourceOffset = offsets[0]; if (sourceOffset == RInt.NA) { Utils.setNA(dest, offset); } else { dest.set(offset, source.getRef(sourceOffset)); } offset++; if (offset < destSize) { if (!mayHaveNA) { Selector.advanceNoNA(offsets, sourceDim, selectorVals, ast); } else { Selector.advance(offsets, sourceDim, selectorVals, ast); } } else { break; } } return dest; }
public Object execute( RArray source, Selector selectorI, Selector selectorJ, boolean drop, int exact) throws UnexpectedResultException { assert Utils.check(subset); int[] ndim = source.dimensions(); int m = ndim[0]; int n = ndim[1]; selectorI.start(m, ast); selectorJ.start(n, ast); int nm = selectorI.size(); int nn = selectorJ.size(); boolean mayHaveNA = selectorI.mayHaveNA() || selectorJ.mayHaveNA(); int nsize = nm * nn; if ((nm != 1 && nn != 1) || !drop) { ndim = new int[] {nm, nn}; } else { ndim = null; } RArray res = Utils.createArray(source, nsize, ndim, null, null); // drop attributes if (!mayHaveNA) { int resoffset = 0; for (int nj = 0; nj < nn; nj++) { int j = selectorJ.nextIndex(ast); int srcoffset = j * m; for (int ni = 0; ni < nm; ni++) { int i = selectorI.nextIndex(ast); Object value = source.getRef( srcoffset + i); // FIXME: check overflow? (the same is at many locations, whenever // indexing a matrix) res.set(resoffset++, value); } selectorI.restart(); } } else { for (int nj = 0; nj < nn; nj++) { int j = selectorJ.nextIndex(ast); if (j != RInt.NA) { selectorI.restart(); for (int ni = 0; ni < nm; ni++) { int offset = nj * nm + ni; int i = selectorI.nextIndex(ast); if (i != RInt.NA) { Object value; value = source.getRef( j * m + i); // FIXME: check overflow? (the same is at many locations, whenever // indexing a matrix) res.set(offset, value); } else { Utils.setNA(res, offset); } } } else { for (int ni = 0; ni < nm; ni++) { Utils.setNA(res, nj * nm + ni); } } } } return res; }