Package jmathexpr.arithmetic.op

Source Code of jmathexpr.arithmetic.op.Multiplication

/*
* 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.arithmetic.ANumber;
import jmathexpr.arithmetic.Polynomial;
import jmathexpr.arithmetic.func.Sqrt;
import jmathexpr.arithmetic.integer.Integers;
import jmathexpr.arithmetic.natural.Naturals;
import jmathexpr.arithmetic.real.Reals;
import jmathexpr.op.BinaryOperation;
import jmathexpr.op.Operation;
import jmathexpr.op.Sign;
import jmathexpr.set.Set;
import jmathexpr.set.op.CartesianProduct;
import jmathexpr.util.logging.Logger;
import jmathexpr.util.pattern.ExpressionPattern;

/**
*
* @author Elemér Furka
*/
public class Multiplication extends BinaryOperation {
   
    public Multiplication(Expression lhs, Expression rhs) {
        super(lhs, rhs, Sign.Multiplication);
    }
   
    @Override
    public Expression evaluate() {
        Expression simplified = simplify();
       
        if (!(simplified instanceof Multiplication)) return simplified;
       
        Expression l = ((Multiplication) simplified).lhs;
        Expression r = ((Multiplication) simplified).rhs;
       
        if (l instanceof ANumber && r instanceof ANumber) {
            return ((ANumber) l).multiply((ANumber) r);
        } else if (l instanceof Polynomial) {
            if (r.isConstant()) {
                return ((Polynomial) l).multiply(r);
            }
        }

        return new Multiplication(l, r);
    }
   
    private Expression simplify() {
        Expression l = lhs.evaluate();
        Expression r = rhs.evaluate();
       
        if (l instanceof ANumber && ((ANumber)l).isZero()) {
            return Naturals.zero();
        } else if (r instanceof ANumber && ((ANumber)r).isZero()) {
            return Naturals.zero();
        } else if (l instanceof ANumber && ((ANumber)l).isOne()) {
            return r;
        } else if (r instanceof ANumber && ((ANumber)r).isOne()) {
            return l;
        }
       
        Expression two = Naturals.getInstance().create(2);
       
        if (l instanceof ANumber) {
            ANumber a = (ANumber) l;
           
            if (a.negate().isOne()) {
                return new Negation(r).evaluate();
            } else if (r instanceof Division) {
                Division d = (Division) r;
               
                if (d.rhs() instanceof ANumber) { // a x/b = a/b x
                    l = a.divide((ANumber) d.rhs());
                    r = d.lhs();
                }
            } else if (r instanceof Multiplication) {
                Multiplication m = (Multiplication) r;
               
                if (m.lhs instanceof ANumber) { // a (bx) = (ab) x
                    l = a.multiply((ANumber) m.lhs);
                    r = m.rhs;
                } else if (m.rhs instanceof ANumber) { // a (xb) = (ab) x
                    l = a.multiply((ANumber) m.rhs);
                    r = m.lhs;
                }
            } else if (r instanceof Negation) { // a (-x) = -ax
                l = a.negate();
                r = ((Negation) r).getChild();
               
                return new Multiplication(l, r).evaluate();
            } else if (a.isNegative()) { // -a x = -(ax)
                return new Negation(new Multiplication(a.negate(), r)).evaluate();
            }
        } else if (l instanceof Negation) { // (-a)b = -(ab)
            return new Negation(new Multiplication(((Negation) l).getChild(), r)).evaluate();
        } else if (l instanceof Multiplication) { // (ab) c
            Multiplication m = (Multiplication) l;
           
            if (m.rhs instanceof Sqrt && r instanceof Sqrt) {
                l = m.lhs;
                r = new Multiplication(m.rhs, r).evaluate();
            } else if (r instanceof ANumber) { // (ax) c = (ac) x
                l = new Multiplication(m.lhs, r).evaluate();
                r = m.rhs;
            }
        } else if (r instanceof Division) {
            Division d = (Division) r;
           
            if (l.equals(d.rhs())) { // a x/a = x
                if (d.rhs() instanceof ANumber && ((ANumber) d.rhs()).isZero()) {
                    throw new ArithmeticException("Division by zero: " + this);
                }
               
                return d.lhs();
            } else {
                return new Division(new Multiplication(l, d.lhs()), d.rhs()).evaluate();
            }
        } else if (r instanceof Multiplication) { // a (b c)
            Multiplication m = (Multiplication) r;
           
            if (l.equals(m.lhs)) { // a (a c) = a^2 c
                l = new Exponentiation(l, two).evaluate();
                r = m.rhs;
            } else if (l.equals(m.rhs)) { // a (b a) = a^2 b
                l = new Exponentiation(l, two).evaluate();
                r = m.lhs;
            } else if (l instanceof Negation) {
                if (m.lhs instanceof ANumber) { // -a (nx) = -n * ax
                    r = new Multiplication(l, m.rhs).evaluate();
                    l = ((ANumber) m.lhs).negate();
                }               
            } else if (m.lhs instanceof ANumber) {
                r = new Multiplication(l, m.rhs).evaluate();
                l = m.lhs;
            }
        } else if (r instanceof ANumber) {
            ANumber b = (ANumber) r;
           
            if (l instanceof Multiplication) {
                Multiplication m = (Multiplication) l;
               
                if (m.rhs instanceof ANumber) { // (xa) b = x (ab)
                    l = m.lhs;
                    r = ((ANumber) m.rhs).multiply(b);
                } else if (m.lhs instanceof ANumber) { // (ax) b = (ab) x
                    l = ((ANumber) m.lhs).multiply(b);
                    r = m.rhs;
                }
            }
        } else if (r instanceof Negation) { // a (-x) = -(ax)
            return new Negation(new Multiplication(l, ((Negation) r).getChild())).evaluate();
        }
       
        if (r instanceof Operation && r.getPrecedence() == Precedence.Addition) { // a(b+c) = ab+ac
            return applyDistribution(l, (Operation) r);
        } else if (l instanceof Operation && l.getPrecedence() == Precedence.Addition) { // (a+b)c = ac+bc
            return applyDistribution(r, (Operation) l);
        }
       
        if (l.equals(r)) { // a * a = a^2
            return new Exponentiation(l, Naturals.getInstance().create(2)).evaluate();
        }
       
        if (l instanceof Sqrt && r instanceof Sqrt) {
            return new Sqrt(new Multiplication(((Sqrt) l).argument(), ((Sqrt) r).argument())).evaluate();
        }
       
        return new Multiplication(l, r);
    }
   
