Ejemplo n.º 1
0
/**
 * \brief Chops the data into stationary segments based on Bayesian change point analysis
 *
 * This function splits data into two (and recursively runs on those two segments) if it is found that the odds ratio
 * for them being from two independent Gaussian distributions is greater than a certain threshold.
 *
 * The threshold for the natural logarithm of the odds ratio is empirically set to be
 * \f[
 * T = 4.07 + 1.33\log{}_{10}{N},
 * \f]
 * where \f$N\f$ is the length in samples of the dataset. This is based on Monte Carlo simulations of
 * many realisations of Gaussian noise for data of different lengths. The threshold comes from a linear
 * fit to the log odds ratios required to give a 1% chance of splitting Gaussian data (drawn from a single
 * distribution) for data of various lengths.  Note, however, that this relation is not good for stretches of data
 * with lengths of less than about 30 points, and in fact is rather consevative for such short stretches
 * of data, i.e. such short stretches of data will require relatively larger odds ratios for splitting than
 * longer stretches.
 *
 * \param data [in] A complex data vector
 * \param chunkMin [in] The minimum allowed segment length
 *
 * \return A vector of segment lengths
 *
 * \sa find_change_point
 */
UINT4Vector *chop_data( gsl_vector_complex *data, UINT4 chunkMin ){
  UINT4Vector *chunkIndex = NULL;

  UINT4 length = (UINT4)data->size;

  REAL8 logodds = 0.;
  UINT4 changepoint = 0;

  REAL8 threshold = 0.; /* may need tuning or setting globally */

  chunkIndex = XLALCreateUINT4Vector( 1 );

  changepoint = find_change_point( data, &logodds, chunkMin );

  /* threshold scaling for a 0.5% false alarm probability of splitting Gaussian data */
  threshold = 4.07 + 1.33*log10((REAL8)length);

  if ( logodds > threshold ){
    UINT4Vector *cp1 = NULL;
    UINT4Vector *cp2 = NULL;

    gsl_vector_complex_view data1 = gsl_vector_complex_subvector( data, 0, changepoint );
    gsl_vector_complex_view data2 = gsl_vector_complex_subvector( data, changepoint, length-changepoint );

    UINT4 i = 0, l = 0;

    cp1 = chop_data( &data1.vector, chunkMin );
    cp2 = chop_data( &data2.vector, chunkMin );

    l = cp1->length + cp2->length;

    chunkIndex = XLALResizeUINT4Vector( chunkIndex, l );

    /* combine new chunks */
    for (i = 0; i < cp1->length; i++) { chunkIndex->data[i] = cp1->data[i]; }
    for (i = 0; i < cp2->length; i++) { chunkIndex->data[i+cp1->length] = cp2->data[i] + changepoint; }

    XLALDestroyUINT4Vector( cp1 );
    XLALDestroyUINT4Vector( cp2 );
  }
  else{ chunkIndex->data[0] = length; }

  return chunkIndex;
}
Ejemplo n.º 2
0
int
print_Lcurve(const char *filename, poltor_workspace *w)
{
  int s = 0;
  FILE *fp;
  const size_t p = w->p;
  double rnorm, Lnorm;
  gsl_vector_complex_view v = gsl_vector_complex_subvector(w->rhs, 0, p);
  size_t i;

  fp = fopen(filename, "a");
  if (!fp)
    {
      fprintf(stderr, "print_Lcurve: unable to open %s: %s\n",
              filename, strerror(errno));
      return -1;
    }

  /* construct A and b, and calculate chi^2 = ||b - A c||^2 */
  poltor_build_ls(0, w);
  rnorm = sqrt(w->chisq);

  /* compute v = L c; L is stored in w->L by poltor_solve() */
  for (i = 0; i < p; ++i)
    {
      gsl_complex ci = gsl_vector_complex_get(w->c, i);
      double li = gsl_vector_get(w->L, i);
      gsl_complex val = gsl_complex_mul_real(ci, li);

      gsl_vector_complex_set(&v.vector, i, val);
    }

  /* compute || L c || */
  Lnorm = gsl_blas_dznrm2(&v.vector);

  fprintf(fp, "%.12e %.12e %.6e %.6e %.6e\n",
          log(rnorm),
          log(Lnorm),
          w->alpha_int,
          w->alpha_sh,
          w->alpha_tor);

  printcv_octave(w->residuals, "r");
  printcv_octave(w->c, "c");
  printv_octave(w->L, "L");

  fclose(fp);

  return s;
} /* print_Lcurve() */
Ejemplo n.º 3
0
int
lls_complex_fold(const gsl_matrix_complex *A, const gsl_vector_complex *b,
                 lls_complex_workspace *w)
{
  const size_t n = A->size1;

  if (A->size2 != w->p)
    {
      fprintf(stderr, "lls_complex_fold: A has wrong size2\n");
      return GSL_EBADLEN;
    }
  else if (n != b->size)
    {
      fprintf(stderr, "lls_complex_fold: b has wrong size\n");
      return GSL_EBADLEN;
    }
  else
    {
      int s = 0;
      double bnorm;
#if 0
      size_t i;

      gsl_vector_view wv = gsl_vector_subvector(w->w_robust, 0, n);

      if (w->niter > 0)
        {
          gsl_vector_complex_view rc = gsl_vector_complex_subvector(w->r_complex, 0, n);
          gsl_vector_view rv = gsl_vector_subvector(w->r, 0, n);

          /* calculate residuals with previously computed coefficients: r = b - A c */
          gsl_vector_complex_memcpy(&rc.vector, b);
          gsl_blas_zgemv(CblasNoTrans, GSL_COMPLEX_NEGONE, A, w->c, GSL_COMPLEX_ONE, &rc.vector);

          /* compute Re(r) */
          for (i = 0; i < n; ++i)
            {
              gsl_complex ri = gsl_vector_complex_get(&rc.vector, i);
              gsl_vector_set(&rv.vector, i, GSL_REAL(ri));
            }

          /* calculate weights with robust weighting function */
          gsl_multifit_robust_weights(&rv.vector, &wv.vector, w->robust_workspace_p);
        }
      else
        gsl_vector_set_all(&wv.vector, 1.0);

      /* compute final weights as product of input and robust weights */
      gsl_vector_mul(wts, &wv.vector);

#endif
 
      /* AHA += A^H A, using only the upper half of the matrix */
      s = gsl_blas_zherk(CblasUpper, CblasConjTrans, 1.0, A, 1.0, w->AHA);
      if (s)
        return s;

      /* AHb += A^H b */
      s = gsl_blas_zgemv(CblasConjTrans, GSL_COMPLEX_ONE, A, b, GSL_COMPLEX_ONE, w->AHb);
      if (s)
        return s;

      /* bHb += b^H b */
      bnorm = gsl_blas_dznrm2(b);
      w->bHb += bnorm * bnorm;

      fprintf(stderr, "norm(AHb) = %.12e, bHb = %.12e\n",
              gsl_blas_dznrm2(w->AHb), w->bHb);

      if (!gsl_finite(w->bHb))
        {
          fprintf(stderr, "bHb is NAN\n");
          exit(1);
        }

      return s;
    }
} /* lls_complex_fold() */
Ejemplo n.º 4
0
int 
gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau)  
{
  if (A->size1 != A->size2)
    {
      GSL_ERROR ("hermitian tridiagonal decomposition requires square matrix",
                 GSL_ENOTSQR);
    }
  else if (tau->size + 1 != A->size1)
    {
      GSL_ERROR ("size of tau must be (matrix size - 1)", GSL_EBADLEN);
    }
  else
    {
      const size_t N = A->size1;
      size_t i;
  
      const gsl_complex zero = gsl_complex_rect (0.0, 0.0);
      const gsl_complex one = gsl_complex_rect (1.0, 0.0);
      const gsl_complex neg_one = gsl_complex_rect (-1.0, 0.0);

      for (i = 0 ; i < N - 1; i++)
        {
          gsl_vector_complex_view c = gsl_matrix_complex_column (A, i);
          gsl_vector_complex_view v = gsl_vector_complex_subvector (&c.vector, i + 1, N - (i + 1));
          gsl_complex tau_i = gsl_linalg_complex_householder_transform (&v.vector);
          
          /* Apply the transformation H^T A H to the remaining columns */

          if ((i + 1) < (N - 1) 
              && !(GSL_REAL(tau_i) == 0.0 && GSL_IMAG(tau_i) == 0.0)) 
            {
              gsl_matrix_complex_view m = 
                gsl_matrix_complex_submatrix (A, i + 1, i + 1, 
                                              N - (i+1), N - (i+1));
              gsl_complex ei = gsl_vector_complex_get(&v.vector, 0);
              gsl_vector_complex_view x = gsl_vector_complex_subvector (tau, i, N-(i+1));
              gsl_vector_complex_set (&v.vector, 0, one);
              
              /* x = tau * A * v */
              gsl_blas_zhemv (CblasLower, tau_i, &m.matrix, &v.vector, zero, &x.vector);

              /* w = x - (1/2) tau * (x' * v) * v  */
              {
                gsl_complex xv, txv, alpha;
                gsl_blas_zdotc(&x.vector, &v.vector, &xv);
                txv = gsl_complex_mul(tau_i, xv);
                alpha = gsl_complex_mul_real(txv, -0.5);
                gsl_blas_zaxpy(alpha, &v.vector, &x.vector);
              }
              
              /* apply the transformation A = A - v w' - w v' */
              gsl_blas_zher2(CblasLower, neg_one, &v.vector, &x.vector, &m.matrix);

              gsl_vector_complex_set (&v.vector, 0, ei);
            }
          
          gsl_vector_complex_set (tau, i, tau_i);
        }
      
      return GSL_SUCCESS;
    }
}