/*============================================================================ * add_mean_maybe_scale * * Add mean to proj and check that all the elements of proj are now >= 0. * If not, scale proj down by 10%. Repeat until all elements are >= 0. *==========================================================================*/ void add_mean_maybe_scale(float *proj, float *mean, int dim) { int bad; assert(proj != NULL); assert(mean != NULL); assert(dim > 0); do { bad = 0; vecvecadd(proj, mean, dim, proj); #if USE_EV_SCALING int j; for (j=0; j < dim; j++) if (proj[j] < 0) bad = 1; if (bad) { vecvecsub(proj, mean, dim, proj); if (verbosity > 2) fprintf(err, "Scaling...\n"); vecmul(proj, .9, dim, proj); } #endif } while (bad); }
/*============================================================================ * Test routines. *==========================================================================*/ int main(int argc, char **argv) { /*======================================================================= * Vector operation tests *=====================================================================*/ { /* vecdot */ float X[3] = {1.0, 2.0, 3.0}; float Y[3] = {3.0, 2.0, 1.0}; assert(vecdot(X, Y, 3) == 10.0); } { /* vecdot */ float X[3] = {10.0}; float Y[3] = {13.0}; assert(vecdot(X, Y, 1) == 130.0); } { /* veclen */ float X[3] = {3.0, 4.0}; assert(veclen(X, 2) == 5.0); } { /* vecmul */ float X[5] = {1.0, 2.0, 3.0, 4.0, 5.0}; float Y[5] = {2.0, 4.0, 6.0, 8.0, 10.0}; vecmul(X, 2, 5, X); assert(vecveceq(X, Y, 5)); } { /* vecdiv */ float X[5] = {2.0, 4.0, 6.0, 8.0, 10.0}; float Y[5] = {1.0, 2.0, 3.0, 4.0, 5.0}; vecdiv(X, 2, 5, X); assert(vecveceq(X, Y, 5)); } { /* vecvecsub */ float X[5] = {1.0, 2.0, 3.0, 4.0, 5.0}; float Y[5] = {2.0, 4.0, 6.0, 8.0, 10.0}; float Z[5] = {-1.0, -2.0, -3.0, -4.0, -5.0}; vecvecsub(X, Y, 5, X); assert(vecveceq(X, Z, 5)); } { /* vecvecadd */ float X[5] = {1.0, 2.0, 3.0, 4.0, 5.0}; float Y[5] = {2.0, 4.0, 6.0, 8.0, 10.0}; float Z[5] = {3.0, 6.0, 9.0, 12.0, 15.0}; vecvecadd(X, Y, 5, X); assert(vecveceq(X, Z, 5)); } return 0; }
void MTLmarks::VecVecRun(std::string benchmark) { if(benchmark == "daxpy"){ mtl_result = daxpy(size, steps); } else if(benchmark == "vecvecadd"){ mtl_result = vecvecadd(size, steps); } else if(benchmark == "vecvecmult"){ mtl_result = vecvecmult(size, steps); } else if(benchmark == "dotproduct"){ mtl_result = dotproduct(size, steps); } else if(benchmark == "custom"){ mtl_result = custom(size, steps); } else{ std::cerr << "MTLmarks benchmark does not exist." << std::endl; exit(1); } }
/*============================================================================ * main * *==========================================================================*/ int main(int argc, char **argv) { int i; char *infile = NULL; char *outfile = NULL; char *line; int dim=0; float *M = NULL; float *M0 = NULL; float *mean = NULL; float *eigen_values_r = NULL; float *eigen_values_i = NULL; float *eigen_vectors_r = NULL; float *eigen_vectors_l = NULL; eigen_t *eigen = NULL; int num_models = 0; int models_size = 0; float **models = NULL; int num_xs = 0; int xs_size = 0; float *xs = NULL; float start_time=0, end_time=0, total_time=0; int in_model = 0; int in_ensem = 0; int in_input = 0; int nev = 5; in = stdin; out = stdout; err = stderr; static struct option long_options[] = { {"show", optional_argument, 0, 's'}, {"scale", required_argument, 0, 0}, {"sort", required_argument, 0, 0}, {"nev", required_argument, 0, 0}, {"mo", required_argument, 0, 0}, {"proj", optional_argument, 0, 'p'}, {"help", no_argument, 0, 'h'}, {"format", no_argument, 0, 0}, {"header", no_argument, 0, 0}, {"interp", no_argument, 0, 0}, {"add-back-mean", no_argument, 0, 0}, {0, 0, 0, 0} }; /*======================================================================== * Capture commandline arguments for write_header() *======================================================================*/ if (argc != 1) { int c=0; for (i=1; i < argc; i++) c += strlen(argv[i]) + 1; commandline = (char *)calloc(c + 1, sizeof(char)); for (i=1; i < argc; i++) { strcat(commandline, argv[i]); strcat(commandline, " "); } } /*======================================================================== * Process the command line flags *======================================================================*/ while (1) { int option_index = 0; int c = getopt_long(argc, argv, "p::i:o:v::s::hc", long_options, &option_index); if (c == -1) break; switch (c) { case 0: if (!strcmp("mo", long_options[option_index].name)) { opt_multi_out = 1; mo_prefix = optarg; } if (!strcmp("interp", long_options[option_index].name)) { opt_interp_proj = 1; } else if (!strcmp("scale", long_options[option_index].name)) { if (!strcmp("mult", optarg)) opt_scale = SCALE_MULT; else if (!strcmp("diag", optarg)) opt_scale = SCALE_DIAG; else if (!strcmp("none", optarg)) opt_scale = SCALE_NONE; else error("Unrecognized scale type."); } else if (!strcmp("sort", long_options[option_index].name)) { if (!strcmp("ev", optarg)) opt_sort = SORT_EV; else if (!strcmp("lc", optarg)) opt_sort = SORT_LC; else error("Unrecognized sort type."); } else if (!strcmp("header", long_options[option_index].name)) { write_header(err); exit(0); } else if (!strcmp("add-back-mean", long_options[option_index].name)) { opt_add_back_mean = 1; } else if (!strcmp("format", long_options[option_index].name)) { fprintf(err, "\n" "#BEGIN INPUT\n" "<PixeLens input text line 0>\n" "<PixeLens input text line 1>\n" " ...\n" "<PixeLens input text line n>\n" "#END INPUT\n" "#BEGIN ENSEM \n" "#BEGIN MODEL\n" "<point 0>\n" "<point 1>\n" " ...\n" "<point m>\n" "#END MODEL\n" " ...\n" "#END ENSEM\n" "\n" "Blank lines are allowed and any line beginning with a '#' that is\n" "not mentioned above is interpretted as a comment. It may be the case\n" "that there are no models. \n" "\n" ); exit(0); } break; case 's': opt_show = 0; if (optarg == NULL) { opt_show = SHOW_DEFAULT; } else { if (strchr(optarg, 'm')) opt_show |= SHOW_MATRIX_FLAT; if (strchr(optarg, 'M')) opt_show |= SHOW_MATRIX; if (strchr(optarg, 'e')) opt_show |= SHOW_EIGEN_VALUES; if (strchr(optarg, 'r')) opt_show |= SHOW_EIGEN_VECTORS_R; if (strchr(optarg, 'l')) opt_show |= SHOW_EIGEN_VECTORS_L; } break; case 'v': if (optarg == NULL) verbosity++; else verbosity = atoi(optarg); break; case 'i': fprintf(err, "%s\n", optarg); infile = optarg; break; case 'o': outfile = optarg; break; case 'p': fprintf(err, "%s\n", optarg); opt_proj = 1; if (optarg != NULL) nev = atoi(optarg); break; case 'h': help(); break; case '?': exit(2); } } if (opt_multi_out && !opt_proj) { fprintf(err, "--mo needs -p\n"); exit(2); } if (!opt_show && !opt_proj) opt_show = SHOW_DEFAULT; if (infile != NULL) { in = fopen(infile, "r"); if (in == NULL) { fprintf(err, "%s", strerror(errno)); exit(EXIT_FAILURE); } } if (outfile != NULL) { out = fopen(outfile, "w"); if (out == NULL) { fprintf(err, "%s", strerror(errno)); exit(EXIT_FAILURE); } } /*======================================================================== * Read commands or numerical input from the command line and update * the matrix accordingly, until there is no more input. The file we * expect to read has the following structure: * * #BEGIN INPUT * #END INPUT * #BEGIN ENSEM * #BEGIN MODEL * <point 0> * <point 1> * ... * <point dim-1> * #END MODEL * ... * #END ENSEM * * Blank lines are allowed and any line beginning with a '#' that is * not mentioned above is interpretted as a comment. It may be the case * that there are no models. * *======================================================================*/ rl_instream = in; rl_outstream = out; while (1) { line = readline(NULL); if (line == NULL) break; /* EOF */ if (strlen(line) == 0) continue; /* Blank line */ if (strstr(line, "#BEGIN INPUT") == line) { if (num_input_lines == input_size) { input_size += 5; input = (char **)realloc(input, input_size * sizeof(char *)); } input[num_input_lines++] = line; in_input = 1; line = NULL; // prevent deallocation of line by free() } else if (strstr(line, "#END INPUT") == line) { in_input = 0; num_input_lines++; if (num_input_lines-1 == input_size) { input_size += 5; input = (char **)realloc(input, input_size * sizeof(char *)); } input[num_input_lines-1] = line; line = NULL; // prevent deallocation of line by free() } else if (strstr(line, "#BEGIN LENS") == line) /*Backward compatibility*/ { int q; sscanf(line, "#BEGIN LENS dim %i omega %f lambda %f", &q, &omega, &lambda); in_ensem = 1; } else if (strstr(line, "#BEGIN ENSEM") == line) { in_ensem = 1; } else if (strstr(line, "#END LENS") == line || strstr(line, "#END ENSEM") == line) { in_ensem = 0; in_model = 0; } else if (in_ensem && strstr(line, "#BEGIN MODEL") == line) { num_xs = 0; xs = NULL; start_time = CPUTIME; if (in_model) { error("File inconsistency. " "#BEGIN MODEL found before #END MODEL.\n"); } in_model = 1; } else if (in_model && strstr(line, "#END MODEL") == line) { /*================================================================ * Now that the x's have been read, update the matrix. *==============================================================*/ if (!in_model) { error("File inconsistency. " "#END MODEL found before #BEGIN MODEL.\n"); } if (num_models == models_size) { models_size += 100; models = (float **)realloc(models, models_size * sizeof(float *)); } models[num_models++] = xs; if (verbosity > 1) { end_time = CPUTIME; total_time += end_time - start_time; fprintf(err, "[%ix%i matrix; %i models; %fs; %fs]\n", dim, dim, num_models, end_time - start_time, total_time); } in_model = 0; } else if (line[0] == '#') { continue; } else if (in_model) { /*================================================================ * Read the input values. *==============================================================*/ if (num_models == 0) { if (num_xs == xs_size) { xs_size += 100; xs = (float *)realloc(xs, xs_size * sizeof(float)); } dim = num_xs+1; } else if (num_xs > dim) { error("Model sizes differ!"); } else if (xs == NULL) { xs = (float *)malloc(dim * sizeof(float)); } xs[num_xs++] = atof(line); } else if (in_input) { num_input_lines++; if (num_input_lines-1 == input_size) { input_size += 5; input = (char **)realloc(input, input_size * sizeof(char *)); } input[num_input_lines-1] = line; line = NULL; // prevent deallocation of line by free() } free(line); } if (verbosity > 0) fprintf(err, "[%ix%i matrix; %i models]\n", dim, dim, num_models); if (!opt_multi_out) { write_header(out); write_input(out); } /*======================================================================== *------------------------------------------------------------------------ *======================================================================*/ if (dim > 0) { /*==================================================================== * Center the data points to the origin. *==================================================================*/ /* Find the average of the models. */ mean = (float *)calloc(dim, sizeof(float)); for (i=0; i < num_models; i++) vecvecadd(mean, models[i], dim, mean); vecdiv(mean, num_models, dim, mean); /* Subtract off the mean from each of the models. */ if (verbosity > 0) fprintf(err, "Normalizing models...\n"); for (i=0; i < num_models; i++) vecvecsub(models[i], mean, dim, models[i]); /*==================================================================== * Optionally apply a general multiplicative scaling. *==================================================================*/ if (opt_scale & SCALE_MULT) { if (verbosity > 0) fprintf(err, "Applying multiply scaling...\n"); scale(models[i], dim, NULL); } /*==================================================================== * Now with the normalized data, generate the inertia matrix. *==================================================================*/ if (verbosity > 0) fprintf(err, "Creating matrix...\n"); M = (float *)calloc(dim * dim, sizeof(float)); if (M == NULL) error("Can't allocate memory for matrix."); for (i=0; i < num_models; i++) update_matrix(M, models[i], dim); /*==================================================================== * Optionally apply a diagonalization scaling. *==================================================================*/ if (opt_scale & SCALE_DIAG) { M0 = (float *)malloc(dim * dim * sizeof(float)); float *t; int i, j; if (verbosity > 0) fprintf(err, "Applying diagonal scaling...\n"); for (i=0; i < dim; i++) for (j=0; j < dim; j++) M0[i*dim+j] = M[i*dim+j] / sqrt(M[i*dim+i] * M[j*dim+j]); for (i=0; i < num_models; i++) scale(models[i], dim, M); t = M; M = M0; M0 = t; } else { M0 = M; } /*==================================================================== * Compute the eigen values (and vectors) of the matrix we built. *==================================================================*/ if (verbosity>0) fprintf(err, "Calculating eigenvalues(/vectors)...\n"); eigen_values_r = (float *)malloc(dim * sizeof(float)); assert(eigen_values_r != NULL); eigen_values_i = (float *)malloc(dim * sizeof(float)); assert(eigen_values_i != NULL); if (opt_proj || (opt_show & SHOW_EIGEN_VECTORS_R)) { eigen_vectors_r = (float *)malloc(dim * dim * sizeof(float)); assert(eigen_vectors_r != NULL); } if (opt_show & SHOW_EIGEN_VECTORS_L) { eigen_vectors_l = (float *)malloc(dim * dim * sizeof(float)); assert(eigen_vectors_r != NULL); } if (get_eigen_values(M, eigen_values_r, eigen_values_i, eigen_vectors_l, eigen_vectors_r, dim, 0)) { error("Library call failed for given inputs."); } /*==================================================================== * Now place the results in a nice array which we can sort. The array * is sorted by the real part of the eigenvalues, largest to smallest. *==================================================================*/ eigen = (eigen_t *)calloc(dim, sizeof(eigen_t)); for (i=0; i < dim; i++) { if (eigen_values_r[i] == -0) eigen_values_r[i] = 0; if (eigen_values_i[i] == -0) eigen_values_i[i] = 0; eigen[i].re = eigen_values_r[i]; eigen[i].im = eigen_values_i[i]; eigen[i].dim = dim; if (eigen_vectors_l) eigen[i].lvec = &(eigen_vectors_l[i * dim]); if (eigen_vectors_r) eigen[i].rvec = &(eigen_vectors_r[i * dim]); } /*==================================================================== * Optionally add back the mean model. *==================================================================*/ if (opt_add_back_mean) { if (verbosity>0) fprintf(err, "Adding back mean...\n"); /* add back mean */ if (eigen_vectors_r) for (i=0; i < dim; i++) vecvecadd(eigen[i].rvec, mean, dim, eigen[i].rvec); if (eigen_vectors_l) for (i=0; i < dim; i++) vecvecadd(eigen[i].lvec, mean, dim, eigen[i].lvec); } /*==================================================================== * Sort. *==================================================================*/ if (!opt_sort || (opt_sort & SORT_EV)) { qsort(eigen, dim, sizeof(eigen_t), eigen_compar_rev); } else if (opt_sort & SORT_LC) { qsort(eigen, dim, sizeof(eigen_t), largest_ev_last_component); } /*==================================================================== *-------------------------------------------------------------------- *==================================================================*/ if (opt_proj) do_eigen_projections(nev, M0, models, mean, num_models, eigen, dim); } do_output(M, omega, lambda, eigen, dim); if (M == M0) { free(M); } else { free(M); free(M0); } free(eigen_values_r); free(eigen_values_i); free(eigen_vectors_l); free(eigen_vectors_r); free(eigen); free(mean); free(commandline); for (i=0; i < num_input_lines; i++) free(input[i]); free(input); for (i=0; i < num_models; i++) free(models[i]); free(models); if (in != stdin) fclose(in); if (out != stdout) fclose(out); return 0; }
void do_eigen_projections(int nev, float *M, float **models, float *mean, int num_models, eigen_t *eigen, int dim) { int i, m; struct { float *proj; float best_dot; float best_dot_index; char symbol; } proj_model[2]; assert(models != NULL); assert(mean != NULL); assert(eigen != NULL); assert(dim > 0); assert(num_models > 0); assert(0 < nev && nev <= dim); proj_model[0].proj = (float *)malloc(dim * sizeof(float)); proj_model[1].proj = (float *)malloc(dim * sizeof(float)); proj_model[0].symbol = '+'; proj_model[1].symbol = '-'; if (!opt_multi_out) fprintf(out, "#BEGIN ENSEM\n"); for (i=0; i < nev; i++) { /*================================================================ * Find the models that have the largest and smallest projections * onto the current eigenvector. *==============================================================*/ proj_model[0].best_dot = 0; proj_model[0].best_dot_index = -1; proj_model[1].best_dot = 0; proj_model[1].best_dot_index = -1; for (m=0; m < num_models; m++) { float dot = vecdot(models[m], eigen[i].rvec, dim); if (dot >= 0 && dot >= proj_model[0].best_dot) { proj_model[0].best_dot = dot; proj_model[0].best_dot_index = m; vecmul(eigen[i].rvec, dot, dim, proj_model[0].proj); } if (dot <= 0 && dot <= proj_model[1].best_dot) { proj_model[1].best_dot = dot; proj_model[1].best_dot_index = m; vecmul(eigen[i].rvec, dot, dim, proj_model[1].proj); } } if (opt_interp_proj) { if (proj_model[0].best_dot_index != -1 && proj_model[1].best_dot_index != -1) { int j; float *newp = (float *)malloc(dim * sizeof(float)); float *step = (float *)malloc(dim * sizeof(float)); #define NSTEPS 20 #define OVERSHOOT 20 vecvecsub(proj_model[1].proj, proj_model[0].proj, dim, step); vecdiv(step, NSTEPS, dim, step); for (j=0; j < NSTEPS+OVERSHOOT; j++) { vecmul(step, j, dim, newp); vecvecadd(proj_model[0].proj, newp, dim, newp); undo_scale(newp, dim, M); vecvecadd(newp, mean, dim, newp); multi_out_write_ev_model((i+1)*100 + j, 'p', 0, 0, newp, dim); } free(newp); free(step); #undef NSTEPS #undef OVERSHOOT } } else { /*================================================================ * Write out the new models *==============================================================*/ for (m=0; m < 2; m++) { if (proj_model[m].best_dot_index != -1) { float proj_len_before_scale = veclen(proj_model[m].proj, dim); undo_scale(proj_model[m].proj, dim, M); /* add back mean */ vecvecadd(proj_model[m].proj,mean, dim, proj_model[m].proj); multi_out_write_ev_model(i, proj_model[m].symbol, proj_len_before_scale, proj_model[m].best_dot, proj_model[m].proj, dim); } } } } if (!opt_multi_out) fprintf(out, "#END ENSEM\n"); free(proj_model[0].proj); free(proj_model[1].proj); }