Exemplo n.º 1
0
/* *************************************************************** */
void bench_blas_level_3_double(int rows)
{
    struct timeval tstart;
    struct timeval tend;
    double **A, **B, **C, *x, *y;

    x = G_alloc_vector(rows);
    y = G_alloc_vector(rows);

    A = G_alloc_matrix(rows, rows);
    B = G_alloc_matrix(rows, rows);
    C = G_alloc_matrix(rows, rows);

    fill_d_vector_range_1(x, 1, rows);
    fill_d_vector_range_1(y, 1, rows);

    fill_d_vector_range_1(A[0], 1, rows*rows);
    fill_d_vector_range_1(B[0], 1, rows*rows);


    gettimeofday(&tstart, NULL);
#pragma omp parallel default(shared)
{
    G_math_d_aA_B(A, B, 4.0 , C, rows , rows);
}
    gettimeofday(&tend, NULL);
    printf("Computation time G_math_d_aA_B: %g\n", compute_time_difference(tstart, tend));
    gettimeofday(&tstart, NULL);
#pragma omp parallel default(shared)
{
    G_math_d_AB(A, B, C, rows , rows , rows);
}
    gettimeofday(&tend, NULL);
    printf("Computation time G_math_d_AB: %g\n", compute_time_difference(tstart, tend));


    if(x)
      G_free_vector(x);
    if(y)
      G_free_vector(y);

    if(A)
      G_free_matrix(A);
    if(B)
      G_free_matrix(B);
    if(C)
      G_free_matrix(C);

    return;
}
Exemplo n.º 2
0
int
transform(int *datafds, int *outfds, int rows, int cols,
	  double **eigmat, int bands, CELL *mins, CELL *maxs)
{
    int i, j, k, l;
    double *sum;
    CELL **rowbufs;

    sum = G_alloc_vector(bands);
    rowbufs = (CELL**)G_calloc(bands, sizeof(CELL*));


    /* allocate row buffers for each band */
    for (i = 0; i < bands; i++)
	if ((rowbufs[i] = Rast_allocate_c_buf()) == NULL)
	    G_fatal_error(_("Unable to allocate cell buffers."));

    for (i = 0; i < rows; i++) {
	/* get one row of data */
	for (j = 0; j < bands; j++)
	    Rast_get_c_row(datafds[j], rowbufs[j], i);

	/* transform each cell in the row */
	for (l = 0; l < cols; l++) {
	    for (j = 0; j < bands; j++) {
		sum[j] = 0.0;
		for (k = 0; k < bands; k++) {
		    sum[j] += eigmat[j][k] * (double)rowbufs[k][l];
		}
	    }
	    for (j = 0; j < bands; j++) {
		rowbufs[j][l] = (CELL) (sum[j] + 0.5);
		if (rowbufs[j][l] > maxs[j])
		    maxs[j] = rowbufs[j][l];
		if (rowbufs[j][l] < mins[j])
		    mins[j] = rowbufs[j][l];
	    }
	}

	/* output the row of data */
	for (j = 0; j < bands; j++)
	    Rast_put_row(outfds[j], rowbufs[j], CELL_TYPE);
    }
    for (i = 0; i < bands; i++)
	G_free(rowbufs[i]);

    G_free(rowbufs);
    G_free_vector(sum);

    G_message(_("Transform completed.\n"));

    return 0;
}
Exemplo n.º 3
0
/*!
 * \brief LU decomposition
 *
 * \param a double **
 * \param n int
 * \param indx int *
 * \param d double *
 *
 * \return 0 on singular matrix, 1 on success
 */
int G_ludcmp(double **a, int n, int *indx, double *d)
{
    int i, imax = 0, j, k;
    double big, dum, sum, temp;
    double *vv;
    int is_singular = FALSE;

    vv = G_alloc_vector(n);
    *d = 1.0;
/* this pragma works, but doesn't really help speed things up */
/* #pragma omp parallel for private(i, j, big, temp) shared(n, a, vv, is_singular) */
    for (i = 0; i < n; i++) {
	big = 0.0;
	for (j = 0; j < n; j++)
	    if ((temp = fabs(a[i][j])) > big)
		big = temp;

	if (big == 0.0) {
	    is_singular = TRUE;
	    break;
	}

	vv[i] = 1.0 / big;
    }
    if (is_singular) {
	*d = 0.0;
	return 0;	/* Singular matrix  */
    }

    for (j = 0; j < n; j++) {
	for (i = 0; i < j; i++) {
	    sum = a[i][j];
	    for (k = 0; k < i; k++)
		sum -= a[i][k] * a[k][j];
	    a[i][j] = sum;
	}

	big = 0.0;
/* not very efficent, but this pragma helps speed things up a bit */
#pragma omp parallel for private(i, k, sum, dum) shared(j, n, a, vv, big, imax)
	for (i = j; i < n; i++) {
	    sum = a[i][j];
	    for (k = 0; k < j; k++)
		sum -= a[i][k] * a[k][j];
	    a[i][j] = sum;
	    if ((dum = vv[i] * fabs(sum)) >= big) {
		big = dum;
		imax = i;
	    }
	}
	if (j != imax) {
	    for (k = 0; k < n; k++) {
		dum = a[imax][k];
		a[imax][k] = a[j][k];
		a[j][k] = dum;
	    }
	    *d = -(*d);
	    vv[imax] = vv[j];
	}
	indx[j] = imax;
	if (a[j][j] == 0.0)
	    a[j][j] = TINY;
	if (j != n) {
	    dum = 1.0 / (a[j][j]);
	    for (i = j + 1; i < n; i++)
		a[i][j] *= dum;
	}
    }
    G_free_vector(vv);

    return 1;
}
Exemplo n.º 4
0
/*-------------------------------------------------------------------------------------------*/
int cross_correlation(struct Map_info *Map, double passWE, double passNS)
    /*
       Map: Vector map from which cross-crorrelation will take values
       passWE: spline step in West-East direction
       passNS: spline step in North-South direction

       RETURN:
       TRUE on success
       FALSE on failure
     */
{
    int bilin = TRUE;		/*booleans */
    int nsplx, nsply, nparam_spl, ndata;
    double *mean, *rms, *stdev;

    /* double lambda[PARAM_LAMBDA] = { 0.0001, 0.001, 0.01, 0.1, 1.0, 10.0 }; */	/* Fixed values (by the moment) */
    double lambda[PARAM_LAMBDA] = { 0.0001, 0.001, 0.005, 0.01, 0.02, 0.05 };	/* Fixed values (by the moment) */
    /* a more exhaustive search:
    #define PARAM_LAMBDA 11
    double lambda[PARAM_LAMBDA] = { 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 5.0, 10.0 }; */

    double *TN, *Q, *parVect;	/* Interpolation and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    struct Point *observ;
    struct Stats stat_vect;

    /*struct line_pnts *points; */
    /*struct line_cats *Cats; */
    struct Cell_head region;

    G_get_window(&region);

    extern int bspline_field;
    extern char *bspline_column;
    dbCatValArray cvarr;

    G_debug(5,
	    "CrossCorrelation: Some tests using different lambda_i values will be done");

    ndata = Vect_get_num_lines(Map);

    if (ndata > NDATA_MAX)
	G_warning(_("%d are too many points. "
		    "The cross validation would take too much time."), ndata);

    /*points = Vect_new_line_struct (); */
    /*Cats = Vect_new_cats_struct (); */

    /* Current region is read and points recorded into observ */
    observ = P_Read_Vector_Region_Map(Map, &region, &ndata, 1024, 1);
    G_debug(5, "CrossCorrelation: %d points read in region. ", ndata);
    G_verbose_message(_("%d points read in region"),
		      ndata);

    if (ndata > 50)
	G_warning(_("Maybe it takes too long. "
		    "It will depend on how many points you are considering."));
    else
	G_debug(5, "CrossCorrelation: It shouldn't take too long.");

    if (ndata > 0) {		/* If at least one point is in the region */
	int i, j, lbd;		/* lbd: lambda index */
	int BW;	
	double mean_reg, *obs_mean;

	int nrec, ctype = 0, verbosity;
	struct field_info *Fi;
	dbDriver *driver_cats;

	mean = G_alloc_vector(PARAM_LAMBDA);	/* Alloc as much mean, rms and stdev values as the total */
	rms = G_alloc_vector(PARAM_LAMBDA);	/* number of parameter used used for cross validation */
	stdev = G_alloc_vector(PARAM_LAMBDA);

	verbosity = G_verbose(); /* store for later reset */

	/* Working with attributes */
	if (bspline_field > 0) {
	    db_CatValArray_init(&cvarr);

	    Fi = Vect_get_field(Map, bspline_field);
	    if (Fi == NULL)
	      G_fatal_error(_("Database connection not defined for layer %d"),
			    bspline_field);

	    driver_cats =
		db_start_driver_open_database(Fi->driver, Fi->database);
	    G_debug(1, _("CrossCorrelation: driver=%s db=%s"), Fi->driver,
		    Fi->database);

	    if (driver_cats == NULL)
		G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			      Fi->database, Fi->driver);

	    nrec =
		db_select_CatValArray(driver_cats, Fi->table, Fi->key,
				      bspline_column, NULL, &cvarr);
	    G_debug(3, "nrec = %d", nrec);

	    ctype = cvarr.ctype;
	    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
		G_fatal_error(_("Column type not supported"));

	    if (nrec < 0)
		G_fatal_error(_("No records selected from table <%s> "),
			      Fi->table);

	    G_debug(1, "%d records selected from table",
		    nrec);

	    db_close_database_shutdown_driver(driver_cats);
	}

	/* Setting number of splines as a function of WE and SN spline steps */
	nsplx = ceil((region.east - region.west) / passWE);
	nsply = ceil((region.north - region.south) / passNS);
	nparam_spl = nsplx * nsply;	/* Total number of splines */

	if (nparam_spl > 22900)
	    G_fatal_error(_("Too many splines (%d x %d). "
			    "Consider changing spline steps \"ew_step=\" \"ns_step=\"."),
			  nsplx, nsply);

	BW = P_get_BandWidth(bilin, nsply);
	/**/
	/*Least Squares system */
	N = G_alloc_matrix(nparam_spl, BW);	/* Normal matrix */
	TN = G_alloc_vector(nparam_spl);	/* vector */
	parVect = G_alloc_vector(nparam_spl);	/* Parameters vector */
	obsVect = G_alloc_matrix(ndata, 3);	/* Observation vector */
	Q = G_alloc_vector(ndata);		/* "a priori" var-cov matrix */

	obs_mean = G_alloc_vector(ndata);
	stat_vect = alloc_Stats(ndata);

	for (lbd = 0; lbd < PARAM_LAMBDA; lbd++) {	/* For each lambda value */

	    G_message(_("Beginning cross validation with "
		        "lambda_i=%.4f ... (%d of %d)"), lambda[lbd],
		      lbd+1, PARAM_LAMBDA);

	    /*
	       How the cross correlation algorithm is done:
	       For each cycle, only the first ndata-1 "observ" elements are considered for the 
	       interpolation. Within every interpolation mean is calculated to lowering edge 
	       errors. The point left out will be used for an estimation. The error between the 
	       estimation and the observation is recorded for further statistics.
	       At the end of the cycle, the last point, that is, the ndata-1 index, and the point 
	       with j index are swapped.
	     */
	    for (j = 0; j < ndata; j++) {	/* Cross Correlation will use all ndata points */
		double out_x, out_y, out_z;	/* This point is left out */

		for (i = 0; i < ndata; i++) {	/* Each time, only the first ndata-1 points */
		    double dval;		/* are considered in the interpolation */

		    /* Setting obsVect vector & Q matrix */
		    Q[i] = 1;	/* Q=I */
		    obsVect[i][0] = observ[i].coordX;
		    obsVect[i][1] = observ[i].coordY;

		    if (bspline_field > 0) {
			int cat, ival, ret;

			/*type = Vect_read_line (Map, points, Cats, observ[i].lineID); */
			/*if ( !(type & GV_POINTS ) ) continue; */

			/*Vect_cat_get ( Cats, bspline_field, &cat ); */
			cat = observ[i].cat;

			if (cat < 0)
			    continue;

			if (ctype == DB_C_TYPE_INT) {
			    ret =
				db_CatValArray_get_value_int(&cvarr, cat,
							     &ival);
			    obsVect[i][2] = ival;
			    obs_mean[i] = ival;
			}
			else {	/* DB_C_TYPE_DOUBLE */
			    ret =
				db_CatValArray_get_value_double(&cvarr, cat,
								&dval);
			    obsVect[i][2] = dval;
			    obs_mean[i] = dval;
			}
			if (ret != DB_OK) {
			    G_warning(_("No record for point (cat = %d)"),
				      cat);
			    continue;
			}
		    }
		    else {
			obsVect[i][2] = observ[i].coordZ;
			obs_mean[i] = observ[i].coordZ;
		    }
		}		/* i index */

		/* Mean calculation for every point less the last one */
		mean_reg = calc_mean(obs_mean, ndata - 1);

		for (i = 0; i < ndata; i++)
		    obsVect[i][2] -= mean_reg;

		/* This is left out */
		out_x = observ[ndata - 1].coordX;
		out_y = observ[ndata - 1].coordY;
		out_z = obsVect[ndata - 1][2];

		if (bilin) {	/* Bilinear interpolation */
		    normalDefBilin(N, TN, Q, obsVect, passWE, passNS, nsplx,
				   nsply, region.west, region.south,
				   ndata - 1, nparam_spl, BW);
		    nCorrectGrad(N, lambda[lbd], nsplx, nsply, passWE,
				 passNS);
		}
		else {		/* Bicubic interpolation */
		    normalDefBicubic(N, TN, Q, obsVect, passWE, passNS, nsplx,
				     nsply, region.west, region.south,
				     ndata - 1, nparam_spl, BW);
		    nCorrectGrad(N, lambda[lbd], nsplx, nsply, passWE,
				 passNS);
		}

		/* 
		   if (bilin) interpolation (&interp, P_BILINEAR);
		   else interpolation (&interp, P_BICUBIC);
		 */
		G_set_verbose(G_verbose_min());
		G_math_solver_cholesky_sband(N, parVect, TN, nparam_spl, BW);
		G_set_verbose(verbosity);

		/* Estimation of j-point */
		if (bilin)
		    stat_vect.estima[j] =
			dataInterpolateBilin(out_x, out_y, passWE, passNS,
					     nsplx, nsply, region.west,
					     region.south, parVect);

		else
		    stat_vect.estima[j] =
			dataInterpolateBilin(out_x, out_y, passWE, passNS,
					     nsplx, nsply, region.west,
					     region.south, parVect);

		/* Difference between estimated and observated i-point */
		stat_vect.error[j] = out_z - stat_vect.estima[j];
		G_debug(1, "CrossCorrelation: stat_vect.error[%d]  =  %lf", j,
			stat_vect.error[j]);

		/* Once the last value is left out, it is swapped with j-value */
		observ = swap(observ, j, ndata - 1);

		G_percent(j, ndata, 2);
	    }

	    mean[lbd] = calc_mean(stat_vect.error, stat_vect.n_points);
	    rms[lbd] =
		calc_root_mean_square(stat_vect.error, stat_vect.n_points);
	    stdev[lbd] =
		calc_standard_deviation(stat_vect.error, stat_vect.n_points);

	    G_message(_("Mean = %.5lf"), mean[lbd]);
	    G_message(_("Root Mean Square (RMS) = %.5lf"),
		      rms[lbd]);
	    G_message("---");
	}			/* ENDFOR each lambda value */

	G_free_matrix(N);
	G_free_vector(TN);
	G_free_vector(Q);
	G_free_matrix(obsVect);
	G_free_vector(parVect);
#ifdef nodef
	/*TODO: if the minimum lambda is wanted, the function declaration must be changed */
	/* At this moment, consider rms only */
	rms_min = find_minimum(rms, &lbd_min);
	stdev_min = find_minimum(stdev, &lbd_min);

	/* Writing some output */
	G_message(_("Different number of splines and lambda_i values have "
		    "been taken for the cross correlation"));
	G_message(_("The minimum value for the test (rms=%lf) was "
		    "obtained with: lambda_i = %.3f"),
		  rms_min,
		  lambda[lbd_min]);

	*lambda_min = lambda[lbd_min];
#endif

	G_message(_("Table of results:"));
	fprintf(stdout, _("    lambda |       mean |        rms |\n"));
	for (lbd = 0; lbd < PARAM_LAMBDA; lbd++) {
	    fprintf(stdout, " %9.5f | %10.4f | %10.4f |\n", lambda[lbd],
		    mean[lbd], rms[lbd]);
	}
	
	G_free_vector(mean);
	G_free_vector(rms);
    }				/* ENDIF (ndata > 0) */
    else
	G_warning(_("No point lies into the current region"));

    G_free(observ);
    return TRUE;
}
Exemplo n.º 5
0
int main(int argc, char *argv[])
{
    int m1;
    struct FPRange range;
    DCELL cellmin, cellmax;
    FCELL *cellrow, fcellmin;

    struct GModule *module;
    struct
    {
	struct Option *input, *elev, *slope, *aspect, *pcurv, *tcurv, *mcurv,
	    *smooth, *maskmap, *zmult, *fi, *segmax, *npmin, *res_ew, *res_ns,
	    *overlap, *theta, *scalex;
    } parm;
    struct
    {
	struct Flag *deriv, *cprght;
    } flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("resample"));
    module->description =
	_("Reinterpolates and optionally computes topographic analysis from "
	  "input raster map to a new raster map (possibly with "
	  "different resolution) using regularized spline with "
	  "tension and smoothing.");

    parm.input = G_define_standard_option(G_OPT_R_INPUT);

    parm.res_ew = G_define_option();
    parm.res_ew->key = "ew_res";
    parm.res_ew->type = TYPE_DOUBLE;
    parm.res_ew->required = YES;
    parm.res_ew->description = _("Desired east-west resolution");

    parm.res_ns = G_define_option();
    parm.res_ns->key = "ns_res";
    parm.res_ns->type = TYPE_DOUBLE;
    parm.res_ns->required = YES;
    parm.res_ns->description = _("Desired north-south resolution");

    parm.elev = G_define_option();
    parm.elev->key = "elev";
    parm.elev->type = TYPE_STRING;
    parm.elev->required = NO;
    parm.elev->gisprompt = "new,cell,raster";
    parm.elev->description = _("Output z-file (elevation) map");
    parm.elev->guisection = _("Output");

    parm.slope = G_define_option();
    parm.slope->key = "slope";
    parm.slope->type = TYPE_STRING;
    parm.slope->required = NO;
    parm.slope->gisprompt = "new,cell,raster";
    parm.slope->description = _("Output slope map (or fx)");
    parm.slope->guisection = _("Output");

    parm.aspect = G_define_option();
    parm.aspect->key = "aspect";
    parm.aspect->type = TYPE_STRING;
    parm.aspect->required = NO;
    parm.aspect->gisprompt = "new,cell,raster";
    parm.aspect->description = _("Output aspect map (or fy)");
    parm.aspect->guisection = _("Output");

    parm.pcurv = G_define_option();
    parm.pcurv->key = "pcurv";
    parm.pcurv->type = TYPE_STRING;
    parm.pcurv->required = NO;
    parm.pcurv->gisprompt = "new,cell,raster";
    parm.pcurv->description = _("Output profile curvature map (or fxx)");
    parm.pcurv->guisection = _("Output");

    parm.tcurv = G_define_option();
    parm.tcurv->key = "tcurv";
    parm.tcurv->type = TYPE_STRING;
    parm.tcurv->required = NO;
    parm.tcurv->gisprompt = "new,cell,raster";
    parm.tcurv->description = _("Output tangential curvature map (or fyy)");
    parm.tcurv->guisection = _("Output");

    parm.mcurv = G_define_option();
    parm.mcurv->key = "mcurv";
    parm.mcurv->type = TYPE_STRING;
    parm.mcurv->required = NO;
    parm.mcurv->gisprompt = "new,cell,raster";
    parm.mcurv->description = _("Output mean curvature map (or fxy)");
    parm.mcurv->guisection = _("Output");

    parm.smooth = G_define_option();
    parm.smooth->key = "smooth";
    parm.smooth->type = TYPE_STRING;
    parm.smooth->required = NO;
    parm.smooth->gisprompt = "old,cell,raster";
    parm.smooth->description = _("Name of raster map containing smoothing");
    parm.smooth->guisection = _("Settings");

    parm.maskmap = G_define_option();
    parm.maskmap->key = "maskmap";
    parm.maskmap->type = TYPE_STRING;
    parm.maskmap->required = NO;
    parm.maskmap->gisprompt = "old,cell,raster";
    parm.maskmap->description = _("Name of raster map to be used as mask");
    parm.maskmap->guisection = _("Settings");

    parm.overlap = G_define_option();
    parm.overlap->key = "overlap";
    parm.overlap->type = TYPE_INTEGER;
    parm.overlap->required = NO;
    parm.overlap->answer = OVERLAP;
    parm.overlap->description = _("Rows/columns overlap for segmentation");
    parm.overlap->guisection = _("Settings");

    parm.zmult = G_define_option();
    parm.zmult->key = "zmult";
    parm.zmult->type = TYPE_DOUBLE;
    parm.zmult->answer = ZMULT;
    parm.zmult->required = NO;
    parm.zmult->description = _("Multiplier for z-values");
    parm.zmult->guisection = _("Settings");

    parm.fi = G_define_option();
    parm.fi->key = "tension";
    parm.fi->type = TYPE_DOUBLE;
    parm.fi->answer = TENSION;
    parm.fi->required = NO;
    parm.fi->description = _("Spline tension value");
    parm.fi->guisection = _("Settings");

    parm.theta = G_define_option();
    parm.theta->key = "theta";
    parm.theta->type = TYPE_DOUBLE;
    parm.theta->required = NO;
    parm.theta->description = _("Anisotropy angle (in degrees)");
    parm.theta->guisection = _("Anisotropy");

    parm.scalex = G_define_option();
    parm.scalex->key = "scalex";
    parm.scalex->type = TYPE_DOUBLE;
    parm.scalex->required = NO;
    parm.scalex->description = _("Anisotropy scaling factor");
    parm.scalex->guisection = _("Anisotropy");

    flag.cprght = G_define_flag();
    flag.cprght->key = 't';
    flag.cprght->description = _("Use dnorm independent tension");

    flag.deriv = G_define_flag();
    flag.deriv->key = 'd';
    flag.deriv->description =
	_("Output partial derivatives instead of topographic parameters");
    flag.deriv->guisection = _("Output");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    G_get_set_window(&winhd);

    inp_ew_res = winhd.ew_res;
    inp_ns_res = winhd.ns_res;
    inp_cols = winhd.cols;
    inp_rows = winhd.rows;
    inp_x_orig = winhd.west;
    inp_y_orig = winhd.south;

    input = parm.input->answer;
    smooth = parm.smooth->answer;
    maskmap = parm.maskmap->answer;

    elev = parm.elev->answer;
    slope = parm.slope->answer;
    aspect = parm.aspect->answer;
    pcurv = parm.pcurv->answer;
    tcurv = parm.tcurv->answer;
    mcurv = parm.mcurv->answer;

    cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL));
    cond1 = ((slope != NULL) || (aspect != NULL) || cond2);
    deriv = flag.deriv->answer;
    dtens = flag.cprght->answer;

    ertre = 0.1;

    if (!G_scan_resolution(parm.res_ew->answer, &ew_res, winhd.proj))
	G_fatal_error(_("Unable to read ew_res value"));

    if (!G_scan_resolution(parm.res_ns->answer, &ns_res, winhd.proj))
	G_fatal_error(_("Unable to read ns_res value"));

    if (sscanf(parm.fi->answer, "%lf", &fi) != 1)
	G_fatal_error(_("Invalid value for tension"));

    if (sscanf(parm.zmult->answer, "%lf", &zmult) != 1)
	G_fatal_error(_("Invalid value for zmult"));

    if (sscanf(parm.overlap->answer, "%d", &overlap) != 1)
	G_fatal_error(_("Invalid value for overlap"));

    if (parm.theta->answer) {
	if (sscanf(parm.theta->answer, "%lf", &theta) != 1)
	    G_fatal_error(_("Invalid value for theta"));
    }
    if (parm.scalex->answer) {
	if (sscanf(parm.scalex->answer, "%lf", &scalex) != 1)
	    G_fatal_error(_("Invalid value for scalex"));
	if (!parm.theta->answer)
	    G_fatal_error(_("When using anisotropy both theta and scalex must be specified"));
    }

    /*
     * G_set_embedded_null_value_mode(1);
     */
    outhd.ew_res = ew_res;
    outhd.ns_res = ns_res;
    outhd.east = winhd.east;
    outhd.west = winhd.west;
    outhd.north = winhd.north;
    outhd.south = winhd.south;
    outhd.proj = winhd.proj;
    outhd.zone = winhd.zone;
    G_adjust_Cell_head(&outhd, 0, 0);
    ew_res = outhd.ew_res;
    ns_res = outhd.ns_res;
    nsizc = outhd.cols;
    nsizr = outhd.rows;
    disk = nsizc * nsizr * sizeof(int);

    az = G_alloc_vector(nsizc + 1);

    if (cond1) {
	adx = G_alloc_vector(nsizc + 1);
	ady = G_alloc_vector(nsizc + 1);
	if (cond2) {
	    adxx = G_alloc_vector(nsizc + 1);
	    adyy = G_alloc_vector(nsizc + 1);
	    adxy = G_alloc_vector(nsizc + 1);
	}
    }

    if (smooth != NULL) {

	fdsmooth = Rast_open_old(smooth, "");

	Rast_get_cellhd(smooth, "", &smhd);

	if ((winhd.ew_res != smhd.ew_res) || (winhd.ns_res != smhd.ns_res))
	    G_fatal_error(_("Map <%s> is the wrong resolution"), smooth);

	if (Rast_read_fp_range(smooth, "", &range) >= 0)
	    Rast_get_fp_range_min_max(&range, &cellmin, &cellmax);

	fcellmin = (float)cellmin;

	if (Rast_is_f_null_value(&fcellmin) || fcellmin < 0.0)
	    G_fatal_error(_("Smoothing values can not be negative or NULL"));
    }

    Rast_get_cellhd(input, "", &inphd);

    if ((winhd.ew_res != inphd.ew_res) || (winhd.ns_res != inphd.ns_res))
	G_fatal_error(_("Input map resolution differs from current region resolution!"));

    fdinp = Rast_open_old(input, "");

    sdisk = 0;
    if (elev != NULL)
	sdisk += disk;
    if (slope != NULL)
	sdisk += disk;
    if (aspect != NULL)
	sdisk += disk;
    if (pcurv != NULL)
	sdisk += disk;
    if (tcurv != NULL)
	sdisk += disk;
    if (mcurv != NULL)
	sdisk += disk;

    G_message(_("Processing all selected output files will require"));
    if (sdisk > 1024) {
	if (sdisk > 1024 * 1024) {
	    if (sdisk > 1024 * 1024 * 1024) {
		G_message(_("%.2f GB of disk space for temp files."), sdisk / (1024. * 1024. * 1024.));
	    }
	    else
		G_message(_("%.2f MB of disk space for temp files."), sdisk / (1024. * 1024.));
	}
	else
	    G_message(_("%.2f KB of disk space for temp files."), sdisk / 1024.);
    }
    else
	G_message(_("%d bytes of disk space for temp files."), sdisk);


    fstar2 = fi * fi / 4.;
    tfsta2 = fstar2 + fstar2;
    deltx = winhd.east - winhd.west;
    delty = winhd.north - winhd.south;
    xmin = winhd.west;
    xmax = winhd.east;
    ymin = winhd.south;
    ymax = winhd.north;
    if (smooth != NULL)
	smc = -9999;
    else
	smc = 0.01;


    if (Rast_read_fp_range(input, "", &range) >= 0) {
	Rast_get_fp_range_min_max(&range, &cellmin, &cellmax);
    }
    else {
	cellrow = Rast_allocate_f_buf();
	for (m1 = 0; m1 < inp_rows; m1++) {
	    Rast_get_f_row(fdinp, cellrow, m1);
	    Rast_row_update_fp_range(cellrow, m1, &range, FCELL_TYPE);
	}
	Rast_get_fp_range_min_max(&range, &cellmin, &cellmax);
    }

    fcellmin = (float)cellmin;
    if (Rast_is_f_null_value(&fcellmin))
	G_fatal_error(_("Maximum value of a raster map is NULL."));

    zmin = (double)cellmin *zmult;
    zmax = (double)cellmax *zmult;

    G_debug(1, "zmin=%f, zmax=%f", zmin, zmax);

    if (fd4 != NULL)
	fprintf(fd4, "deltx,delty %f %f \n", deltx, delty);
    create_temp_files();

    IL_init_params_2d(&params, NULL, 1, 1, zmult, KMIN, KMAX, maskmap,
		      outhd.rows, outhd.cols, az, adx, ady, adxx, adyy, adxy,
		      fi, MAXPOINTS, SCIK1, SCIK2, SCIK3, smc, elev, slope,
		      aspect, pcurv, tcurv, mcurv, dmin, inp_x_orig,
		      inp_y_orig, deriv, theta, scalex, Tmp_fd_z, Tmp_fd_dx,
		      Tmp_fd_dy, Tmp_fd_xx, Tmp_fd_yy, Tmp_fd_xy, NULL, NULL,
		      0, NULL);

    /*  In the above line, the penultimate argument is supposed to be a 
     * deviations file pointer.  None is obvious, so I used NULL. */
    /*  The 3rd and 4th argument are int-s, elatt and smatt (from the function
     * definition.  The value 1 seemed like a good placeholder...  or not. */

    IL_init_func_2d(&params, IL_grid_calc_2d, IL_matrix_create,
		    IL_check_at_points_2d,
		    IL_secpar_loop_2d, IL_crst, IL_crstg, IL_write_temp_2d);

    G_message(_("Temporarily changing the region to desired resolution ..."));
    Rast_set_window(&outhd);

    bitmask = IL_create_bitmask(&params);
    /* change region to initial region */
    G_message(_("Changing back to the original region ..."));
    Rast_set_window(&winhd);

    ertot = 0.;
    cursegm = 0;
    G_message(_("Percent complete: "));


    NPOINT =
	IL_resample_interp_segments_2d(&params, bitmask, zmin, zmax, &zminac,
				       &zmaxac, &gmin, &gmax, &c1min, &c1max,
				       &c2min, &c2max, &ertot, nsizc, &dnorm,
				       overlap, inp_rows, inp_cols, fdsmooth,
				       fdinp, ns_res, ew_res, inp_ns_res,
				       inp_ew_res, dtens);


    G_message(_("dnorm in mainc after grid before out1= %f"), dnorm);

    if (NPOINT < 0) {
	clean();
	G_fatal_error(_("split_and_interpolate() failed"));
    }

    if (fd4 != NULL)
	fprintf(fd4, "max. error found = %f \n", ertot);
    G_free_vector(az);
    if (cond1) {
	G_free_vector(adx);
	G_free_vector(ady);
	if (cond2) {
	    G_free_vector(adxx);
	    G_free_vector(adyy);
	    G_free_vector(adxy);
	}
    }
    G_message(_("dnorm in mainc after grid before out2= %f"), dnorm);

    if (IL_resample_output_2d(&params, zmin, zmax, zminac, zmaxac, c1min,
			      c1max, c2min, c2max, gmin, gmax, ertot, input,
			      &dnorm, &outhd, &winhd, smooth, NPOINT) < 0) {
	clean();
	G_fatal_error(_("Unable to write raster maps -- try increasing cell size"));
    }

    G_free(zero_array_cell);
    clean();
    if (fd4)
	fclose(fd4);
    Rast_close(fdinp);
    if (smooth != NULL)
	Rast_close(fdsmooth);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Exemplo n.º 6
0
static int calccoef(struct Control_Points_3D *cp, double OR[], int ndims)
{
    double **src_mat = NULL;
    double **src_mat_T = NULL;
    double **dest_mat = NULL;
    double **dest_mat_T = NULL;
    double **src_dest_mat = NULL;
    double *S_vec = NULL;
    double **R_mat = NULL;
    double **R_mat_T = NULL;
    double **mat_mn1 = NULL;
    double **mat_mn2 = NULL;
    double **mat_nm1 = NULL;
    double **mat_nm2 = NULL;
    double **mat_nn1 = NULL;
    double **E_mat = NULL;
    double **P_mat = NULL;
    double **Q_mat = NULL;
    double *D_vec = NULL;
    double *one_vec = NULL;
    double trace1 = 0.0;
    double trace2 = 0.0;
    int numactive;		/* NUMBER OF ACTIVE CONTROL POINTS */
    int m, n, i, j;
    int status;

    /* CALCULATE THE NUMBER OF VALID CONTROL POINTS */

    for (i = numactive = 0; i < cp->count; i++) {
	if (cp->status[i] > 0)
	    numactive++;
    }
    m = numactive;
    n = ndims;

    src_mat = G_alloc_matrix(m, n);
    dest_mat = G_alloc_matrix(m, n);

    for (i = numactive = 0; i < cp->count; i++) {
	if (cp->status[i] > 0) {
	    src_mat[numactive][0] = cp->e1[i];
	    src_mat[numactive][1] = cp->n1[i];
	    src_mat[numactive][2] = cp->z1[i];

	    dest_mat[numactive][0] = cp->e2[i];
	    dest_mat[numactive][1] = cp->n2[i];
	    dest_mat[numactive][2] = cp->z2[i];

	    numactive++;
	}
    }

    D_vec = G_alloc_vector(ndims);

    src_mat_T = G_alloc_matrix(n, m);
    dest_mat_T = G_alloc_matrix(n, m);
    src_dest_mat = G_alloc_matrix(n, n);
    R_mat = G_alloc_matrix(n, n);
    R_mat_T = G_alloc_matrix(n, n);

    mat_mn1 = G_alloc_matrix(m, n);
    mat_mn2 = G_alloc_matrix(m, n);
    mat_nm1 = G_alloc_matrix(n, m);
    mat_nm2 = G_alloc_matrix(n, m);
    mat_nn1 = G_alloc_matrix(n, n);

    E_mat = G_alloc_matrix(m, m);
    P_mat = G_alloc_matrix(ndims, ndims);
    Q_mat = G_alloc_matrix(ndims, ndims);

    transpose_matrix(m, n, dest_mat, dest_mat_T);

    for (i = 0; i < m; i++) {
	for (j = 0; j < m; j++) {
	    if (i != j) {
		E_mat[i][j] = -1.0 / (double)m;
	    }
	    else{
		E_mat[i][j] = 1.0 - 1.0 / (double)m;
	    }
	}
    }

    matmult(n, m, m, dest_mat_T, E_mat, mat_nm1);
    matmult(n, m, n, mat_nm1, src_mat, src_dest_mat);
    copy_matrix(n, n, src_dest_mat, P_mat);
    copy_matrix(n, n, src_dest_mat, mat_nn1);

    status = G_math_svduv(D_vec, mat_nn1, P_mat, n, Q_mat, n);

    if (status == 0)
	status = MSUCCESS;

    transpose_matrix(n, n, P_mat, mat_nn1);

    /* rotation matrix */
    matmult(n, n, n, Q_mat, mat_nn1, R_mat_T);
    transpose_matrix(n, n, R_mat_T, R_mat);

    /* scale */
    matmult(n, n, n, src_dest_mat, R_mat_T, mat_nn1);
    trace1 = trace(n, n, mat_nn1);

    transpose_matrix(m, n, src_mat, src_mat_T);
    matmult(n, m, m, src_mat_T, E_mat, mat_nm1);
    matmult(n, m, n, mat_nm1, src_mat, mat_nn1);
    trace2 = trace(n, n, mat_nn1);

    OR[14] = trace1 / trace2;

    /* shifts */
    matmult(m, n, n, src_mat, R_mat_T, mat_mn1);
    scale_matrix(m, n, OR[14], mat_mn1, mat_mn2);
    subtract_matrix(m, n, dest_mat, mat_mn2, mat_mn1);
    scale_matrix(m, n, 1.0 / m, mat_mn1, mat_mn2);
    transpose_matrix(m, n, mat_mn2, mat_nm1);

    S_vec = G_alloc_vector(n);
    one_vec = G_alloc_vector(m);

    for (i = 0; i < m; i++){
	one_vec[i] = 1.0;
    }

    matrix_multiply(n, m, mat_nm1, one_vec, S_vec);

    /* matrix to vector */
    for (i = 0; i < ndims; i++) {
	for (j = 0; j < ndims; j++) {
	    OR[i * ndims + j] = R_mat[i][j];
	}
    }
    
    G_free_matrix(src_mat);
    G_free_matrix(src_mat_T);
    G_free_matrix(dest_mat);
    G_free_matrix(dest_mat_T);
    G_free_matrix(src_dest_mat);
    G_free_vector(D_vec);
    G_free_matrix(E_mat);
    G_free_matrix(P_mat);
    G_free_matrix(Q_mat);
    G_free_matrix(R_mat);
    G_free_matrix(R_mat_T);
    G_free_matrix(mat_mn1);
    G_free_matrix(mat_mn2);
    G_free_matrix(mat_nm1);
    G_free_matrix(mat_nm2);
    G_free_matrix(mat_nn1);
    G_free_vector(S_vec);
    G_free_vector(one_vec);

    return status;
}
Exemplo n.º 7
0
/*----------------------------------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Declarations */
    int dim_vect, nparameters, BW, npoints;
    int nsply, nsplx, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    const char *dvr, *db, *mapset;
    char table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
    double lambda, mean, stepN, stepE, HighThresh,
	LowThresh;
    double N_extension, E_extension, edgeE, edgeN;

    int i, nterrain, count_terrain;

    int last_row, last_column, flag_auxiliar = FALSE;

    int *lineVect;
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect, **obsVect_all;	/* Interpolation and least-square matrix */

    struct Map_info In, Out, Terrain;
    struct Option *in_opt, *out_opt, *out_terrain_opt, *stepE_opt,
	*stepN_opt, *lambda_f_opt, *Thresh_A_opt, *Thresh_B_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

    struct Cell_head elaboration_reg, original_reg;
    struct Reg_dimens dims;
    struct bound_box general_box, overlap_box;

    struct Point *observ;
    struct lidar_cat *lcat;

    dbDriver *driver;

