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(_SPHCLUS_H)
00033 #define _SPHCLUS_H
00034
00035 #include "general.h"
00036 #include "cluster.h"
00037 #include "vec.h"
00038 #include "exceptions.h"
00039 #include "extravec.h"
00040
00041 namespace CLUS
00042 {
00043
00044
00045
00046 class SphericCluster: public Cluster
00047 {
00048
00049 protected:
00050
00051 double s_Ai;
00052
00053
00054 Vector<double> s_Ai_Xj;
00055
00056 Vector<double> L;
00057
00058 public:
00059 SphericCluster():Cluster(),s_Ai(0.0),s_Ai_Xj(),L()
00060 {}
00061
00062 SphericCluster(int InDim, int OutDim)
00063 :Cluster(InDim, OutDim), s_Ai(0.0), s_Ai_Xj(InDim+OutDim),
00064 L(InDim+OutDim)
00065 {}
00066
00067 SphericCluster(int InDim, int OutDim, int):
00068 Cluster(InDim, OutDim), s_Ai_Xj(0), L(InDim+OutDim)
00069 {}
00070
00071 void CopyFrom(SphericCluster& aux)
00072 {
00073 weight=aux.weight;
00074 dimension=aux.dimension;
00075 L=aux.L;
00076 state=aux.state;
00077 }
00078
00079 void RandomCluster(void)
00080 {
00081 int i;
00082 for(i=0;i<inDim;i++)
00083 {
00084 L[i]=RANDOM01FLOAT*2-1;
00085 }
00086 for(i=inDim;i<inDim+outDim;i++)
00087 {
00088 L[i]=-0.4+0.8*RANDOM01FLOAT;
00089 }
00090 }
00091
00092 void InitializeOnPoint(const double* point)
00093 {
00094
00095
00096 for(int i=0; i<inDim+outDim; i++)
00097 L[i]=point[i]+RANDOM01FLOAT*1.0e-5;
00098 }
00099
00100 inline double InferDistance(const double* InputData)
00101 {
00102 dataCache=InputData;
00103 distanceInfer=0;
00104 for(int i=0;i<inDim;i++)
00105 distanceInfer+=pow2(dataCache[i]-L[i]);
00106 distanceInfer*=weight;
00107 if (distanceInfer==0.0)
00108 distanceInfer=10e-300;
00109 return distanceInfer;
00110 }
00111
00112 inline double ClusDistance(const double* TrainData)
00113 {
00114 distanceClus=0;
00115 dataCache=TrainData;
00116 int i;
00117 for(i=0;i<inDim;i++)
00118 distanceClus+=pow2(dataCache[i]-L[i]);
00119 distanceInfer=distanceClus*weight;
00120 for(i=inDim;i<inDim+outDim;i++)
00121 distanceClus+=pow2(dataCache[i]-L[i]);
00122 distanceClus*=weight;
00123 if (distanceClus==0.0)
00124 distanceClus=10e-300;
00125 return distanceClus;
00126 }
00127
00128 inline void HBeginIdentif(void)
00129 {
00130 dimension=0.0;
00131 }
00132
00133 inline double CorrectAppartGrade(double Coef)
00134 {
00135 double Ai=1/(distanceClus*Coef);
00136 double Ai2=pow2(Ai);
00137 s_Ai+=Ai2;
00138 for(int i=0;i<inDim+outDim;i++)
00139 s_Ai_Xj[i]+=Ai2*dataCache[i];
00140 return Ai2*distanceClus;
00141
00142 }
00143
00144 inline double HCorrectAppartGrade(double Coef)
00145 {
00146 double ret=CorrectAppartGrade(Coef);
00147 dimension+=ret;
00148 return ret;
00149 }
00150
00151 inline double AdjustPrototypes(void)
00152 {
00153 double oldX, distP=0.0;
00154 for(int i=0;i<inDim+outDim;i++)
00155 {
00156 oldX=L[i];
00157 L[i]=s_Ai_Xj[i]/s_Ai;
00158 s_Ai_Xj[i]=0.0;
00159 distP+=pow2(oldX-L[i]);
00160 }
00161
00162 s_Ai=0.0;
00163 return sqrt(distP)/(inDim+outDim);
00164 }
00165
00166 inline double HAdjustPrototypes(void)
00167 {
00168 dimension/=s_Ai;
00169
00170 cerr << dimension << endl;
00171
00172 return AdjustPrototypes();
00173 }
00174
00175 inline void AdjustYwithYoverD(Vector<double>& Y)
00176 {
00177 for(int i=0; i<outDim; i++)
00178 Y[i]+=L[i+inDim]/distanceInfer;
00179 }
00180
00181 inline void AdjustYwithYoverD(Vector<double>& Y, double dist)
00182 {
00183 for(int i=0; i<outDim; i++)
00184 Y[i]+=L[i+inDim]/dist;
00185 }
00186
00187 double ComputeLastY(void)
00188 {
00189 return L[inDim+outDim-1];
00190 }
00191
00192 static string TypeName(void)
00193 {
00194 return string("SphericCluster");
00195 }
00196
00197 void SaveToStream(ostream& out)
00198 {
00199
00200 out << "[ ";
00201 for(int i=0; i<inDim+outDim; i++)
00202 out << L[i] << " ";
00203 out << " ] { " ;
00204 out << weight << " }" << endl;
00205 }
00206
00207 void LoadFromStream(istream& in)
00208 {
00209 string s;
00210 in >> s;
00211 if (s != "[")
00212 throw ErrMsg("[ missing in sphericcluster");
00213 for(int i=0; i<inDim+outDim; i++)
00214 in >> L[i];
00215 in >> s;
00216 if (s != "]")
00217 throw ErrMsg("] missing in sphericcluster");
00218 in >> s;
00219 if (s!="{")
00220 throw ErrMsg("{ missing in sphericcluster");
00221 in >> weight;
00222 in >> s;
00223 if (s!="}")
00224 throw ErrMsg("} missing in sphericcluster");
00225
00226 }
00227
00228 bool Split(SphericCluster& right, SphericCluster& save, double minDim)
00229 {
00230 if (state==Final)
00231 return false;
00232 if (state==Dead)
00233 throw ErrMsg("Attempt to split a dead cluster");
00234 if (state==Splited)
00235 throw ErrMsg("Attempt to split a splited cluster");
00236
00237 if (dimension <=minDim)
00238 return false;
00239
00240
00241 save.weight=weight;
00242 save.state=Splited;
00243 save.L=L;
00244 save.dimension=dimension;
00245
00246 state=right.state=Splitable;
00247 weight=right.weight=weight/2;
00248
00249 Vector<double> delta(L.dim());
00250 GenerateRandomVector2(delta);
00251 SetNormTo(delta,dimension);
00252
00253
00254
00255 right.L=L+delta;
00256 Dif(L,L.dim(),delta);
00257 dimension=right.dimension=0.0;
00258
00259 return true;
00260 }
00261
00262 bool CheckSplit(SphericCluster& left, SphericCluster& right, double splitCrit)
00263 {
00264
00265 cerr << dimension << " : " << left.dimension << " " << right.dimension << endl;
00266
00267 if (dimension*splitCrit > left.dimension + right.dimension)
00268 {
00269
00270 return true;
00271 }
00272 else
00273 {
00274
00275 right.state=Dead;
00276
00277 left.weight=weight;
00278 left.state=Final;
00279 left.L=L;
00280 left.dimension=0.0;
00281
00282 return false;
00283 }
00284 }
00285 };
00286 }
00287
00288 #endif