Package trigonometry

Source Code of trigonometry.TrigonometryPlugin

package trigonometry;

import java.util.ArrayList;

import lipstone.joshua.parser.exceptions.ParserException;
import lipstone.joshua.parser.exceptions.PluginConflictException;
import lipstone.joshua.parser.exceptions.UndefinedResultException;
import lipstone.joshua.parser.plugin.ParserPlugin;
import lipstone.joshua.parser.plugin.helpdata.Operation;
import lipstone.joshua.parser.plugin.helpdata.Parameter;
import lipstone.joshua.parser.plugin.types.OperationPlugin;
import lipstone.joshua.parser.types.BigDec;
import lipstone.joshua.parser.util.ConsCell;
import lipstone.joshua.parser.util.ConsType;

import org.apfloat.ApcomplexMath;

public class TrigonometryPlugin extends ParserPlugin implements OperationPlugin {
  String[] angleInput = {"sin", "cos", "tan", "sec", "csc", "cot"}, angleOutput = {"arcsin", "arccos", "arctan", "arcsec", "arccsc", "arccot"};
 
  @Override
  public ConsCell runOperation(String operation, ConsCell input) throws ParserException {
    BigDec output = null;
    ConsCell value = parser.run(input);
    if (value.length() != 1 || value.getCarType() != ConsType.NUMBER)
      throw new UndefinedResultException("The " + operation + " operation takes one decimal number for its arguments.", this);
    BigDec inp = (BigDec) value.getCar();
   
    //Special points (e.g. angles at which sin, cos, etc. have exact answers
    if (operation.equals("cos") && ((parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(180.0)).eq(new BigDec(90.0)))
        || (parser.getAngleType().equals("Radians") && inp.mod(new BigDec(Math.PI)).eq(new BigDec(Math.PI / 2))) || (parser.getAngleType().equals("Grads") && inp.mod(new BigDec(200.0)).eq(new BigDec(100.0))))) {
      return new ConsCell(BigDec.ZERO, ConsType.NUMBER);
    }
    if ((operation.equals("sin") || operation.equals("tan")) && ((parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(180.0)).eq(new BigDec(0.0)))
        || (parser.getAngleType().equals("Radians") && inp.mod(new BigDec(Math.PI)).eq(BigDec.ZERO)) || (parser.getAngleType().equals("Grads") && inp.mod(new BigDec(200.0)).eq(BigDec.ZERO)))) {
      return new ConsCell(BigDec.ZERO, ConsType.NUMBER);
    }
    if (operation.equals("sin") && (parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(360.0)).eq(new BigDec(30.0)) ||
        parser.getAngleType().equals("Radians") && inp.eq(new BigDec(Math.PI / 6)) || parser.getAngleType().equals("Grads") && inp.mod(new BigDec(400.0)).eq(new BigDec(33.333333)))) {
      return new ConsCell(new BigDec(0.5), ConsType.NUMBER);
    }
    if (operation.equals("cos") && (parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(360.0)).eq(new BigDec(60.0)) ||
        parser.getAngleType().equals("Radians") && inp.eq(new BigDec(Math.PI / 3)) || parser.getAngleType().equals("Grads") && inp.mod(new BigDec(400.0)).eq(new BigDec(66.666667)))) {
      return new ConsCell(new BigDec(0.5), ConsType.NUMBER);
    }
    if (operation.equals("sin") && (parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(360.0)).eq(new BigDec(210.0)) ||
        parser.getAngleType().equals("Radians") && inp.eq(new BigDec(2 * Math.PI / 3)) ||
        parser.getAngleType().equals("Grads") && inp.mod(new BigDec(400.0)).eq(new BigDec(233.333333)))) {
      return new ConsCell(new BigDec(-0.5), ConsType.NUMBER);
    }
    if (operation.equals("cos") && (parser.getAngleType().equals("Degrees") && inp.mod(new BigDec(360.0)).eq(new BigDec(240.0)) ||
        parser.getAngleType().equals("Radians") && inp.eq(new BigDec(4 * Math.PI / 3)) ||
        parser.getAngleType().equals("Grads") && inp.mod(new BigDec(400.0)).eq(new BigDec(266.666667)))) {
      return new ConsCell(new BigDec(-0.5), ConsType.NUMBER);
    }
    //End special points
   
    for (String str : angleInput)
      if (operation.equals(str)) {
        inp = parser.getAngleType().toRadians(inp);
        break;
      }
   
    if (((operation.equals("arcsin") || operation.equals("arccos")) && !(inp.gteq(new BigDec(-1.0)) && inp.lteq(new BigDec(1.0))))
        || ((operation.equals("arcsec") || operation.equals("arccsc")) && (inp.gteq(new BigDec(-1.0)) && inp.lteq(new BigDec(1.0))))
        || (operation.equals("arccosh") && (inp.lt(BigDec.ONE))) || (operation.equals("arctanh") && (inp.abs().gteq(BigDec.ONE)))
        || (operation.equals("arccoth") && (inp.abs().lteq(BigDec.ONE)))
        || (operation.equals("arcsech") && !(inp.gt(BigDec.ZERO) && inp.lteq(BigDec.ONE)))
        || (operation.equals("arccsch") && (inp.eq(BigDec.ZERO)))) {
      return new ConsCell(BigDec.ZERO, ConsType.NUMBER);
    }
   
    while ((operation.equals("sec") || operation.equals("csc") || operation.equals("cot")) && inp.lt(BigDec.ZERO))
      inp = inp.add(new BigDec(Math.PI * 2));
    while ((operation.equals("sec") || operation.equals("csc") || operation.equals("cot")) && inp.gt(new BigDec(Math.PI * 2)))
      inp = inp.subtract(new BigDec(Math.PI * 2));
   
    if (operation.equals("sin"))
      output = new BigDec(ApcomplexMath.sin(inp.getInternal()));
    if (operation.equals("cos"))
      output = new BigDec(ApcomplexMath.cos(inp.getInternal()));
    if (operation.equals("tan"))
      output = new BigDec(ApcomplexMath.tan(inp.getInternal()));
    if (operation.equals("sec"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.cos(inp.getInternal())));
    if (operation.equals("csc"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.sin(inp.getInternal())));
    if (operation.equals("cot"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.tan(inp.getInternal())));
    if (operation.equals("arcsin"))
      output = inp.eq(BigDec.ZERO) ? BigDec.ZERO : new BigDec(ApcomplexMath.asin(inp.getInternal()));
    if (operation.equals("arccos"))
      output = inp.eq(BigDec.ZERO) ? BigDec.ONE : new BigDec(ApcomplexMath.acos(inp.getInternal()));
    if (operation.equals("arctan"))
      output = inp.eq(BigDec.ZERO) ? BigDec.ZERO : new BigDec(ApcomplexMath.atan(inp.getInternal()));
    if (operation.equals("arcsec"))
      output = BigDec.ONE.divide(inp.eq(BigDec.ZERO) ? BigDec.ONE : new BigDec(ApcomplexMath.acos(inp.getInternal())));
    if (operation.equals("arccsc"))
      output = BigDec.ONE.divide(inp.eq(BigDec.ZERO) ? BigDec.ZERO : new BigDec(ApcomplexMath.asin(inp.getInternal())));
    if (operation.equals("arccot"))
      output = BigDec.ONE.divide(inp.eq(BigDec.ZERO) ? BigDec.ZERO : new BigDec(ApcomplexMath.atan(inp.getInternal())));
    if (operation.equals("sinh"))
      output = new BigDec(ApcomplexMath.sinh(inp.getInternal()));
    if (operation.equals("cosh"))
      output = new BigDec(ApcomplexMath.cosh(inp.getInternal()));
    if (operation.equals("tanh"))
      output = new BigDec(ApcomplexMath.tanh(inp.getInternal()));
    if (operation.equals("sech"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.cosh(inp.getInternal())));
    if (operation.equals("csch"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.sinh(inp.getInternal())));
    if (operation.equals("coth"))
      output = BigDec.ONE.divide(new BigDec(ApcomplexMath.tanh(inp.getInternal())));
    if (operation.equals("arcsinh"))
      return parser.run(new String("ln(x+(x^2+1)^(1/2))").replaceAll("x", "(" + inp.toString() + ")"));
    if (operation.equals("arccosh"))
      return parser.run(new String("ln(x+(x^2-1)^(1/2))").replaceAll("x", "(" + inp.toString() + ")"));
    if (operation.equals("arctanh"))
      return parser.run(new String("1/2*ln((1+x)/(1-x))").replaceAll("x", "(" + inp.toString() + ")"));
    if (operation.equals("arcsech"))
      return parser.run(new String("ln((1+(1-x^2)^(1/2))/x)").replaceAll("x", "(" + inp.toString() + ")"));
    if (operation.equals("arccsch"))
      return parser.run(new String("ln(1/x+((1+x^2)^(1/2))/(abs(x)))").replaceAll("x", "(" + inp.toString() + ")"));
    if (operation.equals("arccoth"))
      return parser.run(new String("1/2*ln((x+1)/(x-1))").replaceAll("x", "(" + inp.toString() + ")"));
   
    if (output == null//If the operation was not in this plugin
      return null;
   
    for (String str : angleOutput)
      if (operation.equals(str)) {
        output = parser.getAngleType().fromRadians(output);
        break;
      }
    return new ConsCell(output, ConsType.NUMBER);
  }
 
  @Override
  public void loadOperations() throws PluginConflictException {
    loadTrigFunctions();
    loadInverseTrigFunctions();
    loadHyperbolicTrigFunctions();
    loadInverseHyperbolicTrigFunctions();
  }
 
  private void loadTrigFunctions() throws PluginConflictException {
    Parameter x = new Parameter("x", "Any real number", false);
    ArrayList<Parameter> params = new ArrayList<Parameter>();
    params.add(x);
    addOperation(new Operation("sin", params, "the sine of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("cos", params, "the cosine of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("tan", params, "the tangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
   
    x = new Parameter("x", "Any real number except odd multiples of pi/2", false);
    params.set(0, x);
    addOperation(new Operation("sec", params, "the secant of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    x = new Parameter("x", "Any real number except multiples of pi", false);
    params.set(0, x);
    addOperation(new Operation("csc", params, "the cosecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("cot", params, "the cotangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
  }
 
  private void loadInverseTrigFunctions() throws PluginConflictException {
    Parameter x = new Parameter("x", "Any real number within (-???, -1)???(1, ???)", false);
    ArrayList<Parameter> params = new ArrayList<Parameter>();
    params.add(x);
    addOperation(new Operation("arcsin", params, "the arcsine of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"asin"}, this));
    addOperation(new Operation("arccos", params, "the arccosine of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acos"}, this));
    x = new Parameter("x", "Any real number", false);
    params.set(0, x);
    addOperation(new Operation("arctan", params, "the arctangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"atan"}, this));
   
    x = new Parameter("x", "Any real number within [-1, 1]", false);
    params.set(0, x);
    addOperation(new Operation("arcsec", params, "the arcsecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"asec"}, this));
    addOperation(new Operation("arccsc", params, "the arccosecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acsc"}, this));
    x = new Parameter("x", "Any real number", false);
    params.set(0, x);
    addOperation(new Operation("arccot", params, "the arccotangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acot"}, this));
  }
 
  private void loadHyperbolicTrigFunctions() throws PluginConflictException {
    Parameter x = new Parameter("x", "Any real number", false);
    ArrayList<Parameter> params = new ArrayList<Parameter>();
    params.add(x);
    addOperation(new Operation("sinh", params, "the hyperbolic sine of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("cosh", params, "the hyperbolic cosine of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("tanh", params, "the hyperbolic tangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
   
    addOperation(new Operation("sech", params, "the hyperbolic secant of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    addOperation(new Operation("csch", params, "the hyperbolic cosecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
    x = new Parameter("x", "Any real number except zero", false);
    params.set(0, x);
    addOperation(new Operation("coth", params, "the hyperbolic cotangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", this));
  }
 
  private void loadInverseHyperbolicTrigFunctions() throws PluginConflictException {
    Parameter x = new Parameter("x", "Any real number", false);
    ArrayList<Parameter> params = new ArrayList<Parameter>();
    params.add(x);
    addOperation(new Operation("arcsinh", params, "the hyperbolic arcsine of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"asinh"}, this));
    addOperation(new Operation("arccosh", params, "the hyperbolic arccosine of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acosh"}, this));
    x = new Parameter("x", "Any real number", false);
    params.set(0, x);
    addOperation(new Operation("arctanh", params, "the hyperbolic arctangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"atanh"}, this));
   
    x = new Parameter("x", "Any real number within [-1, 1]", false);
    params.set(0, x);
    addOperation(new Operation("arcsech", params, "the hyperbolic arcsecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"asech"}, this));
    addOperation(new Operation("arccsch", params, "the hyperbolic arccosecant of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acsch"}, this));
    x = new Parameter("x", "Any real number", false);
    params.set(0, x);
    addOperation(new Operation("arccoth", params, "the hyperbolic arccotangent of x.", "Use the angle type options to specify Degrees/Radians/Grads", new String[]{"acoth"}, this));
  }
 
  @Override
  public void unloadOperations() {/*Don't need to do anything here*/}
 
TOP

Related Classes of trigonometry.TrigonometryPlugin

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.