org.protempa.graph.Weight Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protempa-framework Show documentation
Show all versions of protempa-framework Show documentation
Protempa Framework is the core of Protempa.
/* * #%L * JavaUtil * %% * Copyright (C) 2012 - 2013 Emory University * %% * 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. * #L% */ package org.protempa.graph; import java.io.Serializable; /** * Like a
Weight; and a value * greater thanLong
except that there are special values representing * positive infinity, negative infinity, positive epsilon (smallest positive * value), and negative epsilon (smallest negative value). * * @author Andrew Post */ public final class Weight implements Comparable, Serializable { private static final long serialVersionUID = -20812788110969523L; /** * Whether or not this weight has a value of infinity. */ private boolean isInfinity = false; /** * true
if this weight has a value of positive infinity, *false
if this weight has a value of negative infinity. */ private boolean posOrNeg = true; private long val; private transient volatile int hashCode; Weight() { } /** * Creates a weight with the given value. * * @param val * along
value. */ Weight(long val) { this.val = val; } /** * Creates a weight with the given value. * * @param val * aNumber
value (if null, default value is *0L
). It is converted to along
* usingNumber.longValue()
. */ Weight(Number val) { if (val != null) { this.val = val.longValue(); } } /** * Creates a weight with a value of positive or negative infinity. * * @param posOrNeg *true
to create a weight with a value of * positive infinity,false
to create a weight * with a value of negative infinity. */ Weight(boolean posOrNeg) { isInfinity = true; this.posOrNeg = posOrNeg; } /** * Copy constructor. * * @param w * aWeight
. Ifnull
, this * creates aWeight
with the default value (0
). */ Weight(Weight w) { if (w != null) { isInfinity = w.isInfinity; posOrNeg = w.posOrNeg; val = w.val; } } void set(Weight w) { if (w != null) { isInfinity = w.isInfinity; posOrNeg = w.posOrNeg; val = w.val; } else { isInfinity = false; posOrNeg = true; val = 0L; } hashCode = 0; } /** * Gets the value of this weight. * * @return a long representing the value of this weight. If this weight has * a value of positive infinity,Long.MAX_VALUE
is * returned. If this weight has a value of negative infinity, *Long.MIN_VALUE
is returned. */ public long value() { if (isInfinity && !posOrNeg) { return Long.MIN_VALUE; } else if (isInfinity && posOrNeg) { return Long.MAX_VALUE; } else { return val; } } /** * Checks to see if this weight is greater than the given long value. * * @param val * a long value. * @return true if this weight is greater than the given long value, false * otherwise. */ public boolean greaterThan(long val) { if (isInfinity && posOrNeg) { return true; } else if (isInfinity && !posOrNeg) { return false; } else { return this.val > val; } } public int compareToLong(long val) { if (greaterThan(val)) { return 1; } else if (lessThan(val)) { return -1; } else { return 0; } } /** * Checks to see if this weight is less than the given long value. * * @param val * a long value. * @return true if this weight is less than the given long value, false * otherwise. */ public boolean lessThan(long val) { if (isInfinity && !posOrNeg) { return true; } else if (isInfinity && posOrNeg) { return false; } else { return this.val < val; } } /** * Checks if this weight has the same value as the given long. * * @param val * along
. * @return true if this weight has the same value, false otherwise. Always * returns false if the value of this weight is infinity. */ public boolean isEqual(long val) { if (isInfinity) { return false; } else { return this.val == val; } } /** * Creates a new weight with value equal to the sum of both weights. Note * that +inf and -inf cannot be added. If you try, an * IllegalArgumentException will be thrown. * * @param w * a weight. * @return a new weight. */ public Weight add(Weight w) { if (w == null) { return new Weight(this); } else { boolean wIsInfinity = w.isInfinity; boolean wPosOrNeg = w.posOrNeg; if ((isInfinity && posOrNeg && wIsInfinity && !wPosOrNeg) || (isInfinity && !posOrNeg && wIsInfinity && wPosOrNeg)) { throw new IllegalArgumentException("+inf - inf!"); } else if ((isInfinity && posOrNeg) || (w.isInfinity && wPosOrNeg)) { return WeightFactory.POS_INFINITY; } else if ((isInfinity && !posOrNeg) || (wIsInfinity && !wPosOrNeg)) { return WeightFactory.NEG_INFINITY; } else { return new Weight(val + w.val); } } } void addToSelf(Weight w) { if (w != null) { boolean wIsInfinity = w.isInfinity; boolean wPosOrNeg = w.posOrNeg; if ((isInfinity && posOrNeg && wIsInfinity && !wPosOrNeg) || (isInfinity && !posOrNeg && wIsInfinity && wPosOrNeg)) { throw new IllegalArgumentException("+inf - inf!"); } else if ((isInfinity && posOrNeg) || (wIsInfinity && wPosOrNeg)) { set(WeightFactory.POS_INFINITY); } else if ((isInfinity && !posOrNeg) || (wIsInfinity && !wPosOrNeg)) { set(WeightFactory.NEG_INFINITY); } else { val += w.val; hashCode = 0; } } } /** * Creates a new weight the value equal to the difference between the two * weights. Note that infinity cannot be subtracted from infinity. If you * try, an IllegalArgumentException will be thrown. * * @param w * a weight. * @return a new weight. */ public Weight subtract(Weight w) { if (w == null) { return new Weight(this); } else { boolean wIsInfinity = w.isInfinity; boolean wPosOrNeg = w.posOrNeg; if ((isInfinity && posOrNeg && wIsInfinity && wPosOrNeg) || (isInfinity && !posOrNeg && wIsInfinity && !wPosOrNeg)) { throw new IllegalArgumentException("+inf - inf!"); } else if ((isInfinity && posOrNeg) || (wIsInfinity && !wPosOrNeg)) { return WeightFactory.POS_INFINITY; } else if ((isInfinity && !posOrNeg) || (wIsInfinity && wPosOrNeg)) { return WeightFactory.NEG_INFINITY; } else { return new Weight(val - w.val); } } } /** * Gets the larger of the two given weights. * * @param w1 * a weight. Cannot benull
. * @param w2 * a weight. Cannot benull
. * @return a weight. */ public static Weight max(Weight w1, Weight w2) { if (w1 == null) { throw new IllegalArgumentException("Argument w1 cannot be null"); } if (w2 == null) { throw new IllegalArgumentException("Argument w2 cannot be null"); } if ((w1.isInfinity && w1.posOrNeg) || (w2.isInfinity && !w2.posOrNeg)) { return w1; } else if ((w2.isInfinity && w2.posOrNeg) || (w1.isInfinity && !w1.posOrNeg)) { return w2; } else if (w1.val >= w2.val) { return w1; } else { return w2; } } /** * Gets the smaller of the two given weights. * * @param w1 * a weight. Cannot benull
. * @param w2 * a weight. Cannot benull
. * @return a weight. */ public static Weight min(Weight w1, Weight w2) { if (w1 == null) { throw new IllegalArgumentException("Argument w1 cannot be null"); } if (w2 == null) { throw new IllegalArgumentException("Argument w2 cannot be null"); } if ((w1.isInfinity && !w1.posOrNeg) || (w2.isInfinity && w2.posOrNeg)) { return w1; } else if ((w2.isInfinity && !w2.posOrNeg) || (w1.isInfinity && w1.posOrNeg)) { return w2; } else if (w1.val <= w2.val) { return w1; } else { return w2; } } /** * Checks if this weight has value of positive infinity. * * @returntrue
if it does,false
if it * doesn't. */ public boolean isPositiveInfinity() { return isInfinity && posOrNeg; } /** * Checks if this weight has value of negative infinity. * * @returntrue
if it does,false
if it * doesn't. */ public boolean isNegativeInfinity() { return isInfinity && !posOrNeg; } /** * Checks if this weight has value of positive or negative infinity. * * @returntrue
if it does,false
if it * doesn't. */ public boolean isInfinity() { return isInfinity; } /** * Creates a new weight with the opposite sign. * * @return a newWeight
. */ public Weight invertSign() { if (isInfinity) { if (posOrNeg) { return WeightFactory.NEG_INFINITY; } else { return WeightFactory.POS_INFINITY; } } return new Weight(-val); } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { if (isInfinity) { if (posOrNeg) { return "+inf"; } else if (!posOrNeg) { return "-inf"; } } return String.valueOf(val); } /** * Compares twoWeight
objects numerically. * * @param anotherWeight * theWeight
to be compared. * @return the value0
if thisWeight
is equal * to the argumentWeight
; a value less than *0
if thisWeight
is numerically * less than the argument0
if thisWeight
is * numerically greater than the argumentWeight
* (signed comparison). */ public int compareTo(Weight anotherWeight) { boolean wIsInfinity = anotherWeight.isInfinity; boolean wPosOrNeg = anotherWeight.posOrNeg; if (isInfinity && wIsInfinity && ((posOrNeg && wPosOrNeg) || (!posOrNeg && !wPosOrNeg))) { return 0; } else if ((isInfinity && posOrNeg) || (wIsInfinity && !wPosOrNeg)) { return 1; } else if ((isInfinity && !posOrNeg) || (wIsInfinity && wPosOrNeg)) { return -1; } else if (val < anotherWeight.val) { return -1; } else if (val > anotherWeight.val) { return 1; } else { return 0; } } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null) { return false; } if (getClass() != o.getClass()) { return false; } Weight w = (Weight) o; return isInfinity == w.isInfinity && posOrNeg == w.posOrNeg && val == w.val; } @Override public int hashCode() { if (hashCode == 0) { int result = 17; result = 37 * result + (isInfinity ? 0 : 1); result = 37 * result + (posOrNeg ? 0 : 1); result = 37 * result + (int) (val ^ (val >>> 32)); hashCode = result; } return hashCode; } /** * Checks if this weight has a value within the specified range. * * @param min * the minimumWeight
of the range. * @param max * the maximumWeight
of the range. * @returntrue
if this weight is within the specified range, *false
if not. */ boolean isWithinRange(Weight min, Weight max) { return compareTo(min) >= 0 && compareTo(max) <= 0; } }