static int pcholesky_swap_rowcol(gsl_matrix * m, const size_t i, const size_t j) { if (i != j) { const size_t N = m->size1; size_t k; /* fill in column i above diagonal using lower triangle */ for (k = 0; k < i; ++k) { double mki = gsl_matrix_get(m, i, k); gsl_matrix_set(m, k, i, mki); } /* fill in row i above diagonal using lower triangle */ for (k = i + 1; k < N; ++k) { double mik = gsl_matrix_get(m, k, i); gsl_matrix_set(m, i, k, mik); } /* fill in column j above diagonal using lower triangle */ for (k = 0; k < j; ++k) { double mkj = gsl_matrix_get(m, j, k); gsl_matrix_set(m, k, j, mkj); } /* fill in row j above diagonal using lower triangle */ for (k = j + 1; k < N; ++k) { double mjk = gsl_matrix_get(m, k, j); gsl_matrix_set(m, j, k, mjk); } gsl_matrix_swap_rows(m, i, j); gsl_matrix_swap_columns(m, i, j); } return GSL_SUCCESS; }
/** * reorderRows: * Finds the leftmost row beginning from start, ignoring everything to the * left of leftCol. Puts this row at 'start', swapping with the original. * Assumes that the matrix is set up as [N I]. * Returns the new value of leftCol * If there are no appropriate rows, returns numReacs. */ int reorderRows( gsl_matrix* U, int start, int leftCol ) { int leftMostRow = start; int numReacs = U->size2 - U->size1; int newLeftCol = numReacs; for ( size_t i = start; i < U->size1; ++i ) { for ( int j = leftCol; j < numReacs; ++j ) { if ( fabs( gsl_matrix_get( U, i, j ) ) > SteadyState::EPSILON ){ if ( j < newLeftCol ) { newLeftCol = j; leftMostRow = i; } break; } } } if ( leftMostRow != start ) { // swap them. gsl_matrix_swap_rows( U, start, leftMostRow ); } return newLeftCol; }
int gsl_linalg_PTLQ_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm) { const size_t N = A->size1; const size_t M = A->size2; if (tau->size != GSL_MIN (M, N)) { GSL_ERROR ("size of tau must be MIN(M,N)", GSL_EBADLEN); } else if (p->size != N) { GSL_ERROR ("permutation size must be N", GSL_EBADLEN); } else if (norm->size != N) { GSL_ERROR ("norm size must be N", GSL_EBADLEN); } else { size_t i; *signum = 1; gsl_permutation_init (p); /* set to identity */ /* Compute column norms and store in workspace */ for (i = 0; i < N; i++) { gsl_vector_view c = gsl_matrix_row (A, i); double x = gsl_blas_dnrm2 (&c.vector); gsl_vector_set (norm, i, x); } for (i = 0; i < GSL_MIN (M, N); i++) { /* Bring the column of largest norm into the pivot position */ double max_norm = gsl_vector_get(norm, i); size_t j, kmax = i; for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > max_norm) { max_norm = x; kmax = j; } } if (kmax != i) { gsl_matrix_swap_rows (A, i, kmax); gsl_permutation_swap (p, i, kmax); gsl_vector_swap_elements(norm,i,kmax); (*signum) = -(*signum); } /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ { gsl_vector_view c_full = gsl_matrix_row (A, i); gsl_vector_view c = gsl_vector_subvector (&c_full.vector, i, M - i); double tau_i = gsl_linalg_householder_transform (&c.vector); gsl_vector_set (tau, i, tau_i); /* Apply the transformation to the remaining columns */ if (i + 1 < N) { gsl_matrix_view m = gsl_matrix_submatrix (A, i +1, i, N - (i+1), M - i); gsl_linalg_householder_mh (tau_i, &c.vector, &m.matrix); } } /* Update the norms of the remaining columns too */ if (i + 1 < M) { for (j = i + 1; j < N; j++) { double x = gsl_vector_get (norm, j); if (x > 0.0) { double y = 0; double temp= gsl_matrix_get (A, j, i) / x; if (fabs (temp) >= 1) y = 0.0; else y = x * sqrt (1 - temp * temp); /* recompute norm to prevent loss of accuracy */ if (fabs (y / x) < sqrt (20.0) * GSL_SQRT_DBL_EPSILON) { gsl_vector_view c_full = gsl_matrix_row (A, j); gsl_vector_view c = gsl_vector_subvector(&c_full.vector, i+1, M - (i+1)); y = gsl_blas_dnrm2 (&c.vector); } gsl_vector_set (norm, j, y); } } } } return GSL_SUCCESS; } }
/** * Compute a flat approximation for the continuous-wave metric (by neglecting the z-motion of * the detector in ecliptic coordinates. * * gij has to be an allocated symmetric matrix of dimension \a dim: the order of coordinates * is \f$[ \omega_0, \tilde{n}_x, \tilde{n}_y, \omega_1, \omega_2, ... ]\f$, * but \a dim must be at least 3 and maximally 6 (Freq + 2 sky + 3 spin-downs) * The dimensionless coordinates are defined as * \f$\omega_s \equiv 2\pi \, f^{(s)}\, T^{s+1} / (s+1)!\f$ in terms of the observation time \f$T\f$, * and \f$\tilde{n}_l \equiv 2\pi \bar{f} \hat{n} R_{orb} / c\f$, where \f$R_{orb}\f$ is the orbital * radius (AU). * */ int XLALFlatMetricCW ( gsl_matrix *gij, /**< [out] metric */ LIGOTimeGPS refTime, /**< [in] reference time for spin-parameters */ LIGOTimeGPS startTime, /**< [in] startTime */ REAL8 Tspan, /**< [in] total observation time spanned */ const EphemerisData *edat /**< [in] ephemeris data */ ) { UINT4 dim, numSpins, s, sp; REAL8 gg; cov_params_t params; if ( !gij || ( gij->size1 != gij->size2 ) || !edat ) return -1; dim = gij->size1; if ( dim < 3 || dim > 6 ) { XLALPrintError ("\nMetric dimension must be 3 <= dim <= 6!\n\n"); return -1; } numSpins = dim - 2; params.edat = edat; params.refTime = XLALGPSGetREAL8 ( &refTime ); params.startTime = XLALGPSGetREAL8 ( &startTime ); params.Tspan = Tspan; /* gXX */ params.comp1 = COMP_RX; params.comp2 = COMP_RX; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, 0, 0, gg); /* gYY */ params.comp1 = COMP_RY; params.comp2 = COMP_RY; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, 1, 1, gg); /* gXY */ params.comp1 = COMP_RX; params.comp2 = COMP_RY; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, 0, 1, gg); gsl_matrix_set (gij, 1, 0, gg); /* spins */ for ( s=0; s < numSpins; s ++ ) { params.comp1 = COMP_RX; params.comp2 = (component_t) s; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, 0, s+2, gg); gsl_matrix_set (gij, s+2, 0, gg); params.comp1 = COMP_RY; params.comp2 = (component_t) s; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, 1, s+2, gg); gsl_matrix_set (gij, s+2, 1, gg); for ( sp = s; sp < numSpins; sp ++ ) { params.comp1 = (component_t) s; params.comp2 = (component_t) sp; gg = cov_Phi_ij ( ¶ms ); gsl_matrix_set (gij, s+2, sp+2, gg); gsl_matrix_set (gij, sp+2, s+2, gg); } /* for sp in [s, numSpins) */ } /* for s < numSpins */ /* get metric from {nxt, nyt, w0, w1, w2,..} into 'canonical' order {w0, nxt, nyt, w1, w2, ... } */ gsl_matrix_swap_rows (gij, 0, 2); /* swap w0 <--> kx */ gsl_matrix_swap_rows (gij, 1, 2); /* swap kx <--> ky */ gsl_matrix_swap_columns (gij, 0, 2); /* swap w0 <--> kx */ gsl_matrix_swap_columns (gij, 1, 2); /* swap kx <--> ky */ /* Ok */ return 0; } /* XLALFlatMetricCW() */