All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.scce.addlib.dd.xdd.latticedd.example.Interval Maven / Gradle / Ivy

Go to download

The Java Library for Algebraic Decision Diagrams, Code Generation, and Layouting

There is a newer version: 3.1.0
Show newest version
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 - 2024 Weber Informatics LLC | Privacy Policy