/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jmathexpr.arithmetic.func;
import jmathexpr.Expression;
import jmathexpr.arithmetic.ANumber;
import jmathexpr.arithmetic.integer.IntegerNumber;
import jmathexpr.arithmetic.natural.NaturalNumber;
import jmathexpr.arithmetic.natural.Naturals;
import jmathexpr.arithmetic.op.Addition;
import jmathexpr.arithmetic.op.Division;
import jmathexpr.arithmetic.op.Multiplication;
import jmathexpr.arithmetic.rational.RationalNumber;
/**
* The square root (sqrt) function.
*
* @author Elemér Furka
*/
public class Sqrt extends UnivariateNumberFunction {
public Sqrt(Expression arg) {
super("sqrt", arg);
}
@Override
public Expression evaluate() {
Expression x = arg.evaluate();
if (x instanceof ANumber) {
ANumber a = (ANumber) x;
if (a instanceof NaturalNumber) {
return Naturals.sqrt((NaturalNumber) a);
} else if (!a.isNegative()) {
if (a instanceof IntegerNumber) {
return Naturals.sqrt(a.toNatural());
} else if (a instanceof RationalNumber) {
return sqrt((RationalNumber) a);
}
}
} else if (x instanceof Multiplication) {
Expression e = sqrt((Multiplication) x);
if (e instanceof Multiplication) {
return e;
}
} else if (x instanceof Addition) {
Expression factorized = ((Addition) x).factorize();
if (factorized instanceof Multiplication) {
Expression e = sqrt((Multiplication) factorized);
if (e instanceof Multiplication) {
return e;
}
}
}
return new Sqrt(x);
}
private Expression sqrt(Multiplication product) {
Expression l = new Sqrt(product.lhs()).evaluate();
Expression r = new Sqrt(product.rhs()).evaluate();
if (!(l instanceof Sqrt && r instanceof Sqrt)) {
return new Multiplication(l, r).evaluate();
} else {
return new Sqrt(product);
}
}
private Expression sqrt(RationalNumber r) {
Expression sqrtn = Naturals.sqrt(r.numerator().toNatural());
Expression sqrtd = Naturals.sqrt(r.denominator());
if (sqrtn instanceof NaturalNumber || sqrtd instanceof NaturalNumber) {
return new Division(sqrtn, sqrtd).evaluate();
} else {
return new Sqrt(r);
}
}
@Override
protected UnivariateNumberFunction create(Expression arg) {
return new Sqrt(arg);
}
}