// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1990 - 2016 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Boulder, Colorado, USA // ** BSD licence applies - redistribution and use in source and binary // ** forms, with or without modification, are permitted provided that // ** the following conditions are met: // ** 1) If the software is modified to produce derivative works, // ** such modified software should be clearly marked, so as not // ** to confuse it with the version available from UCAR. // ** 2) Redistributions of source code must retain the above copyright // ** notice, this list of conditions and the following disclaimer. // ** 3) Redistributions in binary form must reproduce the above copyright // ** notice, this list of conditions and the following disclaimer in the // ** documentation and/or other materials provided with the distribution. // ** 4) Neither the name of UCAR nor the names of its contributors, // ** if any, may be used to endorse or promote products derived from // ** this software without specific prior written permission. // ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS // ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* #include <toolsa/copyright.h> #include <cstdio> #include <rapmath/OrderedList.hh> #include <rapmath/Math.hh> using std::vector; using std::pair; /*----------------------------------------------------------------*/ // default constructor..empty list OrderedList::OrderedList() { _n = 0; _is_ordered = false; _is_ordered_weights = false; } /*----------------------------------------------------------------*/ // destructor OrderedList::~OrderedList() { clear(); } /*----------------------------------------------------------------*/ void OrderedList::print(void) const { vector<pair<double,int> >::const_iterator i; printf("List:"); for (i=_val.begin(); i!= _val.end(); ++i) printf(" %.3lf", i->first); printf("Weights:"); for (i=_w.begin(); i!= _w.end(); ++i) printf(" %.3lf", i->first); printf("\n"); } /*----------------------------------------------------------------*/ void OrderedList::clear(void) { _n = 0; _val.clear(); _w.clear(); _is_ordered = false; _is_ordered_weights = false; } /*----------------------------------------------------------------*/ void OrderedList::addToListUnordered(double v) { pair<double,int> d(v, -1); _val.push_back(d); d.first = 1.0; _w.push_back(d); ++_n; _is_ordered = false; _is_ordered_weights = false; } /*----------------------------------------------------------------*/ void OrderedList::addToListUnordered(const std::pair<double,double> &dw) { pair<double,int> d(dw.first, -1); _val.push_back(d); d.first = dw.second; _w.push_back(d); ++_n; _is_ordered = false; _is_ordered_weights = false; } /*----------------------------------------------------------------*/ void OrderedList::order(void) { // create interface to usort method Math::sort(_val); _is_ordered = true; } /*----------------------------------------------------------------*/ void OrderedList::orderWeights(void) { Math::sort(_w); _is_ordered_weights = true; } /*----------------------------------------------------------------*/ double OrderedList::percentile(double p) { int pcnt; if (_n <= 0) return 0.0; if (_n == 1) return _ithd(0); if (!_is_ordered) { order(); } pcnt = (int)(p*(double)_n); if (pcnt < 0) pcnt = 0; if (pcnt >= _n) pcnt = _n-1; return (_ithd(_ithi(pcnt))); } /*----------------------------------------------------------------*/ double OrderedList::weightPercentile(double p) { int pcnt; if (_n <= 0) return 0.0; if (_n == 1) return _ithd(0); if (!_is_ordered_weights) { orderWeights(); } pcnt = (int)(p*(double)_n); if (pcnt < 0) pcnt = 0; if (pcnt >= _n) pcnt = _n-1; return (_ithd(_ithwi(pcnt))); } /*----------------------------------------------------------------*/ double OrderedList::weightConstrainedAverage(double p0, double p1) { int pcnt0, pcnt1, i; double sum, num; if (_n <= 0) return 0.0; if (_n == 1) return _ithd(0); if (!_is_ordered_weights) orderWeights(); pcnt0 = (int)(p0*(double)_n); if (pcnt0 < 0) pcnt0 = 0; if (pcnt0 >= _n) pcnt0 = (int)(_n-1); pcnt1 = (int)(p1*(double)_n); if (pcnt1 < 0) pcnt1 = 0; if (pcnt1 >= _n) pcnt1 = _n-1; num = sum = 0.0; for (i=pcnt0; i<=pcnt1; ++i) { num += 1.0; sum += _ithd(_ithwi(i)); } if (num > 0.0) return sum/num; else return 0.0; } /*----------------------------------------------------------------*/ // return ith ordered index (from bottom up) int OrderedList::ithPerm(int i) { if (i < 0 || i >= _n) return -1; if (_n <= 0) return -1; if (_n == 1) return 0; if (!_is_ordered) order(); return (_val.begin() + i)->second; }