new plotter

This commit is contained in:
Sergey Solovyev
2013-01-18 20:56:58 +04:00
parent 93c5e2a093
commit b60b576433
13 changed files with 240 additions and 659 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}