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; 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 index = imax; 075 return false; 076 } 077 078 index += istep; 079 return index < imax; 080 } 081 082 /** 083 * @return position indices (nb not a copy) 084 */ 085 @Override 086 public int[] getPos() { 087 return pos; 088 } 089 090 @Override 091 public void reset() { 092 if (shape.length > 0) { 093 Arrays.fill(pos, 0); 094 pos[endrank] = -1; 095 } 096 index = -istep; 097 } 098 099 @Override 100 public int[] getShape() { 101 return shape; 102 } 103}