Exemple #1
0
int
gsl_eigen_jacobi (gsl_matrix * a,
                  gsl_vector * eval,
                  gsl_matrix * evec, unsigned int max_rot, unsigned int *nrot)
{
  size_t i, p, q;
  const size_t M = a->size1, N = a->size2;
  double red, redsum = 0.0;

  if (M != N)
    {
      GSL_ERROR ("eigenproblem requires square matrix", GSL_ENOTSQR);
    }
  else if (M != evec->size1 || M != evec->size2)
    {
      GSL_ERROR ("eigenvector matrix must match input matrix", GSL_EBADLEN);
    }
  else if (M != eval->size)
    {
      GSL_ERROR ("eigenvalue vector must match input matrix", GSL_EBADLEN);
    }

  gsl_vector_set_zero (eval);
  gsl_matrix_set_identity (evec);

  for (i = 0; i < max_rot; i++)
    {
      double nrm = norm (a);

      if (nrm == 0.0)
        break;

      for (p = 0; p < N; p++)
        {
          for (q = p + 1; q < N; q++)
            {
              double c, s;

              red = symschur2 (a, p, q, &c, &s);
              redsum += red;

              /* Compute A <- J^T A J */
              apply_jacobi_L (a, p, q, c, s);
              apply_jacobi_R (a, p, q, c, s);

              /* Compute V <- V J */
              apply_jacobi_R (evec, p, q, c, s);
            }
        }
    }

  *nrot = i;

  for (p = 0; p < N; p++)
    {
      double ep = gsl_matrix_get (a, p, p);
      gsl_vector_set (eval, p, ep);
    }

  if (i == max_rot)
    {
      return GSL_EMAXITER;
    }

  return GSL_SUCCESS;
}
void jacobi2Sided(real (*A)[3], real (*U)[3], real (*V)[3]) {
    int p, q;
    real w, x, y, z, m1, m2, c, s, r, c1, c2, s1, s2, r2, t2, d1, d2, k, tmp;
    int flg;
    int cnt = 3;

    while (cnt--) {
        for (p = 1; p < 3; p++) {
            for (q = 0; q < p; q++) {
                w = A[p][p];
                x = A[p][q];
                y = A[q][p];
                z = A[q][q];
                flg = 0;
                if (y == 0 && z == 0) {
                    y = x;
                    x = 0;
                    flg = 1;
                }

                m1 = w + z;
                m2 = x - y;
                if (fabsv(m2) <= TOL * fabsv(m1)) {
                    c = 1;
                    s = 0;
                } else {
                    r = m1 / m2;
                    s = SIGN(r) / sqrtv(1 + r * r);
                    c = s * r;
                }

                m1 = s * (x + y) + c * (z - w);
                m2 = 2 * (c * x - s * z);
                if (fabsv(m2) <= TOL * fabsv(m1)) {
                    c2 = 1;
                    s2 = 0;
                } else {
                    r2 = m1 / m2;
                    t2 = SIGN(r2) / (fabsv(r2) + sqrtv(1 + r2 * r2)); //%use hypot..?
                    c2 = 1 / sqrtv(1 + t2 * t2);
                    s2 = c2 * t2;
                }
                c1 = c2 * c - s2 * s;
                s1 = s2 * c + c2 * s;

                if (flg == 1) {
                    c2 = c1;
                    s2 = s1;
                    c1 = 1;
                    s1 = 0;
                }
                d1 = c1 * (w * c2 - x * s2) - s1 * (y * c2 - z * s2);
                d2 = s1 * (w * s2 + x * c2) + c1 * (y * s2 + z * c2);

                if (fabsv(d1) > fabsv(d2)) {
                    tmp = c1;
                    c1 = -s1;
                    s1 = tmp;
                    tmp = c2;
                    c2 = -s2;
                    s2 = tmp;
                    tmp = d2;
                    d2 = d1;
                    d1 = tmp;
                }

                k = 1;
                if (d1 < 0) {
                    c1 = -c1;
                    s1 = -s1;
                    k = -k;
                }
                if (d2 < 0) {
                    k = -k;
                }
                apply_jacobi_L(A, p, q, c1, s1, k);
                apply_jacobi_R(A, p, q, c2, s2, 1);
                apply_jacobi_R(U, p, q, c1, s1, k);
                apply_jacobi_R(V, p, q, c2, s2, 1);
            }
        }
    }
}