001/*- 002 ******************************************************************************* 003 * Copyright (c) 2011, 2016 Diamond Light Source Ltd. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Peter Chang - initial API and implementation and/or initial documentation 011 *******************************************************************************/ 012 013package org.eclipse.january.dataset; 014 015import java.util.Arrays; 016 017 018/** 019 * Class to run over contiguous datasets and keep track of position. Note this is slower than ContiguousIterator 020 */ 021public class ContiguousIteratorWithPosition extends IndexIterator { 022 final private int[] shape; 023 final private int endrank; // last dimensions index 024 final private int imax; // maximum index in array 025 final private int istep; // step over items 026 final private int[] pos; // position in dataset 027 028 /** 029 * Constructor for an iterator over the items of a dataset that are 030 * within the dimensions 031 * 032 * @param shape 033 * @param length of entire data array 034 */ 035 public ContiguousIteratorWithPosition(final int[] shape, final int length) { 036 this(shape, length, 1); 037 } 038 039 /** 040 * Constructor for an iterator over the items of a dataset that are 041 * within the dimensions 042 * 043 * @param shape 044 * @param length of entire data array 045 * @param isize number of elements in an item 046 */ 047 public ContiguousIteratorWithPosition(final int[] shape, final int length, final int isize) { 048 this.shape = shape; 049 endrank = this.shape.length - 1; 050 istep = isize; 051 if (shape.length == 0) { 052 pos = new int[0]; 053 } else { 054 pos = new int[endrank + 1]; 055 pos[endrank] = -1; 056 } 057 index = -isize; 058 imax = length * isize; 059 } 060 061 @Override 062 public boolean hasNext() { 063 // now move on one position 064 int j = endrank; 065 for (; j >= 0; j--) { 066 pos[j]++; 067 if (pos[j] >= shape[j]) { 068 pos[j] = 0; 069 } else { 070 break; 071 } 072 } 073 if (j == -1 && endrank >= 0) { 074 return false; 075 } 076 077 index += istep; 078 return index < imax; 079 } 080 081 /** 082 * @return position indices (nb not a copy) 083 */ 084 @Override 085 public int[] getPos() { 086 return pos; 087 } 088 089 @Override 090 public void reset() { 091 if (shape.length > 0) { 092 Arrays.fill(pos, 0); 093 pos[endrank] = -1; 094 } 095 index = -istep; 096 } 097 098 @Override 099 public int[] getShape() { 100 return shape; 101 } 102}