/*----------------------------------------------------------------------------------------------------------*/
    /* Options' declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    module->description =
	_("Corrects the v.lidar.growing output. It is the last of the three algorithms for LIDAR filtering.");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
	_("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->description =
	_("Input observation vector map name (v.lidar.growing output)");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->description = _("Output classified vector map name");

    out_terrain_opt = G_define_option();
    out_terrain_opt->key = "terrain";
    out_terrain_opt->type = TYPE_STRING;
    out_terrain_opt->key_desc = "name";
    out_terrain_opt->required = YES;
    out_terrain_opt->gisprompt = "new,vector,vector";
    out_terrain_opt->description =
	_("Only 'terrain' points output vector map");

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "25";
    stepE_opt->description =
	_("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "25";
    stepN_opt->description =
	_("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_c";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description =
	_("Regularization weight in reclassification evaluation");
    lambda_f_opt->answer = "1";

    Thresh_A_opt = G_define_option();
    Thresh_A_opt->key = "tch";
    Thresh_A_opt->type = TYPE_DOUBLE;
    Thresh_A_opt->required = NO;
    Thresh_A_opt->description =
	_("High threshold for object to terrain reclassification");
    Thresh_A_opt->answer = "2";

    Thresh_B_opt = G_define_option();
    Thresh_B_opt->key = "tcl";
    Thresh_B_opt->type = TYPE_DOUBLE;
    Thresh_B_opt->required = NO;
    Thresh_B_opt->description =
	_("Low threshold for terrain to object reclassification");
    Thresh_B_opt->answer = "1";

    /* Parsing */
    G_gisinit(argv[0]);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);
    HighThresh = atof(Thresh_A_opt->answer);
    LowThresh = atof(Thresh_B_opt->answer);

    if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of database"));

    if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of driver"));

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_aux", xname);
    }
    else
	sprintf(table_name, "%s_aux", out_opt->answer);

    /* Something went wrong in a previous v.lidar.correction execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
        db_set_error_handler_driver(driver);
        
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Checking vector names */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 G_FATAL_EXIT);

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

    Vect_set_open_level(1);	/* without topology */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    /* Input vector must be 3D */
    if (!Vect_is_3d(&In))
	G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer);

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
	double dens, dist;
	if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
	    G_message("Estimated point density: %.4g", dens);
	    G_message("Estimated mean distance between points: %.4g", dist);
	}
	else
	    G_warning(_("No points in current region!"));
	
	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }

    /* Open output vector */
    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) {
	Vect_close(&In);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    if (0 > Vect_open_new(&Terrain, out_terrain_opt->answer, WITH_Z)) {
	Vect_close(&In);
	Vect_close(&Out);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);
    Vect_copy_head_data(&In, &Terrain);
    Vect_hist_copy(&In, &Terrain);
    Vect_hist_command(&Terrain);

    /* Start driver and open db */
    driver = db_start_driver_open_database(dvr, db);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      dvr);
    db_set_error_handler_driver(driver);

    /* Create auxiliar table */
    if ((flag_auxiliar =
	 P_Create_Aux2_Table(driver, table_name)) == FALSE) {
	Vect_close(&In);
	Vect_close(&Out);
	Vect_close(&Terrain);
	exit(EXIT_FAILURE);
    }

    db_create_index2(driver, table_name, "ID");
    /* sqlite likes that ??? */
    db_close_database_shutdown_driver(driver);
    driver = db_start_driver_open_database(dvr, db);

    /* Setting regions and boxes */
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    /*------------------------------------------------------------------
      | Subdividing and working with tiles: 									
      | Each original region will be divided into several subregions. 
      | Each one will be overlaped by its neighbouring subregions. 
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
	dims.overlap = OVERLAP_SIZE * stepN;
    else
	dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(P_BILINEAR, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(n_("adjusted EW spline %d",
                         "adjusted EW splines %d",
                         nsplx_adj), nsplx_adj);
    G_verbose_message(n_("adjusted NS spline %d",
                         "adjusted NS splines %d",
                         nsply_adj), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each row */

	P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
		      GENERAL_ROW);

	if (elaboration_reg.north > original_reg.north) {	/* First row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

	nsply =
	    ceil((elaboration_reg.north -
		  elaboration_reg.south) / stepN) + 0.5;
	/*
	if (nsply > NSPLY_MAX) {
	    nsply = NSPLY_MAX;
	}
	*/
	G_debug(1, _("nsply = %d"), nsply);

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each column */

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  GENERAL_COLUMN);

	    if (elaboration_reg.west < original_reg.west) {	/* First column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }

	    nsplx =
		ceil((elaboration_reg.east - elaboration_reg.west) / stepE) +
		0.5;
	    /*
	    if (nsplx > NSPLX_MAX) {
		nsplx = NSPLX_MAX;
	    }
	    */
	    G_debug(1, _("nsplx = %d"), nsplx);

	    dim_vect = nsplx * nsply;
	    G_debug(1, _("read vector region map"));
	    observ =
		P_Read_Vector_Correction(&In, &elaboration_reg, &npoints,
					 &nterrain, dim_vect, &lcat);

	    G_debug(5, _("npoints = %d, nterrain = %d"), npoints, nterrain);
	    if (npoints > 0) {	/* If there is any point falling into elaboration_reg. */
		count_terrain = 0;
		nparameters = nsplx * nsply;

		/* Mean calculation */
		G_debug(3, _("Mean calculation"));
		mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

		/*Least Squares system */
		BW = P_get_BandWidth(P_BILINEAR, nsply);	/* Bilinear interpolation */
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		TN = G_alloc_vector(nparameters);	/* vector */
		parVect = G_alloc_vector(nparameters);	/* Bilinear parameters vector */
		obsVect = G_alloc_matrix(nterrain + 1, 3);	/* Observation vector with terrain points */
		obsVect_all = G_alloc_matrix(npoints + 1, 3);	/* Observation vector with all points */
		Q = G_alloc_vector(nterrain + 1);	/* "a priori" var-cov matrix */
		lineVect = G_alloc_ivector(npoints + 1);

		/* Setting obsVect vector & Q matrix */
		G_debug(3, _("Only TERRAIN points"));
		for (i = 0; i < npoints; i++) {
		    if (observ[i].cat == TERRAIN_SINGLE) {
			obsVect[count_terrain][0] = observ[i].coordX;
			obsVect[count_terrain][1] = observ[i].coordY;
			obsVect[count_terrain][2] = observ[i].coordZ - mean;
			Q[count_terrain] = 1;	/* Q=I */
			count_terrain++;
		    }
		    lineVect[i] = observ[i].lineID;
		    obsVect_all[i][0] = observ[i].coordX;
		    obsVect_all[i][1] = observ[i].coordY;
		    obsVect_all[i][2] = observ[i].coordZ - mean;
		}

		G_free(observ);

		G_verbose_message(_("Bilinear interpolation"));
		normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
			       nsply, elaboration_reg.west,
			       elaboration_reg.south, nterrain, nparameters,
			       BW);
		nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);

		G_free_matrix(N);
		G_free_vector(TN);
		G_free_vector(Q);
		G_free_matrix(obsVect);

		G_verbose_message( _("Correction and creation of terrain vector"));
		P_Sparse_Correction(&In, &Out, &Terrain, &elaboration_reg,
				    general_box, overlap_box, obsVect_all, lcat,
				    parVect, lineVect, stepN, stepE,
				    dims.overlap, HighThresh, LowThresh,
				    nsplx, nsply, npoints, driver, mean, table_name);

		G_free_vector(parVect);
		G_free_matrix(obsVect_all);
		G_free_ivector(lineVect);
	    }
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider changing the spline step."));
	    }
	    G_free(lcat);
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    /* Dropping auxiliar table */
    if (npoints > 0) {
	G_debug(1, _("Dropping <%s>"), table_name);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Auxiliar table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    Vect_close(&Out);
    Vect_close(&Terrain);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*! END MAIN */
Exemplo n.º 8
0
static void seed(struct ClassSig *Sig, int nbands)
{
    int i, b1, b2;
    double period;
    double *mean, **R;

    G_debug(1, "seed()");

    /* Compute the mean of variance for each band */
    mean = G_alloc_vector(nbands);
    R = G_alloc_matrix(nbands, nbands);
    n_nulls = (int *)G_calloc(nbands, sizeof(int));

    total_nulls = 0;
    for (b1 = 0; b1 < nbands; b1++) {
	n_nulls[b1] = 0;
	mean[b1] = 0.0;
	for (i = 0; i < Sig->ClassData.npixels; i++) {
	    if (Rast_is_d_null_value(&Sig->ClassData.x[i][b1])) {
		n_nulls[b1]++;
		total_nulls++;
	    }
	    else
		mean[b1] += Sig->ClassData.x[i][b1];
	}
	mean[b1] /= (double)(Sig->ClassData.npixels - n_nulls[b1]);
    }

    for (b1 = 0; b1 < nbands; b1++)
	for (b2 = 0; b2 < nbands; b2++) {
	    R[b1][b2] = 0.0;
	    for (i = 0; i < Sig->ClassData.npixels; i++) {
		if (!Rast_is_d_null_value(&Sig->ClassData.x[i][b1]) &&
		    !Rast_is_d_null_value(&Sig->ClassData.x[i][b2]))
		    R[b1][b2] +=
			(Sig->ClassData.x[i][b1]) * (Sig->ClassData.x[i][b2]);
	    }
	    R[b1][b2] /= (double)(Sig->ClassData.npixels - n_nulls[b1] -
				  n_nulls[b2]);
	    R[b1][b2] -= mean[b1] * mean[b2];
	}

    /* Compute the sampling period for seeding */
    if (Sig->nsubclasses > 1) {
	period = (Sig->ClassData.npixels - 1) / (Sig->nsubclasses - 1.0);
    }
    else
	period = 0;


    /* Seed the means and set the diagonal covariance components */
    for (i = 0; i < Sig->nsubclasses; i++) {
	for (b1 = 0; b1 < nbands; b1++) {
	    if (Rast_is_d_null_value(&Sig->ClassData.x[(int)(i * period)][b1]))
		Rast_set_d_null_value(&Sig->SubSig[i].means[b1], 1);
	    else
		Sig->SubSig[i].means[b1] =
		    Sig->ClassData.x[(int)(i * period)][b1];

	    for (b2 = 0; b2 < nbands; b2++) {
		Sig->SubSig[i].R[b1][b2] = R[b1][b2];
	    }
	}

	Sig->SubSig[i].pi = 1.0 / Sig->nsubclasses;
    }

    G_free_vector(mean);
    G_free_matrix(R);

    compute_constants(Sig, nbands);
}
Exemplo n.º 9
0
static int 
ludcmp(double **a,int n,int *indx,double *d)
{
    int i,imax,j,k;
    double big,dum,sum,temp;
    double *vv;//,*G_alloc_vector();
    //double fabs();

    vv=G_alloc_vector(n);
    *d=1.0;
    for (i=0;i<n;i++) 
    {
        big=0.0;
        for (j=0;j<n;j++)
            if ((temp=fabs(a[i][j])) > big)
		big=temp;
        if (big == 0.0)
	    return 0; /* Singular matrix  */
        vv[i]=1.0/big;
    }
    for (j=0;j<n;j++) 
    {
        for (i=0;i<j;i++) 
	{
            sum=a[i][j];
            for (k=0;k<i;k++)
		sum -= a[i][k]*a[k][j];
            a[i][j]=sum;
        }
        big=0.0;
        for (i=j;i<n;i++) 
	{
            sum=a[i][j];
            for (k=0;k<j;k++)
                sum -= a[i][k]*a[k][j];
            a[i][j]=sum;
            if ( (dum=vv[i]*fabs(sum)) >= big) 
	    {
                big=dum;
                imax=i;
            }
        }
        if (j != imax) 
	{
            for (k=0;k<n;k++) 
	    {
                dum=a[imax][k];
                a[imax][k]=a[j][k];
                a[j][k]=dum;
            }
            *d = -(*d);
            vv[imax]=vv[j];
        }
        indx[j]=imax;

 	/* Change made 3/27/98 for robustness */
        if ( (a[j][j]>=0)&&(a[j][j]<TINY) ) a[j][j]= TINY;
        if ( (a[j][j]<0)&&(a[j][j]>-TINY) ) a[j][j]= -TINY;

        if (j != n-1) 
	{
            dum=1.0/(a[j][j]);
            for (i=j+1;i<n;i++)
		a[i][j] *= dum;
        }
    }
    G_free_vector (vv);
    return(1);
}
Exemplo n.º 10
0
int IL_resample_interp_segments_2d(struct interp_params *params, struct BM *bitmask,	/* bitmask */
				   double zmin, double zmax,	/* min and max input z-values */
				   double *zminac, double *zmaxac,	/* min and max interp. z-values */
				   double *gmin, double *gmax,	/* min and max inperp. slope val. */
				   double *c1min, double *c1max, double *c2min, double *c2max,	/* min and max interp. curv. val. */
				   double *ertot,	/* total interplating func. error */
				   off_t offset1,	/* offset for temp file writing */
				   double *dnorm,
				   int overlap,
				   int inp_rows,
				   int inp_cols,
				   int fdsmooth,
				   int fdinp,
				   double ns_res,
				   double ew_res,
				   double inp_ns_res,
				   double inp_ew_res, int dtens)
{

    int i, j, k, l, m, m1, i1;	/* loop coounters */
    int cursegm = 0;
    int new_comp = 0;
    int n_rows, n_cols, inp_r, inp_c;
    double x_or, y_or, xm, ym;
    static int first = 1, new_first = 1;
    double **matrix = NULL, **new_matrix = NULL, *b = NULL;
    int *indx = NULL, *new_indx = NULL;
    static struct fcell_triple *in_points = NULL;	/* input points */
    int inp_check_rows, inp_check_cols,	/* total input rows/cols */
      out_check_rows, out_check_cols;	/* total output rows/cols */
    int first_row, last_row;	/* first and last input row of segment */
    int first_col, last_col;	/* first and last input col of segment */
    int num, prev;
    int div;			/* number of divides */
    int rem_out_row, rem_out_col;	/* output rows/cols remainders */
    int inp_seg_r, inp_seg_c,	/* # of input rows/cols in segment */
      out_seg_r, out_seg_c;	/* # of output rows/cols in segment */
    int ngstc, nszc		/* first and last output col of the
				 * segment */
     , ngstr, nszr;		/* first and last output row of the
				 * segment */
    int index;			/* index for input data */
    int c, r;
    int overlap1;
    int p_size;
    struct quaddata *data;
    double xmax, xmin, ymax, ymin;
    int totsegm;		/* total number of segments */
    int total_points = 0;
    struct triple triple;	/* contains garbage */


    xmin = params->x_orig;
    ymin = params->y_orig;
    xmax = xmin + ew_res * params->nsizc;
    ymax = ymin + ns_res * params->nsizr;
    prev = inp_rows * inp_cols;
    if (prev <= params->kmax)
	div = 1;		/* no segmentation */

    else {			/* find the number of divides */
	for (i = 2;; i++) {
	    c = inp_cols / i;
	    r = inp_rows / i;
	    num = c * r;
	    if (num < params->kmin) {
		if (((params->kmin - num) > (prev + 1 - params->kmax)) &&
		    (prev + 1 < params->KMAX2)) {
		    div = i - 1;
		    break;
		}
		else {
		    div = i;
		    break;
		}
	    }
	    if ((num > params->kmin) && (num + 1 < params->kmax)) {
		div = i;
		break;
	    }
	    prev = num;
	}
    }
    out_seg_r = params->nsizr / div;	/* output rows per segment */
    out_seg_c = params->nsizc / div;	/* output cols per segment */
    inp_seg_r = inp_rows / div;	/* input rows per segment */
    inp_seg_c = inp_cols / div;	/* input rows per segment */
    rem_out_col = params->nsizc % div;
    rem_out_row = params->nsizr % div;
    overlap1 = min1(overlap, inp_seg_c - 1);
    overlap1 = min1(overlap1, inp_seg_r - 1);
    out_check_rows = 0;
    out_check_cols = 0;
    inp_check_rows = 0;
    inp_check_cols = 0;

    if (div == 1) {
	p_size = inp_seg_c * inp_seg_r;
    }
    else {
	p_size = (overlap1 * 2 + inp_seg_c) * (overlap1 * 2 + inp_seg_r);
    }
    if (!in_points) {
	if (!
	    (in_points =
	     (struct fcell_triple *)G_malloc(sizeof(struct fcell_triple) *
					     p_size * div))) {
	    fprintf(stderr, "Cannot allocate memory for in_points\n");
	    return -1;
	}
    }

    *dnorm =
	sqrt(((xmax - xmin) * (ymax -
			       ymin) * p_size) / (inp_rows * inp_cols));

    if (dtens) {
	params->fi = params->fi * (*dnorm) / 1000.;
	fprintf(stderr, "dnorm = %f, rescaled tension = %f\n", *dnorm,
		params->fi);
    }

    if (div == 1) {		/* no segmentation */
	totsegm = 1;
	cursegm = 1;

	input_data(params, 1, inp_rows, in_points, fdsmooth, fdinp, inp_rows,
		   inp_cols, zmin, inp_ns_res, inp_ew_res);

	x_or = 0.;
	y_or = 0.;
	xm = params->nsizc * ew_res;
	ym = params->nsizr * ns_res;

	data = (struct quaddata *)quad_data_new(x_or, y_or, xm, ym,
						params->nsizr, params->nsizc,
						0, params->KMAX2);
	m1 = 0;
	for (k = 1; k <= p_size; k++) {
	    if (!Rast_is_f_null_value(&(in_points[k - 1].z))) {
		data->points[m1].x = in_points[k - 1].x / (*dnorm);
		data->points[m1].y = in_points[k - 1].y / (*dnorm);
		/*        data->points[m1].z = (double) (in_points[k - 1].z) / (*dnorm); */
		data->points[m1].z = (double)(in_points[k - 1].z);
		data->points[m1].sm = in_points[k - 1].smooth;
		m1++;
	    }
	}
	data->n_points = m1;
	total_points = m1;
	if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
	    fprintf(stderr, "Cannot allocate memory for indx\n");
	    return -1;
	}
	if (!(matrix = G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) {
	    fprintf(stderr, "Cannot allocate memory for matrix\n");
	    return -1;
	}
	if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
	    fprintf(stderr, "Cannot allocate memory for b\n");
	    return -1;
	}

	if (params->matrix_create(params, data->points, m1, matrix, indx) < 0)
	    return -1;
	for (i = 0; i < m1; i++) {
	    b[i + 1] = data->points[i].z;
	}
	b[0] = 0.;
	G_lubksb(matrix, m1 + 1, indx, b);

	params->check_points(params, data, b, ertot, zmin, *dnorm, triple);

	if (params->grid_calc(params, data, bitmask,
			      zmin, zmax, zminac, zmaxac, gmin, gmax,
			      c1min, c1max, c2min, c2max, ertot, b, offset1,
			      *dnorm) < 0) {
	    fprintf(stderr, "interpolation failed\n");
	    return -1;
	}
	else {
	    if (totsegm != 0) {
		G_percent(cursegm, totsegm, 1);
	    }
	    /*
	     * if (b) G_free_vector(b); if (matrix) G_free_matrix(matrix); if
	     * (indx) G_free_ivector(indx);
	     */
	    fprintf(stderr, "dnorm in ressegm after grid before out= %f \n",
		    *dnorm);
	    return total_points;
	}
    }

    out_seg_r = params->nsizr / div;	/* output rows per segment */
    out_seg_c = params->nsizc / div;	/* output cols per segment */
    inp_seg_r = inp_rows / div;	/* input rows per segment */
    inp_seg_c = inp_cols / div;	/* input rows per segment */
    rem_out_col = params->nsizc % div;
    rem_out_row = params->nsizr % div;
    overlap1 = min1(overlap, inp_seg_c - 1);
    overlap1 = min1(overlap1, inp_seg_r - 1);
    out_check_rows = 0;
    out_check_cols = 0;
    inp_check_rows = 0;
    inp_check_cols = 0;

    totsegm = div * div;

    /* set up a segment */
    for (i = 1; i <= div; i++) {	/* input and output rows */
	if (i <= div - rem_out_row)
	    n_rows = out_seg_r;
	else
	    n_rows = out_seg_r + 1;
	inp_r = inp_seg_r;
	out_check_cols = 0;
	inp_check_cols = 0;
	ngstr = out_check_rows + 1;	/* first output row of the segment */
	nszr = ngstr + n_rows - 1;	/* last output row of the segment */
	y_or = (ngstr - 1) * ns_res;	/* y origin of the segment */
	/*
	 * Calculating input starting and ending rows and columns of this
	 * segment
	 */
	first_row = (int)(y_or / inp_ns_res) + 1;
	if (first_row > overlap1) {
	    first_row -= overlap1;	/* middle */
	    last_row = first_row + inp_seg_r + overlap1 * 2 - 1;
	    if (last_row > inp_rows) {
		first_row -= (last_row - inp_rows);	/* bottom */
		last_row = inp_rows;
	    }
	}
	else {
	    first_row = 1;	/* top */
	    last_row = first_row + inp_seg_r + overlap1 * 2 - 1;
	}
	if ((last_row > inp_rows) || (first_row < 1)) {
	    fprintf(stderr, "Row overlap too large!\n");
	    return -1;
	}
	input_data(params, first_row, last_row, in_points, fdsmooth, fdinp,
		   inp_rows, inp_cols, zmin, inp_ns_res, inp_ew_res);

	for (j = 1; j <= div; j++) {	/* input and output cols */
	    if (j <= div - rem_out_col)
		n_cols = out_seg_c;
	    else
		n_cols = out_seg_c + 1;
	    inp_c = inp_seg_c;

	    ngstc = out_check_cols + 1;	/* first output col of the segment */
	    nszc = ngstc + n_cols - 1;	/* last output col of the segment */
	    x_or = (ngstc - 1) * ew_res;	/* x origin of the segment */

	    first_col = (int)(x_or / inp_ew_res) + 1;
	    if (first_col > overlap1) {
		first_col -= overlap1;	/* middle */
		last_col = first_col + inp_seg_c + overlap1 * 2 - 1;
		if (last_col > inp_cols) {
		    first_col -= (last_col - inp_cols);	/* right */
		    last_col = inp_cols;
		}
	    }
	    else {
		first_col = 1;	/* left */
		last_col = first_col + inp_seg_c + overlap1 * 2 - 1;
	    }
	    if ((last_col > inp_cols) || (first_col < 1)) {
		fprintf(stderr, "Column overlap too large!\n");
		return -1;
	    }
	    m = 0;
	    /* Getting points for interpolation (translated) */

	    xm = nszc * ew_res;
	    ym = nszr * ns_res;
	    data = (struct quaddata *)quad_data_new(x_or, y_or, xm, ym,
						    nszr - ngstr + 1,
						    nszc - ngstc + 1, 0,
						    params->KMAX2);
	    new_comp = 0;

	    for (k = 0; k <= last_row - first_row; k++) {
		for (l = first_col - 1; l < last_col; l++) {
		    index = k * inp_cols + l;
		    if (!Rast_is_f_null_value(&(in_points[index].z))) {
			/* if the point is inside the segment (not overlapping) */
			if ((in_points[index].x - x_or >= 0) &&
			    (in_points[index].y - y_or >= 0) &&
			    ((nszc - 1) * ew_res - in_points[index].x >= 0) &&
			    ((nszr - 1) * ns_res - in_points[index].y >= 0))
			    total_points += 1;
			data->points[m].x =
			    (in_points[index].x - x_or) / (*dnorm);
			data->points[m].y =
			    (in_points[index].y - y_or) / (*dnorm);
			/*            data->points[m].z = (double) (in_points[index].z) / (*dnorm); */
			data->points[m].z = (double)(in_points[index].z);
			data->points[m].sm = in_points[index].smooth;
			m++;
		    }
		    else
			new_comp = 1;

		    /*          fprintf(stderr,"%f,%f,%f
		       zmin=%f\n",in_points[index].x,in_points[index].y,in_points[index].z,zmin);
		     */
		}
	    }
	    /*      fprintf (stdout,"m,index:%di,%d\n",m,index); */
	    if (m <= params->KMAX2)
		data->n_points = m;
	    else
		data->n_points = params->KMAX2;
	    out_check_cols += n_cols;
	    inp_check_cols += inp_c;
	    cursegm = (i - 1) * div + j - 1;

	    /* show before to catch 0% */
	    if (totsegm != 0) {
		G_percent(cursegm, totsegm, 1);
	    }
	    if (m == 0) {
		/*
		 * fprintf(stderr,"Warning: segment with zero points encountered,
		 * insrease overlap\n");
		 */
		write_zeros(params, data, offset1);
	    }
	    else {
		if (new_comp) {
		    if (new_first) {
			new_first = 0;
			if (!b) {
			    if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
				fprintf(stderr,
					"Cannot allocate memory for b\n");
				return -1;
			    }
			}
			if (!(new_indx = G_alloc_ivector(params->KMAX2 + 1))) {
			    fprintf(stderr,
				    "Cannot allocate memory for new_indx\n");
			    return -1;
			}
			if (!
			    (new_matrix =
			     G_alloc_matrix(params->KMAX2 + 1,
					    params->KMAX2 + 1))) {
			    fprintf(stderr,
				    "Cannot allocate memory for new_matrix\n");
			    return -1;
			}
		    }		/*new_first */
		    if (params->
			matrix_create(params, data->points, data->n_points,
				      new_matrix, new_indx) < 0)
			return -1;

		    for (i1 = 0; i1 < m; i1++) {
			b[i1 + 1] = data->points[i1].z;
		    }
		    b[0] = 0.;
		    G_lubksb(new_matrix, data->n_points + 1, new_indx, b);

		    params->check_points(params, data, b, ertot, zmin,
					 *dnorm, triple);

		    if (params->grid_calc(params, data, bitmask,
					  zmin, zmax, zminac, zmaxac, gmin,
					  gmax, c1min, c1max, c2min, c2max,
					  ertot, b, offset1, *dnorm) < 0) {

			fprintf(stderr, "interpolate() failed\n");
			return -1;
		    }
		}		/*new_comp */
		else {
		    if (first) {
			first = 0;
			if (!b) {
			    if (!(b = G_alloc_vector(params->KMAX2 + 2))) {
				fprintf(stderr,
					"Cannot allocate memory for b\n");
				return -1;
			    }
			}
			if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
			    fprintf(stderr,
				    "Cannot allocate memory for indx\n");
			    return -1;
			}
			if (!
			    (matrix =
			     G_alloc_matrix(params->KMAX2 + 1,
					    params->KMAX2 + 1))) {
			    fprintf(stderr,
				    "Cannot allocate memory for matrix\n");
			    return -1;
			}
		    }		/* first */
		    if (params->
			matrix_create(params, data->points, data->n_points,
				      matrix, indx) < 0)
			return -1;
		    /*        } here it was bug */
		    for (i1 = 0; i1 < m; i1++)
			b[i1 + 1] = data->points[i1].z;
		    b[0] = 0.;
		    G_lubksb(matrix, data->n_points + 1, indx, b);

		    params->check_points(params, data, b, ertot, zmin,
					 *dnorm, triple);

		    if (params->grid_calc(params, data, bitmask,
					  zmin, zmax, zminac, zmaxac, gmin,
					  gmax, c1min, c1max, c2min, c2max,
					  ertot, b, offset1, *dnorm) < 0) {

			fprintf(stderr, "interpolate() failed\n");
			return -1;
		    }
		}
	    }
	    if (data) {
		G_free(data->points);
		G_free(data);
	    }
	    /*
	     * cursegm++;
	     */
	}

	inp_check_rows += inp_r;
	out_check_rows += n_rows;
    }

    /* run one last time after the loop is done to catch 100% */
    if (totsegm != 0)
	G_percent(1, 1, 1);	/* cursegm doesn't get to totsegm so we force 100% */

    /*
     * if (b) G_free_vector(b); if (indx) G_free_ivector(indx); if (matrix)
     * G_free_matrix(matrix);
     */
    fprintf(stderr, "dnorm in ressegm after grid before out2= %f \n", *dnorm);
    return total_points;
}
Exemplo n.º 11
0
int main(int argc, char *argv[])
{
    int i, j;			/* Loop control variables */
    int bands;			/* Number of image bands */
    double *mu;			/* Mean vector for image bands */
    double **covar;		/* Covariance Matrix */
    double *eigval;
    double **eigmat;
    int *inp_fd;
    int scale, scale_max, scale_min;

    struct GModule *module;
    struct Option *opt_in, *opt_out, *opt_scale;

    /* initialize GIS engine */
    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("imagery"));
    G_add_keyword(_("image transformation"));
    G_add_keyword(_("PCA"));
    module->description = _("Principal components analysis (PCA) "
			    "for image processing.");

    /* Define options */
    opt_in = G_define_standard_option(G_OPT_R_INPUTS);
    opt_in->description = _("Name of two or more input raster maps");

    opt_out = G_define_option();
    opt_out->label = _("Base name for output raster maps");
    opt_out->description =
	_("A numerical suffix will be added for each component map");
    opt_out->key = "output_prefix";
    opt_out->type = TYPE_STRING;
    opt_out->key_desc = "string";
    opt_out->required = YES;

    opt_scale = G_define_option();
    opt_scale->key = "rescale";
    opt_scale->type = TYPE_INTEGER;
    opt_scale->key_desc = "min,max";
    opt_scale->required = NO;
    opt_scale->answer = "0,255";
    opt_scale->label =
	_("Rescaling range for output maps");
    opt_scale->description =
	_("For no rescaling use 0,0");
    opt_scale->guisection = _("Rescale");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    /* determine number of bands passed in */
    for (bands = 0; opt_in->answers[bands] != NULL; bands++) ;

    if (bands < 2)
	G_fatal_error(_("Sorry, at least 2 input bands must be provided"));

    /* default values */
    scale = 1;
    scale_min = 0;
    scale_max = 255;

    /* get scale parameters */
    set_output_scale(opt_scale, &scale, &scale_min, &scale_max);

    /* allocate memory */
    covar = G_alloc_matrix(bands, bands);
    mu = G_alloc_vector(bands);
    inp_fd = G_alloc_ivector(bands);
    eigmat = G_alloc_matrix(bands, bands);
    eigval = G_alloc_vector(bands);

    /* open and check input/output files */
    for (i = 0; i < bands; i++) {
	char tmpbuf[128];

	sprintf(tmpbuf, "%s.%d", opt_out->answer, i + 1);
	G_check_input_output_name(opt_in->answers[i], tmpbuf, GR_FATAL_EXIT);

	inp_fd[i] = Rast_open_old(opt_in->answers[i], "");
    }

    G_verbose_message(_("Calculating covariance matrix..."));
    calc_mu(inp_fd, mu, bands);

    calc_covariance(inp_fd, covar, mu, bands);

    for (i = 0; i < bands; i++) {
	for (j = 0; j < bands; j++) {
	    covar[i][j] =
		covar[i][j] /
		((double)((Rast_window_rows() * Rast_window_cols()) - 1));
	    G_debug(3, "covar[%d][%d] = %f", i, j, covar[i][j]);
	}
    }

    G_math_d_copy(covar[0], eigmat[0], bands*bands);
    G_debug(1, "Calculating eigenvalues and eigenvectors...");
    G_math_eigen(eigmat, eigval, bands);

#ifdef PCA_DEBUG
    /* dump eigen matrix and eigen values */
    dump_eigen(bands, eigmat, eigval);
#endif

    G_debug(1, "Ordering eigenvalues in descending order...");
    G_math_egvorder(eigval, eigmat, bands);

    G_debug(1, "Transposing eigen matrix...");
    G_math_d_A_T(eigmat, bands);

    /* write output images */
    write_pca(eigmat, inp_fd, opt_out->answer, bands, scale, scale_min,
	      scale_max);

    /* write colors and history to output */
    for (i = 0; i < bands; i++) {
	char outname[80];

	sprintf(outname, "%s.%d", opt_out->answer, i + 1);

	/* write colors and history to file */
	write_support(bands, outname, eigmat, eigval);

	/* close output file */
	Rast_unopen(inp_fd[i]);
    }
    
    /* free memory */
    G_free_matrix(covar);
    G_free_vector(mu);
    G_free_ivector(inp_fd);
    G_free_matrix(eigmat);
    G_free_vector(eigval);

    exit(EXIT_SUCCESS);
}
Exemplo n.º 12
0
int main(int argc, char *argv[])
{
    int npmin;
    int ii;
    double x_orig, y_orig, dnorm, deltx, delty, xm, ym;
    char dmaxchar[200];
    char dminchar[200];

    struct quaddata *data;
    struct multfunc *functions;
    struct multtree *tree;
    int open_check, with_z;
    char buf[1024];

    struct GModule *module;
    struct
    {
	struct Option *input, *field, *zcol, *wheresql, *scol, *elev, *slope,
	    *aspect, *pcurv, *tcurv, *mcurv, *treefile, *overfile, *maskmap,
	    *dmin, *dmax, *zmult, *fi, *rsm, *segmax, *npmin, *cvdev, *devi,
	    *theta, *scalex;
    } parm;
    struct
    {
	struct Flag *deriv, *cprght, *cv;
    } flag;


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("3D"));
    module->label = _("Performs surface interpolation from vector points map by splines.");
    module->description =
	_("Spatial approximation and topographic analysis from given "
	  "point or isoline data in vector format to floating point "
	  "raster format using regularized spline with tension.");

    flag.cv = G_define_flag();
    flag.cv->key = 'c';
    flag.cv->description =
	_("Perform cross-validation procedure without raster approximation");
    flag.cv->guisection = _("Parameters");

    flag.cprght = G_define_flag();
    flag.cprght->key = 't';
    flag.cprght->description = _("Use scale dependent tension");
    flag.cprght->guisection = _("Parameters");

    flag.deriv = G_define_flag();
    flag.deriv->key = 'd';
    flag.deriv->description =
	_("Output partial derivatives instead of topographic parameters");
    flag.deriv->guisection = _("Outputs");

    parm.input = G_define_standard_option(G_OPT_V_INPUT);
    
    parm.field = G_define_standard_option(G_OPT_V_FIELD);
    parm.field->answer = "1";
    parm.field->guisection = _("Selection");

    parm.zcol = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.zcol->key = "zcolumn";
    parm.zcol->required = NO;
    parm.zcol->label =
	_("Name of the attribute column with values to be used for approximation");
    parm.zcol->description = _("If not given and input is 2D vector map then category values are used. "
                               "If input is 3D vector map then z-coordinates are used.");
    parm.zcol->guisection = _("Parameters");

    parm.wheresql = G_define_standard_option(G_OPT_DB_WHERE);
    parm.wheresql->guisection = _("Selection");

    parm.elev = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.elev->key = "elevation";
    parm.elev->required = NO;
    parm.elev->description = _("Name for output surface elevation raster map");
    parm.elev->guisection = _("Outputs");

    parm.slope = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.slope->key = "slope";
    parm.slope->required = NO;
    parm.slope->description = _("Name for output slope raster map");
    parm.slope->guisection = _("Outputs");

    parm.aspect = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.aspect->key = "aspect";
    parm.aspect->required = NO;
    parm.aspect->description = _("Name for output aspect raster map");
    parm.aspect->guisection = _("Outputs");

    parm.pcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.pcurv->key = "pcurvature";
    parm.pcurv->required = NO;
    parm.pcurv->description = _("Name for output profile curvature raster map");
    parm.pcurv->guisection = _("Outputs");

    parm.tcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.tcurv->key = "tcurvature";
    parm.tcurv->required = NO;
    parm.tcurv->description = _("Name for output tangential curvature raster map");
    parm.tcurv->guisection = _("Outputs");

    parm.mcurv = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.mcurv->key = "mcurvature";
    parm.mcurv->required = NO;
    parm.mcurv->description = _("Name for output mean curvature raster map");
    parm.mcurv->guisection = _("Outputs");

    parm.devi = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.devi->key = "deviations";
    parm.devi->required = NO;
    parm.devi->description = _("Name for output deviations vector point map");
    parm.devi->guisection = _("Outputs");

    parm.cvdev = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.cvdev->key = "cvdev";
    parm.cvdev->required = NO;
    parm.cvdev->description =
	_("Name for output cross-validation errors vector point map");
    parm.cvdev->guisection = _("Outputs");

    parm.treefile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.treefile->key = "treeseg";
    parm.treefile->required = NO;
    parm.treefile->description =
	_("Name for output vector map showing quadtree segmentation");
    parm.treefile->guisection = _("Outputs");

    parm.overfile = G_define_standard_option(G_OPT_V_OUTPUT);
    parm.overfile->key = "overwin";
    parm.overfile->required = NO;
    parm.overfile->description =
	_("Name for output vector map showing overlapping windows");
    parm.overfile->guisection = _("Outputs");

    parm.maskmap = G_define_standard_option(G_OPT_R_INPUT);
    parm.maskmap->key = "mask";
    parm.maskmap->required = NO;
    parm.maskmap->description = _("Name of raster map used as mask");
    parm.maskmap->guisection = _("Parameters");

    parm.fi = G_define_option();
    parm.fi->key = "tension";
    parm.fi->type = TYPE_DOUBLE;
    parm.fi->answer = TENSION;
    parm.fi->required = NO;
    parm.fi->description = _("Tension parameter");
    parm.fi->guisection = _("Parameters");

    parm.rsm = G_define_option();
    parm.rsm->key = "smooth";
    parm.rsm->type = TYPE_DOUBLE;
    parm.rsm->required = NO;
    parm.rsm->description = _("Smoothing parameter");
    parm.rsm->guisection = _("Parameters");

    parm.scol = G_define_option();
    parm.scol->key = "smooth_column";
    parm.scol->type = TYPE_STRING;
    parm.scol->required = NO;
    parm.scol->description =
	_("Name of the attribute column with smoothing parameters");
    parm.scol->guisection = _("Parameters");

    parm.segmax = G_define_option();
    parm.segmax->key = "segmax";
    parm.segmax->type = TYPE_INTEGER;
    parm.segmax->answer = MAXSEGM;
    parm.segmax->required = NO;
    parm.segmax->description = _("Maximum number of points in a segment");
    parm.segmax->guisection = _("Parameters");

    parm.npmin = G_define_option();
    parm.npmin->key = "npmin";
    parm.npmin->type = TYPE_INTEGER;
    parm.npmin->answer = MINPOINTS;
    parm.npmin->required = NO;
    parm.npmin->description =
	_("Minimum number of points for approximation in a segment (>segmax)");
    parm.npmin->guisection = _("Parameters");

    parm.dmin = G_define_option();
    parm.dmin->key = "dmin";
    parm.dmin->type = TYPE_DOUBLE;
    parm.dmin->required = NO;
    parm.dmin->description =
	_("Minimum distance between points (to remove almost identical points)");
    parm.dmin->guisection = _("Parameters");

    parm.dmax = G_define_option();
    parm.dmax->key = "dmax";
    parm.dmax->type = TYPE_DOUBLE;
    parm.dmax->required = NO;
    parm.dmax->description =
	_("Maximum distance between points on isoline (to insert additional points)");
    parm.dmax->guisection = _("Parameters");

    parm.zmult = G_define_option();
    parm.zmult->key = "zscale";
    parm.zmult->type = TYPE_DOUBLE;
    parm.zmult->answer = ZMULT;
    parm.zmult->required = NO;
    parm.zmult->description =
	_("Conversion factor for values used for approximation");
    parm.zmult->guisection = _("Parameters");

    parm.theta = G_define_option();
    parm.theta->key = "theta";
    parm.theta->type = TYPE_DOUBLE;
    parm.theta->required = NO;
    parm.theta->description =
	_("Anisotropy angle (in degrees counterclockwise from East)");
    parm.theta->guisection = _("Parameters");

    parm.scalex = G_define_option();
    parm.scalex->key = "scalex";
    parm.scalex->type = TYPE_DOUBLE;
    parm.scalex->required = NO;
    parm.scalex->description = _("Anisotropy scaling factor");
    parm.scalex->guisection = _("Parameters");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    G_get_set_window(&cellhd);

    ew_res = cellhd.ew_res;
    ns_res = cellhd.ns_res;
    n_cols = cellhd.cols;
    n_rows = cellhd.rows;
    x_orig = cellhd.west;
    y_orig = cellhd.south;
    xm = cellhd.east;
    ym = cellhd.north;
    if (ew_res < ns_res)
	dmin = ew_res / 2;
    else
	dmin = ns_res / 2;
    disk = n_rows * n_cols * sizeof(int);
    sdisk = n_rows * n_cols * sizeof(short int);
    sprintf(dmaxchar, "%f", dmin * 5);
    sprintf(dminchar, "%f", dmin);

    if (!parm.dmin->answer) {
	parm.dmin->answer = G_store(dminchar);
	parm.dmin->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmin->answers[0] = G_store(dminchar);
	parm.dmin->answers[1] = NULL;
    }
    if (!parm.dmax->answer) {
	parm.dmax->answer = G_store(dmaxchar);
	parm.dmax->answers = (char **) G_malloc(2 * sizeof(char *));
	parm.dmax->answers[0] = G_store(dmaxchar);
	parm.dmax->answers[1] = NULL;
    }
    
    input = parm.input->answer;
    zcol = parm.zcol->answer;
    scol = parm.scol->answer;
    wheresql = parm.wheresql->answer;
    maskmap = parm.maskmap->answer;
    elev = parm.elev->answer;
    devi = parm.devi->answer;
    cvdev = parm.cvdev->answer;
    slope = parm.slope->answer;
    aspect = parm.aspect->answer;
    pcurv = parm.pcurv->answer;
    tcurv = parm.tcurv->answer;
    mcurv = parm.mcurv->answer;
    treefile = parm.treefile->answer;
    overfile = parm.overfile->answer;

    if (devi) {
	if (Vect_legal_filename(devi) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  devi);
    }
    if (cvdev) {
	if (Vect_legal_filename(cvdev) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  cvdev);
    }
    if (treefile) {
	if (Vect_legal_filename(treefile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  treefile);
    }
    if (overfile) {
	if (Vect_legal_filename(overfile) == -1)
	    G_fatal_error(_("Output vector map name <%s> is not valid map name"),
			  overfile);
    }
    /*    if (treefile)
       Vect_check_input_output_name(input, treefile, G_FATAL_EXIT);

       if (overfile)
       Vect_check_input_output_name(input, overfile, G_FATAL_EXIT);
     */
    if ((elev == NULL) && (pcurv == NULL) && (tcurv == NULL)
	&& (mcurv == NULL)
	&& (slope == NULL) && (aspect == NULL) && (devi == NULL)
	&& (cvdev == NULL))
	G_warning(_("You are not outputting any raster or vector maps"));
    
    cond2 = ((pcurv != NULL) || (tcurv != NULL) || (mcurv != NULL));
    cond1 = ((slope != NULL) || (aspect != NULL) || cond2);
    deriv = flag.deriv->answer;
    dtens = flag.cprght->answer;
    cv = flag.cv->answer;

    if ((cv && cvdev == NULL) || (!(cv) && cvdev != NULL))
	G_fatal_error(_("Both cross-validation options (-c flag and cvdev vector output) must be specified"));

    if ((elev != NULL || cond1 || cond2 || devi != NULL) && cv)
	G_fatal_error(_("The cross-validation cannot be computed simultaneously with output raster or devi file"));

    ertre = 0.1;
    sscanf(parm.dmax->answer, "%lf", &dmax);
    sscanf(parm.dmin->answer, "%lf", &dmin);
    sscanf(parm.fi->answer, "%lf", &fi);
    sscanf(parm.segmax->answer, "%d", &KMAX);
    sscanf(parm.npmin->answer, "%d", &npmin);
    sscanf(parm.zmult->answer, "%lf", &zmult);

    /* if (fi=0.000000)  G_fatal_error("Tension must be > 0.000000") */

    if (parm.theta->answer)
	sscanf(parm.theta->answer, "%lf", &theta);

    if (parm.scalex->answer) {
	sscanf(parm.scalex->answer, "%lf", &scalex);
	if (!parm.theta->answer)
	    G_fatal_error(_("Using anisotropy - both theta and scalex have to be specified"));
    }

    if (parm.rsm->answer) {
	sscanf(parm.rsm->answer, "%lf", &rsm);
	if (rsm < 0.0)
	    G_fatal_error("Smoothing must be a positive value");
	if (scol != NULL)
	    G_warning(_("Both smatt and smooth options specified - using constant"));
    }
    else {
	sscanf(SMOOTH, "%lf", &rsm);
	if (scol != NULL)
	    rsm = -1;		/* used in InterpLib to indicate variable smoothing */
    }


    if (npmin > MAXPOINTS - 50) {
	G_warning(_("The computation will last too long - lower npmin is suggested"));
	KMAX2 = 2 * npmin;	/* was: KMAX2 = npmin + 50; */
    }
    else
	KMAX2 = 2 * npmin;	/* was: KMAX2 = MAXPOINTS; fixed by JH in 12/01 */

    /* handling of KMAX2 in GRASS4 v.surf.rst
       if (npmin > MAXPOINTS - 50)
       KMAX2 = npmin + 50;
       else
       KMAX2 = MAXPOINTS;
     */

    dmin = dmin * dmin;
    KMIN = npmin;

    az = G_alloc_vector(n_cols + 1);
    if (!az) {
	G_fatal_error(_("Not enough memory for %s"), "az");
    }
    if (cond1) {
	adx = G_alloc_vector(n_cols + 1);
	if (!adx) {
	    G_fatal_error(_("Not enough memory for %s"), "adx");
	}
	ady = G_alloc_vector(n_cols + 1);
	if (!ady) {
	    G_fatal_error(_("Not enough memory for %s"), "ady");
	}
	if (cond2) {
	    adxx = G_alloc_vector(n_cols + 1);
	    if (!adxx) {
		G_fatal_error(_("Not enough memory for %s"), "adxx");
	    }
	    adyy = G_alloc_vector(n_cols + 1);
	    if (!adyy) {
		G_fatal_error(_("Not enough memory for %s"), "adyy");
	    }
	    adxy = G_alloc_vector(n_cols + 1);
	    if (!adxy) {
		G_fatal_error(_("Not enough memory for %s"), "adxy");
	    }
	}
    }
    if ((data =
	 quad_data_new(x_orig, y_orig, xm, ym, n_rows, n_cols, 0,
		       KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "quaddata");
    if ((functions =
	 MT_functions_new(quad_compare, quad_divide_data, quad_add_data,
			  quad_intersect, quad_division_check,
			  quad_get_points)) == NULL)

	G_fatal_error(_("Unable to create %s"), "quadfunc");

    if ((tree = MT_tree_new(data, NULL, NULL, 0)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree");
    root = tree;

    if ((info = MT_tree_info_new(root, functions, dmin, KMAX)) == NULL)
	G_fatal_error(_("Unable to create %s"), "tree info");

    open_check = Vect_open_old2(&Map, input, "", parm.field->answer);
    if (open_check < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), input);
    /*    if (open_check < 2)
          G_fatal_error(_("You first need to run v.build on vector map <%s>"), input);
    */

    /* get value used for approximation */
    with_z = !parm.zcol->answer && Vect_is_3d(&Map);
    field = Vect_get_field_number(&Map, parm.field->answer);
    if (!with_z && field < 1)
	G_fatal_error(_("Layer <%s> not found"), parm.field->answer);

    if (Vect_is_3d(&Map)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (parm.zcol->answer)
            G_verbose_message(_("Input is 2D: using attribute values for approximation"));
        else
            G_verbose_message(_("Input is 2D: using category values for approximation"));
    }
        
    /* we can't read the input file's timestamp as they don't exist in   */
    /*   the new vector format. Even so, a TimeStamp structure is needed */
    /*   for IL_init_params_2d(), so we set it to NULL.                  */
    /* If anyone is ever motivated to add it, the Plus_head struct has   */
    /*  'long coor_mtime' and dig_head has 'char *date; char *source_date;' */
    /*   which could be read in.                                         */

    if (devi != NULL || cvdev != NULL) {

	Pnts = Vect_new_line_struct();
	Cats2 = Vect_new_cats_struct();
	db_init_string(&sql2);

	if (devi != NULL) {
	    if (Vect_open_new(&Map2, devi, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), devi);
	} else {
	    if (Vect_open_new(&Map2, cvdev, 1) < 0)
		G_fatal_error(_("Unable to create vector map <%s>"), cvdev);
	}
	Vect_hist_command(&Map2);
	ff = Vect_default_field_info(&Map2, 1, NULL, GV_1TABLE);
	Vect_map_add_dblink(&Map2, 1, NULL, ff->table, GV_KEY_COLUMN, ff->database,
			    ff->driver);

	/* Create new table */
	db_zero_string(&sql2);
	sprintf(buf, "create table %s ( ", ff->table);
	db_append_string(&sql2, buf);
	db_append_string(&sql2, "cat integer");
	db_append_string(&sql2, ", flt1 double precision");
	db_append_string(&sql2, ")");
	G_debug(1, "%s", db_get_string(&sql2));
	driver2 = db_start_driver_open_database(ff->driver, ff->database);
	if (driver2 == NULL)
	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
			  ff->database, ff->driver);
        db_set_error_handler_driver(driver2);

	if (db_execute_immediate(driver2, &sql2) != DB_OK) {
	    G_fatal_error(_("Unable to create table '%s'"),
			  db_get_string(&sql2));
	}
	db_begin_transaction(driver2);
	count = 1;

    }

    ertot = 0.;
    
    create_temp_files();

    IL_init_params_2d(&params, NULL, 1, 1, zmult, KMIN, KMAX, maskmap, n_rows,
		      n_cols, az, adx, ady, adxx, adyy, adxy, fi, KMAX2,
		      SCIK1, SCIK2, SCIK3, rsm, elev, slope, aspect, pcurv,
		      tcurv, mcurv, dmin, x_orig, y_orig, deriv, theta,
		      scalex, Tmp_fd_z, Tmp_fd_dx, Tmp_fd_dy, Tmp_fd_xx,
		      Tmp_fd_yy, Tmp_fd_xy, devi, NULL, cv,
		      parm.wheresql->answer);

    IL_init_func_2d(&params, IL_grid_calc_2d, IL_matrix_create,
		    IL_check_at_points_2d, IL_secpar_loop_2d, IL_crst,
		    IL_crstg, IL_write_temp_2d);

    totsegm =
	IL_vector_input_data_2d(&params, &Map, with_z ? 0 : field,
				zcol, scol,
				info, &xmin, &xmax,
				&ymin, &ymax, &zmin, &zmax, &NPOINT, &dmax);
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    /*Vect_set_release_support(&Map); */
    Vect_close(&Map);

    if (treefile != NULL) {
	if (0 > Vect_open_new(&TreeMap, treefile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to open vector map <%s>"), treefile);
	}
	Vect_hist_command(&TreeMap);

	/*
	   sprintf (TreeMap.head.your_name, "grass");
	   sprintf (TreeMap.head.map_name, "Quad tree for %s", input);
	   TreeMap.head.orig_scale = 100000;
	   TreeMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &TreeMap);
	Vect_build(&TreeMap);
	Vect_close(&TreeMap);
    }

    disk = disk + totsegm * sizeof(int) * 4;
    sdisk = sdisk + totsegm * sizeof(int) * 4;
    if (elev != NULL)
	ddisk += disk;
    if (slope != NULL)
	sddisk += sdisk;
    if (aspect != NULL)
	sddisk += sdisk;
    if (pcurv != NULL)
	ddisk += disk;
    if (tcurv != NULL)
	ddisk += disk;
    if (mcurv != NULL)
	ddisk += disk;
    ddisk += sddisk;
    G_verbose_message(_("Processing all selected output files "
			"will require %d bytes of disk space for temp files"), ddisk);

    deltx = xmax - xmin;
    delty = ymax - ymin;
    dnorm = sqrt((deltx * delty * KMIN) / NPOINT);

    if (dtens) {
	params.fi = params.fi * dnorm / 1000.;
	G_verbose_message("dnorm = %f, rescaled tension = %f", dnorm, params.fi);
    }
    
    bitmask = IL_create_bitmask(&params);
    
    if (totsegm <= 0) {
	clean();
	G_fatal_error(_("Input failed"));
    }

    ertot = 0.;
    G_message(_("Processing segments..."));    
    if (IL_interp_segments_2d(&params, info, info->root, bitmask,
			      zmin, zmax, &zminac, &zmaxac, &gmin, &gmax,
			      &c1min, &c1max, &c2min, &c2max, &ertot, totsegm,
			      n_cols, dnorm) < 0) {
	clean();
	G_fatal_error(_("Interp_segmets failed"));
    }

    G_free_vector(az);
    if (cond1) {
	G_free_vector(adx);
	G_free_vector(ady);
	if (cond2) {
	    G_free_vector(adxx);
	    G_free_vector(adyy);
	    G_free_vector(adxy);
	}
    }
    ii = IL_output_2d(&params, &cellhd, zmin, zmax, zminac, zmaxac, c1min,
		      c1max, c2min, c2max, gmin, gmax, ertot, input, dnorm,
		      dtens, 1, NPOINT);
    if (ii < 0) {
	clean();
	G_fatal_error(_("Unable to write raster maps - try to increase resolution"));
    }

    G_free(zero_array_cell);
    if (elev != NULL)
	fclose(Tmp_fd_z);
    if (slope != NULL)
	fclose(Tmp_fd_dx);
    if (aspect != NULL)
	fclose(Tmp_fd_dy);
    if (pcurv != NULL)
	fclose(Tmp_fd_xx);
    if (tcurv != NULL)
	fclose(Tmp_fd_yy);
    if (mcurv != NULL)
	fclose(Tmp_fd_xy);

    if (overfile != NULL) {
	if (0 > Vect_open_new(&OverMap, overfile, 0)) {
	    clean();
	    G_fatal_error(_("Unable to create vector map <%s>"), overfile);
	}
	Vect_hist_command(&OverMap);

	/*
	   sprintf (OverMap.head.your_name, "grass");
	   sprintf (OverMap.head.map_name, "Overlap segments for %s", input);
	   OverMap.head.orig_scale = 100000;
	   OverMap.head.plani_zone = G_zone ();
	 */
	print_tree(root, x_orig, y_orig, &OverMap);
	Vect_build(&OverMap);
	Vect_close(&OverMap);
    }

    if (elev != NULL)
	unlink(Tmp_file_z);
    if (slope != NULL)
	unlink(Tmp_file_dx);
    if (aspect != NULL)
	unlink(Tmp_file_dy);
    if (pcurv != NULL)
	unlink(Tmp_file_xx);
    if (tcurv != NULL)
	unlink(Tmp_file_yy);
    if (mcurv != NULL)
	unlink(Tmp_file_xy);

    if (cvdev != NULL || devi != NULL) {
	db_commit_transaction(driver2);
	db_close_database_shutdown_driver(driver2);
	Vect_build(&Map2);
	Vect_close(&Map2);
    }

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Exemplo n.º 13
0
Arquivo: main.c Projeto: caomw/grass
int main(int argc, char *argv[])
{
    /* Variables' declarations */
    int nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion = 0, nsubregions = 0;
    double N_extension, E_extension, edgeE, edgeN;
    int dim_vect, nparameters, BW, npoints;
    double lambda_B, lambda_F, grad_H, grad_L, alpha, mean;
    const char *dvr, *db, *mapset;
    char table_interpolation[GNAME_MAX], table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int last_row, last_column, flag_auxiliar = FALSE;

    int *lineVect;
    double *TN, *Q, *parVect_bilin, *parVect_bicub;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    /* Structs' declarations */
    struct Map_info In, Out;
    struct Option *in_opt, *out_opt, *stepE_opt, *stepN_opt,
	*lambdaF_opt, *lambdaB_opt, *gradH_opt, *gradL_opt, *alfa_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

    struct Cell_head elaboration_reg, original_reg;
    struct Reg_dimens dims;
    struct bound_box general_box, overlap_box;

    struct Point *observ;

    dbDriver *driver;

/*------------------------------------------------------------------------------------------*/
    /* Options' declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    G_add_keyword(_("edges"));
    module->description =
	_("Detects the object's edges from a LIDAR data set.");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
	_("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    stepE_opt = G_define_option();
    stepE_opt->key = "see";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "4";
    stepE_opt->description =
	_("Interpolation spline step value in east direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "sen";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "4";
    stepN_opt->description =
	_("Interpolation spline step value in north direction");
    stepN_opt->guisection = _("Settings");

    lambdaB_opt = G_define_option();
    lambdaB_opt->key = "lambda_g";
    lambdaB_opt->type = TYPE_DOUBLE;
    lambdaB_opt->required = NO;
    lambdaB_opt->description =
	_("Regularization weight in gradient evaluation");
    lambdaB_opt->answer = "0.01";
    lambdaB_opt->guisection = _("Settings");

    gradH_opt = G_define_option();
    gradH_opt->key = "tgh";
    gradH_opt->type = TYPE_DOUBLE;
    gradH_opt->required = NO;
    gradH_opt->description =
	_("High gradient threshold for edge classification");
    gradH_opt->answer = "6";
    gradH_opt->guisection = _("Settings");

    gradL_opt = G_define_option();
    gradL_opt->key = "tgl";
    gradL_opt->type = TYPE_DOUBLE;
    gradL_opt->required = NO;
    gradL_opt->description =
	_("Low gradient threshold for edge classification");
    gradL_opt->answer = "3";
    gradL_opt->guisection = _("Settings");

    alfa_opt = G_define_option();
    alfa_opt->key = "theta_g";
    alfa_opt->type = TYPE_DOUBLE;
    alfa_opt->required = NO;
    alfa_opt->description = _("Angle range for same direction detection");
    alfa_opt->answer = "0.26";
    alfa_opt->guisection = _("Settings");

    lambdaF_opt = G_define_option();
    lambdaF_opt->key = "lambda_r";
    lambdaF_opt->type = TYPE_DOUBLE;
    lambdaF_opt->required = NO;
    lambdaF_opt->description =
	_("Regularization weight in residual evaluation");
    lambdaF_opt->answer = "2";
    lambdaF_opt->guisection = _("Settings");

    /* Parsing */
    G_gisinit(argv[0]);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    line_out_counter = 1;
    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda_F = atof(lambdaF_opt->answer);
    lambda_B = atof(lambdaB_opt->answer);
    grad_H = atof(gradH_opt->answer);
    grad_L = atof(gradL_opt->answer);
    alpha = atof(alfa_opt->answer);

    grad_L = grad_L * grad_L;
    grad_H = grad_H * grad_H;

    if (!(db = G__getenv2("DB_DATABASE", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of database"));

    if (!(dvr = G__getenv2("DB_DRIVER", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of driver"));

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_aux", xname);
	sprintf(table_interpolation, "%s_edge_Interpolation", xname);
    }
    else {
	sprintf(table_name, "%s_aux", out_opt->answer);
	sprintf(table_interpolation, "%s_edge_Interpolation", out_opt->answer);
    }

    /* Something went wrong in a previous v.lidar.edgedetection execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Something went wrong in a previous v.lidar.edgedetection execution */
    if (db_table_exists(dvr, db, table_interpolation)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
	if (P_Drop_Aux_Table(driver, table_interpolation) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Checking vector names */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 G_FATAL_EXIT);

    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
    }

    Vect_set_open_level(1);
    /* Open input vector */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    /* Input vector must be 3D */
    if (!Vect_is_3d(&In))
	G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer);

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
	double dens, dist;
	if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
	    G_message("Estimated point density: %.4g", dens);
	    G_message("Estimated mean distance between points: %.4g", dist);
	}
	else
	    G_warning(_("No points in current region!"));
	
	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }

    /* Open output vector */
    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z))
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* Start driver and open db */
    driver = db_start_driver_open_database(dvr, db);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      dvr);
    db_set_error_handler_driver(driver);

    /* Create auxiliar and interpolation table */
    if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE)
	G_fatal_error(_("It was impossible to create <%s>."), table_name);

    if (P_Create_Aux2_Table(driver, table_interpolation) == FALSE)
	G_fatal_error(_("It was impossible to create <%s> interpolation table in database."),
		      out_opt->answer);

    db_create_index2(driver, table_name, "ID");
    db_create_index2(driver, table_interpolation, "ID");
    /* sqlite likes that ??? */
    db_close_database_shutdown_driver(driver);
    driver = db_start_driver_open_database(dvr, db);

    /* Setting regions and boxes */
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    /*------------------------------------------------------------------
      | Subdividing and working with tiles: 									
      | Each original region will be divided into several subregions. 
      | Each one will be overlaped by its neighbouring subregions. 
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
	dims.overlap = OVERLAP_SIZE * stepN;
    else
	dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(P_BICUBIC, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each row */

	P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
		      GENERAL_ROW);

	if (elaboration_reg.north > original_reg.north) {	/* First row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

	nsply =
	    ceil((elaboration_reg.north - elaboration_reg.south) / stepN) +
	    0.5;
	/*
	if (nsply > NSPLY_MAX) {
	    nsply = NSPLY_MAX;
	}
	*/
	G_debug(1, "nsply = %d", nsply);

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each column */

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  GENERAL_COLUMN);

	    if (elaboration_reg.west < original_reg.west) {	/* First column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }

	    nsplx =
		ceil((elaboration_reg.east - elaboration_reg.west) / stepE) +
		0.5;
	    /*
	    if (nsplx > NSPLX_MAX) {
		nsplx = NSPLX_MAX;
	    }
	    */
	    G_debug(1, "nsplx = %d", nsplx);

	    /*Setting the active region */
	    dim_vect = nsplx * nsply;
	    G_debug(1, "read vector region map");
	    observ =
		P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
					 dim_vect, 1);

	    if (npoints > 0) {	/* If there is any point falling into elaboration_reg... */
		int i, tn;

		nparameters = nsplx * nsply;

		/* Mean's calculation */
		mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

		/* Least Squares system */
		G_debug(1, _("Allocating memory for bilinear interpolation"));
		BW = P_get_BandWidth(P_BILINEAR, nsply);	/* Bilinear interpolation */
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		TN = G_alloc_vector(nparameters);	/* vector */
		parVect_bilin = G_alloc_vector(nparameters);	/* Bilinear parameters vector */
		obsVect = G_alloc_matrix(npoints + 1, 3);	/* Observation vector */
		Q = G_alloc_vector(npoints + 1);	/* "a priori" var-cov matrix */

		lineVect = G_alloc_ivector(npoints + 1);

		/* Setting obsVect vector & Q matrix */
		for (i = 0; i < npoints; i++) {
		    obsVect[i][0] = observ[i].coordX;
		    obsVect[i][1] = observ[i].coordY;
		    obsVect[i][2] = observ[i].coordZ - mean;
		    lineVect[i] = observ[i].lineID;
		    Q[i] = 1;	/* Q=I */
		}

		G_free(observ);

		G_verbose_message(_("Bilinear interpolation"));
		normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
			       nsply, elaboration_reg.west,
			       elaboration_reg.south, npoints, nparameters,
			       BW);
		nCorrectGrad(N, lambda_B, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect_bilin, TN, nparameters, BW);

		G_free_matrix(N);
		for (tn = 0; tn < nparameters; tn++)
		    TN[tn] = 0;

		G_debug(1, _("Allocating memory for bicubic interpolation"));
		BW = P_get_BandWidth(P_BICUBIC, nsply);
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		parVect_bicub = G_alloc_vector(nparameters);	/* Bicubic parameters vector */

		G_verbose_message(_("Bicubic interpolation"));
		normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
				 nsply, elaboration_reg.west,
				 elaboration_reg.south, npoints, nparameters,
				 BW);
		nCorrectLapl(N, lambda_F, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect_bicub, TN, nparameters, BW);

		G_free_matrix(N);
		G_free_vector(TN);
		G_free_vector(Q);

		G_verbose_message(_("Point classification"));
		classification(&Out, elaboration_reg, general_box,
			       overlap_box, obsVect, parVect_bilin,
			       parVect_bicub, mean, alpha, grad_H, grad_L,
			       dims.overlap, lineVect, npoints, driver,
			       table_interpolation, table_name);

		G_free_vector(parVect_bilin);
		G_free_vector(parVect_bicub);
		G_free_matrix(obsVect);
		G_free_ivector(lineVect);
	    }			/* IF */
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider changing the spline step."));
	    }
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    /* Dropping auxiliar table */
    if (npoints > 0) {
	G_debug(1, _("Dropping <%s>"), table_name);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_warning(_("Auxiliar table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);

    Vect_map_add_dblink(&Out, F_INTERPOLATION, NULL, table_interpolation,
			"id", db, dvr);

    Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*!END MAIN */
Exemplo n.º 14
0
static int 
ludcmp(double **a,int n,int *indx,double *d)
{
    int i,imax,j,k;
    double big,dum,sum,temp;
    double *vv,*G_alloc_vector();
    double fabs();

    vv=G_alloc_vector(n);
    *d=1.0;
    for (i=0;i<n;i++) 
    {
        big=0.0;
        for (j=0;j<n;j++)
            if ((temp=fabs(a[i][j])) > big)
                big=temp;
        if (big == 0.0)
            return 0; /* Singular matrix  */
        vv[i]=1.0/big;
    }
    
    int f,g;
    
    for (j=0;j<n;j++) 
    {   
        for (i=0;i<j;i++) 
        {
            sum=a[i][j];
            for (k=0;k<i;k++)
                sum -= a[i][k]*a[k][j];
            a[i][j]=sum;
        }
        
        /*
        printf("\n\nMatrix After Step 1:\n");
        for(f=0; f<n; f++) {
            for(g=0; g<n; g++) {
                printf("%.2f ",a[f][g]);
            }
            printf("\n");
        }*/
        
        big=0.0;
        dum=0.0;
        for (i=j;i<n;i++) 
        {
            sum=a[i][j];
            for (k=0;k<j;k++)
                sum -= a[i][k]*a[k][j];
            a[i][j]=sum;
            dum=vv[i]*fabs(sum);
            //printf("sum: %f, dum: %f, big: %f\n",sum,dum,big);
            //printf("dum-big: %E\n",dum-big);
            //if(dum >= big)
            if ( (dum-big) >= 0.0 || fabs(dum-big) < 1e-3) 
            {
                big=dum;
                imax=i;
                //printf("imax: %d\n",imax);
            }
        }
        
        if (j != imax) 
        {
            for (k=0;k<n;k++) 
            {
                dum=a[imax][k];
                a[imax][k]=a[j][k];
                a[j][k]=dum;
            }
            *d = -(*d);
            vv[imax]=vv[j];
        }
        indx[j]=imax;
        
        /*
        printf("\n\nMatrix after %dth iteration of LU decomposition:\n",j);
        for(f=0; f<n; f++) {
            for(g=0; g<n; g++) {
                printf("%.2f ",a[f][g]);
            }
            printf("\n");
        }
        printf("imax: %d\n",imax);
        */

        /* Change made 3/27/98 for robustness */
        if ( (a[j][j]>=0)&&(a[j][j]<TINY) ) a[j][j]= TINY;
        if ( (a[j][j]<0)&&(a[j][j]>-TINY) ) a[j][j]= -TINY;

        if (j != n-1) 
        {
            dum=1.0/(a[j][j]);
            for (i=j+1;i<n;i++)
                a[i][j] *= dum;
        }
    }
    G_free_vector (vv);
    return(1);
}
Exemplo n.º 15
0
/*!
 * \brief Creates system of linear equations from interpolated points
 *
 * Creates system of linear equations represented by matrix using given
 * points and interpolating function interp()
 *
 * \param params struct interp_params *
 * \param points points for interpolation as struct triple
 * \param n_points number of points
 * \param[out] matrix the matrix
 * \param indx
 *
 * \return -1 on failure, 1 on success
 */
int IL_matrix_create(struct interp_params *params,
		     struct triple *points,	/* points for interpolation */
		     int n_points,	/* number of points */
		     double **matrix,	/* matrix */
		     int *indx)
{
    double xx, yy;
    double rfsta2, r;
    double d;
    int n1, k1, k2, k, i1, l, m, i, j;
    double fstar2 = params->fi * params->fi / 4.;
    static double *A = NULL;
    double RO, amaxa;
    double rsin = 0, rcos = 0, teta, scale = 0;	/*anisotropy parameters - added by JH 2002 */
    double xxr, yyr;

    if (params->theta) {
	teta = params->theta * (M_PI / 180);	/* deg to rad */
	rsin = sin(teta);
	rcos = cos(teta);
    }
    if (params->scalex)
	scale = params->scalex;


    n1 = n_points + 1;

    if (!A) {
	if (!
	    (A =
	     G_alloc_vector((params->KMAX2 + 2) * (params->KMAX2 + 2) + 1))) {
	    fprintf(stderr, "Cannot allocate memory for A\n");
	    return -1;
	}
    }

    /*
       C      GENERATION OF MATRIX
       C      FIRST COLUMN
     */
    A[1] = 0.;
    for (k = 1; k <= n_points; k++) {
	i1 = k + 1;
	A[i1] = 1.;
    }
    /*
       C      OTHER COLUMNS
     */
    RO = -params->rsm;
    /* fprintf (stderr, "sm[%d] = %f,  ro=%f\n", 1, points[1].smooth, RO); */
    for (k = 1; k <= n_points; k++) {
	k1 = k * n1 + 1;
	k2 = k + 1;
	i1 = k1 + k;
	if (params->rsm < 0.) {	/*indicates variable smoothing */
	    A[i1] = -points[k - 1].sm;	/* added by Mitasova nov. 96 */
	    /* G_debug(5, "sm[%d]=%f, a=%f", k, points[k-1].sm, A[i1]); */
	}
	else {
	    A[i1] = RO;		/* constant smoothing */
	}
	/* if (i1 == 100) fprintf (stderr,i "A[%d] = %f\n", i1, A[i1]); */

	/* A[i1] = RO; */
	for (l = k2; l <= n_points; l++) {
	    xx = points[k - 1].x - points[l - 1].x;
	    yy = points[k - 1].y - points[l - 1].y;

	    if ((params->theta) && (params->scalex)) {
		/* re run anisotropy */
		xxr = xx * rcos + yy * rsin;
		yyr = yy * rcos - xx * rsin;
		xx = xxr;
		yy = yyr;
		r = scale * xx * xx + yy * yy;
		rfsta2 = fstar2 * (scale * xx * xx + yy * yy);
	    }
	    else {
		r = xx * xx + yy * yy;
		rfsta2 = fstar2 * (xx * xx + yy * yy);
	    }

	    if (rfsta2 == 0.) {
		fprintf(stderr, "ident. points in segm.\n");
		fprintf(stderr, "x[%d]=%f, x[%d]=%f, y[%d]=%f, y[%d]=%f\n",
			k - 1, points[k - 1].x, l - 1, points[l - 1].x, k - 1,
			points[k - 1].y, l - 1, points[l - 1].y);
		return -1;
	    }
	    i1 = k1 + l;
	    A[i1] = params->interp(r, params->fi);
	}
    }

    /* C       SYMMETRISATION */
    amaxa = 1.;
    for (k = 1; k <= n1; k++) {
	k1 = (k - 1) * n1;
	k2 = k + 1;
	for (l = k2; l <= n1; l++) {
	    m = (l - 1) * n1 + k;
	    A[m] = A[k1 + l];
	    amaxa = amax1(A[m], amaxa);
	}
    }
    m = 0;
    for (i = 0; i <= n_points; i++) {
	for (j = 0; j <= n_points; j++) {
	    m++;
	    matrix[i][j] = A[m];
	}
    }

    G_debug(3, "calling G_ludcmp()  n=%d indx=%d", n_points, *indx);
    if (G_ludcmp(matrix, n_points + 1, indx, &d) <= 0) {
	/* find the inverse of the matrix */
	fprintf(stderr, "G_ludcmp() failed! n=%d  d=%.2f\n", n_points, d);
	return -1;
    }

    /* G_free_vector(A); */
    return 1;
}
Exemplo n.º 16
0
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variables declarations */
    int nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    double N_extension, E_extension, edgeE, edgeN;
    int dim_vect, nparameters, BW, npoints;
    double mean, lambda;
    const char *dvr, *db, *mapset;
    char table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int last_row, last_column, flag_auxiliar = FALSE;
    int filter_mode;

    int *lineVect;
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    /* Structs declarations */
    struct Map_info In, Out, Outlier, Qgis;
    struct Option *in_opt, *out_opt, *outlier_opt, *qgis_opt, *stepE_opt,
	*stepN_opt, *lambda_f_opt, *Thres_O_opt, *filter_opt;
    struct Flag *spline_step_flag;
    struct GModule *module;

    struct Reg_dimens dims;
    struct Cell_head elaboration_reg, original_reg;
    struct bound_box general_box, overlap_box;

    struct Point *observ;

    dbDriver *driver;

    /*----------------------------------------------------------------*/
    /* Options declaration */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("extract"));
    G_add_keyword(_("select"));
    G_add_keyword(_("filter"));
    module->description = _("Removes outliers from vector point data.");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
	_("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    outlier_opt = G_define_option();
    outlier_opt->key = "outlier";
    outlier_opt->type = TYPE_STRING;
    outlier_opt->key_desc = "name";
    outlier_opt->required = YES;
    outlier_opt->gisprompt = "new,vector,vector";
    outlier_opt->description = _("Name of output outlier vector map");

    qgis_opt = G_define_option();
    qgis_opt->key = "qgis";
    qgis_opt->type = TYPE_STRING;
    qgis_opt->key_desc = "name";
    qgis_opt->required = NO;
    qgis_opt->gisprompt = "new,vector,vector";
    qgis_opt->description = _("Name of vector map for visualization in QGIS");

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "10";
    stepE_opt->description =
	_("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "10";
    stepN_opt->description =
	_("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization weight");
    lambda_f_opt->answer = "0.1";
    lambda_f_opt->guisection = _("Settings");

    Thres_O_opt = G_define_option();
    Thres_O_opt->key = "threshold";
    Thres_O_opt->type = TYPE_DOUBLE;
    Thres_O_opt->required = NO;
    Thres_O_opt->description = _("Threshold for the outliers");
    Thres_O_opt->answer = "50";

    filter_opt = G_define_option();
    filter_opt->key = "filter";
    filter_opt->type = TYPE_STRING;
    filter_opt->required = NO;
    filter_opt->description = _("Filtering option");
    filter_opt->options = "both,positive,negative";
    filter_opt->answer = "both";

    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of database"));

    if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET)))
	G_fatal_error(_("Unable to read name of driver"));

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);
    Thres_Outlier = atof(Thres_O_opt->answer);

    filter_mode = 0;
    if (strcmp(filter_opt->answer, "positive") == 0)
	filter_mode = 1;
    else if (strcmp(filter_opt->answer, "negative") == 0)
	filter_mode = -1;
    P_set_outlier_fn(filter_mode);

    flag_auxiliar = FALSE;

    /* Checking vector names */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 G_FATAL_EXIT);

    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
    }

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_aux", xname);
    }
    else
	sprintf(table_name, "%s_aux", out_opt->answer);

    /* Something went wrong in a previous v.outlier execution */
    if (db_table_exists(dvr, db, table_name)) {
	/* Start driver and open db */
	driver = db_start_driver_open_database(dvr, db);
	if (driver == NULL)
	    G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
			  dvr);
        db_set_error_handler_driver(driver);

	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Old auxiliar table could not be dropped"));
	db_close_database_shutdown_driver(driver);
    }

    /* Open input vector */
    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
	G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
		      in_opt->answer);

    /* Input vector must be 3D */
    if (!Vect_is_3d(&In))
	G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer);

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
	double dens, dist;
	if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
	    G_message("Estimated point density: %.4g", dens);
	    G_message("Estimated mean distance between points: %.4g", dist);
	}
	else
	    G_warning(_("No points in current region!"));
	
	Vect_close(&In);
	exit(EXIT_SUCCESS);
    }

    /* Open output vector */
    if (qgis_opt->answer)
	if (0 > Vect_open_new(&Qgis, qgis_opt->answer, WITHOUT_Z))
	    G_fatal_error(_("Unable to create vector map <%s>"),
			  qgis_opt->answer);

    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) {
	Vect_close(&Qgis);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    if (0 > Vect_open_new(&Outlier, outlier_opt->answer, WITH_Z)) {
	Vect_close(&Out);
	Vect_close(&Qgis);
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);
    }

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    Vect_copy_head_data(&In, &Outlier);
    Vect_hist_copy(&In, &Outlier);
    Vect_hist_command(&Outlier);

    if (qgis_opt->answer) {
	Vect_copy_head_data(&In, &Qgis);
	Vect_hist_copy(&In, &Qgis);
	Vect_hist_command(&Qgis);
    }

    /* Open driver and database */
    driver = db_start_driver_open_database(dvr, db);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      dvr);
    db_set_error_handler_driver(driver);

    /* Create auxiliar table */
    if ((flag_auxiliar =
	 P_Create_Aux2_Table(driver, table_name)) == FALSE)
	G_fatal_error(_("It was impossible to create <%s> table."), table_name);

    db_create_index2(driver, table_name, "ID");
    /* sqlite likes that ??? */
    db_close_database_shutdown_driver(driver);
    driver = db_start_driver_open_database(dvr, db);

    /* Setting regions and boxes */
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    /*------------------------------------------------------------------
      | Subdividing and working with tiles: 									
      | Each original region will be divided into several subregions. 
      | Each one will be overlaped by its neighbouring subregions. 
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);		/* Set dim struct to zero */

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
	dims.overlap = OVERLAP_SIZE * stepN;
    else
	dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(P_BILINEAR, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("Adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each row */

	P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
		      GENERAL_ROW);

	if (elaboration_reg.north > original_reg.north) {	/* First row */

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  FIRST_ROW);
	}

	if (elaboration_reg.south <= original_reg.south) {	/* Last row */

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  LAST_ROW);
	    last_row = TRUE;
	}

	nsply =
	    ceil((elaboration_reg.north -
		  elaboration_reg.south) / stepN) + 0.5;
	/*
	if (nsply > NSPLY_MAX)
	    nsply = NSPLY_MAX;
	*/
	G_debug(1, "nsply = %d", nsply);

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each column */

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);
	    else /* v.outlier -e will report mean point distance: */
		G_warning(_("No subregions found! Check values for 'ew_step' and 'ns_step' parameters"));

	    P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
			  GENERAL_COLUMN);

	    if (elaboration_reg.west < original_reg.west) {	/* First column */

		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, FIRST_COLUMN);
	    }

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */

		P_set_regions(&elaboration_reg, &general_box, &overlap_box,
			      dims, LAST_COLUMN);
		last_column = TRUE;
	    }
	    nsplx =
		ceil((elaboration_reg.east -
		      elaboration_reg.west) / stepE) + 0.5;
	    /*
	    if (nsplx > NSPLX_MAX)
		nsplx = NSPLX_MAX;
	    */
	    G_debug(1, "nsplx = %d", nsplx);

	    /*Setting the active region */
	    dim_vect = nsplx * nsply;
	    observ =
		P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
					 dim_vect, 1);

	    if (npoints > 0) {	/* If there is any point falling into elaboration_reg... */
		int i;

		nparameters = nsplx * nsply;

		/* Mean calculation */
		mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

		/* Least Squares system */
		G_debug(1, "Allocation memory for bilinear interpolation");
		BW = P_get_BandWidth(P_BILINEAR, nsply);	/* Bilinear interpolation */
		N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
		TN = G_alloc_vector(nparameters);	/* vector */
		parVect = G_alloc_vector(nparameters);	/* Bicubic parameters vector */
		obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
		Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
		lineVect = G_alloc_ivector(npoints);

		/* Setting obsVect vector & Q matrix */
		for (i = 0; i < npoints; i++) {
		    obsVect[i][0] = observ[i].coordX;
		    obsVect[i][1] = observ[i].coordY;
		    obsVect[i][2] = observ[i].coordZ - mean;
		    lineVect[i] = observ[i].lineID;
		    Q[i] = 1;	/* Q=I */
		}

		G_free(observ);

		G_verbose_message(_("Bilinear interpolation"));
		normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
			       nsply, elaboration_reg.west,
			       elaboration_reg.south, npoints, nparameters,
			       BW);
		nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
		G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);

		G_free_matrix(N);
		G_free_vector(TN);
		G_free_vector(Q);

		G_verbose_message(_("Outlier detection"));
		if (qgis_opt->answer)
		    P_Outlier(&Out, &Outlier, &Qgis, elaboration_reg,
			      general_box, overlap_box, obsVect, parVect,
			      mean, dims.overlap, lineVect, npoints,
			      driver, table_name);
		else
		    P_Outlier(&Out, &Outlier, NULL, elaboration_reg,
			      general_box, overlap_box, obsVect, parVect,
			      mean, dims.overlap, lineVect, npoints,
			      driver, table_name);


		G_free_vector(parVect);
		G_free_matrix(obsVect);
		G_free_ivector(lineVect);

	    }			/*! END IF; npoints > 0 */
	    else {
		G_free(observ);
		G_warning(_("No data within this subregion. "
			    "Consider increasing spline step values."));
	    }
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    /* Drop auxiliar table */
    if (npoints > 0) {
	G_debug(1, "%s: Dropping <%s>", argv[0], table_name);
	if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
	    G_fatal_error(_("Auxiliary table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    Vect_close(&Out);
    Vect_close(&Outlier);
    if (qgis_opt->answer) {
	Vect_build(&Qgis);
	Vect_close(&Qgis);
    }

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
Exemplo n.º 17
0
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* Variable declarations */
    int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj;
    int nsubregion_col, nsubregion_row, subregion_row, subregion_col;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross;	/* booleans */
    double stepN, stepE, lambda, mean;
    double N_extension, E_extension, edgeE, edgeN;

    const char *mapset, *drv, *db, *vector, *map;
    char table_name[GNAME_MAX], title[64];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int dim_vect, nparameters, BW;
    int *lineVect;		/* Vector restoring primitive's ID */
    double *TN, *Q, *parVect;	/* Interpolating and least-square vectors */
    double **N, **obsVect;	/* Interpolation and least-square matrix */

    SEGMENT out_seg, mask_seg;
    const char *out_file, *mask_file;
    int out_fd, mask_fd;
    double seg_size;
    int seg_mb, segments_in_memory;
    int have_mask;

    /* Structs declarations */
    int raster;
    struct Map_info In, In_ext, Out;
    struct History history;

    struct GModule *module;
    struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt,
               *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt,
               *memory_opt, *solver, *error, *iter;
    struct Flag *cross_corr_flag, *spline_step_flag;

    struct Reg_dimens dims;
    struct Cell_head elaboration_reg, original_reg;
    struct bound_box general_box, overlap_box, original_box;

    struct Point *observ;
    struct line_cats *Cats;
    dbCatValArray cvarr;

    int with_z;
    int nrec, ctype = 0;
    struct field_info *Fi;
    dbDriver *driver, *driver_cats;

    /*----------------------------------------------------------------*/
    /* Options declarations */
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("surface"));
    G_add_keyword(_("interpolation"));
    G_add_keyword(_("LIDAR"));
    module->description =
        _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization.");

    cross_corr_flag = G_define_flag();
    cross_corr_flag->key = 'c';
    cross_corr_flag->description =
        _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method");

    spline_step_flag = G_define_flag();
    spline_step_flag->key = 'e';
    spline_step_flag->label = _("Estimate point density and distance");
    spline_step_flag->description =
        _("Estimate point density and distance for the input vector points within the current region extends and quit");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->label = _("Name of input vector point map");

    dfield_opt = G_define_standard_option(G_OPT_V_FIELD);
    dfield_opt->guisection = _("Settings");

    col_opt = G_define_standard_option(G_OPT_DB_COLUMN);
    col_opt->required = NO;
    col_opt->label =
        _("Name of the attribute column with values to be used for approximation");
    col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used.");
    col_opt->guisection = _("Settings");

    in_ext_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_ext_opt->key = "sparse_input";
    in_ext_opt->required = NO;
    in_ext_opt->label =
        _("Name of input vector map with sparse points");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);
    out_opt->required = NO;
    out_opt->guisection = _("Outputs");

    out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    out_map_opt->key = "raster_output";
    out_map_opt->required = NO;
    out_map_opt->guisection = _("Outputs");

    mask_opt = G_define_standard_option(G_OPT_R_INPUT);
    mask_opt->key = "mask";
    mask_opt->label = _("Raster map to use for masking (applies to raster output only)");
    mask_opt->description = _("Only cells that are not NULL and not zero are interpolated");
    mask_opt->required = NO;

    stepE_opt = G_define_option();
    stepE_opt->key = "ew_step";
    stepE_opt->type = TYPE_DOUBLE;
    stepE_opt->required = NO;
    stepE_opt->answer = "4";
    stepE_opt->description =
        _("Length of each spline step in the east-west direction");
    stepE_opt->guisection = _("Settings");

    stepN_opt = G_define_option();
    stepN_opt->key = "ns_step";
    stepN_opt->type = TYPE_DOUBLE;
    stepN_opt->required = NO;
    stepN_opt->answer = "4";
    stepN_opt->description =
        _("Length of each spline step in the north-south direction");
    stepN_opt->guisection = _("Settings");

    type_opt = G_define_option();
    type_opt->key = "method";
    type_opt->description = _("Spline interpolation algorithm");
    type_opt->type = TYPE_STRING;
    type_opt->options = "bilinear,bicubic";
    type_opt->answer = "bilinear";
    type_opt->guisection = _("Settings");
    G_asprintf((char **) &(type_opt->descriptions),
               "bilinear;%s;bicubic;%s",
               _("Bilinear interpolation"),
               _("Bicubic interpolation"));

    lambda_f_opt = G_define_option();
    lambda_f_opt->key = "lambda_i";
    lambda_f_opt->type = TYPE_DOUBLE;
    lambda_f_opt->required = NO;
    lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)");
    lambda_f_opt->answer = "0.01";
    lambda_f_opt->guisection = _("Settings");

    solver = N_define_standard_option(N_OPT_SOLVER_SYMM);
    solver->options = "cholesky,cg";
    solver->answer = "cholesky";

    iter = N_define_standard_option(N_OPT_MAX_ITERATIONS);

    error = N_define_standard_option(N_OPT_ITERATION_ERROR);

    memory_opt = G_define_option();
    memory_opt->key = "memory";
    memory_opt->type = TYPE_INTEGER;
    memory_opt->required = NO;
    memory_opt->answer = "300";
    memory_opt->label = _("Maximum memory to be used (in MB)");
    memory_opt->description = _("Cache size for raster rows");

    /*----------------------------------------------------------------*/
    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
        exit(EXIT_FAILURE);

    vector = out_opt->answer;
    map = out_map_opt->answer;

    if (vector && map)
        G_fatal_error(_("Choose either vector or raster output, not both"));

    if (!vector && !map && !cross_corr_flag->answer)
        G_fatal_error(_("No raster or vector or cross-validation output"));

    if (!strcmp(type_opt->answer, "linear"))
        bilin = P_BILINEAR;
    else
        bilin = P_BICUBIC;

    stepN = atof(stepN_opt->answer);
    stepE = atof(stepE_opt->answer);
    lambda = atof(lambda_f_opt->answer);

    flag_auxiliar = FALSE;

    drv = db_get_default_driver_name();
    if (!drv) {
        if (db_set_default_connection() != DB_OK)
            G_fatal_error(_("Unable to set default DB connection"));
        drv = db_get_default_driver_name();
    }
    db = db_get_default_database_name();
    if (!db)
        G_fatal_error(_("No default DB defined"));

    /* Set auxiliary table's name */
    if (vector) {
        if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) {
            sprintf(table_name, "%s_aux", xname);
        }
        else
            sprintf(table_name, "%s_aux", out_opt->answer);
    }

    /* Something went wrong in a previous v.surf.bspline execution */
    if (db_table_exists(drv, db, table_name)) {
        /* Start driver and open db */
        driver = db_start_driver_open_database(drv, db);
        if (driver == NULL)
            G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
                          drv);
        db_set_error_handler_driver(driver);

        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Old auxiliary table could not be dropped"));
        db_close_database_shutdown_driver(driver);
    }

    /* Open input vector */
    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL)
        G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (1 > Vect_open_old(&In, in_opt->answer, mapset))
        G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                      in_opt->answer);

    bspline_field = 0; /* assume 3D input */
    bspline_column = col_opt->answer;

    with_z = !bspline_column && Vect_is_3d(&In);

    if (Vect_is_3d(&In)) {
        if (!with_z)
            G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation"));
        else
            G_verbose_message(_("Input is 3D: using z-coordinates for approximation"));
    }
    else { /* 2D */
        if (!bspline_column)
            G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key);
    }

    if (!with_z) {
        bspline_field = Vect_get_field_number(&In, dfield_opt->answer);
    }

    /* Estimate point density and mean distance for current region */
    if (spline_step_flag->answer) {
        double dens, dist;
        if (P_estimate_splinestep(&In, &dens, &dist) == 0) {
            fprintf(stdout, _("Estimated point density: %.4g"), dens);
            fprintf(stdout, _("Estimated mean distance between points: %.4g"), dist);
        }
        else {
            fprintf(stdout, _("No points in current region"));
        }

        Vect_close(&In);
        exit(EXIT_SUCCESS);
    }

    /*----------------------------------------------------------------*/
    /* Cross-correlation begins */
    if (cross_corr_flag->answer) {
        G_debug(1, "CrossCorrelation()");
        cross = cross_correlation(&In, stepE, stepN);

        if (cross != TRUE)
            G_fatal_error(_("Cross validation didn't finish correctly"));
        else {
            G_debug(1, "Cross validation finished correctly");

            Vect_close(&In);

            G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN);
            exit(EXIT_SUCCESS);
        }
    }

    /* Open input ext vector */
    ext = FALSE;
    if (in_ext_opt->answer) {
        ext = TRUE;
        G_message(_("Vector map <%s> of sparse points will be interpolated"),
                  in_ext_opt->answer);

        if ((mapset = G_find_vector2(in_ext_opt->answer, "")) == NULL)
            G_fatal_error(_("Vector map <%s> not found"), in_ext_opt->answer);

        Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
        if (1 > Vect_open_old(&In_ext, in_ext_opt->answer, mapset))
            G_fatal_error(_("Unable to open vector map <%s> at the topological level"),
                          in_opt->answer);
    }

    /* Open output map */
    /* vector output */
    if (vector && !map) {
        if (strcmp(drv, "dbf") == 0)
            G_fatal_error(_("Sorry, the <%s> driver is not compatible with "
                            "the vector output of this module. "
                            "Try with raster output or another driver."), drv);

        Vect_check_input_output_name(in_opt->answer, out_opt->answer,
                                     G_FATAL_EXIT);
        grid = FALSE;

        if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z))
            G_fatal_error(_("Unable to create vector map <%s>"),
                          out_opt->answer);

        /* Copy vector Head File */
        if (ext == FALSE) {
            Vect_copy_head_data(&In, &Out);
            Vect_hist_copy(&In, &Out);
        }
        else {
            Vect_copy_head_data(&In_ext, &Out);
            Vect_hist_copy(&In_ext, &Out);
        }
        Vect_hist_command(&Out);

        G_verbose_message(_("Points in input vector map <%s> will be interpolated"),
                          vector);
    }


    /* read z values from attribute table */
    if (bspline_field > 0) {
        G_message(_("Reading values from attribute table..."));
        db_CatValArray_init(&cvarr);
        Fi = Vect_get_field(&In, bspline_field);
        if (Fi == NULL)
            G_fatal_error(_("Cannot read layer info"));

        driver_cats = db_start_driver_open_database(Fi->driver, Fi->database);
        /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */

        if (driver_cats == NULL)
            G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
                          Fi->database, Fi->driver);
        db_set_error_handler_driver(driver_cats);

        nrec =
            db_select_CatValArray(driver_cats, Fi->table, Fi->key,
                                  col_opt->answer, NULL, &cvarr);
        G_debug(3, "nrec = %d", nrec);

        ctype = cvarr.ctype;
        if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
            G_fatal_error(_("Column type not supported"));

        if (nrec < 0)
            G_fatal_error(_("Unable to select data from table"));

        G_verbose_message(_("%d records selected from table"), nrec);

        db_close_database_shutdown_driver(driver_cats);
    }

    /*----------------------------------------------------------------*/
    /* Interpolation begins */
    G_debug(1, "Interpolation()");

    /* Open driver and database */
    driver = db_start_driver_open_database(drv, db);
    if (driver == NULL)
        G_fatal_error(_("No database connection for driver <%s> is defined. "
                        "Run db.connect."), drv);
    db_set_error_handler_driver(driver);

    /* Create auxiliary table */
    if (vector) {
        if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) {
            P_Drop_Aux_Table(driver, table_name);
            G_fatal_error(_("Interpolation: Creating table: "
                            "It was impossible to create table <%s>."),
                          table_name);
        }
        /* db_create_index2(driver, table_name, "ID"); */
        /* sqlite likes that ??? */
        db_close_database_shutdown_driver(driver);
        driver = db_start_driver_open_database(drv, db);
    }

    /* raster output */
    raster = -1;
    Rast_set_fp_type(DCELL_TYPE);
    if (!vector && map) {
        grid = TRUE;
        raster = Rast_open_fp_new(out_map_opt->answer);

        G_verbose_message(_("Cells for raster map <%s> will be interpolated"),
                          map);
    }

    /* Setting regions and boxes */
    G_debug(1, "Interpolation: Setting regions and boxes");
    G_get_window(&original_reg);
    G_get_window(&elaboration_reg);
    Vect_region_box(&original_reg, &original_box);
    Vect_region_box(&elaboration_reg, &overlap_box);
    Vect_region_box(&elaboration_reg, &general_box);

    nrows = Rast_window_rows();
    ncols = Rast_window_cols();

    /* Alloc raster matrix */
    have_mask = 0;
    out_file = mask_file = NULL;
    out_fd = mask_fd = -1;
    if (grid == TRUE) {
        int row;
        DCELL *drastbuf;

        seg_mb = atoi(memory_opt->answer);
        if (seg_mb < 3)
            G_fatal_error(_("Memory in MB must be >= 3"));

        if (mask_opt->answer)
            seg_size = sizeof(double) + sizeof(char);
        else
            seg_size = sizeof(double);

        seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20);
        segments_in_memory = seg_mb / seg_size + 0.5;
        G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE);

        out_file = G_tempfile();
        out_fd = creat(out_file, 0666);
        if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1)
            G_fatal_error(_("Can not create temporary file"));
        close(out_fd);

        out_fd = open(out_file, 2);
        if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1)
            G_fatal_error(_("Can not initialize temporary file"));

        /* initialize output */
        G_message(_("Initializing output..."));

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        Rast_set_d_null_value(drastbuf, ncols);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            Segment_put_row(&out_seg, drastbuf, row);
        }
        G_percent(row, nrows, 2);

        if (mask_opt->answer) {
            int row, col, maskfd;
            DCELL dval, *drastbuf;
            char mask_val;

            G_message(_("Load masking map"));

            mask_file = G_tempfile();
            mask_fd = creat(mask_file, 0666);
            if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1)
                G_fatal_error(_("Can not create temporary file"));
            close(mask_fd);

            mask_fd = open(mask_file, 2);
            if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1)
                G_fatal_error(_("Can not initialize temporary file"));

            maskfd = Rast_open_old(mask_opt->answer, "");
            drastbuf = Rast_allocate_buf(DCELL_TYPE);

            for (row = 0; row < nrows; row++) {
                G_percent(row, nrows, 2);
                Rast_get_d_row(maskfd, drastbuf, row);
                for (col = 0; col < ncols; col++) {
                    dval = drastbuf[col];
                    if (Rast_is_d_null_value(&dval) || dval == 0)
                        mask_val = 0;
                    else
                        mask_val = 1;

                    Segment_put(&mask_seg, &mask_val, row, col);
                }
            }

            G_percent(row, nrows, 2);
            G_free(drastbuf);
            Rast_close(maskfd);

            have_mask = 1;
        }
    }

    /*------------------------------------------------------------------
      | Subdividing and working with tiles:
      | Each original region will be divided into several subregions.
      | Each one will be overlaped by its neighbouring subregions.
      | The overlapping is calculated as a fixed OVERLAP_SIZE times
      | the largest spline step plus 2 * edge
      ----------------------------------------------------------------*/

    /* Fixing parameters of the elaboration region */
    P_zero_dim(&dims);		/* Set dim struct to zero */

    nsplx_adj = NSPLX_MAX;
    nsply_adj = NSPLY_MAX;
    if (stepN > stepE)
        dims.overlap = OVERLAP_SIZE * stepN;
    else
        dims.overlap = OVERLAP_SIZE * stepE;
    P_get_edge(bilin, &dims, stepE, stepN);
    P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj);

    G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj);
    G_verbose_message(_("Adjusted NS splines %d"), nsply_adj);

    /* calculate number of subregions */
    edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v;
    edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h;

    N_extension = original_reg.north - original_reg.south;
    E_extension = original_reg.east - original_reg.west;

    nsubregion_col = ceil(E_extension / edgeE) + 0.5;
    nsubregion_row = ceil(N_extension / edgeN) + 0.5;

    if (nsubregion_col < 0)
        nsubregion_col = 0;
    if (nsubregion_row < 0)
        nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    /* Creating line and categories structs */
    Cats = Vect_new_cats_struct();
    Vect_cat_set(Cats, 1, 0);

    subregion_row = 0;
    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each subregion row */
        subregion_row++;
        P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                      GENERAL_ROW);

        if (elaboration_reg.north > original_reg.north) {	/* First row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          FIRST_ROW);
        }

        if (elaboration_reg.south <= original_reg.south) {	/* Last row */

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          LAST_ROW);
            last_row = TRUE;
        }

        nsply =
            ceil((elaboration_reg.north -
                  elaboration_reg.south) / stepN) + 0.5;
        G_debug(1, "Interpolation: nsply = %d", nsply);
        /*
        if (nsply > NSPLY_MAX)
            nsply = NSPLY_MAX;
        */
        elaboration_reg.east = original_reg.west;
        last_column = FALSE;
        subregion_col = 0;

        /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */
        /*     I'm not sure about pthreads, but you can tell OpenMP to start all at the
        	same time and it will keep num_workers supplied with the next job as free
        	cpus become available */
        while (last_column == FALSE) {	/* For each subregion column */
            int npoints = 0;
            /* needed for sparse points interpolation */
            int npoints_ext, *lineVect_ext = NULL;
            double **obsVect_ext;	/*, mean_ext = .0; */
            struct Point *observ_ext;

            subregion_col++;
            subregion++;
            if (nsubregions > 1)
                G_message(_("Processing subregion %d of %d..."), subregion, nsubregions);

            P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims,
                          GENERAL_COLUMN);

            if (elaboration_reg.west < original_reg.west) {	/* First column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, FIRST_COLUMN);
            }

            if (elaboration_reg.east >= original_reg.east) {	/* Last column */

                P_set_regions(&elaboration_reg, &general_box, &overlap_box,
                              dims, LAST_COLUMN);
                last_column = TRUE;
            }
            nsplx =
                ceil((elaboration_reg.east -
                      elaboration_reg.west) / stepE) + 0.5;
            G_debug(1, "Interpolation: nsplx = %d", nsplx);
            /*
            if (nsplx > NSPLX_MAX)
            nsplx = NSPLX_MAX;
            */
            G_debug(1, "Interpolation: (%d,%d): subregion bounds",
                    subregion_row, subregion_col);
            G_debug(1, "Interpolation: \t\tNORTH:%.2f\t",
                    elaboration_reg.north);
            G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f",
                    elaboration_reg.west, elaboration_reg.east);
            G_debug(1, "Interpolation: \t\tSOUTH:%.2f",
                    elaboration_reg.south);

#ifdef DEBUG_SUBREGIONS
            fprintf(stdout, "B 5\n");
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south);
            fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north);
            fprintf(stdout, "C 1 1\n");
            fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2,
                    (elaboration_reg.south + elaboration_reg.north) / 2);
            fprintf(stdout, " 1 %d\n", subregion);
#endif



            /* reading points in interpolation region */
            dim_vect = nsplx * nsply;
            observ_ext = NULL;
            if (grid == FALSE && ext == TRUE) {
                observ_ext =
                    P_Read_Vector_Region_Map(&In_ext,
                                             &elaboration_reg,
                                             &npoints_ext, dim_vect,
                                             1);
            }
            else
                npoints_ext = 1;

            if (grid == TRUE && have_mask) {
                /* any unmasked cells in general region ? */
                mean = 0;
                observ_ext =
                    P_Read_Raster_Region_masked(&mask_seg, &original_reg,
                                                original_box, general_box,
                                                &npoints_ext, dim_vect, mean);
            }

            observ = NULL;
            if (npoints_ext > 0) {
                observ =
                    P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints,
                                             dim_vect, bspline_field);
            }
            else
                npoints = 1;

            G_debug(1,
                    "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d",
                    subregion_row, subregion_col, npoints);
            if (npoints > 0)
                G_verbose_message(_("%d points found in this subregion"), npoints);
            /* only interpolate if there are any points in current subregion */
            if (npoints > 0 && npoints_ext > 0) {
                int i;

                nparameters = nsplx * nsply;
                BW = P_get_BandWidth(bilin, nsply);

                /* Least Squares system */
                N = G_alloc_matrix(nparameters, BW);	/* Normal matrix */
                TN = G_alloc_vector(nparameters);	/* vector */
                parVect = G_alloc_vector(nparameters);	/* Parameters vector */
                obsVect = G_alloc_matrix(npoints, 3);	/* Observation vector */
                Q = G_alloc_vector(npoints);	/* "a priori" var-cov matrix */
                lineVect = G_alloc_ivector(npoints);	/*  */

                for (i = 0; i < npoints; i++) {	/* Setting obsVect vector & Q matrix */
                    double dval;

                    Q[i] = 1;	/* Q=I */
                    lineVect[i] = observ[i].lineID;
                    obsVect[i][0] = observ[i].coordX;
                    obsVect[i][1] = observ[i].coordY;

                    /* read z coordinates from attribute table */
                    if (bspline_field > 0) {
                        int cat, ival, ret;

                        cat = observ[i].cat;
                        if (cat < 0)
                            continue;

                        if (ctype == DB_C_TYPE_INT) {
                            ret =
                                db_CatValArray_get_value_int(&cvarr, cat,
                                                             &ival);
                            obsVect[i][2] = ival;
                            observ[i].coordZ = ival;
                        }
                        else {	/* DB_C_TYPE_DOUBLE */
                            ret =
                                db_CatValArray_get_value_double(&cvarr, cat,
                                                                &dval);
                            obsVect[i][2] = dval;
                            observ[i].coordZ = dval;
                        }
                        if (ret != DB_OK) {
                            G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"),
                                      subregion_row, subregion_col, cat);
                            continue;
                        }
                    }
                    /* use z coordinates of 3D vector */
                    else {
                        obsVect[i][2] = observ[i].coordZ;
                    }
                }

                /* Mean calculation for every point */
                mean = P_Mean_Calc(&elaboration_reg, observ, npoints);

                G_debug(1, "Interpolation: (%d,%d): mean=%lf",
                        subregion_row, subregion_col, mean);

                G_free(observ);

                for (i = 0; i < npoints; i++)
                    obsVect[i][2] -= mean;

                /* Bilinear interpolation */
                if (bilin) {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bilinear interpolation...",
                            subregion_row, subregion_col);
                    normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                   nsply, elaboration_reg.west,
                                   elaboration_reg.south, npoints,
                                   nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }
                /* Bicubic interpolation */
                else {
                    G_debug(1,
                            "Interpolation: (%d,%d): Bicubic interpolation...",
                            subregion_row, subregion_col);
                    normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx,
                                     nsply, elaboration_reg.west,
                                     elaboration_reg.south, npoints,
                                     nparameters, BW);
                    nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN);
                }

                if(G_strncasecmp(solver->answer, "cg", 2) == 0)
                    G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer));
                else
                    G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW);


                G_free_matrix(N);
                G_free_vector(TN);
                G_free_vector(Q);

                if (grid == TRUE) {	/* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */
                    G_debug(1, "Interpolation: (%d,%d): Regular_Points...",
                            subregion_row, subregion_col);

                    if (!have_mask) {
                        P_Regular_Points(&elaboration_reg, &original_reg, general_box,
                                         overlap_box, &out_seg, parVect,
                                         stepN, stepE, dims.overlap, mean,
                                         nsplx, nsply, nrows, ncols, bilin);
                    }
                    else {
                        P_Sparse_Raster_Points(&out_seg,
                                               &elaboration_reg, &original_reg,
                                               general_box, overlap_box,
                                               observ_ext, parVect,
                                               stepE, stepN,
                                               dims.overlap, nsplx, nsply,
                                               npoints_ext, bilin, mean);
                    }
                }
                else {		/* OBSERVATION POINTS INTERPOLATION */
                    if (ext == FALSE) {
                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect, parVect,
                                        lineVect, stepE, stepN,
                                        dims.overlap, nsplx, nsply, npoints,
                                        bilin, Cats, driver, mean,
                                        table_name);
                    }
                    else {	/* FLAG_EXT == TRUE */

                        /* done that earlier */
                        /*
                        int npoints_ext, *lineVect_ext = NULL;
                        double **obsVect_ext;
                        struct Point *observ_ext;

                        observ_ext =
                            P_Read_Vector_Region_Map(&In_ext,
                        			     &elaboration_reg,
                        			     &npoints_ext, dim_vect,
                        			     1);
                        */

                        obsVect_ext = G_alloc_matrix(npoints_ext, 3);	/* Observation vector_ext */
                        lineVect_ext = G_alloc_ivector(npoints_ext);

                        for (i = 0; i < npoints_ext; i++) {	/* Setting obsVect_ext vector & Q matrix */
                            obsVect_ext[i][0] = observ_ext[i].coordX;
                            obsVect_ext[i][1] = observ_ext[i].coordY;
                            obsVect_ext[i][2] = observ_ext[i].coordZ - mean;
                            lineVect_ext[i] = observ_ext[i].lineID;
                        }

                        G_free(observ_ext);

                        G_debug(1, "Interpolation: (%d,%d): Sparse_Points...",
                                subregion_row, subregion_col);
                        P_Sparse_Points(&Out, &elaboration_reg, general_box,
                                        overlap_box, obsVect_ext, parVect,
                                        lineVect_ext, stepE, stepN,
                                        dims.overlap, nsplx, nsply,
                                        npoints_ext, bilin, Cats, driver,
                                        mean, table_name);

                        G_free_matrix(obsVect_ext);
                        G_free_ivector(lineVect_ext);
                    }		/* END FLAG_EXT == TRUE */
                }		/* END GRID == FALSE */
                G_free_vector(parVect);
                G_free_matrix(obsVect);
                G_free_ivector(lineVect);
            }
            else {
                if (observ)
                    G_free(observ);
                if (observ_ext)
                    G_free(observ_ext);
                if (npoints == 0)
                    G_warning(_("No data within this subregion. "
                                "Consider increasing spline step values."));
            }
        }			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    G_verbose_message(_("Writing output..."));
    /* Writing the output raster map */
    if (grid == TRUE) {
        int row, col;
        DCELL *drastbuf, dval;


        if (have_mask) {
            Segment_release(&mask_seg);	/* release memory  */
            close(mask_fd);
            unlink(mask_file);
        }

        drastbuf = Rast_allocate_buf(DCELL_TYPE);
        for (row = 0; row < nrows; row++) {
            G_percent(row, nrows, 2);
            for (col = 0; col < ncols; col++) {
                Segment_get(&out_seg, &dval, row, col);
                drastbuf[col] = dval;
            }
            Rast_put_d_row(raster, drastbuf);
        }

        Rast_close(raster);

        Segment_release(&out_seg);	/* release memory  */
        close(out_fd);
        unlink(out_file);
        /* set map title */
        sprintf(title, "%s interpolation with Tykhonov regularization",
                type_opt->answer);
        Rast_put_cell_title(out_map_opt->answer, title);
        /* write map history */
        Rast_short_history(out_map_opt->answer, "raster", &history);
        Rast_command_history(&history);
        Rast_write_history(out_map_opt->answer, &history);
    }
    /* Writing to the output vector map the points from the overlapping zones */
    else if (flag_auxiliar == TRUE) {
        if (ext == FALSE)
            P_Aux_to_Vector(&In, &Out, driver, table_name);
        else
            P_Aux_to_Vector(&In_ext, &Out, driver, table_name);

        /* Drop auxiliary table */
        G_debug(1, "%s: Dropping <%s>", argv[0], table_name);
        if (P_Drop_Aux_Table(driver, table_name) != DB_OK)
            G_fatal_error(_("Auxiliary table could not be dropped"));
    }

    db_close_database_shutdown_driver(driver);

    Vect_close(&In);
    if (ext != FALSE)
        Vect_close(&In_ext);
    if (vector)
        Vect_close(&Out);

    G_done_msg(" ");

    exit(EXIT_SUCCESS);
}				/*END MAIN */
Exemplo n.º 18
0
static int compute_constants(
				/* invert matrix and compute Sig->SubSig[i].cnst          */
				/* Returns singular=1 if a singluar subcluster was found. */
				/* Returns singular=2 if all subclusters were singular.   */
				/* When singular=2 then nsubclasses=0.                    */
				struct ClassSig *Sig, int nbands)
{
    int i, j;
    int b1, b2;
    int singular;
    double det;
    double pi_sum;

    static int first = 1;
    static int *indx;
    static double **y;
    static double *col;


    /* allocate memory first time subroutine is called */
    if (first) {
	indx = G_alloc_ivector(nbands);
	y = G_alloc_matrix(nbands, nbands);
	col = G_alloc_vector(nbands);
	first = 0;
    }

    G_debug(2, "compute_constants()");
    /* invert matrix and compute constant for each subclass */
    i = 0;
    singular = 0;
    do {
	for (b1 = 0; b1 < nbands; b1++)
	    for (b2 = 0; b2 < nbands; b2++)
		Sig->SubSig[i].Rinv[b1][b2] = Sig->SubSig[i].R[b1][b2];

	invert(Sig->SubSig[i].Rinv, nbands, &det, indx, y, col);
	if (det <= ZERO) {
	    if (Sig->nsubclasses == 1) {
		Sig->nsubclasses--;
		singular = 2;
		G_warning(_("Unreliable clustering. "
			    "Try a smaller initial number of clusters"));
	    }
	    else {
		for (j = i; j < Sig->nsubclasses - 1; j++)
		    copy_SubSig(&(Sig->SubSig[j + 1]), &(Sig->SubSig[j]),
				nbands);
		Sig->nsubclasses--;
		singular = 1;
		G_warning(_("Removed a singular subsignature number %d (%d remain)"),
			  i + 1, Sig->nsubclasses);
		if (Sig->nsubclasses < 0)	/* MN added 12/2001: to avoid endless loop */
		    Sig->nsubclasses = 1;
	    }
	}
	else {
	    Sig->SubSig[i].cnst =
		(-nbands / 2.0) * log(2 * M_PI) - 0.5 * log(det);
	    i++;
	}
    } while (i < Sig->nsubclasses);

