Package jmathexpr.arithmetic.op

Source Code of jmathexpr.arithmetic.op.Addition

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jmathexpr.arithmetic.op;

import jmathexpr.Expression;
import jmathexpr.Precedence;
import jmathexpr.Variable;
import jmathexpr.arithmetic.ANumber;
import jmathexpr.arithmetic.Polynomial;
import jmathexpr.arithmetic.func.Lcm;
import jmathexpr.arithmetic.integer.IntegerNumber;
import jmathexpr.arithmetic.natural.Naturals;
import jmathexpr.arithmetic.real.Reals;
import jmathexpr.op.BinaryOperation;
import jmathexpr.op.Sign;
import jmathexpr.set.Set;
import jmathexpr.set.op.CartesianProduct;
import jmathexpr.util.logging.Logger;

/**
*
* @author Elemér Furka
*/
public class Addition extends BinaryOperation {
   
    public Addition(Expression lhs, Expression rhs) {
        super (lhs, rhs, Sign.Addition);
    }
   
    @Override
    public Expression evaluate() {
        Expression simplified = simplify();
       
        if (!(simplified instanceof Addition)) return simplified;
       
        Expression l = ((Addition) simplified).lhs;
        Expression r = ((Addition) simplified).rhs;
       
        if (l instanceof ANumber && r instanceof ANumber) {
            return ((ANumber) l).add((ANumber) r);
        }
       
        return new Addition(l, r);
    }
   
    private Expression simplify() {
        Expression l = lhs.evaluate();
        Expression r = rhs.evaluate();
       
        if (l.equals(r)) {
            return new Multiplication(Naturals.getInstance().create(2), l);
        } else if (l instanceof Division && r instanceof Division) {
            Division dl = (Division) l;
            Division dr = (Division) r;
           
            if (dl.rhs().equals(dr.rhs())) { // common denominator
                return new Division(new Addition(dl.lhs(), dr.lhs()), dl.rhs()).evaluate();
            }
        } else if (l instanceof Division) { // a/b + c = (a + bc) / b
            Division div = (Division) l;
           
            return new Division(new Addition(
                    div.lhs(), new Multiplication(div.rhs(), r)), div.rhs()).evaluate();
        } else if (l instanceof Negation) { // -a + b = b - a
            if (r instanceof Negation) { // -a - b = -(a + b)
                return new Negation(new Addition(((Negation) l).getChild(), ((Negation) r).getChild()));
            } else { // -a + b = b - a
                return new Subtraction(r, ((Negation) l).getChild()).evaluate();
            }
        } else if (l.getPrecedence() == Precedence.Addition || r.getPrecedence() == Precedence.Addition) {
            return new Sum(l, r).evaluate();
        } else if (r instanceof Negation) { // a + (-b) = a - b
            return new Subtraction(l, ((Negation) r).getChild()).evaluate();
        }
       
        return new Addition(l, r);
    }
   
    /**
     * Factorize this sum (if possible).
     *
     * @return either the factorized form of this sum or this
     */
    public Expression factorize() {
        IntegerNumber l = null, r = null;
        Expression lrest = null, rrest = null;
       
        if (lhs instanceof IntegerNumber) {
            l = (IntegerNumber) lhs;
            lrest = Naturals.one();
        } else if (lhs instanceof Multiplication
                && ((Multiplication) lhs).lhs() instanceof IntegerNumber) {
            l = (IntegerNumber) ((Multiplication) lhs).lhs();
            lrest = ((Multiplication) lhs).rhs();
        } else if (lhs instanceof Division
                && ((Division) lhs).lhs() instanceof IntegerNumber) {
            l = (IntegerNumber) ((Division) lhs).lhs();
            lrest = new Division(Naturals.one(), ((Division) lhs).rhs());
        }

        if (rhs instanceof IntegerNumber) {
            r = (IntegerNumber) rhs;
            rrest = Naturals.one();
        } else if (rhs instanceof Multiplication
                && ((Multiplication) rhs).lhs() instanceof IntegerNumber) {
            r = (IntegerNumber) ((Multiplication) rhs).lhs();
            rrest = ((Multiplication) rhs).rhs();
        } else if (rhs instanceof Division
                && ((Division) rhs).lhs() instanceof IntegerNumber) {
            r = (IntegerNumber) ((Division) rhs).lhs();
            rrest = new Division(Naturals.one(), ((Division) rhs).rhs());
        }
       
        if (l != null && r != null) {
            IntegerNumber lcm = (IntegerNumber) new Lcm(l, r).evaluate();
            IntegerNumber gcd = (IntegerNumber) l.multiply(r).divide(lcm);
           
            if (!gcd.isOne()) {
                return new Multiplication(gcd, new Addition(
                        new Multiplication(l.divide(gcd), lrest),
                        new Multiplication(r.divide(gcd), rrest)).evaluate());
            }
        }
       
        return this;
    }

    @Override
    public Precedence getPrecedence() {
        return Precedence.Addition;
    }

    @Override
    public CartesianProduct domain() {
        return new CartesianProduct(Reals.getInstance(), Reals.getInstance());
    }

    @Override
    public Set codomain() {
        return Reals.getInstance();
    }

    @Override
    protected BinaryOperation create(Expression lhs, Expression rhs) {
        return new Addition(lhs, rhs);
    }
   
    /**
     * Converts this sum into a polynomial.
     *
     * @param x the indeterminate
     * @return a newly created polynomial instance
     */
    public Polynomial toPolynomial(Variable x) {
        return new Sum(lhs, rhs).toPolynomial(x); // it also works if lhs or rhs is an addition/subtraction/sum
    }
   
    @Override
    public boolean matches(Expression expr) {
        boolean matches = super.matches(expr);
       
        if (!matches) {
            if (expr instanceof Sum) {
                return ((Sum) expr).matches(this);
            } else if (expr instanceof Polynomial) {
                return ((Polynomial) expr).matches(this);
            }
        }
       
        return matches;
    }
   
    /**
     * Multiplies both terms of this addition by the given expression from left.
     *
     * @param expr an arbitrary expression
     * @return a new Addition instance having its both terms multiplied by the
     * specified expression
     */
    public Addition multiply(Expression expr) {
        return new Addition(new Multiplication(expr, lhs), new Multiplication(expr, rhs));
    }

    @Override
    public boolean isCommutative() {
        return true;
    }
}
TOP

Related Classes of jmathexpr.arithmetic.op.Addition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.