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;
import static org.solovyev.android.calculator.functions.CppFunction.NO_ID;
import android.annotation.SuppressLint;
import android.content.Context;
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.common.math.MathRegistry;
import butterknife.Bind;
import butterknife.ButterKnife;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@ -72,6 +67,11 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
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 {
protected static final String ARG_FUNCTION = "function";
@ -274,12 +274,6 @@ public abstract class BaseFunctionFragment extends BaseDialogFragment implements
}
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;
}

View File

@ -12,14 +12,15 @@ import android.support.v7.app.AlertDialog;
import org.solovyev.android.Activities;
import org.solovyev.android.Check;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.Engine;
import org.solovyev.android.calculator.R;
import org.solovyev.android.calculator.entities.EntityRemovalDialog;
import jscl.math.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jscl.math.function.Function;
public class EditFunctionFragment extends BaseFunctionFragment {
public EditFunctionFragment() {
@ -103,10 +104,11 @@ public class EditFunctionFragment extends BaseFunctionFragment {
@Override
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;
}
final String name = nameView.getText().toString();
final Function existingFunction = functionsRegistry.get(name);
if (existingFunction != null) {
if (!existingFunction.isIdDefined()) {

View File

@ -1,46 +1,46 @@
package org.solovyev.android.calculator.plot;
import android.text.TextUtils;
import org.solovyev.android.plotter.Function;
import jscl.math.Expression;
import javax.annotation.Nonnull;
import jscl.math.Generic;
import jscl.math.JsclInteger;
import jscl.math.NumericWrapper;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import jscl.math.numeric.Complex;
import jscl.math.numeric.Numeric;
import jscl.math.numeric.Real;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class ExpressionFunction extends Function {
private static final Complex NaN = Complex.valueOf(Double.NaN, 0d);
@Nonnull
public final jscl.math.function.Function function;
public final Constant xVariable;
public final Constant yVariable;
public final boolean imaginary;
public final int arity;
private final Generic[] parameters;
public ExpressionFunction(@Nonnull jscl.math.function.Function function, @Nullable Constant x,
@Nullable Constant y, boolean imaginary) {
super(imaginary ? "Im(" + function.toString() + ")" : function.toString());
public ExpressionFunction(@Nonnull jscl.math.function.Function function,
boolean imaginary) {
super(makeFunctionName(function, imaginary));
this.function = function;
this.xVariable = x;
this.yVariable = y;
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) {
if (x != null && y != null) {
return 2;
} else if (x == null && y == null) {
return 0;
@Nonnull
private static String makeFunctionName(@Nonnull jscl.math.function.Function function, boolean imaginary) {
String name = function.getName();
if (TextUtils.isEmpty(name)) {
if (function instanceof CustomFunction) {
name = ((CustomFunction) function).getContent();
} else {
name = function.toString();
}
}
return 1;
return imaginary ? "Im(" + name + ")" : name;
}
@Override
@ -50,81 +50,53 @@ public class ExpressionFunction extends Function {
@Override
public float evaluate() {
final Complex value = calculate(function);
if (imaginary) {
return (float) value.imaginaryPart();
try {
return unwrap(function.numeric());
} catch (RuntimeException e) {
return Float.NaN;
}
return (float) value.realPart();
}
@Override
public float evaluate(float x) {
final Complex value = calculate(function, xVariable, x);
if (imaginary) {
return (float) value.imaginaryPart();
try {
parameters[0] = new NumericWrapper(Real.valueOf(x));
function.setParameters(parameters);
return unwrap(function.numeric());
} catch (RuntimeException e) {
return Float.NaN;
}
return (float) value.realPart();
}
@Override
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 {
parameters[0] = new NumericWrapper(Real.valueOf(x));
parameters[1] = new NumericWrapper(Real.valueOf(y));
function.setParameters(parameters);
return unwrap(function.numeric());
} catch (RuntimeException e) {
return NaN;
return Float.NaN;
}
}
@Nonnull
public static Complex unwrap(Generic numeric) {
public float unwrap(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;
return ((JsclInteger) numeric).intValue();
}
if (numeric instanceof NumericWrapper) {
return unwrap(((NumericWrapper) numeric).content());
}
return Float.NaN;
}
@Nonnull
public static Complex unwrap(Numeric content) {
public float unwrap(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();
return (float) ((Real) content).doubleValue();
}
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.TextView;
import com.google.common.base.Strings;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.AppComponent;
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.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.List;
import javax.annotation.Nonnull;
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
implements SeekBar.OnSeekBarChangeListener {
@Inject
@ -67,22 +65,14 @@ public class PlotEditFunctionFragment extends BaseFunctionFragment
final PlotEditFunctionFragment fragment = new PlotEditFunctionFragment();
if (pf != null && pf.function instanceof ExpressionFunction) {
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;
if (ef.xVariable != null) {
parameters.add(ef.xVariable.getName());
}
if (ef.yVariable != null) {
parameters.add(ef.yVariable.getName());
}
final List<String> parameters = new ArrayList<>(((CustomFunction) ef.function).getParameterNames());
args.putParcelable(ARG_FUNCTION, CppFunction
.builder(name,
((CustomFunction) ef.function).getContent())
.withParameters(parameters)
.withId(pf.function.getId())
.build());
.builder(ef.function.getName(),
((CustomFunction) ef.function).getContent())
.withParameters(parameters)
.withId(pf.function.getId())
.build());
fragment.setArguments(args);
}
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 y = parameters.size() > 1 ? new Constant(parameters.get(1)) : null;
final ExpressionFunction expressionFunction =
new ExpressionFunction(function.toJsclBuilder().create(), x, y, false);
new ExpressionFunction(function.toJsclBuilder().create(), false);
final PlotFunction plotFunction = PlotFunction.create(expressionFunction,
applyMeshSpec());
final int id = function.getId();

View File

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