int main(void) {
	int base, power, returnval, isLoop = 1;
	char input[3], charContinue;
	printf("Welcome to the integer powers program!\n");
	while (isLoop ==1) {
		printf("Please type in the base of the integer power (i.e. the 2 in 2^5):\n");
		scanf("%s", input);
		base = atoi(input);
		fflush(NULL);	

		printf("Please type in the power of the integer power (i.e. the 5 in 2^5):\n");
		scanf("%s", input);
		power = atoi(input);
		fflush(NULL);		

		returnval = exponentiate(base, power);
		printf("The result of %i^%i is %i.\n", base, power, returnval);
		
		printf("Would you like to continue? [y/n]\n");
		scanf("%s", &charContinue);
		fflush(NULL);
		if (charContinue != 'y') {
			printf("Goodbye!\n");
			isLoop = 0;
		}
	}
	return 0;
}
inline
typename ICR::EnsembleLearning::Discrete<T>::moments_t
ICR::EnsembleLearning::Discrete<T>::CalcSample(moments_parameter PM) 
{
  std::vector<data_t> M(PM.size());
  std::transform(PM.begin(),PM.end(),M.begin(),exponentiate());
  return moments_t(M);
}
Beispiel #3
0
H2TangentVector H2TangentVector::parallelTransportOld(const double &t) const
{
    H2Point y0 = root;
    H2Point yt = exponentiate(t);
    H2Isometry f;
    f.setDiskCoordinates(Complex(1.0,0.0), y0.getDiskCoordinate());

    H2TangentVector u(f*yt, (1.0 - norm((f*yt).getDiskCoordinate())) * ((f*(*this)).vector));

    return (f.inverse())*u;
}
Beispiel #4
0
void exponentiate(unsigned long long int N){
	int i, j;
	switch (N){
		case 0:
		case 1:
			for (i = 0; i < 4; i++)
				for (j = 0; j < 4; j++)
					matrix[i][j] = orig[i][j];
			return;
		default:
			if (N % 2 == 0){
				exponentiate(N/2);
				square();
			} else {
				exponentiate(N/2);
				square();
				multiplyonce();
			}
			return;
	}
}
Beispiel #5
0
static char *exponentiate_short_test( void ) 
{
  // Hermitian proj has been tested
  GLU_complex hHa[ HERMSIZE ] , Ha[ NCNC ] GLUalign ;
  GLU_complex hUa[ NCNC ] GLUalign , Ua[ NCNC ] GLUalign ;

  // create a unitary matrix
  Sunitary_gen( Ua , 0 ) ;

  // hermitian proj it
  Hermitian_proj( Ha , Ua ) ;
  Hermitian_proj_short( hHa , Ua ) ;

  exponentiate( Ua , Ha ) ;
  exponentiate( hUa , Ha ) ;

  GLU_bool is_ok = GLU_TRUE ;
  int i ;
  for( i = 0 ; i < NCNC ; i++ ) {
    if( cabs( Ua[i] - hUa[i] ) > PREC_TOL ) is_ok = GLU_FALSE ;
  }
  mu_assert( "[GLUnit] error : exponentiate_short is broken", is_ok );
  return 0 ;
}
Beispiel #6
0
// test the exponential e^{0} = Identity?
static char *exponentiate_test( void ) {
  GLU_complex A[ NCNC ] GLUalign , Id[ NCNC ] GLUalign ;
  zero_mat( A ) ;
  exponentiate( Id , A ) ;
  int i ;
  GLU_bool is_ok = GLU_TRUE ;
  for( i = 0 ; i < NCNC ; i++ ) {
    if( i % ( NC + 1 ) == 0 ) {
      if( cabs( Id[ i ] - 1.0 ) > PREC_TOL ) is_ok = GLU_FALSE ;
    } else {
      if( cabs( Id[ i ] ) > PREC_TOL ) is_ok = GLU_FALSE ;
    }
  }
  mu_assert( "[GLUnit] error : exponentiate is broken", is_ok );
  return 0 ;
}
Exponential::Exponential(Expression* base, Rational* exponent){
    this->type = "exponential";
    this->base = base;
    this->exponent = exponent;
    this->exde = new Integer(exponent->getDenominator());
    if (exde->getValue() != 1) {
    	//if the denominator of the exponent is not 1, make the base a root of the denominator, then setting the denominator equal to 1
    	Integer* baseAsInteger = (Integer *) base;
        this->base = new nthRoot(exde->getValue(), baseAsInteger->getValue(), 1);
        Integer* one = new Integer(1);
        this->exponent->setDenominator(one);
    }else{
        this->exnu = new Integer(exponent->getNumerator());
        if (canExponentiate()) {
            exponentiate();
        }
    }
}
Beispiel #8
0
// log and exponentiate should be equivalent
static char *exact_log_test( void ) {
  GLU_complex A[ NCNC ] , Ua[ NCNC ] , eA[ NCNC ] ;

  // create a unitary matrix
  Sunitary_gen( Ua , 0 ) ;

  exact_log_slow( A , Ua ) ;
  exponentiate( eA , A ) ;
  
  int i ;
  GLU_bool is_ok = GLU_TRUE ;
  for( i = 0 ; i < NCNC ; i++ ) {
    if( cabs( eA[i] - Ua[i] ) > NC*PREC_TOL ) is_ok = GLU_FALSE ;
  }
#if NC < 15
  mu_assert( "[GLUnit] error : exact_log_slow is broken", is_ok ) ;
#endif
  return 0 ;
}
inline
typename ICR::EnsembleLearning::Discrete<T>::moments_t
ICR::EnsembleLearning::Discrete<T>::CalcMoments(NP_parameter NP)
{
  //NPs are unnormalised log probabilities.

  std::vector<data_t> unLogProbs(NP.size());  //unnormalised
  std::vector<data_t> LogProbs(NP.size());    //log normalised
  std::vector<data_t> Probs(NP.size());       //normalised
  PARALLEL_COPY( NP.begin(), NP.end(), unLogProbs.begin());
  //calculate the log partition factor, Z.  The normalisation is 1/Z.
  const data_t LogNorm = -CalcLogNorm(unLogProbs); //Thats why there is a minus here
  PARALLEL_TRANSFORM(  unLogProbs.begin(),  unLogProbs.end(), 
		       LogProbs.begin(), subtract(LogNorm));
  
  PARALLEL_TRANSFORM(  LogProbs.begin(),  LogProbs.end(), 
		       Probs.begin(), exponentiate());

  return moments_t(Probs);
}
Beispiel #10
0
H2TangentVector H2TangentVector::parallelTransport(const double &t) const
{
    H2Point yt = exponentiate(t);
    Complex v,outV;
    double L,absV;

    Complex z = root.getDiskCoordinate();
    v = vector;
    absV = std::abs(v);
    // Absolute value t? NO.
    L = t*length();

    Complex u = v/absV;
    Complex thing = cosh(L/2)+u*conj(z)*sinh(L/2);
    outV = v/(thing*thing);

    H2TangentVector output(yt,outV);
    return output;

}
Beispiel #11
0
int main(void){
	unsigned long long int T, N;

	scanf("%llu", &T);

	while (T--){
		scanf("%llu", &N);
		if (N <= 2){
			printf("0\n");
		} else {
			exponentiate(N-2);
			multiply();
#if DEBUG
			printf("{%llu, %lld, %lld, %lld}\n", curr[0], curr[1], curr[2], curr[3]);
#endif
			printf("%llu\n", curr[0] % MOD);
		}
	}

	return 0;
}
inline
typename ICR::EnsembleLearning::Discrete<T>::data_t
ICR::EnsembleLearning::Discrete<T>::CalcLogNorm(vector_data_parameter unLogProbs) 
{
  /* Unnormalised
   *If all the probs are very small then can easily get servere numerical errors,
   * eg. norm = 0.
   * To solve this we subtract most significant log before exponetating 
   *   (and add it again after).
   */
  const data_t LogMax = *PARALLEL_MAX(unLogProbs.begin(),unLogProbs.end());

  std::vector<T> unLogProbsTmp(unLogProbs.size());  
  PARALLEL_TRANSFORM( unLogProbs.begin(),unLogProbs.end(), unLogProbsTmp.begin(), 
		      subtract(LogMax));
  //exponentiate log (prob/max)
  std::vector<T> unProbs(unLogProbsTmp.size());
  PARALLEL_TRANSFORM( unLogProbsTmp.begin(),unLogProbsTmp.end(), unProbs.begin(), 
		      exponentiate());
  const data_t norm = PARALLEL_ACCUMULATE(unProbs.begin(), unProbs.end(),0.0) ;
  
  return -std::log(norm)- LogMax;

}
Beispiel #13
0
// Generate the representation of Z_m^* for a given odd integer m
// and plaintext base p
PAlgebra::PAlgebra(unsigned long mm, unsigned long pp)
{
    m = mm;
    p = pp;

    assert( (m&1) == 1 );
    assert( ProbPrime(p) );
    // replaced by Mahdi after a conversation with Shai
    // assert( m > p && (m % p) != 0 );	// original line
    assert( (m % p) != 0 );
    // end of replace by Mahdi
    assert( m < NTL_SP_BOUND );

    // Compute the generators for (Z/mZ)^*
    vector<unsigned long> classes(m);
    vector<long> orders(m);

    unsigned long i;
    for (i=0; i<m; i++) { // initially each element in its own class
        if (GCD(i,m)!=1)
            classes[i] = 0; // i is not in (Z/mZ)^*
        else
            classes[i] = i;
    }

    // Start building a representation of (Z/mZ)^*, first use the generator p
    conjClasses(classes,p,m);  // merge classes that have a factor of 2

    // The order of p is the size of the equivalence class of 1
    ordP = (unsigned long) count (classes.begin(), classes.end(), 1);

    // Compute orders in (Z/mZ)^*/<p> while comparing to (Z/mZ)^*
    long idx, largest;
    while (true) {
        compOrder(orders,classes,true,m);
        idx = argmax(orders);      // find the element with largest order
        largest = orders[idx];

        if (largest <= 0) break;   // stop comparing to order in (Z/mZ)^*

        // store generator with same order as in (Z/mZ)^*
        gens.push_back(idx);
        ords.push_back(largest);
        conjClasses(classes,idx,m); // merge classes that have a factor of idx
    }
    // Compute orders in (Z/mZ)^*/<p> without comparing to (Z/mZ)^*
    while (true) {
        compOrder(orders,classes,false,m);
        idx = argmax(orders);      // find the element with largest order
        largest = orders[idx];

        if (largest <= 0) break;   // we have the trivial group, we are done

        // store generator with different order than (Z/mZ)^*
        gens.push_back(idx);
        ords.push_back(-largest);  // store with negative sign
        conjClasses(classes,idx,m);  // merge classes that have a factor of idx
    }

    nSlots = qGrpOrd();
    phiM = ordP * nSlots;

    // Allocate space for the various arrays
    T.resize(nSlots);
    dLogT.resize(nSlots*gens.size());
    Tidx.assign(m,-1);    // allocate m slots, initialize them to -1
    zmsIdx.assign(m,-1);  // allocate m slots, initialize them to -1
    for (i=idx=0; i<m; i++) if (GCD(i,m)==1) zmsIdx[i] = idx++;

    // Now fill the Tidx and dLogT translation tables. We identify an element
    // t\in T with its representation t = \prod_{i=0}^n gi^{ei} mod m (where
    // the gi's are the generators in gens[]) , represent t by the vector of
    // exponents *in reverse order* (en,...,e1,e0), and order these vectors
    // in lexicographic order.

    // buffer is initialized to all-zero, which represents 1=\prod_i gi^0
    vector<unsigned long> buffer(gens.size()); // temporaty holds exponents
    i = idx = 0;
    do {
        unsigned long t = exponentiate(buffer);
        for (unsigned long j=0; j<buffer.size(); j++) dLogT[idx++] = buffer[j];
        T[i] = t;       // The i'th element in T it t
        Tidx[t] = i++;  // the index of t in T is i

        // increment buffer by one (in lexigoraphic order)
    } while (nextExpVector(buffer)); // until we cover all the group

    PhimX = Cyclotomic(m); // compute and store Phi_m(X)

    // initialize prods array
    long ndims = gens.size();
    prods.resize(ndims+1);
    prods[ndims] = 1;
    for (long j = ndims-1; j >= 0; j--) {
        prods[j] = OrderOf(j) * prods[j+1];
    }
}
Beispiel #14
0
// exactly the same as above ,  just calculates the f-functions in-step instead of requiring them
// takes a shortened, Hermitian Q and gives back the SU(NC) matrix U
void
exponentiate_short( GLU_complex U[ NCNC ] , 
		    const GLU_complex Q[ HERMSIZE ] )
{
#if NC == 3
  GLU_real *qq = ( GLU_real* )Q ;
  const double REQ0 = *( qq + 0 ) ;
  const double REQ1 = *( qq + 2 ) ;
  const double IMQ1 = *( qq + 3 ) ;
  const double REQ2 = *( qq + 4 ) ;
  const double IMQ2 = *( qq + 5 ) ;
  const double REQ4 = *( qq + 6 ) ;
  const double REQ5 = *( qq + 8 ) ;
  const double IMQ5 = *( qq + 9 ) ;
  const double REQ8 = -( REQ0 + REQ4 ) ;
  const double c1 = ( REQ0 * -REQ8 + REQ4 * REQ4			\
		      + REQ1 * REQ1 + IMQ1 * IMQ1			\
		      + REQ2 * REQ2 + IMQ2 * IMQ2			\
		      + REQ5 * REQ5 + IMQ5 * IMQ5 ) * OneO3 ;
  
  //  Iff c0_max < ( smallest representable double) the matrix Q is zero and its
  //  exponential is the identity matrix .
  if( unlikely( c1 < DBL_MIN ) ) {
    *( U + 0 ) = 1. ; 
    *( U + 1 ) = 0. ; 
    *( U + 2 ) = 0. ; 
    //
    *( U + 3 ) = 0. ; 
    *( U + 4 ) = 1. ; 
    *( U + 5 ) = 0. ; 
    //
    *( U + 6 ) = 0. ; 
    *( U + 7 ) = 0. ; 
    *( U + 8 ) = 1. ; 
    return ;
  }

  // 1/3 * tr AAA is just det( A )
  // Below is a quickened determinant
  double c0 =  REQ0  * ( REQ4 * REQ8				\
			 - REQ5  * REQ5  - IMQ5  * IMQ5  ) ;
  // from the middle
  c0 -= REQ1  * ( REQ1 * REQ8 		\
		  - REQ5  * REQ2  - IMQ5  * IMQ2  ) ;
  c0 += IMQ1  * ( - IMQ1 * REQ8		\
		  + REQ5  * IMQ2  - IMQ5  * REQ2 ) ;
  // final column
  c0 += REQ2  * ( - REQ4  * REQ2			\
		  + REQ1 * REQ5  - IMQ1 * IMQ5  ) ;
  c0 -= IMQ2  * ( REQ4  * IMQ2				\
		  - REQ1 * IMQ5  - IMQ1 * REQ5 ) ;

  // so if c0 is negative we flip the sign ...
  const double flag = c0 < 0 ? -1.0 : 1.0 ;
  c0 *= flag ;

  // compute the constants c0_max and the root of c1 ...
  const double rc1 = sqrt( c1 ) ;
  const double c0_max = 2. * rc1 * c1 ; 
  const double theta = acos( c0 / c0_max ) * OneO3 ; 
  const double ctheta = cos( theta ) ;
  register const double u = rc1 * ctheta ; 
  register const double w = r3 * rc1 * sin( theta ) ; 
  const double uu = u * u  ,  ww = w * w  ,  cw = cos( w ) ; 
  const double denom = 1.0 / ( 9. * uu - ww ) ;
  const double cu = cos( u ) ;
  const double su = sin( u ) ;
  const double complex one = cu - I * su ;
  double complex two = conj( one ) ;
  two *= two ;

  // taylor expand if getting toward the numerically unstable end
  const double E0 = fabs( w ) < SINTOL ? ( 1 - ww / 6. * ( 1 - ww / 20. * ( 1 - ww / 42. ) ) ) : sin( w ) / w ; 

  double complex f0 = ( uu - ww ) * two + one * ( 8 * uu * cw + 2 * I * u * ( 3 * uu + ww ) * E0 ) ; 
  double complex f1 = 2. * u * two - one * ( 2. * u * cw - I * ( 3 * uu - ww ) * E0 ) ; 
  double complex f2 = two - one * ( cw + 3 * I * u * E0 ) ; 

  f0 = ( creal( f0 ) + I * cimag( f0 ) * flag ) ;
  f1 = ( flag * creal( f1 ) + I * cimag( f1 ) ) ;
  f2 = ( creal( f2 ) + I * cimag( f2 ) * flag ) ;

  f0 *= denom ;
  f1 *= denom ;
  f2 *= denom ;

  // QQ[0].
  const double temp0 = REQ0 * REQ0 + REQ1 * REQ1 +	\
    IMQ1 * IMQ1 + REQ2 * REQ2 + IMQ2 * IMQ2 ;
  // QQ[1]
  const double complex temp1 = -REQ1 * ( REQ8 ) + REQ2 * REQ5 + IMQ2 * IMQ5 
    + I * ( REQ5 * IMQ2 - REQ2 * IMQ5 - IMQ1 * REQ8 ) ;
  // QQ[2]
  const double complex temp2 = REQ1 * REQ5 - IMQ1 * IMQ5 - REQ2 * REQ4 +
    I * ( IMQ1 * REQ5 + IMQ5 * REQ1 - IMQ2 * REQ4 ) ;
  // QQ[4]
  const double temp3 = REQ4 * REQ4 + REQ1 * REQ1	\
    + IMQ1 * IMQ1 + REQ5 * REQ5 + IMQ5 * IMQ5 ;
  // QQ[5]
  const double complex temp4 = REQ1 * REQ2 + IMQ2 * IMQ1 - REQ0 * REQ5 +
    I * ( REQ1 * IMQ2 - REQ2 * IMQ1 - REQ0 * IMQ5 ) ;
  // QQ[8]
  const double temp5 = REQ8 * REQ8 + REQ2 * REQ2 +	\
    IMQ2 * IMQ2 + REQ5 * REQ5 + IMQ5 * IMQ5 ;

  //can really speed this up
  *( U + 0 ) = f0 + f1 * REQ0 + f2 * temp0  ; 
  *( U + 1 ) = f1 * Q[1] + f2 * temp1 ; 
  *( U + 2 ) = f1 * Q[2] + f2 * temp2 ; 
  //
  *( U + 3 ) = f1 * conj( Q[1] ) + f2 * conj( temp1 ) ; 
  *( U + 4 ) = f0 + f1 * REQ4 + f2 * temp3 ; 
  *( U + 5 ) = f1 * Q[4] + f2 * temp4 ; 
  //
  *( U + 6 ) = f1 * conj( Q[2] ) + f2 * conj( temp2 ) ; 
  *( U + 7 ) = f1 * conj( Q[4] ) + f2 * conj( temp4 ) ; 
  *( U + 8 ) = f0 + f1 * REQ8 + f2 * temp5 ; 
#elif NC == 2
  double f0 , f1 ; // f1 is purely imaginary
  // eigenvalues are pretty simple +/- sqrt( |a|^2 + |b|^2 ) Only need one
  const double z = sqrt( creal( Q[0] ) * creal( Q[0] ) +	\
			 creal( Q[1] ) * creal( Q[1] ) +	\
			 cimag( Q[1] ) * cimag( Q[1] ) ) ;

  // have eigenvalues, now for the "fun" bit.
  f0 = cos( z ) ;
  // taylor expand 
  f1 = fabs ( z ) < SINTOLSU2 ? ( 1.0 - z / 6. * ( 1 - z / 20. * ( 1 - z / 42. ) ) ) : sin( z ) / z ;

  const double complex f1Q0 = I * f1 * Q[0] ;
  const double complex f1Q1 = I * f1 * Q[1] ;
  *( U + 0 ) = (GLU_complex)( f0 + f1Q0 ) ;
  *( U + 1 ) = (GLU_complex)( f1Q1 ) ;
  *( U + 2 ) = (GLU_complex)( -conj( f1Q1 ) ) ;
  *( U + 3 ) = (GLU_complex)( f0 - f1Q0 ) ; 
#else
  // hmmm could be a toughy, wrap to exponentiate
  GLU_complex temp[ NCNC ] GLUalign ;
  rebuild_hermitian( temp , Q ) ;
  exponentiate( U , temp ) ;
#endif
  return ;
}
Beispiel #15
0
H2Point H2TangentVector::exponentiate() const
{
    return exponentiate(1.0);
}
Beispiel #16
0
PAlgebra::PAlgebra(unsigned long mm, unsigned long pp,  
                   const vector<long>& _gens, const vector<long>& _ords )
{
  assert( ProbPrime(pp) );
  assert( (mm % pp) != 0 );
  assert( mm < NTL_SP_BOUND );
  assert( mm > 1 );

  cM  = 1.0; // default value for the ring constant
  m = mm;
  p = pp;

  long k = NextPowerOfTwo(m);
  if (mm == (1UL << k))
    pow2 = k;
  else
    pow2 = 0;

   

  // For dry-run, use a tiny m value for the PAlgebra tables
  if (isDryRun()) mm = (p==3)? 4 : 3;

  // Compute the generators for (Z/mZ)^* (defined in NumbTh.cpp)

  if (_gens.size() == 0 || isDryRun()) 
      ordP = findGenerators(this->gens, this->ords, mm, pp);
  else {
    assert(_gens.size() == _ords.size());
    gens = _gens;
    ords = _ords;
    ordP = multOrd(pp, mm);
  }
  nSlots = qGrpOrd();
  phiM = ordP * nSlots;

  // Allocate space for the various arrays
  T.resize(nSlots);
  dLogT.resize(nSlots*gens.size());
  Tidx.assign(mm,-1);    // allocate m slots, initialize them to -1
  zmsIdx.assign(mm,-1);  // allocate m slots, initialize them to -1
  long i, idx;
  for (i=idx=0; i<(long)mm; i++) if (GCD(i,mm)==1) zmsIdx[i] = idx++;

  // Now fill the Tidx and dLogT translation tables. We identify an element
  // t\in T with its representation t = \prod_{i=0}^n gi^{ei} mod m (where
  // the gi's are the generators in gens[]) , represent t by the vector of
  // exponents *in reverse order* (en,...,e1,e0), and order these vectors
  // in lexicographic order.

  // FIXME: is the comment above about reverse order true? It doesn't 
  // seem like it to me.  VJS.

  // buffer is initialized to all-zero, which represents 1=\prod_i gi^0
  vector<unsigned long> buffer(gens.size()); // temporaty holds exponents
  i = idx = 0;
  long ctr = 0;
  do {
    ctr++;
    unsigned long t = exponentiate(buffer);
    for (unsigned long j=0; j<buffer.size(); j++) dLogT[idx++] = buffer[j];

    assert(GCD(t,mm) == 1); // sanity check for user-supplied gens
    assert(Tidx[t] == -1);

    T[i] = t;       // The i'th element in T it t
    Tidx[t] = i++;  // the index of t in T is i

    // increment buffer by one (in lexigoraphic order)
  } while (nextExpVector(buffer)); // until we cover all the group

  assert(ctr == long(nSlots)); // sanity check for user-supplied gens

  PhimX = Cyclotomic(mm); // compute and store Phi_m(X)

  // initialize prods array
  long ndims = gens.size();
  prods.resize(ndims+1);
  prods[ndims] = 1;
  for (long j = ndims-1; j >= 0; j--) {
    prods[j] = OrderOf(j) * prods[j+1];
  }
  //  pp_factorize(mFactors,mm); // prime-power factorization from NumbTh.cpp
}
Beispiel #17
0
	shared_ptr<GroupElement> exponentiateWithPreComputedValues(shared_ptr<GroupElement> groupElement, 
		biginteger exponent) override { return exponentiate(groupElement, exponent); };
