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

it.unife.ml.math.ApproxDouble Maven / Gradle / Ivy

/**
 *  This file is part of BUNDLE.
 *
 *  BUNDLE is a probabilistic reasoner for OWL 2 ontologies.
 *
 *  BUNDLE is a module of the LEAP system, but can be used as standalone.
 *
 *  LEAP was implemented as a plugin of DL-Learner http://dl-learner.org,
 *  but some components can be used as stand-alone.
 *
 *  LEAP and all its modules are free software; you can redistribute the and/or modify
 *  them under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  LEAP and all its parts are distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 *
 */
package it.unife.ml.math;

/**
 *
 * @author Giuseppe Cota 
 */
public class ApproxDouble {

    private static Integer accuracy = null;

    private static Integer defaultAccuracy = 5;

    private static Integer maxAccuracy = 5;

    /**
     * @return the defaultAccuracy
     */
    public static Integer getDefaultAccuracy() {
        return defaultAccuracy;
    }

    private static ApproxDouble ONE;

    private static ApproxDouble ZERO;

    private Long base;

//    private Long exp;
//    public ApproxDouble(Long base) {
//        this.base = base;
////        this.exp = exp;
//    }
    public ApproxDouble(Double baseD) {
        if (accuracy == null) {
            ApproxDouble.setAccuracy(defaultAccuracy);
        }
        double approx =  Math.round(baseD * Math.pow(10, accuracy)) / Math.pow(10, accuracy);
        this.base = (long) (approx * Math.pow(10, accuracy));
    }

    public ApproxDouble(ApproxDouble prob) {
        this.base = prob.base;
    }

    public static boolean isAccuracySet() {
        return accuracy != null;
    }

    public static void setAccuracy(Integer accuracy) {
        if (accuracy <= maxAccuracy) {
            ApproxDouble.accuracy = ApproxDouble.accuracy == null ? accuracy : throw_();
        }
    }

    public static void resetAccuracy() {
        ApproxDouble.accuracy = null;
    }

    private static int throw_() {
        throw new RuntimeException("Accuracy is already set");
    }

    /**
     * It adds the value contained in the object given as parameter to the value
     * contained in *this* instance.
     *
     * @param addend
     * @return
     */
    public ApproxDouble _add(ApproxDouble addend) {
        base += addend.base;
        return this;
    }

    /**
     * It returns a new object that contains the value of *this* instance plus
     * the value contained in the object given as parameter.
     *
     * @param addend
     * @return
     */
    public ApproxDouble add(ApproxDouble addend) {
        ApproxDouble result = new ApproxDouble(this);
        return result._add(addend);
    }

    /**
     * It multiplies the value contained in the object given as parameter to the
     * value contained in *this* instance.
     *
     * @param factor
     * @return
     */
    public ApproxDouble _multiply(ApproxDouble factor) {
        base = Math.round((double) base * factor.base / Math.pow(10, factor.accuracy));
        return this;
    }

    /**
     * It returns a new object that contains the value of *this* instance
     * multiplied by the value contained in the object given as parameter.
     *
     * @param factor
     * @return a new ApproxDouble object
     */
    public ApproxDouble multiply(ApproxDouble factor) {
        ApproxDouble result = new ApproxDouble(this);
        return result._multiply(factor);
    }

    /**
     * It subtracts the value contained in the object given as parameter to the
     * value contained in *this* instance.
     *
     * @param subtrahend
     * @return *this* object
     */
    public ApproxDouble _subtract(ApproxDouble subtrahend) {
        base -= subtrahend.base;
        return this;
    }

    /**
     * It returns a new object that contains the value of *this* instance minus
     * the value contained in the object given as parameter.
     *
     * @param subtrahend
     * @return a new ApproxDouble object
     */
    public ApproxDouble subtract(ApproxDouble subtrahend) {
        ApproxDouble result = new ApproxDouble(this);
        return result._subtract(subtrahend);
    }

    /**
     * It divides the value contained in the object given as parameter to the
     * value contained in *this* instance.
     *
     * @param divisor
     * @return
     */
    public ApproxDouble _divide(ApproxDouble divisor) {
        base = Math.round(((double) base / divisor.base) * Math.pow(10, divisor.accuracy));
        return this;
    }

    /**
     * It returns a new object that contains the value of *this* instance
     * divided by the value contained in the object given as parameter.
     *
     * @param divisor
     * @return a new ApproxDouble object
     */
    public ApproxDouble divide(ApproxDouble divisor) {
        ApproxDouble result = new ApproxDouble(this);
        return result._divide(divisor);
    }
    
    public ApproxDouble multiplyAndDivide(ApproxDouble factor, ApproxDouble divisor) {
        ApproxDouble result = new ApproxDouble(this);
        return result._multiplyAndDivide(factor, divisor);
    }
    
    
    private ApproxDouble _multiplyAndDivide(ApproxDouble factor, ApproxDouble divisor) {
        base = Math.round((double) (base * factor.base) / divisor.base);
        return this;
    }
    

    public int compareTo(ApproxDouble prob2) {
        return this.base.compareTo(prob2.base);
    }

    public static ApproxDouble one() {
        if (ONE == null) {
            ONE = new ApproxDouble(1D);
        }
        return ONE;
    }

    public static ApproxDouble zero() {
        if (ZERO == null) {
            ZERO = new ApproxDouble(0D);
        }
        return ZERO;
    }
    
    public void setValue(ApproxDouble value) {
        this.base = value.base;
    }

    public Double getValue() {
        return (double) base / Math.pow(10, accuracy);
    }

    public ApproxDouble abs() {
        ApproxDouble result = new ApproxDouble(this);
        return (result.signum() < 0 ? result._negate() : result);
    }

    private int signum() {
        return this.base.compareTo(0L);
    }

    private ApproxDouble _negate() {
        this.base = -this.base;
        return this;
    }

    @Override
    public String toString() {
        return "" + getValue();
    }
    
    public double doubleValue() {
        return getValue();
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy