new plotter
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 1/18/13
|
||||
* Time: 7:44 PM
|
||||
*/
|
||||
interface FunctionEvaluator {
|
||||
int getArity();
|
||||
double eval();
|
||||
double eval(double x);
|
||||
double eval(double x, double y);
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -9,15 +11,17 @@ import java.util.List;
|
||||
*/
|
||||
public class PlotData {
|
||||
|
||||
@NotNull
|
||||
private List<PlotFunction> functions;
|
||||
|
||||
private boolean plot3d;
|
||||
|
||||
public PlotData(List<PlotFunction> functions, boolean plot3d) {
|
||||
public PlotData(@NotNull List<PlotFunction> functions, boolean plot3d) {
|
||||
this.functions = functions;
|
||||
this.plot3d = plot3d;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<PlotFunction> getFunctions() {
|
||||
return functions;
|
||||
}
|
||||
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||
* For more information, please, contact se.solovyev@gmail.com
|
||||
* or visit http://se.solovyev.org
|
||||
*/
|
||||
|
||||
package org.solovyev.android.calculator.plot;
|
||||
|
||||
import jscl.math.Expression;
|
||||
import jscl.math.Generic;
|
||||
import jscl.math.JsclInteger;
|
||||
import jscl.math.NumericWrapper;
|
||||
import jscl.math.function.Constant;
|
||||
import jscl.math.numeric.Complex;
|
||||
import jscl.math.numeric.Numeric;
|
||||
import jscl.math.numeric.Real;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 12/5/11
|
||||
* Time: 8:58 PM
|
||||
*/
|
||||
public final class PlotUtils {
|
||||
|
||||
// not intended for instantiation
|
||||
private PlotUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Complex calculatorExpression(@NotNull Generic expression) {
|
||||
try {
|
||||
return unwrap(expression.numeric());
|
||||
} catch (RuntimeException e) {
|
||||
return NaN;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Complex calculatorExpression(@NotNull Generic expression, @NotNull Constant xVar, double x) {
|
||||
try {
|
||||
return unwrap(expression.substitute(xVar, Expression.valueOf(x)).numeric());
|
||||
} catch (RuntimeException e) {
|
||||
return NaN;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Complex calculatorExpression(@NotNull Generic expression, @NotNull Constant xVar, double x, @NotNull Constant yVar, double y) {
|
||||
try {
|
||||
Generic tmp = expression.substitute(xVar, Expression.valueOf(x));
|
||||
tmp = tmp.substitute(yVar, Expression.valueOf(y));
|
||||
return unwrap(tmp.numeric());
|
||||
} catch (RuntimeException e) {
|
||||
return NaN;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Complex NaN = Complex.valueOf(Double.NaN, 0d);
|
||||
|
||||
@NotNull
|
||||
public static Complex unwrap(@Nullable Generic numeric) {
|
||||
if (numeric instanceof JsclInteger) {
|
||||
return Complex.valueOf(((JsclInteger) numeric).intValue(), 0d);
|
||||
} else if (numeric instanceof NumericWrapper) {
|
||||
return unwrap(((NumericWrapper) numeric).content());
|
||||
} else {
|
||||
return NaN;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Complex unwrap(@Nullable Numeric content) {
|
||||
if (content instanceof Real) {
|
||||
return Complex.valueOf(((Real) content).doubleValue(), 0d);
|
||||
} else if (content instanceof Complex) {
|
||||
return ((Complex) content);
|
||||
} else {
|
||||
throw new ArithmeticException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.common.text.StringUtils;
|
||||
|
||||
public class XyFunction {
|
||||
public class XyFunction implements FunctionEvaluator {
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
@@ -41,6 +41,9 @@ public class XyFunction {
|
||||
|
||||
private int arity;
|
||||
|
||||
@NotNull
|
||||
private final FunctionEvaluator evaluator;
|
||||
|
||||
public XyFunction(@NotNull Generic expression,
|
||||
@Nullable Constant xVariable,
|
||||
@Nullable Constant yVariable,
|
||||
@@ -52,8 +55,10 @@ public class XyFunction {
|
||||
|
||||
if (imag) {
|
||||
this.expressionString = "Im(" + expression.toString() + ")";
|
||||
this.evaluator = new ImaginaryEvaluator(this);
|
||||
} else {
|
||||
this.expressionString = expression.toString();
|
||||
this.evaluator = new RealEvaluator(this);
|
||||
}
|
||||
this.xVariableName = xVariable == null ? null : xVariable.getName();
|
||||
this.yVariableName = yVariable == null ? null : yVariable.getName();
|
||||
@@ -74,10 +79,26 @@ public class XyFunction {
|
||||
return imag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArity() {
|
||||
return arity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval() {
|
||||
return evaluator.eval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x) {
|
||||
return evaluator.eval(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x, double y) {
|
||||
return evaluator.eval(x, y);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Generic getExpression() {
|
||||
return expression;
|
||||
@@ -113,8 +134,7 @@ public class XyFunction {
|
||||
return yVariableName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof XyFunction)) return false;
|
||||
@@ -130,4 +150,85 @@ public class XyFunction {
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
*
|
||||
* STATIC
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
private static abstract class AbstractEvaluator implements FunctionEvaluator {
|
||||
|
||||
@NotNull
|
||||
protected final XyFunction xyFunction;
|
||||
|
||||
@Nullable
|
||||
private Double constant = null;
|
||||
|
||||
public AbstractEvaluator(@NotNull XyFunction xyFunction) {
|
||||
this.xyFunction = xyFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double eval() {
|
||||
if (constant == null) {
|
||||
constant = eval0();
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
|
||||
protected abstract double eval0();
|
||||
|
||||
@Override
|
||||
public final int getArity() {
|
||||
return xyFunction.getArity();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class RealEvaluator extends AbstractEvaluator {
|
||||
|
||||
private RealEvaluator(@NotNull XyFunction xyFunction) {
|
||||
super(xyFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval0() {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression).realPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x) {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression, xyFunction.xVariable, x).realPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x, double y) {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression, xyFunction.xVariable, x, xyFunction.yVariable, y).realPart();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ImaginaryEvaluator extends AbstractEvaluator {
|
||||
|
||||
private ImaginaryEvaluator(@NotNull XyFunction xyFunction) {
|
||||
super(xyFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval0() {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression).imaginaryPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x) {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression, xyFunction.xVariable, x).imaginaryPart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double x, double y) {
|
||||
return PlotUtils.calculatorExpression(xyFunction.expression, xyFunction.xVariable, x, xyFunction.yVariable, y).imaginaryPart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user