Example #1
0
typename aol::Vector<_DataType>::RealType aol::Vector<_DataType>:: getWeightedMedianValue( const aol::Vector<RealType> &Weights ) const {
  const int numVals = this->size();

  if ( numVals != Weights.size() )
    throw Exception ( "aol::Vector<DataType>::getWeightedMedianValue: numVals != Weights.size() !\n", __FILE__, __LINE__ );

  if ( Weights.getMinValue() <= 0 )
    throw Exception ( "aol::Vector<DataType>::getWeightedMedianValue: Nonpositive weights are not supported!\n", __FILE__, __LINE__ );

  std::vector<std::pair<_DataType, RealType> > valuesAndWeights;
  valuesAndWeights.reserve ( numVals );
  for ( int i = 0; i < numVals; ++i )
    valuesAndWeights.push_back ( std::pair<_DataType, RealType> ( this->get ( i ), Weights[i] ) );

  std::sort( valuesAndWeights.begin(), valuesAndWeights.end() );
  const RealType halfOfTotalWeight = 0.5 * Weights.sum();

  RealType weight = 0;
  for ( int i = 0; i < numVals; ++i ) {
    weight += valuesAndWeights[i].second;
    if ( ( weight > halfOfTotalWeight ) || ( i == ( numVals - 1 ) ) )
      return valuesAndWeights[i].first;
    else if ( aol::appeqAbsolute ( weight, halfOfTotalWeight ) ) {
      return ( valuesAndWeights[i].first * valuesAndWeights[i].second + valuesAndWeights[i+1].first * valuesAndWeights[i+1].second ) / ( valuesAndWeights[i].second +  valuesAndWeights[i+1].second );
    }
  }
  return valuesAndWeights[numVals-1].first;
}