NumericalStorage.java
package org.thegalactic.context.constraint.numerical;
/*
* NumericalStorage.java
*
* Copyright: 2016 The Galactic Organization, France
*
* License: http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html CeCILL-B license
*
* This file is part of java-lattices.
* You can redistribute it and/or modify it under the terms of the CeCILL-B license.
*/
import java.util.ArrayList;
import java.util.List;
/**
* Binary Storage.
*/
public final class NumericalStorage {
/**
* inf values.
*/
private final List<Double> inf;
/**
* sup values.
*/
private final List<Double> sup;
/**
* EXCEPTION_SIZE.
*/
private static final String EXCEPTION_SIZE = "NumericalStorage objects must have the same size";
/**
* Factory method to construct a numerical storage.
*
* @param size number of values
*
* @return a new NumericalStorage object
*/
public static NumericalStorage create(final int size) {
return new NumericalStorage(size);
}
/**
* This class is not designed to be publicly instantiated.
*
* @param size number of values
*/
private NumericalStorage(final int size) {
this.inf = new ArrayList<Double>(size);
this.sup = new ArrayList<Double>(size);
// Initialise as an empty set
for (int index = 0; index < size; index++) {
this.inf.add(index, Double.POSITIVE_INFINITY);
this.sup.add(index, Double.NEGATIVE_INFINITY);
}
}
/**
* Set the set at specified index empty.
*
* @param index index of the numerical set
*
* @return this for chaining
*/
public NumericalStorage setEmpty(final int index) {
this.inf.set(index, Double.POSITIVE_INFINITY);
this.sup.set(index, Double.NEGATIVE_INFINITY);
return this;
}
/**
* Is the set at specified index empty?
*
* @param index index of the numerical set
*
* @return this for chaining
*/
public boolean isEmpty(final int index) {
return this.inf.get(index) > this.sup.get(index);
}
/**
* Set the set at specified index a point.
*
* @param index index of the numerical set
* @param value the new value
*
* @return this for chaining
*/
public NumericalStorage setPoint(final int index, final double value) {
this.inf.set(index, value);
this.sup.set(index, value);
return this;
}
/**
* Is the set at specified index a point?
*
* @param index index of the numerical set
*
* @return this for chaining
*/
public boolean isPoint(final int index) {
return this.inf.get(index).equals(this.sup.get(index));
}
/**
* Set the inf mark to specified value.
*
* @param index the specified index
* @param value the new value
*
* @return this for chaining
*/
public NumericalStorage setInf(final int index, final double value) {
if (this.isEmpty(index)) {
this.setPoint(index, value);
} else if (value > this.sup.get(index)) {
this.setEmpty(index);
} else {
this.inf.set(index, value);
}
return this;
}
/**
* Set the sup mark to specified value.
*
* @param index the specified index
* @param value the new value
*
* @return this for chaining
*/
public NumericalStorage setSup(final int index, final double value) {
if (this.isEmpty(index)) {
this.setPoint(index, value);
} else if (value < this.inf.get(index)) {
this.setEmpty(index);
} else {
this.sup.set(index, value);
}
return this;
}
/**
* Get the inf value at specified index.
*
* @param index the specified index
*
* @return the inf value
*/
public double getInf(final int index) {
return this.inf.get(index);
}
/**
* Get the sup value at specified index.
*
* @param index the specified index
*
* @return the inf value
*/
public double getSup(final int index) {
return this.sup.get(index);
}
/**
* Reduce by inf value.
*
* @param index value to be reduced
* @param value value used to reduce
*
* @return this for chaining.
*/
public NumericalStorage reduceInf(final int index, final double value) {
this.inf.set(index, Math.max(this.inf.get(index), value));
return this;
}
/**
* Reduce by sup value.
*
* @param index value to be reduced
* @param value value used to reduce
*
* @return this for chaining.
*/
public NumericalStorage reduceSup(final int index, final double value) {
this.sup.set(index, Math.min(this.sup.get(index), value));
return this;
}
/**
* Extend by inf value.
*
* @param index value to be extended
* @param value value used to extend
*
* @return this for chaining
*/
public NumericalStorage extendInf(final int index, final double value) {
this.inf.set(index, Math.min(this.inf.get(index), value));
return this;
}
/**
* Extend by sup value.
*
* @param index value to be extended
* @param value value used to extend
*
* @return this for chaining
*/
public NumericalStorage extendSup(final int index, final double value) {
this.sup.set(index, Math.max(this.sup.get(index), value));
return this;
}
/**
* Extends value.
*
* @param index value to be extended
* @param value value used to extend
*
* @return this for chaining.
*/
public NumericalStorage extend(final int index, final double value) {
this.extendInf(index, value);
this.extendSup(index, value);
return this;
}
/**
* Intersection.
*
* @param storage NumericalStorage
*
* @return this for chaining
*
* @todo Is it the meet operation?
*/
public NumericalStorage intersection(final NumericalStorage storage) {
final int size = this.inf.size();
if (storage.inf.size() == size) {
for (int index = 0; index < size; index++) {
this.inf.set(index, Math.max(this.inf.get(index), storage.inf.get(index)));
this.sup.set(index, Math.min(this.sup.get(index), storage.sup.get(index)));
}
return this;
} else {
throw new IllegalArgumentException(EXCEPTION_SIZE);
}
}
/**
* Union.
*
* An approximation is made for union when the two intervals are disjoint.
* The result is the minimum interval containing both intervals.
*
* @param storage NumericalStorage
*
* @return this for chaining
*/
public NumericalStorage union(final NumericalStorage storage) {
final int size = this.inf.size();
if (storage.inf.size() == size) {
for (int index = 0; index < size; index++) {
this.inf.set(index, Math.min(this.inf.get(index), storage.inf.get(index)));
this.sup.set(index, Math.max(this.sup.get(index), storage.sup.get(index)));
}
return this;
} else {
throw new IllegalArgumentException(EXCEPTION_SIZE);
}
}
/**
* Get the size.
*
* @return the size
*/
public int size() {
return this.inf.size();
}
/**
* Returns a String representation of this object.
*
* @return a string representation of this object
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append('[');
final int size = this.inf.size();
for (int index = 0; index < size; index++) {
if (index != 0) {
builder.append(", ");
}
if (this.isEmpty(index)) {
builder.append('@');
} else if (this.isPoint(index)) {
builder.append(this.inf.get(index));
} else {
builder.append('(');
builder.append(this.inf.get(index));
builder.append(',');
builder.append(this.sup.get(index));
builder.append(')');
}
}
builder.append(']');
return builder.toString();
}
}