• Main Page
  • Related Pages
  • Classes
  • Files
  • Examples
  • File List
  • File Members

LinearModel.cpp

Go to the documentation of this file.
00001 //===========================================================================
00047 //===========================================================================
00048 
00049 
00050 #include <math.h>
00051 #include <SharkDefs.h>
00052 #include <LinAlg/LinAlg.h>
00053 #include <ReClaM/LinearModel.h>
00054 
00055 
00056 LinearMap::LinearMap(int inputdim, int outputdim)
00057 {
00058     inputDimension = inputdim;
00059     outputDimension = outputdim;
00060 
00061     parameter.resize(inputdim * outputdim, false);
00062     parameter = 0.0;
00063 }
00064 
00065 LinearMap::~LinearMap()
00066 {
00067 }
00068 
00069 
00070 void LinearMap::model(const Array<double>& input, Array<double> &output)
00071 {
00072     if (input.ndim() == 1)
00073     {
00074         unsigned int i, o;
00075         double value;
00076         output.resize(outputDimension, false);
00077         int p = 0;
00078         for (o = 0; o < outputDimension; o++)
00079         {
00080             value = 0.0;
00081             for (i = 0; i < inputDimension; i++)
00082             {
00083                 value += input(i) * parameter(p);
00084                 p++;
00085             }
00086             output(o) = value;
00087         }
00088     }
00089     else if (input.ndim() == 2)
00090     {
00091         unsigned int j, jc = input.dim(0);
00092         unsigned int i, o;
00093         double value;
00094         output.resize(jc, outputDimension, false);
00095         for (j = 0; j < jc; j++)
00096         {
00097             int p = 0;
00098             for (o = 0; o < outputDimension; o++)
00099             {
00100                 value = 0.0;
00101                 for (i = 0; i < inputDimension; i++)
00102                 {
00103                     value += input(j, i) * parameter(p);
00104                     p++;
00105                 }
00106                 output(j, o) = value;
00107             }
00108         }
00109     }
00110     else throw SHARKEXCEPTION("[LinearMap::model] invalid number of dimensions.");
00111 }
00112 
00113 void LinearMap::modelDerivative(const Array<double>& input, Array<double>& derivative)
00114 {
00115     if (input.ndim() == 1)
00116     {
00117         unsigned int o, p, pc = getParameterDimension();
00118         derivative.resize(outputDimension, pc, false);
00119         for (o = 0; o < outputDimension; o++)
00120         {
00121             for (p = 0; p < pc; p++)
00122             {
00123                 derivative(o, p) = input(p);
00124             }
00125         }
00126     }
00127     else throw SHARKEXCEPTION("[LinearMap::modelDerivative] invalid number of dimensions.");
00128 }
00129 
00130 
00132 
00133 
00134 AffineLinearMap::AffineLinearMap(int inputdim, int outputdim)
00135 {
00136     inputDimension = inputdim;
00137     outputDimension = outputdim;
00138 
00139     parameter.resize(inputdim * outputdim + outputdim, false);
00140     parameter = 0.0;
00141 }
00142 
00143 AffineLinearMap::~AffineLinearMap()
00144 {
00145 }
00146 
00147 
00148 void AffineLinearMap::model(const Array<double>& input, Array<double> &output)
00149 {
00150     int pb = inputDimension * outputDimension;
00151 
00152     if (input.ndim() == 1)
00153     {
00154         unsigned int i, o;
00155         double value;
00156         output.resize(outputDimension, false);
00157         int p = 0;
00158         for (o = 0; o < outputDimension; o++)
00159         {
00160             value = parameter(pb + o);
00161             for (i = 0; i < inputDimension; i++)
00162             {
00163                 value += input(i) * parameter(p);
00164                 p++;
00165             }
00166             output(o) = value;
00167         }
00168     }
00169     else if (input.ndim() == 2)
00170     {
00171         unsigned int j, jc = input.dim(0);
00172         unsigned int i, o;
00173         double value;
00174         output.resize(jc, outputDimension, false);
00175         for (j = 0; j < jc; j++)
00176         {
00177             int p = 0;
00178             for (o = 0; o < outputDimension; o++)
00179             {
00180                 value = parameter(pb + o);
00181                 for (i = 0; i < inputDimension; i++)
00182                 {
00183                     value += input(j, i) * parameter(p);
00184                     p++;
00185                 }
00186                 output(j, o) = value;
00187             }
00188         }
00189     }
00190     else throw SHARKEXCEPTION("[AffineLinearMap::model] invalid number of dimensions.");
00191 }
00192 
00193 void AffineLinearMap::modelDerivative(const Array<double>& input, Array<double>& derivative)
00194 {
00195     if (input.ndim() == 1)
00196     {
00197         unsigned int o, p, pc = getParameterDimension();
00198         derivative.resize(outputDimension, pc, false);
00199         for (o = 0; o < outputDimension; o++)
00200         {
00201             for (p = 0; p < pc; p++)
00202             {
00203                 derivative(o, p) = input(p);
00204             }
00205         }
00206     }
00207     else throw SHARKEXCEPTION("[AffineLinearMap::modelDerivative] invalid number of dimensions.");
00208 }
00209 
00210 
00212 
00213 
00214 LinearFunction::LinearFunction(int dimension)
00215 : LinearMap(dimension, 1)
00216 {
00217 }
00218 
00219 
00221 
00222 
00223 AffineLinearFunction::AffineLinearFunction(int dimension)
00224 : AffineLinearMap(dimension, 1)
00225 {
00226 }
00227 
00228 
00230 
00231 
00232 LinearClassifier::LinearClassifier(int dimension, int classes)
00233 {
00234     inputDimension = dimension;
00235     outputDimension = classes;
00236     numberOfClasses = classes;
00237 
00238     // parameters are class mean vectors and global covariance matrix
00239     mean.resize(classes, dimension, false);
00240     covariance.resize(dimension, dimension, false);
00241     inverse.resize(dimension, dimension, false);
00242     parameter.resize(dimension * classes + dimension * (dimension+1) / 2, false);
00243     mean = 0.0;
00244     covariance = 0.0;
00245     inverse = 0.0;
00246     parameter = 0.0;
00247 
00248     bNeedsUpdate = true;
00249 }
00250 
00251 LinearClassifier::~LinearClassifier()
00252 {
00253 }
00254 
00255 
00256 void LinearClassifier::setParameter(unsigned int index, double value)
00257 {
00258     Model::setParameter(index, value);
00259 
00260     if (index < numberOfClasses * inputDimension)
00261     {
00262         // mean vector component
00263         int cls = index / inputDimension;
00264         int dim = index % inputDimension;
00265         mean(cls, dim) = value;
00266     }
00267     else
00268     {
00269         // symmetric matrix component
00270         index -= numberOfClasses * inputDimension;
00271         int y = (int)floor(sqrt(2.0*index + 0.25) - 0.5);
00272         int x = index - y*(y+1)/2;
00273         covariance(x, y) = covariance(y, x) = value;
00274         bNeedsUpdate = true;
00275     }
00276 }
00277 
00278 void LinearClassifier::model(const Array<double>& input, Array<double>& output)
00279 {
00280     if (bNeedsUpdate)
00281     {
00282         invertSymm(inverse, covariance);
00283         bNeedsUpdate = false;
00284     }
00285 
00286     Array<double> diff(inputDimension);
00287 
00288     if (input.ndim() == 1)
00289     {
00290         output.resize(numberOfClasses, false);
00291         output = 0.0;
00292         int c, d;
00293         int best = 0;
00294         double dist2, bestDist = MAXDOUBLE;
00295         for (c=0; c<numberOfClasses; c++)
00296         {
00297             for (d=0; d<(int)inputDimension; d++) diff(d) = input(d) - mean(c, d);
00298             dist2 = vecMatVec(diff, inverse, diff);
00299             if (dist2 < bestDist)
00300             {
00301                 bestDist = dist2;
00302                 best = c;
00303             }
00304         }
00305         output(best) = 1.0;
00306     }
00307     else if (input.ndim() == 2)
00308     {
00309         int i, ic = input.dim(0);
00310         output.resize(ic, numberOfClasses, false);
00311         output = 0.0;
00312         for (i=0; i<ic; i++)
00313         {
00314             int c, d;
00315             int best = 0;
00316             double dist2, bestDist = MAXDOUBLE;
00317             for (c=0; c<numberOfClasses; c++)
00318             {
00319                 for (d=0; d<(int)inputDimension; d++) diff(d) = input(i, d) - mean(c, d);
00320                 dist2 = vecMatVec(diff, inverse, diff);
00321                 if (dist2 < bestDist)
00322                 {
00323                     bestDist = dist2;
00324                     best = c;
00325                 }
00326             }
00327             output(i, best) = 1.0;
00328         }
00329     }
00330     else throw SHARKEXCEPTION("[LinearClassifier::model] invalid number of dimensions.");
00331 }
  • Shark Main Page
  • Array
  • Rng
  • LinAlg
  • FileUtil
  • EALib
  • MOO-EALib
  • ReClaM
  • Fuzzy
  • Mixture
  • Tutorials
  • FAQ