This commit is contained in:
serso 2016-02-25 17:45:28 +01:00
parent 828f9fa07b
commit 13f12d5d14
5 changed files with 78 additions and 120 deletions

View File

@ -22,8 +22,6 @@
package org.solovyev.android.calculator.functions; package org.solovyev.android.calculator.functions;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -59,9 +57,6 @@ import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
import org.solovyev.android.calculator.view.EditTextCompat; import org.solovyev.android.calculator.view.EditTextCompat;
import org.solovyev.common.math.MathRegistry; import org.solovyev.common.math.MathRegistry;
import butterknife.Bind;
import butterknife.ButterKnife;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -72,6 +67,11 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import butterknife.Bind;
import butterknife.ButterKnife;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID;
public abstract class BaseFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener { public abstract class BaseFunctionFragment extends BaseDialogFragment implements View.OnClickListener, View.OnFocusChangeListener, View.OnKeyListener {
protected static final String ARG_FUNCTION = "function"; protected static final String ARG_FUNCTION = "function";
@ -274,12 +274,6 @@ public abstract class BaseFunctionFragment extends BaseDialogFragment implements
} }
protected boolean validateName() { protected boolean validateName() {
final String name = nameView.getText().toString();
if (!Engine.isValidName(name)) {
setError(nameLabel, getString(R.string.function_name_is_not_valid));
return false;
}
clearError(nameLabel);
return true; return true;
} }

View File

