Index section ( List < Range > ranges ) throws InvalidRangeException { // check ranges are valid if ( ranges . size ( ) != rank ) throw new InvalidRangeException ( "Bad ranges [] length" ) ; for ( int ii = 0 ; ii < rank ; ii ++ ) { Range r = ranges . get ( ii ) ; if ( r == null ) continue ; if ( r == Range . VLEN ) continue ; if ( ( r . first ( ) < 0 ) || ( r . first ( ) >= shape [ ii ] ) ) throw new InvalidRangeException ( "Bad range starting value at index " + ii + " == " + r . first ( ) ) ; if ( ( r . last ( ) < 0 ) || ( r . last ( ) >= shape [ ii ] ) ) throw new InvalidRangeException ( "Bad range ending value at index " + ii + " == " + r . last ( ) ) ; } int reducedRank = rank ; for ( Range r : ranges ) { if ( ( r != null ) && ( r . length ( ) == 1 ) ) reducedRank -- ; } Index newindex = Index . factory ( reducedRank ) ; newindex . offset = offset ; // calc shape, size, and index transformations // calc strides into original (backing) store int newDim = 0 ; for ( int ii = 0 ; ii < rank ; ii ++ ) { Range r = ranges . get ( ii ) ; if ( r == null ) { // null range means use the whole original dimension newindex . shape [ newDim ] = shape [ ii ] ; newindex . stride [ newDim ] = stride [ ii ] ; //if (name != null) newindex.name[newDim] = name[ii]; newDim ++ ; } else if ( r . length ( ) != 1 ) { newindex . shape [ newDim ] = r . length ( ) ; newindex . stride [ newDim ] = stride [ ii ] * r . stride ( ) ; newindex . offset += stride [ ii ] * r . first ( ) ; //if (name != null) newindex.name[newDim] = name[ii]; newDim ++ ; } else { newindex . offset += stride [ ii ] * r . first ( ) ; // constant due to rank reduction } } newindex . size = computeSize ( newindex . shape ) ; newindex . fastIterator = fastIterator && ( newindex . size == size ) ; // if equal, then its not a real subset, so can still use fastIterator newindex . precalc ( ) ; // any subclass-specific optimizations return newindex ; }
create a new Index based on a subsection of this one with rank reduction if dimension length == 1 .