/* * * * Copyright (c) 2011-2015 EPFL DATA Laboratory * * Copyright (c) 2014-2015 The Squall Collaboration (see NOTICE) * * * * All rights reserved. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * */ package ch.epfl.data.squall.thetajoin.matrix_assignment; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; /** * This iterator helps to iterate over the 'cell' index of a hypercube. * For example, if we have a matrix 2 x 2, it will iterate over (0,0), (0,1), (1,0), (1,1). * * @author Tam */ public class CellIterator implements Iterator<List<Integer>>{ private final int[] _limits; private final int[] _pivots; private int[] _pos; private boolean _hasNext = true; /** * This helps you to iterate over all the cells of a hypercube. * @param limits the size of each dimension of a hypercube */ public CellIterator(int[] limits){ this(limits, -1, 0); } /** * This helps you to iterative over the cells of a hypercube while fixing a dimension. * For example, given a 3 x 3 matrix, fixing the first dimension with index = 1 gives you the iteration of (1,0), (1,1), (1,2). * @param limits the size of each dimension of a hypercube * @param fixedDim the dimension you want to fix * @param fixedIndex the index of the fixed dimension */ public CellIterator(int[] limits, int fixedDim, int fixedIndex){ this(limits, new int[]{fixedDim}, new int[]{fixedIndex}); } public CellIterator(int[] limits, int[] fixedDim, int[] fixedIndex){ _limits = limits; _pos = new int[limits.length]; Arrays.fill(_pos, 0); _pivots = fixedDim; for (int i = 0; i < fixedDim.length; i++) { if (_pivots[i] >= 0 && _pivots[i] < _pos.length) { _pos[_pivots[i]] = fixedIndex[i]; } } } @Override public boolean hasNext() { return _hasNext; } @Override public List<Integer> next() { List<Integer> res = new ArrayList<Integer>(); for (int p : _pos){ res.add(p); } for (int i = 0; i < _pos.length; i++){ boolean fixed = false; for (int j = 0; j < _pivots.length; j++) { if (i == _pivots[j]) { if (i == _pos.length - 1) _hasNext = false; fixed = true; break; } } if (fixed) continue; if (_pos[i] == _limits[i] - 1){ if (i == _pos.length - 1) _hasNext = false; _pos[i] = 0; } else { _pos[i]++; break; } } return res; } @Override public void remove() { throw new UnsupportedOperationException(); } public static void main(String... args){ testcase1(); testcase2(); testcase3(); testcase4(); testcase5(); } public static void testcase1(){ int[] rd = {2,5,2}; CellIterator me = new CellIterator(rd); int count = 0; while (me.hasNext()){ count++; List<Integer> combination = me.next(); System.out.println(combination.toString()); } assert count == Utilities.multiply(rd); } public static void testcase2(){ int[] rd = {2,5,2}; CellIterator me = new CellIterator(rd, 2, 3); int count = 0; while (me.hasNext()){ count++; List<Integer> combination = me.next(); System.out.println(combination.toString()); } assert count == 10; } public static void testcase3(){ int[] rd = {5,4,10,5}; CellIterator me = new CellIterator(rd); int count = 0; while (me.hasNext()){ count++; List<Integer> combination = me.next(); System.out.println(combination.toString()); } assert count == Utilities.multiply(rd); } public static void testcase4(){ int[] rd = {5,4,10,5}; CellIterator me = new CellIterator(rd, 2, 7); int count = 0; while (me.hasNext()){ count++; List<Integer> combination = me.next(); System.out.println(combination.toString()); } assert count == 100; } public static void testcase5(){ int[] rd = {2,5,2}; CellIterator me = new CellIterator(rd, new int[]{0, 2}, new int[]{1, 0}); int count = 0; while (me.hasNext()){ count++; List<Integer> combination = me.next(); System.out.println(combination.toString()); } assert count == 5; } }