Esempio n. 1
0
int crearcarh (gsl_matrix* input)
{
  FILE *out;
  out = fopen("autovectores_3D_data.dat", "w");
  gsl_matrix_swap_columns (input, 0, 2);

  fprintf(out , "%f %f %f \n %f %f %f \n %f %f %f" ,gsl_matrix_get (input, 0,0), gsl_matrix_get (input, 1,0) ,gsl_matrix_get (input, 2,0),gsl_matrix_get (input, 0,1), gsl_matrix_get (input, 1,1) ,gsl_matrix_get (input, 2,1),gsl_matrix_get (input, 0,2), gsl_matrix_get (input, 1,2) ,gsl_matrix_get (input, 2,2));

return 0;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
int
gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, 
                      gsl_vector * work)
{
  size_t a, b, i, j, iter;

  const size_t M=A->size1;
  const size_t N=A->size2;
  size_t K;
  if (M<N) K=M;
  else K=N;

  if (M < N)
    {
      GSL_ERROR ("svd of MxN matrix, M<N, is not implemented", GSL_EUNIMPL);
    }
  else if (V->size1 != N)
    {
      GSL_ERROR ("square matrix V must match second dimension of matrix A",
                 GSL_EBADLEN);
    }
  else if (V->size1 != V->size2)
    {
      GSL_ERROR ("matrix V must be square", GSL_ENOTSQR);
    }
  else if (S->size != N)
    {
      GSL_ERROR ("length of vector S must match second dimension of matrix A",
                 GSL_EBADLEN);
    }
  else if (work->size != N)
    {
      GSL_ERROR ("length of workspace must match second dimension of matrix A",
                 GSL_EBADLEN);
    }

  /* Handle the case of N=1 (SVD of a column vector) */

  if (N == 1)
    {
      gsl_vector_view column=gsl_matrix_column (A, 0);
      double norm=gsl_blas_dnrm2 (&column.vector);

      gsl_vector_set (S, 0, norm); 
      gsl_matrix_set (V, 0, 0, 1.0);
      
      if (norm != 0.0)
        {
          gsl_blas_dscal (1.0/norm, &column.vector);
        }

      return GSL_SUCCESS;
    }
  
  {
    gsl_vector_view f=gsl_vector_subvector (work, 0, K - 1);
    
    /* bidiagonalize matrix A, unpack A into U S V */
    
    gsl_linalg_bidiag_decomp (A, S, &f.vector);

    //std::cout << "A: " << gsl_matrix_get(A,0,0) << " "
    //<< gsl_matrix_get(A,M-1,N-1) << std::endl;
    //std::cout << "S: " << S->data[0] << " " 
    //<< S->data[S->size-1] 
    //<< std::endl;
    
    gsl_linalg_bidiag_unpack2 (A, S, &f.vector, V);

    //std::cout << "S2: " << S->data[0] << " " 
    //<< S->data[S->size-1] 
    //<< std::endl;
    
    /* apply reduction steps to B=(S,Sd) */
    
    chop_small_elements (S, &f.vector);
    
    //std::cout << "S3: " << S->data[0] << " " 
    //<< S->data[S->size-1] 
    //<< std::endl;
    
    /* Progressively reduce the matrix until it is diagonal */
    
    b=N - 1;
    iter=0;

    while (b > 0)
      {
        double fbm1=gsl_vector_get (&f.vector, b - 1);

        if (fbm1 == 0.0 || gsl_isnan (fbm1))
          {
            b--;
            continue;
          }

	//std::cout << "b,fbm1: " << b << " " << fbm1 << std::endl;
        
        /* Find the largest unreduced block (a,b) starting from b
           and working backwards */

        a=b - 1;

        while (a > 0)
          {
            double fam1=gsl_vector_get (&f.vector, a - 1);

            if (fam1 == 0.0 || gsl_isnan (fam1))
              {
                break;
              }
            
            a--;

	    //std::cout << "a,fam1: " << a << " " << fam1 << std::endl;
          }

        iter++;
        
        if (iter > 100 * N) 
          {
            GSL_ERROR("SVD decomposition failed to converge", GSL_EMAXITER);
          }

        
        {
          const size_t n_block=b - a + 1;
          gsl_vector_view S_block=gsl_vector_subvector (S, a, n_block);
          gsl_vector_view f_block=gsl_vector_subvector 
	    (&f.vector, a, n_block - 1);
          
          gsl_matrix_view U_block =
            gsl_matrix_submatrix (A, 0, a, A->size1, n_block);
          gsl_matrix_view V_block =
            gsl_matrix_submatrix (V, 0, a, V->size1, n_block);
          
          int rescale=0;
          double scale=1; 
          double norm=0;

          /* Find the maximum absolute values of the diagonal and subdiagonal */

          for (i=0; i < n_block; i++) 
            {
              double s_i=gsl_vector_get (&S_block.vector, i);
              double a=fabs(s_i);
              if (a > norm) norm=a;
	      //std::cout << "aa: " << a << std::endl;
            }

          for (i=0; i < n_block - 1; i++) 
            {
              double f_i=gsl_vector_get (&f_block.vector, i);
              double a=fabs(f_i);
              if (a > norm) norm=a;
	      //std::cout << "aa2: " << a << std::endl;
            }

          /* Temporarily scale the submatrix if necessary */

          if (norm > GSL_SQRT_DBL_MAX)
            {
              scale=(norm / GSL_SQRT_DBL_MAX);
              rescale=1;
            }
          else if (norm < GSL_SQRT_DBL_MIN && norm > 0)
            {
              scale=(norm / GSL_SQRT_DBL_MIN);
              rescale=1;
            }

	  //std::cout << "rescale: " << rescale << std::endl;

          if (rescale) 
            {
              gsl_blas_dscal(1.0 / scale, &S_block.vector);
              gsl_blas_dscal(1.0 / scale, &f_block.vector);
            }

          /* Perform the implicit QR step */

	  /*
	  for(size_t ii=0;ii<M;ii++) {
	    for(size_t jj=0;jj<N;jj++) {
	    std::cout << ii << "." << jj << "." 
	    << gsl_matrix_get(A,ii,jj) << std::endl;
	    }
	  }
	  for(size_t ii=0;ii<N;ii++) {
	    for(size_t jj=0;jj<N;jj++) {
	    std::cout << "V: " << ii << "." << jj << "." 
	    << gsl_matrix_get(V,ii,jj) << std::endl;
	    }
	  }
	  */

          qrstep (&S_block.vector, &f_block.vector, &U_block.matrix, 
		  &V_block.matrix);

	  /*
	  for(size_t ii=0;ii<M;ii++) {
	    for(size_t jj=0;jj<N;jj++) {
	    std::cout << ii << " " << jj << " " 
	    << gsl_matrix_get(A,ii,jj) << std::endl;
	    }
	  }
	  for(size_t ii=0;ii<N;ii++) {
	    for(size_t jj=0;jj<N;jj++) {
	    std::cout << "V: " << ii << " " << jj << " " 
	    << gsl_matrix_get(V,ii,jj) << std::endl;
	    }
	  }
	  */

          /* remove any small off-diagonal elements */
          
          chop_small_elements (&S_block.vector, &f_block.vector);
          
          /* Undo the scaling if needed */

          if (rescale)
            {
              gsl_blas_dscal(scale, &S_block.vector);
              gsl_blas_dscal(scale, &f_block.vector);
            }
        }
        
      }
  }

  /* Make singular values positive by reflections if necessary */
  
  for (j=0; j < K; j++)
    {
      double Sj=gsl_vector_get (S, j);
      
      if (Sj < 0.0)
        {
          for (i=0; i < N; i++)
            {
              double Vij=gsl_matrix_get (V, i, j);
              gsl_matrix_set (V, i, j, -Vij);
            }
          
          gsl_vector_set (S, j, -Sj);
        }
    }
  
  /* Sort singular values into decreasing order */
  
  for (i=0; i < K; i++)
    {
      double S_max=gsl_vector_get (S, i);
      size_t i_max=i;
      
      for (j=i + 1; j < K; j++)
        {
          double Sj=gsl_vector_get (S, j);
          
          if (Sj > S_max)
            {
              S_max=Sj;
              i_max=j;
            }
        }
      
      if (i_max != i)
        {
          /* swap eigenvalues */
          gsl_vector_swap_elements (S, i, i_max);
          
          /* swap eigenvectors */
          gsl_matrix_swap_columns (A, i, i_max);
          gsl_matrix_swap_columns (V, i, i_max);
        }
    }
  
  return GSL_SUCCESS;
}
Esempio n. 4
0
  void svd2 (gsl_vector * d, gsl_vector * f, gsl_matrix * U, 
	     gsl_matrix * V) {
    size_t i;
    double c, s, a11, a12, a21, a22;

    const size_t M=U->size1;
    const size_t N=V->size1;

    double d0=gsl_vector_get (d, 0);
    double f0=gsl_vector_get (f, 0);
  
    double d1=gsl_vector_get (d, 1);

    if (d0 == 0.0)
      {
	/* Eliminate off-diagonal element in [0,f0;0,d1] to make [d,0;0,0] */

	create_givens (f0, d1, &c, &s);

	/* compute B <= G^T B X,  where X=[0,1;1,0] */

	gsl_vector_set (d, 0, c * f0 - s * d1);
	gsl_vector_set (f, 0, s * f0 + c * d1);
	gsl_vector_set (d, 1, 0.0);

	/* Compute U <= U G */

	for (i=0; i < M; i++)
	  {
	    double Uip=gsl_matrix_get (U, i, 0);
	    double Uiq=gsl_matrix_get (U, i, 1);
	    gsl_matrix_set (U, i, 0, c * Uip - s * Uiq);
	    gsl_matrix_set (U, i, 1, s * Uip + c * Uiq);
	  }

	/* Compute V <= V X */

	gsl_matrix_swap_columns (V, 0, 1);

	return;
      }
    else if (d1 == 0.0)
      {
	/* Eliminate off-diagonal element in [d0,f0;0,0] */

	create_givens (d0, f0, &c, &s);

	/* compute B <= B G */

	gsl_vector_set (d, 0, d0 * c - f0 * s);
	gsl_vector_set (f, 0, 0.0);

	/* Compute V <= V G */

	for (i=0; i < N; i++)
	  {
	    double Vip=gsl_matrix_get (V, i, 0);
	    double Viq=gsl_matrix_get (V, i, 1);
	    gsl_matrix_set (V, i, 0, c * Vip - s * Viq);
	    gsl_matrix_set (V, i, 1, s * Vip + c * Viq);
	  }

	return;
      }
    else
      {
	/* Make columns orthogonal, A=[d0, f0; 0, d1] * G */

	create_schur (d0, f0, d1, &c, &s);

	/* compute B <= B G */
      
	a11=c * d0 - s * f0;
	a21=- s * d1;
      
	a12=s * d0 + c * f0;
	a22=c * d1;
      
	/* Compute V <= V G */
      
	for (i=0; i < N; i++)
	  {
	    double Vip=gsl_matrix_get (V, i, 0);
	    double Viq=gsl_matrix_get (V, i, 1);
	    gsl_matrix_set (V, i, 0, c * Vip - s * Viq);
	    gsl_matrix_set (V, i, 1, s * Vip + c * Viq);
	  }
      
	/* Eliminate off-diagonal elements, bring column with largest
	   norm to first column */
      
	if (hypot(a11, a21) < hypot(a12,a22))
	  {
	    double t1, t2;

	    /* B <= B X */

	    t1=a11; a11=a12; a12=t1;
	    t2=a21; a21=a22; a22=t2;

	    /* V <= V X */

	    gsl_matrix_swap_columns(V, 0, 1);
	  } 

	create_givens (a11, a21, &c, &s);
      
	/* compute B <= G^T B */
      
	gsl_vector_set (d, 0, c * a11 - s * a21);
	gsl_vector_set (f, 0, c * a12 - s * a22);
	gsl_vector_set (d, 1, s * a12 + c * a22);
      
	/* Compute U <= U G */
      
	for (i=0; i < M; i++)
	  {
	    double Uip=gsl_matrix_get (U, i, 0);
	    double Uiq=gsl_matrix_get (U, i, 1);
	    gsl_matrix_set (U, i, 0, c * Uip - s * Uiq);
	    gsl_matrix_set (U, i, 1, s * Uip + c * Uiq);
	  }

	return;
      }
  }
