Changeset 2012


Ignore:
Timestamp:
Aug 1, 2013, 11:22:25 AM (9 years ago)
Author:
olle
Message:

Fixes #497. Refs #79. Class/file center/Center.java in se.lu.onk.Center updated in median calculation:

  1. Private method median(List<Float> vec) is updated by replacing the current algorithm by a call to new private method float calculatePercentile(List<Float> vec, float fraction), with fraction value set to 0.5.
  2. New private method float calculatePercentile(List<Float> vec, float fraction) added. It first sorts the values in ascending order (the original input list is not changed), and then returns a weighted value of the list values of the two index values nearest to the desired percentile. If the percentile corresponds exactly to an integer index, the list value for that index is returned.


File:
1 edited

Legend:

Unmodified
Added
Removed
  • plugins/base1/se.lu.onk.Center/trunk/src/center/Center.java

    r894 r2012  
    3434import java.util.ArrayList;
    3535import java.util.Arrays;
     36import java.util.Collections;
    3637import java.util.HashMap;
    3738import java.util.List;
     
    138139    {
    139140      param_centerCycles = 20;
    140       System.err.println("To many center cycles. It has been adjusted to 20.");
     141      System.err.println("Too many center cycles. It has been adjusted to 20.");
    141142    }
    142143   
     
    327328  private float median(List<Float> vec)
    328329  {
     330    /*
     331    // Old code
    329332    float[] window =
    330333      { Float.NaN, Float.NaN, Float.NaN};
     
    349352    }
    350353    return window[0];
     354    */
     355    return calculatePercentile(vec, 0.5f);
     356  }
     357
     358  /**
     359   * Calculates percentile value for list with (Float) values.
     360   * If the percentile corresponds exactly to an integer index,
     361   * the list value for that index is returned, otherwise a
     362   * weighted value of the list values of the two index values
     363   * nearest to the desired percentile.
     364   *
     365   * Code adapted from Python function described in
     366   * http://stackoverflow.com/questions/2374640/how-do-i-calculate-percentiles-with-python-numpy.
     367   *
     368   * @param vec List<Float> List with (Float) values to calculate percentile for.
     369   * @param fraction float Fraction corresponding to desired percentile, e.g. median ~ 0.5, 95% percentile ~ 0.95.
     370   * @return float The percentile value.
     371   */
     372  private float calculatePercentile(List<Float> vec, float fraction)
     373  {
     374    Float percentileValue = null;
     375    // Get ascending sorted list
     376    List<Float> ascSortedList = new ArrayList<Float>();
     377    for (Float val: vec)
     378    {
     379      ascSortedList.add(val);
     380    }
     381    Collections.sort(ascSortedList);
     382    //
     383    int len = ascSortedList.size();
     384    // List index values goes from 0 to (len - 1)
     385    float indexVal = fraction*(len - 1);
     386    float floorVal = Double.valueOf(Math.floor(indexVal)).floatValue();
     387    float ceilVal = Double.valueOf(Math.ceil(indexVal)).floatValue();
     388    if (floorVal == ceilVal)
     389    {
     390      percentileValue = ascSortedList.get((int) indexVal);
     391    }
     392    else
     393    {
     394      // Calculate percentile value as weighted value of two list values
     395      float d0 = ascSortedList.get((int) floorVal) * (ceilVal - indexVal);
     396      float d1 = ascSortedList.get((int) ceilVal)  * (indexVal - floorVal);
     397      percentileValue = d0 + d1;
     398    }
     399    return percentileValue.floatValue();
    351400  }
    352401
Note: See TracChangeset for help on using the changeset viewer.