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); }
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; }
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; } }
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 ; }
// 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(); } } }
// 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); }
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; }
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; }
// 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]; } }
// 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 ; }
H2Point H2TangentVector::exponentiate() const { return exponentiate(1.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 }
shared_ptr<GroupElement> exponentiateWithPreComputedValues(shared_ptr<GroupElement> groupElement, biginteger exponent) override { return exponentiate(groupElement, exponent); };
// 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)); }