/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.numerics; import java.text.DecimalFormat; import org.opensourcephysics.controls.XML; import org.opensourcephysics.controls.XMLControl; /** * DoubleArray stores an array of doubles as a string and as an array. */ public class DoubleArray { public static int NumberFormatError = 1; public static int ArrayIndexOutOfBoundsError = 2; protected DecimalFormat format = new DecimalFormat("0.00"); // display format //$NON-NLS-1$ protected DecimalFormat formatExp = new DecimalFormat("0.00#E0"); // display format //$NON-NLS-1$ protected double[] array; protected String defaultString; protected double[] defaultArray; protected int errorcode = 0; /** * Creates a DoubleArray of the given length with all elements set to zero. * * The length of the arry cannot be changed. * * @param n */ public DoubleArray(int n) { array = new double[n]; defaultArray = array; } /** * Creates a DoubleArray of the given length with all elements set to zero. * * The length of the arry cannot be changed. * * @param array */ public DoubleArray(double[] array) { defaultArray = array.clone(); this.array = defaultArray; } /** * Creates an arry with the given string being the default string. * * The given string determines the length of the array. This lenght cannot be changed. * @param str * @throws NumberFormatException */ public DoubleArray(String str) throws NumberFormatException { this.array = toDouble(str); defaultString = str; defaultArray = array; } /** * Creates a DecimalFormat for printing array elements using the given pattern and the symbols * for the default locale. * * @see java.text.DecimalFormat */ public void setDecimalFormat(String pattern) { format = new DecimalFormat(pattern); formatExp = format; } /** * Gets the default array. * * The default is used if the input string is not valid due to a number format exception or an * array length exception. * * @return string */ public String getDefault() { return defaultString; } /** * Converts the array to a comma delimited string enclosed in braces. * * @return string */ public String toString() { if(errorcode>0) { return defaultString; } String str = "{"; //$NON-NLS-1$ for(int i = 0, n = array.length; i<n; i++) { str += ((Math.abs(array[i])<0.1)||(Math.abs(array[i])>1000)) ? formatExp.format(array[i]) : format.format(array[i]); if(i<n-1) { str += ", "; //$NON-NLS-1$ } } str += "}"; //$NON-NLS-1$ return str; } /** * Gets the error code * @return */ public int getError() { return errorcode; } /** * Converts the string to an array and returns the array. * * If the conversion fails, the error code is set and default array is returned. * * @return double[] the converted array */ public double[] getArray(String str) { set(str); return array; } /** * Gets the array of doubles. * @return */ public double[] getArray() { return array; } /** * Sets the array to the given string. * @return true if successful; false otherwise */ public boolean set(String str) { errorcode = 0; try { array = toDouble(str); } catch(NumberFormatException ex) { errorcode = NumberFormatError; array = toDouble(defaultString); return false; } catch(ArrayIndexOutOfBoundsException ex) { errorcode = ArrayIndexOutOfBoundsError; array = toDouble(defaultString); return false; } return true; } public void setDefaultArray(double[] array) { defaultArray = array.clone(); this.array = defaultArray; } /** * Converts a comma delimited string enclosed in braces to an array. * * v={1.5, 2.0, -3.2} would returns an array with componets (1.5,2.0,-3.2). * @param str * @return */ protected double[] toDouble(String str) throws ArrayIndexOutOfBoundsException { if(str==null) { str = "{}"; //$NON-NLS-1$ } double[] array = null; int start = str.indexOf("{")+1; //$NON-NLS-1$ int end = str.indexOf("}"); //$NON-NLS-1$ if(end-start<=0) { errorcode = ArrayIndexOutOfBoundsError; return defaultArray; } String[] s = str.substring(start, end).split(","); //$NON-NLS-1$ if((this.array!=null)&&(this.array.length!=s.length)) { throw new ArrayIndexOutOfBoundsException("Array length cannot be changed in DoubleArray. "+str); //$NON-NLS-1$ } array = new double[s.length]; for(int i = 0, n = s.length; i<n; i++) { try { array[i] = Double.parseDouble(s[i]); } catch(NumberFormatException ex) { errorcode = NumberFormatError; } } return array; } /* * Tests this class. * @param args command line parameters */ /* public static void main(String[] args) { DoubleArray a = new DoubleArray("{1.5, 2.0, -3.2}"); System.out.println(a); a.set("{3.0, -500, 0}"); // set new value System.out.println(a); a.set("{xx.5, 2.0, -3.2}"); // array set to default due to error in input System.out.println(a); a.set("{3.0, -500, 0, 0}"); // array set to default due to error in input }*/ /** * Returns an XML.ObjectLoader to save and load object data. * * @return the XML.ObjectLoader */ public static XML.ObjectLoader getLoader() { return new Loader(); } /** * A class to save and load DoubleArray data. */ static class Loader implements XML.ObjectLoader { /** * Saves DoubleArray data in an XMLControl. * * @param control the control * @param obj the DrawingPanel to save */ public void saveObject(XMLControl control, Object obj) { DoubleArray array = (DoubleArray) obj; control.setValue("data", array.getArray()); //$NON-NLS-1$ } /** * Creates a DoubleArray. * * @param control the control * @return the newly created panel */ public Object createObject(XMLControl control) { return new DoubleArray((double[]) control.getObject("data")); //$NON-NLS-1$ } /** * Loads an object with data from an XMLControl. * * @param control the control * @param obj the object * @return the loaded object */ public Object loadObject(XMLControl control, Object obj) { DoubleArray dataArray = (DoubleArray) obj; double[] data = (double[]) control.getObject("data"); //$NON-NLS-1$ dataArray.array = data; dataArray.defaultArray = data; return obj; } } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */