Example #1
0
_f_log8 _IEEE_FINITE_L8( _f_real8 x)
{
	/* Union defined to work with IEEE 64-bit floating point. */
	union _ieee_double {
		_f_real8	dword;
		unsigned long long    ui[1];
	};
	union	_ieee_double x_val;

	x_val.dword		= x;

	/* if x is finite, return TRUE */
	return ((_f_log8) isfinite64(x_val.ui[0]));
}
Example #2
0
int
geomap(
        const size_t ninput, const coord_t* const input,
        const size_t nref, const coord_t* const ref,
        const bbox_t* const bbox,
        const geomap_fit_e fit_geometry,
        const surface_type_e function,
        const size_t xxorder,
        const size_t xyorder,
        const size_t yxorder,
        const size_t yyorder,
        const xterms_e xxterms,
        const xterms_e yxterms,
        const size_t maxiter,
        const double reject,
        /* Input/Output */
        size_t* const noutput,
        /* Output */
        geomap_output_t* const output, /* [MAX(ninput, nref)] */
        geomap_result_t* const result,
        stimage_error_t* const error) {

    geomap_fit_t     fit;
    bbox_t           tbbox;
    size_t           ninput_in_bbox = ninput;
    size_t           nref_in_bbox   = nref;
    coord_t*         input_in_bbox  = NULL;
    coord_t*         ref_in_bbox    = NULL;
    double*          xfit           = NULL;
    double*          yfit           = NULL;
    double*          weights        = NULL;
    double*          tweights       = NULL;
    geomap_output_t* outi           = NULL;
    surface_t        sx1, sy1, sx2, sy2;
    int              has_sx2        = 0;
    int              has_sy2        = 0;
    size_t           i              = 0;
    double           my_nan         = fmod(1.0, 0.0);
    int              status         = 1;

    assert(input);
    assert(ref);
    assert(error);

    if (ninput != nref) {
        stimage_error_set_message(
            error, "Must have the same number of input and reference coordinates.");
        goto exit;
    }

    surface_new(&sx1);
    surface_new(&sy1);
    surface_new(&sx2);
    surface_new(&sy2);

    geomap_fit_init(
            &fit, geomap_proj_none, fit_geometry, function,
            xxorder, xyorder, xxterms, yxorder, yyorder, yxterms,
            maxiter, reject);

    /* If bbox is NULL, provide a dummy one full of NaNs */
    if (bbox == NULL) {
        bbox_init(&tbbox);
    } else {
        bbox_copy(bbox, &tbbox);
    }

    /* If the bbox is all NaNs, we don't need to reduce the data, saving an
       alloc and copy */
    if (bbox == NULL ||
        (!isfinite64(tbbox.min.x) && !isfinite64(tbbox.min.y) &&
         !isfinite64(tbbox.max.x) && !isfinite64(tbbox.max.y))) {
        /* If we have no bbox, we don't need to allocate and copy */
        input_in_bbox = (coord_t*)input;
        ref_in_bbox = (coord_t*)ref;
        ninput_in_bbox = ninput;
        nref_in_bbox = nref;
    } else {
        input_in_bbox = malloc_with_error(
                ninput * sizeof(coord_t), error);
        if (input_in_bbox == NULL) goto exit;

        ref_in_bbox = malloc_with_error(
                nref * sizeof(coord_t), error);
        if (ref_in_bbox == NULL) goto exit;

        /* Reduce data to only those in the bbox */
        ninput_in_bbox = nref_in_bbox = limit_to_bbox(
                ninput, input, ref, &tbbox, input_in_bbox, ref_in_bbox);
    }

    /* Compute the mean of the reference and input coordinates */
    compute_mean_coord(nref_in_bbox, ref_in_bbox, &fit.oref);
    compute_mean_coord(ninput_in_bbox, input_in_bbox, &fit.oin);

    /* Set the reference point for the projections to undefined */
    fit.refpt.x = my_nan;
    fit.refpt.y = my_nan;

    /* Allocate some memory */
    xfit = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (xfit == NULL) goto exit;

    yfit = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (yfit == NULL) goto exit;

    /* Compute the weights */
    weights = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (weights == NULL) goto exit;

    for (i = 0; i < ninput_in_bbox; ++i) {
        weights[i] = 1.0;
    }

    /* Determine the actual max and min of the coordinates */
    determine_bbox(nref_in_bbox, ref_in_bbox, &tbbox);
    bbox_copy(&tbbox, &fit.bbox);

    if (geofit(
                &fit, &sx1, &sy1, &sx2, &sy2, &has_sx2, &has_sy2,
                ninput_in_bbox, input_in_bbox, ref_in_bbox, weights,
                error)) goto exit;

    /* Compute the fitted x and y values */
    if (geoeval(
                &sx1, &sy1, &sx2, &sy2, has_sx2, has_sy2, ninput_in_bbox,
                ref_in_bbox, xfit, yfit, error)) goto exit;

    if (geo_get_results(
                &fit, &sx1, &sy1, &sx2, &sy2, has_sx2, has_sy2, result,
                error)) goto exit;

    /* DIFF: This section is from geo_plistd */

    /* Copy the results to the output buffer */
    tweights = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (tweights == NULL) goto exit;

    for (i = 0; i < ninput_in_bbox; ++i) {
        tweights[i] = weights[i];
    }

    for (i = 0; i < fit.nreject; ++i) {
        assert(fit.rej);
        assert(fit.rej[i] < ninput_in_bbox);
        if (weights[fit.rej[i]] > 0.0) {
            tweights[fit.rej[i]] = 0.0;
        }
    }

    outi = output;
    for (i = 0; i < ninput_in_bbox; ++i, ++outi) {
        outi->ref.x = ref_in_bbox[i].x;
        outi->ref.y = ref_in_bbox[i].y;
        outi->input.x = input_in_bbox[i].x;
        outi->input.y = input_in_bbox[i].y;
        if (tweights[i] > 0.0) {
            outi->fit.x = xfit[i];
            outi->fit.y = yfit[i];
            outi->residual.x = input_in_bbox[i].x - xfit[i];
            outi->residual.y = input_in_bbox[i].y - yfit[i];
        } else {
            outi->fit.x = my_nan;
            outi->fit.y = my_nan;
            outi->residual.x = my_nan;
            outi->residual.y = my_nan;
        }
    }
    *noutput = ninput_in_bbox;

    status = 0;

 exit:

    if (input_in_bbox != input) {
        free(input_in_bbox);
    }
    if (ref_in_bbox != ref) {
        free(ref_in_bbox);
    }
    free(weights);
    free(xfit);
    free(yfit);
    free(tweights);
    surface_free(&sx1);
    surface_free(&sy1);
    surface_free(&sx2);
    surface_free(&sy2);

    return status;
}
Example #3
0
/* DIFF: was geo_fitd */
static int
geofit(
        geomap_fit_t* const fit,
        surface_t* const sx1,
        surface_t* const sy1,
        surface_t* const sx2,
        surface_t* const sy2,
        int* const has_sx2,
        int* const has_sy2,
        const size_t ncoord,
        const coord_t* const input,
        const coord_t* const ref,
        double* const weights,
        stimage_error_t* error) {

    double* residual_x = NULL;
    double* residual_y = NULL;
    int status = 1;

    assert(fit);
    assert(sx1);
    assert(sy1);
    assert(sx2);
    assert(sy2);
    assert(input);
    assert(ref);
    assert(weights);
    assert(has_sx2);
    assert(has_sy2);
    assert(error);

    *has_sx2 = 0;
    *has_sy2 = 0;

    residual_x = malloc_with_error(ncoord * sizeof(double), error);
    if (residual_x == NULL) goto exit;

    residual_y = malloc_with_error(ncoord * sizeof(double), error);
    if (residual_y == NULL) goto exit;

    switch(fit->fit_geometry) {
    case geomap_fit_rotate:
        if (geo_fit_theta(
                    fit, sx1, sy1, ncoord, input, ref, weights,
                    residual_x, residual_y, error)) goto exit;
        break;
    case geomap_fit_rscale:
        if (geo_fit_magnify(
                    fit, sx1, sy1, ncoord, input, ref, weights,
                    residual_x, residual_y, error)) goto exit;
        break;
    case geomap_fit_rxyscale:
        if (geo_fit_linear(
                    fit, sx1, sy1, ncoord, input, ref, weights,
                    residual_x, residual_y, error)) goto exit;
        break;
    default:
        if (geo_fit_xy(
                    fit, sx1, sx2, ncoord, 0, input, ref, has_sx2, weights,
                    residual_x, error)
            ||
            geo_fit_xy(
                    fit, sy1, sy2, ncoord, 1, input, ref, has_sy2, weights,
                    residual_y, error)) goto exit;
        break;
    }

    if (fit->maxiter <= 0 || !isfinite64(fit->reject)) {
        fit->nreject = 0;
    } else {
        if (geo_fit_reject(
                    fit, sx1, sy1, sx2, sy2, has_sx2, has_sy2, ncoord, input,
                    ref, weights, residual_x, residual_y, error)) goto exit;
    }

    status = 0;

 exit:
    free(residual_x);
    free(residual_y);
    return status;
}