Example #1
0
static int BasicTest(
  size_t n,
  const int bound_on_0,
  const int bound_on_1,
  const int bound_on_2,
  const int bound_on_3,
  const char *lattice_name,
  const UINT8 total_ref_0,
  const UINT8 total_ref_1,
  const UINT8 total_ref_2,
  const UINT8 total_ref_3
  )
{

  const int bound_on[4] = {bound_on_0, bound_on_1, bound_on_2, bound_on_3};
  const UINT8 total_ref[4] = {total_ref_0, total_ref_1, total_ref_2, total_ref_3};

  // Create lattice tiling
  LatticeTiling *tiling = XLALCreateLatticeTiling(n);
  XLAL_CHECK(tiling != NULL, XLAL_EFUNC);

  // Add bounds
  for (size_t i = 0; i < n; ++i) {
    XLAL_CHECK(bound_on[i] == 0 || bound_on[i] == 1, XLAL_EFAILED);
    XLAL_CHECK(XLALSetLatticeTilingConstantBound(tiling, i, 0.0, bound_on[i] * pow(100.0, 1.0/n)) == XLAL_SUCCESS, XLAL_EFUNC);
  }

  // Set metric to the Lehmer matrix
  const double max_mismatch = 0.3;
  {
    gsl_matrix *GAMAT(metric, n, n);
    for (size_t i = 0; i < n; ++i) {
      for (size_t j = 0; j < n; ++j) {
        const double ii = i+1, jj = j+1;
        gsl_matrix_set(metric, i, j, jj >= ii ? ii/jj : jj/ii);
      }
    }
    XLAL_CHECK(XLALSetTilingLatticeAndMetric(tiling, lattice_name, metric, max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);
    GFMAT(metric);
    printf("Number of (tiled) dimensions: %zu (%zu)\n", XLALTotalLatticeTilingDimensions(tiling), XLALTiledLatticeTilingDimensions(tiling));
    printf("  Bounds: %i %i %i %i\n", bound_on_0, bound_on_1, bound_on_2, bound_on_3);
    printf("  Lattice type: %s\n", lattice_name);
  }

  // Create lattice tiling locator
  LatticeTilingLocator *loc = XLALCreateLatticeTilingLocator(tiling);
  XLAL_CHECK(loc != NULL, XLAL_EFUNC);
  if (lalDebugLevel & LALINFOBIT) {
    printf("  Index trie:\n");
    XLAL_CHECK(XLALPrintLatticeTilingIndexTrie(loc, stdout) == XLAL_SUCCESS, XLAL_EFUNC);
  }

  for (size_t i = 0; i < n; ++i) {

    // Create lattice tiling iterator and locator over 'i+1' dimensions
    LatticeTilingIterator *itr = XLALCreateLatticeTilingIterator(tiling, i+1);
    XLAL_CHECK(itr != NULL, XLAL_EFUNC);

    // Count number of points
    const UINT8 total = XLALTotalLatticeTilingPoints(itr);
    printf("Number of lattice points in %zu dimensions: %" LAL_UINT8_FORMAT "\n", i+1, total);
    XLAL_CHECK(imaxabs(total - total_ref[i]) <= 1, XLAL_EFUNC,
               "ERROR: |total - total_ref[%zu]| = |%" LAL_UINT8_FORMAT " - %" LAL_UINT8_FORMAT "| > 1", i, total, total_ref[i]);
    for (UINT8 k = 0; XLALNextLatticeTilingPoint(itr, NULL) > 0; ++k) {
      const UINT8 itr_index = XLALCurrentLatticeTilingIndex(itr);
      XLAL_CHECK(k == itr_index, XLAL_EFUNC,
                 "ERROR: k = %" LAL_UINT8_FORMAT " != %" LAL_UINT8_FORMAT " = itr_index", k, itr_index);
    }
    XLAL_CHECK(XLALResetLatticeTilingIterator(itr) == XLAL_SUCCESS, XLAL_EFUNC);

    // Check tiling statistics
    printf("  Check tiling statistics ...");
    for (size_t j = 0; j < n; ++j) {
      const LatticeTilingStats *stats = XLALLatticeTilingStatistics(tiling, j);
      XLAL_CHECK(stats != NULL, XLAL_EFUNC);
      XLAL_CHECK(imaxabs(stats->total_points - total_ref[j]) <= 1, XLAL_EFAILED, "\n  "
                 "ERROR: |total - total_ref[%zu]| = |%" LAL_UINT8_FORMAT " - %" LAL_UINT8_FORMAT "| > 1", j, stats->total_points, total_ref[j]);
      XLAL_CHECK(stats->min_points <= stats->avg_points, XLAL_EFAILED, "\n  "
                 "ERROR: min_points = %" LAL_INT4_FORMAT " > %g = avg_points", stats->min_points, stats->avg_points);
      XLAL_CHECK(stats->max_points >= stats->avg_points, XLAL_EFAILED, "\n  "
                 "ERROR: max_points = %" LAL_INT4_FORMAT " < %g = avg_points", stats->max_points, stats->avg_points);
    }
    printf(" done\n");

    // Get all points
    gsl_matrix *GAMAT(points, n, total);
    XLAL_CHECK(XLALNextLatticeTilingPoints(itr, &points) == (int)total, XLAL_EFUNC);
    XLAL_CHECK(XLALNextLatticeTilingPoint(itr, NULL) == 0, XLAL_EFUNC);

    // Get nearest points to each template, check for consistency
    printf("  Testing XLALNearestLatticeTiling{Point|Block}() ...");
    gsl_vector *GAVEC(nearest, n);
    UINT8Vector *nearest_indexes = XLALCreateUINT8Vector(n);
    XLAL_CHECK(nearest_indexes != NULL, XLAL_ENOMEM);
    for (UINT8 k = 0; k < total; ++k) {
      gsl_vector_const_view point_view = gsl_matrix_const_column(points, k);
      const gsl_vector *point = &point_view.vector;
      XLAL_CHECK(XLALNearestLatticeTilingPoint(loc, point, nearest, nearest_indexes) == XLAL_SUCCESS, XLAL_EFUNC);
      gsl_vector_sub(nearest, point);
      double err = gsl_blas_dasum(nearest) / n;
      XLAL_CHECK(err < 1e-6, XLAL_EFAILED, "\n  "
                 "ERROR: err = %e < 1e-6", err);
      XLAL_CHECK(nearest_indexes->data[i] == k, XLAL_EFAILED, "\n  "
                 "ERROR: nearest_indexes[%zu] = %" LAL_UINT8_FORMAT " != %" LAL_UINT8_FORMAT "\n", i, nearest_indexes->data[i], k);
      if (0 < i) {
        const LatticeTilingStats *stats = XLALLatticeTilingStatistics(tiling, i);
        UINT8 nearest_index = 0;
        UINT4 nearest_left = 0, nearest_right = 0;
        XLAL_CHECK(XLALNearestLatticeTilingBlock(loc, point, i, nearest, &nearest_index, &nearest_left, &nearest_right) == XLAL_SUCCESS, XLAL_EFUNC);
        XLAL_CHECK(nearest_index == nearest_indexes->data[i-1], XLAL_EFAILED, "\n  "
                   "ERROR: nearest_index = %" LAL_UINT8_FORMAT " != %" LAL_UINT8_FORMAT "\n", nearest_index, nearest_indexes->data[i-1]);
        UINT4 nearest_len = 1 + nearest_left + nearest_right;
        XLAL_CHECK(nearest_len <= stats->max_points, XLAL_EFAILED, "\n  "
                   "ERROR: nearest_len = %i > %i = stats[%zu]->max_points\n", nearest_len, stats->max_points, i);
      }
      if (i+1 < n) {
        const LatticeTilingStats *stats = XLALLatticeTilingStatistics(tiling, i+1);
        UINT8 nearest_index = 0;
        UINT4 nearest_left = 0, nearest_right = 0;
        XLAL_CHECK(XLALNearestLatticeTilingBlock(loc, point, i+1, nearest, &nearest_index, &nearest_left, &nearest_right) == XLAL_SUCCESS, XLAL_EFUNC);
        XLAL_CHECK(nearest_index == nearest_indexes->data[i], XLAL_EFAILED, "\n  "
                   "ERROR: nearest_index = %" LAL_UINT8_FORMAT " != %" LAL_UINT8_FORMAT "\n", nearest_index, nearest_indexes->data[i]);
        UINT4 nearest_len = 1 + nearest_left + nearest_right;
        XLAL_CHECK(nearest_len <= stats->max_points, XLAL_EFAILED, "\n  "
                   "ERROR: nearest_len = %i > %i = stats[%zu]->max_points\n", nearest_len, stats->max_points, i+1);
      }
    }
    printf(" done\n");

    // Cleanup
    XLALDestroyLatticeTilingIterator(itr);
    GFMAT(points);
    GFVEC(nearest);
    XLALDestroyUINT8Vector(nearest_indexes);

  }

  for (size_t i = 0; i < n; ++i) {

    // Create alternating lattice tiling iterator over 'i+1' dimensions
    LatticeTilingIterator *itr_alt = XLALCreateLatticeTilingIterator(tiling, i+1);
    XLAL_CHECK(itr_alt != NULL, XLAL_EFUNC);
    XLAL_CHECK(XLALSetLatticeTilingAlternatingIterator(itr_alt, true) == XLAL_SUCCESS, XLAL_EFUNC);

    // Count number of points, check for consistency with non-alternating count
    UINT8 total = 0;
    while (XLALNextLatticeTilingPoint(itr_alt, NULL) > 0) ++total;
    XLAL_CHECK(imaxabs(total - total_ref[i]) <= 1, XLAL_EFUNC, "ERROR: alternating |total - total_ref[%zu]| = |%" LAL_UINT8_FORMAT " - %" LAL_UINT8_FORMAT "| > 1", i, total, total_ref[i]);

    // Cleanup
    XLALDestroyLatticeTilingIterator(itr_alt);

  }

  // Cleanup
  XLALDestroyLatticeTiling(tiling);
  XLALDestroyLatticeTilingLocator(loc);
  LALCheckMemoryLeaks();
  printf("\n");
  fflush(stdout);

  return XLAL_SUCCESS;

}
static int CheckSuperskyMetrics(
  const gsl_matrix *rssky_metric,
  const double rssky_metric_ref[4][4],
  const gsl_matrix *rssky_transf,
  const double rssky_transf_ref[6][3],
  const double phys_mismatch[NUM_POINTS][NUM_POINTS],
  const double phys_mismatch_tol
  )
{

  // Check supersky metrics
  {
    gsl_matrix_const_view rssky_metric_ref_view = gsl_matrix_const_view_array( ( const double * )rssky_metric_ref, 4, 4 );
    const double err = XLALCompareMetrics( rssky_metric, &rssky_metric_ref_view.matrix ), err_tol = 1e-6;
    XLAL_CHECK( err <= err_tol, XLAL_ETOL, "'rssky_metric' check failed: err = %0.3e > %0.3e = err_tol", err, err_tol );
  }
  {
    XLAL_CHECK( rssky_transf->size1 == 6 && rssky_transf->size2 == 3, XLAL_ESIZE );
    const double err_tol = 1e-5;
    for ( size_t i = 0; i < rssky_transf->size1; ++i ) {
      for ( size_t j = 0; j < rssky_transf->size2; ++j ) {
        const double rssky_transf_ij = gsl_matrix_get( rssky_transf, i, j );
        const double rssky_transf_ref_ij = rssky_transf_ref[i][j];
        CHECK_RELERR( rssky_transf_ij, rssky_transf_ref_ij, err_tol );
      }
    }
  }

  // Check round-trip conversions of each test point
  {
    gsl_matrix *GAMAT( rssky_points, 4, NUM_POINTS );
    for ( size_t j = 0; j < NUM_POINTS; ++j ) {
      gsl_vector_view rssky_point = gsl_matrix_column( rssky_points, j );
      PulsarDopplerParams XLAL_INIT_DECL( new_phys_point );
      XLAL_CHECK( XLALConvertPhysicalToSuperskyPoint( &rssky_point.vector, &phys_points[j], rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( XLALConvertSuperskyToPhysicalPoint( &new_phys_point, &rssky_point.vector, rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK( CompareDoppler( &phys_points[j], &new_phys_point ) == EXIT_SUCCESS, XLAL_EFUNC );
    }
    gsl_matrix *intm_phys_points = NULL;
    gsl_matrix *new_rssky_points = NULL;
    XLAL_CHECK( XLALConvertSuperskyToPhysicalPoints( &intm_phys_points, rssky_points, rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK( XLALConvertPhysicalToSuperskyPoints( &new_rssky_points, intm_phys_points, rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
    const double err_tol = 1e-6;
    for ( size_t i = 0; i < 4; ++i ) {
      for ( size_t j = 0; j < NUM_POINTS; ++j ) {
        const double rssky_points_ij = gsl_matrix_get( rssky_points, i, j );
        const double new_rssky_points_ij = gsl_matrix_get( new_rssky_points, i, j );
        CHECK_RELERR( rssky_points_ij, new_rssky_points_ij, err_tol );
      }
    }
    GFMAT( rssky_points, intm_phys_points, new_rssky_points );
  }

  // Check mismatches between pairs of points
  {
    gsl_vector *GAVEC( rssky_point_i, 4 );
    gsl_vector *GAVEC( rssky_point_j, 4 );
    gsl_vector *GAVEC( temp, 4 );
    for ( size_t i = 0; i < NUM_POINTS; ++i ) {
      XLAL_CHECK( XLALConvertPhysicalToSuperskyPoint( rssky_point_i, &phys_points[i], rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
      for ( size_t j = 0; j < NUM_POINTS; ++j ) {
        XLAL_CHECK( XLALConvertPhysicalToSuperskyPoint( rssky_point_j, &phys_points[j], rssky_transf ) == XLAL_SUCCESS, XLAL_EFUNC );
        gsl_vector_sub( rssky_point_j, rssky_point_i );
        gsl_blas_dgemv( CblasNoTrans, 1.0, rssky_metric, rssky_point_j, 0.0, temp );
        double mismatch = 0.0;
        gsl_blas_ddot( rssky_point_j, temp, &mismatch );
        CHECK_RELERR( mismatch, phys_mismatch[i][j], phys_mismatch_tol );
      }
    }
    GFVEC( rssky_point_i, rssky_point_j, temp );
  }

  return XLAL_SUCCESS;

}