00001
00007 #ifndef __FIXEDWTREGION_H__
00008 #define __FIXEDWTREGION_H__
00009
00010 #include <assert.h>
00011 #include <algorithm>
00012 #include <vector>
00013 #include <functional>
00014
00015 #include "genericalgs.h"
00016 #include "robj.h"
00017 #include "neuralregion.h"
00018 #include "matrix.h"
00019
00020
00021
00022
00023
00024
00026 template <class MatrixK, class MatrixI, class MatrixO>
00027 void convolve(const MatrixK& kernel, const MatrixI& in, MatrixO& out,
00028 const typename MatrixO::value_type size_scale=1.0,
00029 const bool overwrite=true)
00030 {
00031 typedef typename MatrixK::size_type SubscriptK;
00032 typedef typename MatrixI::size_type SubscriptI;
00033 typedef typename MatrixO::size_type SubscriptO;
00034
00035 for (SubscriptO r=0; r < out.nrows(); r++)
00036 for (SubscriptO c=0; c < out.ncols(); c++){
00037
00038 const SubscriptI rp = std::min(SubscriptI(r*size_scale),SubscriptI(in.nrows()-kernel.nrows()));
00039 const SubscriptI cp = std::min(SubscriptI(c*size_scale),SubscriptI(in.ncols()-kernel.ncols()));
00040 typename MatrixO::value_type sum=0;
00041
00042 for (SubscriptK k=0; k < kernel.nrows(); k++)
00043 for (SubscriptK l=0; l < kernel.ncols(); l++)
00044 sum += kernel[k][l]*in[rp+k][cp+l];
00045 if (overwrite)
00046 out[r][c] = sum;
00047 else
00048 out[r][c] += sum;
00049 }
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00069 class FixedWtRegion : public InternalNeuralRegion {
00070 public:
00071 FixedWtRegion(string name_i, Subscript height, Subscript width, Activity& act_threshold)
00072 : InternalNeuralRegion(name_i,height,width), threshold(act_threshold) { }
00073
00074 virtual ~FixedWtRegion() { Generic::delete_contents(inputs); }
00075
00076 virtual void add_input(const string& name, const ActivityMatrix& input_region,
00077 WeightFunction& fn, Length size_scale=1.0) {
00078 WeightMatrix kernel = (fn)(size_scale);
00079
00080 assert(kernel.nrows()%2==1);
00081 assert(kernel.ncols()%2==1);
00082
00083 Generic::insert_named(inputs,name,new Input(name,kernel,&input_region,size_scale));
00084 }
00085
00086 virtual Dimensions input_dimensions(WeightFunction& fn, Length size_scale=1.0) {
00087 WeightMatrix kernel = (fn)(size_scale);
00088 return Dimensions(Subscript(size_scale*output.nrows()+kernel.nrows()-1),
00089 Subscript(size_scale*output.ncols()+kernel.ncols()-1),
00090 Length(0.5-kernel.nrows()/2),
00091 Length(0.5-kernel.nrows()/2));
00092 }
00093
00094 virtual void activate(bool=false,bool=false) {
00095
00096 int num=0;
00097 for (inputs_type::const_iterator i=inputs.begin(); i!=inputs.end(); i++, num++)
00098 { convolve((*i)->kernel,*((*i)->input),output,(*i)->size_scale,i==inputs.begin()); }
00099
00100
00101 if (num>1) output *= 1.0/num;
00102 Generic::lower_threshold(MSEQ(output),threshold,0.0);
00103 }
00104
00105 virtual const WeightMatrix get_weights(const string& name="", int=0,int=0) const {
00106 const Input* i = Generic::find_named<Input>(inputs,name);
00107 return (i? i->kernel : WeightMatrix());
00108 }
00109
00110 protected:
00112 Activity& threshold;
00113
00115 struct Input {
00116 Input(const string& name_i, const WeightMatrix& kernel_i,
00117 const ActivityMatrix* input_i, const Length size_scale_i)
00118 : name_str(name_i), kernel(kernel_i), input(input_i), size_scale(size_scale_i) { }
00120 const string& name() const { return name_str; }
00121
00122 string name_str;
00123 WeightMatrix kernel;
00124 const ActivityMatrix* input;
00125 Length size_scale;
00126 };
00127
00129 typedef vector<Input*> inputs_type;
00130
00132 inputs_type inputs;
00133 };
00134
00135
00136 #endif