Ejemplo n.º 1
0
/*
 * highly inefficient computation of the imaginary part of complex 
 * conjugate eigenvalues of a 3x3 non-symmetric matrix
 */ 
double
gage_imaginary_part_eigenvalues( gage_t *M ) {
    double A, B, C, scale, frob, m[9], _eval[3];
    double beta, gamma;
    int roots;

    frob = ELL_3M_FROB(M);
    scale = frob > 10 ? 10.0/frob : 1.0;
    ELL_3M_SCALE(m, scale, M);
    /* 
    ** from gordon with mathematica; these are the coefficients of the
    ** cubic polynomial in x: det(x*I - M).  The full cubic is
    ** x^3 + A*x^2 + B*x + C.
    */
    A = -m[0] - m[4] - m[8];
    B = m[0]*m[4] - m[3]*m[1] 
        + m[0]*m[8] - m[6]*m[2] 
        + m[4]*m[8] - m[7]*m[5];
    C = (m[6]*m[4] - m[3]*m[7])*m[2]
        + (m[0]*m[7] - m[6]*m[1])*m[5]
        + (m[3]*m[1] - m[0]*m[4])*m[8];
    roots = ell_cubic(_eval, A, B, C, AIR_TRUE);
    if ( roots != ell_cubic_root_single )
        return 0.;

    /* 2 complex conjuguate eigenvalues */
    beta = A + _eval[0];
    gamma = -C/_eval[0];
    return sqrt( 4.*gamma - beta*beta );
}
Ejemplo n.º 2
0
/*
******** ell_3m_eigenvalues_d()
**
** finds eigenvalues of given matrix.
**
** returns information about the roots according to ellCubeRoot enum,
** see header for ellCubic for details.
**
** given matrix is NOT modified
**
** This does NOT use biff
**
** Doing the frobenius normalization proved successfull in avoiding the
** the creating of NaN eigenvalues when the coefficients of the matrix
** were really large (> 50000).  Also, when the matrix norm was really
** small, the comparison to "epsilon" in ell_cubic mistook three separate
** roots for a single and a double, with this matrix in particular:
**  1.7421892  0.0137642  0.0152975
**  0.0137642  1.7565432 -0.0062296
**  0.0152975 -0.0062296  1.7700019
** (actually, this is prior to tenEigensolve's isotropic removal)
**
** HEY: tenEigensolve_d and tenEigensolve_f start by removing the
** isotropic part of the tensor.  It may be that that smarts should
** be migrated here, but GLK is uncertain how it would change the
** handling of non-symmetric matrices.
*/
int
ell_3m_eigenvalues_d(double _eval[3], const double _m[9], const int newton) {
  double A, B, C, scale, frob, m[9], eval[3];
  int roots;

  frob = ELL_3M_FROB(_m);
  scale = frob ? 1.0/frob : 1.0;
  ELL_3M_SCALE(m, scale, _m);
  /*
  printf("!%s: m = %g %g %g; %g %g %g; %g %g %g\n", "ell_3m_eigenvalues_d",
         m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
  */
  /*
  ** from gordon with mathematica; these are the coefficients of the
  ** cubic polynomial in x: det(x*I - M).  The full cubic is
  ** x^3 + A*x^2 + B*x + C.
  */
  A = -m[0] - m[4] - m[8];
  B = m[0]*m[4] - m[3]*m[1]
    + m[0]*m[8] - m[6]*m[2]
    + m[4]*m[8] - m[7]*m[5];
  C = (m[6]*m[4] - m[3]*m[7])*m[2]
    + (m[0]*m[7] - m[6]*m[1])*m[5]
    + (m[3]*m[1] - m[0]*m[4])*m[8];
  /*
  printf("!%s: A B C = %g %g %g\n", "ell_3m_eigenvalues_d", A, B, C);
  */
  roots = ell_cubic(eval, A, B, C, newton);
  /* no longer need to sort here */
  ELL_3V_SCALE(_eval, 1.0/scale, eval);
  return roots;
}
Ejemplo n.º 3
0
int
main(int argc, char **argv) {
  char buf[512];
  double ans0, ans1, ans2, A, B, C;
  int ret;
  double r[3];

  me = argv[0];
  if (argc != 4) {
    usage();
  }

  sprintf(buf, "%s %s %s", argv[1], argv[2], argv[3]);
  if (3 != sscanf(buf, "%lf %lf %lf", &A, &B, &C)) {
    fprintf(stderr, "%s: couldn't parse 3 floats from command line\n", me);
    exit(1);
  }

  ell_debug = AIR_TRUE;
  ret = ell_cubic(r, A, B, C, AIR_TRUE);
  ans0 = C + r[0]*(B + r[0]*(A + r[0]));
  switch(ret) {
  case ell_cubic_root_single:
    printf("1 single root: %f -> %f\n", r[0], ans0);
    break;
  case ell_cubic_root_triple:
    printf("1 triple root: %f -> %f\n", r[0], ans0);
    break;
  case ell_cubic_root_single_double:
    ans1 = C + r[1]*(B + r[1]*(A + r[1]));
    printf("1 single root %f -> %f, 1 double root %f -> %f\n", 
           r[0], ans0, r[1], ans1);
    break;
  case ell_cubic_root_three:
    ans1 = C + r[1]*(B + r[1]*(A + r[1]));
    ans2 = C + r[2]*(B + r[2]*(A + r[2]));
    printf("3 distinct roots:\n %f -> %f\n %f -> %f\n %f -> %f\n",
           r[0], ans0, r[1], ans1, r[2], ans2);
    break;
  default:
    printf("%s: something fatally wacky happened\n", me);
    exit(1);
  }
  exit(0);
}