Displaying differences for changeset
 
display as  

src/java/cfa/DoubleArray.java

@@ -1458,13 +1458,13 @@
         return dayData;
     }
     /**
-     * Checks if the provided dates are subsequent dates, aka nextDate = date + 1day.  
-     * This check includes December 31st to January 1st catchs, 4-year leap-year catches, 
-     * 100-year non-leap-year catches and 400-year leap-year catches
-     * @param date  the first date to be increased
-     * @return returns the string value of the next date formatted as yyyy-MM-dd
+     * Gets the day that is 'direction' amount before/after the provided date
+     * @param date  the current date
+     * @param direction  the magnitude and direction of days from 'date' that is desired 
+     * (i.e. a value of -2 would yield the date of 2 days ago while a value of 1 will yield tomorrow's date)
+     * @return returns the string value of the date that is 'direction' away formatted as yyyy-MM-dd
      */
-    public String getNextDay(String date){
+    public String getDay(String date, int direction){
         //Parse Date
         double year = Double.parseDouble(date.substring(0,4));
         double month = Double.parseDouble(date.substring(5,7));
@@ -1475,7 +1475,7 @@
         
         //Get next date
         Calendar calendar = new GregorianCalendar(yearInt, monthInt, dayInt);
-        calendar.add(Calendar.DAY_OF_MONTH, 1);
+        calendar.add(Calendar.DAY_OF_MONTH, direction);
         
         //Parse next date
         yearInt = calendar.get(Calendar.YEAR);
@@ -1533,10 +1533,11 @@
      * Loops through and finds "m-day" consecutive values and takes the arithmetic average of them
      * @param flowData  a string[][] containing: column1 = dates, column2 = flowValues
      * @param numDays  an integer representing the number (m) of consecutive days to be desired for analysis
+     * @param averageType  a flag for what sort of average to take of the dataset either 'arithmetic' or 'harmonic' are supported currently
      * @returns  an ArrayList containing an ArrayList of each set of "m-day" consecutive set of flows for analysis (min, max, average, etc)
      * @throws IOException
      */
-    public Object[] getMdayData(String[][] flowData, int numDays) throws IOException{
+    public Object[] getMdayData(String[][] flowData, int numDays, String averageType) throws IOException{
         DoubleMath doubleMath = new DoubleMath();
         
         //Loop through flow data and find "m"-day consecutive flows
@@ -1573,7 +1574,11 @@
                     String startDate = mDayDate.get(0);
                     String endDate = mDayDate.get(numDays - 1);
                     allDate.add(startDate + " to " + endDate);
-                    allData.add(doubleMath.meanArithmetic(mDayData));
+                    if(averageType.equalsIgnoreCase("arithmetic")){
+                        allData.add(doubleMath.meanArithmetic(mDayData));
+                    }else if(averageType.equalsIgnoreCase("harmonic")){
+                        allData.add(doubleMath.meanHarmonic(mDayData));
+                    }
                 }
             }
         }catch(ArrayIndexOutOfBoundsException e){

src/java/cfa/DoubleMath.java

@@ -241,6 +241,32 @@
         return meanHarmonic;
     }
     /**
+     * Calculates the harmonic mean of the provided ArrayList<Double> array, 
+     * only calculates for real positive values.
+     * 
+     * Note that the final estimate of the harmonic mean is a weighted average 
+     * of the harmonic mean of the non-zero elements and zero.
+     * @param data  the ArrayList<Double> array of which the harmonic mean is desired
+     * @return  the double value of the harmonic mean of the data array
+     */
+    public double meanHarmonic(ArrayList<Double> data){
+        //Calculate properties of harmonic mean
+        double reciprocalSum = 0, nZeros = 0, nNonZeros = 0;
+        for(int i=0; i<data.size(); i++){
+            if(data.get(i) > 0){
+                reciprocalSum = reciprocalSum + (1/data.get(i));//sum of reciprocals
+            }else{
+                nZeros++;
+            }
+            nNonZeros++;
+        }
+        
+        //Compute harmonic mean (with correction for the number of zero items in the array)
+        double meanHarmonic = (nNonZeros - nZeros) / (reciprocalSum * ((nNonZeros - nZeros)/nNonZeros));
+        
+        return meanHarmonic;
+    }
+    /**
      * Finds the average of the Log10 of a double[] array
      * @param data  the double[] array that the average is desired for
      * @return  the double value of the average of the Log10 of the data array

src/java/cfa/FlowStatistics.java

@@ -600,7 +600,7 @@
         double centroid = centroidSum / sum;
         
         //Calculate 3-day statistics
-        Object[] resultArray = doubleArray.getMdayData(flowData, 3);
+        Object[] resultArray = doubleArray.getMdayData(flowData, 3, "arithmetic");
         ArrayList<String> average_3day_date = (ArrayList<String>) resultArray[0];
         ArrayList<Double> average_3day = (ArrayList<Double>) resultArray[1];
         double max_3day = doubleMath.max(average_3day);
@@ -609,7 +609,7 @@
         String min_3day_date = getDateOfValue(average_3day_date, average_3day, min_3day);
         
         //Calculate 7-day statistics
-        resultArray = doubleArray.getMdayData(flowData, 7);
+        resultArray = doubleArray.getMdayData(flowData, 7, "arithmetic");
         ArrayList<String> average_7day_date = (ArrayList<String>) resultArray[0];
         ArrayList<Double> average_7day = (ArrayList<Double>) resultArray[1];
         double max_7day = doubleMath.max(average_7day);
@@ -619,7 +619,7 @@
         String min_7day_date = getDateOfValue(average_7day_date, average_7day, min_7day);
         
         //Calculate 30-day statistics
-        resultArray = doubleArray.getMdayData(flowData, 30);
+        resultArray = doubleArray.getMdayData(flowData, 30, "arithmetic");
         ArrayList<String> average_30day_date = (ArrayList<String>) resultArray[0];
         ArrayList<Double> average_30day = (ArrayList<Double>) resultArray[1];
         double max_30day = doubleMath.max(average_30day);
@@ -628,7 +628,7 @@
         String min_30day_date = getDateOfValue(average_30day_date, average_30day, min_30day);
         
         //Calculate 90-day statistics
-        resultArray = doubleArray.getMdayData(flowData, 90);
+        resultArray = doubleArray.getMdayData(flowData, 90, "arithmetic");
         ArrayList<String> average_90day_date = (ArrayList<String>) resultArray[0];
         ArrayList<Double> average_90day = (ArrayList<Double>) resultArray[1];
         double max_90day = doubleMath.max(average_90day);
@@ -639,7 +639,7 @@
         //Calculate mQn (7Q10)Statistics
         double min_Mday = 0;
         if(m != 0){
-            resultArray = doubleArray.getMdayData(flowData, m);
+            resultArray = doubleArray.getMdayData(flowData, m, "arithmetic");
             ArrayList<Double> average_Mday = (ArrayList<Double>) resultArray[1];
             min_Mday = doubleMath.min(average_Mday);
         }

src/java/cfa/gui15minTimeseries_Model.java

@@ -184,7 +184,7 @@
             ArrayList<Double> partialData = doubleArray.getDaysData(flowData, currentDay);
             resultSummary = CalculateStatistics(partialData, resultSummary, currentDay);
             
-            String nextDay = doubleArray.getNextDay(currentDay);
+            String nextDay = doubleArray.getDay(currentDay, 1);
             if(finalDay.compareToIgnoreCase(String.valueOf(nextDay)) >= 0){
                 currentDay = String.valueOf(nextDay);
             }else{