
info.scce.addlib.dd.xdd.latticedd.example.Interval Maven / Gradle / Ivy
package info.scce.addlib.dd.xdd.latticedd.example;
import java.util.Objects;
import static java.lang.Double.parseDouble;
public class Interval {
private double lb;
private double ub;
private boolean lbIncluded;
private boolean ubIncluded;
public Interval(double lb, boolean lbIncluded, double ub, boolean ubIncluded) {
this.lb = lb;
this.ub = ub;
this.lbIncluded = lbIncluded;
this.ubIncluded = ubIncluded;
/* Check misuse of positive or negative infinity */
if (lb == Double.NEGATIVE_INFINITY && this.lbIncluded == true)
throw new RuntimeException("Negative infinity is not a real number");
if (ub == Double.POSITIVE_INFINITY && this.ubIncluded == true)
throw new RuntimeException("Positive infinity is not a real number");
/* Ensure canonical representation of empty intervals as (0, 0) */
if (isEmpty()) {
this.lb = 0;
this.ub = 0;
this.lbIncluded = false;
this.ubIncluded = false;
}
}
public static Interval empty() {
return new Interval(0, false, 0, false);
}
public static Interval complete() {
return new Interval(Double.NEGATIVE_INFINITY, false, Double.POSITIVE_INFINITY, false);
}
public static Interval parseInterval(String str) {
/* Parse lbIncluded */
boolean lbIncluded;
if (str.charAt(0) == '[') lbIncluded = true;
else if (str.charAt(0) == '(') lbIncluded = false;
else return null;
/* Parse bounds */
String[] parts = str.substring(1, str.length() - 1).split(", *");
double lb = parseDouble(parts[0]);
double ub = parseDouble(parts[1]);
/* Parse ubIncluded */
boolean ubIncluded;
if (str.charAt(str.length() - 1) == ']') ubIncluded = true;
else if (str.charAt(str.length() - 1) == ')') ubIncluded = false;
else return null;
return new Interval(lb, lbIncluded, ub, ubIncluded);
}
public boolean contains(Interval other) {
return lbSmallerEqThan(other) && ubGreaterEqThan(other)
|| other.equals(empty());
}
public Interval union(Interval other) {
/* Treat empty intervals special */
if (empty().equals(this)) return other;
else if (empty().equals(other)) return this;
/* Find lower bound */
double lb;
boolean lbIncluded;
if (lbSmallerEqThan(other)) {
lb = this.lb;
lbIncluded = this.lbIncluded;
} else {
lb = other.lb;
lbIncluded = other.lbIncluded;
}
/* Find upper bound */
double ub;
boolean ubIncluded;
if (ubGreaterEqThan(other)) {
ub = this.ub;
ubIncluded = this.ubIncluded;
} else {
ub = other.ub;
ubIncluded = other.ubIncluded;
}
return new Interval(lb, lbIncluded, ub, ubIncluded);
}
public Interval intersect(Interval other) {
/* Treat empty intervals special */
if (empty().equals(this)) return this;
else if (empty().equals(other)) return other;
/* Find lower bound */
double lb;
boolean lbIncluded;
if (lbSmallerEqThan(other)) {
lb = other.lb;
lbIncluded = other.lbIncluded;
} else {
lb = this.lb;
lbIncluded = this.lbIncluded;
}
/* Find upper bound */
double ub;
boolean ubIncluded;
if (ubGreaterEqThan(other)) {
ub = other.ub;
ubIncluded = other.ubIncluded;
} else {
ub = this.ub;
ubIncluded = this.ubIncluded;
}
return new Interval(lb, lbIncluded, ub, ubIncluded);
}
private boolean ubGreaterEqThan(Interval other) {
if (ubIncluded || !other.ubIncluded) return ub >= other.ub;
else return ub > other.ub;
}
private boolean lbSmallerEqThan(Interval other) {
if (lbIncluded || !other.lbIncluded) return lb <= other.lb;
else return lb < other.lb;
}
private boolean isEmpty() {
return (lb > ub) ||
(lb == ub && !(lbIncluded && ubIncluded));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Interval interval = (Interval) o;
return Double.compare(interval.lb, lb) == 0 &&
Double.compare(interval.ub, ub) == 0 &&
lbIncluded == interval.lbIncluded &&
ubIncluded == interval.ubIncluded;
}
@Override
public int hashCode() {
return Objects.hash(lb, ub, lbIncluded, ubIncluded);
}
@Override
public String toString() {
return (lbIncluded ? "[" : "(") + lb + ", " + ub + (ubIncluded ? "]" : ")");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy