diff --git a/android-app/pom.xml b/android-app/pom.xml
index b9dc5dae..c1b41ec5 100644
--- a/android-app/pom.xml
+++ b/android-app/pom.xml
@@ -105,20 +105,6 @@
simple-xml
-
- achartengine
- achartengine
- 0.7.1
-
-
-
- arity
- arity
- 2.1.6
- system
- ${project.basedir}/misc/lib/arity-2.1.6.jar
-
-
admob
admob
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java
index 3582ba34..6d6990c8 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/AbstractCalculatorPlotFragment.java
@@ -12,7 +12,6 @@ import android.view.View;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
-import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.AndroidUtils2;
@@ -400,13 +399,6 @@ public abstract class AbstractCalculatorPlotFragment extends CalculatorFragment
this.yMax = yMax;
}
- public PlotBoundaries(@NotNull XYMultipleSeriesRenderer renderer) {
- this.xMin = renderer.getXAxisMin();
- this.yMin = renderer.getYAxisMin();
- this.xMax = renderer.getXAxisMax();
- this.yMax = renderer.getYAxisMax();
- }
-
@NotNull
public static PlotBoundaries newInstance(double xMin, double xMax, double yMin, double yMax) {
return new PlotBoundaries(xMin, xMax, yMin, yMax);
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java
index 35d0c695..cdafcef8 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorGraph2dView.java
@@ -1,5 +1,3 @@
-// Copyright (C) 2009-2010 Mihai Preda
-
package org.solovyev.android.calculator.plot;
@@ -10,7 +8,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;
import android.widget.ZoomButtonsController;
-import org.javia.arity.Function;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
@@ -151,19 +148,19 @@ public class CalculatorGraph2dView extends View implements GraphView {
@Override
public void init(@NotNull FunctionViewDef functionViewDef) {
- this.graphViewHelper = GraphViewHelper.newInstance(functionViewDef, Collections.emptyList());
+ this.graphViewHelper = GraphViewHelper.newInstance(functionViewDef, Collections.emptyList());
}
- public void setFunctionPlotDefs(@NotNull List functionPlotDefs) {
+ public void setPlotFunctions(@NotNull List plotFunctions) {
- for (ArityPlotFunction functionPlotDef : functionPlotDefs) {
- final int arity = functionPlotDef.getFunction().arity();
+ for (PlotFunction plotFunction : plotFunctions) {
+ final int arity = plotFunction.getXyFunction().getArity();
if (arity != 0 && arity != 1) {
throw new IllegalArgumentException("Function must have arity 0 or 1 for 2d plot!");
}
}
- this.graphViewHelper = this.graphViewHelper.copy(functionPlotDefs);
+ this.graphViewHelper = this.graphViewHelper.copy(plotFunctions);
clearAllGraphs();
invalidate();
}
@@ -200,10 +197,6 @@ public class CalculatorGraph2dView extends View implements GraphView {
drawGraph(canvas);
}
- private float eval(Function f, float x) {
- return (float) f.eval(x);
- }
-
// distance from (x,y) to the line (x1,y1) to (x2,y2), squared, multiplied by 4
/*
private float distance(float x1, float y1, float x2, float y2, float x, float y) {
@@ -224,14 +217,14 @@ public class CalculatorGraph2dView extends View implements GraphView {
return up * up / (dx * dx + dy * dy);
}
- private void computeGraph(@NotNull Function function,
+ private void computeGraph(@NotNull XyFunction f,
float xMin,
float xMax,
float yMin,
float yMax,
@NotNull GraphData graph) {
- if (function.arity() == 0) {
- final float v = (float) function.eval();
+ if (f.getArity() == 0) {
+ final float v = (float) f.eval();
graph.clear();
graph.push(xMin, v);
graph.push(xMax, v);
@@ -249,7 +242,7 @@ public class CalculatorGraph2dView extends View implements GraphView {
}
}
if (graph.empty()) {
- graph.push(xMin, eval(function, xMin));
+ graph.push(xMin, (float)f.eval(xMin));
}
final float ratio = getRatio();
@@ -270,7 +263,7 @@ public class CalculatorGraph2dView extends View implements GraphView {
}
if (next.empty()) {
float x = leftX + maxStep;
- next.push(x, eval(function, x));
+ next.push(x, (float) f.eval(x));
++nEval;
}
rightX = next.topX();
@@ -283,7 +276,7 @@ public class CalculatorGraph2dView extends View implements GraphView {
float dx = rightX - leftX;
float middleX = (leftX + rightX) / 2;
- float middleY = eval(function, middleX);
+ float middleY = (float) f.eval(middleX);
++nEval;
boolean middleIsOutside = (middleY < leftY && middleY < rightY) || (leftY < middleY && rightY < middleY);
if (dx < minStep) {
@@ -482,20 +475,20 @@ public class CalculatorGraph2dView extends View implements GraphView {
{
//GRAPH
- final List functionPlotDefs = graphViewHelper.getFunctionPlotDefs();
+ final List functionPlotDefs = graphViewHelper.getFunctionPlotDefs();
// create path once
final Path path = new Path();
for (int i = 0; i < functionPlotDefs.size(); i++) {
- final ArityPlotFunction fpd = functionPlotDefs.get(i);
- computeGraph(fpd.getFunction(), xMin, xMax, lastYMin, lastYMax, graphs.get(i));
+ final PlotFunction fpd = functionPlotDefs.get(i);
+ computeGraph(fpd.getXyFunction(), xMin, xMax, lastYMin, lastYMax, graphs.get(i));
graphToPath(graphs.get(i), path);
path.transform(matrix);
- AbstractCalculatorPlotFragment.applyToPaint(fpd.getLineDef(), paint);
+ AbstractCalculatorPlotFragment.applyToPaint(fpd.getPlotLineDef(), paint);
canvas.drawPath(path, paint);
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java
index 7ebde5ab..fad8ec6b 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/CalculatorPlotFragment.java
@@ -4,16 +4,10 @@ import android.graphics.Bitmap;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
-import jscl.math.Generic;
-import jscl.math.function.Constant;
-import org.javia.arity.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* User: serso
* Date: 12/30/12
@@ -44,28 +38,6 @@ public class CalculatorPlotFragment extends AbstractCalculatorPlotFragment {
graphContainer.removeView((View) graphView);
}
- final List arityFunctions = new ArrayList();
-
- for (PlotFunction plotFunction : plotData.getFunctions()) {
-
- final XyFunction xyFunction = plotFunction.getXyFunction();
-
- final Generic expression = xyFunction.getExpression();
- final Constant xVariable = xyFunction.getXVariable();
- final Constant yVariable = xyFunction.getYVariable();
-
- final int arity = xyFunction.getArity();
-
- final Function arityFunction;
- if (xyFunction.isImag()) {
- arityFunction = new ImaginaryArityFunction(arity, expression, xVariable, yVariable);
- } else {
- arityFunction = new RealArityFunction(arity, expression, xVariable, yVariable);
- }
-
- arityFunctions.add(ArityPlotFunction.newInstance(arityFunction, plotFunction.getPlotLineDef()));
- }
-
if ( plotData.isPlot3d() ) {
graphView = new Graph3dView(getActivity());
} else {
@@ -74,7 +46,7 @@ public class CalculatorPlotFragment extends AbstractCalculatorPlotFragment {
graphView.init(FunctionViewDef.newInstance(Color.WHITE, Color.WHITE, Color.DKGRAY, getBgColor()));
//graphView.setXRange((float)plotBoundaries.getXMin(), (float)plotBoundaries.getXMax());
- graphView.setFunctionPlotDefs(arityFunctions);
+ graphView.setPlotFunctions(plotData.getFunctions());
graphContainer.addView((View) graphView);
}
@@ -135,96 +107,4 @@ public class CalculatorPlotFragment extends AbstractCalculatorPlotFragment {
**********************************************************************
*/
- private static abstract class AbstractArityFunction extends Function {
-
- protected final int arity;
-
- @NotNull
- protected final Generic expression;
-
- @Nullable
- protected final Constant xVariable;
-
- @Nullable
- protected final Constant yVariable;
-
- @Nullable
- private Double constant = null;
-
- public AbstractArityFunction(int arity,
- @NotNull Generic expression,
- @Nullable Constant xVariable,
- @Nullable Constant yVariable) {
- this.arity = arity;
- this.expression = expression;
- this.xVariable = xVariable;
- this.yVariable = yVariable;
- }
-
- @Override
- public final double eval() {
- if (constant == null) {
- constant = eval0();
- }
- return constant;
- }
-
- protected abstract double eval0();
-
- @Override
- public final int arity() {
- return arity;
- }
-
- }
-
- private static class RealArityFunction extends AbstractArityFunction {
-
- private RealArityFunction(int arity,
- @NotNull Generic expression,
- @Nullable Constant xVariable,
- @Nullable Constant yVariable) {
- super(arity, expression, xVariable, yVariable);
- }
-
- @Override
- public double eval0() {
- return PlotUtils.calculatorExpression(expression).realPart();
- }
-
- @Override
- public double eval(double x) {
- return PlotUtils.calculatorExpression(expression, xVariable, x).realPart();
- }
-
- @Override
- public double eval(double x, double y) {
- return PlotUtils.calculatorExpression(expression, xVariable, x, yVariable, y).realPart();
- }
- }
-
- private static class ImaginaryArityFunction extends AbstractArityFunction {
-
- private ImaginaryArityFunction(int arity,
- @NotNull Generic expression,
- @Nullable Constant xVariable,
- @Nullable Constant yVariable) {
- super(arity, expression, xVariable, yVariable);
- }
-
- @Override
- public double eval0() {
- return PlotUtils.calculatorExpression(expression).imaginaryPart();
- }
-
- @Override
- public double eval(double x) {
- return PlotUtils.calculatorExpression(expression, xVariable, x).imaginaryPart();
- }
-
- @Override
- public double eval(double x, double y) {
- return PlotUtils.calculatorExpression(expression, xVariable, x, yVariable, y).imaginaryPart();
- }
- }
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3d.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3d.java
index 1de16160..2f2ae959 100755
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3d.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3d.java
@@ -3,7 +3,6 @@
package org.solovyev.android.calculator.plot;
import android.graphics.Color;
-import org.javia.arity.Function;
import org.jetbrains.annotations.NotNull;
import javax.microedition.khronos.opengles.GL10;
@@ -92,9 +91,9 @@ class Graph3d {
return bb;
}
- public void update(@NotNull GL11 gl, @NotNull ArityPlotFunction fpd, float zoom) {
- final Function function = fpd.getFunction();
- final PlotLineDef lineDef = fpd.getLineDef();
+ public void update(@NotNull GL11 gl, @NotNull PlotFunction fpd, float zoom) {
+ final XyFunction function = fpd.getXyFunction();
+ final PlotLineDef lineDef = fpd.getPlotLineDef();
final int NTICK = useHighQuality3d ? 5 : 0;
final float size = 4 * zoom;
@@ -230,8 +229,8 @@ class Graph3d {
}
}
- private float fillFunctionPolygonVertices(Function function, float size, float[] vertices) {
- final int arity = function.arity();
+ private float fillFunctionPolygonVertices(XyFunction function, float size, float[] vertices) {
+ final int arity = function.getArity();
final float minX = -size;
final float maxX = size;
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3dView.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3dView.java
index b27b6179..644718bf 100755
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3dView.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/Graph3dView.java
@@ -174,18 +174,19 @@ public class Graph3dView extends GLView implements GraphView {
@Override
public void init(@NotNull FunctionViewDef functionViewDef) {
- this.graphViewHelper = GraphViewHelper.newInstance(functionViewDef, Collections.emptyList());
+ this.graphViewHelper = GraphViewHelper.newInstance(functionViewDef, Collections.emptyList());
}
- public void setFunctionPlotDefs(@NotNull List functionPlotDefs) {
- for (ArityPlotFunction functionPlotDef: functionPlotDefs) {
- final int arity = functionPlotDef.getFunction().arity();
+ @Override
+ public void setPlotFunctions(@NotNull List plotFunctions) {
+ for (PlotFunction plotFunction: plotFunctions) {
+ final int arity = plotFunction.getXyFunction().getArity();
if (arity != 0 && arity != 1 && arity != 2) {
throw new IllegalArgumentException("Function must have arity 0 or 1 or 2 for 3d plot!");
}
}
- this.graphViewHelper = this.graphViewHelper.copy(functionPlotDefs);
+ this.graphViewHelper = this.graphViewHelper.copy(plotFunctions);
zoomLevel = 1;
isDirty = true;
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphView.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphView.java
index d9aab0a7..48bc640d 100755
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphView.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphView.java
@@ -12,7 +12,7 @@ public interface GraphView extends ZoomButtonsController.OnZoomListener, TouchHa
public void init(@NotNull FunctionViewDef functionViewDef);
- public void setFunctionPlotDefs(@NotNull List functionPlotDefs);
+ public void setPlotFunctions(@NotNull List plotFunctions);
public void onPause();
public void onResume();
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphViewHelper.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphViewHelper.java
index 7a5bb33c..a6daadb6 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphViewHelper.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/plot/GraphViewHelper.java
@@ -16,7 +16,7 @@ public class GraphViewHelper {
private FunctionViewDef functionViewDef = FunctionViewDef.newDefaultInstance();
@NotNull
- private List functionPlotDefs = Collections.emptyList();
+ private List functionPlotDefs = Collections.emptyList();
private GraphViewHelper() {
}
@@ -28,27 +28,27 @@ public class GraphViewHelper {
@NotNull
public static GraphViewHelper newInstance(@NotNull FunctionViewDef functionViewDef,
- @NotNull List functionPlotDefs) {
+ @NotNull List plotFunctions) {
final GraphViewHelper result = new GraphViewHelper();
result.functionViewDef = functionViewDef;
- result.functionPlotDefs = Collections.unmodifiableList(functionPlotDefs);
+ result.functionPlotDefs = Collections.unmodifiableList(plotFunctions);
return result;
}
@NotNull
- public GraphViewHelper copy(@NotNull List newFunctionPlotDefs) {
+ public GraphViewHelper copy(@NotNull List plotFunctions) {
final GraphViewHelper result = new GraphViewHelper();
result.functionViewDef = functionViewDef;
- result.functionPlotDefs = Collections.unmodifiableList(newFunctionPlotDefs);
+ result.functionPlotDefs = Collections.unmodifiableList(plotFunctions);
return result;
}
@NotNull
- public List getFunctionPlotDefs() {
+ public List getFunctionPlotDefs() {
return functionPlotDefs;
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java b/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java
deleted file mode 100644
index 96ec1292..00000000
--- a/android-app/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * 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.achartengine.chart.CubicLineChart;
-import org.achartengine.chart.PointStyle;
-import org.achartengine.chart.ScatterChart;
-import org.achartengine.chart.XYChart;
-import org.achartengine.model.XYMultipleSeriesDataset;
-import org.achartengine.renderer.BasicStroke;
-import org.achartengine.renderer.XYMultipleSeriesRenderer;
-import org.achartengine.renderer.XYSeriesRenderer;
-import org.achartengine.util.MathHelper;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.solovyev.android.calculator.Locator;
-import org.solovyev.android.calculator.R;
-import org.solovyev.common.msg.MessageType;
-import org.solovyev.common.text.StringUtils;
-
-import java.util.Arrays;
-
-/**
- * User: serso
- * Date: 12/5/11
- * Time: 8:58 PM
- */
-public final class PlotUtils {
-
- private static final double MAX_Y_DIFF = 1;
- private static final double MAX_X_DIFF = 1;
- static final int DEFAULT_NUMBER_OF_STEPS = 100;
-
- // not intended for instantiation
- private PlotUtils() {
- throw new AssertionError();
- }
-
- public static boolean addXY(double minValue,
- double maxValue,
- @NotNull Generic expression,
- @Nullable Constant variable,
- @NotNull MyXYSeries realSeries,
- @Nullable MyXYSeries imagSeries,
- boolean addExtra,
- int numberOfSteps) {
-
- boolean imagExists = false;
-
- double min = Math.min(minValue, maxValue);
- double max = Math.max(minValue, maxValue);
- double dist = max - min;
- if (addExtra) {
- min = min - dist;
- max = max + dist;
- }
-
- final double eps = 0.000000001;
-
- final double defaultStep = Math.max(dist / numberOfSteps, eps);
- double step = defaultStep;
-
- final Point real = new Point();
- final Point imag = new Point();
-
- double x = min;
-
- while (x <= max) {
-
- boolean needToCalculateRealY = realSeries.needToAdd(step, x);
-
- if (needToCalculateRealY) {
- final Complex c = variable == null ? calculatorExpression(expression) : calculatorExpression(expression, variable, x);
- Double y = prepareY(c.realPart());
-
- if (y != null) {
- real.moveToNextPoint(x, y);
- addSingularityPoint(realSeries, real);
- realSeries.add(x, y);
- }
-
- boolean needToCalculateImagY = imagSeries != null && imagSeries.needToAdd(step, x);
- if (needToCalculateImagY) {
- y = prepareY(c.imaginaryPart());
- if (y != null) {
- imag.moveToNextPoint(x, y);
- addSingularityPoint(imagSeries, imag);
- imagSeries.add(x, y);
- }
- if (c.imaginaryPart() != 0d) {
- imagExists = true;
- }
- }
- } else {
- boolean needToCalculateImagY = imagSeries != null && imagSeries.needToAdd(step, x);
- if (needToCalculateImagY) {
- final Complex c = variable == null ? calculatorExpression(expression) : calculatorExpression(expression, variable, x);
- Double y = prepareY(c.imaginaryPart());
- if (y != null) {
- imag.moveToNextPoint(x, y);
- addSingularityPoint(imagSeries, imag);
- imagSeries.add(x, y);
- }
- if (c.imaginaryPart() != 0d) {
- imagExists = true;
- }
- }
- }
-
- step = updateStep(real, step, defaultStep / 2);
-
- x += step;
- }
-
- return imagExists;
- }
-
- @NotNull
- static String getImagFunctionName(@Nullable Constant variable) {
- if (variable != null) {
- return "g(" + variable.getName() + ")" + " = " + "Im(ƒ(" + variable.getName() + "))";
- } else {
- return "g = Im(ƒ)";
- }
- }
-
- @NotNull
- private static String getRealFunctionName(@NotNull Generic expression, @Nullable Constant variable) {
- if (variable != null) {
- return "ƒ(" + variable.getName() + ")" + " = " + expression.toString();
- } else {
- return "ƒ = " + expression.toString();
- }
- }
-
- @NotNull
- static XYChart prepareChart(final double minValue,
- final double maxValue,
- @NotNull final Generic expression,
- @Nullable final Constant variable,
- int bgColor,
- boolean interpolate,
- int realLineColor,
- int imagLineColor) {
- final MyXYSeries realSeries = new MyXYSeries(getRealFunctionName(expression, variable), DEFAULT_NUMBER_OF_STEPS * 2);
- final MyXYSeries imagSeries = new MyXYSeries(getImagFunctionName(variable), DEFAULT_NUMBER_OF_STEPS * 2);
-
- boolean imagExists = addXY(minValue, maxValue, expression, variable, realSeries, imagSeries, false, DEFAULT_NUMBER_OF_STEPS);
-
- final XYMultipleSeriesDataset data = new XYMultipleSeriesDataset();
- data.addSeries(realSeries);
- if (imagExists) {
- data.addSeries(imagSeries);
- }
-
- final XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
- renderer.setShowGrid(true);
- renderer.setXTitle(variable != null ? variable.getName() : null);
- if (variable != null) {
- renderer.setYTitle("f(" + variable.getName() + ")");
- } else {
- renderer.setYTitle("f");
- }
- renderer.setChartTitleTextSize(25);
- renderer.setAxisTitleTextSize(25);
- renderer.setLabelsTextSize(25);
- renderer.setLegendTextSize(25);
- renderer.setMargins(new int[]{25, 25, 25, 25});
- renderer.setApplyBackgroundColor(true);
- renderer.setBackgroundColor(bgColor);
- renderer.setMarginsColor(bgColor);
-
- renderer.setZoomEnabled(true);
- renderer.setZoomButtonsVisible(true);
-
- renderer.addSeriesRenderer(createCommonRenderer(realLineColor));
- if (imagExists) {
- renderer.addSeriesRenderer(createImagRenderer(imagLineColor));
- }
-
- if (interpolate) {
- return new CubicLineChart(data, renderer, 0.1f);
- } else {
- return new ScatterChart(data, renderer);
- }
- }
-
- static XYSeriesRenderer createImagRenderer(int color) {
- final XYSeriesRenderer imagRenderer = createCommonRenderer(color);
- imagRenderer.setStroke(BasicStroke.DASHED);
- return imagRenderer;
- }
-
- @NotNull
- private static XYSeriesRenderer createCommonRenderer(int color) {
- final XYSeriesRenderer renderer = new XYSeriesRenderer();
- renderer.setFillPoints(true);
- renderer.setPointStyle(PointStyle.CIRCLE);
- renderer.setLineWidth(3);
- renderer.setColor(color);
- renderer.setStroke(BasicStroke.SOLID);
- return renderer;
- }
-
- static void handleArithmeticException(@NotNull ArithmeticException e, @NotNull AbstractCalculatorPlotFragment calculatorPlotFragment) {
- String message = e.getLocalizedMessage();
- if (StringUtils.isEmpty(message)) {
- message = e.getMessage();
- }
- Locator.getInstance().getNotifier().showMessage(R.string.arithmetic_error_while_plot, MessageType.error, Arrays.asList(message));
- calculatorPlotFragment.onError();
- }
-
- private static class Point {
- private static final double DEFAULT = Double.MIN_VALUE;
-
- private double x0 = DEFAULT;
- private double x1 = DEFAULT;
- private double x2 = DEFAULT;
-
- private double y0 = DEFAULT;
- private double y1 = DEFAULT;
- private double y2 = DEFAULT;
-
- private Point() {
- }
-
- public void moveToNextPoint(double x, double y) {
- if ( this.x2 == x ) {
- return;
- }
-
- this.x0 = this.x1;
- this.x1 = this.x2;
- this.x2 = x;
-
- this.y0 = this.y1;
- this.y1 = this.y2;
- this.y2 = y;
- }
-
- public boolean isFullyDefined() {
- return x0 != DEFAULT && x1 != DEFAULT && x2 != DEFAULT && y0 != DEFAULT && y1 != DEFAULT && y2 != DEFAULT;
- }
-
- public double getDx2() {
- return x2 - x1;
- }
-
- public double getAbsDx2() {
- if ( x2 > x1 ) {
- return Math.abs(x2 - x1);
- } else {
- return Math.abs(x1 - x2);
- }
- }
-
- public double getAbsDx1() {
- if ( x1 > x0 ) {
- return Math.abs(x1 - x0);
- } else {
- return Math.abs(x0 - x1);
- }
- }
-
- public double getAbsDy1() {
- if ( y1 > y0 ) {
- return Math.abs(y1 - y0);
- } else {
- return Math.abs(y0 - y1);
- }
- }
-
- public double getAbsDy2() {
- if ( y2 > y1 ) {
- return Math.abs(y2 - y1);
- } else {
- return Math.abs(y1 - y2);
- }
- }
-
- public double getX0() {
- return x0;
- }
-
- public double getX1() {
- return x1;
- }
-
- public double getX2() {
- return x2;
- }
-
- public boolean isX2Defined() {
- return x2 != DEFAULT;
- }
-
- public double getY0() {
- return y0;
- }
-
- public double getY1() {
- return y1;
- }
-
- public double getY2() {
- return y2;
- }
-
- public void clearHistory () {
- this.x0 = DEFAULT;
- this.x1 = DEFAULT;
- this.y0 = DEFAULT;
- this.y1 = DEFAULT;
- }
-
- public double getAbsDyDx2() {
- double dx2 = this.getAbsDx2();
- double dy2 = this.getAbsDy2();
- return dy2 / dx2;
- }
-
- public double getAbsDyDx1() {
- double dx1 = this.getAbsDx1();
- double dy1 = this.getAbsDy1();
- return dy1 / dx1;
- }
-
- public double getDyDx1() {
- double result = getAbsDyDx1();
- return y1 > y0 ? result : -result;
- }
-
- public double getDyDx2() {
- double result = getAbsDyDx2();
- return y2 > y1 ? result : -result;
- }
-
- @Override
- public String toString() {
- return "Point{" +
- "x0=" + x0 +
- ", x1=" + x1 +
- ", x2=" + x2 +
- ", y0=" + y0 +
- ", y1=" + y1 +
- ", y2=" + y2 +
- '}';
- }
- }
-
- private static double updateStep(@NotNull Point real,
- double step,
- double eps) {
- if ( !real.isFullyDefined() ) {
- return step;
- } else {
- double dydx2 = real.getAbsDyDx2();
- double dydx1 = real.getAbsDyDx1();
-
- double k = dydx2 / dydx1;
-
- if ( k > 1 ) {
- step = step / k;
- } else if ( k > 0 ) {
- step = step * k;
- }
-
- return Math.max(step, eps);
- }
- }
-
- @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;
- }
- }
-
- public static void addSingularityPoint(@NotNull MyXYSeries series,
- @NotNull Point point) {
- if (point.isFullyDefined()) {
- // y or prevY should be more than 1d because if they are too small false singularity may occur (e.g., 1/0.000000000000000001)
- // double dy0 = y1 - y0;
- // double dx0 = x1 - x0;
- // double dydx0 = dy0 / dx0;
-
- double dy2 = point.getAbsDy2();
- double dx2 = point.getAbsDx2();
- //double dx1 = x2 - x1;
- // double dydx1 = dy2 / dx1;
-
- if ( dy2 > MAX_Y_DIFF && dx2 < MAX_X_DIFF && isDifferentSign(point.getY2(), point.getY1()) && isDifferentSign(point.getDyDx1(), point.getDyDx2())) {
- //Log.d(CalculatorPlotActivity.class.getName(), "Singularity: " + point);
- //Log.d(CalculatorPlotActivity.class.getName(), String.valueOf(prevX + Math.abs(x - prevX) / 2) + ", null");
- series.add(point.getX1() + point.getAbsDx2() / 2, MathHelper.NULL_VALUE);
- point.clearHistory();
- }
- }
- }
-
- private static boolean isDifferentSign(@NotNull Double y0, @NotNull Double y1) {
- return (y0 >= 0 && y1 < 0) || (y1 >= 0 && y0 < 0);
- }
-
- @Nullable
- public static Double prepareY(double y) {
- if (Double.isNaN(y)) {
- return null;
- } else {
- return y;
- }
- }
-
- 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();
- }
- }
-}
diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/FunctionEvaluator.java b/core/src/main/java/org/solovyev/android/calculator/plot/FunctionEvaluator.java
new file mode 100644
index 00000000..ee825472
--- /dev/null
+++ b/core/src/main/java/org/solovyev/android/calculator/plot/FunctionEvaluator.java
@@ -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);
+}
diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/PlotData.java b/core/src/main/java/org/solovyev/android/calculator/plot/PlotData.java
index 2ec8c187..82ce8797 100644
--- a/core/src/main/java/org/solovyev/android/calculator/plot/PlotData.java
+++ b/core/src/main/java/org/solovyev/android/calculator/plot/PlotData.java
@@ -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 functions;
private boolean plot3d;
- public PlotData(List functions, boolean plot3d) {
+ public PlotData(@NotNull List functions, boolean plot3d) {
this.functions = functions;
this.plot3d = plot3d;
}
+ @NotNull
public List getFunctions() {
return functions;
}
diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java b/core/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java
new file mode 100644
index 00000000..62a453cd
--- /dev/null
+++ b/core/src/main/java/org/solovyev/android/calculator/plot/PlotUtils.java
@@ -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();
+ }
+ }
+}
diff --git a/core/src/main/java/org/solovyev/android/calculator/plot/XyFunction.java b/core/src/main/java/org/solovyev/android/calculator/plot/XyFunction.java
index b66f99d9..a2916602 100644
--- a/core/src/main/java/org/solovyev/android/calculator/plot/XyFunction.java
+++ b/core/src/main/java/org/solovyev/android/calculator/plot/XyFunction.java
@@ -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();
+ }
+ }
}