Blame movstat/fill.c

Packit 67cb25
/* movstat/fill.c
Packit 67cb25
 * 
Packit 67cb25
 * Copyright (C) 2018 Patrick Alken
Packit 67cb25
 * 
Packit 67cb25
 * This program is free software; you can redistribute it and/or modify
Packit 67cb25
 * it under the terms of the GNU General Public License as published by
Packit 67cb25
 * the Free Software Foundation; either version 3 of the License, or (at
Packit 67cb25
 * your option) any later version.
Packit 67cb25
 * 
Packit 67cb25
 * This program is distributed in the hope that it will be useful, but
Packit 67cb25
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 67cb25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 67cb25
 * General Public License for more details.
Packit 67cb25
 * 
Packit 67cb25
 * You should have received a copy of the GNU General Public License
Packit 67cb25
 * along with this program; if not, write to the Free Software
Packit 67cb25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit 67cb25
 */
Packit 67cb25
 
Packit 67cb25
#include <config.h>
Packit 67cb25
#include <stdlib.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <gsl/gsl_math.h>
Packit 67cb25
#include <gsl/gsl_errno.h>
Packit 67cb25
#include <gsl/gsl_vector.h>
Packit 67cb25
#include <gsl/gsl_movstat.h>
Packit 67cb25
Packit 67cb25
/*
Packit 67cb25
gsl_movstat_fill()
Packit 67cb25
  Fill window for sample 'idx' from x using given end conditions
Packit 67cb25
Packit 67cb25
Inputs: endtype     - how to handle end points
Packit 67cb25
        x           - input vector, length n
Packit 67cb25
        idx         - index of center sample in window in [0,n-1]
Packit 67cb25
        H           - number of samples left of center to include
Packit 67cb25
        J           - number of samples right of center to include
Packit 67cb25
        window      - (output) window of samples centered on x_{idx},
Packit 67cb25
                      W_{idx}^{H,J}, length H + J + 1
Packit 67cb25
Packit 67cb25
Return: size of filled window (<= H + J + 1)
Packit 67cb25
*/
Packit 67cb25
Packit 67cb25
size_t
Packit 67cb25
gsl_movstat_fill(const gsl_movstat_end_t endtype, const gsl_vector * x, const size_t idx,
Packit 67cb25
                 const size_t H, const size_t J, double * window)
Packit 67cb25
{
Packit 67cb25
  if (idx >= x->size)
Packit 67cb25
    {
Packit 67cb25
      GSL_ERROR_VAL ("window center index must be between 0 and n - 1", GSL_EDOM, 0);
Packit 67cb25
    }
Packit 67cb25
  else
Packit 67cb25
    {
Packit 67cb25
      const int n = (int) x->size;
Packit 67cb25
      const int iidx = (int) idx;
Packit 67cb25
      const int iH = (int) H;
Packit 67cb25
      const int iJ = (int) J;
Packit 67cb25
      int idx1, idx2, j;
Packit 67cb25
      size_t window_size;
Packit 67cb25
Packit 67cb25
      if (endtype == GSL_MOVSTAT_END_TRUNCATE)
Packit 67cb25
        {
Packit 67cb25
          idx1 = GSL_MAX(iidx - iH, 0);
Packit 67cb25
          idx2 = GSL_MIN(iidx + iJ, n - 1);
Packit 67cb25
        }
Packit 67cb25
      else
Packit 67cb25
        {
Packit 67cb25
          idx1 = iidx - iH;
Packit 67cb25
          idx2 = iidx + iJ;
Packit 67cb25
        }
Packit 67cb25
Packit 67cb25
      window_size = (size_t) (idx2 - idx1 + 1);
Packit 67cb25
Packit 67cb25
      /* fill sliding window */
Packit 67cb25
      for (j = idx1; j <= idx2; ++j)
Packit 67cb25
        {
Packit 67cb25
          int widx = j - idx1;
Packit 67cb25
Packit 67cb25
          if (j < 0)
Packit 67cb25
            {
Packit 67cb25
              /* initial condition */
Packit 67cb25
              if (endtype == GSL_MOVSTAT_END_PADZERO)
Packit 67cb25
                window[widx] = 0.0;
Packit 67cb25
              else if (endtype == GSL_MOVSTAT_END_PADVALUE)
Packit 67cb25
                window[widx] = gsl_vector_get(x, 0);
Packit 67cb25
            }
Packit 67cb25
          else if (j >= n)
Packit 67cb25
            {
Packit 67cb25
              if (endtype == GSL_MOVSTAT_END_PADZERO)
Packit 67cb25
                window[widx] = 0.0;
Packit 67cb25
              else if (endtype == GSL_MOVSTAT_END_PADVALUE)
Packit 67cb25
                window[widx] = gsl_vector_get(x, n - 1);
Packit 67cb25
            }
Packit 67cb25
          else
Packit 67cb25
            {
Packit 67cb25
              window[widx] = gsl_vector_get(x, j);
Packit 67cb25
            }
Packit 67cb25
        }
Packit 67cb25
Packit 67cb25
      return window_size;
Packit 67cb25
    }
Packit 67cb25
}