http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/Fraction.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/Fraction.java b/src/main/java/org/apache/commons/math3/fraction/Fraction.java deleted file mode 100644 index 1752043..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/Fraction.java +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.fraction; - -import java.io.Serializable; -import java.math.BigInteger; - -import org.apache.commons.math3.FieldElement; -import org.apache.commons.math3.exception.util.LocalizedFormats; -import org.apache.commons.math3.exception.MathArithmeticException; -import org.apache.commons.math3.exception.NullArgumentException; -import org.apache.commons.math3.util.ArithmeticUtils; -import org.apache.commons.math3.util.FastMath; - -/** - * Representation of a rational number. - * - * implements Serializable since 2.0 - * - * @since 1.1 - */ -public class Fraction - extends Number - implements FieldElement<Fraction>, Comparable<Fraction>, Serializable { - - /** A fraction representing "2 / 1". */ - public static final Fraction TWO = new Fraction(2, 1); - - /** A fraction representing "1". */ - public static final Fraction ONE = new Fraction(1, 1); - - /** A fraction representing "0". */ - public static final Fraction ZERO = new Fraction(0, 1); - - /** A fraction representing "4/5". */ - public static final Fraction FOUR_FIFTHS = new Fraction(4, 5); - - /** A fraction representing "1/5". */ - public static final Fraction ONE_FIFTH = new Fraction(1, 5); - - /** A fraction representing "1/2". */ - public static final Fraction ONE_HALF = new Fraction(1, 2); - - /** A fraction representing "1/4". */ - public static final Fraction ONE_QUARTER = new Fraction(1, 4); - - /** A fraction representing "1/3". */ - public static final Fraction ONE_THIRD = new Fraction(1, 3); - - /** A fraction representing "3/5". */ - public static final Fraction THREE_FIFTHS = new Fraction(3, 5); - - /** A fraction representing "3/4". */ - public static final Fraction THREE_QUARTERS = new Fraction(3, 4); - - /** A fraction representing "2/5". */ - public static final Fraction TWO_FIFTHS = new Fraction(2, 5); - - /** A fraction representing "2/4". */ - public static final Fraction TWO_QUARTERS = new Fraction(2, 4); - - /** A fraction representing "2/3". */ - public static final Fraction TWO_THIRDS = new Fraction(2, 3); - - /** A fraction representing "-1 / 1". */ - public static final Fraction MINUS_ONE = new Fraction(-1, 1); - - /** Serializable version identifier */ - private static final long serialVersionUID = 3698073679419233275L; - - /** The default epsilon used for convergence. */ - private static final double DEFAULT_EPSILON = 1e-5; - - /** The denominator. */ - private final int denominator; - - /** The numerator. */ - private final int numerator; - - /** - * Create a fraction given the double value. - * @param value the double value to convert to a fraction. - * @throws FractionConversionException if the continued fraction failed to - * converge. - */ - public Fraction(double value) throws FractionConversionException { - this(value, DEFAULT_EPSILON, 100); - } - - /** - * Create a fraction given the double value and maximum error allowed. - * <p> - * References: - * <ul> - * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> - * Continued Fraction</a> equations (11) and (22)-(26)</li> - * </ul> - * </p> - * @param value the double value to convert to a fraction. - * @param epsilon maximum error allowed. The resulting fraction is within - * {@code epsilon} of {@code value}, in absolute terms. - * @param maxIterations maximum number of convergents - * @throws FractionConversionException if the continued fraction failed to - * converge. - */ - public Fraction(double value, double epsilon, int maxIterations) - throws FractionConversionException - { - this(value, epsilon, Integer.MAX_VALUE, maxIterations); - } - - /** - * Create a fraction given the double value and maximum denominator. - * <p> - * References: - * <ul> - * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> - * Continued Fraction</a> equations (11) and (22)-(26)</li> - * </ul> - * </p> - * @param value the double value to convert to a fraction. - * @param maxDenominator The maximum allowed value for denominator - * @throws FractionConversionException if the continued fraction failed to - * converge - */ - public Fraction(double value, int maxDenominator) - throws FractionConversionException - { - this(value, 0, maxDenominator, 100); - } - - /** - * Create a fraction given the double value and either the maximum error - * allowed or the maximum number of denominator digits. - * <p> - * - * NOTE: This constructor is called with EITHER - * - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE - * (that way the maxDenominator has no effect). - * OR - * - a valid maxDenominator value and the epsilon value set to zero - * (that way epsilon only has effect if there is an exact match before - * the maxDenominator value is reached). - * </p><p> - * - * It has been done this way so that the same code can be (re)used for both - * scenarios. However this could be confusing to users if it were part of - * the public API and this constructor should therefore remain PRIVATE. - * </p> - * - * See JIRA issue ticket MATH-181 for more details: - * - * https://issues.apache.org/jira/browse/MATH-181 - * - * @param value the double value to convert to a fraction. - * @param epsilon maximum error allowed. The resulting fraction is within - * {@code epsilon} of {@code value}, in absolute terms. - * @param maxDenominator maximum denominator value allowed. - * @param maxIterations maximum number of convergents - * @throws FractionConversionException if the continued fraction failed to - * converge. - */ - private Fraction(double value, double epsilon, int maxDenominator, int maxIterations) - throws FractionConversionException - { - long overflow = Integer.MAX_VALUE; - double r0 = value; - long a0 = (long)FastMath.floor(r0); - if (FastMath.abs(a0) > overflow) { - throw new FractionConversionException(value, a0, 1l); - } - - // check for (almost) integer arguments, which should not go to iterations. - if (FastMath.abs(a0 - value) < epsilon) { - this.numerator = (int) a0; - this.denominator = 1; - return; - } - - long p0 = 1; - long q0 = 0; - long p1 = a0; - long q1 = 1; - - long p2 = 0; - long q2 = 1; - - int n = 0; - boolean stop = false; - do { - ++n; - double r1 = 1.0 / (r0 - a0); - long a1 = (long)FastMath.floor(r1); - p2 = (a1 * p1) + p0; - q2 = (a1 * q1) + q0; - - if ((FastMath.abs(p2) > overflow) || (FastMath.abs(q2) > overflow)) { - // in maxDenominator mode, if the last fraction was very close to the actual value - // q2 may overflow in the next iteration; in this case return the last one. - if (epsilon == 0.0 && FastMath.abs(q1) < maxDenominator) { - break; - } - throw new FractionConversionException(value, p2, q2); - } - - double convergent = (double)p2 / (double)q2; - if (n < maxIterations && FastMath.abs(convergent - value) > epsilon && q2 < maxDenominator) { - p0 = p1; - p1 = p2; - q0 = q1; - q1 = q2; - a0 = a1; - r0 = r1; - } else { - stop = true; - } - } while (!stop); - - if (n >= maxIterations) { - throw new FractionConversionException(value, maxIterations); - } - - if (q2 < maxDenominator) { - this.numerator = (int) p2; - this.denominator = (int) q2; - } else { - this.numerator = (int) p1; - this.denominator = (int) q1; - } - - } - - /** - * Create a fraction from an int. - * The fraction is num / 1. - * @param num the numerator. - */ - public Fraction(int num) { - this(num, 1); - } - - /** - * Create a fraction given the numerator and denominator. The fraction is - * reduced to lowest terms. - * @param num the numerator. - * @param den the denominator. - * @throws MathArithmeticException if the denominator is {@code zero} - */ - public Fraction(int num, int den) { - if (den == 0) { - throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, - num, den); - } - if (den < 0) { - if (num == Integer.MIN_VALUE || - den == Integer.MIN_VALUE) { - throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION, - num, den); - } - num = -num; - den = -den; - } - // reduce numerator and denominator by greatest common denominator. - final int d = ArithmeticUtils.gcd(num, den); - if (d > 1) { - num /= d; - den /= d; - } - - // move sign to numerator. - if (den < 0) { - num = -num; - den = -den; - } - this.numerator = num; - this.denominator = den; - } - - /** - * Returns the absolute value of this fraction. - * @return the absolute value. - */ - public Fraction abs() { - Fraction ret; - if (numerator >= 0) { - ret = this; - } else { - ret = negate(); - } - return ret; - } - - /** - * Compares this object to another based on size. - * @param object the object to compare to - * @return -1 if this is less than {@code object}, +1 if this is greater - * than {@code object}, 0 if they are equal. - */ - public int compareTo(Fraction object) { - long nOd = ((long) numerator) * object.denominator; - long dOn = ((long) denominator) * object.numerator; - return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0); - } - - /** - * Gets the fraction as a {@code double}. This calculates the fraction as - * the numerator divided by denominator. - * @return the fraction as a {@code double} - */ - @Override - public double doubleValue() { - return (double)numerator / (double)denominator; - } - - /** - * Test for the equality of two fractions. If the lowest term - * numerator and denominators are the same for both fractions, the two - * fractions are considered to be equal. - * @param other fraction to test for equality to this fraction - * @return true if two fractions are equal, false if object is - * {@code null}, not an instance of {@link Fraction}, or not equal - * to this fraction instance. - */ - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (other instanceof Fraction) { - // since fractions are always in lowest terms, numerators and - // denominators can be compared directly for equality. - Fraction rhs = (Fraction)other; - return (numerator == rhs.numerator) && - (denominator == rhs.denominator); - } - return false; - } - - /** - * Gets the fraction as a {@code float}. This calculates the fraction as - * the numerator divided by denominator. - * @return the fraction as a {@code float} - */ - @Override - public float floatValue() { - return (float)doubleValue(); - } - - /** - * Access the denominator. - * @return the denominator. - */ - public int getDenominator() { - return denominator; - } - - /** - * Access the numerator. - * @return the numerator. - */ - public int getNumerator() { - return numerator; - } - - /** - * Gets a hashCode for the fraction. - * @return a hash code value for this object - */ - @Override - public int hashCode() { - return 37 * (37 * 17 + numerator) + denominator; - } - - /** - * Gets the fraction as an {@code int}. This returns the whole number part - * of the fraction. - * @return the whole number fraction part - */ - @Override - public int intValue() { - return (int)doubleValue(); - } - - /** - * Gets the fraction as a {@code long}. This returns the whole number part - * of the fraction. - * @return the whole number fraction part - */ - @Override - public long longValue() { - return (long)doubleValue(); - } - - /** - * Return the additive inverse of this fraction. - * @return the negation of this fraction. - */ - public Fraction negate() { - if (numerator==Integer.MIN_VALUE) { - throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION, numerator, denominator); - } - return new Fraction(-numerator, denominator); - } - - /** - * Return the multiplicative inverse of this fraction. - * @return the reciprocal fraction - */ - public Fraction reciprocal() { - return new Fraction(denominator, numerator); - } - - /** - * <p>Adds the value of this fraction to another, returning the result in reduced form. - * The algorithm follows Knuth, 4.5.1.</p> - * - * @param fraction the fraction to add, must not be {@code null} - * @return a {@code Fraction} instance with the resulting values - * @throws NullArgumentException if the fraction is {@code null} - * @throws MathArithmeticException if the resulting numerator or denominator exceeds - * {@code Integer.MAX_VALUE} - */ - public Fraction add(Fraction fraction) { - return addSub(fraction, true /* add */); - } - - /** - * Add an integer to the fraction. - * @param i the {@code integer} to add. - * @return this + i - */ - public Fraction add(final int i) { - return new Fraction(numerator + i * denominator, denominator); - } - - /** - * <p>Subtracts the value of another fraction from the value of this one, - * returning the result in reduced form.</p> - * - * @param fraction the fraction to subtract, must not be {@code null} - * @return a {@code Fraction} instance with the resulting values - * @throws NullArgumentException if the fraction is {@code null} - * @throws MathArithmeticException if the resulting numerator or denominator - * cannot be represented in an {@code int}. - */ - public Fraction subtract(Fraction fraction) { - return addSub(fraction, false /* subtract */); - } - - /** - * Subtract an integer from the fraction. - * @param i the {@code integer} to subtract. - * @return this - i - */ - public Fraction subtract(final int i) { - return new Fraction(numerator - i * denominator, denominator); - } - - /** - * Implement add and subtract using algorithm described in Knuth 4.5.1. - * - * @param fraction the fraction to subtract, must not be {@code null} - * @param isAdd true to add, false to subtract - * @return a {@code Fraction} instance with the resulting values - * @throws NullArgumentException if the fraction is {@code null} - * @throws MathArithmeticException if the resulting numerator or denominator - * cannot be represented in an {@code int}. - */ - private Fraction addSub(Fraction fraction, boolean isAdd) { - if (fraction == null) { - throw new NullArgumentException(LocalizedFormats.FRACTION); - } - // zero is identity for addition. - if (numerator == 0) { - return isAdd ? fraction : fraction.negate(); - } - if (fraction.numerator == 0) { - return this; - } - // if denominators are randomly distributed, d1 will be 1 about 61% - // of the time. - int d1 = ArithmeticUtils.gcd(denominator, fraction.denominator); - if (d1==1) { - // result is ( (u*v' +/- u'v) / u'v') - int uvp = ArithmeticUtils.mulAndCheck(numerator, fraction.denominator); - int upv = ArithmeticUtils.mulAndCheck(fraction.numerator, denominator); - return new Fraction - (isAdd ? ArithmeticUtils.addAndCheck(uvp, upv) : - ArithmeticUtils.subAndCheck(uvp, upv), - ArithmeticUtils.mulAndCheck(denominator, fraction.denominator)); - } - // the quantity 't' requires 65 bits of precision; see knuth 4.5.1 - // exercise 7. we're going to use a BigInteger. - // t = u(v'/d1) +/- v(u'/d1) - BigInteger uvp = BigInteger.valueOf(numerator) - .multiply(BigInteger.valueOf(fraction.denominator/d1)); - BigInteger upv = BigInteger.valueOf(fraction.numerator) - .multiply(BigInteger.valueOf(denominator/d1)); - BigInteger t = isAdd ? uvp.add(upv) : uvp.subtract(upv); - // but d2 doesn't need extra precision because - // d2 = gcd(t,d1) = gcd(t mod d1, d1) - int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue(); - int d2 = (tmodd1==0)?d1:ArithmeticUtils.gcd(tmodd1, d1); - - // result is (t/d2) / (u'/d1)(v'/d2) - BigInteger w = t.divide(BigInteger.valueOf(d2)); - if (w.bitLength() > 31) { - throw new MathArithmeticException(LocalizedFormats.NUMERATOR_OVERFLOW_AFTER_MULTIPLY, - w); - } - return new Fraction (w.intValue(), - ArithmeticUtils.mulAndCheck(denominator/d1, - fraction.denominator/d2)); - } - - /** - * <p>Multiplies the value of this fraction by another, returning the - * result in reduced form.</p> - * - * @param fraction the fraction to multiply by, must not be {@code null} - * @return a {@code Fraction} instance with the resulting values - * @throws NullArgumentException if the fraction is {@code null} - * @throws MathArithmeticException if the resulting numerator or denominator exceeds - * {@code Integer.MAX_VALUE} - */ - public Fraction multiply(Fraction fraction) { - if (fraction == null) { - throw new NullArgumentException(LocalizedFormats.FRACTION); - } - if (numerator == 0 || fraction.numerator == 0) { - return ZERO; - } - // knuth 4.5.1 - // make sure we don't overflow unless the result *must* overflow. - int d1 = ArithmeticUtils.gcd(numerator, fraction.denominator); - int d2 = ArithmeticUtils.gcd(fraction.numerator, denominator); - return getReducedFraction - (ArithmeticUtils.mulAndCheck(numerator/d1, fraction.numerator/d2), - ArithmeticUtils.mulAndCheck(denominator/d2, fraction.denominator/d1)); - } - - /** - * Multiply the fraction by an integer. - * @param i the {@code integer} to multiply by. - * @return this * i - */ - public Fraction multiply(final int i) { - return new Fraction(numerator * i, denominator); - } - - /** - * <p>Divide the value of this fraction by another.</p> - * - * @param fraction the fraction to divide by, must not be {@code null} - * @return a {@code Fraction} instance with the resulting values - * @throws IllegalArgumentException if the fraction is {@code null} - * @throws MathArithmeticException if the fraction to divide by is zero - * @throws MathArithmeticException if the resulting numerator or denominator exceeds - * {@code Integer.MAX_VALUE} - */ - public Fraction divide(Fraction fraction) { - if (fraction == null) { - throw new NullArgumentException(LocalizedFormats.FRACTION); - } - if (fraction.numerator == 0) { - throw new MathArithmeticException(LocalizedFormats.ZERO_FRACTION_TO_DIVIDE_BY, - fraction.numerator, fraction.denominator); - } - return multiply(fraction.reciprocal()); - } - - /** - * Divide the fraction by an integer. - * @param i the {@code integer} to divide by. - * @return this * i - */ - public Fraction divide(final int i) { - return new Fraction(numerator, denominator * i); - } - - /** - * <p> - * Gets the fraction percentage as a {@code double}. This calculates the - * fraction as the numerator divided by denominator multiplied by 100. - * </p> - * - * @return the fraction percentage as a {@code double}. - */ - public double percentageValue() { - return 100 * doubleValue(); - } - - /** - * <p>Creates a {@code Fraction} instance with the 2 parts - * of a fraction Y/Z.</p> - * - * <p>Any negative signs are resolved to be on the numerator.</p> - * - * @param numerator the numerator, for example the three in 'three sevenths' - * @param denominator the denominator, for example the seven in 'three sevenths' - * @return a new fraction instance, with the numerator and denominator reduced - * @throws MathArithmeticException if the denominator is {@code zero} - */ - public static Fraction getReducedFraction(int numerator, int denominator) { - if (denominator == 0) { - throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR_IN_FRACTION, - numerator, denominator); - } - if (numerator==0) { - return ZERO; // normalize zero. - } - // allow 2^k/-2^31 as a valid fraction (where k>0) - if (denominator==Integer.MIN_VALUE && (numerator&1)==0) { - numerator/=2; denominator/=2; - } - if (denominator < 0) { - if (numerator==Integer.MIN_VALUE || - denominator==Integer.MIN_VALUE) { - throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_FRACTION, - numerator, denominator); - } - numerator = -numerator; - denominator = -denominator; - } - // simplify fraction. - int gcd = ArithmeticUtils.gcd(numerator, denominator); - numerator /= gcd; - denominator /= gcd; - return new Fraction(numerator, denominator); - } - - /** - * <p> - * Returns the {@code String} representing this fraction, ie - * "num / dem" or just "num" if the denominator is one. - * </p> - * - * @return a string representation of the fraction. - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - String str = null; - if (denominator == 1) { - str = Integer.toString(numerator); - } else if (numerator == 0) { - str = "0"; - } else { - str = numerator + " / " + denominator; - } - return str; - } - - /** {@inheritDoc} */ - public FractionField getField() { - return FractionField.getInstance(); - } - -}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/FractionConversionException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/FractionConversionException.java b/src/main/java/org/apache/commons/math3/fraction/FractionConversionException.java deleted file mode 100644 index a16a97a..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/FractionConversionException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -package org.apache.commons.math3.fraction; - -import org.apache.commons.math3.exception.ConvergenceException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Error thrown when a double value cannot be converted to a fraction - * in the allowed number of iterations. - * - * @since 1.2 - */ -public class FractionConversionException extends ConvergenceException { - - /** Serializable version identifier. */ - private static final long serialVersionUID = -4661812640132576263L; - - /** - * Constructs an exception with specified formatted detail message. - * Message formatting is delegated to {@link java.text.MessageFormat}. - * @param value double value to convert - * @param maxIterations maximal number of iterations allowed - */ - public FractionConversionException(double value, int maxIterations) { - super(LocalizedFormats.FAILED_FRACTION_CONVERSION, value, maxIterations); - } - - /** - * Constructs an exception with specified formatted detail message. - * Message formatting is delegated to {@link java.text.MessageFormat}. - * @param value double value to convert - * @param p current numerator - * @param q current denominator - */ - public FractionConversionException(double value, long p, long q) { - super(LocalizedFormats.FRACTION_CONVERSION_OVERFLOW, value, p, q); - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/FractionField.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/FractionField.java b/src/main/java/org/apache/commons/math3/fraction/FractionField.java deleted file mode 100644 index 2928509..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/FractionField.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -package org.apache.commons.math3.fraction; - -import java.io.Serializable; - -import org.apache.commons.math3.Field; -import org.apache.commons.math3.FieldElement; - -/** - * Representation of the fractional numbers field. - * <p> - * This class is a singleton. - * </p> - * @see Fraction - * @since 2.0 - */ -public class FractionField implements Field<Fraction>, Serializable { - - /** Serializable version identifier */ - private static final long serialVersionUID = -1257768487499119313L; - - /** Private constructor for the singleton. - */ - private FractionField() { - } - - /** Get the unique instance. - * @return the unique instance - */ - public static FractionField getInstance() { - return LazyHolder.INSTANCE; - } - - /** {@inheritDoc} */ - public Fraction getOne() { - return Fraction.ONE; - } - - /** {@inheritDoc} */ - public Fraction getZero() { - return Fraction.ZERO; - } - - /** {@inheritDoc} */ - public Class<? extends FieldElement<Fraction>> getRuntimeClass() { - return Fraction.class; - } - // CHECKSTYLE: stop HideUtilityClassConstructor - /** Holder for the instance. - * <p>We use here the Initialization On Demand Holder Idiom.</p> - */ - private static class LazyHolder { - /** Cached field instance. */ - private static final FractionField INSTANCE = new FractionField(); - } - // CHECKSTYLE: resume HideUtilityClassConstructor - - /** Handle deserialization of the singleton. - * @return the singleton instance - */ - private Object readResolve() { - // return the singleton instance - return LazyHolder.INSTANCE; - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/FractionFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/FractionFormat.java b/src/main/java/org/apache/commons/math3/fraction/FractionFormat.java deleted file mode 100644 index 06c5a10..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/FractionFormat.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -package org.apache.commons.math3.fraction; - -import java.text.FieldPosition; -import java.text.NumberFormat; -import java.text.ParsePosition; -import java.util.Locale; - -import org.apache.commons.math3.exception.MathIllegalArgumentException; -import org.apache.commons.math3.exception.MathParseException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Formats a Fraction number in proper format or improper format. The number - * format for each of the whole number, numerator and, denominator can be - * configured. - * - * @since 1.1 - */ -public class FractionFormat extends AbstractFormat { - - /** Serializable version identifier */ - private static final long serialVersionUID = 3008655719530972611L; - - /** - * Create an improper formatting instance with the default number format - * for the numerator and denominator. - */ - public FractionFormat() { - } - - /** - * Create an improper formatting instance with a custom number format for - * both the numerator and denominator. - * @param format the custom format for both the numerator and denominator. - */ - public FractionFormat(final NumberFormat format) { - super(format); - } - - /** - * Create an improper formatting instance with a custom number format for - * the numerator and a custom number format for the denominator. - * @param numeratorFormat the custom format for the numerator. - * @param denominatorFormat the custom format for the denominator. - */ - public FractionFormat(final NumberFormat numeratorFormat, - final NumberFormat denominatorFormat) { - super(numeratorFormat, denominatorFormat); - } - - /** - * Get the set of locales for which complex formats are available. This - * is the same set as the {@link NumberFormat} set. - * @return available complex format locales. - */ - public static Locale[] getAvailableLocales() { - return NumberFormat.getAvailableLocales(); - } - - /** - * This static method calls formatFraction() on a default instance of - * FractionFormat. - * - * @param f Fraction object to format - * @return a formatted fraction in proper form. - */ - public static String formatFraction(Fraction f) { - return getImproperInstance().format(f); - } - - /** - * Returns the default complex format for the current locale. - * @return the default complex format. - */ - public static FractionFormat getImproperInstance() { - return getImproperInstance(Locale.getDefault()); - } - - /** - * Returns the default complex format for the given locale. - * @param locale the specific locale used by the format. - * @return the complex format specific to the given locale. - */ - public static FractionFormat getImproperInstance(final Locale locale) { - return new FractionFormat(getDefaultNumberFormat(locale)); - } - - /** - * Returns the default complex format for the current locale. - * @return the default complex format. - */ - public static FractionFormat getProperInstance() { - return getProperInstance(Locale.getDefault()); - } - - /** - * Returns the default complex format for the given locale. - * @param locale the specific locale used by the format. - * @return the complex format specific to the given locale. - */ - public static FractionFormat getProperInstance(final Locale locale) { - return new ProperFractionFormat(getDefaultNumberFormat(locale)); - } - - /** - * Create a default number format. The default number format is based on - * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only - * customizing is the maximum number of fraction digits, which is set to 0. - * @return the default number format. - */ - protected static NumberFormat getDefaultNumberFormat() { - return getDefaultNumberFormat(Locale.getDefault()); - } - - /** - * Formats a {@link Fraction} object to produce a string. The fraction is - * output in improper format. - * - * @param fraction the object to format. - * @param toAppendTo where the text is to be appended - * @param pos On input: an alignment field, if desired. On output: the - * offsets of the alignment field - * @return the value passed in as toAppendTo. - */ - public StringBuffer format(final Fraction fraction, - final StringBuffer toAppendTo, final FieldPosition pos) { - - pos.setBeginIndex(0); - pos.setEndIndex(0); - - getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos); - toAppendTo.append(" / "); - getDenominatorFormat().format(fraction.getDenominator(), toAppendTo, - pos); - - return toAppendTo; - } - - /** - * Formats an object and appends the result to a StringBuffer. <code>obj</code> must be either a - * {@link Fraction} object or a {@link Number} object. Any other type of - * object will result in an {@link IllegalArgumentException} being thrown. - * - * @param obj the object to format. - * @param toAppendTo where the text is to be appended - * @param pos On input: an alignment field, if desired. On output: the - * offsets of the alignment field - * @return the value passed in as toAppendTo. - * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) - * @throws FractionConversionException if the number cannot be converted to a fraction - * @throws MathIllegalArgumentException if <code>obj</code> is not a valid type. - */ - @Override - public StringBuffer format(final Object obj, - final StringBuffer toAppendTo, final FieldPosition pos) - throws FractionConversionException, MathIllegalArgumentException { - StringBuffer ret = null; - - if (obj instanceof Fraction) { - ret = format((Fraction) obj, toAppendTo, pos); - } else if (obj instanceof Number) { - ret = format(new Fraction(((Number) obj).doubleValue()), toAppendTo, pos); - } else { - throw new MathIllegalArgumentException(LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION); - } - - return ret; - } - - /** - * Parses a string to produce a {@link Fraction} object. - * @param source the string to parse - * @return the parsed {@link Fraction} object. - * @exception MathParseException if the beginning of the specified string - * cannot be parsed. - */ - @Override - public Fraction parse(final String source) throws MathParseException { - final ParsePosition parsePosition = new ParsePosition(0); - final Fraction result = parse(source, parsePosition); - if (parsePosition.getIndex() == 0) { - throw new MathParseException(source, parsePosition.getErrorIndex(), Fraction.class); - } - return result; - } - - /** - * Parses a string to produce a {@link Fraction} object. This method - * expects the string to be formatted as an improper fraction. - * @param source the string to parse - * @param pos input/output parsing parameter. - * @return the parsed {@link Fraction} object. - */ - @Override - public Fraction parse(final String source, final ParsePosition pos) { - final int initialIndex = pos.getIndex(); - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse numerator - final Number num = getNumeratorFormat().parse(source, pos); - if (num == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - // parse '/' - final int startIndex = pos.getIndex(); - final char c = parseNextCharacter(source, pos); - switch (c) { - case 0 : - // no '/' - // return num as a fraction - return new Fraction(num.intValue(), 1); - case '/' : - // found '/', continue parsing denominator - break; - default : - // invalid '/' - // set index back to initial, error index should be the last - // character examined. - pos.setIndex(initialIndex); - pos.setErrorIndex(startIndex); - return null; - } - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse denominator - final Number den = getDenominatorFormat().parse(source, pos); - if (den == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - return new Fraction(num.intValue(), den.intValue()); - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/ProperBigFractionFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/ProperBigFractionFormat.java b/src/main/java/org/apache/commons/math3/fraction/ProperBigFractionFormat.java deleted file mode 100644 index 4f84acd..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/ProperBigFractionFormat.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.fraction; - -import java.math.BigInteger; -import java.text.FieldPosition; -import java.text.NumberFormat; -import java.text.ParsePosition; - -import org.apache.commons.math3.exception.util.LocalizedFormats; -import org.apache.commons.math3.exception.NullArgumentException; - -/** - * Formats a BigFraction number in proper format. The number format for each of - * the whole number, numerator and, denominator can be configured. - * <p> - * Minus signs are only allowed in the whole number part - i.e., - * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and - * will result in a <code>ParseException</code>.</p> - * - * @since 1.1 - */ -public class ProperBigFractionFormat extends BigFractionFormat { - - /** Serializable version identifier */ - private static final long serialVersionUID = -6337346779577272307L; - - /** The format used for the whole number. */ - private NumberFormat wholeFormat; - - /** - * Create a proper formatting instance with the default number format for - * the whole, numerator, and denominator. - */ - public ProperBigFractionFormat() { - this(getDefaultNumberFormat()); - } - - /** - * Create a proper formatting instance with a custom number format for the - * whole, numerator, and denominator. - * @param format the custom format for the whole, numerator, and - * denominator. - */ - public ProperBigFractionFormat(final NumberFormat format) { - this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); - } - - /** - * Create a proper formatting instance with a custom number format for each - * of the whole, numerator, and denominator. - * @param wholeFormat the custom format for the whole. - * @param numeratorFormat the custom format for the numerator. - * @param denominatorFormat the custom format for the denominator. - */ - public ProperBigFractionFormat(final NumberFormat wholeFormat, - final NumberFormat numeratorFormat, - final NumberFormat denominatorFormat) { - super(numeratorFormat, denominatorFormat); - setWholeFormat(wholeFormat); - } - - /** - * Formats a {@link BigFraction} object to produce a string. The BigFraction - * is output in proper format. - * - * @param fraction the object to format. - * @param toAppendTo where the text is to be appended - * @param pos On input: an alignment field, if desired. On output: the - * offsets of the alignment field - * @return the value passed in as toAppendTo. - */ - @Override - public StringBuffer format(final BigFraction fraction, - final StringBuffer toAppendTo, final FieldPosition pos) { - - pos.setBeginIndex(0); - pos.setEndIndex(0); - - BigInteger num = fraction.getNumerator(); - BigInteger den = fraction.getDenominator(); - BigInteger whole = num.divide(den); - num = num.remainder(den); - - if (!BigInteger.ZERO.equals(whole)) { - getWholeFormat().format(whole, toAppendTo, pos); - toAppendTo.append(' '); - if (num.compareTo(BigInteger.ZERO) < 0) { - num = num.negate(); - } - } - getNumeratorFormat().format(num, toAppendTo, pos); - toAppendTo.append(" / "); - getDenominatorFormat().format(den, toAppendTo, pos); - - return toAppendTo; - } - - /** - * Access the whole format. - * @return the whole format. - */ - public NumberFormat getWholeFormat() { - return wholeFormat; - } - - /** - * Parses a string to produce a {@link BigFraction} object. This method - * expects the string to be formatted as a proper BigFraction. - * <p> - * Minus signs are only allowed in the whole number part - i.e., - * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and - * will result in a <code>ParseException</code>.</p> - * - * @param source the string to parse - * @param pos input/ouput parsing parameter. - * @return the parsed {@link BigFraction} object. - */ - @Override - public BigFraction parse(final String source, final ParsePosition pos) { - // try to parse improper BigFraction - BigFraction ret = super.parse(source, pos); - if (ret != null) { - return ret; - } - - final int initialIndex = pos.getIndex(); - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse whole - BigInteger whole = parseNextBigInteger(source, pos); - if (whole == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse numerator - BigInteger num = parseNextBigInteger(source, pos); - if (num == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - if (num.compareTo(BigInteger.ZERO) < 0) { - // minus signs should be leading, invalid expression - pos.setIndex(initialIndex); - return null; - } - - // parse '/' - final int startIndex = pos.getIndex(); - final char c = parseNextCharacter(source, pos); - switch (c) { - case 0 : - // no '/' - // return num as a BigFraction - return new BigFraction(num); - case '/' : - // found '/', continue parsing denominator - break; - default : - // invalid '/' - // set index back to initial, error index should be the last - // character examined. - pos.setIndex(initialIndex); - pos.setErrorIndex(startIndex); - return null; - } - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse denominator - final BigInteger den = parseNextBigInteger(source, pos); - if (den == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - if (den.compareTo(BigInteger.ZERO) < 0) { - // minus signs must be leading, invalid - pos.setIndex(initialIndex); - return null; - } - - boolean wholeIsNeg = whole.compareTo(BigInteger.ZERO) < 0; - if (wholeIsNeg) { - whole = whole.negate(); - } - num = whole.multiply(den).add(num); - if (wholeIsNeg) { - num = num.negate(); - } - - return new BigFraction(num, den); - - } - - /** - * Modify the whole format. - * @param format The new whole format value. - * @throws NullArgumentException if {@code format} is {@code null}. - */ - public void setWholeFormat(final NumberFormat format) { - if (format == null) { - throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT); - } - this.wholeFormat = format; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/ProperFractionFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/ProperFractionFormat.java b/src/main/java/org/apache/commons/math3/fraction/ProperFractionFormat.java deleted file mode 100644 index 9dc6778..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/ProperFractionFormat.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.fraction; - -import java.text.FieldPosition; -import java.text.NumberFormat; -import java.text.ParsePosition; - -import org.apache.commons.math3.exception.util.LocalizedFormats; -import org.apache.commons.math3.exception.NullArgumentException; -import org.apache.commons.math3.util.FastMath; -import org.apache.commons.math3.util.MathUtils; - -/** - * Formats a Fraction number in proper format. The number format for each of - * the whole number, numerator and, denominator can be configured. - * <p> - * Minus signs are only allowed in the whole number part - i.e., - * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and - * will result in a <code>ParseException</code>.</p> - * - * @since 1.1 - */ -public class ProperFractionFormat extends FractionFormat { - - /** Serializable version identifier */ - private static final long serialVersionUID = 760934726031766749L; - - /** The format used for the whole number. */ - private NumberFormat wholeFormat; - - /** - * Create a proper formatting instance with the default number format for - * the whole, numerator, and denominator. - */ - public ProperFractionFormat() { - this(getDefaultNumberFormat()); - } - - /** - * Create a proper formatting instance with a custom number format for the - * whole, numerator, and denominator. - * @param format the custom format for the whole, numerator, and - * denominator. - */ - public ProperFractionFormat(NumberFormat format) { - this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); - } - - /** - * Create a proper formatting instance with a custom number format for each - * of the whole, numerator, and denominator. - * @param wholeFormat the custom format for the whole. - * @param numeratorFormat the custom format for the numerator. - * @param denominatorFormat the custom format for the denominator. - */ - public ProperFractionFormat(NumberFormat wholeFormat, - NumberFormat numeratorFormat, - NumberFormat denominatorFormat) - { - super(numeratorFormat, denominatorFormat); - setWholeFormat(wholeFormat); - } - - /** - * Formats a {@link Fraction} object to produce a string. The fraction - * is output in proper format. - * - * @param fraction the object to format. - * @param toAppendTo where the text is to be appended - * @param pos On input: an alignment field, if desired. On output: the - * offsets of the alignment field - * @return the value passed in as toAppendTo. - */ - @Override - public StringBuffer format(Fraction fraction, StringBuffer toAppendTo, - FieldPosition pos) { - - pos.setBeginIndex(0); - pos.setEndIndex(0); - - int num = fraction.getNumerator(); - int den = fraction.getDenominator(); - int whole = num / den; - num %= den; - - if (whole != 0) { - getWholeFormat().format(whole, toAppendTo, pos); - toAppendTo.append(' '); - num = FastMath.abs(num); - } - getNumeratorFormat().format(num, toAppendTo, pos); - toAppendTo.append(" / "); - getDenominatorFormat().format(den, toAppendTo, pos); - - return toAppendTo; - } - - /** - * Access the whole format. - * @return the whole format. - */ - public NumberFormat getWholeFormat() { - return wholeFormat; - } - - /** - * Parses a string to produce a {@link Fraction} object. This method - * expects the string to be formatted as a proper fraction. - * <p> - * Minus signs are only allowed in the whole number part - i.e., - * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and - * will result in a <code>ParseException</code>.</p> - * - * @param source the string to parse - * @param pos input/ouput parsing parameter. - * @return the parsed {@link Fraction} object. - */ - @Override - public Fraction parse(String source, ParsePosition pos) { - // try to parse improper fraction - Fraction ret = super.parse(source, pos); - if (ret != null) { - return ret; - } - - int initialIndex = pos.getIndex(); - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse whole - Number whole = getWholeFormat().parse(source, pos); - if (whole == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse numerator - Number num = getNumeratorFormat().parse(source, pos); - if (num == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - if (num.intValue() < 0) { - // minus signs should be leading, invalid expression - pos.setIndex(initialIndex); - return null; - } - - // parse '/' - int startIndex = pos.getIndex(); - char c = parseNextCharacter(source, pos); - switch (c) { - case 0 : - // no '/' - // return num as a fraction - return new Fraction(num.intValue(), 1); - case '/' : - // found '/', continue parsing denominator - break; - default : - // invalid '/' - // set index back to initial, error index should be the last - // character examined. - pos.setIndex(initialIndex); - pos.setErrorIndex(startIndex); - return null; - } - - // parse whitespace - parseAndIgnoreWhitespace(source, pos); - - // parse denominator - Number den = getDenominatorFormat().parse(source, pos); - if (den == null) { - // invalid integer number - // set index back to initial, error index should already be set - // character examined. - pos.setIndex(initialIndex); - return null; - } - - if (den.intValue() < 0) { - // minus signs must be leading, invalid - pos.setIndex(initialIndex); - return null; - } - - int w = whole.intValue(); - int n = num.intValue(); - int d = den.intValue(); - return new Fraction(((FastMath.abs(w) * d) + n) * MathUtils.copySign(1, w), d); - } - - /** - * Modify the whole format. - * @param format The new whole format value. - * @throws NullArgumentException if {@code format} is {@code null}. - */ - public void setWholeFormat(NumberFormat format) { - if (format == null) { - throw new NullArgumentException(LocalizedFormats.WHOLE_FORMAT); - } - this.wholeFormat = format; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/fraction/package-info.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/fraction/package-info.java b/src/main/java/org/apache/commons/math3/fraction/package-info.java deleted file mode 100644 index f5425c6..0000000 --- a/src/main/java/org/apache/commons/math3/fraction/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -/** - * - * Fraction number type and fraction number formatting. - * - */ -package org.apache.commons.math3.fraction; http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/AbstractListChromosome.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/AbstractListChromosome.java b/src/main/java/org/apache/commons/math3/genetics/AbstractListChromosome.java deleted file mode 100644 index 60450ba..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/AbstractListChromosome.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * Chromosome represented by an immutable list of a fixed length. - * - * @param <T> type of the representation list - * @since 2.0 - */ -public abstract class AbstractListChromosome<T> extends Chromosome { - - /** List representing the chromosome */ - private final List<T> representation; - - /** - * Constructor, copying the input representation. - * @param representation inner representation of the chromosome - * @throws InvalidRepresentationException iff the <code>representation</code> can not represent a valid chromosome - */ - public AbstractListChromosome(final List<T> representation) throws InvalidRepresentationException { - this(representation, true); - } - - /** - * Constructor, copying the input representation. - * @param representation inner representation of the chromosome - * @throws InvalidRepresentationException iff the <code>representation</code> can not represent a valid chromosome - */ - public AbstractListChromosome(final T[] representation) throws InvalidRepresentationException { - this(Arrays.asList(representation)); - } - - /** - * Constructor. - * @param representation inner representation of the chromosome - * @param copyList if {@code true}, the representation will be copied, otherwise it will be referenced. - * @since 3.3 - */ - public AbstractListChromosome(final List<T> representation, final boolean copyList) { - checkValidity(representation); - this.representation = - Collections.unmodifiableList(copyList ? new ArrayList<T>(representation) : representation); - } - - /** - * Asserts that <code>representation</code> can represent a valid chromosome. - * - * @param chromosomeRepresentation representation of the chromosome - * @throws InvalidRepresentationException iff the <code>representation</code> can not represent a valid chromosome - */ - protected abstract void checkValidity(List<T> chromosomeRepresentation) throws InvalidRepresentationException; - - /** - * Returns the (immutable) inner representation of the chromosome. - * @return the representation of the chromosome - */ - protected List<T> getRepresentation() { - return representation; - } - - /** - * Returns the length of the chromosome. - * @return the length of the chromosome - */ - public int getLength() { - return getRepresentation().size(); - } - - /** - * Creates a new instance of the same class as <code>this</code> is, with a given <code>arrayRepresentation</code>. - * This is needed in crossover and mutation operators, where we need a new instance of the same class, but with - * different array representation. - * <p> - * Usually, this method just calls a constructor of the class. - * - * @param chromosomeRepresentation the inner array representation of the new chromosome. - * @return new instance extended from FixedLengthChromosome with the given arrayRepresentation - */ - public abstract AbstractListChromosome<T> newFixedLengthChromosome(final List<T> chromosomeRepresentation); - - @Override - public String toString() { - return String.format("(f=%s %s)", getFitness(), getRepresentation()); - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/BinaryChromosome.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/BinaryChromosome.java b/src/main/java/org/apache/commons/math3/genetics/BinaryChromosome.java deleted file mode 100644 index 47d317c..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/BinaryChromosome.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.math3.exception.util.LocalizedFormats; - - -/** - * Chromosome represented by a vector of 0s and 1s. - * - * @since 2.0 - */ -public abstract class BinaryChromosome extends AbstractListChromosome<Integer> { - - /** - * Constructor. - * @param representation list of {0,1} values representing the chromosome - * @throws InvalidRepresentationException iff the <code>representation</code> can not represent a valid chromosome - */ - public BinaryChromosome(List<Integer> representation) throws InvalidRepresentationException { - super(representation); - } - - /** - * Constructor. - * @param representation array of {0,1} values representing the chromosome - * @throws InvalidRepresentationException iff the <code>representation</code> can not represent a valid chromosome - */ - public BinaryChromosome(Integer[] representation) throws InvalidRepresentationException { - super(representation); - } - - /** - * {@inheritDoc} - */ - @Override - protected void checkValidity(List<Integer> chromosomeRepresentation) throws InvalidRepresentationException { - for (int i : chromosomeRepresentation) { - if (i < 0 || i >1) { - throw new InvalidRepresentationException(LocalizedFormats.INVALID_BINARY_DIGIT, - i); - } - } - } - - /** - * Returns a representation of a random binary array of length <code>length</code>. - * @param length length of the array - * @return a random binary array of length <code>length</code> - */ - public static List<Integer> randomBinaryRepresentation(int length) { - // random binary list - List<Integer> rList= new ArrayList<Integer> (length); - for (int j=0; j<length; j++) { - rList.add(GeneticAlgorithm.getRandomGenerator().nextInt(2)); - } - return rList; - } - - @Override - protected boolean isSame(Chromosome another) { - // type check - if (! (another instanceof BinaryChromosome)) { - return false; - } - BinaryChromosome anotherBc = (BinaryChromosome) another; - // size check - if (getLength() != anotherBc.getLength()) { - return false; - } - - for (int i=0; i< getRepresentation().size(); i++) { - if (!(getRepresentation().get(i).equals(anotherBc.getRepresentation().get(i)))) { - return false; - } - } - // all is ok - return true; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/BinaryMutation.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/BinaryMutation.java b/src/main/java/org/apache/commons/math3/genetics/BinaryMutation.java deleted file mode 100644 index 0802fc6..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/BinaryMutation.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.math3.exception.MathIllegalArgumentException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Mutation for {@link BinaryChromosome}s. Randomly changes one gene. - * - * @since 2.0 - */ -public class BinaryMutation implements MutationPolicy { - - /** - * Mutate the given chromosome. Randomly changes one gene. - * - * @param original the original chromosome. - * @return the mutated chromosome. - * @throws MathIllegalArgumentException if <code>original</code> is not an instance of {@link BinaryChromosome}. - */ - public Chromosome mutate(Chromosome original) throws MathIllegalArgumentException { - if (!(original instanceof BinaryChromosome)) { - throw new MathIllegalArgumentException(LocalizedFormats.INVALID_BINARY_CHROMOSOME); - } - - BinaryChromosome origChrom = (BinaryChromosome) original; - List<Integer> newRepr = new ArrayList<Integer>(origChrom.getRepresentation()); - - // randomly select a gene - int geneIndex = GeneticAlgorithm.getRandomGenerator().nextInt(origChrom.getLength()); - // and change it - newRepr.set(geneIndex, origChrom.getRepresentation().get(geneIndex) == 0 ? 1 : 0); - - Chromosome newChrom = origChrom.newFixedLengthChromosome(newRepr); - return newChrom; - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/Chromosome.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/Chromosome.java b/src/main/java/org/apache/commons/math3/genetics/Chromosome.java deleted file mode 100644 index 22e4750..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/Chromosome.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -/** - * Individual in a population. Chromosomes are compared based on their fitness. - * <p> - * The chromosomes are IMMUTABLE, and so their fitness is also immutable and - * therefore it can be cached. - * - * @since 2.0 - */ -public abstract class Chromosome implements Comparable<Chromosome>,Fitness { - /** Value assigned when no fitness has been computed yet. */ - private static final double NO_FITNESS = Double.NEGATIVE_INFINITY; - - /** Cached value of the fitness of this chromosome. */ - private double fitness = NO_FITNESS; - - /** - * Access the fitness of this chromosome. The bigger the fitness, the better the chromosome. - * <p> - * Computation of fitness is usually very time-consuming task, therefore the fitness is cached. - * - * @return the fitness - */ - public double getFitness() { - if (this.fitness == NO_FITNESS) { - // no cache - compute the fitness - this.fitness = fitness(); - } - return this.fitness; - } - - /** - * Compares two chromosomes based on their fitness. The bigger the fitness, the better the chromosome. - * - * @param another another chromosome to compare - * @return - * <ul> - * <li>-1 if <code>another</code> is better than <code>this</code></li> - * <li>1 if <code>another</code> is worse than <code>this</code></li> - * <li>0 if the two chromosomes have the same fitness</li> - * </ul> - */ - public int compareTo(final Chromosome another) { - return Double.compare(getFitness(), another.getFitness()); - } - - /** - * Returns <code>true</code> iff <code>another</code> has the same representation and therefore the same fitness. By - * default, it returns false -- override it in your implementation if you need it. - * - * @param another chromosome to compare - * @return true if <code>another</code> is equivalent to this chromosome - */ - protected boolean isSame(final Chromosome another) { - return false; - } - - /** - * Searches the <code>population</code> for another chromosome with the same representation. If such chromosome is - * found, it is returned, if no such chromosome exists, returns <code>null</code>. - * - * @param population Population to search - * @return Chromosome with the same representation, or <code>null</code> if no such chromosome exists. - */ - protected Chromosome findSameChromosome(final Population population) { - for (Chromosome anotherChr : population) { - if (this.isSame(anotherChr)) { - return anotherChr; - } - } - return null; - } - - /** - * Searches the population for a chromosome representing the same solution, and if it finds one, - * updates the fitness to its value. - * - * @param population Population to search - */ - public void searchForFitnessUpdate(final Population population) { - Chromosome sameChromosome = findSameChromosome(population); - if (sameChromosome != null) { - fitness = sameChromosome.getFitness(); - } - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/ChromosomePair.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/ChromosomePair.java b/src/main/java/org/apache/commons/math3/genetics/ChromosomePair.java deleted file mode 100644 index ef8769d..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/ChromosomePair.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -/** - * A pair of {@link Chromosome} objects. - * @since 2.0 - * - */ -public class ChromosomePair { - /** the first chromosome in the pair. */ - private final Chromosome first; - - /** the second chromosome in the pair. */ - private final Chromosome second; - - /** - * Create a chromosome pair. - * - * @param c1 the first chromosome. - * @param c2 the second chromosome. - */ - public ChromosomePair(final Chromosome c1, final Chromosome c2) { - super(); - first = c1; - second = c2; - } - - /** - * Access the first chromosome. - * - * @return the first chromosome. - */ - public Chromosome getFirst() { - return first; - } - - /** - * Access the second chromosome. - * - * @return the second chromosome. - */ - public Chromosome getSecond() { - return second; - } - - @Override - public String toString() { - return String.format("(%s,%s)", getFirst(), getSecond()); - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/CrossoverPolicy.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/CrossoverPolicy.java b/src/main/java/org/apache/commons/math3/genetics/CrossoverPolicy.java deleted file mode 100644 index 9af56f1..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/CrossoverPolicy.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -import org.apache.commons.math3.exception.MathIllegalArgumentException; - -/** - * Policy used to create a pair of new chromosomes by performing a crossover - * operation on a source pair of chromosomes. - * - * @since 2.0 - */ -public interface CrossoverPolicy { - - /** - * Perform a crossover operation on the given chromosomes. - * - * @param first the first chromosome. - * @param second the second chromosome. - * @return the pair of new chromosomes that resulted from the crossover. - * @throws MathIllegalArgumentException if the given chromosomes are not compatible with this {@link CrossoverPolicy} - */ - ChromosomePair crossover(Chromosome first, Chromosome second) throws MathIllegalArgumentException; -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/genetics/CycleCrossover.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/genetics/CycleCrossover.java b/src/main/java/org/apache/commons/math3/genetics/CycleCrossover.java deleted file mode 100644 index 364b16b..0000000 --- a/src/main/java/org/apache/commons/math3/genetics/CycleCrossover.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ -package org.apache.commons.math3.genetics; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.math3.exception.DimensionMismatchException; -import org.apache.commons.math3.exception.MathIllegalArgumentException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Cycle Crossover [CX] builds offspring from <b>ordered</b> chromosomes by identifying cycles - * between two parent chromosomes. To form the children, the cycles are copied from the - * respective parents. - * <p> - * To form a cycle the following procedure is applied: - * <ol> - * <li>start with the first gene of parent 1</li> - * <li>look at the gene at the same position of parent 2</li> - * <li>go to the position with the same gene in parent 1</li> - * <li>add this gene index to the cycle</li> - * <li>repeat the steps 2-5 until we arrive at the starting gene of this cycle</li> - * </ol> - * The indices that form a cycle are then used to form the children in alternating order, i.e. - * in cycle 1, the genes of parent 1 are copied to child 1, while in cycle 2 the genes of parent 1 - * are copied to child 2, and so forth ... - * </p> - * - * Example (zero-start cycle): - * <pre> - * p1 = (8 4 7 3 6 2 5 1 9 0) X c1 = (8 1 2 3 4 5 6 7 9 0) - * p2 = (0 1 2 3 4 5 6 7 8 9) X c2 = (0 4 7 3 6 2 5 1 8 9) - * - * cycle 1: 8 0 9 - * cycle 2: 4 1 7 2 5 6 - * cycle 3: 3 - * </pre> - * - * This policy works only on {@link AbstractListChromosome}, and therefore it - * is parameterized by T. Moreover, the chromosomes must have same lengths. - * - * @see <a href="http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/CycleCrossoverOperator.aspx"> - * Cycle Crossover Operator</a> - * - * @param <T> generic type of the {@link AbstractListChromosome}s for crossover - * @since 3.1 - */ -public class CycleCrossover<T> implements CrossoverPolicy { - - /** If the start index shall be chosen randomly. */ - private final boolean randomStart; - - /** - * Creates a new {@link CycleCrossover} policy. - */ - public CycleCrossover() { - this(false); - } - - /** - * Creates a new {@link CycleCrossover} policy using the given {@code randomStart} behavior. - * - * @param randomStart whether the start index shall be chosen randomly or be set to 0 - */ - public CycleCrossover(final boolean randomStart) { - this.randomStart = randomStart; - } - - /** - * Returns whether the starting index is chosen randomly or set to zero. - * - * @return {@code true} if the starting index is chosen randomly, {@code false} otherwise - */ - public boolean isRandomStart() { - return randomStart; - } - - /** - * {@inheritDoc} - * - * @throws MathIllegalArgumentException if the chromosomes are not an instance of {@link AbstractListChromosome} - * @throws DimensionMismatchException if the length of the two chromosomes is different - */ - @SuppressWarnings("unchecked") - public ChromosomePair crossover(final Chromosome first, final Chromosome second) - throws DimensionMismatchException, MathIllegalArgumentException { - - if (!(first instanceof AbstractListChromosome<?> && second instanceof AbstractListChromosome<?>)) { - throw new MathIllegalArgumentException(LocalizedFormats.INVALID_FIXED_LENGTH_CHROMOSOME); - } - return mate((AbstractListChromosome<T>) first, (AbstractListChromosome<T>) second); - } - - /** - * Helper for {@link #crossover(Chromosome, Chromosome)}. Performs the actual crossover. - * - * @param first the first chromosome - * @param second the second chromosome - * @return the pair of new chromosomes that resulted from the crossover - * @throws DimensionMismatchException if the length of the two chromosomes is different - */ - protected ChromosomePair mate(final AbstractListChromosome<T> first, final AbstractListChromosome<T> second) - throws DimensionMismatchException { - - final int length = first.getLength(); - if (length != second.getLength()) { - throw new DimensionMismatchException(second.getLength(), length); - } - - // array representations of the parents - final List<T> parent1Rep = first.getRepresentation(); - final List<T> parent2Rep = second.getRepresentation(); - // and of the children: do a crossover copy to simplify the later processing - final List<T> child1Rep = new ArrayList<T>(second.getRepresentation()); - final List<T> child2Rep = new ArrayList<T>(first.getRepresentation()); - - // the set of all visited indices so far - final Set<Integer> visitedIndices = new HashSet<Integer>(length); - // the indices of the current cycle - final List<Integer> indices = new ArrayList<Integer>(length); - - // determine the starting index - int idx = randomStart ? GeneticAlgorithm.getRandomGenerator().nextInt(length) : 0; - int cycle = 1; - - while (visitedIndices.size() < length) { - indices.add(idx); - - T item = parent2Rep.get(idx); - idx = parent1Rep.indexOf(item); - - while (idx != indices.get(0)) { - // add that index to the cycle indices - indices.add(idx); - // get the item in the second parent at that index - item = parent2Rep.get(idx); - // get the index of that item in the first parent - idx = parent1Rep.indexOf(item); - } - - // for even cycles: swap the child elements on the indices found in this cycle - if (cycle++ % 2 != 0) { - for (int i : indices) { - T tmp = child1Rep.get(i); - child1Rep.set(i, child2Rep.get(i)); - child2Rep.set(i, tmp); - } - } - - visitedIndices.addAll(indices); - // find next starting index: last one + 1 until we find an unvisited index - idx = (indices.get(0) + 1) % length; - while (visitedIndices.contains(idx) && visitedIndices.size() < length) { - idx++; - if (idx >= length) { - idx = 0; - } - } - indices.clear(); - } - - return new ChromosomePair(first.newFixedLengthChromosome(child1Rep), - second.newFixedLengthChromosome(child2Rep)); - } -}