00001
00007 #ifndef __STIMULUSPARAMETERMAP_H__
00008 #define __STIMULUSPARAMETERMAP_H__
00009
00010 #include <string>
00011 using std::string;
00012 #include <vector>
00013 #include <functional>
00014
00015 #include "matrix.h"
00016 #include "histogram.h"
00017 #include "neuralregionmanager.h"
00018
00019
00020
00028 template <class MapBaseType, class ValuePointer>
00029 class StimulusParameterMap {
00030 public:
00031 typedef typename MapBaseType::size_type Subscript;
00032
00033 virtual ~StimulusParameterMap() {}
00034
00036 StimulusParameterMap(const string& name_, ValuePointer& valueptr_)
00037 : valueptr(valueptr_), namestr(name_) { }
00038
00041 int undefined_values() const { return undefined_vals; }
00042
00043 virtual MapBaseType* map() const =0;
00044
00045 virtual MapBaseType* selectivity() const =0;
00046
00047 const string& name() const { return namestr; }
00048
00049 protected:
00051 void undefined_values_start(const int undefined_values) const
00052 { undefined_vals = undefined_values; }
00053
00055 void undefined_values_end(const int undefined_values) const
00056 { undefined_vals = undefined_values-undefined_vals; }
00057
00058 ValuePointer& valueptr;
00059
00060 private:
00061 const string namestr;
00062 mutable int undefined_vals;
00063 };
00064
00065
00066
00074 template <class MapType, class MapBaseType, class ValuePointer>
00075 class StimulusParameterMap_Combined
00076 : public StimulusParameterMap<MapBaseType,ValuePointer> {
00077 typedef mat::MatrixInterfaceAdapter <MapType,typename MapBaseType::value_type> MapAdapterType;
00078
00079 public:
00080 typedef Histo::OneDBinList<> Histogram;
00081 typedef typename MatrixType< typename MapType::value_type >::rectangular MapMatrix;
00082 typedef typename MatrixType< Histogram >::rectangular HistoMatrix;
00083 typedef typename StimulusParameterMap<MapBaseType,ValuePointer>::Subscript Subscript;
00084 typedef typename MapAdapterType::ScaleType ScaleType;
00085
00086
00087 virtual ~StimulusParameterMap_Combined() {}
00088
00089 StimulusParameterMap_Combined(const MapType& reference_map, const string& name_,
00090 ValuePointer& valueptr_,
00091 bool measure_distribution_=true,
00092 bool weighted_average_=false,
00093 bool cyclic_=true,
00094 const ScaleType& selectivity_scale_=ScaleType())
00095 : StimulusParameterMap<MapBaseType,ValuePointer>(name_, valueptr_),
00096 measure_distribution(measure_distribution_),
00097 weighted_average(weighted_average_), cyclic(cyclic_),
00098 selectivity_scale(selectivity_scale_),
00099 maxvals(reference_map.nrows(),reference_map.ncols()),
00100
00101
00102 maxvals_distribution(reference_map.nrows(),reference_map.ncols())
00103 { }
00104
00105
00106 inline void mark_current_value_as_max( Subscript r, Subscript c) { maxvals[r][c] = *valueptr; }
00107
00108 inline void update_distribution(Subscript r, Subscript c, Histogram::Magnitude val) {
00109 assert(measure_distribution);
00110 Histogram* h = &(maxvals_distribution[r][c]);
00111 Histogram::size_type bin = (cyclic ? h->bin_number(*valueptr)
00112 : h->bin_number_inclusive(*valueptr));
00113 h->keep_peak(bin,val);
00114 }
00115
00124 MapBaseType* map() const {
00125 return (measure_distribution && weighted_average?
00126 (distribution_map
00127 (std::mem_fun_ref(cyclic ?
00128 &Histogram::vector_direction :
00129 &Histogram::weighted_average)))
00130 : coarse_map());
00131 }
00132
00133 MapBaseType* selectivity() const {
00134 return distribution_map
00135 (std::mem_fun_ref(cyclic ? &Histogram::vector_selectivity : &Histogram::relative_selectivity),
00136 selectivity_scale);
00137 }
00138
00139 private:
00140
00143 MapBaseType* coarse_map() const { return new MapAdapterType(new MapType(maxvals)); }
00144
00145 public:
00146
00147 const bool has_distribution() const { return measure_distribution; }
00148
00149 private:
00158 template <class HistoFn>
00159 MapBaseType* distribution_map
00160 (const HistoFn fn, const ScaleType& scale=ScaleType()) const {
00161 assert(measure_distribution);
00162 unsigned int orig_undefined_values=Histogram::undefined_values();
00163 MapMatrix* newmap = new MapMatrix(maxvals.nrows(),maxvals.ncols());
00164 undefined_values_start(Histogram::undefined_values());
00165 std::transform(CMSEQ(maxvals_distribution),MBEGIN(*newmap),fn);
00166 undefined_values_end(Histogram::undefined_values());
00167 Histogram::undefined_values_reset(orig_undefined_values);
00168 return new MapAdapterType(new MapType(*newmap), scale);
00169 }
00170
00171 bool measure_distribution;
00172 bool weighted_average;
00173 bool cyclic;
00174 ScaleType selectivity_scale;
00175
00176 MapMatrix maxvals;
00177 HistoMatrix maxvals_distribution;
00178 };
00179
00180
00181
00182
00189 template <class MapType, class MapBaseType, class ValuePointer>
00190 class StimulusParameterMapsForRegion {
00191 typedef typename MapType::size_type Subscript;
00192 typedef StimulusParameterMap_Combined<MapType, MapBaseType, ValuePointer> SPM;
00193 typedef StimulusParameterMap_Combined<MapType, MapBaseType, ValuePointer> SPMtoAllocate;
00194 typedef std::vector<SPM*> SPMs;
00195
00196 public:
00197 typedef typename SPM::ScaleType ScaleType;
00198
00200 StimulusParameterMapsForRegion(NeuralRegionManager* regionmanager)
00201 : rm(regionmanager),
00202 max_activity(rm->region()->nrows(),rm->region()->ncols())
00203 { mat::set(max_activity,0.0); }
00204
00206 void create_spm(const string& name_, ValuePointer& valueptr,
00207 int num_bins, bool measure_distribution=true,
00208 bool weighted_average=false, bool cyclic=false,
00209 const ScaleType& selectivity_scale=ScaleType()) {
00210
00211
00212
00213 Histo::OneDBinList<>::num_bins_default = num_bins;
00214
00215 spms.push_back(new SPMtoAllocate(rm->region()->const_activity(),
00216 name_, valueptr, measure_distribution,
00217 weighted_average, cyclic, selectivity_scale));
00218 }
00219
00220
00221
00222
00223 void update() {
00224 const NeuralRegion* reg = rm->region();
00225
00226 for (int r=0; r<reg->nrows(); r++)
00227 for (int c=0; c<reg->ncols(); c++)
00228 update(r,c);
00229 }
00230
00235 string register_maps() const {
00236 string warnings;
00237 for (typename SPMs::const_iterator spm=spms.begin(); spm!=spms.end(); spm++) {
00238 const SPM* s = *spm;
00239 const string map_name = s->name()+"Preference";
00240 rm->map_add(map_name,s->map());
00241 if (s->undefined_values())
00242 warnings += " " + map_name + ": " + String::stringrep(s->undefined_values());
00243 if (s->has_distribution()) {
00244 const string select_name = s->name()+"Selectivity";
00245 rm->map_add(select_name,s->selectivity());
00246 if (s->undefined_values())
00247 warnings += " " + select_name + ": " + String::stringrep(s->undefined_values());
00248 }
00249 }
00250 return (warnings=="" ? "" : "Undefined values:" + warnings);
00251 }
00252
00253 private:
00254
00256 inline void update(const Subscript r, const Subscript c) {
00257 const NeuralRegion::Activity newval = rm->region()->activity(r,c);
00258 NeuralRegion::Activity oldval = max_activity[r][c];
00259 const bool current_is_max_seen = (newval > oldval);
00260
00261 if (current_is_max_seen)
00262 max_activity[r][c] = newval;
00263
00264 for (typename SPMs::const_iterator spm=spms.begin(); spm!=spms.end(); spm++) {
00265 if (current_is_max_seen) (*spm)->mark_current_value_as_max(r,c);
00266 if ((*spm)->has_distribution()) (*spm)->update_distribution(r,c,newval);
00267 }
00268 }
00269
00270 NeuralRegionManager* rm;
00271 SPMs spms;
00272 NeuralRegion::ActivityMatrix max_activity;
00273 };
00274
00275
00276
00277 #endif