Esempio n. 1
0
///
/// Compute the determinant of a metric \f$ g_{ij} \f$.
///
double XLALMetricDeterminant(
  const gsl_matrix *g_ij		///< [in] Parameter-space metric \f$ g_{ij} \f$
  )
{

  // Check input
  XLAL_CHECK_REAL8( g_ij != NULL, XLAL_EFAULT );

  const size_t n = g_ij->size1;

  // Allocate memory
  gsl_matrix *GAMAT_REAL8( LU_decomp, n, n );
  gsl_permutation *GAPERM_REAL8( LU_perm, n );

  // Compute LU decomposition
  gsl_matrix_memcpy( LU_decomp, g_ij );
  int LU_sign = 0;
  XLAL_CHECK_REAL8( gsl_linalg_LU_decomp( LU_decomp, LU_perm, &LU_sign ) == 0, XLAL_EFAILED, "'g_ij' cannot be LU-decomposed" );

  // Compute determinant
  const double determinant = gsl_linalg_LU_det( LU_decomp, LU_sign );

  // Cleanup
  GFMAT( LU_decomp );
  GFPERM( LU_perm );

  return determinant;

}
Esempio n. 2
0
///
/// Calculate the projected metric onto the subspace orthogonal to coordinate-axis \c c, namely
/// \f$ g^{\prime}_{ij} = g_{ij} - ( g_{ic} g_{jc} / g_{cc} ) \f$, where \f$c\f$ is the index of
/// the projected coordinate.
///
/// \note \c *p_gpr_ij will be allocated if \c NULL. \c *p_gpr_ij and \c g_ij may point to the same
/// matrix.
///
int
XLALProjectMetric(
  gsl_matrix **p_gpr_ij,			///< [in,out] Pointer to projected matrix \f$g^{\prime}_{ij}\f$
  const gsl_matrix *g_ij,			///< [in] Matrix to project \f$g_{ij}\f$
  const UINT4 c					///< [in] Index of projected coordinate
  )
{

  // Check input
  XLAL_CHECK( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK( g_ij->size1 == g_ij->size2, XLAL_ESIZE );
  XLAL_CHECK( p_gpr_ij != NULL, XLAL_EFAULT );
  if ( *p_gpr_ij != NULL ) {
    XLAL_CHECK( (*p_gpr_ij)->size1 == (*p_gpr_ij)->size2, XLAL_ESIZE );
    XLAL_CHECK( (*p_gpr_ij)->size1 == g_ij->size1, XLAL_ESIZE );
  } else {
    GAMAT( *p_gpr_ij, g_ij->size1, g_ij->size2 );
  }
  XLAL_CHECK( c < g_ij->size1, XLAL_EINVAL );

  // Allocate temporary matrix
  gsl_matrix *GAMAT( ret_ij, g_ij->size1, g_ij->size2 );

  // Compute projected matrix
  for ( UINT4 i=0; i < g_ij->size1; i++)
    {
    for ( UINT4 j=0; j < g_ij->size2; j++ )
      {
        if ( i==c || j==c )
          {
            gsl_matrix_set ( ret_ij, i, j, 0.0 );
          }
        else
          {
            double proj = gsl_matrix_get(g_ij, i, j) - (gsl_matrix_get(g_ij, i, c) * gsl_matrix_get(g_ij, j, c) / gsl_matrix_get(g_ij, c, c));
            gsl_matrix_set ( ret_ij, i, j, proj );
          }
      } /* for j < dim2 */

    } /* for i < dim1 */
  gsl_matrix_memcpy( *p_gpr_ij, ret_ij );

  // Cleanup
  GFMAT( ret_ij );

  return XLAL_SUCCESS;

} // XLALProjectMetric()
Esempio n. 3
0
///
/// Diagonally-normalize a metric \f$ g_{ij} \f$.  <i>Diagonally-normalize</i> means normalize
/// metric by its diagonal, namely apply the transformation \f$ g_{ij} \rightarrow g^{\prime}_{ij} =
/// g_{ij} / \sqrt{g_{ii} g_{jj}} \f$, resulting in a lower condition number and unit diagonal
/// elements.
///
/// If \c p_transform is non-NULL, return the diagonal-normalization transform in \c *p_transform.
/// If \c p_gpr_ij is non-NULL, apply the transform to the metric \c *p_gpr_ij.
///
/// \note \c *p_gpr_ij and \c *p_transform will be allocated if \c NULL. \c *p_gpr_ij and \c g_ij
/// may point to the same matrix.
///
int
XLALDiagNormalizeMetric(
  gsl_matrix **p_gpr_ij,			///< [in,out,optional] Pointer to transformed matrix \f$g^{\prime}_{ij}\f$
  gsl_matrix **p_transform,			///< [in,out,optional] Pointer to diagonal-normalization transform
  const gsl_matrix *g_ij			///< [in] Matrix to transform \f$g_{ij}\f$
  )
{

  // Check input
  XLAL_CHECK( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK( g_ij->size1 == g_ij->size2, XLAL_ESIZE );
  if ( p_transform != NULL ) {
    if ( *p_transform != NULL ) {
      XLAL_CHECK( (*p_transform)->size1 == g_ij->size1, XLAL_ESIZE );
      XLAL_CHECK( (*p_transform)->size2 == g_ij->size2, XLAL_ESIZE );
    } else {
      GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
    }
  }

  // Create diagonal normalization transform
  gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
  gsl_matrix_set_zero( transform );
  for ( size_t i = 0; i < g_ij->size1; ++i ) {
    const double gii = gsl_matrix_get(g_ij, i, i);
    XLAL_CHECK( gii > 0, XLAL_EINVAL, "Diagonal normalization not defined for non-positive diagonal elements! g_ii(%zu,%zu) = %g\n", i, i, gii );
    gsl_matrix_set( transform, i, i, 1.0 / sqrt( gii ) );
  }

  // Apply transform
  if ( p_gpr_ij != NULL ) {
    XLAL_CHECK( XLALTransformMetric( p_gpr_ij, transform, g_ij ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Return transform
  if ( p_transform != NULL ) {
    gsl_matrix_memcpy( *p_transform, transform );
  }

  // Cleanup
  GFMAT( transform );

  return XLAL_SUCCESS;

} // XLALDiagNormalizeMetric()
Esempio n. 4
0
///
/// Compute the extent of the bounding box of the mismatch ellipse of a metric \f$ g_{ij} \f$.
///
gsl_vector *XLALMetricEllipseBoundingBox(
  const gsl_matrix *g_ij,		///< [in] Parameter-space metric \f$ g_{ij} \f$
  const double max_mismatch		///< [in] Maximum prescribed mismatch
  )
{

  // Check input
  XLAL_CHECK_NULL( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK_NULL( g_ij->size1 == g_ij->size2, XLAL_ESIZE );

  const size_t n = g_ij->size1;

  // Allocate memory
  gsl_matrix *GAMAT_NULL( LU_decomp, n, n );
  gsl_permutation *GAPERM_NULL( LU_perm, n );
  gsl_matrix *GAMAT_NULL( diag_norm, n, n );
  gsl_matrix *GAMAT_NULL( inverse, n, n );
  gsl_vector *GAVEC_NULL( bounding_box, n );

  // Diagonally normalize metric
  XLAL_CHECK_NULL( XLALDiagNormalizeMetric( &LU_decomp, &diag_norm, g_ij ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Compute metric inverse
  int LU_sign = 0;
  XLAL_CHECK_NULL( gsl_linalg_LU_decomp( LU_decomp, LU_perm, &LU_sign ) == 0, XLAL_EFAILED, "'g_ij' cannot be LU-decomposed" );
  XLAL_CHECK_NULL( gsl_linalg_LU_invert( LU_decomp, LU_perm, inverse ) == 0, XLAL_EFAILED, "'g_ij' cannot be inverted" );

  // Compute bounding box, and invert diagonal normalization
  for( size_t i = 0; i < n; ++i ) {
    const double diag_norm_i = gsl_matrix_get( diag_norm, i, i );
    const double bounding_box_i = 2.0 * sqrt( max_mismatch * gsl_matrix_get( inverse, i, i ) ) * diag_norm_i;
    gsl_vector_set( bounding_box, i, bounding_box_i );
  }

  // Cleanup
  GFMAT( LU_decomp, diag_norm, inverse );
  GFPERM( LU_perm );

  return bounding_box;

} // XLALMetricEllipseBoundingBox()
Esempio n. 5
0
///
/// Apply the inverse of a transform \f$\mathbf{A}^{-1} = \mathbf{B} = (b_{ij})\f$ to a metric
/// \f$\mathbf{G} = (g_{ij})\f$ such that \f$ \mathbf{G} \rightarrow \mathbf{G}^{\prime} =
/// \mathbf{B}^{\mathrm{T}} \mathbf{G} \mathbf{B} \f$, or equivalently \f$ g_{ij} \rightarrow
/// g^{\prime}_{kl} = g_{ij} b_{ik} b_{jl} \f$.
///
/// \note \c *p_gpr_ij will be allocated if \c NULL. \c *p_gpr_ij and \c g_ij may point to the same
/// matrix.
///
int XLALInverseTransformMetric(
  gsl_matrix **p_gpr_ij,			///< [in,out] Pointer to transformed matrix \f$\mathbf{G}^{\prime}\f$
  const gsl_matrix *transform,			///< [in] Transform \f$\mathbf{A}\f$, the inverse of which to apply
  const gsl_matrix *g_ij			///< [in] Matrix to transform \f$\mathbf{G}\f$
  )
{

  // Check input
  XLAL_CHECK( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK( transform != NULL, XLAL_EFAULT );
  XLAL_CHECK( g_ij->size1 == g_ij->size2, XLAL_ESIZE );
  XLAL_CHECK( g_ij->size2 == transform->size1, XLAL_ESIZE );
  XLAL_CHECK( transform->size1 == transform->size2, XLAL_ESIZE );
  XLAL_CHECK( p_gpr_ij != NULL, XLAL_EFAULT );

  // Allocate memory
  gsl_matrix *GAMAT( LU_decomp, transform->size1, transform->size2 );
  gsl_permutation *GAPERM( LU_perm, transform->size1 );
  gsl_matrix *GAMAT( inverse, transform->size1, transform->size2 );

  // Compute inverse of transform
  int LU_sign = 0;
  gsl_matrix_memcpy( LU_decomp, transform );
  XLAL_CHECK( gsl_linalg_LU_decomp( LU_decomp, LU_perm, &LU_sign ) == 0, XLAL_EFAILED, "'transform' cannot be LU-decomposed" );
  XLAL_CHECK( gsl_linalg_LU_invert( LU_decomp, LU_perm, inverse ) == 0, XLAL_EFAILED, "'transform' cannot be inverted" );

  // Apply transform
  XLAL_CHECK( XLALTransformMetric( p_gpr_ij, inverse, g_ij ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Cleanup
  GFMAT( LU_decomp, inverse );
  GFPERM( LU_perm );

  return XLAL_SUCCESS;

} // XLALInverseTransformMetric()
Esempio n. 6
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;

}
Esempio n. 7
0
static int SuperskyTest(
  const double T,
  const double max_mismatch,
  const char *lattice_name,
  const UINT8 patch_count,
  const double freq,
  const double freqband,
  const UINT8 total_ref,
  const double mism_hist_ref[MISM_HIST_BINS]
  )
{

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

  // Compute reduced supersky metric
  const double Tspan = T * 86400;
  LIGOTimeGPS ref_time;
  XLALGPSSetREAL8(&ref_time, 900100100);
  LALSegList segments;
  {
    XLAL_CHECK(XLALSegListInit(&segments) == XLAL_SUCCESS, XLAL_EFUNC);
    LALSeg segment;
    LIGOTimeGPS start_time = ref_time, end_time = ref_time;
    XLALGPSAdd(&start_time, -0.5 * Tspan);
    XLALGPSAdd(&end_time, 0.5 * Tspan);
    XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  MultiLALDetector detectors = {
    .length = 1,
    .sites = { lalCachedDetectors[LAL_LLO_4K_DETECTOR] }
  };
  EphemerisData *edat =  XLALInitBarycenter(TEST_DATA_DIR "earth00-19-DE405.dat.gz",
                                            TEST_DATA_DIR "sun00-19-DE405.dat.gz");
  XLAL_CHECK(edat != NULL, XLAL_EFUNC);
  SuperskyMetrics *metrics = XLALComputeSuperskyMetrics(0, &ref_time, &segments, freq, &detectors, NULL, DETMOTION_SPIN | DETMOTION_PTOLEORBIT, edat);
  XLAL_CHECK(metrics != NULL, XLAL_EFUNC);
  gsl_matrix *rssky_metric = metrics->semi_rssky_metric, *rssky_transf = metrics->semi_rssky_transf;
  metrics->semi_rssky_metric = metrics->semi_rssky_transf = NULL;
  XLALDestroySuperskyMetrics(metrics);
  XLALSegListClear(&segments);
  XLALDestroyEphemerisData(edat);

  // Add bounds
  printf("Bounds: supersky, sky patch 0/%" LAL_UINT8_FORMAT ", freq=%0.3g, freqband=%0.3g\n", patch_count, freq, freqband);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(tiling, rssky_metric, rssky_transf, patch_count, 0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(tiling, rssky_transf, 0, freq, freq + freqband) == XLAL_SUCCESS, XLAL_EFUNC);
  GFMAT(rssky_transf);

  // Set metric
  printf("Lattice type: %s\n", lattice_name);
  XLAL_CHECK(XLALSetTilingLatticeAndMetric(tiling, lattice_name, rssky_metric, max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch test
  XLAL_CHECK(MismatchTest(tiling, rssky_metric, max_mismatch, total_ref, mism_hist_ref) == XLAL_SUCCESS, XLAL_EFUNC);

  return XLAL_SUCCESS;

}

static int MultiSegSuperskyTest(void)
{
  printf("Performing multiple-segment tests ...\n");

  // Compute reduced supersky metrics
  const double Tspan = 86400;
  LIGOTimeGPS ref_time;
  XLALGPSSetREAL8(&ref_time, 900100100);
  LALSegList segments;
  {
    XLAL_CHECK(XLALSegListInit(&segments) == XLAL_SUCCESS, XLAL_EFUNC);
    LALSeg segment;
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, -4 * Tspan);
      XLALGPSAdd(&end_time, -3 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, -0.5 * Tspan);
      XLALGPSAdd(&end_time, 0.5 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
    {
      LIGOTimeGPS start_time = ref_time, end_time = ref_time;
      XLALGPSAdd(&start_time, 3.5 * Tspan);
      XLALGPSAdd(&end_time, 4.5 * Tspan);
      XLAL_CHECK(XLALSegSet(&segment, &start_time, &end_time, 0) == XLAL_SUCCESS, XLAL_EFUNC);
      XLAL_CHECK(XLALSegListAppend(&segments, &segment) == XLAL_SUCCESS, XLAL_EFUNC);
    }
  }
  MultiLALDetector detectors = {
    .length = 1,
    .sites = { lalCachedDetectors[LAL_LLO_4K_DETECTOR] }
  };
  EphemerisData *edat =  XLALInitBarycenter(TEST_DATA_DIR "earth00-19-DE405.dat.gz",
                                            TEST_DATA_DIR "sun00-19-DE405.dat.gz");
  XLAL_CHECK(edat != NULL, XLAL_EFUNC);
  SuperskyMetrics *metrics = XLALComputeSuperskyMetrics(1, &ref_time, &segments, 50, &detectors, NULL, DETMOTION_SPIN | DETMOTION_PTOLEORBIT, edat);
  XLAL_CHECK(metrics != NULL, XLAL_EFUNC);

  // Project and rescale semicoherent metric to give equal frequency spacings
  const double coh_max_mismatch = 0.2, semi_max_mismatch = 0.4;
  XLAL_CHECK(XLALEqualizeReducedSuperskyMetricsFreqSpacing(metrics, coh_max_mismatch, semi_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Create lattice tilings
  LatticeTiling *coh_tiling[metrics->num_segments];
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    coh_tiling[n] = XLALCreateLatticeTiling(4);
    XLAL_CHECK(coh_tiling[n] != NULL, XLAL_EFUNC);
  }
  LatticeTiling *semi_tiling = XLALCreateLatticeTiling(4);
  XLAL_CHECK(semi_tiling != NULL, XLAL_EFUNC);

  // Add bounds
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(coh_tiling[n], metrics->coh_rssky_metric[n], metrics->coh_rssky_transf[n], 1, 0) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(coh_tiling[n], metrics->coh_rssky_transf[n], 0, 50, 50 + 1e-4) == XLAL_SUCCESS, XLAL_EFUNC);
    XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(coh_tiling[n], metrics->coh_rssky_transf[n], 1, 0, -5e-10) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSkyPatch(semi_tiling, metrics->semi_rssky_metric, metrics->semi_rssky_transf, 1, 0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(semi_tiling, metrics->semi_rssky_transf, 0, 50, 50 + 1e-4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK(XLALSetSuperskyLatticeTilingPhysicalSpinBound(semi_tiling, metrics->semi_rssky_transf, 1, 0, -5e-10) == XLAL_SUCCESS, XLAL_EFUNC);

  // Set metric
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLAL_CHECK(XLALSetTilingLatticeAndMetric(coh_tiling[n], "Ans", metrics->coh_rssky_metric[n], coh_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);
  }
  XLAL_CHECK(XLALSetTilingLatticeAndMetric(semi_tiling, "Ans", metrics->semi_rssky_metric, semi_max_mismatch) == XLAL_SUCCESS, XLAL_EFUNC);

  // Check lattice step sizes in frequency
  const size_t ifreq = 3;
  const double semi_dfreq = XLALLatticeTilingStepSizes(semi_tiling, ifreq);
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    const double coh_dfreq = XLALLatticeTilingStepSizes(coh_tiling[n], ifreq);
    const double tol = 1e-8;
    XLAL_CHECK(fabs(coh_dfreq - semi_dfreq) < tol * semi_dfreq, XLAL_EFAILED,
               "  ERROR: semi_dfreq=%0.15e, coh_dfreq[%zu]=%0.15e, |coh_dfreq - semi_dfreq| >= %g * semi_dfreq", semi_dfreq, n, coh_dfreq, tol);
  }

  // Check computation of spindown range for coherent tilings
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    PulsarSpinRange spin_range;
    XLAL_CHECK(XLALSuperskyLatticePulsarSpinRange(&spin_range, coh_tiling[n], metrics->coh_rssky_transf[n]) == XLAL_SUCCESS, XLAL_EFUNC);
  }

  // Cleanup
  for (size_t n = 0; n < metrics->num_segments; ++n) {
    XLALDestroyLatticeTiling(coh_tiling[n]);
  }
  XLALDestroyLatticeTiling(semi_tiling);
  XLALDestroySuperskyMetrics(metrics);
  XLALSegListClear(&segments);
  XLALDestroyEphemerisData(edat);
  LALCheckMemoryLeaks();
  printf("\n");
  fflush(stdout);

  return XLAL_SUCCESS;

}

int main(void)
{

  // Perform basic tests
  XLAL_CHECK_MAIN(BasicTest(1, 0, 0, 0, 0, "Zn" ,    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(1, 1, 1, 1, 1, "Ans",   93,    0,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(1, 1, 1, 1, 1, "Zn" ,   93,    0,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 0, 0, 0, 0, "Ans",    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 1, 1, 1, 1, "Ans",   12,  144,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(2, 1, 1, 1, 1, "Zn" ,   13,  190,    0,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 0, 0, 0, 0, "Zn" ,    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 1, 1, 1, 1, "Ans",    8,   46,  332,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(3, 1, 1, 1, 1, "Zn" ,    8,   60,  583,    0) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 0, 0, "Ans",    1,    1,    1,    1) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 0, 1, "Ans",    1,    1,    1,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 1, 0, "Ans",    1,    1,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 0, 1, 1, "Ans",    1,    1,    4,   20) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 0, 0, "Ans",    1,    4,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 0, 1, "Ans",    1,    5,    5,   25) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 1, 0, "Ans",    1,    5,   24,   24) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 0, 1, 1, 1, "Ans",    1,    5,   20,  115) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 0, 0, "Ans",    4,    4,    4,    4) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 0, 1, "Ans",    5,    5,    5,   23) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 1, 0, "Ans",    5,    5,   23,   23) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 0, 1, 1, "Ans",    6,    6,   24,  139) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 0, 0, "Ans",    5,   25,   25,   25) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 0, 1, "Ans",    6,   30,   30,  162) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 0, "Ans",    6,   27,  151,  151) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 1, "Ans",    6,   30,  145,  897) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(BasicTest(4, 1, 1, 1, 1, "Zn" ,    7,   46,  287, 2543) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with a square parameter space
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  0.03,     0,     0, 21460,  Z1_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  2e-4, -2e-9,     0, 23763,  Z2_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Zn",  1e-4, -1e-9, 1e-17, 19550,  Z3_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 0.03,     0,     0, 21460, A1s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 2e-4, -2e-9,     0, 18283, A2s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchSquareTest("Ans", 1e-4, -2e-9, 2e-17, 20268, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with an age--braking index parameter space
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 100, 4.0e-5, 37872, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 200, 1.5e-5, 37232, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(MismatchAgeBrakeTest("Ans", 300, 1.0e-5, 37022, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform mismatch tests with the reduced supersky parameter space and metric
  XLAL_CHECK_MAIN(SuperskyTest(1.1, 0.8, "Ans",  1, 50, 2.0e-5, 20548, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(SuperskyTest(1.5, 0.8, "Ans",  3, 50, 2.0e-5, 20202, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);
  XLAL_CHECK_MAIN(SuperskyTest(2.5, 0.8, "Ans", 17, 50, 2.0e-5, 29147, A3s_mism_hist) == XLAL_SUCCESS, XLAL_EFUNC);

  // Perform tests with the reduced supersky parameter space metric and multiple segments
  XLAL_CHECK_MAIN(MultiSegSuperskyTest() == XLAL_SUCCESS, XLAL_EFUNC);

  return EXIT_SUCCESS;

}
Esempio n. 8
0
static int MismatchTest(
  LatticeTiling *tiling,
  gsl_matrix *metric,
  const double max_mismatch,
  const UINT8 total_ref,
  const double mism_hist_ref[MISM_HIST_BINS]
  )
{

  const size_t n = XLALTotalLatticeTilingDimensions(tiling);

  // Create lattice tiling iterator and locator
  LatticeTilingIterator *itr = XLALCreateLatticeTilingIterator(tiling, n);
  XLAL_CHECK(itr != NULL, XLAL_EFUNC);
  LatticeTilingLocator *loc = XLALCreateLatticeTilingLocator(tiling);
  XLAL_CHECK(loc != NULL, XLAL_EFUNC);

  // Count number of points
  const UINT8 total = XLALTotalLatticeTilingPoints(itr);
  printf("Number of lattice points: %" LAL_UINT8_FORMAT "\n", total);
  XLAL_CHECK(imaxabs(total - total_ref) <= 1, XLAL_EFUNC, "ERROR: |total - total_ref| = |%" LAL_UINT8_FORMAT " - %" LAL_UINT8_FORMAT "| > 1", total, total_ref);

  // 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);

  // Initialise mismatch histogram counts
  double mism_hist[MISM_HIST_BINS] = {0};
  double mism_hist_total = 0, mism_hist_out_of_range = 0;

  // Perform 10 injections for every template
  {
    gsl_matrix *GAMAT(injections, 3, total);
    gsl_matrix *GAMAT(nearest, 3, total);
    gsl_matrix *GAMAT(temp, 3, total);
    RandomParams *rng = XLALCreateRandomParams(total);
    XLAL_CHECK(rng != NULL, XLAL_EFUNC);
    for (size_t i = 0; i < 10; ++i) {

      // Generate random injection points
      XLAL_CHECK(XLALRandomLatticeTilingPoints(tiling, 0.0, rng, injections) == XLAL_SUCCESS, XLAL_EFUNC);

      // Find nearest lattice template points
      XLAL_CHECK(XLALNearestLatticeTilingPoints(loc, injections, &nearest, NULL) == XLAL_SUCCESS, XLAL_EFUNC);

      // Compute mismatch between injections
      gsl_matrix_sub(nearest, injections);
      gsl_blas_dsymm(CblasLeft, CblasUpper, 1.0, metric, nearest, 0.0, temp);
      for (size_t j = 0; j < temp->size2; ++j) {
        gsl_vector_view temp_j = gsl_matrix_column(temp, j);
        gsl_vector_view nearest_j = gsl_matrix_column(nearest, j);
        double mismatch = 0.0;
        gsl_blas_ddot(&nearest_j.vector, &temp_j.vector, &mismatch);
        mismatch /= max_mismatch;

        // Increment mismatch histogram counts
        ++mism_hist_total;
        if (mismatch < 0.0 || mismatch > 1.0) {
          ++mism_hist_out_of_range;
        } else {
          ++mism_hist[lround(floor(mismatch * MISM_HIST_BINS))];
        }

      }

    }

    // Cleanup
    GFMAT(injections, nearest, temp);
    XLALDestroyRandomParams(rng);

  }

  // Normalise histogram
  for (size_t i = 0; i < MISM_HIST_BINS; ++i) {
    mism_hist[i] *= MISM_HIST_BINS / mism_hist_total;
  }

  // Print mismatch histogram and its reference
  printf("Mismatch histogram: ");
  for (size_t i = 0; i < MISM_HIST_BINS; ++i) {
    printf(" %0.3f", mism_hist[i]);
  }
  printf("\n");
  printf("Reference histogram:");
  for (size_t i = 0; i < MISM_HIST_BINS; ++i) {
    printf(" %0.3f", mism_hist_ref[i]);
  }
  printf("\n");

  // Determine error between mismatch histogram and its reference
  double mism_hist_error = 0.0;
  for (size_t i = 0; i < MISM_HIST_BINS; ++i) {
    mism_hist_error += fabs(mism_hist[i] - mism_hist_ref[i]);
  }
  mism_hist_error /= MISM_HIST_BINS;
  printf("Mismatch histogram error: %0.3e\n", mism_hist_error);
  const double mism_hist_error_tol = 5e-2;
  if (mism_hist_error >= mism_hist_error_tol) {
    XLAL_ERROR(XLAL_EFAILED, "ERROR: mismatch histogram error exceeds %0.3e\n", mism_hist_error_tol);
  }

  // Check fraction of injections out of histogram range
  const double mism_out_of_range = mism_hist_out_of_range / mism_hist_total;
  printf("Fraction of points out of histogram range: %0.3e\n", mism_out_of_range);
  const double mism_out_of_range_tol = 2e-3;
  if (mism_out_of_range > mism_out_of_range_tol) {
    XLAL_ERROR(XLAL_EFAILED, "ERROR: fraction of points out of histogram range exceeds %0.3e\n", mism_out_of_range_tol);
  }

  // Perform 10 injections outside parameter space
  {
    gsl_matrix *GAMAT(injections, 3, 10);
    gsl_matrix *GAMAT(nearest, n, total);
    RandomParams *rng = XLALCreateRandomParams(total);
    XLAL_CHECK(rng != NULL, XLAL_EFUNC);

    // Generate random injection points outside parameter space
    XLAL_CHECK(XLALRandomLatticeTilingPoints(tiling, 5.0, rng, injections) == XLAL_SUCCESS, XLAL_EFUNC);

    // Find nearest lattice template points
    XLAL_CHECK(XLALNearestLatticeTilingPoints(loc, injections, &nearest, NULL) == XLAL_SUCCESS, XLAL_EFUNC);

    // Cleanup
    GFMAT(injections, nearest);
    XLALDestroyRandomParams(rng);

  }

  // Cleanup
  XLALDestroyLatticeTiling(tiling);
  XLALDestroyLatticeTilingIterator(itr);
  XLALDestroyLatticeTilingLocator(loc);
  GFMAT(metric, points);
  LALCheckMemoryLeaks();
  printf("\n");
  fflush(stdout);

  return XLAL_SUCCESS;

}
Esempio n. 9
0
///
/// Compute the transform which changes the metric reference time \f$ \tau_0 \rightarrow \tau_1 =
/// \tau_0 + \Delta\tau \f$.
///
/// If \c p_transform is non-NULL, return the reference-time transform in \c *p_transform.
/// If \c p_gpr_ij is non-NULL, apply the transform to the metric \c *p_gpr_ij.
///
/// \note \c *p_gpr_ij and \c *p_transform will be allocated if \c NULL. \c *p_gpr_ij and \c g_ij
/// may point to the same matrix.
///
int
XLALChangeMetricReferenceTime(
  gsl_matrix **p_gpr_ij,			///< [in,out,optional] Pointer to transformed matrix \f$g^{\prime}_{ij}\f$
  gsl_matrix **p_transform,			///< [in,out,optional] Pointer to reference time transform
  const gsl_matrix *g_ij,			///< [in] Matrix to transform \f$g_{ij}\f$
  const DopplerCoordinateSystem *coordSys,	///< [in] Coordinate system of metric
  const double Dtau				///< [in] Difference between new and old reference times \f$\Delta\tau\f$
  )
{

  // Check input
  XLAL_CHECK( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK( g_ij->size1 == g_ij->size2, XLAL_ESIZE );
  if ( p_transform != NULL ) {
    if ( *p_transform != NULL ) {
      XLAL_CHECK( (*p_transform)->size1 == g_ij->size1, XLAL_ESIZE );
      XLAL_CHECK( (*p_transform)->size2 == g_ij->size2, XLAL_ESIZE );
    } else {
      GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
    }
  }
  XLAL_CHECK( coordSys != NULL, XLAL_EFAULT );
  XLAL_CHECK( coordSys->dim == g_ij->size1, XLAL_ESIZE );
  for( size_t i = 0; i < coordSys->dim; ++i ) {
    switch( coordSys->coordIDs[i] ) {
    case DOPPLERCOORD_GC_NU0:
    case DOPPLERCOORD_GC_NU1:
    case DOPPLERCOORD_GC_NU2:
    case DOPPLERCOORD_GC_NU3:
      XLAL_ERROR( XLAL_EINVAL, "GCT coordinates are not supported" );
    default:
      break;
    }
  }

  // Compute transformation matrix for frequency-spindown coordinates
  // from Prix: "Frequency metric for CW searches" (2014-08-17), p. 4
  gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
  gsl_matrix_set_identity( transform );
  if( Dtau != 0.0 ) {
    for( size_t i = 0; i < coordSys->dim; ++i ) {
      const DopplerCoordinateID icoord = coordSys->coordIDs[i];
      if (DOPPLERCOORD_FREQ <= icoord && icoord <= DOPPLERCOORD_LASTFDOT) {
        const size_t ispinorder = icoord - DOPPLERCOORD_FREQ;

        for( size_t j = i + 1; j < coordSys->dim; ++j ) {
          const DopplerCoordinateID jcoord = coordSys->coordIDs[j];
          if (DOPPLERCOORD_FREQ <= jcoord && jcoord <= DOPPLERCOORD_LASTFDOT) {
            const size_t jspinorder = jcoord - DOPPLERCOORD_FREQ;

            if( jspinorder > ispinorder ) {
              const double tij = LAL_FACT_INV[jspinorder - ispinorder] * pow( -1 * Dtau, jspinorder - ispinorder );
              gsl_matrix_set( transform, i, j, tij );
            }

          }
        }

      }
    }
  }

  // Apply transform
  if ( p_gpr_ij != NULL ) {
    XLAL_CHECK( XLALTransformMetric( p_gpr_ij, transform, g_ij ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Return transform
  if ( p_transform != NULL ) {
    gsl_matrix_memcpy( *p_transform, transform );
  }

  // Cleanup
  GFMAT( transform );

  return XLAL_SUCCESS;

} // XLALPhaseMetricRefTimeTransform()
Esempio n. 10
0
///
/// Return a metric in <i>naturalized</i> coordinates.
/// Frequency coordinates of spindown order \f$s\f$ are scaled by
/// \f[ \frac{2\pi}{(s+1)!} \left(\frac{\overline{\Delta T}}{2}\right)^{s+1} \f]
/// where \f$\overline{\Delta T}\equiv\sum_{k}^{N} \Delta T_k\f$ is the average segment-length
/// over all \f$N\f$ segments.
///
/// Sky coordinates are scaled by Holgers' units, see Eq.(44) in PRD82,042002(2010),
/// without the equatorial rotation in alpha:
/// \f[ \frac{2\pi f R_{E}  \cos(\delta_{D})}{c} \f]
/// where \f$f\f$ is the frequency and
/// \f$R_{E}\f$ the Earth radius, and \f$\delta_{D}\f$ is the detectors latitude.
///
/// If \c p_transform is non-NULL, return the naturalization transform in \c *p_transform.
/// If \c p_gpr_ij is non-NULL, apply the transform to the metric \c *p_gpr_ij.
///
/// \note \c *p_gpr_ij and \c *p_transform will be allocated if \c NULL. \c *p_gpr_ij and \c g_ij
/// may point to the same matrix.
///
int
XLALNaturalizeMetric(
  gsl_matrix **p_gpr_ij,			///< [in,out,optional] Pointer to transformed matrix \f$g^{\prime}_{ij}\f$
  gsl_matrix **p_transform,			///< [in,out,optional] Pointer to naturalization transform
  const gsl_matrix *g_ij,			///< [in] Matrix to transform \f$g_{ij}\f$
  const DopplerMetricParams *metricParams	///< [in] Input parameters used to calculate naturalization transform
  )
{

  // Check input
  XLAL_CHECK( g_ij != NULL, XLAL_EFAULT );
  XLAL_CHECK( g_ij->size1 == g_ij->size2, XLAL_ESIZE );
  if ( p_transform != NULL ) {
    if ( *p_transform != NULL ) {
      XLAL_CHECK( (*p_transform)->size1 == g_ij->size1, XLAL_ESIZE );
      XLAL_CHECK( (*p_transform)->size2 == g_ij->size2, XLAL_ESIZE );
    } else {
      GAMAT( *p_transform, g_ij->size1, g_ij->size2 );
    }
  }
  XLAL_CHECK( metricParams != NULL, XLAL_EFAULT );

  // Compute average segment length
  XLAL_CHECK ( XLALSegListIsInitialized ( &(metricParams->segmentList) ), XLAL_EINVAL, "Passed un-initialzied segment list 'metricParams->segmentList'\n");
  UINT4 Nseg = metricParams->segmentList.length;
  REAL8 sumTseg = 0;
  for ( UINT4 k=0; k < Nseg; k ++ )
    {
      LIGOTimeGPS *startTime_k = &(metricParams->segmentList.segs[k].start);
      LIGOTimeGPS *endTime_k   = &(metricParams->segmentList.segs[k].end);
      sumTseg += XLALGPSDiff( endTime_k, startTime_k );
    }
  REAL8 avgTseg = sumTseg / Nseg;

  // Compute naturalization transform
  gsl_matrix *GAMAT( transform, g_ij->size1, g_ij->size2 );
  gsl_matrix_set_zero( transform );
  for (size_t i = 0; i < g_ij->size1; ++i) {
    const DopplerCoordinateID coordID = metricParams->coordSys.coordIDs[i];
    const double Freq = metricParams->signalParams.Doppler.fkdot[0];
    const double T = avgTseg;
    double scale = 0;
    switch (coordID) {
    case DOPPLERCOORD_NONE:
      scale = 1;
      break;

    case DOPPLERCOORD_FREQ:
    case DOPPLERCOORD_GC_NU0:
      scale = LAL_TWOPI * LAL_FACT_INV[1] * (0.5 * T);
      break;

    case DOPPLERCOORD_F1DOT:
    case DOPPLERCOORD_GC_NU1:
      scale = LAL_TWOPI * LAL_FACT_INV[2] * POW2(0.5 * T);
      break;

    case DOPPLERCOORD_F2DOT:
    case DOPPLERCOORD_GC_NU2:
      scale = LAL_TWOPI * LAL_FACT_INV[3] * POW3(0.5 * T);
      break;

    case DOPPLERCOORD_F3DOT:
    case DOPPLERCOORD_GC_NU3:
      scale = LAL_TWOPI * LAL_FACT_INV[4] * POW4(0.5 * T);
      break;

    case DOPPLERCOORD_ALPHA:
    case DOPPLERCOORD_DELTA:
    case DOPPLERCOORD_N2X_EQU:
    case DOPPLERCOORD_N2Y_EQU:
    case DOPPLERCOORD_N2X_ECL:
    case DOPPLERCOORD_N2Y_ECL:
    case DOPPLERCOORD_N3X_EQU:
    case DOPPLERCOORD_N3Y_EQU:
    case DOPPLERCOORD_N3Z_EQU:
    case DOPPLERCOORD_N3X_ECL:
    case DOPPLERCOORD_N3Y_ECL:
    case DOPPLERCOORD_N3Z_ECL:
    case DOPPLERCOORD_N3SX_EQU:
    case DOPPLERCOORD_N3SY_EQU:
    case DOPPLERCOORD_N3OX_ECL:
    case DOPPLERCOORD_N3OY_ECL:
      {
        const REAL8 rEarth_c = (LAL_REARTH_SI / LAL_C_SI);
        REAL8 cosdD = cos ( metricParams->multiIFO.sites[0].frDetector.vertexLatitudeRadians );
        scale = LAL_TWOPI * Freq * rEarth_c * cosdD;
      }
      break;

    default:
      scale = 1;
      break;
    } // switch(coordID)
    gsl_matrix_set( transform, i, i, 1.0 / scale );
  }

  // Apply transform
  if ( p_gpr_ij != NULL ) {
    XLAL_CHECK( XLALTransformMetric( p_gpr_ij, transform, g_ij ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Return transform
  if ( p_transform != NULL ) {
    gsl_matrix_memcpy( *p_transform, transform );
  }

  // Cleanup
  GFMAT( transform );

  return XLAL_SUCCESS;

} // XLALNaturalizeMetric()
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;

}