"Fossies" - the Fresh Open Source Software Archive

Member "veusz-3.1/veusz/helpers/src/qtloops/numpyfuncs.cpp" (16 Aug 2013, 2937 Bytes) of package /linux/privat/veusz-3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "numpyfuncs.cpp" see the Fossies "Dox" file reference documentation.

    1 //    Copyright (C) 2011 Jeremy S. Sanders
    2 //    Email: Jeremy Sanders <jeremy@jeremysanders.net>
    3 //
    4 //    This program is free software; you can redistribute it and/or modify
    5 //    it under the terms of the GNU General Public License as published by
    6 //    the Free Software Foundation; either version 2 of the License, or
    7 //    (at your option) any later version.
    8 //
    9 //    This program is distributed in the hope that it will be useful,
   10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 //    GNU General Public License for more details.
   13 //
   14 //    You should have received a copy of the GNU General Public License along
   15 //    with this program; if not, write to the Free Software Foundation, Inc.,
   16 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   17 /////////////////////////////////////////////////////////////////////////////
   18 
   19 #include "numpyfuncs.h"
   20 #include <limits>
   21 #include "isnan.h"
   22 
   23 namespace {
   24   template <class T> inline T min(T a, T b)
   25   {
   26     return (a<b) ? a : b;
   27   }
   28 }
   29 
   30 void binData(const Numpy1DObj& indata, int binning,
   31          bool average,
   32          int* numoutbins, double** outdata)
   33 {
   34   // round up output size
   35   int size = indata.dim / binning;
   36   if( indata.dim % binning != 0 )
   37     ++size;
   38 
   39   // create output array
   40   *numoutbins = size;
   41   double *out = new double[size];
   42   *outdata = out;
   43 
   44   // do binning
   45   double sum = 0.;
   46   int ct = 0;
   47   for(int i = 0 ; i < indata.dim; ++i)
   48     {
   49       // include new data
   50       if ( isFinite( indata(i) ) )
   51     {
   52       sum += indata(i);
   53       ct += 1;
   54     }
   55 
   56       // every bin or at end of array
   57       if ( i % binning == binning-1 || i == indata.dim-1 )
   58     {
   59       if( ct == 0 )
   60         {
   61           out[i / binning] = std::numeric_limits<double>::quiet_NaN();
   62         }
   63       else
   64         {
   65           if( average )
   66         out[i / binning] = sum / ct;
   67           else
   68         out[i / binning] = sum;
   69         }
   70       sum = 0;
   71       ct = 0;
   72     }
   73     }
   74 }
   75 
   76 void rollingAverage(const Numpy1DObj& indata,
   77             const Numpy1DObj* weights,
   78             int width,
   79             int* numoutbins, double** outdata)
   80 {
   81   // round up output size
   82   int size = indata.dim;
   83   if( weights != 0 )
   84     size = min( weights->dim, size );
   85 
   86   // create output array
   87   *numoutbins = size;
   88   double *out = new double[size];
   89   *outdata = out;
   90 
   91   for(int i = 0 ; i < size; ++i)
   92     {
   93       double ct = 0.;
   94       double sum = 0.;
   95 
   96       // iterate over rolling width
   97       for(int di = -width; di <= width; ++di)
   98     {
   99       const int ri = di+i;
  100       if ( ri >= 0 && ri < size && isFinite(indata(ri)) )
  101         {
  102           if( weights != 0 )
  103         {
  104           // weighted average
  105           const double w = (*weights)(ri);
  106           if( isFinite(w) )
  107             {
  108               ct += w;
  109               sum += w*indata(ri);
  110             }
  111         }
  112           else
  113         {
  114           // standard average
  115           ct += 1;
  116           sum += indata(ri);
  117         }
  118         }
  119     }
  120 
  121       if( ct != 0. )
  122     out[i] = sum / ct;
  123       else
  124     out[i] = std::numeric_limits<double>::quiet_NaN();
  125     }
  126 }