Package jmathexpr.arithmetic.equation

Source Code of jmathexpr.arithmetic.equation.RadicalEquation$SeparateRadicals$SqrtSubtract

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

import java.util.ArrayList;
import java.util.List;

import jmathexpr.Expression;
import jmathexpr.Variable;
import jmathexpr.arithmetic.ANumber;
import jmathexpr.arithmetic.equation.rule.EquationRule;
import jmathexpr.arithmetic.equation.rule.RuleMachine;
import jmathexpr.arithmetic.func.Sqrt;
import jmathexpr.arithmetic.natural.Naturals;
import jmathexpr.arithmetic.op.Addition;
import jmathexpr.arithmetic.op.Exponentiation;
import jmathexpr.arithmetic.op.Subtraction;
import jmathexpr.arithmetic.op.Sum;
import jmathexpr.arithmetic.rule.DistributiveLaw;
import jmathexpr.relation.Equality;
import jmathexpr.set.Set;
import jmathexpr.util.logging.Logger;
import jmathexpr.util.pattern.AnyPattern;
import jmathexpr.util.pattern.ExpressionPattern;
import jmathexpr.util.pattern.FunctionPattern;
import jmathexpr.util.pattern.NotPattern;
import jmathexpr.util.pattern.TerminationPattern;
import jmathexpr.util.rule.CompositeRule;
import jmathexpr.util.rule.SimpleRule;
import jmathexpr.util.rule.SubRule;

/**
* Radical equation in one unknown. This class is immutable.
*
* @author Elemér Furka
*/
public class RadicalEquation extends Equation {
   
    /**
     * Creates a new radical equation specifying the two sides of the equality.
     *
     * @param lhs left hand side of the equality
     * @param rhs right hand side of the equality
     */
    public RadicalEquation(Expression lhs, Expression rhs, Variable x) {
        super(lhs, rhs, x);
    }

    /**
     * Creates a new radical equation instance using an existing equality.
     *
     * @param equality the equality to be transformed into an equation
     */
    public RadicalEquation(Equality equality, Variable x) {
        this(equality.lhs(), equality.rhs(), x);
    }

    @Override
    protected RadicalEquation create(Expression lhs, Expression rhs) {
        return new RadicalEquation(lhs, rhs, x);
    }
   
    /**
     * Tests if the given equality is a radical equation.
     *
     * @param equality the equality to test
     * @param x the unknown in the equation
     * @return true if the equality is a radical equation
     */
    public static boolean isA(Equality equality, Variable x) {
        return equality.contains(new Sqrt(new FunctionPattern(x)));
    }
   
    /**
     * Solves this radical equation equality by equality. The steps are stored internally.
     *
     * @return a set of zero or one or infinite number of elements: the solution of this radical equation
     */
    @Override
    public Set solve() throws EquationSolveException {
        rules = new RuleMachine(this);
       
        rules.addRule(new SeparateRadicals());
        rules.addRule(new Square());
        rules.addRule(new DistributiveLaw());
        rules.addRule(new ToLinearEquation());
        rules.addRule(new ToQuadraticEquation());

        Set result = rules.execute();
       
        result = check(result);
                       
        return result;
    }
   
    /**
     * Separates radical expressions.
     */
    private class SeparateRadicals extends CompositeRule {

        private final TerminationPattern a = new AnyPattern();
       
        private final ExpressionPattern b = new NotPattern(new Sqrt(new FunctionPattern(x)));
        private final ExpressionPattern s = new FunctionPattern(
                new Sqrt(new FunctionPattern(x)));
       
        private SeparateRadicals() {
            super(false);
        }
        @Override
        public boolean matches(Expression expr) {
            target = expr;
           
            // the order of these two subrules is important (the second one may match the first one)
            if ((rule = new SqrtSubtract()).matches(expr)) return true;
            if ((rule = new SqrtAdd()).matches(expr)) return true;
           
            return false;
        }      

        /**
         * sqrt(f(x)) + a = b -> sqrt(f(x)) = b - a
         */
        private class SqrtAdd extends SubRule {

            @Override
            public boolean matches(Expression expr) {
                ExpressionPattern sum = new Sum(s, a);
               
                return new Equality(sum, b).matches(expr);
            }

            @Override
            public Expression apply() {
                Equality eq = (Equality) target;
                Expression lhs = Sum.subtract(eq.lhs(), a.hit());
                Expression rhs = Sum.subtract(eq.rhs(), a.hit());

                return new Equality(lhs, rhs);
            }
        }

        /**
         * sqrt(f(x)) - a = b -> sqrt(f(x)) = b + a
         */
        private class SqrtSubtract extends SubRule {

            @Override
            public boolean matches(Expression expr) {
                ExpressionPattern diff = new Subtraction(s, a);
               
                return new Equality(diff, b).matches(expr);
            }

            @Override
            public Expression apply() {
                Equality eq = (Equality) target;
                Expression lhs = Sum.add(eq.lhs(), a.hit());
                Expression rhs = Sum.add(eq.rhs(), a.hit());

                return new Equality(lhs, rhs);
            }
        }
    }
   
    /**
     * Rule used to raise to square both sides of the equation.
     */
    private class Square extends SimpleRule {
       
        @Override
        public boolean matches(Expression expr) {
            target = expr;
           
            return expr.contains(new Sqrt(new FunctionPattern(x)));
        }

        @Override
        public Expression apply() {
            ANumber two = Naturals.getInstance().create(2);
            Equality eq = (Equality) target;
           
            return new Equality(new Exponentiation(eq.lhs(), two),
                    new Exponentiation(eq.rhs(), two));
        }
    }
   
    /**
     * This rule transforms the current equation into a linear equation.
     */
    private class ToLinearEquation extends SimpleRule implements EquationRule {
       
        @Override
        public boolean matches(Expression expr) {
            target = expr;
           
            return LinearEquation.isConvertible((Equality) expr, x);
        }

        @Override
        public Expression apply() {
            throw new UnsupportedOperationException("Call convertedEquations() instead!");
        }

        @Override
        public List<Equation> convertedEquations() {
            List<Equation> equations = new ArrayList();
            Equality eq = (Equality) target;
           
            equations.add(new LinearEquation(eq, x));
           
            return equations;
        }
    }
   
    /**
     * This rule transforms the current equation into a quadratic equation.
     */
    private class ToQuadraticEquation extends SimpleRule implements EquationRule {
       
        @Override
        public boolean matches(Expression expr) {
            target = expr;
           
            return QuadraticEquation.isConvertible(expr, x);
        }

        @Override
        public Expression apply() {
            throw new UnsupportedOperationException("Call convertedEquations() instead!");
        }

        @Override
        public List<Equation> convertedEquations() {
            List<Equation> equations = new ArrayList();
            Equality eq = (Equality) target;
           
            equations.add(new QuadraticEquation(eq, x));
           
            return equations;
        }
    }
}
TOP

Related Classes of jmathexpr.arithmetic.equation.RadicalEquation$SeparateRadicals$SqrtSubtract

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.