Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

neuralregion.h

Go to the documentation of this file.
00001 
00007 #ifndef __NEURALREGION_H__
00008 #define __NEURALREGION_H__
00009 
00010 #include <utility>
00011 #include <string>
00012 using std::string;
00013 
00014 #include "matrix.h"
00015 #include "generic_stdlib.h"
00016 #include "matrixadapter.h"
00017 #include "boundingbox.h"
00018 #include "weightset.h"
00019 #include "bounded.h"
00020 #include "pointermap.h"
00021 #include "sequencetransform.h"
00022 
00023 
00024 
00028 class NeuralRegion : public HasTable<mat::MatrixInterface<Bounded::Magnitude> > {
00029 public:
00032 
00037   typedef Bounded::Magnitude Magnitude;
00038 
00040   typedef Magnitude Activity;
00041 
00043   typedef double Length;
00044 
00051   typedef MatrixType<Activity>::rectangular ActivityMatrix;
00052 
00054   typedef ActivityMatrix::size_type Subscript;
00055 
00057   typedef std::pair<Subscript,Subscript> SubscriptPair;
00058 
00060   typedef mat::MatrixInterface<Magnitude> MapBaseType;
00061 
00064   typedef mat::MatrixInterfaceAdapter<ActivityMatrix,Magnitude> ActivityAdapter;
00065   
00067   typedef Boundary::AARBoundingBox<int,int> Bounds;
00068 
00070   typedef SequenceTransform::OneD<ActivityMatrix,ActivityMatrix> ActivationFunction;
00071 
00076   struct Dimensions {
00077     Dimensions(Subscript h, Subscript w, Length xo=0.5, Length yo=0.5)
00078       : height(h), width(w), xoffset(xo), yoffset(yo) {  }
00079     Subscript height;   
00080     Subscript width;    
00081     Length    xoffset;  
00082     Length    yoffset;  
00083   };
00085 
00088   NeuralRegion(string name_i, Dimensions dims)
00089     : HasTable<mat::MatrixInterface<Bounded::Magnitude> >(),
00090       name_str(name_i), output(dims.height,dims.width), 
00091       bp(dims.height,dims.width),
00092       residual(dims.height,dims.width) { }
00093   
00094   NeuralRegion(const NeuralRegion& other) 
00095     : HasTable<mat::MatrixInterface<Bounded::Magnitude> >(),
00096       name_str(other.name_str), output(other.output), 
00097       bp(other.bp), residual(other.residual) { }
00098   
00099   virtual ~NeuralRegion() { }
00101   
00102 
00104   virtual void activate(bool learn=false, bool settle=true, bool activatefn=true) =0; 
00105 
00106   
00109   
00110   /*   activity(Subscript i, Subscript j) may need to be made non-virtual for speed.  */
00112   virtual Activity activity(Subscript i, Subscript j) const {  return output[i][j];  }
00115   virtual const ActivityMatrix& const_activity() const      {  return output;        }
00116 
00117   virtual const ActivityMatrix& backprojection() const      {  return bp;    }
00118 
00119   virtual const ActivityMatrix& residual_activity() const      {  return residual;    }
00120 
00121   //  virtual ActivityMatrix& activity()                        {  return output;        }
00122 
00124 
00126   const string& name() const {  return name_str;  }
00127 
00128   const int nrows() const {  return int(output.nrows());  }
00129   const int ncols() const {  return int(output.ncols());  }
00130 
00134   virtual bool is_internal() const  {  return false;  }
00135   
00139   virtual bool is_plastic() const  {  return true;  }
00140 
00149   virtual void save_state(const string&) { }
00150   
00157   virtual bool restore_state(const int, const string&) {  return true;  } 
00158 
00162   virtual void prune() {  }
00163   
00167   virtual double size_connection_bytes()   const=0;
00168   
00173   virtual double size_unique_connections() const=0;
00174 
00175   /* Backproject current activity. Must be implemented by derived classes. yschoe 
00176   virtual void backproject() = 0;
00177   */
00178 
00179 private:
00180   const string name_str;
00181 
00184 public:
00186   Bounds bounds() const {  return Bounds(0,0,output.ncols()-1,output.nrows()-1);  }
00188 
00189 // yschoe: make this temporarily public; was protected:
00190 public:
00192   ActivityMatrix output;
00193   ActivityMatrix bp;
00194   ActivityMatrix residual;
00195 };
00196 
00197 
00198 
00203 class InternalNeuralRegion : public NeuralRegion {
00204 public:
00207   InternalNeuralRegion(string name_i, Dimensions dims)
00208     : NeuralRegion(name_i,dims) { }
00209   
00210   virtual ~InternalNeuralRegion() { }
00212 
00219   typedef ActivityMatrix WeightMatrix;
00220 
00222   typedef Generic::unary_virtual_function<double,WeightMatrix> WeightFunction;
00223 
00225   typedef Boundary::BoundingBox<int,int> WeightBounds;
00226 
00228   typedef WeightSet<WeightMatrix,WeightBounds,MapBaseType,mat::MatrixInterfaceAdapter<WeightMatrix,Magnitude> > Weights;
00229 
00230   
00232   virtual Dimensions input_dimensions(WeightFunction& fn, Length size_scale=1.0) =0;
00233 
00234   virtual bool is_internal() const  {  return true;  }
00235   
00239   virtual void add_input(const string& name, NeuralRegion& upstream_region,
00240                          WeightFunction& fn, Length size_scale) =0;
00241 
00243   virtual void backproject() = 0;
00244 
00248   virtual void backproject(const string& name, const double gammaaff=1.0) {
00249 
00250         // This function should be called by derived classes' 
00251         // backproject(noarg), which will know which map to call.
00252         // --- cout << " - " << name << endl;
00253 
00254         // 1. get named input (upstream's output). Cleaning up the 
00255         //    backprojection region should be done prior to calling this
00256         //    function, so it is omitted here.
00257         NeuralRegion* inp = dynamic_cast<NeuralRegion*>(get_input(name));
00258         if (!inp) {
00259           // Messaging not currently possible from this routine
00260           //cout << "Error: input region nonexistent" << endl;
00261                 return;
00262         }
00263 
00264         // 2. Loop thorough all neurons in the current NeuralRegion bp 
00265         int nr = output.nrows(), nc = output.ncols();
00266         for (int i=0; i<nr; i++)
00267           for (int j=0; j<nc; j++) {
00268 
00269             double cur_output = bp[i][j];
00270 
00271             // 2.1 get named weights and bounds (upstream->downstream)
00272             const WeightMatrix  wmat = get_weights(name,i,j);
00273             const WeightBounds* wbounds = get_weights_bounds(name,i,j);
00274 
00275             // 2.2 get current activity (this map's output)
00276             //    output is the current ActivityMatrix;
00277             int xl = wbounds->aarectangle().corners().xl;
00278             int yl = wbounds->aarectangle().corners().yl;
00279             int xh = wbounds->aarectangle().corners().xh;
00280             int yh = wbounds->aarectangle().corners().yh;
00281 
00282             // 2.3 backproject loop
00283             for (int x=xl; x<=xh; ++x)
00284               for (int y=yl; y<=yh; ++y)
00285                 (inp->bp[x][y]) += cur_output * wmat[x-xl][y-yl] / gammaaff;
00286 
00287             delete wbounds;
00288 
00289           }
00290         // 2. end
00291 
00292   };
00293 
00294   
00295 #ifdef OBJ_LISSOM
00296   
00298   virtual void resp_to_residual() {};
00299 
00302   virtual void resp_to_residual(const string& name, const double gammaaff=1.0) {
00303 
00304         // This function should be called by derived classes' 
00305         // resp_to_residual(noarg), which will know which map to call.
00306         //
00307         // precondition: upstream "residual" must have been properly calculated
00308         // assumption: result will be ADDED to the current "output"
00309         //      so "output" should have been cleaned if this is the first time.
00310 
00311         // 1. propagation starts at the current "residual"
00312 
00313         // 2. Loop thorough all neurons in the current NeuralRegion residual
00314         NeuralRegion* inp = dynamic_cast<NeuralRegion*>(get_input(name));
00315 
00316         int nr = output.nrows(), nc = output.ncols();
00317         for (int i=0; i<nr; i++)
00318           for (int j=0; j<nc; j++) {
00319 
00320             // 2.1 get named weights and bounds (upstream->downstream)
00321             const WeightMatrix  wmat = get_weights(name,i,j);
00322             const WeightBounds* wbounds = get_weights_bounds(name,i,j);
00323 
00324             // 2.2 get current activity (this map's output)
00325             //    output is the current ActivityMatrix;
00326             int xl = wbounds->aarectangle().corners().xl;
00327             int yl = wbounds->aarectangle().corners().yl;
00328             int xh = wbounds->aarectangle().corners().xh;
00329             int yh = wbounds->aarectangle().corners().yh;
00330 
00331             // 2.3 backproject loop
00332             double sum = 0.0;
00333 
00334             for (int x=xl; x<=xh; ++x)
00335               for (int y=yl; y<=yh; ++y)
00336                 sum += (inp->residual[x][y]) 
00337                               * wmat[x-xl][y-yl];
00338 
00339             output[i][j] += sum / gammaaff;
00340 
00341             delete wbounds;
00342 
00343           }
00344         // 2. end
00345 
00346   }
00347 
00349   virtual void train_obj_weights() {};
00350 
00352   virtual void randomize_lat_wts() {};
00353 #endif /* OBJ_LISSOM */
00354 
00355 
00357 
00359   virtual const Weights weights(const string& name, int ui=0, int uj=0) const
00360   {  return Weights(new WeightMatrix(get_weights(name,ui,uj)),get_weights_bounds(name,ui,uj));  }
00361 
00362 
00363 //private: /* Eventually */
00372   virtual const WeightMatrix get_weights(const string& name, int ui=0, int uj=0) const =0;
00373 
00382   virtual WeightBounds* get_weights_bounds(const string& name, int ui=0, int uj=0) const =0;
00383 
00385 
00387 
00388   virtual NeuralRegion* get_input(const string& name) = 0;
00390 
00391 };
00392 
00393 
00394 #endif /* __NEURALREGION_H__ */

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2