package net.sf.openrocket.util; import java.lang.reflect.Array; public class ArrayUtils { /** * Returns a double array with values from start to end with given step. * Starts exactly at start and stops at the multiple of step <= stop. */ public static double[] range(double start, double stop, double step){ int size = (int) Math.floor(((stop - start) / step)) + 1; //System.out.println("Range from "+start+" to "+stop+" step "+step+" has length "+size); double[] output = new double[size]; int i = 0; double x = start; while (i<size){ output[i] = x; x = x+step; i++; } return output; } /** * Return the mean of an array */ public static double mean(double[] vals){ double subtotal = 0; for (int i = 0; i < vals.length; i++ ){ if (!Double.isNaN(vals[i])){ subtotal += vals[i]; } } subtotal = subtotal / vals.length; return subtotal; } /** * Returns the maximum value in the array. */ public static double max(double[] vals) { double m = vals[0]; for (int i = 1; i < vals.length; i++) m = Math.max(m, vals[i]); return m; } /** * Returns the minimum value in the array. */ public static double min(double[] vals) { double m = vals[0]; for (int i = 1; i < vals.length; i++) m = Math.min(m, vals[i]); return m; } /** * Returns the variance of the array of doubles */ public static double variance(double[] vals) { double mu = mean(vals); double sumsq = 0.0; double temp = 0; for (int i = 0; i < vals.length; i++){ if (!Double.isNaN(vals[i])){ temp = (mu - vals[i]); sumsq += temp*temp; } } return sumsq / (vals.length); } /** * Returns the standard deviation of an array of doubles */ public static double stdev(double[] vals) { return Math.sqrt(variance(vals)); } /** * Returns the RMS value of an array of doubles */ public static double rms(double[] vals) { double m = mean(vals); double s = stdev(vals); return Math.sqrt( m*m + s*s ); } /** * Returns the integral of a given array calculated by the trapezoidal rule * dt is the time step between each array value. Any NaN values are treated as zero */ public static double trapz(double[] y, double dt){ double stop = (y.length -1) * dt; if (y.length <= 1 || dt <= 0) return 0; double[] x = range(0, stop, dt); double sum = 0.0; for (int i = 1; i < x.length; i++) { double temp = (x[i] - x[i-1]) * (y[i] + y[i-1]); if (!Double.isNaN(temp)){ sum += temp; } } return sum * 0.5; } /** * Returns the nearest value in an array to a given value * Search starts from the lowest array index */ public static double tnear(double[] range, double near, double start, double step){ double min = Double.POSITIVE_INFINITY; int mini = 0; //System.out.println("Nearest to "+near+" in range length "+range.length); for (int i=0; i < range.length; i++){ double x = Math.abs(range[i] - near); if (x < min){ min = x; mini = i; } } //System.out.println("Found nearest at i="+mini); return start + (mini*step); } public static <T> T[] copyOf( T[] original, int length ) { return copyOfRange(original,0,length); } /** * Implementation of java.util.Arrays.copyOfRange * * Since Froyo does not include this function it must be implemented here. * * @param original * @param start * @param end * @return */ public static <T> T[] copyOfRange( T[] original, int start, int end ) { if ( original == null ) { throw new NullPointerException(); } if ( start < 0 || start > original.length ) { throw new ArrayIndexOutOfBoundsException(); } if ( start > end ) { throw new IllegalArgumentException(); } @SuppressWarnings("unchecked") T[] result = (T[]) Array.newInstance( original.getClass().getComponentType(), end-start ); int index = 0; int stop = original.length < end ? original.length : end; for ( int i = start; i < stop; i ++ ) { if ( i < original.length ) { result[index] = original[i]; } index++; } return result; } public static double[] copyOf( double[] original, int length ) { return copyOfRange(original,0,length); } public static double[] copyOfRange( double[] original, int start, int end ) { if ( original == null ) { throw new NullPointerException(); } if ( start < 0 || start > original.length ) { throw new ArrayIndexOutOfBoundsException(); } if ( start > end ) { throw new IllegalArgumentException(); } double[] result = new double[(end-start)]; int index = 0; int stop = original.length < end ? original.length : end; for ( int i = start; i < stop; i ++ ) { if ( i < original.length ) { result[index] = original[i]; } index++; } return result; } public static byte[] copyOf( byte[] original, int length ) { return copyOfRange(original,0,length); } public static byte[] copyOfRange( byte[] original, int start, int end ) { if ( original == null ) { throw new NullPointerException(); } if ( start < 0 || start > original.length ) { throw new ArrayIndexOutOfBoundsException(); } if ( start > end ) { throw new IllegalArgumentException(); } byte[] result = new byte[(end-start)]; int index = 0; int stop = original.length < end ? original.length : end; for ( int i = start; i < stop; i ++ ) { if ( i < original.length ) { result[index] = original[i]; } index++; } return result; } }