示例#1
0
文件: nonrigid.cpp 项目: smistad/cpd
NonrigidResult Nonrigid::compute_impl(const MatrixRef X, const MatrixRef Y,
                                      double sigma2) {
    assert(X.cols() == Y.cols());

    auto M = Y.rows();
    auto D = Y.cols();
    Matrix T = Y;
    size_t max_iter = this->max_iterations();
    size_t iter = 0;
    double tol = this->tolerance();
    double ntol = std::numeric_limits<double>::max();
    double L = 1.0;
    Matrix W = Matrix::Zero(M, D);
    double beta = this->beta();
    double lambda = this->lambda();
    Vector Pt1;
    Vector P1;
    Matrix PX;

    Matrix G = construct_affinity_matrix(Y, Y, beta);

    while (iter < max_iter && ntol > tol &&
           sigma2 > 10 * std::numeric_limits<double>::epsilon()) {
        double L_old = L;
        std::tie(Pt1, P1, PX, L) = calculate_probabilities(X, T, sigma2);
        L = L + lambda / 2 * (W.transpose() * G * W).trace();
        ntol = std::abs((L - L_old) / L);

        // TODO this shouldn't be cout
        std::cout << "CPD Nonrigid (FGT) : dL= " << ntol << ", iter= " << iter
                  << ", sigma2= " << sigma2 << "\n";

        auto dP = P1.asDiagonal();
        W = (dP * G + lambda * sigma2 * Matrix::Identity(M, M))
                .colPivHouseholderQr()
                .solve(PX - dP * Y);

        T = Y + G * W;
        double Np = P1.sum();
        sigma2 =
            std::abs(((X.array().pow(2) * Pt1.replicate(1, D).array()).sum() +
                      (T.array().pow(2) * P1.replicate(1, D).array()).sum() -
                      2 * (PX.transpose() * T).trace()) /
                     (Np * D));

        ++iter;
    }

    return {T};
}
示例#2
0
void separation(const char* filename, double background_integral, double* stream_integrals)
{
    int q[ap->number_streams];
    double nstars[ap->number_streams];
    int total;
    double sprob[ap->number_streams];
    double prob_s[ap->number_streams];
    double prob_b;
    double pbx;
    double psg[ap->number_streams];
    double d;
    int twoPanel;
    double** cmatrix;
    double dnormal[3];
    double dortho[3];
    double xsun[3];
    double epsilon_s[ap->number_streams];
    double epsilon_b;
    double star_coords[3];
    double starxyz[3];
    double starxyzTransform[3];
    int s_ok = 0;
    int i, j, retval;
    FILE* file;
    double reff_xr_rp3, *qw_r3_N, *r_point;

    twoPanel = 1;
    for (j = 0; j < ap->number_streams; j++)
    {
        nstars[j] = 0;
        q[j] = 0;
    }
    total = 0;
    prob_ok_init();

    printf("Integral complete.\n Beginning probability calculations...\n");
    file = fopen(filename, "w");

    if (ap->sgr_coordinates == 0)
    {
        stripe_normal(ap->wedge, dnormal);
    }
    else if (ap->sgr_coordinates == 1)
    {
        sgr_stripe_normal(ap->wedge, dnormal);
    }
    else
    {
        printf("Error: ap->sgr_coordinates not valid");
    }

    free_star_points(sp);
    free(sp);
    sp = (STAR_POINTS*)malloc(sizeof(STAR_POINTS));
    retval = read_star_points(star_points_file, sp);
    if (retval)
    {
        fprintf(stderr, "APP: error reading star points: %d\n", retval);
        exit(1);
    }
    printf("read %d stars.\n", sp->number_stars);


    cmatrix = (double**)malloc(sizeof(double*) * 3);
    for (i = 0; i < 3; i++)
        cmatrix[i] = (double*)malloc(sizeof(double) * 3);
    dortho[0] = 0.0;
    dortho[1] = 0.0;
    dortho[2] = 1.0;
    get_transform(dnormal, dortho, cmatrix);

    printf("\nTransformation matrix:\n");
    printf("\t%lf %lf %lf\n", cmatrix[0][0], cmatrix[0][1], cmatrix[0][2]);
    printf("\t%lf %lf %lf\n", cmatrix[1][0], cmatrix[1][1], cmatrix[1][2]);
    printf("\t%lf %lf %lf\n\n", cmatrix[2][0], cmatrix[2][1], cmatrix[2][2]);

    xsun[0] = -8.5;
    xsun[1] = 0.0;
    xsun[2] = 0.0;
    d = dotp(dnormal, xsun);

    printf("==============================================\n");
    printf("bint: %lf", background_integral);
    for (j = 0; j < ap->number_streams; j++)
    {
        printf(", ");
        printf("sint[%d]: %lf", j, stream_integrals[j]);
    }
    printf("\n");

    /*get stream & background weight constants*/
    double denom = 1.0;
    for (j = 0; j < ap->number_streams; j++)
    {
        denom += exp(ap->stream_weights[j]);
    }

    for (j = 0; j < ap->number_streams; j++)
    {
        epsilon_s[j] = exp(ap->stream_weights[j]) / denom;
        printf("epsilon_s[%d]: %lf\n", j, epsilon_s[j]);
    }
    epsilon_b = 1.0 / denom;
    printf("epsilon_b:    %lf\n", epsilon_b);

    r_point = (double*)malloc(sizeof(double) * ap->convolve);
    qw_r3_N = (double*)malloc(sizeof(double) * ap->convolve);

    init_constants(ap);

    printf("initialized constants\n");

    for (i = 0; i < sp->number_stars; i++)
    {
        MW_DEBUG("[%d/%d] setting star coords\n", i, sp->number_stars);
        star_coords[0] = sp->stars[i][0];
        star_coords[1] = sp->stars[i][1];
        star_coords[2] = sp->stars[i][2];
        MW_DEBUG("star_coords: %g %g %g\n", star_coords[0], star_coords[1], star_coords[2]);

        MW_DEBUG("twoPanel: %d\n", twoPanel);

        if (twoPanel == 1)
        {
            MW_DEBUG("setting probability constants\n");
            set_probability_constants(ap->convolve, star_coords[2], r_point, qw_r3_N, &reff_xr_rp3);
            MW_DEBUG("calculating probabilities\n");
            calculate_probabilities(r_point, qw_r3_N, reff_xr_rp3, star_coords, ap, &prob_b, prob_s);
            MW_DEBUG("calculated probabilities\n");

            MW_DEBUG("prob_s: %lf\n", prob_s[0]);
            MW_DEBU("prob_b: %lf\n", prob_b);

            pbx = epsilon_b * prob_b / background_integral;

            for (j = 0; j < ap->number_streams; j++)
            {
                psg[j] = epsilon_s[j] * prob_s[j] / stream_integrals[j];
            }

            MW_DEBUG("pbx: %g\n", pbx);
            MW_DEBUG("psg: %g\n", psg[0]);

            double psgSum = 0;
            for (j = 0; j < ap->number_streams; j++)
            {
                psgSum += psg[j];
            }

            for (j = 0; j < ap->number_streams; j++)
            {
                sprob[j] = psg[j] / (psgSum + pbx);
            }

            MW_DEBUG("sprob: %g\n", sprob[0]);

            for (j = 0; j < ap->number_streams; j++)
            {
                nstars[j] += sprob[j];
            }

            MW_DEBUG("nstars: %g\n", nstars[0]);
        }
        else
        {
            for (j = 0; j < ap->number_streams; j++)
            {
                sprob[j] = 1.0;
                nstars[j] += 1.0;
            }
        }


        /*determine if star with sprob should be put into stream*/
        //for(j = 0; j < ap->number_streams; j++) {
        s_ok = prob_ok(ap->number_streams, sprob);
        //  if (s_ok == 1) {
        //      s_ok += j;
        //      break;
        //  }
        //}

        MW_DEBUG("s_ok: %d\n", s_ok);

        if (s_ok >= 1)
        {
            q[s_ok-1]++;
        }

        lbr2xyz(star_coords, starxyz);
        transform_point(starxyz, cmatrix, xsun, starxyzTransform);

        fprintf(file, "%d %lf %lf %lf\n", s_ok, starxyzTransform[0], starxyzTransform[1], starxyzTransform[2]);
        //free(starxyz);
        //free(starxyzTransform);

        total += 1;

        if ( (total % 10000) == 0 )
            printf("%d\n", total);
    }

    printf("%d total stars\n", total);
    for (j = 0; j < ap->number_streams; j++)
    {
        printf("%lf in stream[%d] (%lf%%)\n", nstars[j], j, (nstars[j] / total * 100));
    }

    for (j = 0; j < ap->number_streams; j++)
    {
        printf("%d stars separated into stream\n", q[j]);
    }
    fclose(file);
    printf("Output written to: %s\n", filename);
    free(r_point);
    free(qw_r3_N);
    free_constants(ap);
}