//
// FormulaUtil.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad.formula;

import java.lang.reflect.*;
import java.rmi.RemoteException;
import java.util.*;
import visad.*;

/** Contains a variety of useful methods related to the
    visad.formula package.

*/ public class FormulaUtil { /** create a FormulaManager object with many commonly desired features */ public static FormulaManager createStandardManager() { String[] binOps = {".", "^", "*", "/", "%", "+", "-"}; int[] binPrec = {200, 400, 600, 600, 600, 800, 800}; String[] binMethods = { "visad.formula.FormulaUtil.dot(visad.TupleIface, visad.Real)", "visad.Data.pow(visad.Data)", "visad.Data.multiply(visad.Data)", "visad.Data.divide(visad.Data)", "visad.Data.remainder(visad.Data)", "visad.Data.add(visad.Data)", "visad.Data.subtract(visad.Data)" }; String[] unaryOps = {"-"}; int[] unaryPrec = {500}; String[] unaryMethods = {"visad.Data.negate()"}; String[] functions = { "abs", "acos", "acosDegrees", "asin", "asinDegrees", "atan", "atan2", "atanDegrees", "atan2Degrees", "ceil", "combine", "cos", "cosDegrees", "derive", "domainMultiply", "domainFactor", "exp", "extract", "floor", "getSample", "linkx", "log", "max", "min", "negate", "rint", "round", "sin", "sinDegrees", "sqrt", "tan", "tanDegrees" }; String[] funcMethods = { "visad.Data.abs()", "visad.Data.acos()", "visad.Data.acosDegrees()", "visad.Data.asin()", "visad.Data.asinDegrees()", "visad.Data.atan()", "visad.Data.atan2(visad.Data)", "visad.Data.atanDegrees()", "visad.Data.atan2Degrees(visad.Data)", "visad.Data.ceil()", "visad.FieldImpl.combine(visad.Field[])", "visad.Data.cos()", "visad.Data.cosDegrees()", "visad.formula.FormulaUtil.derive(visad.Function, " + "visad.formula.VRealType)", "visad.FieldImpl.domainMultiply()", "visad.formula.FormulaUtil.factor(" + "visad.FieldImpl, visad.formula.VRealType)", "visad.Data.exp()", "visad.formula.FormulaUtil.extract(visad.Field, visad.Real)", "visad.Data.floor()", "visad.formula.FormulaUtil.brackets(visad.Field, visad.Real)", "visad.formula.FormulaUtil.link(visad.formula.VMethod, " + "java.lang.Object[])", "visad.Data.log()", "visad.Data.max(visad.Data)", "visad.Data.min(visad.Data)", "visad.Data.negate()", "visad.Data.rint()", "visad.Data.round()", "visad.Data.sin()", "visad.Data.sinDegrees()", "visad.Data.sqrt()", "visad.Data.tan()", "visad.Data.tanDegrees()" }; int implicitPrec = 200; String[] implicitMethods = { "visad.formula.FormulaUtil.implicit(visad.Function, visad.Real)", "visad.Function.evaluate(visad.RealTuple)" }; String preParseMethod = "visad.formula.FormulaUtil.preParse(" + "java.lang.String, visad.formula.FormulaManager)"; FormulaManager f; try { f = new FormulaManager(binOps, binPrec, binMethods, unaryOps, unaryPrec, unaryMethods, functions, funcMethods, implicitPrec, implicitMethods, preParseMethod); } catch (FormulaException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); return null; } return f; } /** evaluate the dot operator */ public static Data dot(TupleIface t, Real r) { Data d = null; try { d = t.getComponent((int) r.getValue()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return d; } /** evaluate the derive function */ public static Data derive(Function f, VRealType rt) { Data val = null; try { val = f.derivative(rt.getRealType(), Data.NO_ERRORS); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return val; } /** evaluate the domainFactor function */ public static visad.Field factor(FieldImpl f, VRealType rt) { visad.Field val = null; try { val = f.domainFactor(rt.getRealType()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return val; } /** evaluate the extract function */ public static Data extract(visad.Field f, Real r) { Data d = null; try { d = f.extract((int) r.getValue()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return d; } /** evaluate the link function */ public static Data link(VMethod m, Object[] o) throws VisADException { Data ans = null; if (o != null) { for (int i=0; i0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e1 = i-1; // check for correct syntax if (i > len - 3 || !l.substring(i, i+3).equals("/d(")) return s; i += 3; int s2 = i; for (int paren=1; paren>0; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i-1; ns = ns + "derive(" + s.substring(s1, e1) + "," + s.substring(s2, e2) + ")"; i--; } else if (!letter && i < len - 4 && l.substring(i, i+5).equals("link(")) { // evaluate link(code) notation and replace with link variable i += 5; int s1 = i; try { while (l.charAt(i) != '(') i++; } catch (ArrayIndexOutOfBoundsException exc) { // incorrect syntax return s; } i++; int e1 = i-1; int s2 = i; for (int paren=2; paren>1; i++) { // check for correct syntax if (i >= len) return s; char c = l.charAt(i); if (c == '(') paren++; if (c == ')') paren--; } int e2 = i-1; // check for correct syntax if (i >= len || l.charAt(i) != ')') return s; String prestr = s.substring(s1, e1) + "("; String str = prestr; // parse method's arguments; determine if they are Data or RealType String sub = s.substring(s2, e2); StringTokenizer st = new StringTokenizer(sub, ",", false); boolean first = true; Vector v = new Vector(); while (st.hasMoreTokens()) { String token = st.nextToken(); if (first) first = false; else str = str + ","; RealType rt = RealType.getRealTypeByName(token); String sv = (rt == null ? "visad.Data" : "visad.RealType"); v.add(sv); str = str + sv; } str = str + ")"; // obtain Method object Method[] meths = FormulaUtil.stringsToMethods(new String[] {str}); if (meths[0] == null) { // attempt to identify any matching methods by compressing // some or all of the arguments into array form int vlen = v.size(); Vector vstrs = new Vector(); for (int iv=0; iv= 0) meths[0] = meths[found]; else { // could not find a matching method return s; } } // store method object in a link variable String link = "link" + (++linkNum); try { fm.setThing(link, new VMethod(meths[0])); } // catch any errors setting the link variable catch (FormulaException exc) { return s; } catch (VisADException exc) { return s; } catch (RemoteException exc) { return s; } ns = ns + "linkx(" + link + "," + s.substring(s2, e2) + ")"; } else if (!letter) { int j = i; char c = l.charAt(j++); while (j < len && ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))) { c = l.charAt(j++); } // check for end-of-string if (j == len) return ns + s.substring(i, len); if (c == '[') { // convert x[y] notation to standard getSample(x, y) notation int k = j; for (int paren=1; paren>0; k++) { // check for correct syntax if (k >= len) return s; c = l.charAt(k); if (c == '[') paren++; if (c == ']') paren--; } ns = ns + "getSample(" + s.substring(i, j-1) + "," + s.substring(j, k-1) + ")"; i = k-1; } else ns = ns + s.charAt(i); } else { // append character to new string ns = ns + s.charAt(i); } char c = (i < len) ? l.charAt(i) : '\0'; letter = (c >= 'a' && c <= 'z'); } return ns; } // useful methods for advanced reflection: /** convert an array of strings of the form "package.Class.method(Class, Class, ...)" to an array of Method objects */ public static Method[] stringsToMethods(String[] strings) { int len = strings.length; Method[] methods = new Method[len]; for (int j=0; j 0) { if (a < 0) { args = new Object[num]; System.arraycopy(o, 0, args, 0, num); } else { // compress some of the arguments into array form args = new Object[len]; if (a > 0) System.arraycopy(o, 0, args, 0, a); Object array = Array.newInstance(c[a].getComponentType(), num-len+1); System.arraycopy(o, a, array, 0, num-len+1); args[a] = array; if (a < len-1) System.arraycopy(o, num-len+a+1, args, a+1, len-a-1); } } else args = null; } else { // object method if (num > 0) obj = o[0]; else { // invalid object method return null; } if (num > 1) { if (a < 0) { args = new Object[num-1]; System.arraycopy(o, 1, args, 0, num-1); } else { // compress some of the arguments into array form args = new Object[len]; if (a > 0) System.arraycopy(o, 1, args, 0, a); Object array = Array.newInstance(c[a].getComponentType(), num-len); System.arraycopy(o, a+1, array, 0, num-len); args[a+1] = array; if (a < len-1) System.arraycopy(o, num-len+a+1, args, a+1, len-a-1); } } else args = null; } return m.invoke(obj, args); } }

Ads help maintain this website.