1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                     Tool Library                      //
9 //                 statistics_regression                 //
10 //                                                       //
11 //-------------------------------------------------------//
12 //                                                       //
13 //             point_multi_grid_regression.cpp           //
14 //                                                       //
15 //                 Copyright (C) 2004 by                 //
16 //                      Olaf Conrad                      //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    e-mail:     oconrad@saga-gis.org                   //
40 //                                                       //
41 //    contact:    Olaf Conrad                            //
42 //                Institute of Geography                 //
43 //                University of Goettingen               //
44 //                Goldschmidtstr. 5                      //
45 //                37077 Goettingen                       //
46 //                Germany                                //
47 //                                                       //
48 ///////////////////////////////////////////////////////////
49 
50 //---------------------------------------------------------
51 #include "point_multi_grid_regression.h"
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
CPoint_Multi_Grid_Regression(void)61 CPoint_Multi_Grid_Regression::CPoint_Multi_Grid_Regression(void)
62 {
63 	//-----------------------------------------------------
64 	Set_Name		(_TL("Multiple Regression Analysis (Points and Predictor Grids)"));
65 
66 	Set_Author		("O.Conrad (c) 2004");
67 
68 	Set_Description	(_TW(
69 		"Linear regression analysis of point attributes with multiple grids. "
70 		"Details of the regression/correlation analysis will be saved to a table. "
71 		"The regression function is used to create a new grid with regression based values. "
72 		"The multiple regression analysis uses a forward selection procedure."
73 	));
74 
75 	Add_Reference(
76 		"Bahrenberg, G., Giese, E., Nipper, J.", "1992",
77 		"Statistische Methoden in der Geographie 2 - Multivariate Statistik",
78 		"Stuttgart, 415p."
79 	);
80 
81 	//-----------------------------------------------------
82 	Parameters.Add_Grid_List("",
83 		"PREDICTORS"	, _TL("Predictors"),
84 		_TL(""),
85 		PARAMETER_INPUT, true
86 	);
87 
88 	Parameters.Add_Shapes("",
89 		"POINTS"		, _TL("Points"),
90 		_TL(""),
91 		PARAMETER_INPUT
92 	);
93 
94 	Parameters.Add_Table_Field("POINTS",
95 		"ATTRIBUTE"		, _TL("Dependent Variable"),
96 		_TL("")
97 	);
98 
99 	Parameters.Add_Table("",
100 		"INFO_COEFF"	, _TL("Details: Coefficients"),
101 		_TL(""),
102 		PARAMETER_OUTPUT_OPTIONAL
103 	);
104 
105 	Parameters.Add_Table("",
106 		"INFO_MODEL"	, _TL("Details: Model"),
107 		_TL(""),
108 		PARAMETER_OUTPUT_OPTIONAL
109 	);
110 
111 	Parameters.Add_Table("",
112 		"INFO_STEPS"	, _TL("Details: Steps"),
113 		_TL(""),
114 		PARAMETER_OUTPUT_OPTIONAL
115 	);
116 
117 	Parameters.Add_Shapes("",
118 		"RESIDUALS"		, _TL("Residuals"),
119 		_TL(""),
120 		PARAMETER_OUTPUT_OPTIONAL, SHAPE_TYPE_Point
121 	);
122 
123 	Parameters.Add_Grid("",
124 		"REGRESSION"	, _TL("Regression"),
125 		_TL("regression model applied to predictor grids"),
126 		PARAMETER_OUTPUT
127 	);
128 
129 	Parameters.Add_Grid("",
130 		"REGRESCORR"	, _TL("Regression with Residual Correction"),
131 		_TL("regression model applied to predictor grids with interpolated residuals added"),
132 		PARAMETER_OUTPUT_OPTIONAL
133 	);
134 
135 	Parameters.Add_Choice("",
136 		"RESAMPLING"	, _TL("Resampling"),
137 		_TL(""),
138 		CSG_String::Format("%s|%s|%s|%s",
139 			_TL("Nearest Neighbour"),
140 			_TL("Bilinear Interpolation"),
141 			_TL("Bicubic Spline Interpolation"),
142 			_TL("B-Spline Interpolation")
143 		), 3
144 	);
145 
146 	Parameters.Add_Bool("",
147 		"COORD_X"		, _TL("Include X Coordinate"),
148 		_TL(""),
149 		false
150 	);
151 
152 	Parameters.Add_Bool("",
153 		"COORD_Y"		, _TL("Include Y Coordinate"),
154 		_TL(""),
155 		false
156 	);
157 
158 	Parameters.Add_Bool("",
159 		"INTERCEPT"		, _TL("Intercept"),
160 		_TL(""),
161 		true
162 	);
163 
164 	Parameters.Add_Choice("",
165 		"METHOD"		, _TL("Method"),
166 		_TL(""),
167 		CSG_String::Format("%s|%s|%s|%s",
168 			_TL("include all"),
169 			_TL("forward"),
170 			_TL("backward"),
171 			_TL("stepwise")
172 		), 3
173 	);
174 
175 	Parameters.Add_Double("",
176 		"P_VALUE"		, _TL("Significance Level"),
177 		_TL("Significance level (aka p-value) as threshold for automated predictor selection, given as percentage"),
178 		5., 0., true, 100., true
179 	);
180 
181 	Parameters.Add_Choice("",
182 		"CROSSVAL"		, _TL("Cross Validation"),
183 		_TL(""),
184 		CSG_String::Format("%s|%s|%s|%s",
185 			_TL("none"),
186 			_TL("leave one out"),
187 			_TL("2-fold"),
188 			_TL("k-fold")
189 		), 0
190 	);
191 
192 	Parameters.Add_Int("",
193 		"CROSSVAL_K"	, _TL("Cross Validation Subsamples"),
194 		_TL("number of subsamples for k-fold cross validation"),
195 		10, 2, true
196 	);
197 
198 	Parameters.Add_Choice("",
199 		"RESIDUAL_COR"	, _TL("Residual Interpolation"),
200 		_TL(""),
201 		CSG_String::Format("%s|%s",
202 			_TL("Multilevel B-Spline Interpolation"),
203 			_TL("Inverse Distance Weighted")
204 		), 0
205 	);
206 }
207 
208 
209 ///////////////////////////////////////////////////////////
210 //														 //
211 ///////////////////////////////////////////////////////////
212 
213 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)214 int CPoint_Multi_Grid_Regression::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
215 {
216 	if(	pParameter->Cmp_Identifier("CROSSVAL") )
217 	{
218 		pParameters->Set_Enabled("CROSSVAL_K", pParameter->asInt() == 3);	// k-fold
219 	}
220 
221 	if(	pParameter->Cmp_Identifier("METHOD") )
222 	{
223 		pParameters->Set_Enabled("P_VALUE", pParameter->asInt() > 0);
224 	}
225 
226 	if(	pParameter->Cmp_Identifier("REGRESCORR") )
227 	{
228 		pParameters->Set_Enabled("RESIDUAL_COR", pParameter->asPointer() != NULL);
229 	}
230 
231 	return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
232 }
233 
234 
235 ///////////////////////////////////////////////////////////
236 //														 //
237 ///////////////////////////////////////////////////////////
238 
239 //---------------------------------------------------------
On_Execute(void)240 bool CPoint_Multi_Grid_Regression::On_Execute(void)
241 {
242 	bool					bResult;
243 	int						iAttribute;
244 	double					P;
245 	CSG_Strings				Names;
246 	CSG_Matrix				Samples;
247 	CSG_Shapes				*pPoints;
248 	CSG_Grid				*pRegression;
249 	CSG_Parameter_Grid_List	*pGrids;
250 
251 	//-----------------------------------------------------
252 	pGrids		= Parameters("PREDICTORS")->asGridList();
253 	pRegression	= Parameters("REGRESSION")->asGrid();
254 	pPoints		= Parameters("POINTS"    )->asShapes();
255 	iAttribute	= Parameters("ATTRIBUTE" )->asInt();
256 	P			= Parameters("P_VALUE"   )->asDouble() / 100.;
257 
258 	//-----------------------------------------------------
259 	if( !Get_Samples(pGrids, pPoints, iAttribute, Samples, Names) )
260 	{
261 		return( false );
262 	}
263 
264 	//-----------------------------------------------------
265 	m_Regression.Set_With_Intercept(Parameters("INTERCEPT")->asBool());
266 
267 	switch( Parameters("METHOD")->asInt() )
268 	{
269 	default: bResult = m_Regression.Get_Model         (Samples      , &Names);	break;
270 	case  1: bResult = m_Regression.Get_Model_Forward (Samples, P   , &Names);	break;
271 	case  2: bResult = m_Regression.Get_Model_Backward(Samples,    P, &Names);	break;
272 	case  3: bResult = m_Regression.Get_Model_Stepwise(Samples, P, P, &Names);	break;
273 	}
274 
275 	if( bResult == false )
276 	{
277 		Error_Set(_TL("regression analysis could not detect a significant predictor"));
278 
279 		return( false );
280 	}
281 
282 	//-----------------------------------------------------
283 	Message_Add(m_Regression.Get_Info(), false);
284 
285 	//-----------------------------------------------------
286 	int	CrossVal;
287 
288 	switch( Parameters("CROSSVAL")->asInt() )
289 	{
290 	default: CrossVal = 0;                                 break;	// none
291 	case  1: CrossVal = 1;                                 break;	// leave one out (LOOVC)
292 	case  2: CrossVal = 2;                                 break;	// 2-fold
293 	case  3: CrossVal = Parameters("CROSSVAL_K")->asInt(); break;	// k-fold
294 	}
295 
296 	if( CrossVal > 0 && m_Regression.Get_CrossValidation(CrossVal) )
297 	{
298 		Message_Fmt("\n%s:", _TL("Cross Validation"));
299 		Message_Fmt("\n\t%s:\t%s"  , _TL("Type"   ), Parameters("CROSSVAL")->asString());
300 		Message_Fmt("\n\t%s:\t%d"  , _TL("Samples"), m_Regression.Get_CV_nSamples()    );
301 		Message_Fmt("\n\t%s:\t%f"  , _TL("RMSE"   ), m_Regression.Get_CV_RMSE()        );
302 		Message_Fmt("\n\t%s:\t%.2f", _TL("NRMSE"  ), m_Regression.Get_CV_NRMSE() * 100.);
303 		Message_Fmt("\n\t%s:\t%.2f", _TL("R2"     ), m_Regression.Get_CV_R2()    * 100.);
304 	}
305 
306 	//-----------------------------------------------------
307 	Set_Regression(pGrids, pRegression, CSG_String::Format("%s.%s [%s]", pPoints->Get_Name(), Parameters("ATTRIBUTE")->asString(), _TL("Regression")));
308 
309 	//-----------------------------------------------------
310 	if( Parameters("INFO_COEFF")->asTable() )
311 	{
312 		Parameters("INFO_COEFF")->asTable()->Assign(m_Regression.Get_Info_Regression());
313 		Parameters("INFO_COEFF")->asTable()->Set_Name(_TL("MLRA Coefficients"));
314 	}
315 
316 	if( Parameters("INFO_MODEL")->asTable() )
317 	{
318 		Parameters("INFO_MODEL")->asTable()->Assign(m_Regression.Get_Info_Model());
319 		Parameters("INFO_MODEL")->asTable()->Set_Name(_TL("MLRA Model"));
320 	}
321 
322 	if( Parameters("INFO_STEPS")->asTable() )
323 	{
324 		Parameters("INFO_STEPS")->asTable()->Assign(m_Regression.Get_Info_Steps());
325 		Parameters("INFO_STEPS")->asTable()->Set_Name(_TL("MLRA Steps"));
326 	}
327 
328 	//-----------------------------------------------------
329 	Set_Residuals(Parameters("RESIDUALS")->asShapes());
330 
331 	Set_Residual_Corr(pRegression, Parameters("RESIDUALS")->asShapes(), Parameters("REGRESCORR")->asGrid());
332 
333 	m_Regression.Destroy();
334 
335 	return( true );
336 }
337 
338 
339 ///////////////////////////////////////////////////////////
340 //														 //
341 ///////////////////////////////////////////////////////////
342 
343 //---------------------------------------------------------
Get_Samples(CSG_Parameter_Grid_List * pGrids,CSG_Shapes * pPoints,int iAttribute,CSG_Matrix & Samples,CSG_Strings & Names)344 bool CPoint_Multi_Grid_Regression::Get_Samples(CSG_Parameter_Grid_List *pGrids, CSG_Shapes *pPoints, int iAttribute, CSG_Matrix &Samples, CSG_Strings &Names)
345 {
346 	int			iGrid;
347 	double		zGrid;
348 	CSG_Vector	Sample;
349 
350 	//-----------------------------------------------------
351 	bool	bCoord_X	= Parameters("COORD_X")->asBool();
352 	bool	bCoord_Y	= Parameters("COORD_Y")->asBool();
353 
354 	TSG_Grid_Resampling	Resampling;
355 
356 	switch( Parameters("RESAMPLING")->asInt() )
357 	{
358 	default: Resampling	= GRID_RESAMPLING_NearestNeighbour;	break;
359 	case  1: Resampling	= GRID_RESAMPLING_Bilinear        ;	break;
360 	case  2: Resampling	= GRID_RESAMPLING_BicubicSpline   ;	break;
361 	case  3: Resampling	= GRID_RESAMPLING_BSpline         ;	break;
362 	}
363 
364 	Names	+= pPoints->Get_Field_Name(iAttribute);		// Dependent Variable
365 
366 	for(iGrid=0; iGrid<pGrids->Get_Grid_Count(); iGrid++)	// Independent Variables
367 	{
368 		Names	+= pGrids->Get_Grid(iGrid)->Get_Name();
369 	}
370 
371 	if( bCoord_X )	{	Names	+= "X";	}
372 	if( bCoord_Y )	{	Names	+= "Y";	}
373 
374 	Sample.Create(1 + pGrids->Get_Grid_Count() + (bCoord_X ? 1 : 0) + (bCoord_Y ? 1 : 0));
375 
376 	//-----------------------------------------------------
377 	for(int iShape=0; iShape<pPoints->Get_Count() && Set_Progress(iShape, pPoints->Get_Count()); iShape++)
378 	{
379 		CSG_Shape	*pShape	= pPoints->Get_Shape(iShape);
380 
381 		if( !pShape->is_NoData(iAttribute) )
382 		{
383 			Sample[0]	= pShape->asDouble(iAttribute);
384 
385 			for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
386 			{
387 				for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
388 				{
389 					bool		bAdd	= true;
390 					TSG_Point	Point	= pShape->Get_Point(iPoint, iPart);
391 
392 					for(iGrid=0; iGrid<pGrids->Get_Grid_Count() && bAdd; iGrid++)
393 					{
394 						if( pGrids->Get_Grid(iGrid)->Get_Value(Point, zGrid, Resampling) )
395 						{
396 							Sample[1 + iGrid]	= zGrid;
397 						}
398 						else
399 						{
400 							bAdd	= false;
401 						}
402 					}
403 
404 					if( bAdd )
405 					{
406 						if( bCoord_X )	{	Sample[1 + iGrid++]	= Point.x;	}
407 						if( bCoord_Y )	{	Sample[1 + iGrid++]	= Point.y;	}
408 
409 						Samples.Add_Row(Sample);
410 					}
411 				}
412 			}
413 		}
414 	}
415 
416 	//-----------------------------------------------------
417 	return( Samples.Get_NRows() >= pGrids->Get_Grid_Count() );
418 }
419 
420 
421 ///////////////////////////////////////////////////////////
422 //														 //
423 ///////////////////////////////////////////////////////////
424 
425 //---------------------------------------------------------
Set_Regression(CSG_Parameter_Grid_List * pGrids,CSG_Grid * pRegression,const CSG_String & Name)426 bool CPoint_Multi_Grid_Regression::Set_Regression(CSG_Parameter_Grid_List *pGrids, CSG_Grid *pRegression, const CSG_String &Name)
427 {
428 	if( !pRegression )
429 	{
430 		return( false );
431 	}
432 
433 	//-----------------------------------------------------
434 	int			iGrid, nGrids, x, y;
435 	TSG_Point	p;
436 
437 	TSG_Grid_Resampling	Resampling;
438 
439 	switch( Parameters("RESAMPLING")->asInt() )
440 	{
441 	default:	Resampling	= GRID_RESAMPLING_NearestNeighbour;	break;
442 	case  1:	Resampling	= GRID_RESAMPLING_Bilinear;			break;
443 	case  2:	Resampling	= GRID_RESAMPLING_BicubicSpline;	break;
444 	case  3:	Resampling	= GRID_RESAMPLING_BSpline;			break;
445 	}
446 
447 	CSG_Grid	**ppGrids	= (CSG_Grid **)SG_Malloc(m_Regression.Get_nPredictors() * sizeof(CSG_Grid *));
448 
449 	int	iCoord_X	= -1;
450 	int	iCoord_Y	= -1;
451 
452 	for(iGrid=0, nGrids=0; iGrid<m_Regression.Get_nPredictors(); iGrid++)
453 	{
454 		if( m_Regression.Get_Predictor(iGrid) < pGrids->Get_Grid_Count() )
455 		{
456 			ppGrids[nGrids++]	= pGrids->Get_Grid(m_Regression.Get_Predictor(iGrid));
457 		}
458 		else if( m_Regression.Get_Predictor(iGrid) == pGrids->Get_Grid_Count() && Parameters("COORD_X")->asBool() )
459 		{
460 			iCoord_X = iGrid;
461 		}
462 		else // if( m_Regression.Get_Predictor(iGrid) > pGrids->Get_Count() || Parameters("COORD_X")->asBool() == false )
463 		{
464 			iCoord_Y = iGrid;
465 		}
466 	}
467 
468 	pRegression->Set_Name(Name);
469 
470 	//-----------------------------------------------------
471 	for(y=0, p.y=Get_YMin(); y<Get_NY() && Set_Progress(y); y++, p.y+=Get_Cellsize())
472 	{
473 		for(x=0, p.x=Get_XMin(); x<Get_NX(); x++, p.x+=Get_Cellsize())
474 		{
475 			bool	bOkay;
476 			double	z	= m_Regression.Get_RConst();
477 
478 			for(iGrid=0, bOkay=true; bOkay && iGrid<nGrids; iGrid++)
479 			{
480 				double	zGrid;
481 
482 				if( ppGrids[iGrid]->Get_Value(p, zGrid, Resampling) )
483 				{
484 					z	+= m_Regression.Get_RCoeff(iGrid) * zGrid;
485 				}
486 				else
487 				{
488 					bOkay	= false;
489 				}
490 			}
491 
492 			//---------------------------------------------
493 			if( bOkay )
494 			{
495 				if( iCoord_X >= 0 )
496 				{
497 					z	+= m_Regression.Get_RCoeff(iCoord_X) * p.x;
498 				}
499 
500 				if( iCoord_Y >= 0 )
501 				{
502 					z	+= m_Regression.Get_RCoeff(iCoord_Y) * p.y;
503 				}
504 
505 				pRegression->Set_Value (x, y, z);
506 			}
507 			else
508 			{
509 				pRegression->Set_NoData(x, y);
510 			}
511 		}
512 	}
513 
514 	//-----------------------------------------------------
515 	SG_Free(ppGrids);
516 
517 	return( true );
518 }
519 
520 
521 ///////////////////////////////////////////////////////////
522 //														 //
523 ///////////////////////////////////////////////////////////
524 
525 //---------------------------------------------------------
Set_Residuals(CSG_Shapes * pResiduals)526 bool CPoint_Multi_Grid_Regression::Set_Residuals(CSG_Shapes *pResiduals)
527 {
528 	if( !pResiduals )
529 	{
530 		return( false );
531 	}
532 
533 	//-----------------------------------------------------
534 	CSG_Shapes	*pPoints		= Parameters("POINTS"    )->asShapes();
535 	CSG_Grid	*pRegression	= Parameters("REGRESSION")->asGrid();
536 	int			iAttribute		= Parameters("ATTRIBUTE" )->asInt();
537 
538 	TSG_Grid_Resampling	Resampling;
539 
540 	switch( Parameters("RESAMPLING")->asInt() )
541 	{
542 	default:	Resampling	= GRID_RESAMPLING_NearestNeighbour;	break;
543 	case  1:	Resampling	= GRID_RESAMPLING_Bilinear;			break;
544 	case  2:	Resampling	= GRID_RESAMPLING_BicubicSpline;	break;
545 	case  3:	Resampling	= GRID_RESAMPLING_BSpline;			break;
546 	}
547 
548 	//-----------------------------------------------------
549 	pResiduals->Create(SHAPE_TYPE_Point, CSG_String::Format("%s.%s [%s]", pPoints->Get_Name(), Parameters("ATTRIBUTE")->asString(), _TL("Residuals")));
550 	pResiduals->Add_Field(pPoints->Get_Field_Name(iAttribute), SG_DATATYPE_Double);
551 	pResiduals->Add_Field("TREND"	, SG_DATATYPE_Double);
552 	pResiduals->Add_Field("RESIDUAL", SG_DATATYPE_Double);
553 
554 	//-----------------------------------------------------
555 	for(int iShape=0; iShape<pPoints->Get_Count() && Set_Progress(iShape, pPoints->Get_Count()); iShape++)
556 	{
557 		CSG_Shape	*pShape	= pPoints->Get_Shape(iShape);
558 
559 		if( !pShape->is_NoData(iAttribute) )
560 		{
561 			double	zShape	= pShape->asDouble(iAttribute);
562 
563 			for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
564 			{
565 				for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
566 				{
567 					double		zGrid;
568 					TSG_Point	Point	= pShape->Get_Point(iPoint, iPart);
569 
570 					if( pRegression->Get_Value(Point, zGrid, Resampling) )
571 					{
572 						CSG_Shape	*pResidual	= pResiduals->Add_Shape();
573 
574 						pResidual->Add_Point(Point);
575 						pResidual->Set_Value(0, zShape);
576 						pResidual->Set_Value(1, zGrid);
577 						pResidual->Set_Value(2, zShape - zGrid);
578 					}
579 				}
580 			}
581 		}
582 	}
583 
584 	//-----------------------------------------------------
585 	return( true );
586 }
587 
588 //---------------------------------------------------------
Set_Residual_Corr(CSG_Grid * pRegression,CSG_Shapes * pResiduals,CSG_Grid * pCorrection)589 bool CPoint_Multi_Grid_Regression::Set_Residual_Corr(CSG_Grid *pRegression, CSG_Shapes *pResiduals, CSG_Grid *pCorrection)
590 {
591 	//-----------------------------------------------------
592 	if( !pCorrection )
593 	{
594 		return( false );
595 	}
596 
597 	//-----------------------------------------------------
598 	CSG_Shapes	Residuals;
599 
600 	if( !pResiduals )
601 	{
602 		if( !Set_Residuals(&Residuals) )
603 		{
604 			return( false );
605 		}
606 
607 		pResiduals	= &Residuals;
608 	}
609 
610 	//-----------------------------------------------------
611 	switch( Parameters("RESIDUAL_COR")->asInt() )
612 	{
613 	default:	// Multlevel B-Spline Interpolation
614 		SG_RUN_TOOL_ExitOnError("grid_spline", 4,
615 				SG_TOOL_PARAMETER_SET("SHAPES"           , pResiduals)
616 			&&  SG_TOOL_PARAMETER_SET("FIELD"            , 2)
617 			&&  SG_TOOL_PARAMETER_SET("TARGET_DEFINITION", 1)	// grid or grid system
618 			&&  SG_TOOL_PARAMETER_SET("TARGET_OUT_GRID"  , pCorrection)
619 		);
620 		break;
621 
622 	case  1:	// Inverse Distance Weighted
623 		SG_RUN_TOOL_ExitOnError("grid_gridding", 1,
624 				SG_TOOL_PARAMETER_SET("SHAPES"           , pResiduals)
625 			&&  SG_TOOL_PARAMETER_SET("FIELD"            , 2)
626 			&&  SG_TOOL_PARAMETER_SET("TARGET_DEFINITION", 1)	// grid or grid system
627 			&&  SG_TOOL_PARAMETER_SET("TARGET_OUT_GRID"  , pCorrection)
628 			&&  SG_TOOL_PARAMETER_SET("SEARCH_RANGE"     , 1)	// global
629 			&&  SG_TOOL_PARAMETER_SET("SEARCH_POINTS_ALL", 1)	// all points within search distance
630 		);
631 		break;
632 	}
633 
634 	//-----------------------------------------------------
635 	#pragma omp parallel for
636 	for(int y=0; y<Get_NY(); y++)
637 	{
638 		for(int x=0; x<Get_NX(); x++)
639 		{
640 			if( pRegression->is_NoData(x, y) || pCorrection->is_NoData(x, y) )
641 			{
642 				pCorrection->Set_NoData(x, y);
643 			}
644 			else
645 			{
646 				pCorrection->Add_Value(x, y, pRegression->asDouble(x, y));
647 			}
648 		}
649 	}
650 
651 	pCorrection->Fmt_Name("%s.%s [%s]", Parameters("POINTS")->asShapes()->Get_Name(), Parameters("ATTRIBUTE")->asString(), _TL("Residual Corrected Regression"));
652 
653 	//-----------------------------------------------------
654 	return( true );
655 }
656 
657 
658 ///////////////////////////////////////////////////////////
659 //														 //
660 //														 //
661 //														 //
662 ///////////////////////////////////////////////////////////
663 
664 //---------------------------------------------------------
665 
666 //	//-----------------------------------------------------
667 //	Parameters.Add_Choice(
668 //		NULL	,"CORRECTION"	, _TL("Adjustment"),
669 //		_TL(""),
670 //		CSG_String::Format("%s|%s|%s|%s|%s|%s",
671 //			_TL("Smith"),
672 //			_TL("Wherry 1"),
673 //			_TL("Wherry 2"),
674 //			_TL("Olkin & Pratt"),
675 //			_TL("Pratt"),
676 //			_TL("Claudy 3")
677 //		), 1
678 //	);
679 //
680 //	TSG_Regression_Correction	m_Correction;
681 //
682 //	switch( Parameters("CORRECTION")->asInt() )
683 //	{
684 //	case 0:	m_Correction	= REGRESSION_CORR_Smith;		break;
685 //	case 1:	m_Correction	= REGRESSION_CORR_Wherry_1;		break;
686 //	case 2:	m_Correction	= REGRESSION_CORR_Wherry_2;		break;
687 //	case 3:	m_Correction	= REGRESSION_CORR_Olkin_Pratt;	break;
688 //	case 4:	m_Correction	= REGRESSION_CORR_Pratt;		break;
689 //	case 5:	m_Correction	= REGRESSION_CORR_Claudy_3;		break;
690 //	}
691 //
692 
693 
694 ///////////////////////////////////////////////////////////
695 //														 //
696 //														 //
697 //														 //
698 ///////////////////////////////////////////////////////////
699 
700 //---------------------------------------------------------
701