#include #include #include //for multithreading #include #include #include //getLine #include "misc.h" #define DOUBLEMODE 0 #define DOUBLEERRORMODE 1 #define RATIOMODE 2 /*Determines if computations are done with floating point type, floating point with error bounds or fractions. Floating point without error bounds are the default.*/ #ifndef MODE #define MODE DOUBLEMODE #endif /*number of threads for parallel execution.*/ #define NUM_THREADS 7 /*Make sure the appropriate files are included for the type of computation and sets the data types accordingly.*/ #if MODE == DOUBLEERRORMODE #include "double-error.h" #define VALUETYPE double_error #define EXPTYPE double_error #elif MODE == RATIOMODE #include "ratio.h" #define VALUETYPE rational #define EXPTYPE unsigned int #else #include "double.h" #define VALUETYPE double #define EXPTYPE double #endif #define STRING_SIZE 65536 typedef unsigned long index_t; /*maximum length of the circle*/ #define N 36 /*maximal order of derivative*/ #define K 64 /*maximal number of exponents*/ #define P 5 /*Given function f on domain [0,D-1], compute derivative of order k and store result in df.*/ void differentiate(VALUETYPE* f, VALUETYPE* df, int D, int k){ VALUETYPE df0[D]; /*Set zeroth derivative to be f.*/ for(int i=0; i0; l--) { /*Go through all intervals [i,i+l).*/ for(int i=0; iD it suffices to go until i+D-1.*/ int intervalend = fmin(i+l,i+D); int n=i; while(n < intervalend){ /*If the average of the current best interval for n is surely larger than A[i][l] then the same will be true for all subsequent points in that interval. Thus, to save time just skip ahead to the end of that interval.*/ if(is_greater_certainly(Af[Pbest[n%D]][Lbest[n%D]],Af[i][l])) n += (Pbest[n%D]-n-D)%D + Lbest[n%D]; else{ /*Since the new average might win set the new best average to be the maximum of the last maximum and the new.*/ A = maximum(A,Af[Pbest[n%D]][Lbest[n%D]]); /*To avoid duplicating computations, look ahead how many subsequent points have as their latest best interval the same interval, and accordingly set their new current best average to be the same.*/ int k = n+1; while((Pbest[k%D] == Pbest[n%D]) && (Lbest[k%D] == Lbest[n%D]) && k= powd){ /*Increment s,d,powd to correspond to functions of length d+1.*/ s += powd; d++; powd = powd << 1; } /*If our index i corresponds to a function on a circle of length larger than N then return -1 which will causo the program to stop.*/ if(d>N) return -1; /*t encodes a characteristic function on the circle of length d. Since we only consider functions with f[0]=0 and f[d-1]=1, set its places accordingly.*/ index_t t = ( (i-s) << 1 ) + 1UL; /*This variable indicates if we want to consider this t. Next we will perform test to determine if it should be set to false.*/ bool is_representative = true; /*Check if t encodes a function that is made up of multiple copies of a shorter function. We skip those because they and their maximal function are periodic and thus should be considered on a smaller circle instead.*/ /*Go through all possible lenghts r of that shorter function.*/ for(int r = 1; r < d; r++){ /*r has to be a divisor of d.*/ if(d % r == 0){ bool is_r_copy = true; /*bit mask of length r*/ index_t ones = 0; for(int o = 0; o>n*r) & ones ) != tail ) is_r_copy = false; if(is_r_copy) is_representative = false; } } /*We aim to filter out equivalent translates. The representative we pick is the one which represents the smallest integer. Every function which is a nontrivial translate of itself must in fact consist of multiplie copies of a shorter array (right?). Those we already filtered out in the previous step, so every nontrivial translate of that representative indeed represents a strictly smaller integer. */ if(is_representative){ index_t ones = 0; for(int o = 0; o= ( (t<>(d-n)) & ones) ) is_representative = false; } /*Set f to the values encoded in bit array t.*/ if(is_representative){ for(int n=0; n> n) & 1UL); return d; } else return 0; } int generate_triangle(VALUETYPE* f, index_t i){ int j = i+1; if(j <= N/2){ for(int n=0; n < N; n++) f[n] = int_to_valuetype(0); for(int n=0; n < j; n++) f[n] = int_to_valuetype(j-n); for(int n=1; n < j; n++) f[N-n] = int_to_valuetype(j-n); return N; } else return -1; } int generate_random(VALUETYPE* f, index_t i){ f[0] = int_to_valuetype(1); f[1] = int_to_valuetype(0); for(int n=2; n < N; n++) f[n] = int_to_valuetype(rand() % 2); return N; } /*Writes into f the values of the function indexed by i. Returns the size of the support of f, or -1 if there is no function with that index.*/ int generate_function(VALUETYPE* f, index_t i){ return generate_each_charf(f,i); //return generate_random(f,i); //return generate_triangle(f,i); } #define FORMAT_TEXT 0 #define FORMAT_LATEX 1 /*Write into pointer s the function corresponding to an index, and that the ratio of the L^p norms of the kth derivative of the maximal function and the function equals r.*/ void format_result(char* s, index_t index, int k, EXPTYPE p, VALUETYPE r, int format){ VALUETYPE f[N]; int d = generate_function(f,index); if(format == FORMAT_TEXT){ strcpy(s,"f: "); int l = 3; for(int i=0; i=1){ /*Compute kth derivative of f and Mf from (k-1)th derivative*/ differentiate(df[(k+1)%2],df[k%2],D,1); differentiate(dMf[(k+1)%2],dMf[k%2],D,1); } for(int p=0; p num_thread; int* domain_current = args -> domain_current; int d = 0; while(d >= 0){ d = compute(i, args -> exponents, args -> records_ratio, args -> records_index); if(d > *domain_current){ *domain_current = d; printf("Start considering length: %d\n",d); } i += NUM_THREADS; } (*(args -> cont))++; if(*(args -> cont) >= NUM_THREADS) printf("Calculation finished. Press any button to stop.\n"); return NULL; } int main() { EXPTYPE exponents[P]; exponents[0] = int_to_exptype(1); exponents[1] = int_to_exptype(2); exponents[2] = int_to_exptype(4); exponents[3] = int_to_exptype(8); exponents[4] = infinity_to_exptype(); pthread_t threads[NUM_THREADS]; Args args[NUM_THREADS]; VALUETYPE records_ratio[K+1][P]; index_t records_index[K+1][P]; for(int k=0; k<=K; k++) for(int p=0; p