@ -12,14 +12,15 @@ import android.support.v7.app.AlertDialog;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.entities.EntityRemovalDialog; import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import jscl.math.function.Function;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import jscl.math.function.Function;
public class EditFunctionFragment extends BaseFunctionFragment { public class EditFunctionFragment extends BaseFunctionFragment {
public EditFunctionFragment() { public EditFunctionFragment() {
@ -103,10 +104,11 @@ public class EditFunctionFragment extends BaseFunctionFragment {
@Override @Override
protected boolean validateName() { protected boolean validateName() {
if (!super.validateName()) { final String name = nameView.getText().toString();
if (!Engine.isValidName(name)) {
setError(nameLabel, getString(R.string.function_name_is_not_valid));
return false; return false;
} }
final String name = nameView.getText().toString();
final Function existingFunction = functionsRegistry.get(name); final Function existingFunction = functionsRegistry.get(name);
if (existingFunction != null) { if (existingFunction != null) {
if (!existingFunction.isIdDefined()) { if (!existingFunction.isIdDefined()) {

View File

@ -1,46 +1,46 @@
package org.solovyev.android.calculator.plot; package org.solovyev.android.calculator.plot;
import android.text.TextUtils;
import org.solovyev.android.plotter.Function; import org.solovyev.android.plotter.Function;
import jscl.math.Expression; import javax.annotation.Nonnull;
import jscl.math.Generic; import jscl.math.Generic;
import jscl.math.JsclInteger; import jscl.math.JsclInteger;
import jscl.math.NumericWrapper; import jscl.math.NumericWrapper;
import jscl.math.function.Constant; import jscl.math.function.CustomFunction;
import jscl.math.numeric.Complex; import jscl.math.numeric.Complex;
import jscl.math.numeric.Numeric; import jscl.math.numeric.Numeric;
import jscl.math.numeric.Real; import jscl.math.numeric.Real;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ExpressionFunction extends Function { public class ExpressionFunction extends Function {
private static final Complex NaN = Complex.valueOf(Double.NaN, 0d);
@Nonnull @Nonnull
public final jscl.math.function.Function function; public final jscl.math.function.Function function;
public final Constant xVariable;
public final Constant yVariable;
public final boolean imaginary; public final boolean imaginary;
public final int arity; public final int arity;
private final Generic[] parameters;
public ExpressionFunction(@Nonnull jscl.math.function.Function function, @Nullable Constant x, public ExpressionFunction(@Nonnull jscl.math.function.Function function,
@Nullable Constant y, boolean imaginary) { boolean imaginary) {
super(imaginary ? "Im(" + function.toString() + ")" : function.toString()); super(makeFunctionName(function, imaginary));
this.function = function; this.function = function;
this.xVariable = x;
this.yVariable = y;
this.imaginary = imaginary; this.imaginary = imaginary;
this.arity = countArity(x, y); this.arity = function.getMaxParameters();
this.parameters = new Generic[this.arity];
} }
private static int countArity(@Nullable Constant x, @Nullable Constant y) { @Nonnull
if (x != null && y != null) { private static String makeFunctionName(@Nonnull jscl.math.function.Function function, boolean imaginary) {
return 2; String name = function.getName();
} else if (x == null && y == null) { if (TextUtils.isEmpty(name)) {
return 0; if (function instanceof CustomFunction) {
name = ((CustomFunction) function).getContent();
} else {
name = function.toString();
}
} }
return 1; return imaginary ? "Im(" + name + ")" : name;
} }
@Override @Override
@ -50,81 +50,53 @@ public class ExpressionFunction extends Function {
@Override @Override
public float evaluate() { public float evaluate() {
final Complex value = calculate(function); try {
if (imaginary) { return unwrap(function.numeric());
return (float) value.imaginaryPart(); } catch (RuntimeException e) {
return Float.NaN;
} }
return (float) value.realPart();
} }
@Override @Override
public float evaluate(float x) { public float evaluate(float x) {
final Complex value = calculate(function, xVariable, x); try {
if (imaginary) { parameters[0] = new NumericWrapper(Real.valueOf(x));
return (float) value.imaginaryPart(); function.setParameters(parameters);
return unwrap(function.numeric());
} catch (RuntimeException e) {
return Float.NaN;
} }
return (float) value.realPart();
} }
@Override @Override
public float evaluate(float x, float y) { public float evaluate(float x, float y) {
final Complex value = calculate(function, xVariable, x, yVariable, y);
if (imaginary) {
return (float) value.imaginaryPart();
}
return (float) value.realPart();
}
@Nonnull
public static Complex calculate(jscl.math.function.Function function, Constant xVar,
float x, Constant yVar, float y) {
try {
Generic tmp = function.substitute(xVar, Expression.valueOf((double) x));
tmp = tmp.substitute(yVar, Expression.valueOf((double) y));
return unwrap(tmp.numeric());
} catch (RuntimeException e) {
return NaN;
}
}
@Nonnull
public static Complex calculate(jscl.math.function.Function function, Constant xVar,
float x) {
try {
return unwrap(function.substitute(xVar, Expression.valueOf((double) x)).numeric());
} catch (RuntimeException e) {
return NaN;
}
}
@Nonnull
public static Complex calculate(jscl.math.function.Function function) {
try { try {
parameters[0] = new NumericWrapper(Real.valueOf(x));
parameters[1] = new NumericWrapper(Real.valueOf(y));
function.setParameters(parameters);
return unwrap(function.numeric()); return unwrap(function.numeric());
} catch (RuntimeException e) { } catch (RuntimeException e) {
return NaN; return Float.NaN;
} }
} }
@Nonnull public float unwrap(Generic numeric) {
public static Complex unwrap(Generic numeric) {
if (numeric instanceof JsclInteger) { if (numeric instanceof JsclInteger) {
return Complex.valueOf(((JsclInteger) numeric).intValue(), 0d); return ((JsclInteger) numeric).intValue();
} else if (numeric instanceof NumericWrapper) {
return unwrap(((NumericWrapper) numeric).content());
} else {
return NaN;
} }
if (numeric instanceof NumericWrapper) {
return unwrap(((NumericWrapper) numeric).content());
}
return Float.NaN;
} }
@Nonnull public float unwrap(Numeric content) {
public static Complex unwrap(Numeric content) {
if (content instanceof Real) { if (content instanceof Real) {
return Complex.valueOf(((Real) content).doubleValue(), 0d); return (float) ((Real) content).doubleValue();
} else if (content instanceof Complex) {
return ((Complex) content);
} else {
throw new ArithmeticException();
} }
if (content instanceof Complex) {
return (float) (imaginary ? ((Complex) content).imaginaryPart() : ((Complex) content).realPart());
}
return Float.NaN;
} }
} }

View File

@ -10,8 +10,6 @@ import android.view.View;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import com.google.common.base.Strings;
import org.solovyev.android.calculator.App; import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent; import org.solovyev.android.calculator.AppComponent;
import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.R;
@ -23,18 +21,18 @@ import org.solovyev.android.plotter.PlotIconView;
import org.solovyev.android.plotter.Plotter; import org.solovyev.android.plotter.Plotter;
import org.solovyev.android.plotter.meshes.MeshSpec; import org.solovyev.android.plotter.meshes.MeshSpec;
import butterknife.Bind;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import uz.shift.colorpicker.LineColorPicker;
import uz.shift.colorpicker.OnColorChangedListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject; import javax.inject.Inject;
import butterknife.Bind;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import uz.shift.colorpicker.LineColorPicker;
import uz.shift.colorpicker.OnColorChangedListener;
public class PlotEditFunctionFragment extends BaseFunctionFragment public class PlotEditFunctionFragment extends BaseFunctionFragment
implements SeekBar.OnSeekBarChangeListener { implements SeekBar.OnSeekBarChangeListener {
@Inject @Inject
@ -67,22 +65,14 @@ public class PlotEditFunctionFragment extends BaseFunctionFragment
final PlotEditFunctionFragment fragment = new PlotEditFunctionFragment(); final PlotEditFunctionFragment fragment = new PlotEditFunctionFragment();
if (pf != null && pf.function instanceof ExpressionFunction) { if (pf != null && pf.function instanceof ExpressionFunction) {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
final String name =
pf.function.hasName() ? Strings.nullToEmpty(pf.function.getName()) : "";
final List<String> parameters = new ArrayList<>();
final ExpressionFunction ef = (ExpressionFunction) pf.function; final ExpressionFunction ef = (ExpressionFunction) pf.function;
if (ef.xVariable != null) { final List<String> parameters = new ArrayList<>(((CustomFunction) ef.function).getParameterNames());
parameters.add(ef.xVariable.getName());
}
if (ef.yVariable != null) {
parameters.add(ef.yVariable.getName());
}
args.putParcelable(ARG_FUNCTION, CppFunction args.putParcelable(ARG_FUNCTION, CppFunction
.builder(name, .builder(ef.function.getName(),
((CustomFunction) ef.function).getContent()) ((CustomFunction) ef.function).getContent())
.withParameters(parameters) .withParameters(parameters)
.withId(pf.function.getId()) .withId(pf.function.getId())
.build()); .build());
fragment.setArguments(args); fragment.setArguments(args);
} }
return fragment; return fragment;
@ -168,7 +158,7 @@ public class PlotEditFunctionFragment extends BaseFunctionFragment
final Constant x = parameters.size() > 0 ? new Constant(parameters.get(0)) : null; final Constant x = parameters.size() > 0 ? new Constant(parameters.get(0)) : null;
final Constant y = parameters.size() > 1 ? new Constant(parameters.get(1)) : null; final Constant y = parameters.size() > 1 ? new Constant(parameters.get(1)) : null;
final ExpressionFunction expressionFunction = final ExpressionFunction expressionFunction =
new ExpressionFunction(function.toJsclBuilder().create(), x, y, false); new ExpressionFunction(function.toJsclBuilder().create(), false);
final PlotFunction plotFunction = PlotFunction.create(expressionFunction, final PlotFunction plotFunction = PlotFunction.create(expressionFunction,
applyMeshSpec()); applyMeshSpec());
final int id = function.getId(); final int id = function.getId();

View File

@ -1,5 +1,11 @@
package jscl.math; package jscl.math;
import java.math.BigInteger;
import java.util.Collections;
import java.util.Set;
import javax.annotation.Nonnull;
import jscl.JsclMathEngine; import jscl.JsclMathEngine;
import jscl.math.function.Constant; import jscl.math.function.Constant;
import jscl.math.function.Constants; import jscl.math.function.Constants;
@ -11,12 +17,6 @@ import jscl.math.numeric.Real;
import jscl.math.numeric.Vector; import jscl.math.numeric.Vector;
import jscl.mathml.MathML; import jscl.mathml.MathML;
import java.math.BigInteger;
import java.util.Collections;
import java.util.Set;
import javax.annotation.Nonnull;
public final class NumericWrapper extends Generic implements INumeric<NumericWrapper> { public final class NumericWrapper extends Generic implements INumeric<NumericWrapper> {
@Nonnull @Nonnull
@ -185,7 +185,7 @@ public final class NumericWrapper extends Generic implements INumeric<NumericWra
} }
public Generic substitute(@Nonnull Variable variable, Generic generic) { public Generic substitute(@Nonnull Variable variable, Generic generic) {
return null; return this;
} }
public Generic expand() { public Generic expand() {