diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2010-02-17 13:25:03 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2010-02-17 13:25:03 +0000 |
commit | f9ebf19ba3ca4c3ee67cc88bbea407d4dd734249 (patch) | |
tree | 0bb8ef7d55cc633fccefc77f27e50029af74adcf /test/c | |
parent | 6f3a9afdda5c02dc84522fc8604addb7e5c8d7df (diff) |
3 more benchmarks
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1252 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test/c')
-rw-r--r-- | test/c/Makefile | 3 | ||||
-rw-r--r-- | test/c/Results/bisect | 20 | ||||
-rw-r--r-- | test/c/Results/chomp | 19 | ||||
-rw-r--r-- | test/c/Results/perlin | 1 | ||||
-rw-r--r-- | test/c/bisect.c | 376 | ||||
-rw-r--r-- | test/c/chomp.c | 370 | ||||
-rw-r--r-- | test/c/perlin.c | 75 |
7 files changed, 863 insertions, 1 deletions
diff --git a/test/c/Makefile b/test/c/Makefile index bff6211..060c8fc 100644 --- a/test/c/Makefile +++ b/test/c/Makefile @@ -12,7 +12,8 @@ TIME=xtime -o /dev/null -mintime 1.0 # Xavier's hack BENCHS=fib integr qsort fft sha1 aes almabench lists \ binarytrees fannkuch knucleotide mandelbrot nbody \ - nsieve nsievebits spectral vmach + nsieve nsievebits spectral vmach \ + bisect chomp perlin PROGS=$(BENCHS) initializers diff --git a/test/c/Results/bisect b/test/c/Results/bisect new file mode 100644 index 0000000..de52da1 --- /dev/null +++ b/test/c/Results/bisect @@ -0,0 +1,20 @@ + 2 1.60051e+01 + 3 8.10101e+01 + 4 2.56008e+02 + 5 6.25006e+02 + 6 1.29600e+03 + 7 2.40100e+03 + 8 4.09600e+03 + 9 6.56100e+03 + 10 1.00000e+04 + 11 1.46410e+04 + 12 2.07360e+04 + 13 2.85610e+04 + 14 3.84160e+04 + 15 5.06250e+04 + 16 6.55360e+04 + 17 8.35210e+04 + 18 1.04976e+05 + 19 1.30321e+05 + 20 1.60000e+05 +eps2 = 9.71445e-05, k = 22965 diff --git a/test/c/Results/chomp b/test/c/Results/chomp new file mode 100644 index 0000000..c215420 --- /dev/null +++ b/test/c/Results/chomp @@ -0,0 +1,19 @@ +player 0 plays at (2,2) +player 1 plays at (7,1) +player 0 plays at (0,2) +player 1 plays at (7,0) +player 0 plays at (6,1) +player 1 plays at (6,0) +player 0 plays at (5,1) +player 1 plays at (5,0) +player 0 plays at (4,1) +player 1 plays at (4,0) +player 0 plays at (3,1) +player 1 plays at (3,0) +player 0 plays at (2,1) +player 1 plays at (2,0) +player 0 plays at (1,1) +player 1 plays at (1,0) +player 0 plays at (0,1) +player 1 plays at (0,0) +player 1 loses diff --git a/test/c/Results/perlin b/test/c/Results/perlin new file mode 100644 index 0000000..74e5655 --- /dev/null +++ b/test/c/Results/perlin @@ -0,0 +1 @@ +1.7556e+02 diff --git a/test/c/bisect.c b/test/c/bisect.c new file mode 100644 index 0000000..759f997 --- /dev/null +++ b/test/c/bisect.c @@ -0,0 +1,376 @@ +/**** + Copyright (C) 1996 McGill University. + Copyright (C) 1996 McCAT System Group. + Copyright (C) 1996 ACAPS Benchmark Administrator + benadmin@acaps.cs.mcgill.ca + + This program is free software; you can redistribute it and/or modify + it provided this copyright notice is maintained. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +****/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <float.h> + +void *allocvector(size_t size) +{ + void *V; + + if ( (V = (void *) malloc((size_t) size)) == NULL ) { + fprintf(stderr, "Error: couldn't allocate V in allocvector.\n"); + exit(2); + } + memset(V,0,size); + return V; +} + +void dallocvector(int n, double **V) +{ + *V = (double *) allocvector((size_t) n*sizeof(double)); +} + + +#define FUDGE (double) 1.01 + + + +int sturm(int n, double c[], double b[], double beta[], double x) + +/************************************************************************** + +Purpose: +------------ + Calculates the sturm sequence given by + + q_1(x) = c[1] - x + + q_i(x) = (c[i] - x) - b[i]*b[i] / q_{i-1}(x) + + and returns a(x) = the number of negative q_i. a(x) gives the number + of eigenvalues smaller than x of the symmetric tridiagonal matrix + with diagonal c[0],c[1],...,c[n-1] and off-diagonal elements + b[1],b[2],...,b[n-1]. + + +Input parameters: +------------------------ + n : + The order of the matrix. + + c[0]..c[n-1] : + An n x 1 array giving the diagonal elements of the tridiagonal matrix. + + b[1]..b[n-1] : + An n x 1 array giving the sub-diagonal elements. b[0] may be + arbitrary but is replaced by zero in the procedure. + + beta[1]..beta[n-1] : + An n x 1 array giving the square of the sub-diagonal elements, + i.e. beta[i] = b[i]*b[i]. beta[0] may be arbitrary but is replaced by + zero in the procedure. + + x : + Argument for the Sturm sequence. + + +Returns: +------------------------ + integer a = Number of eigenvalues of the matrix smaller than x. + + +Notes: +------------------------ +On SGI PowerChallenge this function should be compiled with option +"-O3 -OPT:IEEE_arithmetic=3" in order to activate the optimization +mentioned in the code below. + + +**********************************************************************/ + +{ + int i; + int a; + double q; + + a = 0; + q = 1.0; + + for(i=0; i<n; i++) { + +#ifndef TESTFIRST + + if (q != 0.0) { + +#ifndef RECIPROCAL + q = (c[i] - x) - beta[i]/q; +#else + /* A potentially NUMERICALLY DANGEROUS optimizations is used here. + * The previous statement should read: + * q = (c[i] - x) - beta[i]/q + * But computing the reciprocal might help on some architectures + * that have multiply-add and/or reciprocal instuctions. + */ + iq = 1.0/q; + q = (c[i] - x) - beta[i]*iq; +#endif + + } + else { + q = (c[i] - x) - fabs(b[i])/DBL_EPSILON; + } + + if (q < 0) + a = a + 1; + } + +#else + + if (q < 0) { + a = a + 1; + +#ifndef RECIPROCAL + q = (c[i] - x) - beta[i]/q; +#else + /* A potentially NUMERICALLY DANGEROUS optimizations is used here. + * The previous statement should read: + * q = (c[i] - x) - beta[i]/q + * But computing the reciprocal might help on some architectures + * that have multiply-add and/or reciprocal instuctions. + */ + iq = 1.0/q; + q = (c[i] - x) - beta[i]*iq; +#endif + + } + else if (q > 0.0) { +#ifndef RECIPROCAL + q = (c[i] - x) - beta[i]/q; +#else + /* A potentially NUMERICALLY DANGEROUS optimizations is used here. + * The previous statement should read: + * q = (c[i] - x) - beta[i]/q + * But computing the reciprocal might help on some architectures + * that have multiply-add and/or reciprocal instuctions. + */ + iq = 1.0/q; + q = (c[i] - x) - beta[i]*iq; +#endif + } + else { + q = (c[i] - x) - fabs(b[i])/DBL_EPSILON; + } + + } + if (q < 0) + a = a + 1; +#endif + + return a; +} + + + + +void dbisect(double c[], double b[], double beta[], + int n, int m1, int m2, double eps1, double *eps2, int *z, + double x[]) + + +/************************************************************************** + +Purpose: +------------ + + Calculates eigenvalues lambda_{m1}, lambda_{m1+1},...,lambda_{m2} of + a symmetric tridiagonal matrix with diagonal c[0],c[1],...,c[n-1] + and off-diagonal elements b[1],b[2],...,b[n-1] by the method of + bisection, using Sturm sequences. + + + Input parameters: +------------------------ + + c[0]..c[n-1] : + An n x 1 array giving the diagonal elements of the tridiagonal matrix. + + b[1]..b[n-1] : + An n x 1 array giving the sub-diagonal elements. b[0] may be + arbitrary but is replaced by zero in the procedure. + + beta[1]..beta[n-1] : + An n x 1 array giving the square of the sub-diagonal elements, + i.e. beta[i] = b[i]*b[i]. beta[0] may be arbitrary but is replaced by + zero in the procedure. + + n : + The order of the matrix. + + m1, m2 : + The eigenvalues lambda_{m1}, lambda_{m1+1},...,lambda_{m2} are + calculated (NB! lambda_1 is the smallest eigenvalue). + m1 <= m2must hold otherwise no eigenvalues are computed. + returned in x[m1-1],x[m1],...,x[m2-1] + + eps1 : + a quantity that affects the precision to which eigenvalues are + computed. The bisection is continued as long as + x_high - x_low > 2*DBL_EPSILON(|x_low| + |x_high|) + eps1 (1) + When (1) is no longer satisfied, (x_high + x_low)/2 gives the + current eigenvalue lambda_k. Here DBL_EPSILON (constant) is + the machine accuracy, i.e. the smallest number such that + (1 + DBL_EPSILON) > 1. + + Output parameters: +------------------------ + + eps2 : + The overall bound for the error in any eigenvalue. + z : + The total number of iterations to find all eigenvalues. + x : + The array x[m1],x[m1+1],...,x[m2] contains the computed eigenvalues. + +**********************************************************************/ +{ + int i; + double h,xmin,xmax; + beta[0] = b[0] = 0.0; + + + /* calculate Gerschgorin interval */ + xmin = c[n-1] - FUDGE*fabs(b[n-1]); + xmax = c[n-1] + FUDGE*fabs(b[n-1]); + for(i=n-2; i>=0; i--) { + h = FUDGE*(fabs(b[i]) + fabs(b[i+1])); + if (c[i] + h > xmax) xmax = c[i] + h; + if (c[i] - h < xmin) xmin = c[i] - h; + } + + /* printf("xmax = %lf xmin = %lf\n",xmax,xmin); */ + + /* estimate precision of calculated eigenvalues */ + *eps2 = DBL_EPSILON * (xmin + xmax > 0 ? xmax : -xmin); + if (eps1 <= 0) + eps1 = *eps2; + *eps2 = 0.5 * eps1 + 7 * *eps2; + { int a,k; + double x1,xu,x0; + double *wu; + + if( (wu = (double *) calloc(n+1,sizeof(double))) == NULL) { + fputs("bisect: Couldn't allocate memory for wu",stderr); + exit(1); + } + + /* Start bisection process */ + x0 = xmax; + for(i=m2; i >= m1; i--) { + x[i] = xmax; + wu[i] = xmin; + } + *z = 0; + /* loop for the k-th eigenvalue */ + for(k=m2; k>=m1; k--) { + xu = xmin; + for(i=k; i>=m1; i--) { + if(xu < wu[i]) { + xu = wu[i]; + break; + } + } + if (x0 > x[k]) + x0 = x[k]; + + x1 = (xu + x0)/2; + while ( x0-xu > 2*DBL_EPSILON*(fabs(xu)+fabs(x0))+eps1 ) { + *z = *z + 1; + + /* Sturms Sequence */ + + a = sturm(n,c,b,beta,x1); + + /* Bisection step */ + if (a < k) { + if (a < m1) + xu = wu[m1] = x1; + else { + xu = wu[a+1] = x1; + if (x[a] > x1) x[a] = x1; + } + } + else { + x0 = x1; + } + x1 = (xu + x0)/2; + } + x[k] = (xu + x0)/2; + } + free(wu); + } +} + +void test_matrix(int n, double *C, double *B) +/* Symmetric tridiagonal matrix with diagonal + + c_i = i^4, i = (1,2,...,n) + + and off-diagonal elements + + b_i = i-1, i = (2,3,...n). + It is possible to determine small eigenvalues of this matrix, with the + same relative error as for the large ones. +*/ +{ + int i; + + for(i=0; i<n; i++) { + B[i] = (double) i; + C[i] = (double ) (i+1)*(i+1); + C[i] = C[i] * C[i]; + } +} + + +int main(int argc,char *argv[]) +{ + int rep,n,k,i,j; + double eps,eps2; + double *D,*E,*beta,*S; + + rep = 50; + n = 500; + eps = 2.2204460492503131E-16; + + dallocvector(n,&D); + dallocvector(n,&E); + dallocvector(n,&beta); + dallocvector(n,&S); + + for (j=0; j<rep; j++) { + test_matrix(n,D,E); + + for (i=0; i<n; i++) { + beta[i] = E[i] * E[i]; + S[i] = 0.0; + } + + E[0] = beta[0] = 0; + dbisect(D,E,beta,n,1,n,eps,&eps2,&k,&S[-1]); + + } + + for(i=1; i<20; i++) + printf("%5d %.5e\n",i+1,S[i]); + + printf("eps2 = %.5e, k = %d\n",eps2,k); + + return 0; +} + + diff --git a/test/c/chomp.c b/test/c/chomp.c new file mode 100644 index 0000000..042877d --- /dev/null +++ b/test/c/chomp.c @@ -0,0 +1,370 @@ +#include <stdio.h> +#include <stdlib.h> + +#define NDATA (int *)malloc(ncol * sizeof(int)) +#define NLIST (struct _list *)malloc(sizeof(struct _list)) +#define NPLAY (struct _play *)malloc(sizeof(struct _play)) + +struct _list +{ + int *data; + struct _list *next; +} *wanted; + +struct _play +{ + int value; + int *state; + struct _list *first; + struct _play *next; +} *game_tree; + +int nrow,ncol; /* global so as to avoid passing them all over the place */ + +int *copy_data(data) /* creates a duplicate of a given -data list */ +int *data; +{ + int *new = NDATA; + int counter = ncol; + while (counter --) + new[counter] = data[counter]; + return new; +} + +int next_data(int *data) /* gives the next logical setup to the one passed */ + /* new setup replaces the old. Returns 0 if no valid */ +{ /* setup exists after the one passed */ + int counter = 0; + int valid = 0; /* default to none */ + while ((counter != ncol) && (! valid)) /* until its done */ + { + if (data[counter] == nrow) /* if we hit a border */ + { + data[counter] = 0; /* reset it to zero */ + counter ++; /* and take next column */ + } + else + { + data[counter] ++; /* otherwise, just increment row number */ + valid = 1; /* and set valid to true. */ + } + } + return valid; /* return whether or not */ +} /* a next could be found */ + +void melt_data(int *data1,int *data2) /* melts 2 _data's into the first one. */ +{ + int counter = ncol; + while (counter --) /* do every column */ + { + if (data1[counter] > data2[counter]) /* take the lowest one */ + data1[counter] = data2[counter]; /* and put in first _data */ + } +} + +int equal_data(int *data1,int *data2) /* check if both _data's are equal */ +{ + int counter = ncol; + while ((counter --) && (data1[counter] == data2[counter])); + return (counter < 0); +} + +int valid_data(int *data) /* checks if the play could ever be achieved. */ +{ + int low; /* var to hold the current height */ + int counter = 0; + low = nrow; /* default to top of board */ + while (counter != ncol) /* for every column */ + { + if (data[counter] > low) break; /* if you get something higher */ + low = data[counter]; /* set this as current height */ + counter ++; + } + return (counter == ncol); +} + +void dump_list(struct _list *list) /* same for a _list structure */ +{ + if (list != NULL) + { + dump_list(list -> next); /* dump the rest of it */ + free(list -> data); /* and its _data structure */ + free(list); + } +} + +void dump_play(play) /* and for the entire game tree */ +struct _play *play; +{ + if (play != NULL) + { + dump_play(play -> next); /* dump the rest of the _play */ + dump_list(play -> first); /* its _list */ + free(play -> state); /* and its _data */ + free(play); + } +} + +int get_value(int *data) /* get the value (0 or 1) for a specific _data */ +{ + struct _play *search; + search = game_tree; /* start at the begginig */ + while (! equal_data(search -> state,data)) /* until you find a match */ + search = search -> next; /* take next element */ + return search -> value; /* return its value */ +} + +void show_data(int *data) /* little display routine to give off results */ +{ + int counter = 0; + while (counter != ncol) + { + printf("%d",data[counter ++]); + if (counter != ncol) putchar(','); + } +} + +void show_move(int *data) /* puts in the "(" and ")" for show_data() */ +{ + putchar('('); + show_data(data); + printf(")\n"); +} + +void show_list(struct _list *list) /* show the entire list of moves */ +{ + while (list != NULL) + { + show_move(list -> data); + list = list -> next; + } +} + +void show_play(struct _play *play) /* to diplay the whole tree */ +{ + while (play != NULL) + { + printf("For state :\n"); + show_data(play -> state); + printf(" value = %d\n",play -> value); + printf("We get, in order :\n"); + show_list(play -> first); + play = play -> next; + } +} + +int in_wanted(int *data) /* checks if the current _data is in the wanted list */ +{ + struct _list *current; + current = wanted; /* start at the begginig */ + while (current != NULL) /* unitl the last one */ + { + if (equal_data(current -> data,data)) break; /* break if found */ + current = current -> next; /* take next element */ + } + if (current == NULL) return 0; /* if at the end, not found */ + return 1; +} + +int *make_data(int row,int col) /* creates a new _data with the correct */ + /* contents for the specified row & col */ +{ + int count; + int *new = NDATA; + for (count = 0;count != col;count ++) /* creates col-1 cells with nrow */ + new[count] = nrow; + for (;count != ncol;count ++) /* and the rest with row as value */ + new[count] = row; + return new; /* and return pointer to first element */ +} + +struct _list *make_list(int *data,int *value,int *all) /* create the whole _list of moves */ + /* for the _data structure data */ +{ + int row,col; + int *temp; + struct _list *head,*current; + *value = 1; /* set to not good to give */ + head = NLIST; /* create dummy header */ + head -> next = NULL; /* set NULL as next element */ + current = head; /* start from here */ + for (row = 0;row != nrow;row ++) /* for every row */ + { + for (col = 0;col != ncol;col ++) /* for every column */ + { + temp = make_data(row,col); /* create _data for this play */ + melt_data(temp,data); /* melt it with the current one */ + if (! equal_data(temp,data)) /* if they are different, it good */ + { + current -> next = NLIST; /* create new element in list */ + current -> next -> data = copy_data(temp); /* copy data, and place in list */ + current -> next -> next = NULL; /* NULL the next element */ + current = current -> next; /* advance pointer */ + if (*value == 1) /* if still not found a good one */ + *value = get_value(temp); /* look at this value */ + if ((! *all) && (*value == 0)) + { /* if we found it, and all is not set */ + col = ncol - 1; /* do what it take sto break out now */ + row = nrow - 1; + if (in_wanted(temp)) /* if in the wanted list */ + *all = 2; /* flag it */ + } + } + else /* if its not a valid move */ + { + if (col == 0) row = nrow - 1; /* break out if at first column */ + col = ncol - 1; /* but make sure you break out */ + } /* of the col for-loop anyway */ + free(temp); /* dump this unneeded space */ + } + } + current = head -> next; /* skip first element */ + free(head); /* dump it */ + if (current != NULL) *value = 1 - *value; /* invert value if its */ + return current; /* not the empty board */ +} + +struct _play *make_play(int all) /* make up the entire tree-like stuff */ +{ + int val; + int *temp; + struct _play *head,*current; + head = NPLAY; /* dummy header again */ + current = head; /* start here */ + game_tree = NULL; /* no elements yet */ + temp = make_data(0,0); /* new data, for empty board */ + temp[0] --; /* set it up at (-1,xx) so that next_data() returns (0,xx) */ + while (next_data(temp)) /* take next one, and break if none */ + { + if (valid_data(temp)) /* if board position is possible */ + { + current -> next = NPLAY; /* create a new _play cell */ + if (game_tree == NULL) game_tree = current -> next; + /* set up game_tree if it was previously NULL */ + current -> next -> state = copy_data(temp); /* make a copy of temp */ + current -> next -> first = make_list(temp,&val,&all); + /* make up its whole list of possible moves */ + current -> next -> value = val; /* place its value */ + current -> next -> next = NULL; /* no next element */ + current = current -> next; /* advance pointer */ + if (all == 2) /* if found flag is on */ + { + free(temp); /* dump current temp */ + temp = make_data(nrow,ncol); /* and create one that will break */ + } + } + } + current = head -> next; /* skip first element */ + free(head); /* dump it */ + return current; /* and return pointer to start of list */ +} + +void make_wanted(int *data) /* makes up the list of positions from the full board */ +{ + /* everything here is almost like in the previous function. */ + /* The reason its here, is that it does not do as much as */ + /* the one before, and thus goes faster. Also, it saves the */ + /* results directly in wanted, which is a global variable. */ + + int row,col; + int *temp; + struct _list *head,*current; + head = NLIST; + head -> next = NULL; + current = head; + for (row = 0;row != nrow;row ++) + { + for (col = 0;col != ncol;col ++) + { + temp = make_data(row,col); + melt_data(temp,data); + if (! equal_data(temp,data)) + { + current -> next = NLIST; + current -> next -> data = copy_data(temp); + current -> next -> next = NULL; + current = current -> next; + } + else + { + if (col == 0) row = nrow - 1; + col = ncol - 1; + } + free(temp); + } + } + current = head -> next; + free(head); + wanted = current; +} + +int *get_good_move(struct _list *list) /* gets the first good move from a _list */ +{ + if (list == NULL) return NULL; /* if list is NULL, say so */ + /* until end-of-list or a good one is found */ + /* a good move is one that gives off a zero value */ + while ((list -> next != NULL) && (get_value(list -> data))) + list = list -> next; + return copy_data(list -> data); /* return the value */ +} + +int *get_winning_move(struct _play *play) /* just scans for the first good move */ + /* in the last _list of a _play. This */ +{ /* is the full board */ + int *temp; + while (play -> next != NULL) play = play -> next; /* go to end of _play */ + temp = get_good_move(play -> first); /* get good move */ + return temp; /* return it */ +} + +struct _list *where(int *data,struct _play *play) +{ + while (! equal_data(play -> state,data)) /* search for given _data */ + play = play -> next; + return play -> first; /* return the pointer */ +} + +void get_real_move(int *data1,int *data2,int *row,int *col) /* returns row & col of the move */ + /* which created data1 from data2 */ +{ + *col = 0; + while (data1[*col] == data2[*col]) /* until there is a change */ + (*col) ++; /* and increment col number */ + *row = data1[*col]; /* row is given by the content of the structure */ +} + +int main(void) +{ + int row,col,player; + int *current,*temp; + struct _play *tree; + + + ncol = 7; +#ifdef SMALL_PROBLEM_SIZE + nrow = 7; +#else + nrow = 8; +#endif + tree = make_play(1); /* create entire tree structure, not just the */ + player = 0; /* needed part for first move */ + current = make_data(nrow,ncol); /* start play at full board */ + while (current != NULL) + { + temp = get_good_move(where(current,tree)); /* get best move */ + if (temp != NULL) /* temp = NULL when the poison pill is taken */ + { + get_real_move(temp,current,&row,&col); /* calculate coordinates */ + /* print it out nicely */ + printf("player %d plays at (%d,%d)\n",player,row,col); + player = 1 - player; /* next player to do the same */ + free(current); /* dump for memory management */ + } + current = temp; /* update board */ + } + dump_play(tree); /* dump unneeded tree */ + printf("player %d loses\n",1 - player); /* display winning player */ + return 0; +} + +/*****************************************************************************/ diff --git a/test/c/perlin.c b/test/c/perlin.c new file mode 100644 index 0000000..1559c1c --- /dev/null +++ b/test/c/perlin.c @@ -0,0 +1,75 @@ +// perlin noise, derived from the Java reference implementation at +// http://mrl.nyu.edu/~perlin/noise/ + +#include <math.h> +#include <stdio.h> + +static int p[512]; + +static int permutation[256] = { 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 + }; + +static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); } + +static double lerp(double t, double a, double b) { return a + t * (b - a); } + +static double grad(int hash, double x, double y, double z) { + int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + double u = h<8 ? x : y, // INTO 12 GRADIENT DIRECTIONS. + v = h<4 ? y : h==12||h==14 ? x : z; + return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); +} + +static double noise(double x, double y, double z) { + int X = (int)floor(x) & 255, // FIND UNIT CUBE THAT + Y = (int)floor(y) & 255, // CONTAINS POINT. + Z = (int)floor(z) & 255; + x -= floor(x); // FIND RELATIVE X,Y,Z + y -= floor(y); // OF POINT IN CUBE. + z -= floor(z); + double u = fade(x), // COMPUTE FADE CURVES + v = fade(y), // FOR EACH OF X,Y,Z. + w = fade(z); + int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z, // HASH COORDINATES OF + B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS, + + return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD + grad(p[BA ], x-1, y , z )), // BLENDED + lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS + grad(p[BB ], x-1, y-1, z ))),// FROM 8 + lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS + grad(p[BA+1], x-1, y , z-1 )), // OF CUBE + lerp(u, grad(p[AB+1], x , y-1, z-1 ), + grad(p[BB+1], x-1, y-1, z-1 )))); +} + +static void init() { + int i = 0; + for (i=0; i < 256 ; i++) + p[256+i] = p[i] = permutation[i]; +} + +int main() { + init(); + + double x, y, z, sum = 0.0; + for (x = -11352.57; x < 23561.57; x += .1235) + for (y = -346.1235; y < 124.124; y += 1.4325) + for (z = -156.235; y < 23.2345; y += 2.45) + sum += noise(x, y, z); + + printf("%.4e\n", sum); + return 0; +} |