72 return( Value * Value );
92 return( floor(0.5 + Value) );
95 double d = pow(10., Decimals);
98 if( fabs(v - floor(v)) > 0. )
100 return( floor(0.5 + v) / d );
109 if( Decimals <= 0 || Value == 0. )
111 return( (
int)(0.5 + Value) );
114 Decimals = (int)(-(ceil(log10(fabs(Value))) - Decimals));
118 double d = pow(10., Decimals);
121 ? -((
int)(0.5 - Value * d)) / d
122 : ((
int)(0.5 + Value * d)) / d
127 double d = pow(10., -Decimals);
130 ? -((
int)(0.5 - Value / d)) * d
131 : ((
int)(0.5 + Value / d)) * d
146 Number = abs(Number);
148 return( Number < 10 ? 1 : 1 + (
int)log10((
double)Number) );
163 if( Width > 0 && Precision >= 0 )
return(
CSG_String::Format(
"%*.*e", Width, Precision, Number) );
171 if( Width > 0 && Precision >= 0 )
return(
CSG_String::Format(
"%*.*f", Width, Precision, Number) );
189 if( *((
int *)a) < *((
int *)b) )
192 if( *((
int *)a) > *((
int *)b) )
201 if( *((
double *)a) < *((
double *)b) )
204 if( *((
double *)a) > *((
double *)b) )
213 return( strcmp((
const char *)a, (
const char *)b) );
227 ? (Deg + Min / 60. + Sec / 3600.)
228 : (Deg - Min / 60. - Sec / 3600.)
235 Sec = fmod(Value < 0. ? -Value : Value, 360.);
237 Deg = (int)Sec; Sec = 60. * (Sec - Deg);
238 Min = (int)Sec; Sec = 60. * (Sec - Min);
276 return( 1. * rand() / (
double)RAND_MAX );
284 return( min + (max - min) * rand() / (
double)RAND_MAX );
307 w = x1 * x1 + x2 * x2;
311 w = sqrt((-2. * log(w)) / w);
313 return( mean + stddev * x1 * w );
341 Create(Mean, StdDev, Count);
346 Create(Values, bHoldValues);
354 m_Values.
Create(bHoldValues ?
sizeof(
double) : 0, 0, TSG_Array_Growth::SG_ARRAY_GROWTH_1);
431 double Scale = nValues / (double)
m_nValues;
545 m_Sum += Weight * Value;
546 m_Sum2 += Weight * Value*Value;
726 return( (
sLong)Index );
750 return( (
sLong)Index );
879 if( Value == m_Value[i] )
906 if( Value == m_Value[i] )
934 if( Value.
Cmp(m_Value[i]) == 0 )
961 if( Value.
Cmp(m_Value[i]) == 0 )
1022 return( pRecord ? (
int)pRecord->
Get_Index() : -1);
1030 return( pRecord ? (
int)pRecord->
Get_Index() : -1);
1038 return( pRecord ? (
int)pRecord->
Get_Index() : -1);
1053 (pRecord = m_pTable->
Add_Record())->Set_Value(0, Value);
1063 return( (
int)(m_pTable->
Get_Count() - 1) );
1073 (pRecord = m_pTable->
Add_Record())->Set_Value(0, Value);
1083 return( (
int)(m_pTable->
Get_Count() - 1) );
1093 (pRecord = m_pTable->
Add_Record())->Set_Value(0, Value);
1103 return( (
int)(m_pTable->
Get_Count() - 1) );
1131 return( pRecord ? pRecord->
asInt(1) : 0 );
1139 return( pRecord ? pRecord->
asInt(0) : 0 );
1147 return( pRecord ? pRecord->
asDouble(0) : 0 );
1170 for(
int i=1; i<m_pTable->
Get_Count(); i++)
1172 if( Count < m_pTable->Get_Record_byIndex(i)->
asInt(1) )
1192 for(
int i=1; i<m_pTable->
Get_Count(); i++)
1233 Create(nClasses, Minimum, Maximum);
1241 Create(nClasses, Minimum, Maximum, Values, maxSamples);
1249 Create(nClasses, Minimum, Maximum, pTable, Field, maxSamples);
1257 Create(nClasses, Minimum, Maximum, pGrid, maxSamples);
1265 Create(nClasses, Minimum, Maximum, pGrids, maxSamples);
1293 void CSG_Histogram::_On_Construction(
void)
1297 m_Cumulative = NULL;
1304 bool CSG_Histogram::_Create(
size_t nClasses,
double Minimum,
double Maximum)
1306 if( nClasses > 0 && Minimum < Maximum )
1310 m_Elements = (
size_t *)
SG_Calloc(nClasses,
sizeof(
size_t));
1311 m_Cumulative = (
size_t *)
SG_Calloc(nClasses,
sizeof(
size_t));
1313 if( m_Elements && m_Cumulative )
1315 m_nClasses = nClasses;
1316 m_Minimum = Minimum;
1317 m_Maximum = Maximum;
1318 m_ClassWidth = (Maximum - Minimum) / (
double)m_nClasses;
1332 m_Statistics += Value;
1334 if( m_nClasses > 0 && m_Minimum <= Value && Value <= m_Maximum )
1336 size_t Class = (size_t)((Value - m_Minimum) / m_ClassWidth);
1338 if( Class >= m_nClasses )
1340 Class = m_nClasses - 1;
1343 m_Elements[Class]++;
1350 if( m_nClasses > 0 && Scale > 0. )
1354 for(
size_t i=0; i<m_nClasses; i++)
1356 m_Elements[i] = (size_t)(Scale * m_Elements[i]);
1368 if( m_nClasses > 0 )
1372 m_nMaximum = m_Cumulative[0] = m_Elements[0];
1374 for(
size_t i=1; i<m_nClasses; i++)
1376 m_Cumulative[i] = m_Cumulative[i - 1] + m_Elements[i];
1378 if( m_nMaximum < m_Elements[i] )
1380 m_nMaximum = m_Elements[i];
1391 bool CSG_Histogram::_Update(
sLong nElements)
1393 if( nElements > 0 && m_Statistics.
Get_Count() > 0 )
1395 double Scale = (double)nElements / (
double)m_Statistics.
Get_Count();
1399 for(
size_t i=1; i<m_nClasses; i++)
1401 m_Elements[i] = (size_t)(0.5 + Scale * m_Elements[i]);
1414 if( m_nClasses < 2 ) {
return( 0. ); }
1416 if( Quantile <= 0. ) {
return( m_Minimum ); }
1417 if( Quantile >= 1. ) {
return( m_Maximum ); }
1421 for(
size_t i=0, n0=0; i<m_nClasses; n0=m_Cumulative[i++])
1423 if( n < m_Cumulative[i] )
1425 if( m_Cumulative[i] >= n0 )
1430 double d = (n - n0) / (
double)(m_Cumulative[i] - n0);
1432 return(
Get_Break(i) + d * m_ClassWidth );
1434 else if( n == m_Cumulative[i] )
1440 return( m_Maximum );
1458 if( m_nClasses < 2 ) {
return( 0. ); }
1460 if( Value <= m_Minimum ) {
return( 0. ); }
1461 if( Value >= m_Maximum ) {
return( 1. ); }
1463 size_t Class = (size_t)(m_nClasses * (Value - m_Minimum) / (m_Maximum - m_Minimum));
1465 if( Class >= m_nClasses )
1474 return( dq * (Value - m_Minimum) / m_ClassWidth );
1480 return( q0 + dq * (Value -
Get_Break(Class)) / m_ClassWidth );
1500 if( !_Create(Histogram.m_nClasses, Histogram.m_Minimum, Histogram.m_Maximum) )
1505 m_Statistics = Histogram.m_Statistics;
1506 m_ClassWidth = Histogram.m_ClassWidth;
1507 m_nMaximum = Histogram.m_nMaximum ;
1509 for(
size_t i=0; i<m_nClasses; i++)
1511 m_Cumulative[i] = Histogram.m_Cumulative[i];
1512 m_Elements [i] = Histogram.m_Elements [i];
1521 return( _Create(nClasses, Minimum, Maximum) );
1527 if( Minimum >= Maximum )
1535 if( !_Create(nClasses, Minimum, Maximum) )
1541 if( maxSamples > 0 && maxSamples < (
size_t)Values.
Get_N() )
1543 double d = (double)Values.
Get_N() / (double)maxSamples;
1545 for(
double i=0; i<(double)Values.
Get_N(); i+=d)
1550 d = (double)m_Statistics.
Get_Count() / (double)maxSamples;
1552 return( _Update(d < 1. ? (
int)(d * (double)Values.
Get_N()) : Values.
Get_N()) );
1556 for(
int i=0; i<Values.
Get_N(); i++)
1567 if( !pTable || Field < 0 || Field >= pTable->
Get_Field_Count() || !_Create(nClasses,
1568 Minimum < Maximum ? Minimum : pTable->Get_Minimum(Field),
1569 Minimum < Maximum ? Maximum : pTable->Get_Maximum(Field)) )
1575 if( maxSamples > 0 && maxSamples < (
size_t)pTable->
Get_Count() )
1577 double d = (double)pTable->
Get_Count() / (double)maxSamples;
1579 for(
double i=0; i<(double)pTable->
Get_Count(); i+=d)
1581 double Value = pTable->
Get_Record((
int)i)->asDouble(Field);
1589 d = (double)m_Statistics.
Get_Count() / (double)maxSamples;
1611 if( !pGrid || !_Create(nClasses,
1612 Minimum < Maximum ? Minimum : pGrid->Get_Min(),
1613 Minimum < Maximum ? Maximum : pGrid->Get_Max()) )
1619 if( maxSamples > 0 && (
sLong)maxSamples < pGrid->Get_NCells() )
1621 double d = (double)pGrid->
Get_NCells() / (double)maxSamples;
1623 for(
double i=0; i<(double)pGrid->
Get_NCells(); i+=d)
1633 d = (double)m_Statistics.
Get_Count() / (double)maxSamples;
1653 if( !pGrids || !_Create(nClasses,
1654 Minimum < Maximum ? Minimum : pGrids->Get_Min(),
1655 Minimum < Maximum ? Maximum : pGrids->Get_Max()) )
1661 if( maxSamples > 0 && (
sLong)maxSamples < pGrids->Get_NCells() )
1663 double d = (double)pGrids->
Get_NCells() / (double)maxSamples;
1665 for(
double i=0; i<(double)pGrids->
Get_NCells(); i+=d)
1675 d = (double)m_Statistics.
Get_Count() / (double)maxSamples;
1723 Create(pTable, Field, nClasses, Histogram);
1729 Create(pGrid, nClasses, Histogram);
1735 Create(pGrids, nClasses, Histogram);
1741 Create(Values, nClasses, Histogram);
1752 bool bResult =
false;
1756 bResult = m_Histogram.
Create(Histogram, 0, 0, pTable, Field) && _Histogram(nClasses);
1758 else if( Field >= 0 && Field < pTable->Get_Field_Count() )
1770 bResult = m_Values.
Sort() && _Calculate(nClasses);
1781 bool bResult =
false;
1785 bResult = m_Histogram.
Create(Histogram, 0, 0, pGrid) && _Histogram(nClasses);
1797 bResult = m_Values.
Sort() && _Calculate(nClasses);
1808 bool bResult =
false;
1812 bResult = m_Histogram.
Create(Histogram, 0, 0, pGrids) && _Histogram(nClasses);
1824 bResult = m_Values.
Sort() && _Calculate(nClasses);
1835 bool bResult =
false;
1839 bResult = m_Histogram.
Create(Histogram, 0, 0, Values) && _Histogram(nClasses);
1843 bResult = m_Values.
Create(Values) && m_Values.
Sort() && _Calculate(nClasses);
1857 bool CSG_Natural_Breaks::_Histogram(
int nClasses)
1859 if( _Calculate(nClasses) )
1867 m_Breaks[i] = m_Histogram.
Get_Value(m_Breaks[i] * d);
1883 inline double CSG_Natural_Breaks::_Get_Value(
int i)
1890 return( m_Values[i] );
1894 bool CSG_Natural_Breaks::_Calculate(
int nClasses)
1903 CSG_Matrix mv(nClasses, nValues); mv.Assign(FLT_MAX);
1905 int **mc = (
int **)
SG_Malloc(nValues *
sizeof(
int *));
1907 mc[0] = (
int *)
SG_Calloc((
size_t)nClasses * nValues,
sizeof(int));
1909 for(
int i=0; i<nValues; i++)
1911 mc[i] = mc[0] + i * (size_t)nClasses;
1915 for(
int i=1; i<nValues; i++)
1917 double v = 0., s1 = 0., s2 = 0., w = 0.;
1919 for(
int m=0, n=i+1; m<=i; m++, n--)
1925 v = s2 - (s1 * s1) / w;
1929 for(
int j=1; j<nClasses; j++)
1931 if( mv[i][j] >= (v + mv[n - 1][j - 1]) )
1934 mv[i][j] = v + mv[n - 1][j - 1];
1947 for(
int i=0; i<nClasses; i++)
1952 int j = Class[(size_t)nClasses - 1] = nValues - 1;
1954 for(
int i=nClasses-1; i>0; i--)
1956 Class[(size_t)i - 1] = j = mc[j - 1][i];
1960 m_Breaks.
Create((
size_t)nClasses + 1);
1962 m_Breaks[0] = _Get_Value(0);
1964 for(
int i=1; i<nClasses; i++)
1966 m_Breaks[i] = _Get_Value(Class[i - 1]);
1969 m_Breaks[nClasses] = _Get_Value(nValues - 1);
2017 m_nFeatures = nFeatures;
2019 m_Features.
Create(m_nFeatures *
sizeof(
double), 0, TSG_Array_Growth::SG_ARRAY_GROWTH_3);
2030 return( m_nFeatures > 0 && m_Features.
Inc_Array() );
2036 if( iElement >= 0 && iElement <
Get_nElements() && iFeature >= 0 && iFeature < m_nFeatures )
2038 ((
double *)m_Features.
Get_Entry(iElement))[iFeature] = Value;
2065 m_nMembers.
Create(nClusters);
2066 m_Variance.
Create(nClusters);
2067 m_Centroid.
Create(m_nFeatures, nClusters);
2074 switch( Initialization )
2079 m_Clusters[iElement] = nClusters - 1;
2085 m_Clusters[iElement] = iElement % nClusters;
2090 if( 0 > m_Clusters[iElement] || m_Clusters[iElement] >= nClusters )
2092 m_Clusters[iElement] = iElement % nClusters;
2105 default: bResult = _Minimum_Distance(
true , nMaxIterations);
break;
2106 case 1: bResult = _Hill_Climbing (
true , nMaxIterations);
break;
2107 case 2: bResult = _Minimum_Distance(
true , nMaxIterations)
2108 && _Hill_Climbing (
false, nMaxIterations);
break;
2114 for(
int iCluster=0; iCluster<nClusters; iCluster++)
2116 m_Variance[iCluster] = m_nMembers[iCluster] <= 0 ? 0. : m_Variance[iCluster] / m_nMembers[iCluster];
2124 bool CSG_Cluster_Analysis::_Minimum_Distance(
bool bInitialize,
int nMaxIterations)
2126 int iElement, iCluster, nClusters = m_Variance.
Get_N();
2128 double SP_Last = -1.;
2140 m_nMembers[iCluster = m_Clusters[iElement]]++;
2142 double *Feature = (
double *)m_Features.
Get_Entry(iElement);
2144 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2146 m_Centroid[iCluster][iFeature] += Feature[iFeature];
2151 for(iCluster=0; iCluster<nClusters; iCluster++)
2153 double d = m_nMembers[iCluster] > 0 ? 1. / m_nMembers[iCluster] : 0.;
2155 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2157 m_Centroid[iCluster][iFeature] *= d;
2162 int nShifts = 0; m_SP = 0.;
2166 double *Feature = (
double *)m_Features.
Get_Entry(iElement);
2168 double minVariance = -1.;
2169 int minCluster = -1;
2171 for(iCluster=0; iCluster<nClusters; iCluster++)
2173 double Variance = 0.;
2175 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2177 Variance +=
SG_Get_Square(m_Centroid[iCluster][iFeature] - Feature[iFeature]);
2180 if( minVariance < 0. || Variance < minVariance )
2182 minVariance = Variance;
2183 minCluster = iCluster;
2187 if( m_Clusters[iElement] != minCluster )
2189 m_Clusters[iElement] = minCluster;
2194 m_SP += minVariance;
2195 m_Variance[minCluster] += minVariance;
2202 _TL(
"pass" ), m_Iteration,
2203 _TL(
"change"), m_Iteration < 2 ? m_SP : SP_Last - m_SP
2208 if( nShifts == 0 || (nMaxIterations > 0 && nMaxIterations <= m_Iteration) )
2218 bool CSG_Cluster_Analysis::_Hill_Climbing(
bool bInitialize,
int nMaxIterations)
2220 int iElement, iCluster, nClusters = m_Variance.
Get_N();
2229 m_nMembers[iCluster = m_Clusters[iElement]]++;
2231 double *Feature = (
double *)m_Features.
Get_Entry(iElement);
2233 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2235 double d = Feature[iFeature];
2237 m_Centroid[iCluster][iFeature] += d;
2238 m_Variance[iCluster] += d*d;
2243 for(iCluster=0; iCluster<nClusters; iCluster++)
2245 double v = 0., d = m_nMembers[iCluster] <= 0 ? 0. : 1. / (double)m_nMembers[iCluster];
2247 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2249 m_Centroid[iCluster][iFeature] *= d;
2253 m_Variance[iCluster] -= v * m_nMembers[iCluster];
2257 double SP_Last = -1.;
int noShift = 0;
2263 iCluster = m_Clusters[iElement];
2265 if( noShift++ <
Get_nElements() && m_nMembers[iCluster] > 1 )
2267 double *Feature = (
double *)m_Features.
Get_Entry(iElement);
2269 double Variance = 0.;
2271 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2273 Variance +=
SG_Get_Square(m_Centroid[iCluster][iFeature] - Feature[iFeature]);
2276 double V1 = Variance * m_nMembers[iCluster] / (m_nMembers[iCluster] - 1.);
2279 int kCluster = 0;
double VMin = -1.;
2281 for(
int jCluster=0; jCluster<nClusters; jCluster++)
2283 if( jCluster != iCluster )
2287 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2289 Variance +=
SG_Get_Square(m_Centroid[jCluster][iFeature] - Feature[iFeature]);
2292 double V2 = Variance * m_nMembers[jCluster] / (m_nMembers[jCluster] + 1.);
2294 if( VMin < 0. || V2 < VMin )
2297 kCluster = jCluster;
2303 if( VMin >= 0 && VMin < V1 )
2306 m_Variance[iCluster] -= V1;
2307 m_Variance[kCluster] += VMin;
2308 V1 = 1. / (m_nMembers[iCluster] - 1.);
2309 double V2 = 1. / (m_nMembers[kCluster] + 1.);
2311 for(
int iFeature=0; iFeature<m_nFeatures; iFeature++)
2313 double d = Feature[iFeature];
2315 m_Centroid[iCluster][iFeature] = (m_nMembers[iCluster] * m_Centroid[iCluster][iFeature] - d) * V1;
2316 m_Centroid[kCluster][iFeature] = (m_nMembers[kCluster] * m_Centroid[kCluster][iFeature] + d) * V2;
2319 m_Clusters[iElement] = kCluster;
2321 m_nMembers[iCluster]--;
2322 m_nMembers[kCluster]++;
2328 for(iCluster=0, m_SP=0.; iCluster<nClusters; iCluster++)
2330 m_SP += m_Variance[iCluster];
2336 _TL(
"pass" ), m_Iteration,
2337 _TL(
"change"), m_Iteration <= 1 ? m_SP : SP_Last - m_SP
2342 if( noShift >=
Get_nElements() || (nMaxIterations > 0 && nMaxIterations <= m_Iteration) )
2361 m_nFeatures = 0; m_pClasses = NULL; m_nClasses = 0;
2363 m_Threshold_Distance = 0.;
2364 m_Threshold_Angle = 0.;
2365 m_Threshold_Probability = 0.;
2366 m_Probability_Relative =
false;
2390 m_nFeatures = nFeatures;
2397 if( m_nClasses > 0 )
2399 for(
int i=0; i<m_nClasses; i++)
2401 delete(m_pClasses[i]);
2438 m_bWTA[Method] = bOn;
2458 int nFeatures = m_nFeatures;
Destroy(); m_nFeatures = nFeatures;
2468 if( !Data(
"classes") || !Data(
"features") || !Data[
"features"](
"count") || Data[
"features"][
"count"].Get_Content().asInt() != m_nFeatures || m_nFeatures == 0 )
2473 if( Data[
"features"](
"info") )
2483 if( Classes[i].Cmp_Name(
"class") && Classes[i].Get_Child(
"id") )
2487 CClass *pClass =
new CClass(Classes[i][
"id"].Get_Content());
2489 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; }
2490 if( !pClass->m_Mean.from_String(Classes[i][
"mean"].
Get_Content()) || pClass->m_Mean.Get_N () != m_nFeatures ) { bAdd =
false; }
2491 if( !pClass->m_Min .from_String(Classes[i][
"min" ].
Get_Content()) || pClass->m_Min .Get_N () != m_nFeatures ) { bAdd =
false; }
2492 if( !pClass->m_Max .from_String(Classes[i][
"max" ].
Get_Content()) || pClass->m_Max .Get_N () != m_nFeatures ) { bAdd =
false; }
2501 m_pClasses = (CClass **)
SG_Realloc(m_pClasses, ((
size_t)m_nClasses + 1) *
sizeof(CClass *));
2502 m_pClasses[m_nClasses++] = pClass;
2504 pClass->m_Cov_Det = pClass->m_Cov.Get_Determinant();
2505 pClass->m_Cov_Inv = pClass->m_Cov.Get_Inverse();
2512 return( m_nClasses > 0 );
2518 if( m_nFeatures < 1 || m_nClasses < 1 || File.
is_Empty() )
2525 Data.
Set_Name (
"supervised_classifier");
2530 Features.
Add_Child(
"count", m_nFeatures);
2532 if( Feature_Info && *Feature_Info )
2534 Features.
Add_Child(
"info", Feature_Info);
2541 for(
int i=0; i<m_nClasses; i++)
2545 CClass *pClass = m_pClasses[i];
2548 Class.
Add_Child(
"mean", pClass->m_Mean.to_String());
2549 Class.
Add_Child(
"min" , pClass->m_Min .to_String());
2550 Class.
Add_Child(
"max" , pClass->m_Max .to_String());
2551 Class.
Add_Child(
"cov" , pClass->m_Cov .to_String());
2554 return( Data.
Save(File) );
2567 if( m_nFeatures > 0 && m_nClasses > 0 )
2571 for(
int iClass=0; iClass<m_nClasses; iClass++)
2573 CClass *pClass = m_pClasses[iClass];
2575 s +=
"\n____\n" + pClass->m_ID +
"\nFeature\tMean\tMin\tMax\tStdDev";
2577 for(
int i=0; i<m_nFeatures; i++)
2601 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 )
2606 CClass *pClass, **pClasses = (CClass **)
SG_Realloc(m_pClasses, ((
size_t)m_nClasses + 1) *
sizeof(CClass *));
2610 m_pClasses = pClasses;
2612 m_pClasses[m_nClasses++] = pClass =
new CClass(Class_ID);
2614 pClass->m_ID = Class_ID;
2615 pClass->m_Mean = Mean;
2616 pClass->m_Min = Min;
2617 pClass->m_Max = Max;
2618 pClass->m_Cov = Cov;
2638 for(
int i=0; i<m_nClasses; i++)
2640 m_pClasses[i]->m_Samples.Destroy();
2649 if( m_nFeatures > 0 && m_nFeatures == Features.
Get_N() )
2655 CClass **pClasses = (CClass **)
SG_Realloc(m_pClasses, ((
size_t)m_nClasses + 1) *
sizeof(CClass *));
2659 m_pClasses = pClasses;
2661 m_pClasses[iClass = m_nClasses++] =
new CClass(Class_ID);
2667 return( m_pClasses[iClass]->m_Samples.Add_Row(Features) );
2677 if( m_nFeatures < 1 || m_nClasses < 1 )
2682 for(
int iClass=0; iClass<m_nClasses; iClass++)
2684 if( !m_pClasses[iClass]->
Train() )
2690 if( bClear_Samples )
2704 bool CSG_Classifier_Supervised::CClass::Train(
void)
2706 if( m_Samples.Get_NCols() < 1 || m_Samples.Get_NRows() < 1 )
2712 m_Mean.Create(m_Samples.Get_NCols());
2713 m_Min .Create(m_Samples.Get_NCols());
2714 m_Max .Create(m_Samples.Get_NCols());
2716 for(
int iFeature=0; iFeature<m_Samples.Get_NCols(); iFeature++)
2720 for(
int iSample=0; iSample<m_Samples.Get_NRows(); iSample++)
2722 s += m_Samples[iSample][iFeature];
2731 m_Cov.Create(m_Samples.Get_NCols(), m_Samples.Get_NCols());
2733 for(
int iFeature=0; iFeature<m_Samples.Get_NCols(); iFeature++)
2735 for(
int jFeature=iFeature; jFeature<m_Samples.Get_NCols(); jFeature++)
2739 for(
int iSample=0; iSample<m_Samples.Get_NRows(); iSample++)
2741 cov += (m_Samples[iSample][iFeature] - m_Mean[iFeature]) * (m_Samples[iSample][jFeature] - m_Mean[jFeature]);
2744 if( m_Samples.Get_NRows() > 1 )
2746 cov /= m_Samples.Get_NRows() - 1;
2749 m_Cov[iFeature][jFeature] = m_Cov[jFeature][iFeature] = cov;
2753 m_Cov_Inv = m_Cov.Get_Inverse ();
2754 m_Cov_Det = m_Cov.Get_Determinant();
2770 if( m_nFeatures > 0 )
2787 Class = -1; Quality = 0.;
2803 return( Class >= 0 );
2862 void CSG_Classifier_Supervised::_Get_Binary_Encoding(
const CSG_Vector &Features,
int &Class,
double &Quality)
2866 CClass *pClass = m_pClasses[iClass];
2874 d += (Features(iFeature) < Mean_Spectral) == (pClass->m_Mean[iFeature] < pClass->m_Mean_Spectral) ? 0 : 1;
2878 d += (Features[iFeature ] < Features[iFeature + 1]) == (pClass->m_Mean[iFeature ] < pClass->m_Mean[iFeature + 1]) ? 0 : 1;
2882 d += (Features[iFeature - 1] < Features[iFeature ]) == (pClass->m_Mean[iFeature - 1] < pClass->m_Mean[iFeature ]) ? 0 : 1;
2886 d += (Features[iFeature - 1] < Features[iFeature + 1]) == (pClass->m_Mean[iFeature - 1] < pClass->m_Mean[iFeature + 1]) ? 0 : 1;
2890 if( Class < 0 || Quality > d )
2892 Class = iClass; Quality = d;
2898 void CSG_Classifier_Supervised::_Get_Parallel_Epiped(
const CSG_Vector &Features,
int &Class,
double &Quality)
2902 CClass *pClass = m_pClasses[iClass];
2904 bool bMember =
true;
2908 bMember = pClass->m_Min[iFeature] <= Features[iFeature] && Features[iFeature] <= pClass->m_Max[iFeature];
2913 Class = iClass; Quality++;
2919 void CSG_Classifier_Supervised::_Get_Minimum_Distance(
const CSG_Vector &Features,
int &Class,
double &Quality)
2923 CClass *pClass = m_pClasses[iClass];
2925 double Distance = (Features - pClass->m_Mean).Get_Length();
2927 if( Class < 0 || Quality > Distance )
2929 Class = iClass; Quality = Distance;
2933 if( m_Threshold_Distance > 0. && Quality > m_Threshold_Distance )
2940 void CSG_Classifier_Supervised::_Get_Mahalanobis_Distance(
const CSG_Vector &Features,
int &Class,
double &Quality)
2944 CClass *pClass = m_pClasses[iClass];
2948 double Distance = D * (pClass->m_Cov_Inv * D);
2950 if( Class < 0 || Quality > Distance )
2952 Class = iClass; Quality = Distance;
2956 if( m_Threshold_Distance > 0. && Quality > m_Threshold_Distance )
2963 void CSG_Classifier_Supervised::_Get_Maximum_Likelihood(
const CSG_Vector &Features,
int &Class,
double &Quality)
2969 CClass *pClass = m_pClasses[iClass];
2973 double Distance = D * (pClass->m_Cov_Inv * D);
2975 double Probability = pow(2. *
M_PI, -0.5 * m_nFeatures) * pow(pClass->m_Cov_Det, -0.5) * exp(-0.5 * Distance);
2978 dSum += Probability;
2980 if( Class < 0 || Quality < Probability )
2982 Class = iClass; Quality = Probability;
2988 if( m_Probability_Relative )
2990 Quality = 100. * Quality / dSum;
2993 if( m_Threshold_Probability > 0. && Quality < m_Threshold_Probability )
3001 void CSG_Classifier_Supervised::_Get_Spectral_Angle_Mapping(
const CSG_Vector &Features,
int &Class,
double &Quality)
3005 CClass *pClass = m_pClasses[iClass];
3007 double Angle = Features.
Get_Angle(pClass->m_Mean);
3009 if( Class < 0 || Quality > Angle )
3011 Class = iClass; Quality = Angle;
3017 if( m_Threshold_Angle > 0. && Quality > m_Threshold_Angle )
3024 void CSG_Classifier_Supervised::_Get_Spectral_Divergence(
const CSG_Vector &Features,
int &Class,
double &Quality)
3029 void CSG_Classifier_Supervised::_Get_Winner_Takes_All(
const CSG_Vector &Features,
int &Class,
double &Quality)
3035 int iClass;
double iQuality;
3037 if( m_bWTA[iMethod] &&
Get_Class(Features, iClass, iQuality, iMethod) && ++Votes[iClass] > Quality )
3039 Class = iClass; Quality = Votes[iClass];
3062 if( !T || !df || df < 1. )
3075 if( p <= 0. || p >= 1. || df < 1 )
3081 double t, p0, p1, diff = 1.;
3085 while( fabs(diff) > 0.0001 )
3087 t = Get_T_Inv(p1, df);
3088 diff = Get_T_P(t, df) - p0;
3092 return( bNegative ? -t : t );
3125 const double a1 = 0.0000053830, a2 = 0.0000488906, a3 = 0.0000380036;
3126 const double a4 = 0.0032776263, a5 = 0.0211410061, a6 = 0.0498673470;
3130 double p = (((((a1 * z + a2) * z + a3) * z + a4) * z + a5) * z + a6) * z + 1.;
3132 return( pow(p, -16) );
3138 const double a0 = 2.5066282, a1 = -18.6150006, a2 = 41.3911977, a3 = -25.4410605;
3139 const double b1 = -8.4735109, b2 = 23.0833674, b3 = -21.0622410, b4 = 3.1308291;
3140 const double c0 = -2.7871893, c1 = -2.2979648, c2 = 4.8501413, c3 = 2.3212128;
3141 const double d1 = 3.5438892, d2 = 1.6370678;
3145 double r = sqrt(-log(0.5 - p));
3147 return( (((c3 * r + c2) * r + c1) * r + c0) / ((d2 * r + d1) * r + 1.) );
3153 return( p * (((a3 * r + a2) * r + a1) * r + a0) / ((((b4 * r + b3) * r + b2) * r + b1) * r + 1.) );
3158 double CSG_Test_Distribution::Get_T_P(
double T,
int df)
3160 return( df == 1 ? 1. - 2. * atan(fabs(T)) /
M_PI
3161 : df == 2 ? 1. - fabs(T) / sqrt(T*T + 2.)
3162 : df == 3 ? 1. - 2. * (atan(fabs(T) / sqrt(3.)) + fabs(T) * sqrt(3.) / (T*T + 3.)) /
M_PI
3163 : df == 4 ? 1. - fabs(T) * (1. + 2. / (T*T + 4.)) / sqrt(T*T + 4.)
3169 double CSG_Test_Distribution::Get_T_Z(
double T,
int df)
3173 double A9, B9, T9, Z8, P7, B7, z;
3180 : A9 * (((1. - T9 * 0.75) * T9 / 3. - 0.5) * T9 + 1.) * T9;
3181 P7 = ((0.4 * Z8 + 3.3) * Z8 + 24.) * Z8 + 85.5;
3182 B7 = 0.8 * pow(Z8, 2.) + 100. + B9;
3183 z = (1. + (-P7 / B7 + Z8 + 3.) / B9) * sqrt(Z8);
3189 double CSG_Test_Distribution::Get_T_Inv(
double p,
int df)
3195 return( cos(p *
M_PI / 2.) / sin(p *
M_PI / 2.) );
3200 return( sqrt(2. / (p * (2. - p)) - 2.) );
3203 double a = 1. / (df - 0.5);
3204 double b = 48. / (a*a);
3205 double c = ((20700. * a / b - 98.) * a - 16.) * a + 96.36;
3206 double d = ((94.5 / (b + c) - 3.) / b + 1.) * sqrt(a *
M_PI / 2.) * df;
3208 double y = pow(x, 2. / df);
3217 c = c + 0.3 * (df - 4.5) * (x + 0.6);
3220 c = (((0.05 * d * x - 5) * x - 7.) * x - 2.) * x + b + c;
3221 y = (((((0.4 * y + 6.3) * y + 36.) * y + 94.5) / c - y - 3.) / b + 1.) * x;
3235 y = ((1. / (((df + 6.) / (df * y) - 0.089 * d - 0.822) * (df + 2.) * 3.)
3236 + 0.5 / (df + 4.)) * y - 1.) * (df + 1.) / (df + 2.) + 1. / y;
3239 return( sqrt(df * y) );
3250 double F = ((
sLong)nSamples - (
sLong)nPredictors - 1) * (R2 / nPredictors) / (1. - R2);
3262 if( F >= 0.00001 && dfn > 0 && dfd > 0 )
3264 if( F * dfn >= dfd || F > 1. + 20. / dfn + 10. / sqrt((
double)dfn) )
3266 p = Get_Gamma(F, dfn, dfd);
3270 p = 1. - Get_Gamma(1. / F, dfd, dfn);
3274 if( p <= 0. || p >= 1. )
3276 p = F > 1. ? 0. : F < 1. ? 1. : 0.5;
3285 if( alpha < 0. || alpha > 1. || dfd < 0 || dfn < 0 )
3295 const int ITERMAX = 100;
3296 const double EPSILON = 0.0001;
3299 double lo, hi, mid, p;
3306 for(i=0; i<ITERMAX; i++)
3331 for(i=0; i<ITERMAX; i++)
3352 mid = (hi + lo) / 2.;
3354 for(i=0; i<ITERMAX && (hi-lo)>
EPSILON*mid; i++)
3356 mid = (hi + lo) / 2.;
3361 else if( p > alpha )
3371 double CSG_Test_Distribution::Get_Gamma(
double F,
double dfn,
double dfd)
3375 const double EXPMIN = -30.;
3376 const double SMALL = 0.00000000001;
3378 double x, c, er, s, n, t1, t;
3383 x = dfd / (dfd + dfn * F);
3384 c = Get_Log_Gamma(dfn + dfd) - Get_Log_Gamma(dfn) - Get_Log_Gamma(dfd + 1.) + dfd * log(x) + dfn * log(1. - x);
3400 while( t > er || t > t1 )
3404 t *= ((dfn + n) * x / (dfd + n));
3412 double CSG_Test_Distribution::Get_Log_Gamma(
double a)
3416 const int ARGMIN = 6;
3418 const double HL2PI = 0.91893853320467275;
3420 int n = (int)floor(ARGMIN - a + 0.0001);
3430 g = (1. - g * (1. / 30. - g * (1. / 105. - g * (1. / 140. - g / 99.)))) / (12. * a);
3431 g = g + ((a - 0.5) * log(a) - a + HL2PI);
3433 for(
int i=0; i<n; i++)
3452 int nVariables = Values.
Get_NX();
3453 int nSamples = Values.
Get_NY();
3460 C.Create(nVariables, nVariables);
3465 for(j=0; j<nVariables; j++)
3467 for(i=0; i<nSamples; i++)
3469 S[j] += Values[i][j];
3474 for(k=0; k<nVariables; k++)
3476 for(j=k; j<nVariables; j++)
3480 for(i=0; i<nSamples; i++)
3482 cov += (Values[i][j] - S[j].
Get_Mean()) * (Values[i][k] - S[k].Get_Mean());
3492 C[j][k] =
C[k][j] = cov;