SAGA API v9.10
Loading...
Searching...
No Matches
mat_regression.cpp
Go to the documentation of this file.
1
3// //
4// SAGA //
5// //
6// System for Automated Geoscientific Analyses //
7// //
8// Application Programming Interface //
9// //
10// Library: SAGA_API //
11// //
12//-------------------------------------------------------//
13// //
14// mat_regression.cpp //
15// //
16// Copyright (C) 2005 by Olaf Conrad //
17// //
18//-------------------------------------------------------//
19// //
20// This file is part of 'SAGA - System for Automated //
21// Geoscientific Analyses'. //
22// //
23// This library is free software; you can redistribute //
24// it and/or modify it under the terms of the GNU Lesser //
25// General Public License as published by the Free //
26// Software Foundation, either version 2.1 of the //
27// License, or (at your option) any later version. //
28// //
29// This library is distributed in the hope that it will //
30// be useful, but WITHOUT ANY WARRANTY; without even the //
31// implied warranty of MERCHANTABILITY or FITNESS FOR A //
32// PARTICULAR PURPOSE. See the GNU Lesser General Public //
33// License for more details. //
34// //
35// You should have received a copy of the GNU Lesser //
36// General Public License along with this program; if //
37// not, see <http://www.gnu.org/licenses/>. //
38// //
39//-------------------------------------------------------//
40// //
41// contact: Olaf Conrad //
42// Institute of Geography //
43// University of Goettingen //
44// Goldschmidtstr. 5 //
45// 37077 Goettingen //
46// Germany //
47// //
48// e-mail: oconrad@saga-gis.org //
49// //
51
52//---------------------------------------------------------
53#include "mat_tools.h"
54
55
57// //
58// //
59// //
61
62//---------------------------------------------------------
63double SG_Regression_Get_Adjusted_R2(double r2, int n, int p, TSG_Regression_Correction Correction)
64{
65 double r = 1. - r2;
66
67 switch( Correction )
68 {
69 case REGRESSION_CORR_None: default:
70 return( r2 );
71
73 r2 = 1. - ((n ) / (n - p )) * r;
74 break;
75
77 r2 = 1. - ((n - 1.) / (n - p - 1.)) * r;
78 break;
79
81 r2 = 1. - ((n - 1.) / (n - p )) * r;
82 break;
83
85 // r2 = 1. - ((n - 3.) / (n - p - 2.)) * (r + (2. / (n - p)) * r*r);
86 r2 = 1. - ((n - 3.) * r / (n - p - 1.)) * (1. + (2. * r) / (n - p + 1.));
87 break;
88
90 r2 = 1. - ((n - 3.) * r / (n - p - 1.)) * (1. + (2. * r) / (n - p - 2.3));
91 break;
92
94 r2 = 1. - ((n - 4.) * r / (n - p - 1.)) * (1. + (2. * r) / (n - p + 1.));
95 break;
96 }
97
98 return( r2 < 0. ? 0. : r2 > 1. ? 1. : r2 );
99}
100
101
103// //
104// //
105// //
107
108//---------------------------------------------------------
113
114//---------------------------------------------------------
119
120
122// //
124
125//---------------------------------------------------------
127{
128 m_R2 = -1.; // mark as invalid (or unprocessed)
129
131
132 m_x.Destroy();
133 m_y.Destroy();
134}
135
136
138// //
140
141//---------------------------------------------------------
142bool CSG_Regression::Add_Values(double x, double y)
143{
144 return( m_y.Add_Row(y) && m_x.Add_Row(x) );
145}
146
147//---------------------------------------------------------
148bool CSG_Regression::Set_Values(int nValues, double *x, double *y)
149{
150 Destroy();
151
152 return( m_y.Create(nValues, y) && m_x.Create(nValues, x) );
153}
154
155
157// //
159
160//---------------------------------------------------------
162{
163 static CSG_String s; s.Clear();
164
165 s += CSG_String::Format("\nNumber of observations = %d\n", Get_Count());
166 s += CSG_String::Format("\nPredictor variable (x):\n min. = %.6f, max. = %.6f, mean = %.6f, stddev. = %.6f\n", m_xMin, m_xMax, m_xMean, sqrt(m_xVar));
167 s += CSG_String::Format("\nDependent variable (y):\n min. = %.6f, max. = %.6f, mean = %.6f, stddev. = %.6f\n", m_yMin, m_yMax, m_yMean, sqrt(m_yVar));
168 s += CSG_String::Format(SG_T("\nRegression (r = %.4f, r² = %.4f):\n\n y = "), m_R, m_R2);
169
170 switch( m_Type )
171 {
172 case REGRESSION_Linear: s += CSG_String::Format("%.6f %+.6f * x" , m_RConst, m_RCoeff); break; // Y = a + b * X
173 case REGRESSION_Rez_X : s += CSG_String::Format("%.6f %+.6f / x" , m_RConst, m_RCoeff); break; // Y = a + b / X
174 case REGRESSION_Rez_Y : s += CSG_String::Format("%.6f / (%.6f - x)" , m_RConst, m_RCoeff); break; // Y = a / (b - X)
175 case REGRESSION_Pow : s += CSG_String::Format("%.6f * x^%.6f" , m_RConst, m_RCoeff); break; // Y = a * X^b
176 case REGRESSION_Exp : s += CSG_String::Format("%.6f * e^(%.6f * x)", m_RConst, m_RCoeff); break; // Y = a * e^(b * X)
177 case REGRESSION_Log : s += CSG_String::Format("%.6f %+.6f * ln(x)" , m_RConst, m_RCoeff); break; // Y = a + b * ln(X)
178 }
179
180 s += "\n";
181
182 return( s );
183}
184
185
187// //
189
190//---------------------------------------------------------
191double CSG_Regression::Get_x(double y) const
192{
193 if( m_R2 >= 0. )
194 {
195 switch( m_Type )
196 {
197 case REGRESSION_Linear: // Y = a + b * X -> X = (Y - a) / b
198 if( m_RCoeff != 0. )
199 return( (m_RConst * y) / m_RCoeff );
200 break;
201
202 case REGRESSION_Rez_X: // Y = a + b / X -> X = b / (Y - a)
203 if( (y = y - m_RConst) != 0. )
204 return( m_RCoeff / y );
205 break;
206
207 case REGRESSION_Rez_Y: // Y = a / (b - X) -> X = b - a / Y
208 if( y != 0. )
209 return( m_RCoeff - m_RConst / y );
210 break;
211
212 case REGRESSION_Pow: // Y = a * X^b -> X = (Y / a)^(1 / b)
213 if( m_RConst != 0. && m_RCoeff != 0. )
214 return( pow(y / m_RConst, 1. / m_RCoeff) );
215 break;
216
217 case REGRESSION_Exp: // Y = a * e^(b * X) -> X = ln(Y / a) / b
218 if( m_RConst != 0. && (y = y / m_RConst) > 0. && m_RCoeff != 0. )
219 return( log(y) / m_RCoeff );
220 break;
221
222 case REGRESSION_Log: // Y = a + b * ln(X) -> X = e^((Y - a) / b)
223 if( m_RCoeff != 0. )
224 return( exp((y - m_RConst) / m_RCoeff) );
225 break;
226 }
227 }
228
229 return( sqrt(-1.) ); // NaN
230}
231
232//---------------------------------------------------------
233double CSG_Regression::Get_y(double x) const
234{
235 if( m_R2 >= 0. )
236 {
237 switch( m_Type )
238 {
239 case REGRESSION_Linear: // Y = a + b * X
240 return( m_RConst + m_RCoeff * x );
241
242 case REGRESSION_Rez_X: // Y = a + b / X
243 if( x != 0. )
244 return( m_RConst + m_RCoeff / x );
245 break;
246
247 case REGRESSION_Rez_Y: // Y = a / (b - X)
248 if( (x = m_RCoeff - x) != 0. )
249 return( m_RConst / x );
250 break;
251
252 case REGRESSION_Pow: // Y = a * X^b
253 return( m_RConst * pow(x, m_RCoeff) );
254
255 case REGRESSION_Exp: // Y = a e^(b * X)
256 return( m_RConst * exp(m_RCoeff * x) );
257
258 case REGRESSION_Log: // Y = a + b * ln(X)
259 if( x > 0. )
260 return( m_RConst + m_RCoeff * log(x) );
261 break;
262 }
263 }
264
265 return( sqrt(-1.) );
266}
267
268
270// //
272
273//---------------------------------------------------------
274inline double CSG_Regression::_Y_Transform(double y)
275{
276 switch( m_Type )
277 {
278 default:
279 return( y );
280
281 case REGRESSION_Rez_Y:
282 if( y == 0. ) { y = M_FLT_EPSILON; }
283 return( 1. / y );
284
285 case REGRESSION_Pow:
286 case REGRESSION_Exp:
287 if( y <= 0. ) { y = M_FLT_EPSILON; }
288 return( log(y) );
289 }
290}
291
292//---------------------------------------------------------
293inline double CSG_Regression::_X_Transform(double x)
294{
295 switch( m_Type )
296 {
297 default:
298 return( x );
299
300 case REGRESSION_Rez_X:
301 if( x == 0. ) { x = M_FLT_EPSILON; }
302 return( 1. / x );
303
304 case REGRESSION_Pow:
305 case REGRESSION_Log:
306 if( x <= 0. ) { x = M_FLT_EPSILON; }
307 return( log(x) );
308 }
309}
310
311
313// //
315
316//---------------------------------------------------------
318{
319 m_R2 = -1.; // mark as invalid (unprocessed)
320 m_Type = Type;
321
322 if( Get_Count() < 2 )
323 {
324 return( false );
325 }
326
328
329 for(int i=0; i<Get_Count(); i++)
330 {
331 sx += _X_Transform(m_x[i]);
332 sy += _Y_Transform(m_y[i]);
333 }
334
337
338 if( m_xMin >= m_xMax || m_yMin >= m_yMax )
339 {
340 return( false );
341 }
342
343 //-----------------------------------------------------
344 double s_x = 0., s_y = 0., s_xx = 0., s_xy = 0., s_dx2 = 0., s_dy2 = 0., s_dxdy = 0.;
345
346 for(int i=0; i<Get_Count(); i++)
347 {
348 double x = _X_Transform(m_x[i]);
349 double y = _Y_Transform(m_y[i]);
350
351 s_x += x;
352 s_y += y;
353 s_xx += x * x;
354 s_xy += x * y;
355
356 x -= m_xMean;
357 y -= m_yMean;
358
359 s_dx2 += x * x;
360 s_dy2 += y * y;
361 s_dxdy += x * y;
362 }
363
364 //-----------------------------------------------------
365 m_RCoeff = s_dxdy / s_dx2;
366 m_RConst = (s_xx * s_y - s_x * s_xy) / (Get_Count() * s_xx - s_x * s_x);
367 m_R = s_dxdy / sqrt(s_dx2 * s_dy2);
368 m_R2 = m_R*m_R;
371
372 //-----------------------------------------------------
373 if( !bStdError )
374 {
375 m_SE = -1.;
376 }
377 else
378 {
379 m_SE = 0.;
380
381 for(int i=0; i<Get_Count(); i++)
382 {
383 double d = fabs(m_y[i] - Get_y(m_x[i]));
384
385 m_SE += d;
386 }
387
388 m_SE /= Get_Count();
389 }
390
391 //-----------------------------------------------------
392 switch( m_Type )
393 {
394 default: // case REGRESSION_Linear:
395 return( true );
396
397 case REGRESSION_Rez_X: {
398 m_xVar = 1. / m_xVar;
399 break; }
400
401 case REGRESSION_Rez_Y: {
402 double d = m_RConst;
403 m_RConst = 1. / m_RCoeff;
404 m_RCoeff = d * m_RCoeff;
405 m_yVar = 1. / m_yVar;
406 break; }
407
408 case REGRESSION_Pow: {
409 m_RConst = exp(m_RConst);
410 m_xVar = exp(m_xVar);
411 m_yVar = exp(m_yVar);
412 break; }
413
414 case REGRESSION_Exp: {
415 m_RConst = exp(m_RConst);
416 m_yVar = exp(m_yVar);
417 break; }
418
419 case REGRESSION_Log: {
420 m_xVar = exp(m_xVar);
421 break; }
422 }
423
425
426 if( !s.Create(m_x) ) { return( false ); } m_xMin = s.Get_Minimum(); m_xMean = s.Get_Mean(); m_xMax = s.Get_Maximum(); m_xVar = s.Get_Variance();
427 if( !s.Create(m_y) ) { return( false ); } m_yMin = s.Get_Minimum(); m_yMean = s.Get_Mean(); m_yMax = s.Get_Maximum(); m_yVar = s.Get_Variance();
428
429 return( true );
430}
431
432//---------------------------------------------------------
433bool CSG_Regression::Calculate(int nValues, double *x, double *y, TSG_Regression_Type Type, bool bStdError)
434{
435 return( Set_Values(nValues, x, y) && Calculate(Type, bStdError) );
436}
437
438
440// //
441// //
442// //
444
445//---------------------------------------------------------
#define SG_T(s)
Definition api_core.h:537
#define SG_Char
Definition api_core.h:536
double _X_Transform(double y)
bool Calculate(TSG_Regression_Type Type=REGRESSION_Linear, bool bStdError=false)
bool Set_Values(int nValues, double *x, double *y)
CSG_Vector m_y
Definition mat_tools.h:1677
double _Y_Transform(double x)
CSG_Vector m_x
Definition mat_tools.h:1677
bool Add_Values(double x, double y)
TSG_Regression_Type m_Type
Definition mat_tools.h:1679
int Get_Count(void) const
Definition mat_tools.h:1626
double Get_x(double y) const
virtual ~CSG_Regression(void)
double Get_y(double x) const
const SG_Char * asString(void)
double Get_Maximum(void)
Definition mat_tools.h:749
double Get_Mean(void)
Definition mat_tools.h:753
bool Create(bool bHoldValues=false)
double Get_Variance(void)
Definition mat_tools.h:754
double Get_Minimum(void)
Definition mat_tools.h:748
void Clear(void)
static CSG_String Format(const char *Format,...)
static double Get_F_Tail_from_R2(double R2, int nPredictors, int nSamples, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
double SG_Regression_Get_Adjusted_R2(double r2, int n, int p, TSG_Regression_Correction Correction)
TSG_Regression_Type
Definition mat_tools.h:1604
@ REGRESSION_Linear
Definition mat_tools.h:1605
@ REGRESSION_Rez_Y
Definition mat_tools.h:1607
@ REGRESSION_Log
Definition mat_tools.h:1610
@ REGRESSION_Exp
Definition mat_tools.h:1609
@ REGRESSION_Pow
Definition mat_tools.h:1608
@ REGRESSION_Rez_X
Definition mat_tools.h:1606
#define M_FLT_EPSILON
Definition mat_tools.h:121
TSG_Regression_Correction
Definition mat_tools.h:1583
@ REGRESSION_CORR_Smith
Definition mat_tools.h:1585
@ REGRESSION_CORR_Wherry_1
Definition mat_tools.h:1586
@ REGRESSION_CORR_Pratt
Definition mat_tools.h:1589
@ REGRESSION_CORR_None
Definition mat_tools.h:1584
@ REGRESSION_CORR_Claudy_3
Definition mat_tools.h:1590
@ REGRESSION_CORR_Wherry_2
Definition mat_tools.h:1587
@ REGRESSION_CORR_Olkin_Pratt
Definition mat_tools.h:1588
SAGA_API_DLL_EXPORT double SG_Regression_Get_Adjusted_R2(double R2, int nSamples, int nPredictors, TSG_Regression_Correction Correction=REGRESSION_CORR_Wherry_1)