00001
00007 #include <utility>
00008
00009 #include "neuralregionmap.h"
00010 #include "matriximage.h"
00011 #include "matrixadapter.h"
00012 #include "imagegrid.h"
00013 #include "ppm_draw.h"
00014 #include "globals.h"
00015 #include "worldviews.h"
00016 #include "loopspec.h"
00017 #include "stimulusparametermap.h"
00018 #include "pathspecification.h"
00019
00020
00021 #ifdef EXPLICIT_INSTANTIATION_FOR_STATICS
00022 template class Histo::OneDBinList<int,double>;
00023 template class Plot::HSVPixel<Plot::Pixel::FComponent,Plot::Pixel::HueComponent>;
00024 template class ExpressionParser<PointerLookup<Typeless> >;
00025 #endif
00026
00027
00028
00029
00030
00031
00032
00033 #if (__GNUC__ <= 2)
00034 #define BINARY_FILE_FLAGS
00035 #else
00036 #define BINARY_FILE_FLAGS ,std::ios::binary
00037 #endif
00038
00039
00040
00042 int NeuralRegionMap::ppm_post_write_hook(const char* filename ) const
00043 {
00044 const Tristate spawn = blackboard.get_with_default("spawn_viewer",True);
00045 const bool interactive = blackboard.get_with_default("interactive",True);
00046
00047 if (spawn==True || (spawn==Uninitialized && interactive) ) {
00048 static int spawned_already=False;
00049 const bool independent = blackboard.get_with_default("ppm_spawn_independent_viewers",False);
00050 const string remote_viewer = blackboard.get_with_default("ppm_remote_viewer",string(""));
00051 const string image_viewer = blackboard.get_with_default("ppm_image_viewer",string(""));
00052 const bool remote = blackboard.get_with_default("running_remotely",False);
00053
00054 if (!spawned_already || independent) {
00055 const string command =
00056 (remote? remote_viewer : image_viewer) + " " +
00057 filename + " " + (remote? "" : "&");
00058
00059 system(command.c_str());
00060 spawned_already=True;
00061 }
00062 }
00063
00064 return 0;
00065 }
00066
00067
00071 void ppm_write_to_file(const string& filebase,const Plot::AARImage<>& img)
00072 {
00073
00074 const string filename = filebase + ".ppm";
00075 {
00076 std::ofstream os(filename.c_str() BINARY_FILE_FLAGS);
00077 img.ppm_write(os,filename,(unsigned char)(255));
00078 }
00079 }
00080
00081
00082
00083 string NeuralRegionMap::current_region;
00084 int NeuralRegionMap::current_width=-1;
00085 int NeuralRegionMap::current_height=-1;
00086 int NeuralRegionMap::current_ui=-1;
00087 int NeuralRegionMap::current_uj=-1;
00088 string NeuralRegionMap::current_plot;
00089 int NeuralRegionMap::plot_pe=PARENTPE;
00090
00091
00097 template <class OutputRectangle, class InputRectangle>
00098 inline OutputRectangle weightbounds_to_subregion(const InputRectangle& r)
00099 {
00100 const typename InputRectangle::Points p=r.corners();
00101 return OutputRectangle(-p.yl,-p.xl,-p.yh-1,-p.xh-1);
00102 }
00103
00104
00105
00107 const string NeuralRegionMap::pe_extension () const {
00108 if (plot_pe==Uninitialized)
00109 return string(".pe")+String::stringrep(MyPE,String::StreamFormat(2,'0'));
00110 return string();
00111 }
00112
00113
00114
00117 const string NeuralRegionMap::filenamebase(const string& plotgroup, const string& suppliedformat) const
00118 {
00119 const string defaultformat = blackboard.lookup_map("::PlotGroup::" + plotgroup).
00120 get_with_default("filename_format",string(""));
00121 const string filenameformat = (suppliedformat != string("") ? suppliedformat : defaultformat);
00122 const string basename = Parse(*(params.valueptr()),filenameformat.c_str()).cmds() + pe_extension();
00123 return basename;
00124 }
00125
00126
00127
00137 NeuralRegionMap::RegionManagerList
00138 NeuralRegionMap::retrieve_matching_regions(const string& names_string,
00139 Tristate plastic,
00140 Tristate internal) const
00141 {
00142 StringParser sp;
00143 StringParser::arglist names;
00144 sp.parse(names_string,names);
00145 const bool all = names.empty();
00146
00147
00148 if (all) sp.parse(string("Dummy"),names);
00149
00150 RegionManagerList result;
00151 for (StringParser::arglist::const_iterator a=names.begin(); a!=names.end(); a++)
00152 for (const_iterator i=begin(); i!=end(); i++) {
00153 RegionManager* item = (*i).second;
00154 if ( (all || String::non_numeric_basename_matches(*a,item->region()->name())) &&
00155 ((internal!=True || item->region()->is_internal() ) &&
00156 (internal!=False || !(item->region()->is_internal())) &&
00157 (plastic!=True || item->region()->is_plastic()) &&
00158 (plastic!=False || !(item->region()->is_plastic()))))
00159 result.push_back(item);
00160 }
00161
00162 return result;
00163 }
00164
00165
00166
00168 NeuralRegionMap::RegionManagerList
00169 NeuralRegionMap::retrieve_matching_regions(const ParamMap& params,
00170 const string& name_of_regionlist_param,
00171 const bool uselimits) const
00172 {
00173 const string regionlist = params.get_with_default(name_of_regionlist_param.c_str(),string(""));
00174 const Tristate plastic = (uselimits? params.get_with_default("plastic",Uninitialized) : Uninitialized);
00175 const Tristate internal = (uselimits? params.get_with_default("internal",Uninitialized) : Uninitialized);
00176 return retrieve_matching_regions(regionlist, plastic, internal);
00177 }
00178
00179
00180
00181 const bool NeuralRegionMap::gnuplot_image(const ParamMap& argparams,
00182 NeuralRegionManager::PlotSpec& plotspec,
00183 const string& filebase,
00184 const NeuralRegionManager::PlotSpec::MatrixTable* tempmaps,
00185 const SpecRegion& subregion) const
00186 {
00187 const Tristate spawn = argparams.get_with_default("spawn_viewer",True);
00188 const bool interactive = argparams.get_with_default("interactive",True);
00189
00190
00191
00192 if (spawn==True || (spawn==Uninitialized && interactive) )
00193 plotspec.gnuplot_image("",tempmaps,&subregion);
00194
00195
00196 return plotspec.gnuplot_image(filebase,tempmaps,&subregion);
00197 }
00198
00199
00209 const NeuralRegionMap::PlotSpecList
00210 NeuralRegionMap::retrieve_matching_plots
00211 (const PlotSpecList::const_iterator& plotsbegin,
00212 const PlotSpecList::const_iterator& plotsend,
00213 const string& names_string) const
00214 {
00215 StringParser sp;
00216 StringParser::arglist names;
00217 sp.parse(names_string,names);
00218 const bool all = names.empty();
00219
00220
00221 if (all) sp.parse(string("Dummy"),names);
00222
00223 NeuralRegionManager::PlotSpecList result;
00224 for (StringParser::arglist::const_iterator a=names.begin(); a!=names.end(); a++)
00225 for (NeuralRegionManager::PlotSpecList::const_iterator i=plotsbegin; i!=plotsend; i++) {
00226 NeuralRegionManager::PlotSpec* item = *i;
00227 if (all || String::non_numeric_basename_matches(*a,item->name()))
00228 result.push_back(item);
00229 }
00230
00231 return result;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 cmdstat NeuralRegionMap::cmd_child_set( CMD_ARGS )
00244 {
00245 CMD_ARG_PARAMS(child_set);
00246
00247 const string parent = arglist.next(argparams.get_with_default("parent",string("")));
00248 const string children = arglist.next(argparams.get_with_default("children",string("")));
00249 const Tristate plastic = argparams.get_with_default("plastic",Uninitialized);
00250 const Tristate internal = argparams.get_with_default("internal",Uninitialized);
00251
00252 if (parent != "Region") {
00253 message(Msg::Error, "Only a parent of 'Region' is supported at this time");
00254 return CMD_PARAMETER_ERROR;
00255 }
00256
00257 RegionManagerList regions = retrieve_matching_regions(children, plastic, internal);
00258 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
00259 StringArgs args(arglist);
00260 cmdparams_set(blackboard.lookup_map("::Region::"+(*r)->region()->name()),
00261 args,true,true);
00262 }
00263
00264 return CMD_NO_ERROR;
00265 }
00266
00267
00268
00269 void NeuralRegionMap::register_params_and_commands( void )
00270 {
00271 ppm_init_hook();
00272
00273 PARAM_A(blackboard,"internal",Uninitialized,.add_lower_bound(Uninitialized),
00274 "True if a region accepts input from other regions, or False if it does not.\n"
00275 "Often used as a guard (filter) for operations on a list of regions, where if\n"
00276 "specified as True only internal regions are included, if specified False only\n"
00277 "non-internal regions are included, and if unspecified (i.e. Uninitialized) all\n"
00278 "regions are included.");
00279
00280 PARAM_A(blackboard,"plastic",Uninitialized,.add_lower_bound(Uninitialized),
00281 "True if a region has modifiable weights, or False if it does not.\n"
00282 "Often used as a guard (filter) for operations on a list of regions, where if\n"
00283 "specified as True only plastic regions are included, if specified False only\n"
00284 "non-plastic regions are included, and if unspecified (i.e. Uninitialized) all\n"
00285 "regions are included.");
00286
00287 CMDOBJ_DOC(plot,"init_network",this,0,"%s [<named_arguments>]* [<plotgroup>]",
00288 "Supported <named_arguments> include:\n"
00289 "<plotgroup>,"
00290 "<filename_format>,"
00291 "<save_matrices>,"
00292 "<gnuplot_plots>,"
00293 "<ppm_plots>,\n"
00294 "<ppm_separate_plots>,"
00295 "<ppm_combined_plots>,"
00296 "<ppm_interior_border>,\n"
00297 "<ppm_histograms>,"
00298 "<ppm_mainplot>.\n\n"
00299
00300 "Generate a plot of the specified <plotgroup> of items, evaluating the\n"
00301 "<filename_format> to construct the filename (not including the extension,\n"
00302 "e.g. .ppm or .ps). The only natively-supported <plotgroup> is:\n\n"
00303
00304 " Activity\n\n"
00305
00306 " Shows activation levels of all the units in each area (including input\n"
00307 " areas) at the current iteration. The areas are shown from left to right\n"
00308 " in the activation_order (which see). Some areas may define more than\n"
00309 " one activity plot, e.g. at different timesteps of a recurrent algorithm;\n"
00310 " if so those timesteps are shown in alphabetical order by name except\n"
00311 " that Activity is at the end. Each of the areas may have an associated\n"
00312 " histogram relating the activity values to another map plot; these appear\n"
00313 " beneath the associated area plot.\n\n"
00314
00315 "The command measure_stimulus_map may be used to create other such plots,\n"
00316 "e.g. for OrientationPreference, OrientationSelectivity, OcularPreference,\n"
00317 "etc.\n\n"
00318
00319 "From zero to several output files will be generated, depending on the values\n"
00320 "of <ppm_plots>, <gnuplot_plots>, and <save_matrices>.\n"
00321
00322 "If <ppm_plots> is true, the plots are generated as PPM images and saved\n"
00323 "to files. Many parameters may be set to control the graphing format for\n"
00324 "these files; unfortunately those have not yet been enumerated in a single\n"
00325 "listing.\n\n"
00326
00327 "If <gnuplot_plots> is true, the plots are generated as PostScript 3D plots\n"
00328 "using gnuplot. At present only limited functionality is supported with\n"
00329 "gnuplot. In particular, only the primary dimension will be shown, e.g.\n"
00330 "activity level, without e.g. any color coding for a subplot like\n"
00331 "OrientationPreference. Each plot is also at present a separate gnuplot\n"
00332 "image; eventually they may be combined into a single plot like the PPM\n"
00333 "plots to facilitate comparison between simultaneous activations.\n\n"
00334
00335 "If <save_matrices> is true, the plots are generated as ASCII data files\n"
00336 "for each Strength matrix (or Color if no Strength) in a format intended\n"
00337 "to be compatible with GNU Octave, but which should be easily convertible\n"
00338 "to any other program accepting an ASCII matrix. Read the output files\n"
00339 "(*.matrix) in an editor to see the format (and the data). To view the\n"
00340 "image in Octave (or, probably, Matlab), you can use the Octave\n"
00341 "commands `load <filename>.matrix ; imagesc(Activity);' (where the\n"
00342 "name Activity will differ depending on the name of the matrix plotted).");
00343 blackboard.lookup_map("::cmd::plot").set_local("plotgroup",string("Activity"));
00344
00345 PARAM_A(blackboard.lookup_map("::cmd"),"ppm_separate_plots",False,.add_lower_bound(False),
00346 "When ppm_plots is true, whether to generate individual image plots for each\n"
00347 "region or set of weights. At present the individual plots do not spawn\n"
00348 "viewers, regardless of the value of spawn_viewer, because of the quantity\n"
00349 "of windows that would be spawned. Also see ppm_combined_plots.");
00350
00351 PARAM_A(blackboard.lookup_map("::cmd"),"ppm_combined_plots",True,.add_lower_bound(False),
00352 "When ppm_plots is true, whether to generate a combined image from all the \n"
00353 "plots for each region or set of weights. Also see ppm_separate_plots.");
00354
00355
00356 CMDOBJ_DOC(plot_unit,"init_network",this,0,"%s [<named_arguments>]* [<ui> <uj>]*",
00357 "Supported <named_arguments> include:\n"
00358 "<colorspec>,"
00359 "<filename_format>,"
00360 "<gnuplot_plots>,"
00361 "<plotgroup>,\n"
00362 "<ppm_border>,"
00363 "<ppm_histograms>,"
00364 "<ppm_interior_border>,\n"
00365 "<ppm_interior_outline>,"
00366 "<ppm_line_*>,"
00367 "<ppm_mainplot>,\n"
00368 "<ppm_master_scale>,"
00369 "<ppm_outline_weights>,"
00370 "<ppm_outline_width>,\n"
00371 "<ppm_page_*>,"
00372 "<ppm_plots>,"
00373 "<ppm_separate_plots>,"
00374 "<ppm_combined_plots>,\n"
00375 "<region>,"
00376 "<verbose>,"
00377 "<weight_bare>,"
00378 "<weight_fill_background>,\n"
00379 "<weight_situate>.\n"
00380 "(Plus others, in all likelihood.)\n\n"
00381
00382 "Same as plot, but plots single-unit data, e.g. weights, rather than data\n"
00383 "from all regions. The only <plotgroup> currently supported is Weights. The\n"
00384 "origin is at the upper left, with <ui> counting downwards and <uj> counting\n"
00385 "to the right.\n\n"
00386
00387 "The values of each weight are scaled using the globals ppm_weight_scale_type\n"
00388 "and ppm_weight_fixed_multiplier before plotting, even with gnuplot. Use a\n"
00389 "type of Fixed and a multiplier of 1.0 to see the true values in gnuplot.\n"
00390 "(Or leave those parameters as they are to see how the magnitudes are being\n"
00391 "auto-scaled for the bitmap display).");
00392 blackboard.lookup_map("::cmd::plot_unit")
00393 .set_local("plotgroup",string("Weights"))
00394 .set_local("weight_situate",True)
00395 .set_local("weight_bare",False);
00396
00397 CMDOBJ_DOC(plot_unit_range,"init_network",this,0,"%s [<named_arguments>]* [<start_r> [<start_c> [<end_r> [<end_c> [<ppm_neuron_skip_aff>]]]]]",
00398 "Supported <named_arguments> include:\n"
00399 "<colorspec>,"
00400 "<filename_format>,"
00401 "<gnuplot_plots>,"
00402 "<name>,"
00403 "<plotgroup>,\n"
00404 "<ppm_border>,"
00405 "<ppm_histograms>,"
00406 "<ppm_interior_border>,\n"
00407 "<ppm_interior_outline>,"
00408 "<ppm_line_*>,"
00409 "<ppm_mainplot>,\n"
00410 "<ppm_master_scale>,"
00411 "<ppm_outline_weights>,"
00412 "<ppm_outline_width>,\n"
00413 "<ppm_page_*>,"
00414 "<ppm_plots>,"
00415 "<ppm_separate_plots>,"
00416 "<ppm_combined_plots>,\n"
00417 "<region>,"
00418 "<verbose>,"
00419 "<weight_bare>,"
00420 "<weight_fill_background>,\n"
00421 "<weight_situate>.\n"
00422 "(Plus others, in all likelihood.)\n\n"
00423
00424 "Same as plot_unit, but plots data (e.g. weights) from a rectangular range of\n"
00425 "units in a region rather than just one.\n\n"
00426
00427 "The only <plotgroup> currently supported is Weights. The <name> should\n"
00428 "specify which set of data of the given <plotgroup> to use, e.g. Afferent0.\n"
00429 "A glob pattern (e.g. * or Afferent*) may also be used, to plot multiple\n"
00430 "items side by side, but support for this may change to e.g. a regular\n"
00431 "expression in the future, so do not rely on it.");
00432 blackboard.lookup_map("::cmd::plot_unit_range")
00433 .set_local("plotgroup",string("Weights"))
00434 .set_local("name",string("Afferent0"))
00435 .set_local("ppm_interior_border",1.0)
00436 .set_local("weight_situate",False)
00437 .set_local("weight_bare",True)
00438 .set_local("ppm_master_scale",double(Uninitialized))
00439 .set_local("ppm_histograms",False);
00440 blackboard.lookup_map("::cmd::plot_unit_range")
00441 .lookup("ppm_interior_border").add_default_expr("");
00442
00443 PARAM_A(blackboard.lookup_map("::cmd"),"verbose",False,.add_lower_bound(False),
00444 "If True, increases the verbosity of the output of a command.");
00445
00446 CMDOBJ_DOC(save_snapshot,"init_network",this,0,"%s [<named_arguments>]* [<filename>]",
00447 "Supported <named_arguments> include:\n"
00448 "<filename>,<regions>,<plastic>,<internal>,<verbose>.\n\n"
00449
00450 "Save the current state of the network weights of the specified region(s).\n"
00451 "The binary files are intended to be portable between any machines that use\n"
00452 "the IEEE floating-point format. When the file is reloaded, load_snapshot\n"
00453 "will assume that it was saved *after* the current iteration had completed,\n"
00454 "which is true when save_snapshot is used directly on the command line or in\n"
00455 "a command file. If saving indirectly via a hook, you should use the hooklist\n"
00456 "after_learning to be consistent with this assumption.");
00457 blackboard.lookup_map("::cmd::save_snapshot")
00458 .set_local("plastic",True);
00459
00460 PARAM_A(blackboard.lookup_map("::cmd"),"reset",False,.add_lower_bound(False),
00461 "Command argument specifying that internal state maintained across command\n"
00462 "invocations should be reset to its initial value.");
00463
00464 PARAM_A(blackboard.lookup_map("::cmd"),"horizontal",True,.add_lower_bound(False),
00465 "When printing items from a list, whether to print each on a new line (False)\n"
00466 "or on the same line (True).");
00467
00468 PARAM_A(blackboard.lookup_map("::cmd"),"label",string(),,
00469 "Command argument: label for printed information.");
00470
00471 CMDOBJ_DOC(map_statistics,"init_network",this,0, "%s [<named_arguments>]* [<name>]",
00472 "Supported <named_arguments> include:\n"
00473 "<regions>,<plastic>,<internal>,<verbose>,<reset>,<cumulative>,<min_max>,<kurtosis>,<horizontal>,<label>,<name>.\n\n"
00474
00475 "Computes and displays some statistics about the named map for the given\n"
00476 "region. The headings can be suppressed (e.g. for multiple calls in a row)\n"
00477 "by setting verbose=False. If <reset> is true then all internal state\n"
00478 "is reset, e.g. to make an average or cumulative sum be zero again; no\n"
00479 "statistics are printed in that case. Note that at present cumulative\n"
00480 "values are cumulative over all regions and all maps measured since\n"
00481 "the previous reset, and thus in most cases only a single map should\n"
00482 "be measured when cumulative is true.");
00483 blackboard.lookup_map("::cmd::map_statistics")
00484 .set_local("name",string("Activity"))
00485 .set_local("plastic",True);
00486
00487 PARAM_A(blackboard.lookup_map("::cmd::map_statistics"),"cumulative",False,.add_lower_bound(False),
00488 "Command argument: whether to print cumulative sums or averages.");
00489
00490 PARAM_A(blackboard.lookup_map("::cmd::map_statistics"),"kurtosis",False,.add_lower_bound(False),
00491 "Command argument: whether to print kurtosis.");
00492
00493 PARAM_A(blackboard.lookup_map("::cmd::map_statistics"),"min_max",False,.add_lower_bound(False),
00494 "Command argument: whether to print min and max values.");
00495
00496
00497 CMDOBJ_DOC(backproject,"init_network",this,0,"%s [<named_arguments>]* [<name>]",
00498 "Supported <named_arguments> include: <verbose>.\n\n"
00499
00500 "Backproject current activity back to upstream regions through the\n"
00501 "incoming connection weights.\n");
00502 blackboard.lookup_map("::cmd::backproject")
00503 .set_local("name",string("Activity"));
00504
00505 #ifdef OBJ_LISSOM
00506 CMDOBJ_DOC(resp_to_residual,"init_network",this,0,"%s [<name>]",
00507 "Computes the input response to the residual of upstream activity.\n"
00508 "(use with OBJ-LISSOM)");
00509
00510 CMDOBJ_DOC(train_obj_weights,"init_network",this,0,"%s [<name>]",
00511 "Modifies weights in OBJ-LISSOM. Should call backproject and resp_to_residual\n"
00512 "just before calling this command.");
00513
00514 CMDOBJ_DOC(randomize_lat_wts,"init_network",this,0,"%s [<name>]",
00515 "Replace all of the lateral weights with random values, as a test of\n"
00516 "OBJ-LISSOM.\n\n");
00517 #endif
00518
00519 CMDOBJ_DOC(kill_connections,"init_network",this,0, "%s [<named_arguments>]*",
00520 "Supported <named_arguments> include:\n"
00521 "<regions>,<plastic>,<internal>,<verbose>.\n\n"
00522
00523 "Prunes connections in each specified region (defaulting to all plastic\n"
00524 "regions) if they are at or below the values of their corresponding\n"
00525 "inh_death, exc_death, etc.");
00526 blackboard.lookup_map("::cmd::kill_connections")
00527 .set_local("plastic",True);
00528
00529 CMDOBJ_DEFINE_CATCHUP(this,0,child_set,
00530 "%s [<constraints>]* <parent> <children> [<path>=<value>]*",
00531
00532 "This command is the same as the general set command, except that it\n"
00533 "can be limited to a subset of paths representing the children of a given\n"
00534 "set of parameters. It can do so without specifying the actual names of\n"
00535 "those children, which may not be known ahead of time or easily enumerable.\n"
00536 "It is also a handy way to apply a set of a parameters to an enumerated\n"
00537 "subset of children.\n\n"
00538
00539 "At present the only <parent> supported is 'Region', and thus the <children>\n"
00540 "are also <regions>. For Region the supported <constraints> include:\n"
00541 "<plastic>,<internal>.\n\n"
00542
00543 "The given list of names of <children> of the parameter set <parent>\n"
00544 "(which may be '' to specify all children) is first subjected to the\n"
00545 "given constraints, if any, to determine a list of regions. (See the\n"
00546 "<plastic> and <internal> parameters for more information.) The given\n"
00547 "parameters are then set to the given values in every child in that\n"
00548 "list. The <path>s are relative to each child; a parameter name\n"
00549 "usually suffices. Example:\n\n"
00550
00551 " child_set plastic=True Region '' colorspec=Grayscale");
00552 blackboard.lookup_map("::cmd::child_set")
00553 .set_local("verbose",True);
00554
00555 PARAM_A(blackboard.lookup_map("::cmd"),"children",string(""),,
00556 "Command argument for a list of the names of children, e.g. of a set of\n"
00557 "parameters. Specified names may omit trailing digits, which will select\n"
00558 "all items matching up to the digits, in the order of their creation. \n"
00559 "(E.g. 'Eye' will match 'Eye0', 'Eye1', etc.)");
00560
00561 CMDOBJ_DOC(define_plot,"init_network",this,0,"%s [<named_arguments>]* [<strength_map> [<color_map> [<confidence_map>]]]",
00562 "Supported <named_arguments> include:\n"
00563 "<plotgroup>,<name>,<regions>,<filename_format>,<plastic>,<internal>.\n\n"
00564
00565 "Define a new plot for use with the plot command.\n\n"
00566
00567 "The <name> of this plot defaults to the name of the first non-empty map\n"
00568 "name specified; this default value can be overridden with an explicit\n"
00569 "<name> if desired. The <plotgroup> in turn defaults to the <name>, and\n"
00570 "it too can be overridden (e.g. to combine multiple plots into a single\n"
00571 "<plotgroup>). If the <plotgroup> (whether specified or deduced) does not\n"
00572 "already exist, it is created, in which case you might also want to specify\n"
00573 "a <filename_format> to override the default format (which is constructed\n"
00574 "from the filebase, iteration number, presentation number, and <plotgroup>).\n\n"
00575
00576 "The <*_map> parameters specify the name of a registered map, e.g. Activity,\n"
00577 "or '' if none is desired for that quantity. The <strength_map> is usually\n"
00578 "the primary dimension, and is colored according to the <color_map> (if\n"
00579 "present). (Note that <color_map> is not a computer-graphics-style\n"
00580 "colormap, i.e. a mapping from a value into a color; rather it is a matrix\n"
00581 "of values to use for the Hue component of the image.) The strength of the\n"
00582 "colors will be determined by the <confidence_map>. The specific colors\n"
00583 "used can be determined by setting appropriate parameters in\n"
00584 "PlotGroup::<plotgroup>::*; see the plot command for more details.\n\n"
00585
00586 "The plot is defined for all regions by default, but an explicit list of\n"
00587 "regions may be supplied as the <regions> parameter. This list (or the\n"
00588 "default of all regions) is further limited to plastic or non-plastic\n"
00589 "regions if <plastic> is True or False, and/or to internal or external\n"
00590 "regions only (regions which can or cannot accept input from other\n"
00591 "regions) if <internal>is True or False.\n\n"
00592
00593 "Once the plot has been defined, you may obtain a plot via\n"
00594 "'plot <plotgroup>'.");
00595 PARAM_A(blackboard.lookup_map("::cmd"),"regions",string(""),,
00596 "Command argument for a list of the names of neural regions, in order. If\n"
00597 "empty, all regions will be used, in the order they were defined. Specified\n"
00598 "names may omit trailing digits, which will select all regions matching up to\n"
00599 "the digits, in the order of their creation. (E.g. 'Eye' will match 'Eye0',\n"
00600 "'Eye1', etc.)");
00601
00602 CMDOBJ_DOC(measure_stimulus_map,"init_network",this,0,
00603 "%s [<named_arguments>]* <presentation-command> [<dimension_spec>]*",
00604 "Supported <named_arguments> include:\n"
00605 "<regions>, <plastic>, and <internal> (as well as any of the\n"
00606 "<named_arguments> from the <dimension_spec>, below, which if specified\n"
00607 "here apply as defaults for all dimensions.)\n\n"
00608
00609 "Computes maps of preferences for specified input patterns. To measure the\n"
00610 "data required, this command calls the <presentation-command> multiple times,\n"
00611 "systematically varying the specified parameters (and thus the input patterns)\n"
00612 "and recording the responses of each unit in each region. The\n"
00613 "<presentation-command> is typically input_present_object or a variant, but\n"
00614 "may be any valid command.\n\n"
00615
00616 "A <dimension_spec> has the form:\n"
00617 "\"[<named_arguments>]* [<name> [<divisions>]]\",\n"
00618 "where any of the following <named_arguments> may be used:\n"
00619 "<cyclic>, <discrete_inputs>, <divisions>, <measure_distribution>,\n"
00620 "<name>, <num_bins>, <register>, <valuegenerator>,\n"
00621 "<varname>, and <weighted_average>.\n\n"
00622
00623 "Each <dimension_spec> specifies one dimension of input variance, e.g.\n"
00624 "orientation or spatial frequency, of which an arbitrary number can be\n"
00625 "supplied. All possible combinations of all values of each dimension\n"
00626 "will be tested, and the set of parameter values which generated the\n"
00627 "maximum response will be stored. From these stored peak values the maps\n"
00628 "will be constructed, using one of a variety of methods determined by the\n"
00629 "<named_arguments> for the dimension (which see).\n\n"
00630
00631 "For each dimension, a global Param_Float parameter ranging from 0.0 to\n"
00632 "1.0 must be defined before this call, using the same <name> as this\n"
00633 "dimension (although if desired a different name for this parameter may\n"
00634 "be specified as <varname>). By default, the full range of possible\n"
00635 "values for this parameter from 0.0 to 1.0 will be divided into\n"
00636 "<divisions> equally-spaced portions, and inputs will be presented\n"
00637 "with parameter values set to the boundaries of these divisions.\n\n"
00638
00639 "The <presentation-command> will generally compute the actual input\n"
00640 "parameter values as a function of the normalized value of each dimension.\n"
00641 "E.g., an orientation might be computed from the dimension named Orientation\n"
00642 "as theta=2*PI*Orientation. This uniformly normalized approach was taken to\n"
00643 "ensure that the underlying map computation is independent of the scale\n"
00644 "and type of transformation, which makes it possible to use the same\n"
00645 "algorithm for both linear and non-linear or discontinuous transformations.\n\n"
00646
00647 "Responses are computed and stored for each region specified in <regions>,\n"
00648 "which is all regions by default. By default, the list of regions (whether\n"
00649 "default or specified) is limited to those with modifiable connections (to\n"
00650 "avoid wasting computation time); this default may be overridden by supplying\n"
00651 "Uninitialized for <plastic>. The list of regions may also be limited to\n"
00652 "internal regions only by supplying True for <internal>.\n\n"
00653
00654 "When this command completes, maps for each specified region\n"
00655 "and for each dimension for which <register> is true are computed and\n"
00656 "registered under the names \"<name>Preference\" and (if\n"
00657 "<measure_distribution> is true) \"<name>Selectivity\". For instance,\n"
00658 "if <name> is 'Orientation', maps will be created with the names\n"
00659 "'OrientationPreference' and (possibly) 'OrientationSelectivity' for\n"
00660 "each specified region. The Selectivity maps range from 0 to 1.0, i.e.\n"
00661 "no selectivity (response was the same to all parameter values) to\n"
00662 "complete selectivity (neuron responded to only one parameter value).\n"
00663 "The method used to calculate the selectivity depends on whether the\n"
00664 "dimension is <cyclic>; see <weighted_average> for more details.\n\n"
00665
00666 "Once the maps are registered, they may then be plotted by calling\n"
00667 "define_plot using these names, and then plot. For instance, the maps\n"
00668 "created for the dimension named 'Orientation' can be plotted using:\n"
00669
00670 "define_plot plastic=True plotgroup=OrMap '' OrientationPreference\n"
00671 "define_plot plastic=True plotgroup=OrMap OrientationSelectivity\n"
00672 "plot OrMap");
00673 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"discrete_inputs",True,.add_lower_bound(False),
00674 "Truncate the value for this parameter to be one of the discrete values 0 to\n"
00675 "<num_bins>. This can be useful when generating random or continuous values, to\n"
00676 "ensure that the value of stimulus parameter corresponds precisely to the bin in\n"
00677 "which its response will later be placed for measurement purposes. Usually set\n"
00678 "to True, but there may be some circumstance in which this is undesirable.");
00679 PARAM_A(blackboard.lookup_map("::cmd"),"divisions",1,.add_lower_bound(0),
00680 "The number of divisions to use for a dimension, e.g. for measure_stimulus_map.\n"
00681 "If the dimension is cyclic, this value is the same as the number of actual\n"
00682 "stimulus presentations that will be used; otherwise the number of presentations\n"
00683 "is one more than the number of divisions because of the boundary condition at\n"
00684 "1.0. The higher the number of divisions, the better the sampling, but the more\n"
00685 "presentations (and therefore time) will be required.");
00686 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"measure_distribution",True,.add_lower_bound(False),
00687 "When measuring a preference map, whether to store a distribution of the\n"
00688 "maximal responses for the different values for this dimension, or just the\n"
00689 "single set of parameters that caused the peak response for this unit.\n"
00690 "Computing and storing the full distribution does not generally take much\n"
00691 "computation time, but it does take memory. The distribution is required\n"
00692 "for calculating selectivity and for <weighted_average> map computation\n"
00693 "types.");
00694 PARAM_A(blackboard.lookup_map("::cmd"),"num_bins",0,.add_lower_bound(-1),
00695 "When measure_distribution is true in measure_stimulus_map, how many\n"
00696 "distinct values of the parameter to keep track of, i.e. the number of\n"
00697 "bins to use in the histogram. Higher values give more precision, but\n"
00698 "take more memory and slightly more time. The default is the total number\n"
00699 "of presentations, which for the default equally-spaced parameter values\n"
00700 "provides exactly enough precision to represent all of the information\n"
00701 "that can be obtained. For non-evenly-spaced parameter values (e.g. using\n"
00702 "a Random <valuegenerator>), increasing num_bins from this default may be\n"
00703 "appropriate. In such cases, unless num_bins is quite large, you will\n"
00704 "probably want to enable discrete_inputs.");
00705 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"register",True,.add_lower_bound(False),
00706 "For a dimension specified when measuring a preference map, whether to compute\n"
00707 "and register a map showing the preferences for that dimension. (Often\n"
00708 "dimensions will be included just to ensure good coverage of possible stimuli,\n"
00709 "without each one necessarily being useful to graph.)");
00710 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"selectivity_scale",1.0,,
00711 "Multiplier applied to the selectivity before it is returned as a map. This\n"
00712 "defaults to 1.0, but can be set to other values to simplify the use of\n"
00713 "selectivity as part of combined plots; the scaling should leave the typical\n"
00714 "or useful values for selectivity in the range 0 to 1.0.");
00715 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"weighted_average",False,.add_lower_bound(False),
00716 "If maximum response distribution information is available\n"
00717 "(measure_distribution is True), compute preference map from a weighted\n"
00718 "average of the values of each bin in the distribution, rather than simply\n"
00719 "using the actual value of the parameter for which response was maximal (the\n"
00720 "default, discrete method). Such a computation will generally produce much\n"
00721 "more precise maps using fewer test stimuli than the discrete method.\n"
00722 "However, weighted_average methods generally require uniform sampling, as\n"
00723 "described below, which is not always desirable.\n\n"
00724
00725 "Because of differences in how the averaging needs to be done near the\n"
00726 "borders of the parameter range, different methods are used depending on\n"
00727 "whether the parameter (dimension) is cyclic or not. If this dimension is\n"
00728 "non-cyclic (cyclic=False), the weighted_average is computed as the center\n"
00729 "of gravity of the distribution, i.e. the arithmetic mean of the product of\n"
00730 "each bin's value and its bin number, over the total value of the bins. The\n"
00731 "selectivity is then computed from the value of the bin with the largest\n"
00732 "value, divided by the total value of all of the bins; it is then scaled to\n"
00733 "range from 0.0 (no differences between bins) to 1.0 (only a single bin is\n"
00734 "nonzero).\n\n"
00735
00736 "If this dimension is cyclic, the preference is computed as the direction of\n"
00737 "a vector sum. The vectors in the sum have as their length the maximum\n"
00738 "response at each of the num_bins possible values, with their direction\n"
00739 "determined by the bin number (on a scale 0..1.0 transformed into 0..2*PI).\n"
00740 "The selectivity is then the length of the vector sum; it is zero if all bins\n"
00741 "have equal values, and 1.0 if only one bin has a nonzero value.\n\n"
00742
00743 "For measurements at evenly-spaced intervals over the full range of possible\n"
00744 "parameter values, weighted_averages are a good measure of the underlying\n"
00745 "continuous-valued parameter preference, assuming that neurons are tuned\n"
00746 "broadly enough (and/or sampled finely enough) that they respond to at least\n"
00747 "two of the tested parameter values. This method will not usually give good\n"
00748 "results when those criteria are not met, i.e. if the sampling is too sparse,\n"
00749 "not at evenly-spaced intervals, or does not cover the full range of possible\n"
00750 "values. Thus a weighted_average measurement should not ordinarily use a\n"
00751 "random <valuegenerator>, and will probably not be useful with other\n"
00752 "ValueGenerator types either. If using a ValueGenerator with a\n"
00753 "weighted_average; be sure to check that all of the possible num_bins values\n"
00754 "are equally represented in the set of testing stimuli, e.g. by setting\n"
00755 "display=True in the <presentation_command>.");
00756 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"valuegenerator",string(""),,
00757 "Usually each stimulus dimension will just increase uniformly and monotonically\n"
00758 "from 0 to 1.0, in which case this parameter is not needed. However, if you\n"
00759 "prefer random values to avoid sampling biases, or perhaps want some other\n"
00760 "distribution, you can specify any ValueGenerator (see input_define_generator)\n"
00761 "here instead. For instance, to use a random value each time, use\n"
00762 "'Random 0.5 0.5'. See also num_bins; for random distributions you will\n"
00763 "probably want more than the default num_bins in the plot.");
00764 PARAM_A(blackboard.lookup_map("::cmd::measure_stimulus_map"),"varname",string(""),,
00765 "Usually a variable with the same name as this dimension will be set to the\n"
00766 "value of the dimension's parameter at each iteration. If you have defined\n"
00767 "a different variable name and want to use it instead, specify its name here.\n"
00768 "Note that the variable must still be a Param_Float ranging from 0 to 1.0\n"
00769 "as for the default case.\n\n"
00770
00771
00772
00773 "Note that at present the parameter (whether default or specified explicitly\n"
00774 "here) must be in the global namespace, because the variable values are\n"
00775 "updated by setting the parameter in that namespace to make it available\n"
00776 "to the <presentation_command>.");
00777 blackboard.lookup_map("::cmd::measure_stimulus_map")
00778 .set_local("plastic",True);
00779
00780
00781 PARAM_A(blackboard,"filename_format",string(""),,
00782 "String expression for a filename to use for a generated file. It will\n"
00783 "be evaluated before each use, and may thus contain references to other\n"
00784 "parameters. Ordinarily, the global value be \"\", which means that\n"
00785 "the value set for the appropriate PlotGroup (<plotgroup>) will be\n"
00786 "used. Alternatively, you can force all plots to have the same filename_format\n"
00787 "(presumably one using multiple string substitutions) by defining this\n"
00788 "parameter at the root level.");
00789
00790 PARAM_A(blackboard,"default_filename_format",
00791 string("${filebase}.${06iteration}p${03presentation}.${current_region}${?current_region,_}${current_plot}"),,
00792 "The filename_format used for new PlotGroups (see define_plot and\n"
00793 "define_plotgroup). Also useful to override one defined for a particular\n"
00794 "type of plot, by supplying filename_format=$${default_filename_format} when\n"
00795 "calling a command.");
00796
00797
00798
00799
00800
00801
00802
00803
00804 blackboard.new_child("PlotGroup", true);
00805 define_plotgroup("Activity" ,"${filebase}.${06iteration}.${03current_object_angle}p${01presentation}");
00806 define_plotgroup("Weights" ,"${filebase}.${06iteration}.wts.${03current_ui}_${03current_uj}");
00807 define_plotgroup("OrientationPreference","${filebase}.${06iteration}.or");
00808 define_plotgroup("OcularPreference" ,"${filebase}.${06iteration}.od");
00809 define_plotgroup("WeightsMap" ,"${filebase}.${06iteration}.aff_map${input_current_eye}");
00810 define_plotgroup("Backprojection" ,"${filebase}.${06iteration}.bp.p${01presentation}");
00811
00812
00813 define_plotgroup("Histogram");
00814 define_plotgroup("SavedState" ,"${filebase}.${06iteration}.wts");
00815
00816
00817
00818 ParameterMap<>& regionparams = *dynamic_cast< ParameterMap<>* >(params.valueptr());
00819
00820 PARAM_A(regionparams,"activation_order",string("Eye Ganglia LGN Primary Secondary Association Frontal"),,
00821 "List of each neural region in the order in which they should be activated\n"
00822 "when new input is computed. Also determines activity plot order. If empty,\n"
00823 "all regions will be activated or plotted, in the order they were defined.");
00824
00825 PARAM_A(regionparams,"connection_order",string("Afferent AfferentExcitatory AfferentInhibitory Lateral LateralExcitatory LateralInhibitory Efferent EfferentExcitatory EfferentInhibitory Feedback FeedbackExcitatory FeedbackInhibitory"),,
00826 "List of each type of connection in the order in which they should be plotted\n"
00827 "by plot_unit. If empty, all connections will be plotted, in the order they\n"
00828 "were defined.");
00829
00830 PARAM_A(regionparams,"ppm_weight_fixed_multiplier",500.0,.add_lower_bound(0.0),
00831 "Amount by which to multiply weight values to get luminance value for\n"
00832 "plots, when ppm_weight_scale_type=PPM_WtScale_Fixed.");
00833
00834 PARAM_A(regionparams,"ppm_weight_fixed_offset",0.0,,
00835 "Amount which to add to weight values to get luminance value for\n"
00836 "plots, when ppm_weight_scale_type=PPM_WtScale_Fixed.");
00837
00838 PARAM_A(regionparams,"colorspec",string("RYW"),,
00839 "Specification for a color lookup function to use for a plot of a single\n"
00840 "dimension. The function returns a color when given a single quantity in\n"
00841 "the range 0.0 to 1.0, here called a level.\n\n"
00842
00843 "The <colorspec> can be one of the named colormaps below, or it can specify\n"
00844 "a list of characters corresponding to colors between which to interpolate.\n"
00845 "(Interpolation is performed linearly in RGB space.) Available colors include:\n\n"
00846
00847 " R Red\n"
00848 " Y Yellow\n"
00849 " G Green\n"
00850 " C Cyan\n"
00851 " B Blue\n"
00852 " M Magenta\n"
00853 " K Black\n"
00854 " W White\n\n"
00855
00856 "Use a lowercase letter to indicate that a color should use half intensity.\n"
00857 "For instance, a <colorspec> of 'KgYW' would map the level range 0.0->1.0\n"
00858 "to the color range black->dark green->yellow->white, with smooth\n"
00859 "interpolation between the specified colors.\n\n"
00860
00861
00862 "Predefined named <colorspec>s include:\n\n"
00863
00864 "Cold\n"
00865 " Bright cool colors based on blue and cyan. Same as KBCW, or WBC for\n"
00866 " ppm_paper_based_colors.\n\n"
00867
00868 "Cool\n"
00869 " Cool colors based on blue and cyan. Same as KBC, or WbBC for\n"
00870 " ppm_paper_based_colors.\n\n"
00871
00872 "Warm\n"
00873 " Warm colors based on red and yellow. Same as KRY, or WrRY for\n"
00874 " ppm_paper_based_colors.\n\n"
00875
00876 "Hot\n"
00877 " Bright warm colors based on red and yellow. Useful for emphasizing\n"
00878 " peak values, particularly on video terminals. Same as KRYW, or WRY for\n"
00879 " ppm_paper_based_colors. \n\n\n"
00880
00881
00882 "CoolWarm\n"
00883 " Uses a Cool <colorspec> for negative excursions from the middle of the\n"
00884 " range, and a Warm <colorspec> for positive excursions. Useful for\n"
00885 " highlighting changes in either direction relative to a prevailing\n"
00886 " background level of 0.5. For paper_based_colors, blob outlines are\n"
00887 " somewhat jagged because of the sharp transition from the colors to white.\n"
00888 " Same as CBKRY, or CBbWrRY for ppm_paper_based_colors.\n\n"
00889
00890 "ColdHot\n"
00891 " Uses a Cold <colorspec> for negative excursions from the middle of the\n"
00892 " range, and a Hot <colorspec> for positive excursions. Useful for\n"
00893 " highlighting changes in either direction relative to a prevailing\n"
00894 " background level of 0.5. For ppm_paper_based_colors==False, the extremes\n"
00895 " are both white, which can be confusing unless the underlying\n"
00896 " parameter is cyclic. Same as WCBKRYW, or CBWRY for ppm_paper_based_colors.\n\n"
00897
00898 "BlueRed\n"
00899 " Uses blue colors for negative excursions from the middle of the\n"
00900 " range, and red colors for positive excursions. Useful for\n"
00901 " highlighting changes in either direction relative to a prevailing\n"
00902 " background level. Same as BKR, or BWR for ppm_paper_based_colors.\n\n\n"
00903
00904
00905 "In addition to the above named abbreviations for interpolated colormaps,\n"
00906 "several other specific types based on the hue, saturation, and value are\n"
00907 "available:\n\n"
00908
00909 "Hue [saturation [value]]\n"
00910 " Useful for plotting cyclic quantities, such as orientation.\n"
00911 " The hue is computed from the level, and is combined with the given fixed\n"
00912 " saturation and value (default '1.0 1.0') to determine the color. The hue\n"
00913 " wraps around at each end of the range (e.g. red->yellow->green->blue->magenta\n"
00914 " ->red), and thus is usually appropriate only when the quantity plotted has\n"
00915 " that same property. For the defaults, nearly identical to RYGCBMR.\n\n"
00916
00917 "Saturation [hue [value]]\n"
00918 " Usually SpecifiedHue is used instead of specifying this type directly.\n"
00919 " The saturation is computed from the level, and is combined with the given\n"
00920 " fixed hue and value (default '0.0 1.0') to determine the color.\n\n"
00921
00922 "Value [hue [saturation]]\n"
00923 " Usually Grayscale is used instead of specifying this type directly.\n"
00924 " The value is computed from the level, and is combined with the given fixed\n"
00925 " hue and saturation (default '0.0 0.0') to determine the color. The defaults\n"
00926 " result in a range of grayscale values from black to white; the optional\n"
00927 " arguments allow other colors to be used instead of gray.\n"
00928 " For the defaults, nearly identical to KW.\n\n"
00929
00930 "Grayscale [hue [saturation]]\n"
00931 " Useful for monochrome displays or printers, or to show photographs.\n"
00932 " Same as Value but the scale is flipped when ppm_paper_based_colors=True.\n"
00933 " This makes the most-active areas show up with the intensity that is most\n"
00934 " visible for the given medium (video or paper). For the defaults, nearly\n"
00935 " identical to KW, or WK for ppm_paper_based_colors.\n\n"
00936
00937 "SpecifiedHue [hue [confidence]]\n"
00938 " Useful for color-coding a plot with a specific hue visible on the default\n"
00939 " background. For paper_based_colors=False, same as ValueColorLookup;\n"
00940 " the confidence is used as the saturation. Such a plot works well for\n"
00941 " showing color on a black background. For paper_based_colors==True,\n"
00942 " returns the specified hue masked by the specified confidence, such\n"
00943 " that low values produce white, and high values produce black for low\n"
00944 " confidences and the specified hue for high confidences. Such a plot\n"
00945 " is good for showing colors on light backgrounds.\n\n"
00946
00947 "MapSpecifiesHue [nameofhuemap [nameofconfidencemap]]\n"
00948 " Neural-region-specific variant of SpecifiedHue where these colorspec\n"
00949 " arguments specify not the actual hue and confidence, but the names of\n"
00950 " registered maps (as in define_plot) in which to look up the hue and\n"
00951 " confidence when plotting. This colorspec can be used by plot_unit or\n"
00952 " plot_unit_range to colorize a plot based on some property of a unit;\n"
00953 " it is not supported in other contexts. Examples:\n"
00954 " Region::Eye0::Afferent0::colorspec='MapSpecifiesHue OrientationPreference OrientationSelectivity'\n"
00955 " Region::Ganglia*::Afferent*::colorspec='MapSpecifiesHue OrientationPreference OrientationSelectivity\n\n"
00956
00957 "SpecifiedColor [hue [saturation [value]]]\n"
00958 " Used to turn off color ranges, e.g. for a plot whose shape is more\n"
00959 " important than the intensity of each pixel, such as a histogram. Ignores\n"
00960 " the level, and always returns the single given fixed color. The default\n"
00961 " color is a medium gray: '0.0 0.0 0.5'. For the defaults, nearly identical\n"
00962 " to 'w'.");
00963
00964 #define PARAM_ARO(bboard,name_str,initial_value,options,doc)\
00965 PARAM_A(bboard,name_str,initial_value,options,doc);\
00966 bboard.lookup(name_str).add_setfn(new setfnobj2_read_only_param_setfn2())
00967
00968 PARAM_ARO(regionparams,"type",string(),,
00969 "Reports the type of this region.");
00970
00971 PARAM_A(regionparams,"height",0,.add_lower_bound(0),
00972 "Reports the number of units in each column of a region.");
00973
00974 PARAM_A(regionparams,"width",0,.add_lower_bound(0),
00975 "Reports the number of units in each row of a region.");
00976
00977 PARAM_A(regionparams,"xoffset",0.5,,
00978 "Reports the horizontal position of the origin of this region.");
00979
00980 PARAM_A(regionparams,"yoffset",0.5,,
00981 "Reports the vertical position of the origin of this region.");
00982
00983
00984 PARAM_A(regionparams,"histo_name",string("OrientationPreference"),,
00985 "When computing a histogram, the name of the map to use when determining the\n"
00986 "bin to which a given unit belongs. At present, the Strength::name for the\n"
00987 "plot which a given histogram accompanies is used for the bin value.");
00988
00989 PARAM_A(regionparams,"histo_colorspec",string("Hue"),,
00990 "Same as colorspec but specific to histogram plots. If this parameter is\n"
00991 "not an empty string, its value is used instead of the value of colorspec\n"
00992 "for a histogram. (Without it, it would be difficult to set the colorspec\n"
00993 "default for all histograms.)");
00994
00995 PARAM_A(regionparams,"num_bins",36,.add_lower_bound(0),
00996 "Number of bins to use in histogram plots.");
00997
00998 PARAM_A(blackboard,"cyclic",True,.add_lower_bound(False).add_upper_bound(True),
00999 "Whether this range or quantity is cyclic, i.e. has upper and lower bounds\n"
01000 "that are identical (like orientation or hue). Being (or not being) cyclic\n"
01001 "is usually most important when we must obtain a number within a specified\n"
01002 "range, when given one that may fall outside of it. If the range is cyclic,\n"
01003 "the values will wrap around to get a result in range; otherwise they will be\n"
01004 "cropped at the ends of the range. It can also affect whether bounds are\n"
01005 "considered exclusive (appropriate for cyclic ranges) or inclusive\n"
01006 "(appropriate for non-cyclic ranges).");
01007
01008 PARAM_A(regionparams,"range_end",0.25,.add_lower_bound(0),
01009 "Upper bound of a 1-dimensional range, e.g. for histogram values.");
01010
01011 PARAM_A(regionparams,"reference",string(),,
01012 "In general, the name of an object to use as a reference. For a map plot,\n"
01013 "the name of a map (in the form region::mapname) to subtract from the current\n"
01014 "Strength map before plotting.");
01015
01016 PARAM_A(regionparams,"vertical",False,.add_lower_bound(False).add_upper_bound(True),
01017 "Determines the orientation of some types of plots, e.g. histograms. If true,\n"
01018 "the image is oriented with the long direction vertically.");
01019
01020 PARAM_A(regionparams,"aspect_ratio",0.25,.add_lower_bound(0),
01021 "Determines the aspect ratio for some types of plots, e.g. histograms. For a\n"
01022 "histogram, the aspect ratio is the ratio between the number of bins and the\n"
01023 "length of the representation to use for the bin fullnesses.");
01024
01025
01026 PARAM_A(blackboard,"name",string(""),,
01027 "A name, as a string. This parameter is used as an argument for commands\n"
01028 "and for e.g. specifying a name for some part of a Region.");
01029
01030 PARAM_A(blackboard,"value_offset",0.0,,
01031 "Offset for a strength or value, e.g. an activity level, as opposed to a\n"
01032 "size_scale. See also value_scale.");
01033
01034 PARAM_A(blackboard,"value_scale",1.0,,
01035 "Scale for a strength or value, e.g. an activity level, as opposed to a\n"
01036 "size_scale. See also value_offset.");
01037
01038 PARAM_A(blackboard,"size_scale",1.0,.add_lower_bound(0.0),
01039 "Scale intended to specify distance or size across the surface of a map,\n"
01040 "as opposed to a value_scale. Most uses of this parameter are overridden\n"
01041 "by ppm_master_scale, which see.\n");
01042
01043 PARAM_A(blackboard,"start_c",-1,.add_lower_bound(-1),
01044 "Number of the column in which to start analysis or plotting.\n"
01045 "See also start_r,end_c,end_r; negative values on any of these\n"
01046 "mean to include all available units.");
01047
01048 PARAM_A(blackboard,"start_r",-1,.add_lower_bound(-1),
01049 "Number of the row in which to start analysis or plotting.\n"
01050 "See also start_c,end_c,end_r; negative values on any of these\n"
01051 "mean to include all available units.");
01052
01053 PARAM_A(blackboard,"end_c",-1,.add_lower_bound(-1),
01054 "Number of the first column not to include in analysis or plotting.\n"
01055 "See also start_c,start_r,end_r; negative values on any of these\n"
01056 "mean to include all available units.");
01057
01058 PARAM_A(blackboard,"end_r",-1,.add_lower_bound(-1),
01059 "Number of the first row not to include in analysis or plotting.\n"
01060 "See also start_c,start_r,end_c; negative values on any of these\n"
01061 "mean to include all available units.");
01062
01063 PARAM_II(PARAM_INT,reversed_color_order,&Plot::HSVPixel<>::reversed_color_order,False,True,
01064 "The hue in HSV-based colors normally goes red->yellow->green->purple->red\n"
01065 "as the numeric hue goes from 0 to 1.0. Some code and publications use the\n"
01066 "reverse order (red->purple->green->yellow->red), and if you want to match\n"
01067 "them, set this parameter to True.");
01068
01069
01070
01071 blackboard.define_param(DECLARE_PARAM(PARAM_INT,"current_ui",true,¤t_ui));
01072 params_define_doc("current_ui",
01073 "Read-only parameter which reports the unit currently being examined;\n"
01074 "see current_region for more details.");
01075 SETFN_DEFINE2(current_ui,read_only_param_setfn2);
01076
01077 blackboard.define_param(DECLARE_PARAM(PARAM_INT,"current_uj",true,¤t_uj));
01078 params_define_doc("current_uj",
01079 "Read-only parameter which reports the unit currently being examined;\n"
01080 "see current_region for more details.");
01081 SETFN_DEFINE2(current_uj,read_only_param_setfn2);
01082
01083 blackboard.define_param(DECLARE_PARAM(PARAM_INT,"current_height",true,¤t_height));
01084 params_define_doc("current_height",
01085 "Read-only parameter which reports the height of the region currently being\n"
01086 "examined; see current_region for more details.");
01087 SETFN_DEFINE2(current_height,read_only_param_setfn2);
01088
01089 blackboard.define_param(DECLARE_PARAM(PARAM_INT,"current_width",true,¤t_width));
01090 params_define_doc("current_width",
01091 "Read-only parameter which reports the width of the region currently being\n"
01092 "examined; see current_region for more details.");
01093 SETFN_DEFINE2(current_width,read_only_param_setfn2);
01094
01095 blackboard.define_param(DECLARE_PARAM(PARAM_USTRING,"current_region",true,¤t_region));
01096 params_define_doc("current_region",
01097 "Read-only parameter which reports the region currently being examined, e.g.\n"
01098 "in weight plots or weight analysis. The current_* parameters can be useful\n"
01099 "for e.g. constructing filenames. At present, their value is only guaranteed\n"
01100 "to be defined during a call to the plot_unit, save_snapshot, and load_snapshot\n"
01101 "commands, and only the relevant ones for each command are updated. When\n"
01102 "not defined, they have clearly undefined values, usually -1 or ''.");
01103 SETFN_DEFINE2(current_region,read_only_param_setfn2);
01104
01105 blackboard.define_param(DECLARE_PARAM(PARAM_USTRING,"current_plot",true,¤t_plot));
01106 params_define_doc("current_plot",
01107 "Read-only parameter which reports the name of the plot currently being\n"
01108 "constructed, if any; see current_region for more details. The name is\n"
01109 "the name of the current PlotGroup except while constructing a specific\n"
01110 "plot, in which case it is the name of that particular plot.");
01111 SETFN_DEFINE2(current_plot,read_only_param_setfn2);
01112
01113
01114
01115 PARAM_I(PARAM_INT, plot_pe,Uninitialized,NPES-1,
01116 "PE which plots data, e.g. for the plot command. By default only a single\n"
01117 "PE plots the data, but when debugging on multiple-PE machines, sometimes\n"
01118 "it is helpful to get plots from every PE (if plot_pe == Uninitialized)\n"
01119 "or just a different PE than usual. This can help e.g. verify that\n"
01120 "each PE has identical copies of global arrays.");
01121 }
01122
01123
01124
01125
01126
01127 void NeuralRegionMap::activate(bool learn, bool settle, bool activatefn, bool verbose) const
01128 {
01129
01130
01131 RegionManagerList regions = retrieve_matching_regions(*params,"activation_order",false);
01132
01133
01134 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
01135 message((verbose? Msg::Notify : Msg::Verbose), "Activating " + (*r)->region()->name());
01136 (*r)->region()->activate(learn,settle,activatefn);
01137 }
01138 }
01139
01140
01141
01143 cmdstat NeuralRegionMap::cmd_plot_unit( CMD_ARGS )
01144 {
01145 CMD_ARG_PARAMS(plot_unit);
01146
01147 const string plotgroup = argparams.get_with_default("plotgroup",string("Weights"));
01148 const string default_region = argparams.get_with_default("default_region",string(""));
01149 const string specified_region = argparams.get_with_default("region",string(""));
01150 const string regionname = (specified_region!=""? specified_region : default_region);
01151
01152 const NeuralRegionManager* rm = lookup_internal_region(regionname);
01153 if (!rm) return CMD_PARAMETER_ERROR;
01154
01155 if (plotgroup!="Weights")
01156 message(Msg::Warning, "The plot_unit command only supports a <plotgroup> of Weights.");
01157
01158
01159 int beenthrough=false;
01160 bool statusok=true;
01161 for (; (!arglist.empty()||!beenthrough); ) {
01162 define_globals(rm,Uninitialized,Uninitialized,plotgroup);
01163 const bool numargsisodd=arglist.oneremaining();
01164 const int ui=arglist.next(rm->default_ui());
01165 const int uj=arglist.next(rm->default_uj());
01166
01167
01168 if (numargsisodd) {
01169 message(Msg::Error, "Wrong number of arguments to plot_unit");
01170 return CMD_PARAMETER_ERROR;
01171 }
01172 define_globals(rm,ui,uj,plotgroup);
01173
01174
01175
01176
01177
01178
01179
01180 if (plot_pe==Uninitialized || MyPE==plot_pe) {
01181 message(Msg::Notify, "Plotting weights for " +
01182 rm->region()->name() + " unit (" +
01183 String::stringrep(ui) + "," +
01184 String::stringrep(uj) + ")");
01185
01186 const bool newstatus = plot_write_unit(argparams, rm, ui, uj);
01187 if (!newstatus) statusok=false;
01188 }
01189
01190 beenthrough=true;
01191 }
01192 define_globals();
01193
01194 CMD_ARG_ASSERT_EMPTY;
01195 return (statusok ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
01196 }
01197
01198
01199
01200
01203 const NeuralRegionManager* NeuralRegionMap::lookup_region(const string& name) const
01204 {
01205 const NeuralRegionManager* rm = getptr(name);
01206
01207 if (!rm) {
01208 message(Msg::Error, "Region '" + name + "' not found");
01209 return 0;
01210 }
01211 return rm;
01212 }
01213
01214
01215
01218 const NeuralRegionManager* NeuralRegionMap::lookup_internal_region(const string& name) const
01219 {
01220 const NeuralRegionManager* rm = lookup_region(name);
01221
01222 if (rm && !rm->internalregion()) {
01223 message(Msg::Error, "Region '" + name + "' has no weights");
01224 return 0;
01225 }
01226 return rm;
01227 }
01228
01229
01230
01232 cmdstat NeuralRegionMap::cmd_plot_unit_range( CMD_ARGS )
01233 {
01234 CMD_ARG_PARAMS(plot_unit_range);
01235
01236 const string plotitem = argparams.get_with_default("name",string(""));
01237 const string default_region = argparams.get_with_default("default_region",string(""));
01238 const string specified_region=argparams.get_with_default("region",string(""));
01239 const string regionname = (specified_region!=""? specified_region : default_region);
01240 const bool verbose = argparams.get_with_default("verbose",True);
01241 int ui_start = arglist.next(argparams.get_with_default("start_r", -1));
01242 int uj_start = arglist.next(argparams.get_with_default("start_c", -1));
01243 int ui_end = arglist.next(argparams.get_with_default("end_r", -1));
01244 int uj_end = arglist.next(argparams.get_with_default("end_c", -1));
01245 int step = arglist.next(argparams.get_with_default("ppm_neuron_skip_aff",1));
01246
01247 const NeuralRegionManager* rm = lookup_internal_region(regionname);
01248 if (!rm) return false;
01249
01250 const int nrows = rm->region()->nrows();
01251 const int ncols = rm->region()->ncols();
01252
01253 if (ui_start<0) ui_start=0; if (ui_end<0) ui_end = nrows;
01254 if (uj_start<0) uj_start=0; if (uj_end<0) uj_end = ncols;
01255 if (step<1) step=1;
01256
01257 ui_start = Generic::crop(0,nrows,ui_start);
01258 ui_end = Generic::crop(0,nrows,ui_end);
01259 uj_start = Generic::crop(0,nrows,uj_start);
01260 uj_end = Generic::crop(0,nrows,uj_end);
01261
01262
01263 WorldViews::set_current_eye(String::numeric_extension<int>(plotitem));
01264
01265 message((verbose? Msg::Notify : Msg::Verbose), "Plotting " + rm->region()->name() + "::" + plotitem);
01266
01267 const bool status = plot_write_unit_range(argparams,rm,plotitem,ui_start,uj_start,ui_end,uj_end,step);
01268 define_globals();
01269
01270 CMD_ARG_ASSERT_EMPTY;
01271 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
01272 }
01273
01274
01275
01277 cmdstat NeuralRegionMap::cmd_plot( CMD_ARGS )
01278 {
01279 CMD_ARG_PARAMS(plot);
01280
01281 if (plot_pe!=Uninitialized && MyPE!=plot_pe)
01282 return true;
01283
01284
01285 ImagePListList imagelists;
01286
01287 const string plotgroup_ = arglist.next(argparams.get_with_default("plotgroup",string("")));
01288 const string plotgroup = (plotgroup_!=""? plotgroup_ : argparams.get_with_default("plotgroup",string("Activity")));
01289 const string suppliedformat = argparams.get_with_default("filename_format",string(""));
01290 const bool verbose = argparams.get_with_default("verbose",True);
01291 const bool save_matrices = argparams.get_with_default("save_matrices",False);
01292 const bool gnuplot_plots = argparams.get_with_default("gnuplot_plots",False);
01293 const bool ppm_plots = argparams.get_with_default("ppm_plots",True);
01294 const bool separate_plots = argparams.get_with_default("ppm_separate_plots",True);
01295 const bool combined_plots = argparams.get_with_default("ppm_combined_plots",True);
01296 const bool histograms = argparams.get_with_default("ppm_histograms",True);
01297 const bool mainplot = argparams.get_with_default("ppm_mainplot",True);
01298 const double master_scale = argparams.get_with_default("ppm_master_scale", double(Uninitialized));
01299
01300 const double interior_b = argparams.get_with_default("ppm_interior_border",1.0);
01301 const int interior_border= (interior_b>=0? int(interior_b) : std::max(2,int(-interior_b*min_of_max_dimensions())));
01302 const Color pagecolor = lookup_param(argparams, "ppm_page", Color());
01303 bool status=true;
01304
01305 SpecRegion maxregion = max_subregion();
01306
01307 RegionManagerList regions = retrieve_matching_regions(*params,"activation_order",false);
01308
01309
01310
01311 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
01312 NeuralRegionManager* rm = (*r);
01313
01314 for (NeuralRegionManager::PlotSpecList::const_iterator pi=rm->plotspeclist_begin(plotgroup);
01315 pi!=rm->plotspeclist_end(plotgroup); pi++) {
01316
01317 define_globals(rm,Uninitialized,Uninitialized,(*pi)->name());
01318
01319
01320
01321
01322 const string ref_path_name = (*pi)->lookup_param("Strength::reference",string());
01323 NeuralRegionManager::PlotSpec::MatrixTable tempmaps;
01324
01325 message((verbose? Msg::Notify : Msg::Verbose), "Plotting " + (*pi)->objectname() + "::" + (*pi)->name() +
01326 (ref_path_name=="" ? string() : " relative to " + ref_path_name));
01327
01328 if (ref_path_name!="") {
01329 const PathSpecification referencepath(ref_path_name);
01330 const NeuralRegionManager* ref_rm = getptr(referencepath.first());
01331 const NeuralRegion::MapBaseType* ref_map =
01332 (!ref_rm? 0 : ref_rm->region()->table().getptr(referencepath.last()));
01333 if (referencepath.all().size()!=2 || !ref_map)
01334 message(Msg::Error, "Invalid reference path: " + ref_path_name);
01335 else {
01336 typedef mat::MatrixInterfaceAdapter<NeuralRegion::MapBaseType> MatAdapter;
01337 tempmaps.set("__StrengthReference",new MatAdapter(*ref_map));
01338 }
01339 }
01340
01341 if (gnuplot_plots) {
01342 if (!gnuplot_image(argparams,**pi,filenamebase(plotgroup,suppliedformat),&tempmaps,
01343 lookup_subregion((**pi).param_map(),SpecRegion())))
01344 status=false;
01345 }
01346
01347 if (save_matrices) {
01348 const SpecRegion& region = lookup_subregion((**pi).param_map(),SpecRegion());
01349 if (!((*pi)->save_matrix(filenamebase(plotgroup,suppliedformat),&tempmaps,
01350 ®ion)))
01351 status=false;
01352 }
01353
01354
01355
01356
01357
01358
01359
01360 if (ppm_plots) {
01361
01362 ImagePList* li = new ImagePList;
01363
01364
01365 if (mainplot) {
01366 Plot::AARImage<>* img = (*pi)->bitmap_image(master_scale,&maxregion,&tempmaps);
01367 if (img) {
01368 if (combined_plots) li->push_back(img);
01369 if (separate_plots) ppm_write_to_file(filenamebase(plotgroup,suppliedformat),*img);
01370 }
01371 }
01372
01373
01374 if (histograms) {
01375 Plot::AARImage<>* histoimg =
01376 (*pi)->bitmap_histogram(master_scale,blackboard.lookup_map("::PlotGroup::Histogram"),&maxregion,&tempmaps);
01377 if (histoimg) {
01378 if (combined_plots) li->push_back(histoimg);
01379 if (separate_plots) ppm_write_to_file(filenamebase(plotgroup,suppliedformat)+"_Histogram",*histoimg);
01380 }
01381 }
01382
01383
01384 if (li->empty())
01385 delete li;
01386 else
01387 imagelists.push_back(li);
01388 }
01389 }
01390 }
01391
01392 define_globals(0,Uninitialized,Uninitialized,plotgroup);
01393 if (ppm_plots && combined_plots)
01394 status = ppmgrid_write(filenamebase(plotgroup,suppliedformat),
01395 imagelists,interior_border,pagecolor);
01396 Generic::nested_delete_contents(imagelists);
01397 define_globals();
01398
01399 CMD_ARG_ASSERT_EMPTY;
01400 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
01401 }
01402
01403
01404
01407 const bool NeuralRegionMap::add_maps_for_unit(NeuralRegionManager::PlotSpec::MatrixTable& tempmaps,
01408 const NeuralRegionManager& rm,
01409 const NeuralRegionManager::PlotSpec& plotspec,
01410 const int ui, const int uj) const
01411 {
01412 const string ref_path_name = plotspec.lookup_param("Strength::reference",string());
01413 if (!rm.add_maps_for_unit(tempmaps,plotspec,ui,uj))
01414 return false;
01415
01416
01417
01418
01419 if (ref_path_name!="") {
01420 const PathSpecification referencepath(ref_path_name);
01421 const NeuralRegionManager* ref_rm = getptr(referencepath.first());
01422 if (referencepath.all().size()!=2 || !ref_rm) {
01423 message(Msg::Error, "Invalid reference path: " + ref_path_name);
01424 return false;
01425 }
01426 else
01427 return ref_rm->add_maps_for_unit(tempmaps,referencepath.last(),
01428 "__StrengthReference",plotspec,ui,uj);
01429 }
01430
01431 return true;
01432 }
01433
01434
01445 const string NeuralRegionMap::overriding_colorspec
01446 (const NeuralRegionManager* rm, int ui, int uj, const string colorspec) const
01447 {
01448 typedef const NeuralRegion::MapBaseType* mapptr;
01449 StringParser sp;
01450 StringArgs specargs(sp, colorspec);
01451 const bool override_colorspec = (specargs.next(string(""))=="MapSpecifiesHue");
01452 const mapptr colorizingmap = !override_colorspec? 0 : rm->region()->table().getptr(specargs.next(string("")));
01453 const mapptr confidencizingmap = !override_colorspec? 0 : rm->region()->table().getptr(specargs.next(string("")));
01454 return
01455 (!override_colorspec? "" :
01456 ("SpecifiedHue" +
01457 (!colorizingmap? "" : " " + String::stringrep(mat::elem(*colorizingmap,ui,uj))) +
01458 (!confidencizingmap? "" : " " + String::stringrep(mat::elem(*confidencizingmap,ui,uj)))));
01459 }
01460
01461
01462
01463 const bool NeuralRegionMap::plot_write_unit
01464 (const ParamMap& argparams, const NeuralRegionManager* rm,
01465 const int ui, const int uj) const
01466 {
01467
01468 ImagePListList imagelists;
01469
01470 const string plotgroup = argparams.get_with_default("plotgroup",string(""));
01471 const string suppliedformat = argparams.get_with_default("filename_format",string(""));
01472 const bool verbose = argparams.get_with_default("verbose",True);
01473 const bool situate = argparams.get_with_default("weight_situate",True);
01474 const bool gnuplot_plots = argparams.get_with_default("gnuplot_plots",False);
01475 const bool ppm_plots = argparams.get_with_default("ppm_plots",True);
01476 const bool separate_plots = argparams.get_with_default("ppm_separate_plots",True);
01477 const bool combined_plots = argparams.get_with_default("ppm_combined_plots",True);
01478 const bool histograms = argparams.get_with_default("ppm_histograms",True);
01479 const bool mainplot = argparams.get_with_default("ppm_mainplot",True);
01480 const double master_scale = argparams.get_with_default("ppm_master_scale", double(Uninitialized));
01481
01482 const double interior_b = argparams.get_with_default("ppm_interior_border",1.0);
01483 const int interior_border= (interior_b>=0? int(interior_b) : std::max(2,int(-interior_b*min_of_max_dimensions())));
01484 const Color pagecolor = lookup_param(argparams, "ppm_page", Color());
01485 bool status=true;
01486
01487 PlotSpecList plots = retrieve_matching_plots
01488 (rm->plotspeclist_begin(plotgroup), rm->plotspeclist_end(plotgroup),
01489 params->get_with_default("connection_order",string("")));
01490
01491 for (PlotSpecList::const_iterator pi=plots.begin(); pi!=plots.end(); pi++) {
01492 define_globals(rm,ui,uj,(*pi)->name());
01493
01494
01495 const bool draw_outline = (*pi)->lookup_param("ppm_outline_weights", False);
01496 const int outline_width = (*pi)->lookup_param("ppm_outline_width", 1);
01497 const string ref_path_name = (*pi)->lookup_param("Strength::reference",string());
01498 const string colorspec = (*pi)->lookup_param("colorspec",string());
01499
01500
01501 NeuralRegionManager::PlotSpec::MatrixTable tempmaps;
01502 if (!add_maps_for_unit(tempmaps,*rm,**pi,ui,uj)) {
01503 define_globals();
01504 return false;
01505 }
01506
01507 message((verbose? Msg::Notify : Msg::Verbose), "Plotting " + rm->internalregion()->name() + "::" + (*pi)->name() +
01508 (ref_path_name=="" ? string() : " relative to " + ref_path_name));
01509
01510
01511 if (gnuplot_plots) {
01512 if (unit_gnuplot(argparams,**pi,filenamebase(plotgroup,suppliedformat),&tempmaps,
01513 rm->internalregion()->weights((*pi)->name(),ui,uj).bounds(),situate))
01514 status=false;
01515 }
01516
01517 if (ppm_plots) {
01518 ImagePList* li = new ImagePList;
01519 unit_bitmap(master_scale,*li,**pi,&tempmaps,
01520 rm->internalregion()->weights((*pi)->name(),ui,uj).bounds(),
01521 pagecolor,draw_outline,outline_width,situate,mainplot,
01522 separate_plots,combined_plots,
01523 filenamebase(plotgroup,suppliedformat),histograms,
01524 -1,false,overriding_colorspec(rm,ui,uj,colorspec));
01525
01526
01527 if (li->empty())
01528 delete li;
01529 else
01530 imagelists.push_back(li);
01531 }
01532 }
01533
01534 define_globals(rm,ui,uj,plotgroup);
01535 if (ppm_plots && combined_plots)
01536 status = ppmgrid_write(filenamebase(plotgroup,suppliedformat),
01537 imagelists,interior_border,pagecolor);
01538 Generic::nested_delete_contents(imagelists);
01539
01540 define_globals();
01541 return status;
01542 }
01543
01544
01545
01546 const bool NeuralRegionMap::plot_write_unit_range
01547 (const ParamMap& argparams, const NeuralRegionManager* rm,
01548 const string& plotitem, int ui_start, int uj_start, int ui_end, int uj_end, int step) const
01549 {
01550
01552 #if (NPES>1)
01553 if (NPEs>1) {
01554 message(Msg::Error, "plot_write_unit_range is not supported on multi-PE systems");
01555 return false;
01556 }
01557 #endif
01558
01559
01560 ImagePListList imagelists;
01561
01562 const string plotgroup = argparams.get_with_default("plotgroup",string(""));
01563 const bool ppm_plots = argparams.get_with_default("ppm_plots",True);
01564 const bool separate_plots = argparams.get_with_default("ppm_separate_plots",True);
01565 const bool combined_plots = argparams.get_with_default("ppm_combined_plots",True);
01566 const bool situate = argparams.get_with_default("weight_situate", False);
01567 const bool bare = argparams.get_with_default("weight_bare", True);
01568 const bool fill_bg = argparams.get_with_default("weight_fill_background", False);
01569 const bool showinterior = argparams.get_with_default("ppm_interior_outline", False);
01570 const Color pagecolor = lookup_param(argparams, (!showinterior && !fill_bg? "ppm_line" : "ppm_page"), Color());
01571 const bool histograms = argparams.get_with_default("ppm_histograms",True);
01572 const bool mainplot = argparams.get_with_default("ppm_mainplot",True);
01573 const double master_scale = argparams.get_with_default("ppm_master_scale", double(Uninitialized));
01574 const string suppliedformat = argparams.get_with_default("filename_format",string(""));
01575 const double interior_b = argparams.get_with_default("ppm_interior_border",1.0);
01576 const int interior_border= (interior_b>=0? int(interior_b) : std::max(2,int(-interior_b*min_of_max_dimensions())));
01577
01578
01579 for (int ui=ui_start; ui<ui_end; ui+=step) {
01580 ImagePList* li = new ImagePList;
01581 for (int uj=uj_start; uj<uj_end; uj+=step) {
01582 for (NeuralRegionManager::PlotSpecList::const_iterator pi=rm->plotspeclist_begin(plotgroup);
01583 pi!=rm->plotspeclist_end(plotgroup); pi++)
01584 if (String::glob_match(plotitem,(*pi)->name())) {
01585 define_globals(rm,ui,uj,(*pi)->name());
01586
01587
01588 NeuralRegionManager::PlotSpec::MatrixTable tempmaps;
01589 if (!add_maps_for_unit(tempmaps,*rm,**pi,ui,uj))
01590 return false;
01591
01592
01593 const bool draw_outline = (bare? False : (*pi)->lookup_param("ppm_outline_weights", False));
01594 const int outline_width = (bare? 0 : (*pi)->lookup_param("ppm_outline_width", 1));
01595 const int border_width = (bare? 0 : (*pi)->lookup_param("ppm_border", 1));
01596 const string colorspec = (*pi)->lookup_param("colorspec",string());
01597
01598
01599 if (ppm_plots)
01600 unit_bitmap(master_scale,*li,**pi,&tempmaps,
01601 rm->internalregion()->weights((*pi)->name(),ui,uj).bounds(),
01602 pagecolor,draw_outline,outline_width,situate,
01603 mainplot,separate_plots,combined_plots,
01604 filenamebase(plotgroup,suppliedformat),
01605 histograms,border_width,fill_bg,
01606 overriding_colorspec(rm,ui,uj,colorspec));
01607 }
01608 }
01609
01610
01611 if (li->empty())
01612 delete li;
01613 else
01614 imagelists.push_back(li);
01615 }
01616
01617 define_globals(rm,Uninitialized,Uninitialized,plotgroup);
01618 bool status=true;
01619 if (ppm_plots && combined_plots)
01620 status = ppmgrid_write(filenamebase(plotgroup+"Map",suppliedformat),
01621 imagelists,interior_border,pagecolor,false);
01622 Generic::nested_delete_contents(imagelists);
01623
01624 return status;
01625 }
01626
01627
01628
01630 bool NeuralRegionMap::unit_gnuplot(const ParamMap& argparams,
01631 NeuralRegionManager::PlotSpec& plotspec,
01632 const string& filebase,
01633 const NeuralRegionManager::PlotSpec::MatrixTable* tempmaps,
01634 const InternalNeuralRegion::WeightBounds& bounds,
01635 bool situate) const
01636 {
01637 SpecRegion region = (situate? lookup_subregion(plotspec.param_map(),SpecRegion()) :
01638 weightbounds_to_subregion<SpecRegion>(bounds.aarectangle()));
01639 return gnuplot_image(argparams,plotspec,filebase,tempmaps,region);
01640 }
01641
01642
01643
01644
01646 bool NeuralRegionMap::unit_bitmap(const double master_scale, ImagePList& imagelist,
01647 const NeuralRegionManager::PlotSpec& plotspec,
01648 const NeuralRegionManager::PlotSpec::MatrixTable* tempmaps,
01649 const InternalNeuralRegion::WeightBounds& bounds,
01650 const Color& pagecolor,
01651 bool draw_outline, int outline_width,
01652 bool situate, bool mainplot, bool separate_plots,
01653 bool combined_plots, const string& filebase,
01654 bool histograms, int border_width, bool fill_bg,
01655 const string& overriding_colorspec) const
01656 {
01657 SpecRegion maxregion = max_subregion();
01658 SpecRegion region = (situate? lookup_subregion(plotspec.param_map(),SpecRegion()) :
01659 weightbounds_to_subregion<SpecRegion>(bounds.aarectangle()));
01660
01661
01662 if (mainplot) {
01663 Plot::MatrixImage<>* img = plotspec.bitmap_image(master_scale,&maxregion,tempmaps,®ion,border_width,overriding_colorspec);
01664 if (!img) return false;
01665
01666
01667 if (draw_outline || fill_bg) {
01668 InternalNeuralRegion::WeightBounds* wtbounds = bounds.clone();
01669 if (!region.isinfinite())
01670 wtbounds->translate(int(region.corners().yl),int(region.corners().xl));
01671 if (fill_bg)
01672 img->outline_boundary(*wtbounds,outline_width,pagecolor,fill_bg);
01673 else
01674 img->outline_boundary(*wtbounds,outline_width);
01675 delete wtbounds;
01676 }
01677
01678
01679 if (combined_plots) imagelist.push_back(img);
01680 if (separate_plots) ppm_write_to_file(filebase,*img);
01681 }
01682
01683
01684 if (histograms) {
01685 Plot::AARImage<>* histoimg =
01686 plotspec.bitmap_histogram(master_scale,blackboard.lookup_map("::PlotGroup::Histogram"),&maxregion,tempmaps);
01687 if (histoimg) {
01688 if (combined_plots) imagelist.push_back(histoimg);
01689 if (separate_plots) ppm_write_to_file(filebase+"_Histogram",*histoimg);
01690 }
01691 }
01692
01693 return true;
01694 }
01695
01696
01697
01699 const bool NeuralRegionMap::ppmgrid_write(const string& filebase,
01700 const ImagePListList& imagelists, int interior_border,
01701 const Color& pagecolor, bool column_major) const
01702 {
01703
01704 if (imagelists.empty()) {
01705 message(Msg::Warning, "Skipping empty image");
01706 return false;
01707 }
01708
01709
01710 typedef MatrixType<Plot::AARImage<>* >::rectangular MatrixOfImagePointers;
01711 const MatrixOfImagePointers moi =
01712 mat::matrix_from_nested_containers
01713 <MatrixOfImagePointers,ImagePList>(imagelists,column_major);
01714
01715 const string filename = filebase + ".ppm";
01716 {
01717 Plot::ImagePointerGrid<> img(moi,interior_border,interior_border,pagecolor);
01718 std::ofstream os(filename.c_str() BINARY_FILE_FLAGS);
01719 img.ppm_write(os,filename,(unsigned char)(255));
01720 }
01721 ppm_post_write_hook( filename.c_str() );
01722
01723 return true;
01724 }
01725
01726
01727
01732 bool NeuralRegionMap::define_plotgroup(const string plotgroup, const string filename_format)
01733 {
01734 const string format = (filename_format!=""? filename_format :
01735 blackboard.get_with_default("default_filename_format",string("file")));
01736 BlackboardType& plotgroups = blackboard.lookup_map("::PlotGroup");
01737 BlackboardType& plotgroupparams= plotgroups.lookup_map(plotgroup,false);
01738 const bool alreadyexists = (&plotgroupparams != &plotgroups);;
01739 BlackboardType* paramsptr = (alreadyexists ? &plotgroupparams :
01740 plotgroups.new_child(plotgroup,true));
01741
01742 if (filename_format!="" || !alreadyexists)
01743 paramsptr->set_local("filename_format",format);
01744
01745 return !alreadyexists;
01746 }
01747
01748
01750 cmdstat NeuralRegionMap::cmd_define_plot( CMD_ARGS )
01751 {
01752 CMD_ARG_PARAMS(define_plot);
01753 bool status=true;
01754 const string strength = arglist.next(string(""));
01755 const string color = arglist.next(string(""));
01756 const string confidence = arglist.next(string(""));
01757
01758 const string specified_name = argparams.get_with_default("name",string(""));
01759 const string name = (specified_name!=""? specified_name :
01760 (strength!=""? strength :
01761 (color!=""? color : confidence)));
01762
01763 const string specified_type = argparams.get_with_default("plotgroup",string(""));
01764 const string plotgroup = (specified_type!="" ? specified_type : name);
01765 const string format = argparams.get_with_default("filename_format",string(""));
01766
01767
01768 if (name=="") {
01769 message(Msg::Error, "Skipping plot definition; no name was specified");
01770 return CMD_PARAMETER_ERROR;
01771 }
01772
01773
01774 define_plotgroup(plotgroup,format);
01775
01776
01777 RegionManagerList regions = retrieve_matching_regions(argparams);
01778 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++)
01779 (*r)->define_plot(plotgroup,name,strength,color,confidence);
01780
01781 CMD_ARG_ASSERT_EMPTY;
01782 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
01783 }
01784
01785
01786
01788 cmdstat NeuralRegionMap::cmd_measure_stimulus_map( CMD_ARGS )
01789 {
01790 CMD_ARG_PARAMS(measure_stimulus_map);
01791 const bool status = measure_stimulus_map(arglist,argparams);
01792 CMD_ARG_ASSERT_EMPTY;
01793 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
01794 }
01795
01796
01797
01800 template<class LoopContainer, class UpdatableObjectContainer>
01801 class NeuralRegionMap::measure_stimulus_map_iteration {
01802 public:
01803
01810 measure_stimulus_map_iteration(const string& input_command_,
01811 const LoopContainer& loops_,
01812 const UpdatableObjectContainer& spmrs_)
01813 : input_command(input_command_), loops(loops_), spmrs(spmrs_) { };
01814
01816 void operator() () {
01817
01818 string variables;
01819 for (typename LoopContainer::const_iterator i=loops.begin(); i!=loops.end(); i++) {
01820 variables += " " + String::stringrep(**i);
01821 blackboard.lookup((*i)->name()).datavalue().set(Polymorph<double>((*i)->value()));
01822 }
01823 message(Msg::Notify, "Setting variables:" + variables);
01824
01825
01826 cmddefs_exec_str(input_command.c_str());
01827
01828
01829 for (typename UpdatableObjectContainer::const_iterator si=spmrs.begin(); si!=spmrs.end(); si++)
01830 (*si)->update();
01831 }
01832
01833 private:
01834 const string& input_command;
01835 const LoopContainer& loops;
01836 const UpdatableObjectContainer& spmrs;
01837 };
01838
01839
01842 template<class T1, class T2>
01843 T1 accum_num_calls(const T1& accum, const T2* p)
01844 { return accum*p->num(); }
01845
01846
01847
01848
01850 const bool NeuralRegionMap::measure_stimulus_map(StringArgs& arglist, ParameterMap<>& argparams)
01851 {
01852 typedef double VType;
01853 typedef ValueGenerator<VType> VGenerator;
01854 typedef LoopSpec<VType> Loop;
01855 typedef std::vector<Loop*> Loops;
01856 typedef StimulusParameterMapsForRegion<const NeuralRegion::ActivityMatrix, NeuralRegion::MapBaseType, Loop> SPMR;
01857 typedef std::vector<SPMR*> SPMRs;
01858 typedef SPMR::ScaleType Scale;
01859
01860 const string input_command = arglist.next(string(""));
01861 RegionManagerList regions = retrieve_matching_regions(argparams);
01862
01863 SPMRs spmrs;
01864
01866 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++)
01867 spmrs.push_back(new SPMR(*r));
01868
01869
01871 Loops loops;
01872 DistributedValueGeneratorFactory<VType> vgf;
01873 while (!arglist.empty()) {
01874 StringArgs dimensionargs=arglist.recursiveparser();
01875
01876
01877 ParameterMap<> subargparams(&argparams);
01878 cmdparams_set(subargparams,dimensionargs,true,false,false);
01879
01880
01881 const string name = dimensionargs.next(subargparams.get_with_default("name",string("")));
01882 const int divisions = dimensionargs.next(subargparams.get_with_default("divisions",1));
01883
01884 const bool registermap = subargparams.get_with_default("register",False);
01885 const bool weighted_average = subargparams.get_with_default("weighted_average",False);
01886 const bool measure_distribution = subargparams.get_with_default("measure_distribution",True);
01887 const int specified_num_bins = subargparams.get_with_default("num_bins",-1);
01888 const Scale selectivity_scale = Scale(subargparams.get_with_default("selectivity_scale",1.0));
01889 const bool cyclic = subargparams.get_with_default("cyclic",True);
01890 const bool discrete_inputs = subargparams.get_with_default("discrete_inputs",True);
01891 const int num_bins = (specified_num_bins>0? specified_num_bins :
01892 (cyclic? divisions : divisions+1));
01893 const int discrete_levels = (discrete_inputs? divisions : -1 );
01894 const string varname = subargparams.get_with_default("varname",string(""));
01895 const string loopspecname = (varname!=""? varname : name);
01896 const string valuegenspec = subargparams.get_with_default("valuegenerator",string(""));
01897 StringArgs valuegenargs = dimensionargs.recursiveparser(valuegenspec);
01898 VGenerator* valuegen = (valuegenargs.empty()? 0 : vgf.create(valuegenargs));
01899
01900 Loop* lp = new Loop(loopspecname,divisions,cyclic,valuegen,discrete_levels);
01901 loops.push_back(lp);
01902
01903
01904 if (registermap) {
01905 if (num_bins>0)
01906 for (SPMRs::iterator s=spmrs.begin(); s!=spmrs.end(); s++)
01907 (*s)->create_spm(name,*lp,num_bins,measure_distribution,weighted_average,cyclic,selectivity_scale);
01908 else
01909 message(Msg::Warning, "Can't register a map for " + name +
01910 " because it has no valid values (num_bins==" + String::stringrep(num_bins) +")");
01911 }
01912 }
01913
01914
01915 const int num_loop_iterations = std::accumulate(ISEQ(loops),1,&accum_num_calls<int,Loop>);
01916 message(Msg::Notify, "Presenting " + String::stringrep(num_loop_iterations) + " inputs");
01917
01918
01919 measure_stimulus_map_iteration<Loops,SPMRs> iteration(input_command,loops,spmrs);
01920 LoopSpecs_ExecuteNested(loops, loops.begin(), iteration);
01921
01922
01923 for (SPMRs::iterator s=spmrs.begin(); s!=spmrs.end(); s++) {
01924 const string warning = (*s)->register_maps();
01925 if (warning!="") message(Msg::Warning, warning);
01926 }
01927
01928 Generic::delete_contents(loops);
01929 Generic::delete_contents(spmrs);
01930
01931 return true;
01932 }
01933
01934
01938 cmdstat NeuralRegionMap::cmd_save_snapshot( CMD_ARGS )
01939 {
01940 CMD_ARG_PARAMS(save_snapshot);
01941 const string plotgroup = "SavedState";
01942 const string filename_format = arglist.next(argparams.get_with_default("filename",string()));
01943 RegionManagerList regions = retrieve_matching_regions(argparams);
01944 const bool verbose = argparams.get_with_default("verbose",True);
01945
01946 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
01947 message((verbose? Msg::Notify : Msg::Verbose), "Saving state of " + (*r)->region()->name());
01948 define_globals(*r,Uninitialized,Uninitialized,plotgroup);
01949 (*r)->region()->save_state(filenamebase(plotgroup,filename_format));
01950 define_globals();
01951 }
01952
01953 CMD_ARG_ASSERT_EMPTY;
01954 return CMD_NO_ERROR;
01955 }
01956
01957
01958
01959
01960
01967 bool NeuralRegionMap::restore_state(const ParamMap& argparams,
01968 const int iteration, const string& filename)
01969 {
01970 RegionManagerList regions = retrieve_matching_regions(argparams);
01971 const string plotgroup = "SavedState";
01972 const bool verbose = argparams.get_with_default("verbose",True);
01973 bool status=false;
01974
01975 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
01976 message((verbose? Msg::Notify : Msg::Verbose), "Restoring state of " + (*r)->region()->name());
01977 define_globals(*r,Uninitialized,Uninitialized,plotgroup);
01978 const bool newstatus = (*r)->region()->
01979 restore_state(iteration,filenamebase(plotgroup,filename));
01980 if (newstatus) status=true;
01981 define_globals();
01982 }
01983
01984 return status;
01985 }
01986
01987
01988
01989 cmdstat NeuralRegionMap::cmd_kill_connections( CMD_ARGS )
01990 {
01991 CMD_ARG_PARAMS(kill_connections);
01992 RegionManagerList regions = retrieve_matching_regions(argparams);
01993 const bool verbose = argparams.get_with_default("verbose",True);
01994
01995 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
01996 message((verbose? Msg::Notify : Msg::Verbose), "Killing connections in " + (*r)->region()->name());
01997 (*r)->region()->prune();
01998 }
01999
02000 CMD_ARG_ASSERT_EMPTY;
02001 return CMD_NO_ERROR;
02002 }
02003
02004
02005 cmdstat NeuralRegionMap::cmd_map_statistics( CMD_ARGS )
02006 {
02007 CMD_ARG_PARAMS(map_statistics);
02008
02009 const string mapname = arglist.next(argparams.get_with_default("name",string("")));
02010
02011
02012
02013
02014 const int divisions = 1;
02015 const int spec_num_bins = argparams.get_with_default("num_bins",1);
02016 const bool cyclic = argparams.get_with_default("cyclic",True);
02017 const int num_bins = (spec_num_bins>0? spec_num_bins :
02018 (cyclic? divisions : divisions+1));
02019 const bool verbose = argparams.get_with_default("verbose",True);
02020 const bool reset = argparams.get_with_default("reset",False);
02021 const bool cumulative = argparams.get_with_default("cumulative",False);
02022 const bool horizontal = argparams.get_with_default("horizontal",True);
02023 const string label = argparams.get_with_default("label",string());
02024 const bool kurtosis = argparams.get_with_default("kurtosis",False);
02025 const bool min_max = argparams.get_with_default("min_max",False);
02026 const string lineend = label+"\n";
02027
02028 RegionManagerList regions = retrieve_matching_regions(argparams);
02029
02030 static double cumulative_sum = 0;
02031 static int cumulative_count= 0;
02032
02033 if (reset) {
02034 cumulative_sum=0;
02035 cumulative_count=0;
02036 return CMD_NO_ERROR;
02037 }
02038
02039
02040 typedef String::StreamFormat SF;
02041 SF magsf (13,' ', 2,true );
02042 SF headsf(13,'_',-1,false);
02043 SF strsf (14,' ',-1,false);
02044 const string header = String::stringrep("",headsf);
02045
02046
02047
02048 if (cumulative_count==0 || verbose) {
02049 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
02050 message(Msg::Requested,
02051 String::stringrep("Region", strsf) +
02052 String::stringrep("Map", strsf) +
02053 String::stringrep("Sum", strsf) +
02054 (cumulative?
02055 String::stringrep("CumulativeAvg", strsf) : "") +
02056 (min_max?
02057 String::stringrep("Min", strsf) +
02058 String::stringrep("Max", strsf) : "") +
02059 (kurtosis?
02060 String::stringrep("Kurtosis", strsf) : "") +
02061 " ",false);
02062 if (!horizontal) break;
02063 }
02064 message(Msg::Requested,"\n",false);
02065
02066 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
02067 message(Msg::Requested,
02068 String::stringrep(header.c_str(), strsf) +
02069 String::stringrep(header.c_str(), strsf) +
02070 String::stringrep(header.c_str(), strsf) +
02071 (cumulative?
02072 String::stringrep(header.c_str(), strsf) : "") +
02073 (min_max?
02074 String::stringrep(header.c_str(), strsf) +
02075 String::stringrep(header.c_str(), strsf) : "") +
02076 (kurtosis?
02077 String::stringrep(header.c_str(), strsf) : "") +
02078 " ",false);
02079 if (!horizontal) break;
02080 }
02081 message(Msg::Requested,"\n",false);
02082 }
02083
02084
02085
02086 for (RegionManagerList::iterator r=regions.begin(); r!=regions.end(); r++) {
02087 const NeuralRegionManager* rm = *r;
02088 const NeuralRegion::MapBaseType* map = rm->region()->table().getptr(mapname);
02089 if (!map) continue;
02090
02091 typedef Histo::OneDBinList<> Histogram;
02092 Histogram histo(num_bins);
02093 double tmp_kurt = 0.0;
02094 double tmp_sum = 0.0;
02095 double tmp_std = 0.0;
02096 double tmp_var = 0.0;
02097 double tmp_mean = 0.0;
02098 double min = 1e20;
02099 double max = -1e20;
02100
02101 for (int r=0; r<map->nrows(); r++)
02102 for (int c=0; c<map->ncols(); c++) {
02103 NeuralRegion::Magnitude val = mat::elem(*map,r,c);
02104 NeuralRegion::Magnitude bin_mag = val;
02105 Histogram::size_type bin = (cyclic ?
02106 histo.bin_number(bin_mag) :
02107 histo.bin_number_inclusive(bin_mag));
02108 histo.add(bin,val);
02109 if (kurtosis) {
02110 tmp_sum += val;
02111 }
02112
02113 if (min_max) {
02114 min = MIN(min,val);
02115 max = MAX(max,val);
02116 }
02117 }
02118
02119
02120
02121 if (kurtosis) {
02122 tmp_mean = tmp_sum / (map->nrows()*map->ncols());
02123
02124 for (int r=0; r<map->nrows(); r++)
02125 for (int c=0; c<map->ncols(); c++) {
02126 NeuralRegion::Magnitude val = mat::elem(*map,r,c);
02127 NeuralRegion::Magnitude diff_val = val - tmp_mean;
02128 tmp_var += diff_val * diff_val;
02129 tmp_kurt += diff_val * diff_val * diff_val * diff_val;
02130 }
02131
02132 if (tmp_var == 0 || (map->nrows()*map->ncols()<=1) ) {
02133 message(Msg::Error,"Division by zero; kurtosis undefined");
02134 tmp_kurt = 0.0;
02135 } else {
02136 tmp_var = tmp_var/(map->nrows()*map->ncols()-1);
02137 tmp_kurt = tmp_kurt / (map->nrows()*map->ncols()*tmp_var*tmp_var) - 3.0;
02138 tmp_std = sqrt(tmp_var);
02139 }
02140 }
02141
02142 const double sum = histo.sum_value();
02143 const string sumstr = String::stringrep(sum,magsf);
02144 const double kurt = tmp_kurt;
02145 cumulative_sum += sum;
02146 cumulative_count++;
02147 message( Msg::Requested,
02148 String::stringrep(rm->region()->name().c_str(), strsf) +
02149 String::stringrep(mapname.c_str(), strsf) +
02150 String::stringrep(sum, magsf) + " " +
02151 (cumulative? String::stringrep(cumulative_sum/cumulative_count, magsf) + " " : "") +
02152 (min_max? String::stringrep(min,magsf) + " " +
02153 String::stringrep(max,magsf) + " " : "") +
02154 (kurtosis? String::stringrep(kurt,magsf) + " " : "") +
02155 (horizontal? " " : lineend),false);
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174 }
02175 if (horizontal) message(Msg::Requested,lineend,false);
02176
02177 CMD_ARG_ASSERT_EMPTY;
02178 return CMD_NO_ERROR;
02179 }
02180
02181
02182
02183
02185 cmdstat NeuralRegionMap::cmd_backproject( CMD_ARGS )
02186 {
02187 CMD_ARG_PARAMS(backproject);
02188
02189 RegionManagerList regions = retrieve_matching_regions(argparams);
02190 const bool verbose = argparams.get_with_default("verbose",True);
02191 bool status = True;
02192
02193
02194 for (RegionManagerList::reverse_iterator r=regions.rbegin(); r!=regions.rend(); r++) {
02195 if ((*r)->region()->is_internal()) {
02196 message((verbose? Msg::Notify : Msg::Verbose), "Backprojecting from " + (*r)->region()->name());
02197 InternalNeuralRegion* ir = dynamic_cast<InternalNeuralRegion*>((*r)->region());
02198 if (ir) {
02199 ir->backproject();
02200 } else {
02201 status = False;
02202 }
02203 }
02204 }
02205
02206 CMD_ARG_ASSERT_EMPTY;
02207 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
02208 }
02209
02210 #ifdef OBJ_LISSOM
02211
02212 cmdstat NeuralRegionMap::cmd_resp_to_residual( CMD_ARGS )
02213 {
02214 CMD_ARG_PARAMS(resp_to_residual);
02215
02216 RegionManagerList regions = retrieve_matching_regions(argparams);
02217 const bool verbose = argparams.get_with_default("verbose",True);
02218 bool status = True;
02219
02220
02221
02222 for (RegionManagerList::iterator i=regions.begin(); i!=regions.end(); i++) {
02223
02224 message((verbose? Msg::Notify : Msg::Verbose), "Calculating response to residual in " + (*i)->region()->name());
02225 InternalNeuralRegion* ir = dynamic_cast<InternalNeuralRegion*>((*i)->region());
02226 if (ir) {
02227 ir->resp_to_residual();
02228 } else {
02229 status = False;
02230 }
02231 }
02232
02233 CMD_ARG_ASSERT_EMPTY;
02234 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
02235 }
02236
02239 cmdstat NeuralRegionMap::cmd_train_obj_weights( CMD_ARGS )
02240 {
02241 CMD_ARG_PARAMS(train_obj_weights);
02242
02243 RegionManagerList regions = retrieve_matching_regions(argparams);
02244 const bool verbose = argparams.get_with_default("verbose",True);
02245 bool status = True;
02246
02247 for (RegionManagerList::iterator i=regions.begin(); i!=regions.end(); i++) {
02248
02249 message((verbose? Msg::Notify : Msg::Verbose), "Training obj_weights in " + (*i)->region()->name());
02250 InternalNeuralRegion* ir = dynamic_cast<InternalNeuralRegion*>((*i)->region());
02251 if (ir) {
02252
02253 ir->train_obj_weights();
02254 } else {
02255 status = False;
02256 }
02257 }
02258
02259 CMD_ARG_ASSERT_EMPTY;
02260 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
02261 }
02262
02264 cmdstat NeuralRegionMap::cmd_randomize_lat_wts( CMD_ARGS )
02265 {
02266 CMD_ARG_PARAMS(randomize_lat_wts);
02267
02268 RegionManagerList regions = retrieve_matching_regions(argparams);
02269 const bool verbose = argparams.get_with_default("verbose",True);
02270 bool status = True;
02271
02272 for (RegionManagerList::iterator i=regions.begin(); i!=regions.end(); i++) {
02273
02274 message((verbose? Msg::Notify : Msg::Verbose), "Randomizing lat wts in " + (*i)->region()->name());
02275 InternalNeuralRegion* ir = dynamic_cast<InternalNeuralRegion*>((*i)->region());
02276 if (ir) {
02277
02278 ir->randomize_lat_wts();
02279 } else {
02280 status = False;
02281 }
02282 }
02283
02284 CMD_ARG_ASSERT_EMPTY;
02285 return (status ? CMD_NO_ERROR : CMD_PARAMETER_ERROR);
02286 }
02287 #endif
02288