Exemplo n.º 1
0
/*============================================================================
 *                            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);

}
Exemplo n.º 2
0
/*============================================================================
 * 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;
}
Exemplo n.º 3
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);
    }
    
}
Exemplo n.º 4
0
/*============================================================================
 *                                  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;
}
Exemplo n.º 5
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);
}