Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / core / src / net / sf / openrocket / util / ArrayUtils.java
diff --git a/core/src/net/sf/openrocket/util/ArrayUtils.java b/core/src/net/sf/openrocket/util/ArrayUtils.java
new file mode 100644 (file)
index 0000000..d029394
--- /dev/null
@@ -0,0 +1,250 @@
+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();
+               }
+               
+               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;
+               
+       }
+
+}
+