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; }