/*************** generate random SU(3) matrix *******************/

#include "comdefs.h"
#include "generic.h"

#include "complex.h"
#include "su3.h"

/* generate a random element for su3.  First, some auxilliary functions */

#define Nc 3
#define Nhit 3          /* how many su2 subgroups  */

typedef struct { complex e[2][2]; } su2_cmat;

/* this is defined in monte */
void left_su2_hit_n(su2_cmat *u, int p, int q, su3_matrix *link);

/*******************************************
 * random su2 matrix
 */


void su2_random( su2_cmat *m )
{
  double r0,r1,r2,r3,rsq;

  /* select a random number evenly inside a 4d sphere */
  do {
    r0 = 2*dran() - 1.0;
    r1 = 2*dran() - 1.0;
    r2 = 2*dran() - 1.0;
    r3 = 2*dran() - 1.0;
    rsq = r0*r0 + r1*r1 + r2*r2 + r3*r3;
  } while ( rsq > 1.0 );

  /* make it su2 matrix */
  
  rsq = 1.0/sqrt( rsq );
  r0 *= rsq;  r1 *= rsq;  r2 *= rsq;  r3 *= rsq;

  m->e[0][0] = cmplx( r0, r3 );
  m->e[0][1] = cmplx( r2, r1 );
  m->e[1][0] = cmplx(-r2, r1 );
  m->e[1][1] = cmplx( r0,-r3 );

}

/* Set su3 matrix to unit matrix
 */

void su3_one(su3_matrix *r)
{
  register int i,j;
  for (i=0; i<3; i++) for (j=0; j<3; j++) {
    r->e[i][j].imag = 0;
    if (i==j) r->e[i][j].real = 1;  else r->e[i][j].real = 0;
  }
}


/******************************************************************
 * a routine for generating a random su3 matrix.
 */


void random_su3P( su3_matrix *a, int n_random )
{
  int i,ina,inb,index1,ii;
  su2_cmat u;
  /* su3_matrix m;
   * complex t;
   */

  su3_one( a );  /* set the matrix first to unity */

  for (i=0; i<n_random; i++) {
    for(index1=0;index1<Nhit;index1++) {
      /*  pick out an SU(2) subgroup */
      ina=(index1+1) % Nc;
      inb=(index1+2) % Nc;
      if(ina > inb) { ii=ina; ina=inb; inb=ii;}
      
      su2_random( &u );  /* get a random su2 */

      left_su2_hit_n( &u, ina, inb, a );  /* and hit the su3 matrix */

      /* mat_mul_an( (*a), (*a), m );
       * t = trace_su3( &m );
       * printf("loop %d  random: trace %g %g\n",i,t.real,t.imag);
       */
    }
    if (i % 4 == 0) reunit_su3( a ); /* keep it unitary */
  }
}
      
      