    private Expression applyDistribution(Expression lhs, Operation rhs) {
        if (rhs instanceof Addition) {
            return ((Addition) rhs).multiply(lhs).evaluate();
        } else if (rhs instanceof Subtraction) {
            return ((Subtraction) rhs).multiply(lhs).evaluate();
        } else if (rhs instanceof Sum) {
            return ((Sum) rhs).multiply(lhs).evaluate();
        } else {
            throw new IllegalStateException(String.format("Unexpected operation: %s (%s)", rhs, rhs.getClass()));
        }
    }
   
    @Override
    public Precedence getPrecedence() {
        return Precedence.Multiplication;
    }
   
    @Override
    public String toString() {
        if (rhs instanceof ANumber) { 
            return super.toString();
        }
       
        String l = lhs.getPrecedence().le(getPrecedence()) ? String.format("(%s)", lhs)
                : lhs.toString();
        String r = rhs.getPrecedence().le(getPrecedence()) ? String.format("(%s)", rhs)
                : rhs.toString();
       
        return l + r;
    }

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

    @Override
    public Set codomain() {
        return Reals.getInstance();
    }
   
    @Override
    public boolean matches(Expression expr) {
        if (super.matches(expr)) return true;
       
        if (((ExpressionPattern) lhs).matches(Integers.getInstance().create(-1))) {               
            if (expr instanceof Negation) { // ax matches -x
                Negation neg = (Negation) expr;

                if (((ExpressionPattern) rhs).matches(neg.getChild())) {
                    return true;
                }
            }
        }
//       
//        if (((ExpressionPattern) lhs).matches(Naturals.one())) {
//            if (((ExpressionPattern) rhs).matches(expr)) { // ax matches x
//                return true;
//            }
//        }

        if (expr instanceof Polynomial) {
            return ((Polynomial) expr).matches(this);
        }
       
        return false;
    }

    @Override
    protected BinaryOperation create(Expression lhs, Expression rhs) {
        return new Multiplication(lhs, rhs);
    }

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

Related Classes of jmathexpr.arithmetic.op.Multiplication

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.