Beispiel #18
0
// create a BPST instanton lattice configuration
int
instanton_config( struct site *lat ) 
{
#if ND != 4
  fprintf( stderr , "Instanton solution not available for ND = %d \n" , ND ) ;
  return GLU_FAILURE ;
#else
  // embed pauli matrices in SU(NC) matrices
  GLU_complex t[ 3 ][ NCNC ] GLUalign ;  
  size_t mu ;
  for( mu = 0 ; mu < 3 ; mu++ ) { zero_mat( t[mu] ) ; }
  t[0][1] = +1. ; t[0][NC]   = +1. ;
  t[1][1] = -I  ; t[1][NC]   =  I  ;
  t[2][0] = +1. ; t[2][NC+1] = -1. ;

  const GLU_real rho = 4.0 ; // instanton size
  const GLU_real sign = 1 ; // instanton (-1) or anti-instanton (1)
  GLU_real c[ ND ] ;
  for( mu = 0 ; mu < ND ; mu++ ) {
    // put it just off the centre
    c[ mu ] = ( Latt.dims[mu]/2 - 0.5 ) ;
  }

  size_t i ;
  #pragma omp parallel for private(i)
  for( i = 0 ; i < LVOLUME ; i++ ) {

    // compute lattice position vector ...
    int x[ ND ] ;
    get_mom_2piBZ( x , i , ND ) ;

    // compute the coordinate "y"
    GLU_real y[ ND ] ;
    size_t nu ;
    for( nu = 0 ; nu < ND ; nu++ ) {
      y[ nu ] = x[ nu ] - c[ nu ] ;
    }
    
    // compute "b"
    GLU_real b[ ND ][ 3 ] ;
    b[0][0] = -sign *y[3]; b[0][1] =  y[2];       b[0][2] = -y[1];
    b[1][0] = -y[2];       b[1][1] = -sign *y[3]; b[1][2] =  y[0];
    b[2][0] =  y[1];       b[2][1] = -y[0];       b[2][2] = -sign *y[3];
    b[3][0] =  sign *y[0]; b[3][1] =  sign *y[1]; b[3][2] =  sign *y[2]; 
 
    // perform the exponentiation, loop nu
    for( nu = 0 ; nu < ND ; nu++ ) {
      GLU_complex temp[ NCNC ] GLUalign ;
      zero_mat( temp ) ;
      size_t j , k ;
      for( j = 0 ; j < 3 ; j++ ) {
	for( k = 0 ; k < NCNC ; k++ ) {
	  temp[ k ] += b[ nu ][ j ] * t[ j ][ k ] ; 
	}
      }
      // multiply by asing
      #ifdef SINGULAR
      const GLU_real c = Asing( y , 0 , nu ) - Asing( y , rho , nu ) ;
      #else
      const GLU_real c = Asing( y , rho , nu ) ;
      #endif
      for( j = 0 ; j < NCNC ; j++ ) {
	temp[ j ] *= c ; 
      }
      exponentiate( lat[i].O[nu] , temp ) ;
    }
  }
  return GLU_SUCCESS ;
#endif
}
int main() {
  printf("2^7: %i\n", exponentiate(2, 7));
  printf("7^5: %i\n", exponentiate(7, 5));
}