@@ -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){ |
@@ -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 |
@@ -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); |
} |