SAGA API  v9.9
mat_tools.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_tools.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 <time.h>
54 #include <cfloat>
55 
56 #include "mat_tools.h"
57 
58 #include "table.h"
59 #include "grid.h"
60 #include "grids.h"
61 
62 
64 // //
65 // //
66 // //
68 
69 //---------------------------------------------------------
70 double SG_Get_Square(double Value)
71 {
72  return( Value * Value );
73 }
74 
75 
77 // //
78 // //
79 // //
81 
82 //---------------------------------------------------------
83 double SG_Get_Rounded(double Value, int Decimals)
84 {
85  if( Decimals < 0 )
86  {
87  return( Value );
88  }
89 
90  if( Decimals == 0 )
91  {
92  return( floor(0.5 + Value) );
93  }
94 
95  double d = pow(10., Decimals);
96  double v = Value * d;
97 
98  if( fabs(v - floor(v)) > 0. )
99  {
100  return( floor(0.5 + v) / d );
101  }
102 
103  return( Value );
104 }
105 
106 //---------------------------------------------------------
107 double SG_Get_Rounded_To_SignificantFigures(double Value, int Decimals)
108 {
109  if( Decimals <= 0 || Value == 0. )
110  {
111  return( (int)(0.5 + Value) );
112  }
113 
114  Decimals = (int)(-(ceil(log10(fabs(Value))) - Decimals));
115 
116  if( Decimals > 0 )
117  {
118  double d = pow(10., Decimals);
119 
120  return( Value < 0.
121  ? -((int)(0.5 - Value * d)) / d
122  : ((int)(0.5 + Value * d)) / d
123  );
124  }
125  else
126  {
127  double d = pow(10., -Decimals);
128 
129  return( Value < 0.
130  ? -((int)(0.5 - Value / d)) * d
131  : ((int)(0.5 + Value / d)) * d
132  );
133  }
134 }
135 
136 
138 // //
139 // //
140 // //
142 
143 //---------------------------------------------------------
144 int SG_Get_Digit_Count(int Number)
145 {
146  Number = abs(Number);
147 
148  return( Number < 10 ? 1 : 1 + (int)log10((double)Number) );
149 }
150 
151 
153 // //
154 // //
155 // //
157 
158 //---------------------------------------------------------
159 CSG_String SG_Get_Double_asString(double Number, int Width, int Precision, bool bScientific)
160 {
161  if( bScientific )
162  {
163  if( Width > 0 && Precision >= 0 ) return( CSG_String::Format("%*.*e", Width, Precision, Number) );
164  if( Width > 0 ) return( CSG_String::Format("%*e" , Width , Number) );
165  if( Precision >= 0 ) return( CSG_String::Format("%.*e" , Precision, Number) );
166 
167  return( CSG_String::Format("%e", Number) );
168  }
169  else
170  {
171  if( Width > 0 && Precision >= 0 ) return( CSG_String::Format("%*.*f", Width, Precision, Number) );
172  if( Width > 0 ) return( CSG_String::Format("%*f" , Width , Number) );
173  if( Precision >= 0 ) return( CSG_String::Format("%.*f" , Precision, Number) );
174 
175  return( CSG_String::Format("%f", Number) );
176  }
177 }
178 
179 
181 // //
182 // //
183 // //
185 
186 //---------------------------------------------------------
187 int SG_Compare_Int(const void *a, const void *b)
188 {
189  if( *((int *)a) < *((int *)b) )
190  return( -1 );
191 
192  if( *((int *)a) > *((int *)b) )
193  return( 1 );
194 
195  return( 0 );
196 }
197 
198 //---------------------------------------------------------
199 int SG_Compare_Double(const void *a, const void *b)
200 {
201  if( *((double *)a) < *((double *)b) )
202  return( -1 );
203 
204  if( *((double *)a) > *((double *)b) )
205  return( 1 );
206 
207  return( 0 );
208 }
209 
210 //---------------------------------------------------------
211 int SG_Compare_Char_Ptr(const void *a, const void *b)
212 {
213  return( strcmp((const char *)a, (const char *)b) );
214 }
215 
216 
218 // //
219 // //
220 // //
222 
223 //---------------------------------------------------------
224 double SG_Degree_To_Decimal(double Deg, double Min, double Sec)
225 {
226  return( Deg > 0.
227  ? (Deg + Min / 60. + Sec / 3600.)
228  : (Deg - Min / 60. - Sec / 3600.)
229  );
230 }
231 
232 //---------------------------------------------------------
233 void SG_Decimal_To_Degree(double Value, double &Deg, double &Min, double &Sec)
234 {
235  Sec = fmod(Value < 0. ? -Value : Value, 360.);
236 
237  Deg = (int)Sec; Sec = 60. * (Sec - Deg);
238  Min = (int)Sec; Sec = 60. * (Sec - Min);
239 
240  if( Value < 0. )
241  {
242  Deg = -Deg;
243  }
244 }
245 
246 
248 // //
249 // //
250 // //
252 
253 //---------------------------------------------------------
255 {
256  Initialize();
257 }
258 
259 //---------------------------------------------------------
261 {
262  Initialize((unsigned)time(NULL));
263 }
264 
265 //---------------------------------------------------------
266 void CSG_Random::Initialize(unsigned int Value)
267 {
268  srand(Value);
269 }
270 
271 //---------------------------------------------------------
272 // Uniform distributed pseudo-random numbers in the range from 0 to 1.
273 //
275 {
276  return( 1. * rand() / (double)RAND_MAX );
277 }
278 
279 //---------------------------------------------------------
280 // Uniform distributed pseudo-random numbers in the range from min to max.
281 //
282 double CSG_Random::Get_Uniform(double min, double max)
283 {
284  return( min + (max - min) * rand() / (double)RAND_MAX );
285 }
286 
287 //---------------------------------------------------------
288 // Generating Gaussian pseudo-random numbers using
289 // the polar form of the Box-Muller transformation.
290 //
291 // Box, G.E.P, Muller, M.E. (1958):
292 // 'A note on the generation of random normal deviates',
293 // Annals Math. Stat, V. 29, pp. 610-611
294 //
295 // Link: http://www.taygeta.com/random/gaussian.html
296 //
297 //---------------------------------------------------------
298 double CSG_Random::Get_Gaussian(double mean, double stddev)
299 {
300  double x1, x2, w;
301 
302  do
303  {
304  x1 = 2. * Get_Uniform() - 1.;
305  x2 = 2. * Get_Uniform() - 1.;
306 
307  w = x1 * x1 + x2 * x2;
308  }
309  while( w >= 1. );
310 
311  w = sqrt((-2. * log(w)) / w);
312 
313  return( mean + stddev * x1 * w );
314 }
315 
316 
318 // //
319 // //
320 // //
322 
323 //---------------------------------------------------------
325 {
326  Create(false);
327 }
328 
330 {
331  Create(bHoldValues);
332 }
333 
335 {
336  Create(Statistics);
337 }
338 
339 CSG_Simple_Statistics::CSG_Simple_Statistics(double Mean, double StdDev, sLong Count)
340 {
341  Create(Mean, StdDev, Count);
342 }
343 
345 {
346  Create(Values, bHoldValues);
347 }
348 
349 //---------------------------------------------------------
350 bool CSG_Simple_Statistics::Create(bool bHoldValues)
351 {
352  Invalidate();
353 
354  m_Values.Create(bHoldValues ? sizeof(double) : 0, 0, TSG_Array_Growth::SG_ARRAY_GROWTH_1);
355 
356  return( true );
357 }
358 
360 {
361  m_bEvaluated = Statistics.m_bEvaluated;
362 
363  m_nValues = Statistics.m_nValues;
364  m_Weights = Statistics.m_Weights;
365  m_Sum = Statistics.m_Sum;
366  m_Sum2 = Statistics.m_Sum2;
367 
368  m_Minimum = Statistics.m_Minimum;
369  m_Maximum = Statistics.m_Maximum;
370  m_Range = Statistics.m_Range;
371  m_Mean = Statistics.m_Mean;
372  m_Variance = Statistics.m_Variance;
373  m_StdDev = Statistics.m_StdDev;
374 
375  m_Kurtosis = Statistics.m_Kurtosis;
376  m_Skewness = Statistics.m_Skewness;
377 
378  m_Gini = Statistics.m_Gini;
379 
380  m_bSorted = Statistics.m_bSorted;
381  m_Values .Create(Statistics.m_Values);
382 
383  return( true );
384 }
385 
386 bool CSG_Simple_Statistics::Create(double Mean, double StdDev, sLong Count)
387 {
388  Invalidate();
389 
390  m_bEvaluated = 1;
391 
392  m_Mean = Mean;
393  m_StdDev = StdDev;
394  m_Variance = StdDev*StdDev;
395  m_nValues = Count;
396  m_Weights = (double)Count;
397 
398  m_Sum = m_Weights * m_Mean;
400 
401  m_Minimum = m_Mean - 1.5 * m_StdDev;
402  m_Maximum = m_Mean + 1.5 * m_StdDev;
404 
405  return( true );
406 }
407 
408 bool CSG_Simple_Statistics::Create(const CSG_Vector &Values, bool bHoldValues)
409 {
410  if( Create(bHoldValues) )
411  {
412  for(sLong i=0; i<Values.Get_Size(); i++)
413  {
414  Add_Value(Values[i]);
415  }
416 
417  return( true );
418  }
419 
420  return( false );
421 }
422 
423 //---------------------------------------------------------
425 {
426  if( m_nValues < 1 || nValues < 1 || m_nValues == nValues )
427  {
428  return( false );
429  }
430 
431  double Scale = nValues / (double)m_nValues;
432 
433  m_Weights *= Scale;
434  m_Sum *= Scale;
435  m_Sum2 *= Scale;
436 
437  m_nValues = nValues;
438 
439  m_bEvaluated = 0;
440 
441  m_Values.Destroy();
442 
443  return( true );
444 }
445 
446 //---------------------------------------------------------
448 {
449  m_bEvaluated = 0;
450 
451  m_nValues = 0;
452  m_Weights = 0.;
453  m_Sum = 0.;
454  m_Sum2 = 0.;
455 
456  m_Minimum = 0.;
457  m_Maximum = 0.;
458  m_Range = 0.;
459  m_Mean = 0.;
460  m_Variance = 0.;
461  m_StdDev = 0.;
462 
463  m_Kurtosis = 0.;
464  m_Skewness = 0.;
465 
466  m_Gini = -1.;
467 
468  m_bSorted = false;
469  m_Values .Destroy();
470 }
471 
472 //---------------------------------------------------------
474 {
475  _Evaluate();
476 
477  return( is_Evaluated() > 0 );
478 }
479 
480 //---------------------------------------------------------
482 {
483  if( Statistics.m_nValues <= 0 )
484  {
485  return;
486  }
487 
488  if( m_nValues == 0 )
489  {
490  Create(Statistics);
491 
492  return;
493  }
494 
495  //--------------------------------------------------------
496  if( (sLong)m_Values.Get_Size() == m_nValues && (sLong)Statistics.m_Values.Get_Size() == Statistics.m_nValues && m_Values.Set_Array((size_t)(m_nValues + Statistics.m_nValues)) )
497  {
498  for(sLong i=0, j=m_nValues; i<Statistics.m_nValues; i++, j++)
499  {
500  ((double *)m_Values.Get_Array())[j] = Statistics.Get_Value(i);
501  }
502  }
503  else
504  {
505  m_Values.Destroy();
506  }
507 
508  m_nValues += Statistics.m_nValues;
509  m_Weights += Statistics.m_Weights;
510  m_Sum += Statistics.m_Sum;
511  m_Sum2 += Statistics.m_Sum2;
512 
513  if( m_Minimum > Statistics.m_Minimum )
514  m_Minimum = Statistics.m_Minimum;
515 
516  if( m_Maximum < Statistics.m_Maximum )
517  m_Maximum = Statistics.m_Maximum;
518 
519  m_Kurtosis = 0.;
520  m_Skewness = 0.;
521 
522  m_bEvaluated = 0;
523  m_bSorted = false;
524 }
525 
526 //---------------------------------------------------------
527 void CSG_Simple_Statistics::Add_Value(double Value, double Weight)
528 {
529  if( m_nValues == 0 )
530  {
531  m_Minimum = m_Maximum = Value;
532  }
533  else if( m_Minimum > Value )
534  {
535  m_Minimum = Value;
536  }
537  else if( m_Maximum < Value )
538  {
539  m_Maximum = Value;
540  }
541 
542  if( Weight )
543  {
544  m_Weights += fabs(Weight);
545  m_Sum += Weight * Value;
546  m_Sum2 += Weight * Value*Value;
547 
548  m_bEvaluated = 0;
549 
550  if( m_Values.Get_Value_Size() > 0 && m_Values.Inc_Array() )
551  {
552  m_bSorted = false;
553 
554  ((double *)m_Values.Get_Array())[m_nValues] = Value;
555  }
556 
557  m_nValues++;
558  }
559 }
560 
561 //---------------------------------------------------------
563 {
564  if( m_bEvaluated == 0 && m_Weights > 0. )
565  {
566  m_bEvaluated = 1;
567 
569  m_Mean = m_Sum / m_Weights;
571  m_StdDev = m_Variance > 0. ? sqrt(m_Variance) : 0.;
572  }
573 
574  //-----------------------------------------------------
575  if( m_bEvaluated == 1 && Level > 1 )
576  {
577  m_bEvaluated = 2;
578 
579  m_Kurtosis = 0.;
580  m_Skewness = 0.;
581 
582  if( Get_StdDev() > 0. && m_Values.Get_Size() > 0 )
583  {
584  for(sLong i=0; i<Get_Count(); i++)
585  {
586  double d = (Get_Value(i) - Get_Mean()) / Get_StdDev();
587 
588  m_Kurtosis += d*d*d*d;
589  m_Skewness += d*d*d;
590  }
591 
592  m_Kurtosis /= Get_Count();
593  m_Skewness /= Get_Count();
594  // m_Skewness *= Get_Count() / ((Get_Count() - 1) * (Get_Count() - 2));
595  }
596  }
597 }
598 
599 //---------------------------------------------------------
607 {
608  return( Get_StdDev() != 0. ? (Get_Mean() - Get_Median()) / Get_StdDev() : 0. );
609 }
610 
611 //---------------------------------------------------------
618 double CSG_Simple_Statistics::Get_Quantile(double Quantile)
619 {
620  if( m_Values.Get_Size() < 1 )
621  {
622  return( m_Mean );
623  }
624 
625  //-----------------------------------------------------
626  if( !m_bSorted )
627  {
628  qsort(m_Values.Get_Array(), m_Values.Get_Size(), sizeof(double), SG_Compare_Double);
629 
630  m_bSorted = true;
631  }
632 
633  if( Quantile <= 0. || m_Values.Get_Size() == 1 )
634  {
635  return( Get_Values()[0] );
636  }
637 
638  if( Quantile >= 1. )
639  {
640  return( Get_Values()[m_Values.Get_Size() - 1] );
641  }
642 
643  //-----------------------------------------------------
644  double r = Quantile * (m_Values.Get_Size() - 1);
645 
646  sLong i = (sLong)r; r -= i;
647 
648  return( r == 0. ? Get_Values()[i] : ((1. - r) * Get_Values()[i] + r * Get_Values()[i + 1]) );
649 }
650 
651 //---------------------------------------------------------
658 double CSG_Simple_Statistics::Get_Percentile(double Percentile)
659 {
660  return( Get_Quantile(Percentile / 100.) );
661 }
662 
663 //---------------------------------------------------------
670 {
671  return( Get_Quantile(0.5) );
672 }
673 
674 //---------------------------------------------------------
682 {
683  if( m_Gini < 0. && m_Values.Get_Size() > 1 )
684  {
685  if( !m_bSorted )
686  {
687  qsort(m_Values.Get_Array(), m_Values.Get_Size(), sizeof(double), SG_Compare_Double);
688 
689  m_bSorted = true;
690  }
691 
692  m_Gini = 0.;
693 
694  for(sLong i=0; i<Get_Count(); i++)
695  {
696  m_Gini += (i + 1.) * Get_Value(i);
697  }
698 
699  m_Gini = 2. * m_Gini / (Get_Count() * Get_Sum()) - (Get_Count() + 1.) / Get_Count();
700  }
701 
702  return( m_Gini );
703 }
704 
705 //---------------------------------------------------------
711 {
712  if( m_Values.Get_Size() == 0 ) { return( -1 ); }
713 
714  size_t Index = 0;
715  double Value = Get_Values()[Index];
716 
717  for(size_t i=1; i<(size_t)m_Values.Get_Size(); i++)
718  {
719  if( Value > Get_Values()[i] )
720  {
721  Index = i;
722  Value = Get_Values()[i];
723  }
724  }
725 
726  return( (sLong)Index );
727 }
728 
729 //---------------------------------------------------------
735 {
736  if( m_Values.Get_Size() == 0 ) { return( -1 ); }
737 
738  size_t Index = 0;
739  double Value = Get_Values()[Index];
740 
741  for(size_t i=1; i<(size_t)m_Values.Get_Size(); i++)
742  {
743  if( Value < Get_Values()[i] )
744  {
745  Index = i;
746  Value = Get_Values()[i];
747  }
748  }
749 
750  return( (sLong)Index );
751 }
752 
753 //---------------------------------------------------------
758 sLong CSG_Simple_Statistics::Get_nValues_Above(double Threshold, bool bEquals)
759 {
760  if( m_Values.Get_Size() == 0 ) { return( -1 ); }
761 
762  sLong n = 0;
763 
764  for(sLong i=0; i<Get_Count(); i++)
765  {
766  if( (bEquals && Get_Value(i) >= Threshold) || Get_Value(i) > Threshold )
767  {
768  n++;
769  }
770  }
771 
772  return( n );
773 }
774 
775 //---------------------------------------------------------
780 sLong CSG_Simple_Statistics::Get_nValues_Below(double Threshold, bool bEquals)
781 {
782  if( m_Values.Get_Size() == 0 ) { return( -1 ); }
783 
784  sLong n = 0;
785 
786  for(sLong i=0; i<Get_Count(); i++)
787  {
788  if( (bEquals && Get_Value(i) <= Threshold) || Get_Value(i) < Threshold )
789  {
790  n++;
791  }
792  }
793 
794  return( n );
795 }
796 
797 
799 // //
800 // //
801 // //
803 
804 //---------------------------------------------------------
806 {
807  int Index = 0;
808 
809  bWeighted = bWeighted && m_bWeights;
810 
811  for(int i=1; i<Get_Count(); i++)
812  {
813  if( bWeighted )
814  {
815  if( m_Weight[i] > m_Weight[Index] )
816  {
817  Index = i;
818  }
819  }
820  else
821  {
822  if( m_Count[i] > m_Count[Index] )
823  {
824  Index = i;
825  }
826  }
827  }
828 
829  return( Index );
830 }
831 
832 //---------------------------------------------------------
834 {
835  int Index = 0;
836 
837  bWeighted = bWeighted && m_bWeights;
838 
839  for(int i=1; i<Get_Count(); i++)
840  {
841  if( bWeighted )
842  {
843  if( m_Weight[i] < m_Weight[Index] )
844  {
845  Index = i;
846  }
847  }
848  else
849  {
850  if( m_Count[i] < m_Count[Index] )
851  {
852  Index = i;
853  }
854  }
855  }
856 
857  return( Index );
858 }
859 
860 
862 // //
864 
865 //---------------------------------------------------------
867 {
868  m_bWeights = bWeights;
869 
870  m_Count.Destroy();
871  m_Value.Destroy();
872 }
873 
874 //---------------------------------------------------------
875 void CSG_Unique_Number_Statistics::Add_Value(double Value, double Weight)
876 {
877  for(int i=0; i<Get_Count(); i++)
878  {
879  if( Value == m_Value[i] )
880  {
881  m_Count[i]++;
882 
883  if( m_bWeights && Weight > 0. )
884  {
885  m_Weight[i] += Weight;
886  }
887 
888  return;
889  }
890  }
891 
892  m_Count.Add(1);
893  m_Value.Add_Row(Value);
894 
895  if( m_bWeights && Weight > 0. )
896  {
897  m_Weight.Add_Row(Weight);
898  }
899 }
900 
901 //---------------------------------------------------------
903 {
904  for(int i=0; i<Get_Count(); i++)
905  {
906  if( Value == m_Value[i] )
907  {
908  return( i );
909  }
910  }
911 
912  return( -1 );
913 }
914 
915 
917 // //
919 
920 //---------------------------------------------------------
922 {
923  m_bWeights = bWeights;
924 
925  m_Count.Destroy();
926  m_Value.Clear();
927 }
928 
929 //---------------------------------------------------------
930 void CSG_Unique_String_Statistics::Add_Value(const CSG_String &Value, double Weight)
931 {
932  for(int i=0; i<Get_Count(); i++)
933  {
934  if( Value.Cmp(m_Value[i]) == 0 )
935  {
936  m_Count[i]++;
937 
938  if( m_bWeights && Weight > 0. )
939  {
940  m_Weight[i] += Weight;
941  }
942 
943  return;
944  }
945  }
946 
947  m_Count.Add(1);
948  m_Value.Add(Value);
949 
950  if( m_bWeights && Weight > 0. )
951  {
952  m_Weight.Add_Row(Weight);
953  }
954 }
955 
956 //---------------------------------------------------------
958 {
959  for(int i=0; i<Get_Count(); i++)
960  {
961  if( Value.Cmp(m_Value[i]) == 0 )
962  {
963  return( i );
964  }
965  }
966 
967  return( -1 );
968 }
969 
970 
972 // //
973 // //
974 // //
976 
977 //---------------------------------------------------------
979 {
980  m_pTable = new CSG_Table;
981 
982  Create(Type);
983 }
984 
985 //---------------------------------------------------------
987 {
988  delete(m_pTable);
989 }
990 
991 //---------------------------------------------------------
993 {
994  m_pTable->Destroy();
995 
996  m_pTable->Add_Field("VALUE", Type);
997  m_pTable->Add_Field("COUNT", SG_DATATYPE_ULong);
998 }
999 
1000 //---------------------------------------------------------
1002 {
1003  m_pTable->Del_Records();
1004 }
1005 
1006 //---------------------------------------------------------
1008 {
1009  return( m_pTable->Get_Field_Type(0) );
1010 }
1011 
1012 
1014 // //
1016 
1017 //---------------------------------------------------------
1019 {
1020  CSG_Table_Record *pRecord = m_pTable->Find_Record(0, Value);
1021 
1022  return( pRecord ? (int)pRecord->Get_Index() : -1);
1023 }
1024 
1025 //---------------------------------------------------------
1027 {
1028  CSG_Table_Record *pRecord = m_pTable->Find_Record(0, Value);
1029 
1030  return( pRecord ? (int)pRecord->Get_Index() : -1);
1031 }
1032 
1033 //---------------------------------------------------------
1035 {
1036  CSG_Table_Record *pRecord = m_pTable->Find_Record(0, Value);
1037 
1038  return( pRecord ? (int)pRecord->Get_Index() : -1);
1039 }
1040 
1041 
1043 // //
1045 
1046 //---------------------------------------------------------
1048 {
1049  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(Get_Category(Value));
1050 
1051  if( !pRecord )
1052  {
1053  (pRecord = m_pTable->Add_Record())->Set_Value(0, Value);
1054 
1055  if( m_pTable->Get_Count() > 16 || m_pTable->is_Indexed() )
1056  {
1057  Sort();
1058  }
1059  }
1060 
1061  pRecord->Add_Value(1, 1);
1062 
1063  return( (int)(m_pTable->Get_Count() - 1) );
1064 }
1065 
1066 //---------------------------------------------------------
1068 {
1069  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(Get_Category(Value));
1070 
1071  if( !pRecord )
1072  {
1073  (pRecord = m_pTable->Add_Record())->Set_Value(0, Value);
1074 
1075  if( m_pTable->Get_Count() > 16 || m_pTable->is_Indexed() )
1076  {
1077  Sort();
1078  }
1079  }
1080 
1081  pRecord->Add_Value(1, 1);
1082 
1083  return( (int)(m_pTable->Get_Count() - 1) );
1084 }
1085 
1086 //---------------------------------------------------------
1088 {
1089  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(Get_Category(Value));
1090 
1091  if( !pRecord )
1092  {
1093  (pRecord = m_pTable->Add_Record())->Set_Value(0, Value);
1094 
1095  if( m_pTable->Get_Count() > 16 || m_pTable->is_Indexed() )
1096  {
1097  Sort();
1098  }
1099  }
1100 
1101  pRecord->Add_Value(1, 1);
1102 
1103  return( (int)(m_pTable->Get_Count() - 1) );
1104 }
1105 
1106 //---------------------------------------------------------
1107 // sort categories ascending
1109 {
1110  return( m_pTable->Set_Index(0, TABLE_INDEX_Ascending) );
1111 }
1112 
1113 
1115 // //
1117 
1118 //---------------------------------------------------------
1119 // returns the number of categories.
1121 {
1122  return( (int)m_pTable->Get_Count() );
1123 }
1124 
1125 //---------------------------------------------------------
1126 // returns the number of observations for the i'th category.
1128 {
1129  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(i);
1130 
1131  return( pRecord ? pRecord->asInt(1) : 0 );
1132 }
1133 
1134 //---------------------------------------------------------
1136 {
1137  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(i);
1138 
1139  return( pRecord ? pRecord->asInt(0) : 0 );
1140 }
1141 
1142 //---------------------------------------------------------
1144 {
1145  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(i);
1146 
1147  return( pRecord ? pRecord->asDouble(0) : 0 );
1148 }
1149 
1150 //---------------------------------------------------------
1152 {
1153  CSG_Table_Record *pRecord = m_pTable->Get_Record_byIndex(i);
1154 
1155  return( pRecord ? pRecord->asString(0) : SG_T("") );
1156 }
1157 
1158 
1160 // //
1162 
1163 //---------------------------------------------------------
1165 {
1166  if( m_pTable->Get_Count() > 0 )
1167  {
1168  int Index = 0, Count = m_pTable->Get_Record_byIndex(0)->asInt(1);
1169 
1170  for(int i=1; i<m_pTable->Get_Count(); i++)
1171  {
1172  if( Count < m_pTable->Get_Record_byIndex(i)->asInt(1) )
1173  {
1174  Index = i;
1175  Count = m_pTable->Get_Record_byIndex(i)->asInt(1);
1176  }
1177  }
1178 
1179  return( Index );
1180  }
1181 
1182  return( -1 );
1183 }
1184 
1185 //---------------------------------------------------------
1187 {
1188  if( m_pTable->Get_Count() > 0 )
1189  {
1190  int Index = 0, Count = m_pTable->Get_Record_byIndex(0)->asInt(1);
1191 
1192  for(int i=1; i<m_pTable->Get_Count(); i++)
1193  {
1194  if( Count > m_pTable->Get_Record_byIndex(i)->asInt(1) )
1195  {
1196  Index = i;
1197  Count = m_pTable->Get_Record_byIndex(i)->asInt(1);
1198  }
1199  }
1200 
1201  return( Index );
1202  }
1203 
1204  return( -1 );
1205 }
1206 
1207 
1209 // //
1210 // //
1211 // //
1213 
1214 //---------------------------------------------------------
1216 {
1217  _On_Construction();
1218 }
1219 
1220 //---------------------------------------------------------
1222 {
1223  _On_Construction();
1224 
1225  Create(Histogram);
1226 }
1227 
1228 //---------------------------------------------------------
1229 CSG_Histogram::CSG_Histogram(size_t nClasses, double Minimum, double Maximum)
1230 {
1231  _On_Construction();
1232 
1233  Create(nClasses, Minimum, Maximum);
1234 }
1235 
1236 //---------------------------------------------------------
1237 CSG_Histogram::CSG_Histogram(size_t nClasses, const CSG_Vector &Values, double Minimum, double Maximum, size_t maxSamples)
1238 {
1239  _On_Construction();
1240 
1241  Create(nClasses, Values, Minimum, Maximum, maxSamples);
1242 }
1243 
1244 //---------------------------------------------------------
1245 CSG_Histogram::CSG_Histogram(size_t nClasses, CSG_Table *pTable, int Field, double Minimum, double Maximum, size_t maxSamples)
1246 {
1247  _On_Construction();
1248 
1249  Create(nClasses, pTable, Field, Minimum, Maximum, maxSamples);
1250 }
1251 
1252 //---------------------------------------------------------
1253 CSG_Histogram::CSG_Histogram(size_t nClasses, class CSG_Grid *pGrid, double Minimum, double Maximum, size_t maxSamples)
1254 {
1255  _On_Construction();
1256 
1257  Create(nClasses, pGrid, Minimum, Maximum, maxSamples);
1258 }
1259 
1260 //---------------------------------------------------------
1261 CSG_Histogram::CSG_Histogram(size_t nClasses, CSG_Grids *pGrids, double Minimum, double Maximum, size_t maxSamples)
1262 {
1263  _On_Construction();
1264 
1265  Create(nClasses, pGrids, Minimum, Maximum, maxSamples);
1266 }
1267 
1268 //---------------------------------------------------------
1270 {
1271  Destroy();
1272 }
1273 
1274 //---------------------------------------------------------
1276 {
1277  m_Statistics.Create();
1278 
1279  SG_FREE_SAFE(m_Elements );
1280  SG_FREE_SAFE(m_Cumulative);
1281 
1282  _On_Construction();
1283 
1284  return( true );
1285 }
1286 
1287 
1289 // //
1291 
1292 //---------------------------------------------------------
1293 void CSG_Histogram::_On_Construction(void)
1294 {
1295  m_nClasses = 0;
1296  m_Elements = NULL;
1297  m_Cumulative = NULL;
1298  m_Minimum = 0.;
1299  m_Maximum = 0.;
1300  m_ClassWidth = 1.;
1301 }
1302 
1303 //---------------------------------------------------------
1304 bool CSG_Histogram::_Create(size_t nClasses, double Minimum, double Maximum)
1305 {
1306  if( nClasses > 0 && Minimum < Maximum )
1307  {
1308  Destroy();
1309 
1310  m_Elements = (size_t *)SG_Calloc(nClasses, sizeof(size_t));
1311  m_Cumulative = (size_t *)SG_Calloc(nClasses, sizeof(size_t));
1312 
1313  if( m_Elements && m_Cumulative )
1314  {
1315  m_nClasses = nClasses;
1316  m_Minimum = Minimum;
1317  m_Maximum = Maximum;
1318  m_ClassWidth = (Maximum - Minimum) / (double)m_nClasses;
1319 
1320  return( true );
1321  }
1322  }
1323 
1324  Destroy();
1325 
1326  return( false );
1327 }
1328 
1329 //---------------------------------------------------------
1330 void CSG_Histogram::Add_Value(double Value)
1331 {
1332  m_Statistics += Value;
1333 
1334  if( m_nClasses > 0 && m_Minimum <= Value && Value <= m_Maximum )
1335  {
1336  size_t Class = (size_t)((Value - m_Minimum) / m_ClassWidth);
1337 
1338  if( Class >= m_nClasses )
1339  {
1340  Class = m_nClasses - 1;
1341  }
1342 
1343  m_Elements[Class]++;
1344  }
1345 }
1346 
1347 //---------------------------------------------------------
1349 {
1350  if( m_nClasses > 0 && Scale > 0. )
1351  {
1352  m_Statistics.Set_Count((sLong)(Scale * Get_Element_Count()));
1353 
1354  for(size_t i=0; i<m_nClasses; i++)
1355  {
1356  m_Elements[i] = (size_t)(Scale * m_Elements[i]);
1357  }
1358 
1359  return( Update() );
1360  }
1361 
1362  return( false );
1363 }
1364 
1365 //---------------------------------------------------------
1367 {
1368  if( m_nClasses > 0 )
1369  {
1370  m_Statistics.Get_Mean(); // _Evaluate()
1371 
1372  m_nMaximum = m_Cumulative[0] = m_Elements[0];
1373 
1374  for(size_t i=1; i<m_nClasses; i++)
1375  {
1376  m_Cumulative[i] = m_Cumulative[i - 1] + m_Elements[i];
1377 
1378  if( m_nMaximum < m_Elements[i] )
1379  {
1380  m_nMaximum = m_Elements[i];
1381  }
1382  }
1383 
1384  return( Get_Element_Count() > 0 );
1385  }
1386 
1387  return( false );
1388 }
1389 
1390 //---------------------------------------------------------
1391 bool CSG_Histogram::_Update(sLong nElements)
1392 {
1393  if( nElements > 0 && m_Statistics.Get_Count() > 0 )
1394  {
1395  double Scale = (double)nElements / (double)m_Statistics.Get_Count();
1396 
1397  m_Statistics.Create(m_Statistics.Get_Mean(), m_Statistics.Get_StdDev(), nElements);
1398 
1399  for(size_t i=1; i<m_nClasses; i++)
1400  {
1401  m_Elements[i] = (size_t)(0.5 + Scale * m_Elements[i]);
1402  }
1403  }
1404 
1405  return( Update() );
1406 }
1407 
1409 {
1410  if( m_nClasses == 0
1411  || m_nClasses != Histogram.m_nClasses
1412  || m_Minimum != Histogram.m_Minimum
1413  || m_Maximum != Histogram.m_Maximum )
1414  {
1415  return( false );
1416  }
1417 
1418  m_Statistics += Histogram.m_Statistics;
1419 
1420  for( size_t i=0; i<m_nClasses; i++ )
1421  {
1422  m_Elements[i] += Histogram.m_Elements[i];
1423  }
1424 
1425  return( true );
1426 }
1427 
1428 //---------------------------------------------------------
1432 double CSG_Histogram::Get_Quantile(double Quantile) const
1433 {
1434  if( m_nClasses < 2 ) { return( 0. ); }
1435 
1436  if( Quantile <= 0. ) { return( m_Minimum ); }
1437  if( Quantile >= 1. ) { return( m_Maximum ); }
1438 
1439  size_t n = (size_t)(Quantile * Get_Element_Count()); // number of elements
1440 
1441  for(size_t i=0, n0=0; i<m_nClasses; n0=m_Cumulative[i++])
1442  {
1443  if( n < m_Cumulative[i] )
1444  {
1445  if( m_Cumulative[i] >= n0 )
1446  {
1447  return( Get_Center(i) );
1448  }
1449 
1450  double d = (n - n0) / (double)(m_Cumulative[i] - n0);
1451 
1452  return( Get_Break(i) + d * m_ClassWidth );
1453  }
1454  else if( n == m_Cumulative[i] )
1455  {
1456  return( Get_Break(i + 1) );
1457  }
1458  }
1459 
1460  return( m_Maximum );
1461 }
1462 
1463 //---------------------------------------------------------
1467 double CSG_Histogram::Get_Percentile(double Percentile) const
1468 {
1469  return( Get_Quantile(Percentile / 100.) );
1470 }
1471 
1472 //---------------------------------------------------------
1476 double CSG_Histogram::Get_Quantile_Value(double Value) const
1477 {
1478  if( m_nClasses < 2 ) { return( 0. ); }
1479 
1480  if( Value <= m_Minimum ) { return( 0. ); }
1481  if( Value >= m_Maximum ) { return( 1. ); }
1482 
1483  size_t Class = (size_t)(m_nClasses * (Value - m_Minimum) / (m_Maximum - m_Minimum));
1484 
1485  if( Class >= m_nClasses )
1486  {
1487  return( 1. );
1488  }
1489 
1490  if( Class < 1 )
1491  {
1492  double dq = m_Cumulative[Class] / (double)Get_Element_Count();
1493 
1494  return( dq * (Value - m_Minimum) / m_ClassWidth );
1495  }
1496 
1497  double q0 = m_Cumulative[Class - 1] / (double)Get_Element_Count();
1498  double dq = (m_Cumulative[Class ] / (double)Get_Element_Count()) - q0;
1499 
1500  return( q0 + dq * (Value - Get_Break(Class)) / m_ClassWidth );
1501 }
1502 
1503 //---------------------------------------------------------
1507 double CSG_Histogram::Get_Percentile_Value(double Value) const
1508 {
1509  return( Get_Quantile_Value(Value) * 100. );
1510 }
1511 
1512 
1514 // //
1516 
1517 //---------------------------------------------------------
1518 bool CSG_Histogram::Create(const CSG_Histogram &Histogram)
1519 {
1520  if( !_Create(Histogram.m_nClasses, Histogram.m_Minimum, Histogram.m_Maximum) )
1521  {
1522  return( false );
1523  }
1524 
1525  m_Statistics = Histogram.m_Statistics;
1526  m_ClassWidth = Histogram.m_ClassWidth;
1527  m_nMaximum = Histogram.m_nMaximum ;
1528 
1529  for(size_t i=0; i<m_nClasses; i++)
1530  {
1531  m_Cumulative[i] = Histogram.m_Cumulative[i];
1532  m_Elements [i] = Histogram.m_Elements [i];
1533  }
1534 
1535  return( true );
1536 }
1537 
1538 //---------------------------------------------------------
1539 bool CSG_Histogram::Create(size_t nClasses, double Minimum, double Maximum)
1540 {
1541  return( _Create(nClasses, Minimum, Maximum) );
1542 }
1543 
1544 //---------------------------------------------------------
1545 bool CSG_Histogram::Create(size_t nClasses, const CSG_Vector &Values, double Minimum, double Maximum, size_t maxSamples)
1546 {
1547  if( Minimum >= Maximum )
1548  {
1549  CSG_Simple_Statistics Statistics(Values);
1550 
1551  Minimum = Statistics.Get_Minimum();
1552  Maximum = Statistics.Get_Maximum();
1553  }
1554 
1555  if( !_Create(nClasses, Minimum, Maximum) )
1556  {
1557  return( false );
1558  }
1559 
1560  //-----------------------------------------------------
1561  if( maxSamples > 0 && maxSamples < (size_t)Values.Get_N() )
1562  {
1563  double d = (double)Values.Get_N() / (double)maxSamples;
1564 
1565  for(double i=0; i<(double)Values.Get_N(); i+=d)
1566  {
1567  Add_Value(Values[(sLong)i]);
1568  }
1569 
1570  d = (double)m_Statistics.Get_Count() / (double)maxSamples;
1571 
1572  return( _Update(d < 1. ? (int)(d * (double)Values.Get_N()) : Values.Get_N()) );
1573  }
1574 
1575  //-----------------------------------------------------
1576  for(int i=0; i<Values.Get_N(); i++)
1577  {
1578  Add_Value(Values[i]);
1579  }
1580 
1581  return( Update() );
1582 }
1583 
1584 //---------------------------------------------------------
1585 bool CSG_Histogram::Create(size_t nClasses, CSG_Table *pTable, int Field, double Minimum, double Maximum, size_t maxSamples)
1586 {
1587  if( !pTable || Field < 0 || Field >= pTable->Get_Field_Count() || !_Create(nClasses,
1588  Minimum < Maximum ? Minimum : pTable->Get_Minimum(Field),
1589  Minimum < Maximum ? Maximum : pTable->Get_Maximum(Field)) )
1590  {
1591  return( false );
1592  }
1593 
1594  //-----------------------------------------------------
1595  if( maxSamples > 0 && maxSamples < (size_t)pTable->Get_Count() )
1596  {
1597  double Value, d = (double)pTable->Get_Count() / (double)maxSamples;
1598 
1599  for(double i=0; i<(double)pTable->Get_Count(); i+=d)
1600  {
1601  if( pTable->Get_Value((sLong)i, Field, Value) )
1602  {
1603  Add_Value(Value);
1604  }
1605  }
1606 
1607  d = (double)m_Statistics.Get_Count() / (double)maxSamples;
1608 
1609  return( _Update(d < 1. ? (int)(d * pTable->Get_Count()) : pTable->Get_Count()) );
1610  }
1611 
1612  //-----------------------------------------------------
1613  for(sLong i=0; i<pTable->Get_Count(); i++)
1614  {
1615  double Value;
1616 
1617  if( pTable->Get_Value(i, Field, Value) )
1618  {
1619  Add_Value(Value);
1620  }
1621  }
1622 
1623  return( Update() );
1624 }
1625 
1626 //---------------------------------------------------------
1627 bool CSG_Histogram::Create(size_t nClasses, CSG_Grid *pGrid, double Minimum, double Maximum, size_t maxSamples)
1628 {
1629  if( !pGrid || !_Create(nClasses,
1630  Minimum < Maximum ? Minimum : pGrid->Get_Min(),
1631  Minimum < Maximum ? Maximum : pGrid->Get_Max()) )
1632  {
1633  return( false );
1634  }
1635 
1636  //-----------------------------------------------------
1637  if( maxSamples > 0 && (sLong)maxSamples < pGrid->Get_NCells() )
1638  {
1639  double d = (double)pGrid->Get_NCells() / (double)maxSamples;
1640 
1641  for(double i=0; i<(double)pGrid->Get_NCells(); i+=d)
1642  {
1643  if( !pGrid->is_NoData((sLong)i) )
1644  {
1645  Add_Value(pGrid->asDouble((sLong)i));
1646  }
1647  }
1648 
1649  d = (double)m_Statistics.Get_Count() / (double)maxSamples;
1650 
1651  return( _Update(d < 1. ? (sLong)(d * (double)pGrid->Get_NCells()) : pGrid->Get_NCells()) );
1652  }
1653 
1654  //-----------------------------------------------------
1655  for(sLong i=0; i<pGrid->Get_NCells(); i++)
1656  {
1657  if( !pGrid->is_NoData(i) )
1658  {
1659  Add_Value(pGrid->asDouble(i));
1660  }
1661  }
1662 
1663  return( Update() );
1664 }
1665 
1666 //---------------------------------------------------------
1667 bool CSG_Histogram::Create(size_t nClasses, CSG_Grids *pGrids, double Minimum, double Maximum, size_t maxSamples)
1668 {
1669  if( !pGrids || !_Create(nClasses,
1670  Minimum < Maximum ? Minimum : pGrids->Get_Min(),
1671  Minimum < Maximum ? Maximum : pGrids->Get_Max()) )
1672  {
1673  return( false );
1674  }
1675 
1676  //-----------------------------------------------------
1677  if( maxSamples > 0 && (sLong)maxSamples < pGrids->Get_NCells() )
1678  {
1679  double d = (double)pGrids->Get_NCells() / (double)maxSamples;
1680 
1681  for(double i=0; i<(double)pGrids->Get_NCells(); i+=d)
1682  {
1683  if( !pGrids->is_NoData((sLong)i) )
1684  {
1685  Add_Value(pGrids->asDouble((sLong)i));
1686  }
1687  }
1688 
1689  d = (double)m_Statistics.Get_Count() / (double)maxSamples;
1690 
1691  return( _Update(d < 1. ? (sLong)(d * (double)pGrids->Get_NCells()) : pGrids->Get_NCells()) );
1692  }
1693 
1694  //-----------------------------------------------------
1695  for(sLong i=0; i<pGrids->Get_NCells(); i++)
1696  {
1697  if( !pGrids->is_NoData(i) )
1698  {
1699  Add_Value(pGrids->asDouble(i));
1700  }
1701  }
1702 
1703  return( Update() );
1704 }
1705 
1706 
1708 // //
1710 
1711 //---------------------------------------------------------
1713 {
1714  Create(Histogram);
1715 
1716  return( *this );
1717 }
1718 
1719 
1721 // //
1722 // //
1723 // //
1725 
1726 //---------------------------------------------------------
1728 {}
1729 
1730 //---------------------------------------------------------
1732 {}
1733 
1734 //---------------------------------------------------------
1735 CSG_Natural_Breaks::CSG_Natural_Breaks(CSG_Table *pTable, int Field, int nClasses, int Histogram)
1736 {
1737  Create(pTable, Field, nClasses, Histogram);
1738 }
1739 
1740 //---------------------------------------------------------
1741 CSG_Natural_Breaks::CSG_Natural_Breaks(CSG_Grid *pGrid, int nClasses, int Histogram)
1742 {
1743  Create(pGrid, nClasses, Histogram);
1744 }
1745 
1746 //---------------------------------------------------------
1747 CSG_Natural_Breaks::CSG_Natural_Breaks(CSG_Grids *pGrids, int nClasses, int Histogram)
1748 {
1749  Create(pGrids, nClasses, Histogram);
1750 }
1751 
1752 //---------------------------------------------------------
1753 CSG_Natural_Breaks::CSG_Natural_Breaks(const CSG_Vector &Values, int nClasses, int Histogram)
1754 {
1755  Create(Values, nClasses, Histogram);
1756 }
1757 
1758 
1760 // //
1762 
1763 //---------------------------------------------------------
1764 bool CSG_Natural_Breaks::Create(CSG_Table *pTable, int Field, int nClasses, int Histogram)
1765 {
1766  bool bResult = false;
1767 
1768  if( Histogram > 0 )
1769  {
1770  bResult = m_Histogram.Create(Histogram, pTable, Field) && _Histogram(nClasses);
1771  }
1772  else if( Field >= 0 && Field < pTable->Get_Field_Count() )
1773  {
1774  for(sLong i=0; i<pTable->Get_Count(); i++)
1775  {
1776  double Value;
1777 
1778  if( pTable->Get_Value(i, Field, Value) )
1779  {
1780  m_Values.Add_Row(Value);
1781  }
1782  }
1783 
1784  bResult = m_Values.Sort() && _Calculate(nClasses);
1785 
1786  m_Values.Destroy();
1787  }
1788 
1789  return( bResult );
1790 }
1791 
1792 //---------------------------------------------------------
1793 bool CSG_Natural_Breaks::Create(CSG_Grid *pGrid, int nClasses, int Histogram)
1794 {
1795  bool bResult = false;
1796 
1797  if( Histogram > 0 )
1798  {
1799  bResult = m_Histogram.Create(Histogram, pGrid) && _Histogram(nClasses);
1800  }
1801  else
1802  {
1803  for(sLong i=0; i<pGrid->Get_NCells(); i++)
1804  {
1805  if( !pGrid->is_NoData(i) )
1806  {
1807  m_Values.Add_Row(pGrid->asDouble(i));
1808  }
1809  }
1810 
1811  bResult = m_Values.Sort() && _Calculate(nClasses);
1812 
1813  m_Values.Destroy();
1814  }
1815 
1816  return( bResult );
1817 }
1818 
1819 //---------------------------------------------------------
1820 bool CSG_Natural_Breaks::Create(CSG_Grids *pGrids, int nClasses, int Histogram)
1821 {
1822  bool bResult = false;
1823 
1824  if( Histogram > 0 )
1825  {
1826  bResult = m_Histogram.Create(Histogram, pGrids) && _Histogram(nClasses);
1827  }
1828  else
1829  {
1830  for(sLong i=0; i<pGrids->Get_NCells(); i++)
1831  {
1832  if( !pGrids->is_NoData(i) )
1833  {
1834  m_Values.Add_Row(pGrids->asDouble(i));
1835  }
1836  }
1837 
1838  bResult = m_Values.Sort() && _Calculate(nClasses);
1839 
1840  m_Values.Destroy();
1841  }
1842 
1843  return( bResult );
1844 }
1845 
1846 //---------------------------------------------------------
1847 bool CSG_Natural_Breaks::Create(const CSG_Vector &Values, int nClasses, int Histogram)
1848 {
1849  bool bResult = false;
1850 
1851  if( Histogram > 0 )
1852  {
1853  bResult = m_Histogram.Create(Histogram, Values) && _Histogram(nClasses);
1854  }
1855  else
1856  {
1857  bResult = m_Values.Create(Values) && m_Values.Sort() && _Calculate(nClasses);
1858 
1859  m_Values.Destroy();
1860  }
1861 
1862  return( bResult );
1863 }
1864 
1865 
1867 // //
1869 
1870 //---------------------------------------------------------
1871 bool CSG_Natural_Breaks::_Histogram(int nClasses)
1872 {
1873  if( _Calculate(nClasses) )
1874  {
1875  double d = (double)m_Histogram.Get_Class_Count() / m_Histogram.Get_Cumulative((int)(m_Histogram.Get_Class_Count() - 1));
1876 
1877  m_Breaks[0] = m_Histogram.Get_Break(0);
1878 
1879  for(int i=1; i<Get_Count(); i++)
1880  {
1881  m_Breaks[i] = m_Histogram.Get_Value(m_Breaks[i] * d);
1882  }
1883 
1884  m_Breaks[nClasses] = m_Histogram.Get_Break((int)m_Histogram.Get_Class_Count());
1885 
1886  m_Histogram.Destroy();
1887 
1888  return( true );
1889  }
1890 
1891  m_Histogram.Destroy();
1892 
1893  return( false );
1894 }
1895 
1896 //---------------------------------------------------------
1897 inline double CSG_Natural_Breaks::_Get_Value(int i)
1898 {
1899  if( m_Histogram.Get_Class_Count() > 0 )
1900  {
1901  return( (double)m_Histogram.Get_Cumulative(i) );
1902  }
1903 
1904  return( m_Values[i] );
1905 }
1906 
1907 //---------------------------------------------------------
1908 bool CSG_Natural_Breaks::_Calculate(int nClasses)
1909 {
1910  if( m_Histogram.Get_Class_Count() == 0 && m_Values.Get_Size() == 0 )
1911  {
1912  return( false );
1913  }
1914 
1915  int nValues = m_Histogram.Get_Class_Count() > 0 ? (int)m_Histogram.Get_Class_Count() : m_Values.Get_N();
1916 
1917  CSG_Matrix mv(nClasses, nValues); mv.Assign(FLT_MAX);
1918 
1919  int **mc = (int **)SG_Malloc(nValues * sizeof(int *));
1920 
1921  mc[0] = (int *)SG_Calloc((size_t)nClasses * nValues, sizeof(int));
1922 
1923  for(int i=0; i<nValues; i++)
1924  {
1925  mc[i] = mc[0] + i * (size_t)nClasses;
1926  }
1927 
1928  //-----------------------------------------------------
1929  for(int i=1; i<nValues; i++)
1930  {
1931  double v = 0., s1 = 0., s2 = 0., w = 0.;
1932 
1933  for(int m=0, n=i+1; m<=i; m++, n--)
1934  {
1935  v = _Get_Value(n);
1936  s2 += v*v;
1937  s1 += v;
1938  w ++;
1939  v = s2 - (s1 * s1) / w;
1940 
1941  if( n > 0 )
1942  {
1943  for(int j=1; j<nClasses; j++)
1944  {
1945  if( mv[i][j] >= (v + mv[n - 1][j - 1]) )
1946  {
1947  mc[i][j] = n;
1948  mv[i][j] = v + mv[n - 1][j - 1];
1949  }
1950  }
1951  }
1952  }
1953 
1954  mc[i][0] = 0;
1955  mv[i][0] = v;
1956  }
1957 
1958  //-----------------------------------------------------
1959  CSG_Array_Int Class(nClasses);
1960 
1961  for(int i=0; i<nClasses; i++)
1962  {
1963  Class[i] = i;
1964  }
1965 
1966  int j = Class[(size_t)nClasses - 1] = nValues - 1;
1967 
1968  for(int i=nClasses-1; i>0; i--)
1969  {
1970  Class[(size_t)i - 1] = j = mc[j - 1][i];
1971  }
1972 
1973  //-----------------------------------------------------
1974  m_Breaks.Create((size_t)nClasses + 1);
1975 
1976  m_Breaks[0] = _Get_Value(0);
1977 
1978  for(int i=1; i<nClasses; i++)
1979  {
1980  m_Breaks[i] = _Get_Value(Class[i - 1]);
1981  }
1982 
1983  m_Breaks[nClasses] = _Get_Value(nValues - 1);
1984 
1985  SG_Free(mc[0]); SG_Free(mc);
1986 
1987  return( true );
1988 }
1989 
1990 
1992 // //
1993 // //
1994 // //
1996 
1997 //---------------------------------------------------------
1999 {
2000  m_nFeatures = 0;
2001  m_Iteration = 0;
2002 }
2003 
2004 //---------------------------------------------------------
2006 {
2007  Destroy();
2008 }
2009 
2010 //---------------------------------------------------------
2012 {
2013  m_Centroid.Destroy();
2014  m_Variance.Destroy();
2015  m_nMembers.Destroy();
2016  m_Clusters.Destroy();
2017  m_Features.Destroy();
2018  m_nFeatures = 0;
2019  m_Iteration = 0;
2020 
2021  return( true );
2022 }
2023 
2024 //---------------------------------------------------------
2025 bool CSG_Cluster_Analysis::Create(int nFeatures)
2026 {
2027  Destroy();
2028 
2029  if( nFeatures > 0 )
2030  {
2031  m_nFeatures = nFeatures;
2032 
2033  m_Features.Create(m_nFeatures * sizeof(double), 0, TSG_Array_Growth::SG_ARRAY_GROWTH_3);
2034 
2035  return( true );
2036  }
2037 
2038  return( false );
2039 }
2040 
2041 //---------------------------------------------------------
2043 {
2044  return( m_nFeatures > 0 && m_Features.Inc_Array() );
2045 }
2046 
2047 //---------------------------------------------------------
2048 bool CSG_Cluster_Analysis::Set_Feature(sLong iElement, int iFeature, double Value)
2049 {
2050  if( iElement >= 0 && iElement < Get_nElements() && iFeature >= 0 && iFeature < m_nFeatures )
2051  {
2052  ((double *)m_Features.Get_Entry(iElement))[iFeature] = Value;
2053 
2054  return( true );
2055  }
2056 
2057  return( false );
2058 }
2059 
2060 //---------------------------------------------------------
2070 //---------------------------------------------------------
2071 bool CSG_Cluster_Analysis::Execute(int Method, int nClusters, int nMaxIterations, int Initialization)
2072 {
2073  if( Get_nElements() < 2 || nClusters < 2 )
2074  {
2075  return( false );
2076  }
2077 
2078  //-----------------------------------------------------
2079  m_nMembers.Create(nClusters);
2080  m_Variance.Create(nClusters);
2081  m_Centroid.Create(m_nFeatures, nClusters);
2082 
2083  //-----------------------------------------------------
2084  m_Clusters.Create(Get_nElements());
2085 
2086  for(int iElement=0; iElement<Get_nElements(); iElement++)
2087  {
2088  switch( Initialization )
2089  {
2090  default: // random
2091  if( (m_Clusters[iElement] = (int)CSG_Random::Get_Uniform(0, nClusters)) >= nClusters )
2092  {
2093  m_Clusters[iElement] = nClusters - 1;
2094  }
2095  break;
2096 
2097  case 1: // periodic
2098  {
2099  m_Clusters[iElement] = iElement % nClusters;
2100  }
2101  break;
2102 
2103  case 2: // keep as is, but check for valid cluster ids
2104  if( 0 > m_Clusters[iElement] || m_Clusters[iElement] >= nClusters )
2105  {
2106  m_Clusters[iElement] = iElement % nClusters;
2107  }
2108  break;
2109  }
2110  }
2111 
2112  //-----------------------------------------------------
2113  bool bResult;
2114 
2115  m_Iteration = 0;
2116 
2117  switch( Method )
2118  {
2119  default: bResult = _Minimum_Distance(true , nMaxIterations); break;
2120  case 1: bResult = _Hill_Climbing (true , nMaxIterations); break;
2121  case 2: bResult = _Minimum_Distance(true , nMaxIterations)
2122  && _Hill_Climbing (false, nMaxIterations); break;
2123  }
2124 
2125  //-----------------------------------------------------
2126  if( bResult )
2127  {
2128  for(int iCluster=0; iCluster<nClusters; iCluster++)
2129  {
2130  m_Variance[iCluster] = m_nMembers[iCluster] <= 0 ? 0. : m_Variance[iCluster] / m_nMembers[iCluster];
2131  }
2132  }
2133 
2134  return( bResult );
2135 }
2136 
2137 //---------------------------------------------------------
2138 bool CSG_Cluster_Analysis::_Minimum_Distance(bool bInitialize, int nMaxIterations)
2139 {
2140  int iElement, iCluster, nClusters = m_Variance.Get_N();
2141 
2142  double SP_Last = -1.;
2143 
2144  //-----------------------------------------------------
2145  for(m_Iteration=1; SG_UI_Process_Get_Okay(); m_Iteration++)
2146  {
2147  m_Variance = 0.;
2148  m_Centroid = 0.;
2149  m_nMembers = 0;
2150 
2151  //-------------------------------------------------
2152  for(iElement=0; iElement<Get_nElements(); iElement++)
2153  {
2154  m_nMembers[iCluster = m_Clusters[iElement]]++;
2155 
2156  double *Feature = (double *)m_Features.Get_Entry(iElement);
2157 
2158  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2159  {
2160  m_Centroid[iCluster][iFeature] += Feature[iFeature];
2161  }
2162  }
2163 
2164  //-------------------------------------------------
2165  for(iCluster=0; iCluster<nClusters; iCluster++)
2166  {
2167  double d = m_nMembers[iCluster] > 0 ? 1. / m_nMembers[iCluster] : 0.;
2168 
2169  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2170  {
2171  m_Centroid[iCluster][iFeature] *= d;
2172  }
2173  }
2174 
2175  //-------------------------------------------------
2176  int nShifts = 0; m_SP = 0.;
2177 
2178  for(iElement=0; iElement<Get_nElements(); iElement++)
2179  {
2180  double *Feature = (double *)m_Features.Get_Entry(iElement);
2181 
2182  double minVariance = -1.;
2183  int minCluster = -1;
2184 
2185  for(iCluster=0; iCluster<nClusters; iCluster++)
2186  {
2187  double Variance = 0.;
2188 
2189  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2190  {
2191  Variance += SG_Get_Square(m_Centroid[iCluster][iFeature] - Feature[iFeature]);
2192  }
2193 
2194  if( minVariance < 0. || Variance < minVariance )
2195  {
2196  minVariance = Variance;
2197  minCluster = iCluster;
2198  }
2199  }
2200 
2201  if( m_Clusters[iElement] != minCluster )
2202  {
2203  m_Clusters[iElement] = minCluster;
2204 
2205  nShifts++;
2206  }
2207 
2208  m_SP += minVariance;
2209  m_Variance[minCluster] += minVariance;
2210  }
2211 
2212  //-------------------------------------------------
2213  m_SP /= Get_nElements();
2214 
2215  SG_UI_Process_Set_Text(CSG_String::Format("%s: %d >> %s %f",
2216  _TL("pass" ), m_Iteration,
2217  _TL("change"), m_Iteration < 2 ? m_SP : SP_Last - m_SP
2218  ));
2219 
2220  SP_Last = m_SP;
2221 
2222  if( nShifts == 0 || (nMaxIterations > 0 && nMaxIterations <= m_Iteration) )
2223  {
2224  return( true );
2225  }
2226  }
2227 
2228  return( true );
2229 }
2230 
2231 //---------------------------------------------------------
2232 bool CSG_Cluster_Analysis::_Hill_Climbing(bool bInitialize, int nMaxIterations)
2233 {
2234  int iElement, iCluster, nClusters = m_Variance.Get_N();
2235 
2236  //-----------------------------------------------------
2237  m_Variance = 0.;
2238  m_Centroid = 0.;
2239  m_nMembers = 0;
2240 
2241  for(iElement=0; iElement<Get_nElements(); iElement++)
2242  {
2243  m_nMembers[iCluster = m_Clusters[iElement]]++;
2244 
2245  double *Feature = (double *)m_Features.Get_Entry(iElement);
2246 
2247  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2248  {
2249  double d = Feature[iFeature];
2250 
2251  m_Centroid[iCluster][iFeature] += d;
2252  m_Variance[iCluster] += d*d;
2253  }
2254  }
2255 
2256  //-----------------------------------------------------
2257  for(iCluster=0; iCluster<nClusters; iCluster++)
2258  {
2259  double v = 0., d = m_nMembers[iCluster] <= 0 ? 0. : 1. / (double)m_nMembers[iCluster];
2260 
2261  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2262  {
2263  m_Centroid[iCluster][iFeature] *= d;
2264  v += SG_Get_Square(m_Centroid[iCluster][iFeature]);
2265  }
2266 
2267  m_Variance[iCluster] -= v * m_nMembers[iCluster];
2268  }
2269 
2270  //-----------------------------------------------------
2271  double SP_Last = -1.; int noShift = 0;
2272 
2273  for(m_Iteration=1; SG_UI_Process_Get_Okay(false); m_Iteration++)
2274  {
2275  for(iElement=0; iElement<Get_nElements(); iElement++)
2276  {
2277  iCluster = m_Clusters[iElement];
2278 
2279  if( noShift++ < Get_nElements() && m_nMembers[iCluster] > 1 )
2280  {
2281  double *Feature = (double *)m_Features.Get_Entry(iElement);
2282 
2283  double Variance = 0.;
2284 
2285  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2286  {
2287  Variance += SG_Get_Square(m_Centroid[iCluster][iFeature] - Feature[iFeature]);
2288  }
2289 
2290  double V1 = Variance * m_nMembers[iCluster] / (m_nMembers[iCluster] - 1.);
2291 
2292  //-----------------------------------------
2293  int kCluster = 0; double VMin = -1.;
2294 
2295  for(int jCluster=0; jCluster<nClusters; jCluster++)
2296  {
2297  if( jCluster != iCluster )
2298  {
2299  Variance = 0.;
2300 
2301  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2302  {
2303  Variance += SG_Get_Square(m_Centroid[jCluster][iFeature] - Feature[iFeature]);
2304  }
2305 
2306  double V2 = Variance * m_nMembers[jCluster] / (m_nMembers[jCluster] + 1.);
2307 
2308  if( VMin < 0. || V2 < VMin )
2309  {
2310  VMin = V2;
2311  kCluster = jCluster;
2312  }
2313  }
2314  }
2315 
2316  //-----------------------------------------
2317  if( VMin >= 0 && VMin < V1 )
2318  {
2319  noShift = 0;
2320  m_Variance[iCluster] -= V1;
2321  m_Variance[kCluster] += VMin;
2322  V1 = 1. / (m_nMembers[iCluster] - 1.);
2323  double V2 = 1. / (m_nMembers[kCluster] + 1.);
2324 
2325  for(int iFeature=0; iFeature<m_nFeatures; iFeature++)
2326  {
2327  double d = Feature[iFeature];
2328 
2329  m_Centroid[iCluster][iFeature] = (m_nMembers[iCluster] * m_Centroid[iCluster][iFeature] - d) * V1;
2330  m_Centroid[kCluster][iFeature] = (m_nMembers[kCluster] * m_Centroid[kCluster][iFeature] + d) * V2;
2331  }
2332 
2333  m_Clusters[iElement] = kCluster;
2334 
2335  m_nMembers[iCluster]--;
2336  m_nMembers[kCluster]++;
2337  }
2338  }
2339  }
2340 
2341  //-------------------------------------------------
2342  for(iCluster=0, m_SP=0.; iCluster<nClusters; iCluster++)
2343  {
2344  m_SP += m_Variance[iCluster];
2345  }
2346 
2347  m_SP /= Get_nElements();
2348 
2349  SG_UI_Process_Set_Text(CSG_String::Format("%s: %d >> %s %f",
2350  _TL("pass" ), m_Iteration,
2351  _TL("change"), m_Iteration <= 1 ? m_SP : SP_Last - m_SP
2352  ));
2353 
2354  SP_Last = m_SP;
2355 
2356  if( noShift >= Get_nElements() || (nMaxIterations > 0 && nMaxIterations <= m_Iteration) )
2357  {
2358  return( true );
2359  }
2360  }
2361 
2362  return( true );
2363 }
2364 
2365 
2367 // //
2368 // //
2369 // //
2371 
2372 //---------------------------------------------------------
2374 {
2375  m_nFeatures = 0; m_pClasses = NULL; m_nClasses = 0;
2376 
2377  m_Threshold_Distance = 0.;
2378  m_Threshold_Angle = 0.;
2379  m_Threshold_Probability = 0.;
2380  m_Probability_Relative = false;
2381 
2382  for(int i=0; i<SG_CLASSIFY_SUPERVISED_WTA; i++)
2383  {
2385  // || i == SG_CLASSIFY_SUPERVISED_Mahalonobis
2388  }
2389 }
2390 
2391 //---------------------------------------------------------
2393 {
2394  Destroy();
2395 }
2396 
2397 //---------------------------------------------------------
2399 {
2400  Destroy();
2401 
2402  if( nFeatures > 0 )
2403  {
2404  m_nFeatures = nFeatures;
2405  }
2406 }
2407 
2408 //---------------------------------------------------------
2410 {
2411  if( m_nClasses > 0 )
2412  {
2413  for(int i=0; i<m_nClasses; i++)
2414  {
2415  delete(m_pClasses[i]);
2416  }
2417 
2418  SG_FREE_SAFE(m_pClasses);
2419  }
2420 
2421  m_nFeatures = 0;
2422 
2423  m_Info.Clear();
2424 }
2425 
2426 
2428 // //
2430 
2431 //---------------------------------------------------------
2432 void CSG_Classifier_Supervised::Set_Threshold_Distance (double Value) { m_Threshold_Distance = Value; }
2433 double CSG_Classifier_Supervised::Get_Threshold_Distance (void) { return( m_Threshold_Distance ); }
2434 
2435 //---------------------------------------------------------
2436 void CSG_Classifier_Supervised::Set_Threshold_Angle (double Value) { m_Threshold_Angle = Value; }
2437 double CSG_Classifier_Supervised::Get_Threshold_Angle (void) { return( m_Threshold_Angle ); }
2438 
2439 //---------------------------------------------------------
2440 void CSG_Classifier_Supervised::Set_Threshold_Probability(double Value) { m_Threshold_Probability = Value; }
2441 double CSG_Classifier_Supervised::Get_Threshold_Probability(void) { return( m_Threshold_Probability ); }
2442 
2443 //---------------------------------------------------------
2444 void CSG_Classifier_Supervised::Set_Probability_Relative (bool Value) { m_Probability_Relative = Value; }
2445 bool CSG_Classifier_Supervised::Get_Probability_Relative (void) { return( m_Probability_Relative ); }
2446 
2447 //---------------------------------------------------------
2448 void CSG_Classifier_Supervised::Set_WTA(int Method, bool bOn)
2449 {
2450  if( Method >= 0 && Method < SG_CLASSIFY_SUPERVISED_WTA )
2451  {
2452  m_bWTA[Method] = bOn;
2453  }
2454 }
2455 
2457 {
2458  return( Method >= 0 && Method < SG_CLASSIFY_SUPERVISED_WTA ? m_bWTA[Method] : false );
2459 }
2460 
2461 
2463 // //
2465 
2466 //---------------------------------------------------------
2467 #include "saga_api.h"
2468 
2469 //---------------------------------------------------------
2471 {
2472  int nFeatures = m_nFeatures; Destroy(); m_nFeatures = nFeatures;
2473 
2474  //-----------------------------------------------------
2475  CSG_MetaData Data;
2476 
2477  if( !Data.Load(File) || !Data.Cmp_Name("supervised_classifier") || SG_Compare_Version(Data.Get_Property("saga-version"), "2.1.4") < 0 )
2478  {
2479  return( false );
2480  }
2481 
2482  if( !Data("classes") || !Data("features") || !Data["features"]("count") || Data["features"]["count"].Get_Content().asInt() != m_nFeatures || m_nFeatures == 0 )
2483  {
2484  return( false );
2485  }
2486 
2487  if( Data["features"]("info") )
2488  {
2489  m_Info = Data["features"]["info"].Get_Content();
2490  }
2491 
2492  //-----------------------------------------------------
2493  CSG_MetaData &Classes = *Data.Get_Child("CLASSES");
2494 
2495  for(int i=0; i<Classes.Get_Children_Count(); i++)
2496  {
2497  if( Classes[i].Cmp_Name("class") && Classes[i].Get_Child("id") )
2498  {
2499  bool bAdd = true;
2500 
2501  CClass *pClass = new CClass(Classes[i]["id"].Get_Content());
2502 
2503  if( !pClass->m_Cov .from_String(Classes[i]["cov" ].Get_Content()) || pClass->m_Cov .Get_NX() != m_nFeatures || !pClass->m_Cov.is_Square() ) { bAdd = false; }
2504  if( !pClass->m_Mean.from_String(Classes[i]["mean"].Get_Content()) || pClass->m_Mean.Get_N () != m_nFeatures ) { bAdd = false; }
2505  if( !pClass->m_Min .from_String(Classes[i]["min" ].Get_Content()) || pClass->m_Min .Get_N () != m_nFeatures ) { bAdd = false; }
2506  if( !pClass->m_Max .from_String(Classes[i]["max" ].Get_Content()) || pClass->m_Max .Get_N () != m_nFeatures ) { bAdd = false; }
2507 
2508  //---------------------------------------------
2509  if( !bAdd )
2510  {
2511  delete(pClass);
2512  }
2513  else
2514  {
2515  m_pClasses = (CClass **)SG_Realloc(m_pClasses, ((size_t)m_nClasses + 1) * sizeof(CClass *));
2516  m_pClasses[m_nClasses++] = pClass;
2517 
2518  pClass->m_Cov_Det = pClass->m_Cov.Get_Determinant();
2519  pClass->m_Cov_Inv = pClass->m_Cov.Get_Inverse();
2520 
2521  pClass->m_Mean_Spectral = CSG_Simple_Statistics(pClass->m_Mean).Get_Mean();
2522  }
2523  }
2524  }
2525 
2526  return( m_nClasses > 0 );
2527 }
2528 
2529 //---------------------------------------------------------
2530 bool CSG_Classifier_Supervised::Save(const CSG_String &File, const SG_Char *Feature_Info)
2531 {
2532  if( m_nFeatures < 1 || m_nClasses < 1 || File.is_Empty() )
2533  {
2534  return( false );
2535  }
2536 
2537  CSG_MetaData Data;
2538 
2539  Data.Set_Name ("supervised_classifier");
2540  Data.Add_Property("saga-version", SAGA_VERSION);
2541 
2542  CSG_MetaData &Features = *Data.Add_Child("features");
2543 
2544  Features.Add_Child("count", m_nFeatures);
2545 
2546  if( Feature_Info && *Feature_Info )
2547  {
2548  Features.Add_Child("info", Feature_Info);
2549  }
2550 
2551  CSG_MetaData &Classes = *Data.Add_Child("classes");
2552 
2553  Classes.Add_Property("count", m_nClasses);
2554 
2555  for(int i=0; i<m_nClasses; i++)
2556  {
2557  CSG_MetaData &Class = *Classes.Add_Child("class");
2558 
2559  CClass *pClass = m_pClasses[i];
2560 
2561  Class.Add_Child("id" , pClass->m_ID );
2562  Class.Add_Child("mean", pClass->m_Mean.to_String());
2563  Class.Add_Child("min" , pClass->m_Min .to_String());
2564  Class.Add_Child("max" , pClass->m_Max .to_String());
2565  Class.Add_Child("cov" , pClass->m_Cov .to_String());
2566  }
2567 
2568  return( Data.Save(File) );
2569 }
2570 
2571 
2573 // //
2575 
2576 //---------------------------------------------------------
2578 {
2579  CSG_String s;
2580 
2581  if( m_nFeatures > 0 && m_nClasses > 0 )
2582  {
2583  s += "\n";
2584 
2585  for(int iClass=0; iClass<m_nClasses; iClass++)
2586  {
2587  CClass *pClass = m_pClasses[iClass];
2588 
2589  s += "\n____\n" + pClass->m_ID + "\nFeature\tMean\tMin\tMax\tStdDev";
2590 
2591  for(int i=0; i<m_nFeatures; i++)
2592  {
2593  s += CSG_String::Format("\n%3d.", i + 1);
2594  s += "\t" + SG_Get_String(pClass->m_Mean[i]);
2595  s += "\t" + SG_Get_String(pClass->m_Min [i]);
2596  s += "\t" + SG_Get_String(pClass->m_Max [i]);
2597  s += "\t" + SG_Get_String(sqrt(pClass->m_Cov[i][i]));
2598  }
2599 
2600  s += "\n";
2601  }
2602  }
2603 
2604  return( s );
2605 }
2606 
2607 
2609 // //
2611 
2612 //---------------------------------------------------------
2613 bool CSG_Classifier_Supervised::Add_Class(const CSG_String &Class_ID, const CSG_Vector &Mean, const CSG_Vector &Min, const CSG_Vector &Max, const CSG_Matrix &Cov)
2614 {
2615  if( m_nFeatures < 1 || Mean.Get_N() != m_nFeatures || Min.Get_N() != m_nFeatures || Max.Get_N() != m_nFeatures || Cov.Get_NCols() != m_nFeatures || Cov.Get_NRows() != m_nFeatures )
2616  {
2617  return( false );
2618  }
2619 
2620  CClass *pClass, **pClasses = (CClass **)SG_Realloc(m_pClasses, ((size_t)m_nClasses + 1) * sizeof(CClass *));
2621 
2622  if( pClasses )
2623  {
2624  m_pClasses = pClasses;
2625 
2626  m_pClasses[m_nClasses++] = pClass = new CClass(Class_ID);
2627 
2628  pClass->m_ID = Class_ID;
2629  pClass->m_Mean = Mean;
2630  pClass->m_Min = Min;
2631  pClass->m_Max = Max;
2632  pClass->m_Cov = Cov;
2633  pClass->m_Cov_Inv = Cov.Get_Inverse();
2634  pClass->m_Cov_Det = Cov.Get_Determinant();
2635 
2636  pClass->m_Mean_Spectral = CSG_Simple_Statistics(Mean).Get_Mean();
2637 
2638  return( true );
2639  }
2640 
2641  return( false );
2642 }
2643 
2644 
2646 // //
2648 
2649 //---------------------------------------------------------
2651 {
2652  for(int i=0; i<m_nClasses; i++)
2653  {
2654  m_pClasses[i]->m_Samples.Destroy();
2655  }
2656 
2657  return( true );
2658 }
2659 
2660 //---------------------------------------------------------
2662 {
2663  if( m_nFeatures > 0 && m_nFeatures == Features.Get_N() )
2664  {
2665  int iClass = Get_Class(Class_ID);
2666 
2667  if( iClass < 0 )
2668  {
2669  CClass **pClasses = (CClass **)SG_Realloc(m_pClasses, ((size_t)m_nClasses + 1) * sizeof(CClass *));
2670 
2671  if( pClasses )
2672  {
2673  m_pClasses = pClasses;
2674 
2675  m_pClasses[iClass = m_nClasses++] = new CClass(Class_ID);
2676  }
2677  }
2678 
2679  if( iClass >= 0 )
2680  {
2681  return( m_pClasses[iClass]->m_Samples.Add_Row(Features) );
2682  }
2683  }
2684 
2685  return( false );
2686 }
2687 
2688 //---------------------------------------------------------
2689 bool CSG_Classifier_Supervised::Train(bool bClear_Samples)
2690 {
2691  if( m_nFeatures < 1 || m_nClasses < 1 )
2692  {
2693  return( false );
2694  }
2695 
2696  for(int iClass=0; iClass<m_nClasses; iClass++)
2697  {
2698  if( !m_pClasses[iClass]->Train() )
2699  {
2700  return( false );
2701  }
2702  }
2703 
2704  if( bClear_Samples )
2705  {
2707  }
2708 
2709  return( true );
2710 }
2711 
2712 
2714 // //
2716 
2717 //---------------------------------------------------------
2718 bool CSG_Classifier_Supervised::CClass::Train(void)
2719 {
2720  if( m_Samples.Get_NCols() < 1 || m_Samples.Get_NRows() < 1 )
2721  {
2722  return( false );
2723  }
2724 
2725  //-----------------------------------------------------
2726  m_Mean.Create(m_Samples.Get_NCols());
2727  m_Min .Create(m_Samples.Get_NCols());
2728  m_Max .Create(m_Samples.Get_NCols());
2729 
2730  for(int iFeature=0; iFeature<m_Samples.Get_NCols(); iFeature++)
2731  {
2733 
2734  for(int iSample=0; iSample<m_Samples.Get_NRows(); iSample++)
2735  {
2736  s += m_Samples[iSample][iFeature];
2737  }
2738 
2739  m_Mean[iFeature] = s.Get_Mean ();
2740  m_Min [iFeature] = s.Get_Minimum();
2741  m_Max [iFeature] = s.Get_Maximum();
2742  }
2743 
2744  //-----------------------------------------------------
2745  m_Cov.Create(m_Samples.Get_NCols(), m_Samples.Get_NCols());
2746 
2747  for(int iFeature=0; iFeature<m_Samples.Get_NCols(); iFeature++)
2748  {
2749  for(int jFeature=iFeature; jFeature<m_Samples.Get_NCols(); jFeature++)
2750  {
2751  double cov = 0.;
2752 
2753  for(int iSample=0; iSample<m_Samples.Get_NRows(); iSample++)
2754  {
2755  cov += (m_Samples[iSample][iFeature] - m_Mean[iFeature]) * (m_Samples[iSample][jFeature] - m_Mean[jFeature]);
2756  }
2757 
2758  if( m_Samples.Get_NRows() > 1 )
2759  {
2760  cov /= m_Samples.Get_NRows() - 1;
2761  }
2762 
2763  m_Cov[iFeature][jFeature] = m_Cov[jFeature][iFeature] = cov;
2764  }
2765  }
2766 
2767  m_Cov_Inv = m_Cov.Get_Inverse ();
2768  m_Cov_Det = m_Cov.Get_Determinant();
2769 
2770  m_Mean_Spectral = CSG_Simple_Statistics(m_Mean).Get_Mean();
2771 
2772  //-----------------------------------------------------
2773  return( true );
2774 }
2775 
2776 
2778 // //
2780 
2781 //---------------------------------------------------------
2783 {
2784  if( m_nFeatures > 0 )
2785  {
2786  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2787  {
2788  if( !Get_Class_ID(iClass).Cmp(Class_ID) )
2789  {
2790  return( iClass );
2791  }
2792  }
2793  }
2794 
2795  return( -1 );
2796 }
2797 
2798 //---------------------------------------------------------
2799 bool CSG_Classifier_Supervised::Get_Class(const CSG_Vector &Features, int &Class, double &Quality, int Method)
2800 {
2801  Class = -1; Quality = 0.;
2802 
2803  if( Get_Feature_Count() == Features.Get_N() )
2804  {
2805  switch( Method )
2806  {
2807  case SG_CLASSIFY_SUPERVISED_BinaryEncoding : _Get_Binary_Encoding (Features, Class, Quality); break;
2808  case SG_CLASSIFY_SUPERVISED_ParallelEpiped : _Get_Parallel_Epiped (Features, Class, Quality); break;
2809  case SG_CLASSIFY_SUPERVISED_MinimumDistance : _Get_Minimum_Distance (Features, Class, Quality); break;
2810  case SG_CLASSIFY_SUPERVISED_Mahalonobis : _Get_Mahalanobis_Distance (Features, Class, Quality); break;
2811  case SG_CLASSIFY_SUPERVISED_MaximumLikelihood: _Get_Maximum_Likelihood (Features, Class, Quality); break;
2812  case SG_CLASSIFY_SUPERVISED_SAM : _Get_Spectral_Angle_Mapping(Features, Class, Quality); break;
2813  case SG_CLASSIFY_SUPERVISED_SID : _Get_Spectral_Divergence (Features, Class, Quality); break;
2814  case SG_CLASSIFY_SUPERVISED_WTA : _Get_Winner_Takes_All (Features, Class, Quality); break;
2815  }
2816 
2817  return( Class >= 0 );
2818  }
2819 
2820  return( false );
2821 }
2822 
2823 
2825 // //
2827 
2828 //---------------------------------------------------------
2830 {
2831  switch( Method )
2832  {
2833  case SG_CLASSIFY_SUPERVISED_BinaryEncoding : return( _TL("Binary Encoding") );
2834  case SG_CLASSIFY_SUPERVISED_ParallelEpiped : return( _TL("Parallelepiped") );
2835  case SG_CLASSIFY_SUPERVISED_MinimumDistance : return( _TL("Minimum Distance") );
2836  case SG_CLASSIFY_SUPERVISED_Mahalonobis : return( _TL("Mahalanobis Distance") );
2837  case SG_CLASSIFY_SUPERVISED_MaximumLikelihood: return( _TL("Maximum Likelihood") );
2838  case SG_CLASSIFY_SUPERVISED_SAM : return( _TL("Spectral Angle Mapping") );
2839  case SG_CLASSIFY_SUPERVISED_SID : return( _TL("Spectral Information Divergence") );
2840  case SG_CLASSIFY_SUPERVISED_SVM : return( _TL("Support Vector Machine") );
2841  case SG_CLASSIFY_SUPERVISED_WTA : return( _TL("Winner Takes All") );
2842  }
2843 
2844  return( SG_T("") );
2845 }
2846 
2847 //---------------------------------------------------------
2849 {
2850  switch( Method )
2851  {
2852  case SG_CLASSIFY_SUPERVISED_BinaryEncoding : return( _TL("Difference") );
2853  case SG_CLASSIFY_SUPERVISED_ParallelEpiped : return( _TL("Memberships") );
2854  case SG_CLASSIFY_SUPERVISED_MinimumDistance : return( _TL("Distance") );
2855  case SG_CLASSIFY_SUPERVISED_Mahalonobis : return( _TL("Distance") );
2856  case SG_CLASSIFY_SUPERVISED_MaximumLikelihood: return( _TL("Proximity") );
2857  case SG_CLASSIFY_SUPERVISED_SAM : return( _TL("Angle") );
2858  case SG_CLASSIFY_SUPERVISED_SID : return( _TL("Divergence") );
2859  case SG_CLASSIFY_SUPERVISED_SVM : return( _TL("") );
2860  case SG_CLASSIFY_SUPERVISED_WTA : return( _TL("Votes") );
2861  }
2862 
2863  return( SG_T("") );
2864 }
2865 
2866 
2868 // //
2870 
2871 //---------------------------------------------------------
2872 // Mazer, A. S., Martin, M., Lee, M., and Solomon, J. E. (1988):
2873 // Image Processing Software for Imaging Spectrometry Analysis.
2874 // Remote Sensing of Environment, v. 24, no. 1, p. 201-210.
2875 //
2876 void CSG_Classifier_Supervised::_Get_Binary_Encoding(const CSG_Vector &Features, int &Class, double &Quality)
2877 {
2878  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2879  {
2880  CClass *pClass = m_pClasses[iClass];
2881 
2882  double Mean_Spectral = CSG_Simple_Statistics(Features).Get_Mean();
2883 
2884  int d = 0;
2885 
2886  for(int iFeature=0; iFeature<Get_Feature_Count(); iFeature++)
2887  {
2888  d += (Features(iFeature) < Mean_Spectral) == (pClass->m_Mean[iFeature] < pClass->m_Mean_Spectral) ? 0 : 1;
2889 
2890  if( iFeature == 0 ) // spectral slopes
2891  {
2892  d += (Features[iFeature ] < Features[iFeature + 1]) == (pClass->m_Mean[iFeature ] < pClass->m_Mean[iFeature + 1]) ? 0 : 1;
2893  }
2894  else if( iFeature == Get_Feature_Count() - 1 )
2895  {
2896  d += (Features[iFeature - 1] < Features[iFeature ]) == (pClass->m_Mean[iFeature - 1] < pClass->m_Mean[iFeature ]) ? 0 : 1;
2897  }
2898  else
2899  {
2900  d += (Features[iFeature - 1] < Features[iFeature + 1]) == (pClass->m_Mean[iFeature - 1] < pClass->m_Mean[iFeature + 1]) ? 0 : 1;
2901  }
2902  }
2903 
2904  if( Class < 0 || Quality > d ) // find the minimum 'Hamming' distance
2905  {
2906  Class = iClass; Quality = d;
2907  }
2908  }
2909 }
2910 
2911 //---------------------------------------------------------
2912 void CSG_Classifier_Supervised::_Get_Parallel_Epiped(const CSG_Vector &Features, int &Class, double &Quality)
2913 {
2914  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2915  {
2916  CClass *pClass = m_pClasses[iClass];
2917 
2918  bool bMember = true;
2919 
2920  for(int iFeature=0; bMember && iFeature<Get_Feature_Count(); iFeature++)
2921  {
2922  bMember = pClass->m_Min[iFeature] <= Features[iFeature] && Features[iFeature] <= pClass->m_Max[iFeature];
2923  }
2924 
2925  if( bMember )
2926  {
2927  Class = iClass; Quality++;
2928  }
2929  }
2930 }
2931 
2932 //---------------------------------------------------------
2933 void CSG_Classifier_Supervised::_Get_Minimum_Distance(const CSG_Vector &Features, int &Class, double &Quality)
2934 {
2935  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2936  {
2937  CClass *pClass = m_pClasses[iClass];
2938 
2939  double Distance = (Features - pClass->m_Mean).Get_Length();
2940 
2941  if( Class < 0 || Quality > Distance )
2942  {
2943  Class = iClass; Quality = Distance;
2944  }
2945  }
2946 
2947  if( m_Threshold_Distance > 0. && Quality > m_Threshold_Distance )
2948  {
2949  Class = -1;
2950  }
2951 }
2952 
2953 //---------------------------------------------------------
2954 void CSG_Classifier_Supervised::_Get_Mahalanobis_Distance(const CSG_Vector &Features, int &Class, double &Quality)
2955 {
2956  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2957  {
2958  CClass *pClass = m_pClasses[iClass];
2959 
2960  CSG_Vector D = Features - pClass->m_Mean;
2961 
2962  double Distance = D * (pClass->m_Cov_Inv * D);
2963 
2964  if( Class < 0 || Quality > Distance )
2965  {
2966  Class = iClass; Quality = Distance;
2967  }
2968  }
2969 
2970  if( m_Threshold_Distance > 0. && Quality > m_Threshold_Distance )
2971  {
2972  Class = -1;
2973  }
2974 }
2975 
2976 //---------------------------------------------------------
2977 void CSG_Classifier_Supervised::_Get_Maximum_Likelihood(const CSG_Vector &Features, int &Class, double &Quality)
2978 {
2979  double dSum = 0.;
2980 
2981  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
2982  {
2983  CClass *pClass = m_pClasses[iClass];
2984 
2985  CSG_Vector D = Features - pClass->m_Mean;
2986 
2987  double Distance = D * (pClass->m_Cov_Inv * D);
2988 
2989  double Probability = pow(2. * M_PI, -0.5 * m_nFeatures) * pow(pClass->m_Cov_Det, -0.5) * exp(-0.5 * Distance);
2990  // double Probability = -log(pClass->m_Cov_Det) - Distance;
2991 
2992  dSum += Probability;
2993 
2994  if( Class < 0 || Quality < Probability )
2995  {
2996  Class = iClass; Quality = Probability;
2997  }
2998  }
2999 
3000  if( Class >= 0 )
3001  {
3002  if( m_Probability_Relative )
3003  {
3004  Quality = 100. * Quality / dSum;
3005  }
3006 
3007  if( m_Threshold_Probability > 0. && Quality < m_Threshold_Probability )
3008  {
3009  Class = -1;
3010  }
3011  }
3012 }
3013 
3014 //---------------------------------------------------------
3015 void CSG_Classifier_Supervised::_Get_Spectral_Angle_Mapping(const CSG_Vector &Features, int &Class, double &Quality)
3016 {
3017  for(int iClass=0; iClass<Get_Class_Count(); iClass++)
3018  {
3019  CClass *pClass = m_pClasses[iClass];
3020 
3021  double Angle = Features.Get_Angle(pClass->m_Mean);
3022 
3023  if( Class < 0 || Quality > Angle )
3024  {
3025  Class = iClass; Quality = Angle;
3026  }
3027  }
3028 
3029  Quality *= M_RAD_TO_DEG;
3030 
3031  if( m_Threshold_Angle > 0. && Quality > m_Threshold_Angle )
3032  {
3033  Class = -1;
3034  }
3035 }
3036 
3037 //---------------------------------------------------------
3038 void CSG_Classifier_Supervised::_Get_Spectral_Divergence(const CSG_Vector &Features, int &Class, double &Quality)
3039 {
3040 }
3041 
3042 //---------------------------------------------------------
3043 void CSG_Classifier_Supervised::_Get_Winner_Takes_All(const CSG_Vector &Features, int &Class, double &Quality)
3044 {
3045  int *Votes = (int *)SG_Calloc(Get_Class_Count(), sizeof(int));
3046 
3047  for(int iMethod=0; iMethod<SG_CLASSIFY_SUPERVISED_WTA; iMethod++)
3048  {
3049  int iClass; double iQuality;
3050 
3051  if( m_bWTA[iMethod] && Get_Class(Features, iClass, iQuality, iMethod) && ++Votes[iClass] > Quality )
3052  {
3053  Class = iClass; Quality = Votes[iClass];
3054  }
3055  }
3056 
3057  SG_Free(Votes);
3058 }
3059 
3060 
3062 // //
3063 // //
3064 // //
3066 
3067 //---------------------------------------------------------
3068 // source: http://psydok.sulb.uni-saarland.de/volltexte/2004/268/html/
3069 
3070 //---------------------------------------------------------
3072 { // Hill's approx. to cumulative t-dist, Commun.A.C.M. 13,617-619.
3073  // See: J.H.Maindonald, Computational Statistics, p.295.
3074  // Calculates p given t and tail type.
3075 
3076  if( !T || !df || df < 1. )
3077  {
3078  return( -1. );
3079  }
3080 
3081  return( _Change_Tail_Type(Get_T_P(T, df), TESTDIST_TYPE_TwoTail, Type, T < 0.) );
3082 }
3083 
3084 //---------------------------------------------------------
3086 { // Keith Dear & Robert Brennan.
3087  // Returns an accurate t to tol sig. fig.'s given p & df.
3088 
3089  if( p <= 0. || p >= 1. || df < 1 )
3090  {
3091  return( -1. );
3092  }
3093 
3094  bool bNegative = (Type == TESTDIST_TYPE_Left && p < 0.5) || (Type == TESTDIST_TYPE_Right && p > 0.5);
3095  double t = 0, p0, p1, diff = 1.;
3096 
3097  p0 = p1 = _Change_Tail_Type(p, Type, TESTDIST_TYPE_TwoTail, bNegative);
3098 
3099  while( fabs(diff) > 0.0001 )
3100  {
3101  t = Get_T_Inv(p1, df); // initial rough value
3102  diff = Get_T_P(t, df) - p0; // compare result with forward fn
3103  p1 = p1 - diff; // small adjustment to p1
3104  }
3105 
3106  return( bNegative ? -t : t );
3107 }
3108 
3109 //---------------------------------------------------------
3110 double CSG_Test_Distribution::_Change_Tail_Type(double p, TSG_Test_Distribution_Type from, TSG_Test_Distribution_Type to, bool bNegative)
3111 {
3112  if( from != to )
3113  {
3114  switch( from ) // convert any tail type to 'left'
3115  {
3116  case TESTDIST_TYPE_Left : break;
3117  case TESTDIST_TYPE_Right : p = 1. - p; break;
3118  case TESTDIST_TYPE_Middle : p = p / 2. + 0.5; if( bNegative ) p = 1. - p; break;
3119  case TESTDIST_TYPE_TwoTail: p = 1. - p / 2. ; if( bNegative ) p = 1. - p; break;
3120  // case TESTDIST_TYPE_Half : p = p + 0.5 ; if( bNegative ) p = 1. - p; break;
3121  }
3122 
3123  switch( to ) // convert p from tail type 'left' to any other
3124  {
3125  case TESTDIST_TYPE_Left : break;
3126  case TESTDIST_TYPE_Right : p = 1. - p; break;
3127  case TESTDIST_TYPE_Middle : if( bNegative ) p = 1. - p; p = 2. * (1. - p); break;
3128  case TESTDIST_TYPE_TwoTail: if( bNegative ) p = 1. - p; p = 2. * p - 1. ; break;
3129  // case TESTDIST_TYPE_Half : if( bNegative ) p = 1. - p; p = p - 0.5 ; break;
3130  }
3131  }
3132 
3133  return( p );
3134 }
3135 
3136 //---------------------------------------------------------
3138 { // Returns the two-tailed standard normal probability of z
3139  const double a1 = 0.0000053830, a2 = 0.0000488906, a3 = 0.0000380036;
3140  const double a4 = 0.0032776263, a5 = 0.0211410061, a6 = 0.0498673470;
3141 
3142  z = fabs(z);
3143 
3144  double p = (((((a1 * z + a2) * z + a3) * z + a4) * z + a5) * z + a6) * z + 1.;
3145 
3146  return( pow(p, -16) );
3147 }
3148 
3149 //---------------------------------------------------------
3151 { // Returns z given a half-middle tail type p.
3152  const double a0 = 2.5066282, a1 = -18.6150006, a2 = 41.3911977, a3 = -25.4410605;
3153  const double b1 = -8.4735109, b2 = 23.0833674, b3 = -21.0622410, b4 = 3.1308291;
3154  const double c0 = -2.7871893, c1 = -2.2979648, c2 = 4.8501413, c3 = 2.3212128;
3155  const double d1 = 3.5438892, d2 = 1.6370678;
3156 
3157  if( p > 0.42 )
3158  {
3159  double r = sqrt(-log(0.5 - p));
3160 
3161  return( (((c3 * r + c2) * r + c1) * r + c0) / ((d2 * r + d1) * r + 1.) );
3162  }
3163  else
3164  {
3165  double r = p * p;
3166 
3167  return( p * (((a3 * r + a2) * r + a1) * r + a0) / ((((b4 * r + b3) * r + b2) * r + b1) * r + 1.) );
3168  }
3169 }
3170 
3171 //---------------------------------------------------------
3172 double CSG_Test_Distribution::Get_T_P(double T, int df)
3173 { // Returns two-tail probability level given t and df.
3174  return( df == 1 ? 1. - 2. * atan(fabs(T)) / M_PI
3175  : df == 2 ? 1. - fabs(T) / sqrt(T*T + 2.)
3176  : df == 3 ? 1. - 2. * (atan(fabs(T) / sqrt(3.)) + fabs(T) * sqrt(3.) / (T*T + 3.)) / M_PI
3177  : df == 4 ? 1. - fabs(T) * (1. + 2. / (T*T + 4.)) / sqrt(T*T + 4.)
3178  : Get_Norm_P(Get_T_Z(fabs(T), df))
3179  );
3180 }
3181 
3182 //---------------------------------------------------------
3183 double CSG_Test_Distribution::Get_T_Z(double T, int df)
3184 { // Converts a t value to an approximate z value w.r.t the given df
3185  // s.t. std.norm.(z) = t(z, df) at the two-tail probability level.
3186 
3187  double A9, B9, T9, Z8, P7, B7, z;
3188 
3189  A9 = df - 0.5;
3190  B9 = 48. * A9*A9,
3191  T9 = T*T / df;
3192  Z8 = T9 >= 0.04
3193  ? A9 * log(1. + T9)
3194  : A9 * (((1. - T9 * 0.75) * T9 / 3. - 0.5) * T9 + 1.) * T9;
3195  P7 = ((0.4 * Z8 + 3.3) * Z8 + 24.) * Z8 + 85.5;
3196  B7 = 0.8 * pow(Z8, 2.) + 100. + B9;
3197  z = (1. + (-P7 / B7 + Z8 + 3.) / B9) * sqrt(Z8);
3198 
3199  return( z );
3200 }
3201 
3202 //---------------------------------------------------------
3203 double CSG_Test_Distribution::Get_T_Inv(double p, int df)
3204 { // Hill's approx. inverse t-dist.: Comm. of A.C.M Vol.13 No.10 1970 pg 620.
3205  // Calculates t given df and two-tail probability.
3206 
3207  if( df == 1 )
3208  {
3209  return( cos(p * M_PI / 2.) / sin(p * M_PI / 2.) );
3210  }
3211 
3212  if( df == 2 )
3213  {
3214  return( sqrt(2. / (p * (2. - p)) - 2.) );
3215  }
3216 
3217  double a = 1. / (df - 0.5);
3218  double b = 48. / (a*a);
3219  double c = ((20700. * a / b - 98.) * a - 16.) * a + 96.36;
3220  double d = ((94.5 / (b + c) - 3.) / b + 1.) * sqrt(a * M_PI / 2.) * df;
3221  double x = d * p;
3222  double y = pow(x, 2. / df);
3223 
3224  if( y > 0.05 + a )
3225  {
3226  x = Get_Norm_Z(0.5 * (1. - p));
3227  y = x*x;
3228 
3229  if( df < 5 )
3230  {
3231  c = c + 0.3 * (df - 4.5) * (x + 0.6);
3232  }
3233 
3234  c = (((0.05 * d * x - 5) * x - 7.) * x - 2.) * x + b + c;
3235  y = (((((0.4 * y + 6.3) * y + 36.) * y + 94.5) / c - y - 3.) / b + 1.) * x;
3236  y = a * y*y;
3237 
3238  if( y > 0.002 )
3239  {
3240  y = exp(y) - 1.;
3241  }
3242  else
3243  {
3244  y = 0.5 * y*y + y;
3245  }
3246  }
3247  else
3248  {
3249  y = ((1. / (((df + 6.) / (df * y) - 0.089 * d - 0.822) * (df + 2.) * 3.)
3250  + 0.5 / (df + 4.)) * y - 1.) * (df + 1.) / (df + 2.) + 1. / y;
3251  }
3252 
3253  return( sqrt(df * y) );
3254 }
3255 
3256 
3258 // //
3260 
3261 //---------------------------------------------------------
3262 double CSG_Test_Distribution::Get_F_Tail_from_R2(double R2, int nPredictors, int nSamples, TSG_Test_Distribution_Type Type)
3263 {
3264  double F = ((sLong)nSamples - (sLong)nPredictors - 1) * (R2 / nPredictors) / (1. - R2);
3265 
3266  return( CSG_Test_Distribution::Get_F_Tail(F, nPredictors, nSamples - nPredictors - 1, Type) );
3267 }
3268 
3269 //---------------------------------------------------------
3270 double CSG_Test_Distribution::Get_F_Tail(double F, int dfn, int dfd, TSG_Test_Distribution_Type Type)
3271 {
3272  // calculates for F, dfn(ominator) and dfd(enominator) the "tail" of the F-distribution
3273 
3274  double p = 1.;
3275 
3276  if( F >= 0.00001 && dfn > 0 && dfd > 0 )
3277  {
3278  if( F * dfn >= dfd || F > 1. + 20. / dfn + 10. / sqrt((double)dfn) )
3279  {
3280  p = Get_Gamma(F, dfn, dfd);
3281  }
3282  else
3283  {
3284  p = 1. - Get_Gamma(1. / F, dfd, dfn);
3285  }
3286  }
3287 
3288  if( p <= 0. || p >= 1. )
3289  {
3290  p = F > 1. ? 0. : F < 1. ? 1. : 0.5;
3291  }
3292 
3293  return( Type == TESTDIST_TYPE_Right ? p : 1. - p );
3294 }
3295 
3296 //---------------------------------------------------------
3297 double CSG_Test_Distribution::Get_F_Inverse(double alpha, int dfn, int dfd, TSG_Test_Distribution_Type Type)
3298 {
3299  if( alpha < 0. || alpha > 1. || dfd < 0 || dfn < 0 )
3300  {
3301  return( -1 );
3302  }
3303 
3304  if( Type != TESTDIST_TYPE_Right )
3305  {
3306  alpha = 1. - alpha;
3307  }
3308 
3309  const int ITERMAX = 100;
3310  const double EPSILON = 0.0001;
3311 
3312  int i;
3313  double lo, hi, mid, p;
3314 
3315  if( alpha <= 0.5 )
3316  {
3317  lo = 0.5;
3318  hi = lo;
3319 
3320  for(i=0; i<ITERMAX; i++)
3321  {
3322  hi *= 2.;
3323  p = Get_F_Tail(hi, dfn, dfd);
3324 
3325  if( p > alpha )
3326  {
3327  lo = hi;
3328  }
3329  else
3330  {
3331  break;
3332  }
3333  }
3334 
3335  if( p > alpha )
3336  {
3337  return( hi );
3338  }
3339  }
3340  else
3341  {
3342  hi = 2;
3343  lo = hi;
3344 
3345  for(i=0; i<ITERMAX; i++)
3346  {
3347  lo /= 2.;
3348  p = Get_F_Tail(lo, dfn, dfd);
3349 
3350  if( p < alpha )
3351  {
3352  hi = lo;
3353  }
3354  else
3355  {
3356  break;
3357  }
3358  }
3359 
3360  if( p < alpha )
3361  {
3362  return( lo );
3363  }
3364  }
3365 
3366  mid = (hi + lo) / 2.;
3367 
3368  for(i=0; i<ITERMAX && (hi-lo)>EPSILON*mid; i++)
3369  {
3370  mid = (hi + lo) / 2.;
3371  p = Get_F_Tail(mid, dfn, dfd);
3372 
3373  if( p < alpha )
3374  hi = mid;
3375  else if( p > alpha )
3376  lo = mid;
3377  else
3378  break;
3379  }
3380 
3381  return( mid );
3382 }
3383 
3384 //---------------------------------------------------------
3385 double CSG_Test_Distribution::Get_Gamma(double F, double dfn, double dfd)
3386 {
3387  // calculates for F, dfn(ominator) and dfd(enominator) the incomplete Gamma-function
3388 
3389  const double EXPMIN = -30.;
3390  const double SMALL = 0.00000000001;
3391 
3392  double x, c, er, s, n, t1, t;
3393 
3394  dfn /= 2.;
3395  dfd /= 2.;
3396 
3397  x = dfd / (dfd + dfn * F);
3398  c = Get_Log_Gamma(dfn + dfd) - Get_Log_Gamma(dfn) - Get_Log_Gamma(dfd + 1.) + dfd * log(x) + dfn * log(1. - x);
3399 
3400  if( c < EXPMIN )
3401  {
3402  return( -1. );
3403  }
3404 
3405  dfn += dfd;
3406  dfd += 1.;
3407  c = exp(c);
3408  er = SMALL / c;
3409  t = dfn * x / dfd;
3410  t1 = 0.;
3411  s = t + 1.;
3412  n = 0;
3413 
3414  while( t > er || t > t1 )
3415  {
3416  n += 1;
3417  t1 = t;
3418  t *= ((dfn + n) * x / (dfd + n));
3419  s += t;
3420  }
3421 
3422  return( s * c );
3423 }
3424 
3425 //---------------------------------------------------------
3426 double CSG_Test_Distribution::Get_Log_Gamma(double a)
3427 {
3428  // calculates the logarithm of the Gamma-function
3429 
3430  const int ARGMIN = 6;
3431 
3432  const double HL2PI = 0.91893853320467275; // = log(2. * M_PI) / 2.
3433 
3434  int n = (int)floor(ARGMIN - a + 0.0001);
3435 
3436  if( n > 0 )
3437  {
3438  a += n;
3439  }
3440 
3441  double g;
3442 
3443  g = 1. / (a*a);
3444  g = (1. - g * (1. / 30. - g * (1. / 105. - g * (1. / 140. - g / 99.)))) / (12. * a);
3445  g = g + ((a - 0.5) * log(a) - a + HL2PI);
3446 
3447  for(int i=0; i<n; i++)
3448  {
3449  a = a - 1.;
3450  g = g - log(a);
3451  }
3452 
3453  return( g );
3454 }
3455 
3456 
3458 // //
3459 // //
3460 // //
3462 
3463 //---------------------------------------------------------
3464 CSG_Matrix SG_Get_Correlation_Matrix (const CSG_Matrix &Values, bool bCovariances)
3465 {
3466  int nVariables = Values.Get_NX();
3467  int nSamples = Values.Get_NY();
3468 
3469  //-----------------------------------------------------
3470  int i, j, k;
3472  CSG_Matrix C;
3473 
3474  C.Create(nVariables, nVariables);
3475 
3476  //-----------------------------------------------------
3477  S = new CSG_Simple_Statistics[nVariables];
3478 
3479  for(j=0; j<nVariables; j++)
3480  {
3481  for(i=0; i<nSamples; i++)
3482  {
3483  S[j] += Values[i][j];
3484  }
3485  }
3486 
3487  //-----------------------------------------------------
3488  for(k=0; k<nVariables; k++)
3489  {
3490  for(j=k; j<nVariables; j++)
3491  {
3492  double cov = 0.;
3493 
3494  for(i=0; i<nSamples; i++)
3495  {
3496  cov += (Values[i][j] - S[j].Get_Mean()) * (Values[i][k] - S[k].Get_Mean());
3497  }
3498 
3499  cov /= nSamples;
3500 
3501  if( !bCovariances )
3502  {
3503  cov /= (S[j].Get_StdDev() * S[k].Get_StdDev());
3504  }
3505 
3506  C[j][k] = C[k][j] = cov;
3507  }
3508  }
3509 
3510  //-----------------------------------------------------
3511  delete[](S);
3512 
3513  return( C );
3514 }
3515 
3516 
3518 // //
3519 // //
3520 // //
3522 
3523 //---------------------------------------------------------
CSG_Classifier_Supervised::Destroy
void Destroy(void)
Definition: mat_tools.cpp:2409
SG_Get_Correlation_Matrix
CSG_Matrix SG_Get_Correlation_Matrix(const CSG_Matrix &Values, bool bCovariances)
Definition: mat_tools.cpp:3464
CSG_Table_Record::asDouble
double asDouble(int Field) const
Definition: table_record.cpp:527
CSG_Test_Distribution::Get_F_Tail
static double Get_F_Tail(double F, int dfn, int dfd, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
Definition: mat_tools.cpp:3270
CSG_Array::Set_Array
bool Set_Array(sLong nValues, bool bShrink=true)
Definition: api_memory.cpp:310
SG_Compare_Int
int SG_Compare_Int(const void *a, const void *b)
Definition: mat_tools.cpp:187
CSG_Histogram::Get_Cumulative
size_t Get_Cumulative(int i) const
Definition: mat_tools.h:1057
CSG_Matrix::Get_Inverse
CSG_Matrix Get_Inverse(bool bSilent=true, int nSubSquare=0) const
Definition: mat_matrix.cpp:1845
SG_FREE_SAFE
#define SG_FREE_SAFE(PTR)
Definition: api_core.h:205
CSG_Cluster_Analysis::Set_Feature
bool Set_Feature(sLong iElement, int iFeature, double Value)
Definition: mat_tools.cpp:2048
SG_Get_Double_asString
CSG_String SG_Get_Double_asString(double Number, int Width, int Precision, bool bScientific)
Definition: mat_tools.cpp:159
SG_T
#define SG_T(s)
Definition: api_core.h:537
CSG_Table::Get_Field_Type
TSG_Data_Type Get_Field_Type(int Field) const
Definition: table.h:363
CSG_Simple_Statistics::Get_SkewnessPearson
double Get_SkewnessPearson(void)
Definition: mat_tools.cpp:606
CSG_Histogram::Update
bool Update(void)
Definition: mat_tools.cpp:1366
_TL
#define _TL(s)
Definition: api_core.h:1559
CSG_Table::Del_Records
virtual bool Del_Records(void)
Definition: table.cpp:936
CSG_Cluster_Analysis::Execute
bool Execute(int Method, int nClusters, int nMaxIterations=0, int Initialization=0)
Definition: mat_tools.cpp:2071
CSG_Array::Get_Size
sLong Get_Size(void) const
Definition: api_core.h:327
CSG_Category_Statistics::Destroy
void Destroy(void)
Definition: mat_tools.cpp:1001
CSG_Unique_Value_Statistics::m_Count
CSG_Array_Int m_Count
Definition: mat_tools.h:841
SAGA_VERSION
#define SAGA_VERSION
Definition: saga_api.h:90
CSG_Cluster_Analysis::Create
bool Create(int nFeatures)
Definition: mat_tools.cpp:2025
CSG_Classifier_Supervised::Print
CSG_String Print(void)
Definition: mat_tools.cpp:2577
CSG_Simple_Statistics::m_Minimum
double m_Minimum
Definition: mat_tools.h:794
CSG_Table::Get_Value
virtual bool Get_Value(sLong Index, int Field, CSG_String &Value) const
Definition: table.cpp:1185
SG_CLASSIFY_SUPERVISED_Mahalonobis
@ SG_CLASSIFY_SUPERVISED_Mahalonobis
Definition: mat_tools.h:1228
CSG_Simple_Statistics::Get_Median
double Get_Median(void)
Definition: mat_tools.cpp:669
TESTDIST_TYPE_Right
@ TESTDIST_TYPE_Right
Definition: mat_tools.h:1527
SG_Compare_Char_Ptr
int SG_Compare_Char_Ptr(const void *a, const void *b)
Definition: mat_tools.cpp:211
M_RAD_TO_DEG
#define M_RAD_TO_DEG
Definition: mat_tools.h:108
CSG_Simple_Statistics::CSG_Simple_Statistics
CSG_Simple_Statistics(void)
Definition: mat_tools.cpp:324
CSG_MetaData::Get_Children_Count
int Get_Children_Count(void) const
Definition: metadata.h:148
CSG_Classifier_Supervised::Get_Threshold_Angle
double Get_Threshold_Angle(void)
Definition: mat_tools.cpp:2437
CSG_Histogram::Get_Percentile
double Get_Percentile(double Percentile) const
Definition: mat_tools.cpp:1467
SG_Get_Rounded
double SG_Get_Rounded(double Value, int Decimals)
Definition: mat_tools.cpp:83
CSG_MetaData::Get_Content
const CSG_String & Get_Content(void) const
Definition: metadata.h:133
CSG_Matrix::Get_NRows
sLong Get_NRows(void) const
Definition: mat_tools.h:525
CSG_Table_Record
Definition: table.h:130
CSG_Array_Int::Add
bool Add(int Value)
Definition: api_memory.cpp:567
CSG_Classifier_Supervised::Get_Probability_Relative
bool Get_Probability_Relative(void)
Definition: mat_tools.cpp:2445
CSG_Histogram::Get_Break
double Get_Break(int i) const
Definition: mat_tools.h:1062
CSG_Classifier_Supervised::Train_Add_Sample
bool Train_Add_Sample(const CSG_String &Class_ID, const CSG_Vector &Features)
Definition: mat_tools.cpp:2661
TESTDIST_TYPE_Middle
@ TESTDIST_TYPE_Middle
Definition: mat_tools.h:1528
SG_Decimal_To_Degree
void SG_Decimal_To_Degree(double Value, double &Deg, double &Min, double &Sec)
Definition: mat_tools.cpp:233
CSG_Category_Statistics::~CSG_Category_Statistics
virtual ~CSG_Category_Statistics(void)
Definition: mat_tools.cpp:986
CSG_Classifier_Supervised::Set_Threshold_Angle
void Set_Threshold_Angle(double Value)
Definition: mat_tools.cpp:2436
SG_Get_String
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
Definition: api_string.cpp:1367
CSG_Unique_Value_Statistics::Get_Minority
virtual int Get_Minority(bool bWeighted=false) const
Definition: mat_tools.cpp:833
CSG_Histogram
Definition: mat_tools.h:1013
CSG_Classifier_Supervised::Add_Class
bool Add_Class(const CSG_String &Class_ID, const CSG_Vector &Mean, const CSG_Vector &Min, const CSG_Vector &Max, const CSG_Matrix &Cov)
Definition: mat_tools.cpp:2613
CSG_Random::Get_Uniform
static double Get_Uniform(void)
Definition: mat_tools.cpp:274
C
#define C
SG_Get_Rounded_To_SignificantFigures
double SG_Get_Rounded_To_SignificantFigures(double Value, int Decimals)
Definition: mat_tools.cpp:107
SG_Malloc
SAGA_API_DLL_EXPORT void * SG_Malloc(size_t size)
Definition: api_memory.cpp:65
SG_UI_Process_Get_Okay
bool SG_UI_Process_Get_Okay(bool bBlink)
Definition: api_callback.cpp:207
CSG_Simple_Statistics::m_Variance
double m_Variance
Definition: mat_tools.h:794
CSG_Simple_Statistics::Get_nValues_Above
sLong Get_nValues_Above(double Threshold, bool bEquals=false)
Definition: mat_tools.cpp:758
CSG_Random::Get_Gaussian
static double Get_Gaussian(double mean, double stddev)
Definition: mat_tools.cpp:298
CSG_Simple_Statistics::m_StdDev
double m_StdDev
Definition: mat_tools.h:794
CSG_Array_Int::Create
int * Create(const CSG_Array_Int &Array)
Definition: api_memory.cpp:551
CSG_Category_Statistics::Get_Count
int Get_Count(void) const
Definition: mat_tools.cpp:1120
CSG_Classifier_Supervised::Get_Feature_Count
int Get_Feature_Count(void)
Definition: mat_tools.h:1258
saga_api.h
CSG_Table::Destroy
virtual bool Destroy(void)
Definition: table.cpp:314
grid.h
CSG_Category_Statistics::Get_Minority
int Get_Minority(void)
Definition: mat_tools.cpp:1186
CSG_Simple_Statistics::Get_Sum
double Get_Sum(void)
Definition: mat_tools.h:751
CSG_Histogram::Create
bool Create(const CSG_Histogram &Histogram)
Definition: mat_tools.cpp:1518
CSG_Classifier_Supervised::CSG_Classifier_Supervised
CSG_Classifier_Supervised(void)
Definition: mat_tools.cpp:2373
CSG_Grids::Get_NCells
sLong Get_NCells(void) const
Definition: grids.h:191
CSG_Unique_String_Statistics::Get_Class_Index
int Get_Class_Index(const CSG_String &Value) const
Definition: mat_tools.cpp:957
CSG_Vector::Add_Row
bool Add_Row(double Value=0.)
Definition: mat_matrix.cpp:188
CSG_Category_Statistics::Sort
bool Sort(void)
Definition: mat_tools.cpp:1108
CSG_Table::Get_Field_Count
int Get_Field_Count(void) const
Definition: table.h:361
CSG_Simple_Statistics::m_Gini
double m_Gini
Definition: mat_tools.h:794
CSG_Cluster_Analysis::Add_Element
bool Add_Element(void)
Definition: mat_tools.cpp:2042
CSG_Simple_Statistics::Evaluate
bool Evaluate(void)
Definition: mat_tools.cpp:473
SG_Free
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
Definition: api_memory.cpp:83
CSG_Simple_Statistics::m_Skewness
double m_Skewness
Definition: mat_tools.h:794
CSG_Cluster_Analysis::~CSG_Cluster_Analysis
virtual ~CSG_Cluster_Analysis(void)
Definition: mat_tools.cpp:2005
CSG_Classifier_Supervised::Get_Class
int Get_Class(const CSG_String &Class_ID)
Definition: mat_tools.cpp:2782
CSG_MetaData::Save
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition: metadata.cpp:879
CSG_MetaData::Get_Child
CSG_MetaData * Get_Child(int Index) const
Definition: metadata.h:149
CSG_Test_Distribution::Get_F_Inverse
static double Get_F_Inverse(double alpha, int dfn, int dfd, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
Definition: mat_tools.cpp:3297
CSG_Classifier_Supervised::Set_Threshold_Distance
void Set_Threshold_Distance(double Value)
Definition: mat_tools.cpp:2432
CSG_Histogram::~CSG_Histogram
virtual ~CSG_Histogram(void)
Definition: mat_tools.cpp:1269
SG_Compare_Double
int SG_Compare_Double(const void *a, const void *b)
Definition: mat_tools.cpp:199
CSG_Unique_Number_Statistics::Add_Value
void Add_Value(double Value, double Weight=1.)
Definition: mat_tools.cpp:875
CSG_Random::CSG_Random
CSG_Random(void)
Definition: mat_tools.cpp:254
CSG_Table::Find_Record
virtual bool Find_Record(sLong &Index, int Field, const CSG_String &Value, bool bCreateIndex=false)
Definition: table.cpp:974
SG_Calloc
SAGA_API_DLL_EXPORT void * SG_Calloc(size_t num, size_t size)
Definition: api_memory.cpp:71
CSG_String::Cmp
int Cmp(const CSG_String &String) const
Definition: api_string.cpp:515
CSG_Histogram::Get_Element_Count
size_t Get_Element_Count(void) const
Definition: mat_tools.h:1051
CSG_Natural_Breaks::Create
bool Create(class CSG_Table *pTable, int Field, int nClasses, int Histogram=0)
Definition: mat_tools.cpp:1764
CSG_Histogram::Get_Center
double Get_Center(int i) const
Definition: mat_tools.h:1065
CSG_Matrix::Get_NCols
sLong Get_NCols(void) const
Definition: mat_tools.h:524
SG_CLASSIFY_SUPERVISED_SVM
@ SG_CLASSIFY_SUPERVISED_SVM
Definition: mat_tools.h:1233
mat_tools.h
CSG_Category_Statistics::Get_Majority
int Get_Majority(void)
Definition: mat_tools.cpp:1164
CSG_Simple_Statistics::Get_Maximum
double Get_Maximum(void)
Definition: mat_tools.h:749
SG_CLASSIFY_SUPERVISED_SID
@ SG_CLASSIFY_SUPERVISED_SID
Definition: mat_tools.h:1232
CSG_Matrix::Create
bool Create(const CSG_Matrix &Matrix)
Definition: mat_matrix.cpp:836
CSG_Random::Initialize
static void Initialize(void)
Definition: mat_tools.cpp:260
CSG_Classifier_Supervised::Get_Name_of_Quality
static CSG_String Get_Name_of_Quality(int Method)
Definition: mat_tools.cpp:2848
CSG_Category_Statistics::Get_Category_Type
TSG_Data_Type Get_Category_Type(void) const
Definition: mat_tools.cpp:1007
CSG_MetaData::Cmp_Name
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition: metadata.cpp:461
CSG_Strings::Clear
void Clear(void)
Definition: api_core.h:736
CSG_Simple_Statistics::Get_nValues_Below
sLong Get_nValues_Below(double Threshold, bool bEquals=false)
Definition: mat_tools.cpp:780
CSG_Table_Record::asString
const SG_Char * asString(int Field, int Decimals=-99) const
Definition: table_record.cpp:461
CSG_Natural_Breaks::~CSG_Natural_Breaks
virtual ~CSG_Natural_Breaks(void)
Definition: mat_tools.cpp:1731
SG_CLASSIFY_SUPERVISED_WTA
@ SG_CLASSIFY_SUPERVISED_WTA
Definition: mat_tools.h:1231
CSG_Vector
Definition: mat_tools.h:362
CSG_Histogram::Add_Histogram
bool Add_Histogram(const CSG_Histogram &Histogram)
Definition: mat_tools.cpp:1408
TSG_Test_Distribution_Type
TSG_Test_Distribution_Type
Definition: mat_tools.h:1525
CSG_Test_Distribution::Get_Norm_P
static double Get_Norm_P(double Z)
Definition: mat_tools.cpp:3137
CSG_Simple_Statistics::Get_Count
sLong Get_Count(void) const
Definition: mat_tools.h:745
CSG_Natural_Breaks::Get_Count
int Get_Count(void) const
Definition: mat_tools.h:1128
CSG_Cluster_Analysis::Get_nElements
sLong Get_nElements(void) const
Definition: mat_tools.h:1181
CSG_Unique_String_Statistics::Add_Value
void Add_Value(const CSG_String &Value, double Weight=1.)
Definition: mat_tools.cpp:930
CSG_Strings::Add
bool Add(const CSG_Strings &Strings)
Definition: api_string.cpp:1069
CSG_Cluster_Analysis::Destroy
bool Destroy(void)
Definition: mat_tools.cpp:2011
CSG_Classifier_Supervised::Get_WTA
bool Get_WTA(int Method)
Definition: mat_tools.cpp:2456
CSG_Classifier_Supervised::Get_Class_ID
const CSG_String & Get_Class_ID(int iClass)
Definition: mat_tools.h:1262
CSG_Vector::Create
bool Create(const CSG_Vector &Vector)
Definition: mat_matrix.cpp:87
CSG_Simple_Statistics::Get_Minimum
double Get_Minimum(void)
Definition: mat_tools.h:748
CSG_Array::Destroy
bool Destroy(void)
Definition: api_memory.cpp:291
CSG_Histogram::Get_Quantile_Value
double Get_Quantile_Value(double Value) const
Definition: mat_tools.cpp:1476
CSG_Simple_Statistics::_Evaluate
void _Evaluate(int Level=1)
Definition: mat_tools.cpp:562
CSG_Simple_Statistics::m_Mean
double m_Mean
Definition: mat_tools.h:794
CSG_Classifier_Supervised::Load
bool Load(const CSG_String &File)
Definition: mat_tools.cpp:2470
CSG_Array::Get_Value_Size
size_t Get_Value_Size(void) const
Definition: api_core.h:326
CSG_Classifier_Supervised::Save
bool Save(const CSG_String &File, const SG_Char *Feature_Info=NULL)
Definition: mat_tools.cpp:2530
CSG_Grids::is_NoData
virtual bool is_NoData(int x, int y, int z) const
Definition: grids.h:373
sLong
signed long long sLong
Definition: api_core.h:158
CSG_Category_Statistics::asString
CSG_String asString(int iCategory) const
Definition: mat_tools.cpp:1151
CSG_MetaData::Add_Property
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition: metadata.cpp:559
CSG_Simple_Statistics::m_bEvaluated
int m_bEvaluated
Definition: mat_tools.h:790
CSG_Simple_Statistics::Get_StdDev
double Get_StdDev(void)
Definition: mat_tools.h:755
CSG_Table::is_Indexed
bool is_Indexed(void) const
Definition: table.h:454
CSG_Classifier_Supervised::Get_Class_Count
int Get_Class_Count(void)
Definition: mat_tools.h:1260
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:400
SG_Get_Square
double SG_Get_Square(double Value)
Definition: mat_tools.cpp:70
CSG_Simple_Statistics::Invalidate
void Invalidate(void)
Definition: mat_tools.cpp:447
CSG_Test_Distribution::Get_Norm_Z
static double Get_Norm_Z(double P)
Definition: mat_tools.cpp:3150
CSG_Category_Statistics::Add_Value
int Add_Value(int Value)
Definition: mat_tools.cpp:1047
SG_UI_Process_Set_Text
void SG_UI_Process_Set_Text(const CSG_String &Text)
Definition: api_callback.cpp:323
SG_CLASSIFY_SUPERVISED_SAM
@ SG_CLASSIFY_SUPERVISED_SAM
Definition: mat_tools.h:1230
CSG_Vector::Get_Angle
double Get_Angle(const CSG_Vector &Vector) const
Definition: mat_matrix.cpp:703
CSG_Array_Int
Definition: api_core.h:423
CSG_Simple_Statistics::is_Evaluated
int is_Evaluated(void) const
Definition: mat_tools.h:741
CSG_Vector::Get_N
int Get_N(void) const
Definition: mat_tools.h:384
CSG_Unique_Number_Statistics::Get_Class_Index
int Get_Class_Index(double Value) const
Definition: mat_tools.cpp:902
CSG_Unique_Value_Statistics::m_Weight
CSG_Vector m_Weight
Definition: mat_tools.h:843
CSG_Classifier_Supervised::Set_WTA
void Set_WTA(int Method, bool bOn)
Definition: mat_tools.cpp:2448
CSG_Classifier_Supervised::Get_Name_of_Method
static CSG_String Get_Name_of_Method(int Method)
Definition: mat_tools.cpp:2829
SG_CLASSIFY_SUPERVISED_ParallelEpiped
@ SG_CLASSIFY_SUPERVISED_ParallelEpiped
Definition: mat_tools.h:1226
CSG_Array::Create
void * Create(const CSG_Array &Array)
Definition: api_memory.cpp:250
CSG_Simple_Statistics::Get_Percentile
double Get_Percentile(double Percentile)
Definition: mat_tools.cpp:658
CSG_Category_Statistics::Get_Category
int Get_Category(int Value) const
Definition: mat_tools.cpp:1018
CSG_Histogram::Scale_Element_Count
bool Scale_Element_Count(double Scale)
Definition: mat_tools.cpp:1348
CSG_Simple_Statistics::Get_Mean
double Get_Mean(void)
Definition: mat_tools.h:753
CSG_Array::Get_Array
void * Get_Array(void) const
Definition: api_core.h:336
CSG_Table::Get_Record_byIndex
CSG_Table_Record * Get_Record_byIndex(sLong Index) const
Definition: table.h:407
CSG_Unique_Value_Statistics::Get_Count
int Get_Count(void) const
Definition: mat_tools.h:819
CSG_Category_Statistics::asDouble
double asDouble(int iCategory) const
Definition: mat_tools.cpp:1143
CSG_Table_Record::Add_Value
bool Add_Value(int Field, double Value)
Definition: table_record.cpp:329
SG_CLASSIFY_SUPERVISED_MaximumLikelihood
@ SG_CLASSIFY_SUPERVISED_MaximumLikelihood
Definition: mat_tools.h:1229
CSG_Histogram::Get_Class_Count
size_t Get_Class_Count(void) const
Definition: mat_tools.h:1049
CSG_Simple_Statistics::Set_Count
bool Set_Count(sLong Count)
Definition: mat_tools.cpp:424
CSG_Simple_Statistics::Add
void Add(const CSG_Simple_Statistics &Statistics)
Definition: mat_tools.cpp:481
CSG_String::Format
static CSG_String Format(const char *Format,...)
Definition: api_string.cpp:270
CSG_Category_Statistics::CSG_Category_Statistics
CSG_Category_Statistics(TSG_Data_Type Type=SG_DATATYPE_String)
Definition: mat_tools.cpp:978
CSG_Classifier_Supervised::Get_Threshold_Probability
double Get_Threshold_Probability(void)
Definition: mat_tools.cpp:2441
CSG_Table::Add_Field
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition: table.cpp:479
CSG_Histogram::Add_Value
void Add_Value(double Value)
Definition: mat_tools.cpp:1330
CSG_Table
Definition: table.h:285
CSG_Vector::Get_Size
sLong Get_Size(void) const
Definition: mat_tools.h:382
CSG_Classifier_Supervised::~CSG_Classifier_Supervised
virtual ~CSG_Classifier_Supervised(void)
Definition: mat_tools.cpp:2392
CSG_Histogram::Get_Percentile_Value
double Get_Percentile_Value(double Value) const
Definition: mat_tools.cpp:1507
CSG_String::Clear
void Clear(void)
Definition: api_string.cpp:259
CSG_Simple_Statistics::m_Maximum
double m_Maximum
Definition: mat_tools.h:794
CSG_Simple_Statistics::m_Sum
double m_Sum
Definition: mat_tools.h:794
CSG_Table_Record::asInt
int asInt(int Field) const
Definition: table_record.cpp:494
CSG_Vector::Destroy
bool Destroy(void)
Definition: mat_matrix.cpp:130
CSG_Simple_Statistics::m_nValues
sLong m_nValues
Definition: mat_tools.h:792
TESTDIST_TYPE_TwoTail
@ TESTDIST_TYPE_TwoTail
Definition: mat_tools.h:1529
CSG_Grids::asDouble
virtual double asDouble(sLong i, bool bScaled=true) const
Definition: grids.h:402
SG_Char
#define SG_Char
Definition: api_core.h:536
CSG_Array::Inc_Array
bool Inc_Array(sLong nValues=1)
Definition: api_memory.cpp:414
M_PI
#define M_PI
Definition: mat_tools.h:96
CSG_Unique_Value_Statistics::m_bWeights
bool m_bWeights
Definition: mat_tools.h:839
CSG_String
Definition: api_core.h:563
CSG_Simple_Statistics::m_Sum2
double m_Sum2
Definition: mat_tools.h:794
CSG_Histogram::Destroy
bool Destroy(void)
Definition: mat_tools.cpp:1275
SG_Get_Digit_Count
int SG_Get_Digit_Count(int Number)
Definition: mat_tools.cpp:144
CSG_Simple_Statistics::Get_Values
double * Get_Values(void) const
Definition: mat_tools.h:776
CSG_Simple_Statistics::Add_Value
void Add_Value(double Value, double Weight=1.)
Definition: mat_tools.cpp:527
CSG_Grid::asDouble
virtual double asDouble(sLong i, bool bScaled=true) const
Definition: grid.h:793
CSG_Simple_Statistics::Get_Value
double Get_Value(sLong i) const
Definition: mat_tools.h:777
CSG_Unique_String_Statistics::Create
virtual void Create(bool bWeights=false)
Definition: mat_tools.cpp:921
CSG_MetaData
Definition: metadata.h:88
CSG_Histogram::operator=
CSG_Histogram & operator=(const CSG_Histogram &Histogram)
Definition: mat_tools.cpp:1712
CSG_MetaData::Load
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition: metadata.cpp:786
CSG_Unique_Value_Statistics::Get_Majority
virtual int Get_Majority(bool bWeighted=false) const
Definition: mat_tools.cpp:805
CSG_String::is_Empty
bool is_Empty(void) const
Definition: api_string.cpp:178
SG_CLASSIFY_SUPERVISED_BinaryEncoding
@ SG_CLASSIFY_SUPERVISED_BinaryEncoding
Definition: mat_tools.h:1225
CSG_Simple_Statistics::Get_Gini
double Get_Gini(void)
Definition: mat_tools.cpp:681
CSG_Matrix::Destroy
bool Destroy(void)
Definition: mat_matrix.cpp:923
CSG_Unique_Number_Statistics::Create
virtual void Create(bool bWeights=false)
Definition: mat_tools.cpp:866
CSG_Simple_Statistics::Create
bool Create(bool bHoldValues=false)
Definition: mat_tools.cpp:350
CSG_Histogram::CSG_Histogram
CSG_Histogram(void)
Definition: mat_tools.cpp:1215
CSG_Category_Statistics::asInt
int asInt(int iCategory) const
Definition: mat_tools.cpp:1135
CSG_Matrix::Get_Determinant
double Get_Determinant(void) const
Definition: mat_matrix.cpp:1806
CSG_Grid
Definition: grid.h:501
CSG_MetaData::Set_Name
void Set_Name(const CSG_String &Name)
Definition: metadata.h:130
CSG_Simple_Statistics::Get_IndexOfMinimum
sLong Get_IndexOfMinimum(void)
Definition: mat_tools.cpp:710
SG_Compare_Version
int SG_Compare_Version(const CSG_String &Version, int Major, int Minor, int Release)
Definition: saga_api.cpp:82
CSG_Classifier_Supervised::Train
bool Train(bool bClr_Samples=false)
Definition: mat_tools.cpp:2689
CSG_Table_Record::Get_Index
sLong Get_Index(void) const
Definition: table.h:136
CSG_Simple_Statistics::m_Kurtosis
double m_Kurtosis
Definition: mat_tools.h:794
CSG_Histogram::Get_Quantile
double Get_Quantile(double Quantile) const
Definition: mat_tools.cpp:1432
TABLE_INDEX_Ascending
@ TABLE_INDEX_Ascending
Definition: table.h:105
SG_CLASSIFY_SUPERVISED_MinimumDistance
@ SG_CLASSIFY_SUPERVISED_MinimumDistance
Definition: mat_tools.h:1227
CSG_Test_Distribution::Get_F_Tail_from_R2
static double Get_F_Tail_from_R2(double R2, int nPredictors, int nSamples, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
Definition: mat_tools.cpp:3262
TSG_Data_Type
TSG_Data_Type
Definition: api_core.h:997
TESTDIST_TYPE_Left
@ TESTDIST_TYPE_Left
Definition: mat_tools.h:1526
SG_Realloc
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
Definition: api_memory.cpp:77
CSG_Simple_Statistics::Get_Quantile
double Get_Quantile(double Quantile)
Definition: mat_tools.cpp:618
CSG_Table::Set_Index
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition: table.cpp:1508
CSG_MetaData::Add_Child
CSG_MetaData * Add_Child(void)
Definition: metadata.cpp:166
CSG_Classifier_Supervised::Set_Threshold_Probability
void Set_Threshold_Probability(double Value)
Definition: mat_tools.cpp:2440
CSG_Classifier_Supervised::Set_Probability_Relative
void Set_Probability_Relative(bool Value)
Definition: mat_tools.cpp:2444
CSG_Table::Add_Record
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition: table.cpp:823
CSG_Classifier_Supervised::Train_Clr_Samples
bool Train_Clr_Samples(void)
Definition: mat_tools.cpp:2650
CSG_Grid::is_NoData
virtual bool is_NoData(int x, int y) const
Definition: grid.h:727
EPSILON
#define EPSILON
Definition: mat_formula.cpp:92
CSG_Category_Statistics::Create
void Create(TSG_Data_Type Type=SG_DATATYPE_String)
Definition: mat_tools.cpp:992
CSG_Matrix
Definition: mat_tools.h:480
CSG_Grids
Definition: grids.h:119
CSG_Test_Distribution::Get_T_Tail
static double Get_T_Tail(double T, int df, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
Definition: mat_tools.cpp:3071
CSG_Test_Distribution::Get_T_Inverse
static double Get_T_Inverse(double alpha, int df, TSG_Test_Distribution_Type Type=TESTDIST_TYPE_Right)
Definition: mat_tools.cpp:3085
CSG_Simple_Statistics::Get_IndexOfMaximum
sLong Get_IndexOfMaximum(void)
Definition: mat_tools.cpp:734
CSG_Array_Int::Destroy
void Destroy(void)
Definition: api_core.h:431
CSG_Simple_Statistics
Definition: mat_tools.h:725
CSG_Simple_Statistics::m_Values
CSG_Array m_Values
Definition: mat_tools.h:796
CSG_Simple_Statistics::m_Range
double m_Range
Definition: mat_tools.h:794
CSG_Natural_Breaks::CSG_Natural_Breaks
CSG_Natural_Breaks(void)
Definition: mat_tools.cpp:1727
table.h
CSG_Histogram::Get_Value
double Get_Value(double i) const
Definition: mat_tools.h:1060
CSG_Vector::Sort
bool Sort(bool bAscending=true)
Definition: mat_matrix.cpp:642
CSG_MetaData::Get_Property
const SG_Char * Get_Property(int Index) const
Definition: metadata.h:181
CSG_Classifier_Supervised::Get_Threshold_Distance
double Get_Threshold_Distance(void)
Definition: mat_tools.cpp:2433
CSG_Matrix::Get_NY
int Get_NY(void) const
Definition: mat_tools.h:523
SG_DATATYPE_ULong
@ SG_DATATYPE_ULong
Definition: api_core.h:1005
CSG_Classifier_Supervised::Create
void Create(int nFeatures)
Definition: mat_tools.cpp:2398
CSG_Array::Get_Entry
void * Get_Entry(sLong Index) const
Returns a pointer to the memory address of the requested variable. You have to type cast and derefere...
Definition: api_core.h:331
SG_Degree_To_Decimal
double SG_Degree_To_Decimal(double Deg, double Min, double Sec)
Definition: mat_tools.cpp:224
CSG_Cluster_Analysis::CSG_Cluster_Analysis
CSG_Cluster_Analysis(void)
Definition: mat_tools.cpp:1998
CSG_Grid::Get_NCells
sLong Get_NCells(void) const
Definition: grid.h:565
CSG_Simple_Statistics::m_Weights
double m_Weights
Definition: mat_tools.h:794
CSG_Matrix::Get_NX
int Get_NX(void) const
Definition: mat_tools.h:522
CSG_Simple_Statistics::m_bSorted
bool m_bSorted
Definition: mat_tools.h:788
grids.h