Esempio n. 5
0
int
gsl_linalg_QRPT_decomp (gsl_matrix * A, gsl_vector * tau, gsl_permutation * p, int *signum, gsl_vector * norm)
{
  const size_t M = A->size1;
  const size_t N = 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_column (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_columns (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_column (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, i + 1, M - i, N - (i+1));

                gsl_linalg_householder_hm (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, i, j) / 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_column (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;
    }
}
Esempio n. 6
0
int
gsl_eigen_symmv_sort (gsl_vector * eval, gsl_matrix * evec, 
                      gsl_eigen_sort_t sort_type)
{
  if (evec->size1 != evec->size2)
    {
      GSL_ERROR ("eigenvector matrix must be square", GSL_ENOTSQR);
    }
  else if (eval->size != evec->size1)
    {
      GSL_ERROR ("eigenvalues must match eigenvector matrix", GSL_EBADLEN);
    }
  else
    {
      const size_t N = eval->size;
      size_t i;

      for (i = 0; i < N - 1; i++)
        {
          size_t j;
          size_t k = i;

          double ek = gsl_vector_get (eval, i);

          /* search for something to swap */
          for (j = i + 1; j < N; j++)
            {
              int test;
              const double ej = gsl_vector_get (eval, j);

              switch (sort_type)
                {       
                case GSL_EIGEN_SORT_VAL_ASC:
                  test = (ej < ek);
                  break;
                case GSL_EIGEN_SORT_VAL_DESC:
                  test = (ej > ek);
                  break;
                case GSL_EIGEN_SORT_ABS_ASC:
                  test = (fabs (ej) < fabs (ek));
                  break;
                case GSL_EIGEN_SORT_ABS_DESC:
                  test = (fabs (ej) > fabs (ek));
                  break;
                default:
                  GSL_ERROR ("unrecognized sort type", GSL_EINVAL);
                }

              if (test)
                {
                  k = j;
                  ek = ej;
                }
            }

          if (k != i)
            {
              /* swap eigenvalues */
              gsl_vector_swap_elements (eval, i, k);

              /* swap eigenvectors */
              gsl_matrix_swap_columns (evec, i, k);
            }
        }

      return GSL_SUCCESS;
    }
}
Esempio n. 7
0
int
gsl_linalg_SV_decomp (gsl_matrix * A, gsl_matrix * V, gsl_vector * S, 
                      gsl_vector * work)
{
  size_t a, b, i, j, iter;

  const size_t M = A->size1;
  const size_t N = A->size2;
  const size_t K = GSL_MIN (M, N);

  if (M < N)
    {
      GSL_ERROR ("svd of MxN matrix, M<N, is not implemented", GSL_EUNIMPL);
    }
  else if (V->size1 != N)
    {
      GSL_ERROR ("square matrix V must match second dimension of matrix A",
                 GSL_EBADLEN);
    }
  else if (V->size1 != V->size2)
    {
      GSL_ERROR ("matrix V must be square", GSL_ENOTSQR);
    }
  else if (S->size != N)
    {
      GSL_ERROR ("length of vector S must match second dimension of matrix A",
                 GSL_EBADLEN);
    }
  else if (work->size != N)
    {
      GSL_ERROR ("length of workspace must match second dimension of matrix A",
                 GSL_EBADLEN);
    }

  /* Handle the case of N = 1 (SVD of a column vector) */

  if (N == 1)
    {
      gsl_vector_view column = gsl_matrix_column (A, 0);
      double norm = gsl_blas_dnrm2 (&column.vector);

      gsl_vector_set (S, 0, norm); 
      gsl_matrix_set (V, 0, 0, 1.0);
      
      if (norm != 0.0)
        {
          gsl_blas_dscal (1.0/norm, &column.vector);
        }

      return GSL_SUCCESS;
    }
  
  {
    gsl_vector_view f = gsl_vector_subvector (work, 0, K - 1);
    
    /* bidiagonalize matrix A, unpack A into U S V */
    
    gsl_linalg_bidiag_decomp (A, S, &f.vector);
    gsl_linalg_bidiag_unpack2 (A, S, &f.vector, V);
    
    /* apply reduction steps to B=(S,Sd) */
    
    chop_small_elements (S, &f.vector);
    
    /* Progressively reduce the matrix until it is diagonal */
    
    b = N - 1;
    iter = 0;

    while (b > 0)
      {
        double fbm1 = gsl_vector_get (&f.vector, b - 1);

        if (fbm1 == 0.0 || gsl_isnan (fbm1))
          {
            b--;
            continue;
          }
        
        /* Find the largest unreduced block (a,b) starting from b
           and working backwards */
        
        a = b - 1;
        
        while (a > 0)
          {
            double fam1 = gsl_vector_get (&f.vector, a - 1);

            if (fam1 == 0.0 || gsl_isnan (fam1))
              {
                break;
              }
            
            a--;
          }

        iter++;
        
        if (iter > 100 * N) 
          {
            GSL_ERROR("SVD decomposition failed to converge", GSL_EMAXITER);
          }

        
        {
          const size_t n_block = b - a + 1;
          gsl_vector_view S_block = gsl_vector_subvector (S, a, n_block);
          gsl_vector_view f_block = gsl_vector_subvector (&f.vector, a, n_block - 1);
          
          gsl_matrix_view U_block =
            gsl_matrix_submatrix (A, 0, a, A->size1, n_block);
          gsl_matrix_view V_block =
            gsl_matrix_submatrix (V, 0, a, V->size1, n_block);
          
          qrstep (&S_block.vector, &f_block.vector, &U_block.matrix, &V_block.matrix);
          
          /* remove any small off-diagonal elements */
          
          chop_small_elements (&S_block.vector, &f_block.vector);
        }
      }
  }
  /* Make singular values positive by reflections if necessary */
  
  for (j = 0; j < K; j++)
    {
      double Sj = gsl_vector_get (S, j);
      
      if (Sj < 0.0)
        {
          for (i = 0; i < N; i++)
            {
              double Vij = gsl_matrix_get (V, i, j);
              gsl_matrix_set (V, i, j, -Vij);
            }
          
          gsl_vector_set (S, j, -Sj);
        }
    }
  
  /* Sort singular values into decreasing order */
  
  for (i = 0; i < K; i++)
    {
      double S_max = gsl_vector_get (S, i);
      size_t i_max = i;
      
      for (j = i + 1; j < K; j++)
        {
          double Sj = gsl_vector_get (S, j);
          
          if (Sj > S_max)
            {
              S_max = Sj;
              i_max = j;
            }
        }
      
      if (i_max != i)
        {
          /* swap eigenvalues */
          gsl_vector_swap_elements (S, i, i_max);
          
          /* swap eigenvectors */
          gsl_matrix_swap_columns (A, i, i_max);
          gsl_matrix_swap_columns (V, i, i_max);
        }
    }
  
  return GSL_SUCCESS;
}
Esempio n. 8
0
// Reverse the columns of a matrix
void shapeAlign::reverse(gsl_matrix* rev){
	for (size_t i = 0; i < rev->size2/2; i++)
		gsl_matrix_swap_columns(rev,i,rev->size2-i-1);
	return;
}
Esempio n. 9
0
/**
 * 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 ( &params );

  gsl_matrix_set (gij, 0, 0, gg);
  /* gYY */
  params.comp1 = COMP_RY;
  params.comp2 = COMP_RY;
  gg = cov_Phi_ij ( &params );

  gsl_matrix_set (gij, 1, 1, gg);
  /* gXY */
  params.comp1 = COMP_RX;
  params.comp2 = COMP_RY;
  gg = cov_Phi_ij ( &params );

  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 ( &params );

      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 ( &params );

      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 ( &params );

	  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() */