    /* renormalize pi */
    pi_sum = 0;
    for (i = 0; i < Sig->nsubclasses; i++)
	pi_sum += Sig->SubSig[i].pi;
    for (i = 0; i < Sig->nsubclasses; i++)
	Sig->SubSig[i].pi /= pi_sum;

    return (singular);
}
Exemplo n.º 19
0
/*
 *
 *  Recursively processes each segment in a tree by:
 *
 *  a) finding points from neighbouring segments so that the total number of
 *  points is between KMIN and KMAX2 by calling tree function MT_get_region().
 *
 *  b) creating and solving the system of linear equations using these points
 *  and interp() by calling matrix_create() and G_ludcmp().
 *
 *  c) checking the interpolating function values at points by calling
 *  check_points().
 *
 *  d) computing grid for this segment using points and interp() by calling
 *  grid_calc().
 *
 */
int IL_interp_segments_2d(struct interp_params *params, struct tree_info *info,	/* info for the quad tree */
			  struct multtree *tree,	/* current leaf of the quad tree */
			  struct BM *bitmask,	/* bitmask */
			  double zmin, double zmax,	/* min and max input z-values */
			  double *zminac, double *zmaxac,	/* min and max interp. z-values */
			  double *gmin, double *gmax,	/* min and max inperp. slope val. */
			  double *c1min, double *c1max, double *c2min, double *c2max,	/* min and max interp. curv. val. */
			  double *ertot,	/* total interplating func. error */
			  int totsegm,		/* total number of segments */
			  off_t offset1,	/* offset for temp file writing */
			  double dnorm)
{
    double xmn, xmx, ymn, ymx, distx, disty, distxp, distyp, temp1, temp2;
    int i, npt, nptprev, MAXENC;
    struct quaddata *data;
    static int cursegm = 0;
    static double *b = NULL;
    static int *indx = NULL;
    static double **matrix = NULL;
    double ew_res, ns_res;
    static int first_time = 1;
    static double smseg;
    int MINPTS;
    double pr;
    struct triple *point;
    struct triple skip_point;
    int m_skip, skip_index, j, k, segtest;
    double xx, yy, zz;

    /* find the size of the smallest segment once */
    if (first_time) {
	smseg = smallest_segment(info->root, 4);
	first_time = 0;
    }
    ns_res = (((struct quaddata *)(info->root->data))->ymax -
	      ((struct quaddata *)(info->root->data))->y_orig) /
	params->nsizr;
    ew_res =
	(((struct quaddata *)(info->root->data))->xmax -
	 ((struct quaddata *)(info->root->data))->x_orig) / params->nsizc;

    if (tree == NULL)
	return -1;
    if (tree->data == NULL)
	return -1;
    if (((struct quaddata *)(tree->data))->points == NULL) {
	for (i = 0; i < 4; i++) {
	    IL_interp_segments_2d(params, info, tree->leafs[i],
				  bitmask, zmin, zmax, zminac, zmaxac, gmin,
				  gmax, c1min, c1max, c2min, c2max, ertot,
				  totsegm, offset1, dnorm);
	}
	return 1;
    }
    else {
	distx = (((struct quaddata *)(tree->data))->n_cols * ew_res) * 0.1;
	disty = (((struct quaddata *)(tree->data))->n_rows * ns_res) * 0.1;
	distxp = 0;
	distyp = 0;
	xmn = ((struct quaddata *)(tree->data))->x_orig;
	xmx = ((struct quaddata *)(tree->data))->xmax;
	ymn = ((struct quaddata *)(tree->data))->y_orig;
	ymx = ((struct quaddata *)(tree->data))->ymax;
	i = 0;
	MAXENC = 0;
	/* data is a window with zero points; some fields don't make sence in this case
	   so they are zero (like resolution,dimentions */
	/* CHANGE */
	/* Calcutaing kmin for surrent segment (depends on the size) */

/*****if (smseg <= 0.00001) MINPTS=params->kmin; else {} ***/
	pr = pow(2., (xmx - xmn) / smseg - 1.);
	MINPTS =
	    params->kmin * (pr / (1 + params->kmin * pr / params->KMAX2));
	/* fprintf(stderr,"MINPTS=%d, KMIN=%d, KMAX=%d, pr=%lf, smseg=%lf, DX=%lf \n", MINPTS,params->kmin,params->KMAX2,pr,smseg,xmx-xmn); */

	data =
	    (struct quaddata *)quad_data_new(xmn - distx, ymn - disty,
					     xmx + distx, ymx + disty, 0, 0,
					     0, params->KMAX2);
	npt = MT_region_data(info, info->root, data, params->KMAX2, 4);

	while ((npt < MINPTS) || (npt > params->KMAX2)) {
	    if (i >= 70) {
		G_warning(_("Taking too long to find points for interpolation - "
			    "please change the region to area where your points are. "
			    "Continuing calculations..."));
		break;
	    }
	    i++;
	    if (npt > params->KMAX2)
		/* decrease window */
	    {
		MAXENC = 1;
		nptprev = npt;
		temp1 = distxp;
		distxp = distx;
		distx = distxp - fabs(distx - temp1) * 0.5;
		temp2 = distyp;
		distyp = disty;
		disty = distyp - fabs(disty - temp2) * 0.5;
		/* decrease by 50% of a previous change in window */
	    }
	    else {
		nptprev = npt;
		temp1 = distyp;
		distyp = disty;
		temp2 = distxp;
		distxp = distx;
		if (MAXENC) {
		    disty = fabs(disty - temp1) * 0.5 + distyp;
		    distx = fabs(distx - temp2) * 0.5 + distxp;
		}
		else {
		    distx += distx;
		    disty += disty;
		}
		/* decrease by 50% of extra distance */
	    }
	    data->x_orig = xmn - distx;	/* update window */
	    data->y_orig = ymn - disty;
	    data->xmax = xmx + distx;
	    data->ymax = ymx + disty;
	    data->n_points = 0;
	    npt = MT_region_data(info, info->root, data, params->KMAX2, 4);
	}
	
	if (totsegm != 0) {
	    G_percent(cursegm, totsegm, 1);
	}
	data->n_rows = ((struct quaddata *)(tree->data))->n_rows;
	data->n_cols = ((struct quaddata *)(tree->data))->n_cols;

	/* for printing out overlapping segments */
	((struct quaddata *)(tree->data))->x_orig = xmn - distx;
	((struct quaddata *)(tree->data))->y_orig = ymn - disty;
	((struct quaddata *)(tree->data))->xmax = xmx + distx;
	((struct quaddata *)(tree->data))->ymax = ymx + disty;

	data->x_orig = xmn;
	data->y_orig = ymn;
	data->xmax = xmx;
	data->ymax = ymx;

	if (!matrix) {
	    if (!
		(matrix =
		 G_alloc_matrix(params->KMAX2 + 1, params->KMAX2 + 1))) {
		G_warning(_("Out of memory"));
		return -1;
	    }
	}
	if (!indx) {
	    if (!(indx = G_alloc_ivector(params->KMAX2 + 1))) {
		G_warning(_("Out of memory"));
		return -1;
	    }
	}
	if (!b) {
	    if (!(b = G_alloc_vector(params->KMAX2 + 3))) {
		G_warning(_("Out of memory"));
		return -1;
	    }
	}
	/* allocate memory for CV points only if cv is performed */
	if (params->cv) {
	    if (!
		(point =
		 (struct triple *)G_malloc(sizeof(struct triple) *
					   data->n_points))) {
		G_warning(_("Out of memory"));
		return -1;
	    }
	}

	/*normalize the data so that the side of average segment is about 1m */
	/* put data_points into point only if CV is performed */

	for (i = 0; i < data->n_points; i++) {
	    data->points[i].x = (data->points[i].x - data->x_orig) / dnorm;
	    data->points[i].y = (data->points[i].y - data->y_orig) / dnorm;
	    if (params->cv) {
		point[i].x = data->points[i].x;	/*cv stuff */
		point[i].y = data->points[i].y;	/*cv stuff */
		point[i].z = data->points[i].z;	/*cv stuff */
	    }

	    /* commented out by Helena january 1997 as this is not necessary
	       although it may be useful to put normalization of z back? 
	       data->points[i].z = data->points[i].z / dnorm;
	       this made smoothing self-adjusting  based on dnorm
	       if (params->rsm < 0.) data->points[i].sm = data->points[i].sm / dnorm;
	     */
	}

	/* cv stuff */
	if (params->cv)
	    m_skip = data->n_points;
	else
	    m_skip = 1;

	/* remove after cleanup - this is just for testing */
	skip_point.x = 0.;
	skip_point.y = 0.;
	skip_point.z = 0.;


	/*** TODO: parallelize this loop instead of the LU solver! ***/
	for (skip_index = 0; skip_index < m_skip; skip_index++) {
	    if (params->cv) {
		segtest = 0;
		j = 0;
		xx = point[skip_index].x * dnorm + data->x_orig +
		    params->x_orig;
		yy = point[skip_index].y * dnorm + data->y_orig +
		    params->y_orig;
		zz = point[skip_index].z;
		if (xx >= data->x_orig + params->x_orig &&
		    xx <= data->xmax + params->x_orig &&
		    yy >= data->y_orig + params->y_orig &&
		    yy <= data->ymax + params->y_orig) {
		    segtest = 1;
		    skip_point.x = point[skip_index].x;
		    skip_point.y = point[skip_index].y;
		    skip_point.z = point[skip_index].z;
		    for (k = 0; k < m_skip; k++) {
			if (k != skip_index && params->cv) {
			    data->points[j].x = point[k].x;
			    data->points[j].y = point[k].y;
			    data->points[j].z = point[k].z;
			    j++;
			}
		    }
		}		/* segment area test */
	    }
	    if (!params->cv) {
		if (params->
		    matrix_create(params, data->points, data->n_points,
				  matrix, indx) < 0)
		    return -1;
	    }
	    else if (segtest == 1) {
		if (params->
		    matrix_create(params, data->points, data->n_points - 1,
				  matrix, indx) < 0)
		    return -1;
	    }
	    if (!params->cv) {
		for (i = 0; i < data->n_points; i++)
		    b[i + 1] = data->points[i].z;
		b[0] = 0.;
		G_lubksb(matrix, data->n_points + 1, indx, b);
	/* put here condition to skip error if not needed */
		params->check_points(params, data, b, ertot, zmin, dnorm,
				     skip_point);
	    }
	    else if (segtest == 1) {
		for (i = 0; i < data->n_points - 1; i++)
		    b[i + 1] = data->points[i].z;
		b[0] = 0.;
		G_lubksb(matrix, data->n_points, indx, b);
		params->check_points(params, data, b, ertot, zmin, dnorm,
				     skip_point);
	    }
	}			/*end of cv loop */

	if (!params->cv)
	    if ((params->Tmp_fd_z != NULL) || (params->Tmp_fd_dx != NULL) ||
		(params->Tmp_fd_dy != NULL) || (params->Tmp_fd_xx != NULL) ||
		(params->Tmp_fd_yy != NULL) || (params->Tmp_fd_xy != NULL)) {

		if (params->grid_calc(params, data, bitmask,
				      zmin, zmax, zminac, zmaxac, gmin, gmax,
				      c1min, c1max, c2min, c2max, ertot, b,
				      offset1, dnorm) < 0)
		    return -1;
	    }

	/* show after to catch 100% */
	cursegm++;
	if (totsegm < cursegm)
	    G_debug(1, "%d %d", totsegm, cursegm);
	
	if (totsegm != 0) {
	    G_percent(cursegm, totsegm, 1);
	}
	/* 
	   G_free_matrix(matrix);
	   G_free_ivector(indx);
	   G_free_vector(b);
	 */
	G_free(data->points);
	G_free(data);
    }
    return 1;
}