/* Put antihermitian traceless part into momentum */
static void
add_forces_to_mom(QDP_ColorVector **back_qdp, QDP_ColorVector **forw_qdp, 
		  int dir, REAL coeff[], int nsrc)
{
  REAL tmp_coeff[nsrc];
  QDP_ColorMatrix *tm[nsrc];
  int i;

  QOP_trace("test 481\n");
  if(GOES_BACKWARDS(dir)) {
    dir = OPP_DIR(dir); 
    for(i=0; i<nsrc; i++) {
      tmp_coeff[i] = -coeff[i];
    }
  } else {
    for(i=0; i<nsrc; i++) {
      tmp_coeff[i] = coeff[i];
    }
  }
  QOP_trace("test 482\n");

  for(i=0; i<nsrc; i++) {
    QDP_V_eq_r_times_V(tv[i], &tmp_coeff[i], forw_qdp[i], QDP_all);
    tm[i] = tempmom_qdp[dir];
  }
  QOP_trace("test 483\n");
  QDP_M_vpeq_V_times_Va(tm, back_qdp, tv, QDP_all, nsrc);
  QOP_trace("test 484\n");
}
Esempio n. 2
0
/* normalizes the vecror vec. Work only on subset. */
void
normalize_qdp(QDP_ColorVector *vec, QDP_Subset subset)
{
  QLA_Real norm;
  QDP_r_eq_norm2_V(&norm, vec, subset);
  norm = 1.0/sqrt(norm);
  QDP_V_eq_r_times_V(vec, &norm, vec, subset);
}
Esempio n. 3
0
int
Rayleigh_min_qdp(QDP_ColorVector *vec, QDP_ColorVector **eigVec,
		 Real Tolerance,  Real RelTol, int Nvecs, int MaxIter,
		 int Restart, QDP_Subset subset)
{
  QLA_Complex cc;
  QLA_Real beta, cos_theta, sin_theta;
  QLA_Real quot, P_norm, theta, real_vecMp, pMp;
  QLA_Real g_norm, old_g_norm, start_g_norm;
  QDP_ColorVector *Mvec, *grad, *P, *MP;
  int iter;

#ifdef DEBUG
  if(QDP_this_node==0) printf("begin Rayleigh_min_qdp\n");
#endif

  Mvec = QDP_create_V();
  grad = QDP_create_V();
  //oldgrad = QDP_create_V();
  P = QDP_create_V();
  MP = QDP_create_V();

  project_out_qdp(vec, eigVec, Nvecs, subset);
  normalize_qdp(vec, subset);
  Matrix_Vec_mult_qdp(vec, Mvec, subset);
  project_out_qdp(Mvec, eigVec, Nvecs, subset);

  /* Compute the quotient quot=vev*M*vec */
  QDP_r_eq_re_V_dot_V(&quot, vec, Mvec, subset);
  /* quot is real since M is hermitian. quot = vec*M*vec */
#ifdef DEBUG
  if(QDP_this_node==0) printf("Rayleigh_min: Start -- quot=%g\n", quot);
#endif
  /* Compute the grad=M*vec - quot*vec */
  QDP_V_eq_V(grad, Mvec, QDP_all);
  QDP_V_meq_r_times_V(grad, &quot, vec, subset);
  /* set P (the search direction) equal to grad */
  QDP_V_eq_V(P, grad, QDP_all);
  /* compute the norms of P and grad */
  QDP_r_eq_norm2_V(&P_norm, P, subset);
  P_norm = sqrt(P_norm);
  QDP_r_eq_norm2_V(&g_norm, grad, subset);
  g_norm = sqrt(g_norm);
  start_g_norm = g_norm;
  //QDP_V_eq_V(oldgrad, grad, subset);
#ifdef DEBUG
  if(QDP_this_node==0) printf("Rayleigh_min: Start -- g_norm=%g\n", g_norm);
#endif  

  iter = 0;
  while( (g_norm>Tolerance*quot) &&
	 ( ((iter<MaxIter)&&(g_norm/start_g_norm>RelTol)) || (iter<MINITER) )
	 ) {
    iter++;
    Matrix_Vec_mult_qdp(P, MP, subset);
    QDP_r_eq_re_V_dot_V(&real_vecMp, vec, MP, subset);
    QDP_r_eq_re_V_dot_V(&pMp, P, MP, subset);
    theta = 0.5*atan(2.0*real_vecMp/(quot*P_norm - pMp/P_norm));
    sin_theta = sin(theta);
    cos_theta = cos(theta);
    if(sin_theta*cos_theta*real_vecMp>0) {
      theta = theta - 0.5*M_PI;  /* chose the minimum not the maximum */
      sin_theta = sin(theta);  /* the sin,cos calls can be avoided */
      cos_theta = cos(theta);
    }
    sin_theta = sin_theta/P_norm;
    /* vec = cos(theta)*vec +sin(theta)*P/p_norm */
    //dax_p_by_qdp(cos_theta, vec, sin_theta, P, subset);
    QDP_V_eq_r_times_V(vec, &cos_theta, vec, subset);
    QDP_V_peq_r_times_V(vec, &sin_theta, P, subset);
    /* Mvec = cos(theta)*Mvec +sin(theta)*MP/p_norm */
    //dax_p_by_qdp(cos_theta, Mvec, sin_theta, MP, subset);
    QDP_V_eq_r_times_V(Mvec, &cos_theta, Mvec, subset);
    QDP_V_peq_r_times_V(Mvec, &sin_theta, MP, subset);
    /* renormalize vec ... */
    if( iter%Restart == 0 ) {
#ifdef DEBUG
      {
	QLA_Real vec_norm;
	if(QDP_this_node==0) printf("Renormalizing...");
	QDP_r_eq_norm2_V(&vec_norm, vec, subset);
	if(QDP_this_node==0) printf("  norm: %g\n", sqrt(vec_norm));
      }
#endif
      /* Project vec on the orthogonal complement of eigVec */
      project_out_qdp(vec, eigVec, Nvecs, subset);
      normalize_qdp(vec, subset);
      Matrix_Vec_mult_qdp(vec, Mvec, subset);
      /* Recompute the quotient */
      QDP_r_eq_re_V_dot_V(&quot, vec, Mvec, subset);
      /* Recompute the grad */
      QDP_V_eq_V(grad, Mvec, QDP_all);
      QDP_V_meq_r_times_V(grad, &quot, vec, subset);
      //QDP_r_eq_norm2_V(&g_norm, grad, subset);
      //printf("g_norm = %g\n", g_norm);
      /* Project P on the orthogonal complement of eigVec */
      //QDP_r_eq_norm2_V(&P_norm, P, subset);
      //printf("P_norm = %g\n", P_norm);
      project_out_qdp(P, eigVec, Nvecs, subset);
      //QDP_r_eq_norm2_V(&P_norm, P, subset);
      //printf("P_norm = %g\n", P_norm);
      /* make P orthogonal to vec */
      QDP_c_eq_V_dot_V(&cc, vec, P, subset);
      //printf("cc = %g\n", QLA_real(cc));
      QDP_V_meq_c_times_V(P, &cc, vec, subset);
      //QDP_r_eq_norm2_V(&P_norm, P, subset);
      //printf("P_norm = %g\n", P_norm);
      /* make P orthogonal to grad */
      QDP_c_eq_V_dot_V(&cc, grad, P, subset);
      //printf("cc = %g\n", QLA_real(cc));
      QDP_V_meq_c_times_V(P, &cc, grad, subset);
      QDP_r_eq_norm2_V(&P_norm, P, subset);
      P_norm = sqrt(P_norm);
    }
    QDP_r_eq_re_V_dot_V(&quot, vec, Mvec, subset);
#ifdef DEBUG
    node0_printf("Rayleigh_min: %i, quot=%8g g=%8g b=%6g P:%6g\n",
		 iter, quot, g_norm, beta, P_norm);
#endif
    old_g_norm = g_norm;

    QDP_V_eq_V(grad, Mvec, QDP_all);
    QDP_V_meq_r_times_V(grad, &quot, vec, subset);

    //QDP_V_meq_V(oldgrad, grad, subset);
    //QDP_r_eq_re_V_dot_V(&g_norm, oldgrad, grad, subset);
    //QDP_V_eq_V(oldgrad, grad, subset);

    QDP_r_eq_norm2_V(&g_norm, grad, subset);
    g_norm = sqrt(g_norm);

    beta = cos_theta*g_norm*g_norm/(old_g_norm*old_g_norm);
    if( beta>2.0 ) beta = 2.0;  /* Cut off beta */

    QDP_c_eq_V_dot_V(&cc, vec, P, subset);
    QLA_real(cc) *= beta;
    QLA_imag(cc) *= beta;
    QDP_V_eq_r_times_V_plus_V(P, &beta, P, grad, subset);
    QDP_V_meq_c_times_V(P, &cc, vec, subset);
    QDP_r_eq_norm2_V(&P_norm, P, subset);
    P_norm = sqrt(P_norm);
  }
  project_out_qdp(vec, eigVec, Nvecs, subset);
  normalize_qdp(vec, subset);
  QDP_destroy_V(MP);
  QDP_destroy_V(P);
  //QDP_destroy_V(oldgrad);
  QDP_destroy_V(grad);
  QDP_destroy_V(Mvec);

  iter++;
#ifdef DEBUG
  if(QDP_this_node==0) printf("end Rayleigh_min_qdp\n");
#endif
  return iter;
}