예제 #1
0
///////////////////////////////////////////////////////////////////////////////
//
/// Finds the zeroes of P(x) in the domain \f$a < x <= b\f$, putting the
/// results into Z
//
///////////////////////////////////////////////////////////////////////////////
void AntisymmetricExpFit::find_zeroes(RealVector &P, const Real &a, const Real &b, RealVector &Z) {
  const int N = P.size();
  RealMatrix cm(N-1,N-1);
  int i,j;

  // --- Form the companion matrix
  // -----------------------------
  cm.fill(0.0);
  for(j=0; j<N-1; ++j) {
    cm(0,j) = -P(N-2-j)/P(N-1);
  }
  for(i=1; i<N-1; ++i) {	
    cm(i,i-1) = 1.0;
  }

  // --- find eigenvalues of
  // --- companion matrix and
  // --- extract roots in [0:1]
  // --------------------------
  EigenSolver<RealMatrix> roots(cm,false);

  Z.resize(N);
  i = 0;
  for(j = 0; j<roots.eigenvalues().size(); ++j) {
    if(fabs(roots.eigenvalues()(j).imag()) < 1e-15 &&
       roots.eigenvalues()(j).real() > a &&
       roots.eigenvalues()(j).real() <= b) {
      Z(i) = roots.eigenvalues()(j).real();
      ++i;
    }
  }
  Z.conservativeResize(i);
}
예제 #2
0
///////////////////////////////////////////////////////////////////////////////
//
/// Find zeroes of the polynomial \f$y = sum_i e_ix^i\f$,
/// where \f$e\f$ is the \f$c^{th}\f$ eigenvector, and put any zeroes
/// that lie in the interval [0:1] into \c k.
///
/// \param c The identifier of the eigenvector to find zeroes of.
//
///////////////////////////////////////////////////////////////////////////////
void AntisymmetricExpFit::fit_exponents(int c) {
  const int 	N = 2.0*ESolver.eigenvectors().rows();
  int		i,j;

  // --- Construct the eigenpolynomial
  // --- from the eigenvalues
  // ---------------------------------
  RealVector P(N);	// eigen polynomial coefficients

  if(provable) {
    // --- PA = P_q(x) - x^{N/2} P_q(x^{-1})
    // --- P = PA/(1-x)
    RealVector PA(N+1);	// eigen polynomial coefficients
    PA(N/2) = 0.0;
    PA.topRows(N/2) = ESolver.eigenvectors().col(c).real();
    PA.bottomRows(N/2) = -ESolver.eigenvectors().col(c).real().reverse();
    P(0) = PA(0);
    for(i = 1; i<P.size(); ++i) {
      P(i) = P(i-1) + PA(i);
    }
  } else {
    P.topRows(N/2) = ESolver.eigenvectors().col(c).real();
    P.bottomRows(N/2) = ESolver.eigenvectors().col(c).real().reverse();
  }

  RealVector Q;		// eigenpolynomial with changed variable
  RealVector Z;		// scaled positions of zeroes
  long double alpha;    // scaling factor of polynomial
  long double s;	// scale
  k.resize(c);
  i = 0;
  alpha = 2.0/3.0;
  if(P.size() > 64) {
    while(i < c && alpha > 1e-8) {
      change_variable(P,alpha,Q);
      j = Q.size()-1;
      s = pow(2.0,j);
      while(j && fabs(Q(j))/s < 1e-18) {
	s /= 2.0;
	--j;
      }
      Q.conservativeResize(j+1);
      find_zeroes(Q, -0.5, 0.5, Z);
      for(j = Z.size()-1; j>=0; --j) {
	s = 1.0 - alpha*(1.0 -Z(j));
	k(i) = s;
	++i;
      }
      alpha /= 3.0;
    }
  } else {
    find_zeroes(P, 0.0, 1.0, k);
  }
}