00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #if !defined(_HIPCLUS_H)
00033 #define _HIPCLUS_H
00034
00035 #include "general.h"
00036 #include "vec.h"
00037 #include "extravec.h"
00038 #include "fmat.h"
00039 #include "sphclus.h"
00040 #include "misc.h"
00041 #include "math.h"
00042 #include "exceptions.h"
00043 #include <iostream>
00044 #include <string>
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 namespace CLUS
00060 {
00061 using namespace TNT;
00062
00063
00064 class HiperPlanCluster:public SphericCluster
00065 {
00066 protected:
00067
00068
00069 Vector<double> C,u;
00070
00071
00072 Fortran_Matrix<double> S;
00073 double Elipsoidality, error, slimness;
00074
00075 void ComputeCCoef(void)
00076 {
00077
00078 double uy=u[inDim];
00079 C[0]=L[inDim];
00080
00081 for(int j=0;j<inDim;j++)
00082 {
00083 C[j+1]=-u[j]/uy;
00084 C[0]+=L[j]*u[j]/uy;
00085 }
00086 }
00087
00088 void ComputeU(void)
00089 {
00090 u[inDim]=1.0;
00091 L[inDim]=C[0];
00092 for(int j=0; j<inDim; j++)
00093 {
00094 u[j]=-C[j+1];
00095 L[inDim]+=C[j+1]*L[j];
00096 }
00097 Normalize(u);
00098 }
00099
00100 public:
00101 HiperPlanCluster():SphericCluster(),C(),u(),S()
00102 {
00103 Elipsoidality=0.8;
00104 error=0.0;
00105 }
00106
00107 HiperPlanCluster(int InDim, int OutDim):SphericCluster(InDim,OutDim),C(InDim+OutDim),
00108 u(InDim+OutDim),S(InDim+OutDim,InDim+OutDim)
00109 {
00110 if (OutDim!=1)
00111 throw ErrMsg("Instances of HiperPlanClusters cannot have more than one output");
00112
00113 Elipsoidality=0.8;
00114 error=0.0;
00115 }
00116
00117 HiperPlanCluster(int InDim, int OutDim, int):SphericCluster(InDim,OutDim,0),C(0),
00118 u(InDim+OutDim),S(0,0)
00119 {
00120 if (OutDim!=1)
00121 throw ErrMsg("Instances of HiperPlanClusters cannot have more than one output");
00122 Elipsoidality=0.8;
00123 error=0.0;
00124 }
00125
00126 void CopyFrom(HiperPlanCluster& aux)
00127 {
00128 weight=aux.weight;
00129 dimension=aux.dimension;
00130 L=aux.L;
00131 u=aux.u;
00132 error=aux.error;
00133 state=aux.state;
00134 Elipsoidality=aux.Elipsoidality;
00135 }
00136
00137 void RandomCluster(void)
00138 {
00139 SphericCluster::RandomCluster();
00140 ZeroUp(u);
00141 u[inDim]=1.0;
00142 ComputeCCoef();
00143 }
00144
00145 void InitializeOnPoint(const double* point)
00146 {
00147 SphericCluster::InitializeOnPoint(point);
00148 ZeroUp(u);
00149 u[inDim]=1.0;
00150 ComputeCCoef();
00151 }
00152
00153 inline double InferDistance(const double* DataCache)
00154 {
00155
00156 double daux=0;
00157 dataCache=DataCache;
00158 distanceInfer=0.0;
00159
00160 for(int i=0;i<inDim;i++)
00161 {
00162 register double dif=dataCache[i]-L[i];
00163 distanceInfer+=pow2(dif);
00164 daux+=C[i+1]*dif;
00165 }
00166
00167 distanceInfer+=pow2(daux);
00168
00169
00170 distanceInfer=(1-Elipsoidality)*distanceInfer+Elipsoidality*error;
00171 distanceInfer*=weight;
00172
00173 if (distanceInfer==0.0)
00174 distanceInfer=10e-300;
00175
00176 return distanceInfer;
00177 }
00178
00179 inline double ClusDistance(const double* DataCache)
00180 {
00181 distanceClus=SphericCluster::ClusDistance(DataCache)*(1-Elipsoidality);
00182 double dplan=0.0;
00183
00184 for(int j=0;j<inDim+1;j++)
00185 dplan+=u[j]*(dataCache[j]-L[j]);
00186
00187 distanceClus+=Elipsoidality*pow2(dplan);
00188
00189
00190 return distanceClus;
00191 }
00192
00193
00194
00195
00196 double CorrectAppartGrade(double Coef)
00197 {
00198
00199
00200 double Ai;
00201 if (!finite(Coef))
00202 Ai=1.0;
00203 else
00204 Ai=1/(distanceClus*Coef);
00205
00206 double Ai2=pow2(Ai);
00207
00208 assert(finite(Ai) || finite(Ai2));
00209
00210 s_Ai+=Ai2;
00211 for (int i=0;i<inDim+1;i++)
00212 {
00213 double aux=Ai2*dataCache[i];
00214 s_Ai_Xj[i]+=aux;
00215
00216 for(int j=i; j<inDim+1; j++)
00217 S(i+1,j+1)+=aux*dataCache[j];
00218 }
00219
00220 return distanceClus*Ai2;
00221 }
00222
00223 inline double HCorrectAppartGrade(double Coef)
00224 {
00225 double ret=CorrectAppartGrade(Coef);
00226 dimension+=ret;
00227 return ret;
00228 }
00229
00230 double AdjustPrototypes(void)
00231 {
00232 double oldX, distP=0.0;
00233 for(int i=0;i<inDim+1;i++)
00234 {
00235 oldX=L[i];
00236
00237 double aux=s_Ai_Xj[i]/s_Ai;
00238 L[i]=aux;
00239 for(int j=i; j<inDim+1; j++)
00240 S(i+1,j+1)-=aux*s_Ai_Xj[j];
00241 s_Ai_Xj[i]=0.0;
00242 distP+=pow2(oldX-L[i]);
00243 }
00244
00245
00246 double lambda,lambda2;
00247
00248 if (MinEigenvalueUpperSymmetric(S,lambda,lambda2,slimness))
00249 {
00250 if (EigenVector(S,lambda,u))
00251 error=lambda/s_Ai;
00252 else
00253 cerr << "OOPS could not find the eigenvector for " << lambda << endl;
00254 slimness/=lambda;
00255 }
00256 else
00257 cerr << "OOPS-eigenvalue problem not solved in " << TypeName() << endl;
00258
00259 ZeroUp(S);
00260 s_Ai=0.0;
00261 ComputeCCoef();
00262
00263 return sqrt(distP)/(inDim+1);
00264 }
00265
00266 inline double HAdjustPrototypes(void)
00267 {
00268 dimension/=s_Ai;
00269 return AdjustPrototypes();
00270 }
00271
00272 void AdjustYwithYoverD(Vector<double>& Y)
00273 {
00274 double y=C[0];
00275
00276 for(int j=0; j<inDim; j++)
00277 y+=C[j+1]*dataCache[j];
00278
00279 Y[0]+=y/distanceInfer;
00280 }
00281
00282 void AdjustYwithYoverD(Vector<double>& Y, double dist)
00283 {
00284 double y=C[0];
00285
00286 for(int j=0; j<inDim; j++)
00287 y+=C[j+1]*dataCache[j];
00288
00289 Y[0]+=y/dist;
00290 }
00291
00292 double ComputeLastY(void)
00293 {
00294 double y=C[0];
00295
00296 for(int j=0; j<inDim; j++)
00297 y+=C[j+1]*dataCache[j];
00298
00299 return y;
00300 }
00301
00302 static string TypeName(void)
00303 {
00304 return string("HiperPlanCluster");
00305 }
00306
00307 void SaveToStream(ostream& out)
00308 {
00309 ComputeCCoef();
00310
00311 out << "[ ";
00312
00313 for(int i=0; i<inDim; i++)
00314 out << L[i] << " ";
00315 out << " ] ( ";
00316
00317 for(int i=0; i<inDim+1; i++)
00318 out << C[i] << " ";
00319 out << " ) { " << Elipsoidality << " " << error
00320 << " " << weight << " } " << endl;
00321 }
00322
00323 void LoadFromStream(istream& in)
00324 {
00325 string s;
00326
00327 in >> s;
00328 if (s!="[")
00329 throw ErrMsg("[ missing in hypercluster");
00330 for(int i=0; i<inDim; i++)
00331 in >> L[i];
00332 in >> s;
00333 if (s!="]")
00334 throw ErrMsg("] missing in hypercluster");
00335 in >> s;
00336 if (s!="(")
00337 throw ErrMsg("( missing in hypercluster");
00338 for(int i=0; i<inDim+1; i++)
00339 in >> C[i];
00340 in >> s;
00341 if (s!=")")
00342 throw ErrMsg(") missing hypercluster");
00343 in >> s;
00344 if (s!="{")
00345 throw ErrMsg("{ missing in hypercluster");
00346 in >> Elipsoidality;
00347 in >> error;
00348 in >> weight;
00349 in >> s;
00350 if (s!="}")
00351 throw ErrMsg("} missing in hypercluster");
00352 ComputeU();
00353 }
00354
00355 void SetElipsoidality(double val)
00356 {
00357 Elipsoidality=val;
00358 }
00359
00360 bool SetOptionDbl(char* optName,double value)
00361 {
00362 if ( strcmp(optName,"elipsoidality")==0 )
00363 {
00364 Elipsoidality=value;
00365 return true;
00366 }
00367
00368 return SphericCluster::SetOptionDbl(optName,value);
00369 }
00370
00371 bool Split(HiperPlanCluster& right, HiperPlanCluster& save, double minDim)
00372 {
00373 if (state==Final)
00374 return false;
00375 if (state==Dead)
00376 throw ErrMsg("Attempt to split a dead cluster");
00377 if (state==Splited)
00378 throw ErrMsg("Attempt to split a splited cluster");
00379
00380 cerr << "Slimness=" << slimness << endl;
00381
00382 if (slimness <=minDim )
00383 return false;
00384
00385
00386 save.weight=weight;
00387 save.state=Splited;
00388 save.L=L;
00389
00390 right.u=save.u=u;
00391 save.error=error;
00392 save.dimension=dimension;
00393 right.Elipsoidality=save.Elipsoidality=Elipsoidality;
00394
00395 state=right.state=Splitable;
00396 weight=right.weight=weight/2;
00397
00398 Vector<double> delta(L.dim());
00399 GenerateRandomVector2(delta);
00400
00401 double y=0.0;
00402 for(int j=0; j<inDim; j++)
00403 y+=u[j]*delta[j];
00404 delta[inDim]=-y/u[inDim];
00405
00406 SetNormTo(delta,dimension);
00407
00408
00409
00410 right.L=L+delta;
00411 Dif(L,L.dim(),delta);
00412
00413 ComputeCCoef();
00414 right.ComputeCCoef();
00415
00416 dimension=right.dimension=0.0;
00417
00418 return true;
00419 }
00420
00421 bool CheckSplit(HiperPlanCluster& left, HiperPlanCluster& right, double splitCrit)
00422 {
00423 if (error*splitCrit > left.error + right.error)
00424 {
00425
00426 return true;
00427 }
00428 else
00429 {
00430
00431 right.state=Dead;
00432
00433 left.weight=weight;
00434 left.state=Final;
00435 left.L=L;
00436 left.u=u;
00437 left.error=error;
00438 left.Elipsoidality=Elipsoidality;
00439 left.dimension=0.0;
00440 left.ComputeCCoef();
00441
00442 return false;
00443 }
00444 }
00445 };
00446 }
00447
00448
00449 #endif