// Computes the probabilities given the set of images void computeProb(void* sdram_ptr, double** wL1, double** wL2, double** wL3, double** bias, double*** probabilities) { int i, j, k; // i represents rows, j represents columns double** layer1 = create2DDoubleArray(LAYER1, NUMTEST); printf("Computing layer 1...\n"); for(i = 0; i < LAYER1; i++) { for(j = 0; j < NUMTEST; j++) { layer1[i][j] = 0; for(k = 0; k < IMGSIZE; k++) { layer1[i][j] += wL1[i][k] * ((double*)sdram_ptr)[k * NUMIMGS + j]; } } printf("Computing Layer 1 Node #: %d\n", i); } printf("Applying layer 1 bias and sigmoid...\n"); for(i = 0; i < LAYER1; i++) { for(j = 0; j < NUMTEST; j++) { layer1[i][j] += bias[i][0]; layer1[i][j] = 1 / (1 + exp(1 - layer1[i][j])); } } printf("Layer 1 computation complete!\n"); printf("Computing layer 2...\n"); double** layer2 = multiplyMatrices(wL2, LAYER2, LAYER1, layer1, LAYER1, NUMTEST); printf("Applying layer 2 bias and sigmoid...\n"); for(i = 0; i < LAYER2; i++) { for(j = 0; j < NUMTEST; j++) { layer2[i][j] += bias[i][1]; layer2[i][j] = 1 / (1 + exp(1 - layer2[i][j])); } } printf("Layer 2 computation complete!\n"); free(layer1); printf("Computing final probabilities...\n"); (*probabilities) = multiplyMatrices(wL3, LAYERFINAL, LAYER2, layer2, LAYER2, NUMTEST); printf("Applying probability sigmoid...\n"); for(i = 0; i < LAYERFINAL; i++) { for(j = 0; j < NUMTEST; j++) { (*probabilities)[i][j] = 1 / (1 + exp(1 - (*probabilities)[i][j])); } } printf("Probability computation complete!\n"); free(layer2); // array2DtoCSV(probabilities, LAYERFINAL, NUMTEST); }
int main() { // Store images, 784 rows, 10000 columns double** images = create2DDoubleArray(IMGSIZE, NUMIMGS); // Store layer 1 weights, 200 rows, 784 columns double** wL1 = create2DDoubleArray(LAYER1, IMGSIZE); // Stores layer 2 weights, 200 rows, 200 columns double** wL2 = create2DDoubleArray(LAYER2, LAYER1); // Stores layer 3 weights, 10 rows, 200 columns double** wL3 = create2DDoubleArray(LAYERFINAL, LAYER2); // Stores bias data, two sets of 200 rows, 1 column double** bias = create2DDoubleArray(LAYER1, 2); // Where the computed probabilities are stored double** probabilities = create2DDoubleArray(LAYERFINAL, NUMTEST); // Stores solutions int solutions[NUMIMGS]; if(loadData(images, wL1, wL2, wL3, bias, solutions) == -1) { return -1; } computeProb(images, wL1, wL2, wL3, bias, &probabilities); double accuracy = computeAccuracy(probabilities, solutions); printf("Hit Percentage: %3.2lf%%\n", accuracy * 100); return 0; }
int main() { void* virtual_base; int fd; void* sdram_ptr; if(setup(&fd, &virtual_base) != 0) { return(1); } sdram_ptr = virtual_base + ((unsigned long)(SDRAM_OFST + 0x00) & (unsigned long)(HW_REGS_MASK)); // Store layer 1 weights, 200 rows, 784 columns double** wL1 = create2DDoubleArray(LAYER1, IMGSIZE); // Stores layer 2 weights, 200 rows, 200 columns double** wL2 = create2DDoubleArray(LAYER2, LAYER1); // Stores layer 3 weights, 10 rows, 200 columns double** wL3 = create2DDoubleArray(LAYERFINAL, LAYER2); // Stores bias data, two sets of 200 rows, 1 column double** bias = create2DDoubleArray(LAYER1, 2); // Where the computed probabilities are stored double** probabilities = create2DDoubleArray(LAYERFINAL, NUMTEST); // Stores solutions int solutions[NUMIMGS]; printf("Loading images to SDRAM...\n"); // Loads image data into the SDRAM if(loadImagesSDRAM(sdram_ptr) == -1) { return -1; } /* printf("((double*)sdram_ptr)[177 * NUMIMGS + 0]: %lf\n", ((double*)sdram_ptr)[177 * NUMIMGS + 0]); printf("((double*)sdram_ptr)[177 * NUMIMGS + 6]: %lf\n", ((double*)sdram_ptr)[177 * NUMIMGS + 6]); */ printf("Loading weights, biases and solutions...\n"); if(loadData(wL1, wL2, wL3, bias, solutions) == -1) { return -1; } clock_t begin, end; printf("Computing Probabilities...\n"); // Computes probabilities for each image begin = clock(); computeProb(sdram_ptr, wL1, wL2, wL3, bias, &probabilities); end = clock(); printf("Computing accuracy...\n"); // Stores and computes the accuracy, 0 < accuracy < 1 double accuracy = computeAccuracy(probabilities, solutions); printf("Hit Percentage: %3.2lf%%\n", accuracy * 100); printf("Time Elapsed: %f\n", (double)(end - begin) / CLOCKS_PER_SEC); if(munmap(virtual_base, HW_REGS_SPAN) != 0) { printf("ERROR: munmap() failed...\n"); close(fd); return(1); } close(fd); return 0; }
slatkin_result slatkin_mc(int maxreps, int r_obs[]) { slatkin_result results; double theta_estimate; int i, j, k, n, repno, Ecount, Fcount; int *r_random, *r_random_to_free; double E_obs, F_obs; double *ranvec; seedMT(time(NULL)); /* Find k and n from the observed configuration */ k = 0; n = 0; while (r_obs[k+1]) { k++; n+=r_obs[k]; } /* memory management notes - the following are dynamically allocated and need to be freed: Slatkin allocates these in the ivector, vector, and matrix methods, BUT does not pass back the raw pointer to the allocated region or "head." Instead, he passes back the spot where he wants the calling code to write data (in the case of the vector call especially). So...we have to readjust the pointers *back* in order to free them...wacky, but true. r_random -- what's being returned is head + 1, so free r_random - 1 ranvec -- just free this pointer b -- have to walk K+1 rows, free each of the rows, then free b */ r_random = ivector(0, k+1); r_random_to_free = r_random - 1; r_random[0] = r_random[k+1] = 0; ranvec = vector(1, k-1); // to avoid doing this in each replicate /* fill b matrix */ //double **b = matrix(1, k, 1, n); double **b = create2DDoubleArray(k+1, n+1); for (j=1; j<=n; j++) b[1][j] = 1.0 / j; for (i=2; i<=k; i++) { b[i][i] = 1.0; for (j=i; j<n; j++) b[i][j+1] = (i * b[i-1][j] + j * b[i][j]) / (j + 1.0); } F_obs = F(k, n, r_obs); E_obs = ewens_stat(r_obs); /*printf("\nn = %d, k = %d, theta = %g, F = %g, maxrep = %d\n", n, k, theta_est(k, n), F_obs, maxrep);*/ Ecount = 0; Fcount = 0; for (repno=1; repno<=maxreps; repno++) { generate(k, n, r_random, ranvec, b); if (ewens_stat(r_random) <= E_obs) Ecount++; if (F(k, n, r_random) <= F_obs) Fcount++; } theta_estimate = theta_est(k, n); results.probability = (double) Ecount / (double) maxreps; results.theta_estimate = theta_estimate; /* free the dynamically allocated memory - the matrix b is still problematic */ free(ranvec); free(r_random_to_free); /* the allocations occur in the matrix() function, starting on line 207 The matrix first allocates a number of rows (k) as pointers to doubles. then it allocates all the columns (n) as pointers to doubles. So to unwind this, we need to walk the matrix and free each row of doubles, and then we can free the original list of double* pointers to the rows themselves. right? */ for(i=0; i < k+1; i++) { free(b[i]); } free(b); return results; }