package umontreal.iro.lecuyer.hups;
import umontreal.iro.lecuyer.util.PrintfFormat;
/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
/*Attention: No array index range tests neither for the dimension
nor for the number of points is performed. This is left to JAVA. */
/**
* This container class permits one to select a subset of a point set.
* This is done by selecting a range or providing an array of either
* point or coordinate indices. A typical application of a range selection
* is to make the number of points or the dimension finite. It is also
* possible to provide, for example, a random permutation in the selection of
* components. It is possible also to take projections of coordinates
* for selected dimensions.
*
*
* Selecting a new subset of points or coordinates overwrites the previous
* selection. The specification of a subset with respect to the points
* is independent from selecting a subset with respect to the coordinates.
* The number of points and the dimension are adapted
* to the current selection and all indices still start from 0,
* i.e., the subset works just like an ordinary point set.
*
*
* When the points or coordinates ranges are changed, existing iterators
* become invalid. They should be reconstructed or reset to avoid
* inconsistencies.
*
*/
public class SubsetOfPointSet extends PointSet {
protected PointSet P; // Source points
protected int i_from, i_to, i_index[]; // Limits or lookup for row
protected int j_from, j_to, j_index[]; // Limits or lookup for column
/**
* Constructs a new {@link PointSet} object, initially identical to P,
* and from which a subset of the points and/or a subset of the coordinates
* is to be extracted.
*
* @param P point set for which a subset is constructed
*
*/
public SubsetOfPointSet (PointSet P) {
this.P = P;
numPoints = P.getNumPoints();
dim = P.getDimension();
i_from = 0;
i_to = P.getNumPoints();
j_from = 0;
j_to = P.getDimension();
}
/**
* Selects the points numbered from ``from'' to ``to - 1'' from the
* original point set.
*
* @param from index of the point, in the contained point set,
* corresponding to the point 0 of this point set
*
* @param to index of the last point taken from the contained point set
*
*
*/
public void selectPointsRange (int from, int to) {
if (0 > from || from >= to || to > P.getNumPoints())
throw new IllegalArgumentException ("Invalid range for points");
i_index = null;
i_from = from;
i_to = to;
numPoints = to - from;
}
/**
* Selects the numPoints points whose numbers are provided in the array
* pointIndices.
*
* @param pointIndices array of point indices to be selected
*
* @param numPoints number of points in the subset of point set
*
*
*/
public void selectPoints (int[] pointIndices, int numPoints) {
if (numPoints > P.getNumPoints() || numPoints > pointIndices.length)
throw new IllegalArgumentException ("Number of indices too large");
i_index = pointIndices;
this.numPoints = numPoints;
}
/**
* Selects the coordinates from ``from'' to ``to - 1'' from the
* original point set.
*
* @param from index of the coordinate, in the contained point set,
* corresponding to the coordinate 0 of each point of this point set
*
* @param to index of the last coordinate taken for each point
* from the contained point set
*
*
*/
public void selectCoordinatesRange (int from, int to) {
if (0 > from || from >= to || to > P.getDimension())
throw new IllegalArgumentException("Invalid column range");
j_index = null;
j_from = from;
j_to = to;
dim = to - from;
}
/**
* Selects the numCoord coordinates whose numbers are provided in
* the array coordIndices.
*
* @param coordIndices array of coordinate indices to be selected
*
* @param numCoord number of coordinatess for each point in the subset of point set
*
*
*/
public void selectCoordinates (int[] coordIndices, int numCoord) {
if (numCoord > P.getDimension() || numCoord > coordIndices.length)
throw new IllegalArgumentException ("Number of indices too large");
j_index = coordIndices;
this.dim = numCoord;
}
public double getCoordinate (int i, int j) {
int access_i, access_j;
// if no range check done: left to JAVA array index check
if (i_index == null) {
if (i < 0 || i >= numPoints)
throw new IllegalArgumentException ("Row out of range");
access_i = i + i_from;
} else
access_i = i_index[i];
if (j_index == null) {
if (j < 0 || j > dim)
throw new IllegalArgumentException("Column out of range");
access_j = j + j_from;
} else
access_j = j_index[j];
return P.getCoordinate (access_i, access_j);
}
public PointSetIterator iterator() {
return new SubsetIterator();
}
public String toString() {
StringBuffer sb = new StringBuffer ("Subset of point set" +
PrintfFormat.NEWLINE);
sb.append ("Inner point set information {" + PrintfFormat.NEWLINE);
sb.append (P.toString());
sb.append (PrintfFormat.NEWLINE + "}" + PrintfFormat.NEWLINE);
if (i_index == null)
sb.append ("Points range from " + i_from + " to " + i_to + "." +
PrintfFormat.NEWLINE);
else {
sb.append ("Point indices: [");
boolean first = true;
for (int i = 0; i < numPoints; i++) {
if (first)
first = false;
else
sb.append (", ");
sb.append (i_index[i]);
}
sb.append ("]" + PrintfFormat.NEWLINE);
}
if (j_index == null)
sb.append ("Coordinates range from " + j_from + " to " + j_to + ".");
else {
sb.append ("Coordinate indices: [");
boolean first = true;
for (int i = 0; i < dim; i++) {
if (first)
first = false;
else
sb.append (", ");
sb.append (j_index[i]);
}
sb.append ("]");
}
return sb.toString();
}
// ***********************************************************
private class SubsetIterator extends DefaultPointSetIterator {
private PointSetIterator innerIterator;
/*
private int i_from;
private int i_to;
private int j_from;
private int j_to;
private int[] i_index;
private int[] j_index;
*/
SubsetIterator() {
// Since one can change range after construction, we
// must save the current one.
//this.i_from = SubsetOfPointSet.this.i_from;
//this.i_to = SubsetOfPointSet.this.i_to;
//this.j_from = SubsetOfPointSet.this.j_from;
//this.j_to = SubsetOfPointSet.this.j_to;
// Also recopy indices in case one has set the indices,
// kept the array and modified it after construction.
//if (SubsetOfPointSet.this.i_index == null)
// this.i_index = null;
//else {
// this.i_index = new int[SubsetOfPointSet.this.i_index.length];
// System.arraycopy (SubsetOfPointSet.this.i_index, 0,
// this.i_index, 0, numPoints);
//}
//if (SubsetOfPointSet.this.j_index == null)
// this.j_index = null;
//else {
// this.j_index = new int[SubsetOfPointSet.this.j_index.length];
// System.arraycopy (SubsetOfPointSet.this.j_index, 0, this.j_index, 0, dim);
//}
// Create the inner iterator and set its state according to the subset.
innerIterator = P.iterator();
if (i_index == null) {
if (i_from != 0)
innerIterator.setCurPointIndex (i_from);
}
else {
if (i_index[0] != 0)
innerIterator.setCurPointIndex (i_index[0]);
}
if (j_index == null) {
if (j_from != 0)
innerIterator.setCurCoordIndex (j_from);
}
else {
if (j_index[0] != 0)
innerIterator.setCurCoordIndex (j_index[0]);
}
}
public void setCurCoordIndex (int j) {
if (j_index == null)
innerIterator.setCurCoordIndex (j + j_from);
else
innerIterator.setCurCoordIndex (j_index[j]);
curCoordIndex = j;
}
public void resetCurCoordIndex() {
if (j_index == null) {
if (j_from == 0)
innerIterator.resetCurCoordIndex();
else
innerIterator.setCurCoordIndex (j_from);
}
else {
if (j_index[0] == 0)
innerIterator.resetCurCoordIndex();
else
innerIterator.setCurCoordIndex (j_index[0]);
}
curCoordIndex = 0;
}
public double nextCoordinate() {
if ((curPointIndex >= numPoints) || (curCoordIndex >= dim))
outOfBounds();
// The inner iterator could throw an exception.
// If that happens, e must not alter the current coordinate.
double coord = 0.0;
if (j_index == null)
coord = innerIterator.nextCoordinate();
else {
int currentIndex = j_index[curCoordIndex];
int futureIndex = (curCoordIndex+1) == dim ?
currentIndex+1 : j_index[curCoordIndex+1];
coord = innerIterator.nextCoordinate();
if (futureIndex != (currentIndex+1))
innerIterator.setCurCoordIndex (futureIndex);
}
curCoordIndex++;
return coord;
}
public void nextCoordinates (double[] p, int d) {
if (curPointIndex >= numPoints || curCoordIndex + d > dim)
outOfBounds();
if (j_index != null) {
super.nextCoordinates (p, d);
return;
}
innerIterator.nextCoordinates (p, d);
curCoordIndex += d;
}
public void setCurPointIndex (int i) {
if (i_index == null)
innerIterator.setCurPointIndex (i + i_from);
else
innerIterator.setCurPointIndex (i_index[i]);
curPointIndex = i;
resetCurCoordIndex();
}
public void resetCurPointIndex() {
if (i_index == null) {
if (i_from == 0)
innerIterator.resetCurPointIndex();
else
innerIterator.setCurPointIndex (i_from);
}
else {
if (i_index[0] == 0)
innerIterator.resetCurPointIndex();
else
innerIterator.setCurPointIndex (i_index[0]);
}
curPointIndex = 0;
resetCurCoordIndex();
}
public int resetToNextPoint() {
if (i_index == null)
innerIterator.resetToNextPoint();
else if (curPointIndex < (numPoints-1))
innerIterator.setCurPointIndex (i_index[curPointIndex + 1]);
curPointIndex++;
resetCurCoordIndex();
return curPointIndex;
}
}
}
Ads help maintain this website.