Main Page | Namespace List | Class Hierarchy | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

sphclus.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (c) 2003, Cornell University
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions are met:
00008 
00009    - Redistributions of source code must retain the above copyright notice,
00010        this list of conditions and the following disclaimer.
00011    - Redistributions in binary form must reproduce the above copyright
00012        notice, this list of conditions and the following disclaimer in the
00013        documentation and/or other materials provided with the distribution.
00014    - Neither the name of Cornell University nor the names of its
00015        contributors may be used to endorse or promote products derived from
00016        this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00022 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00028 THE POSSIBILITY OF SUCH DAMAGE.
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 /**    Class that describes Spheric Clusters
00045  */    
00046 class SphericCluster:    public Cluster
00047 {
00048 
00049 protected:
00050     /// the sum of Ai(Xj)^2
00051     double              s_Ai;
00052 
00053     /// the sum of Ai(Xj)^2*Xj
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         // we add a small random value to avoid problems if two clusters
00095         // are initialy in the same point
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;/* added with 10e-16 to avoid 0.0 distances */
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         // all we need to save is L, no marker between in and out is necesarry
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         // save *this in save
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; // splited clusters are two times smaller
00248 
00249         Vector<double> delta(L.dim());
00250         GenerateRandomVector2(delta);
00251         SetNormTo(delta,dimension);
00252 
00253         // this cluster is the left cluster
00254         // first the right cluster
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             // we have a good split
00270             return true;
00271         }
00272         else
00273         {
00274             // we have a bad split
00275             right.state=Dead;
00276             // copy back original version
00277             left.weight=weight;
00278             left.state=Final; // we dont split this anymore
00279             left.L=L;
00280             left.dimension=0.0;
00281 
00282             return false;
00283         }
00284     }
00285 };
00286 }
00287 
00288 #endif    /* _SPHCLUS_H */

Generated on Mon Jul 21 16:57:25 2003 for SECRET by doxygen 1.3.2