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

worldviews.c

Go to the documentation of this file.
00001 
00007 #include "worldviews.h"
00008 #include "stringutils.h"
00009 
00010 
00011 
00012 /* Static defaults */
00013 int    WorldViews::random_seed =123454321;  /* Arbitrary default */
00014 
00015 char   WorldViews::default_type[WorldViews::MAX_INPUT_DEFAULT_LENGTH]     = "Input_Gaussian";
00016 char   WorldViews::default_angle[WorldViews::MAX_INPUT_DEFAULT_LENGTH]    = "Random PI/2 PI/2";
00017 char   WorldViews::default_position[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "Uncorrelate &uncorrelation 0 RN  Random RN/2 RN/2";
00018 char   WorldViews::default_scale[WorldViews::MAX_INPUT_DEFAULT_LENGTH]    = "1.0";
00019 char   WorldViews::default_offset[WorldViews::MAX_INPUT_DEFAULT_LENGTH]   = "0.0";
00020 char   WorldViews::default_xsigma[WorldViews::MAX_INPUT_DEFAULT_LENGTH]   = "&xsigma";
00021 char   WorldViews::default_ysigma[WorldViews::MAX_INPUT_DEFAULT_LENGTH]   = "&ysigma";
00022 char   WorldViews::default_phase[WorldViews::MAX_INPUT_DEFAULT_LENGTH]    = "Random PI PI";
00023 char   WorldViews::default_size_scale[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "1.0";
00024 char   WorldViews::default_image_filename[WorldViews::MAX_INPUT_DEFAULT_LENGTH] = "image.pgm";
00025 char   WorldViews::default_clone_name[CMD_MAX_LINE_LENGTH]          = "";
00026        
00027 char   WorldViews::default_command[CMD_MAX_LINE_LENGTH]             = "for i=0 i<inputs_pereye i=i+1 input_define Obj$i";
00028 char   WorldViews::imagepath[CMD_MAX_LINE_LENGTH] = "../images/ ../../images/ ../../../images/";
00029 
00030 
00031 int    WorldViews::distribution=Uninitialized;
00032 double WorldViews::input_offset=0.0;
00033 int    WorldViews::inputs_pereye=1;
00034 double WorldViews::xsigma=7;
00035 double WorldViews::ysigma=1.5;
00036 int    WorldViews::current_eye=0;
00037 double WorldViews::scale_input=1.0;
00038 
00039 int    WorldViews::input_log=True;
00040 
00041 int    WorldViews::input_accum_type=Retinal_Composite::Max;
00042 
00043 
00044 double WorldViews::input_separation_max=Uninitialized;
00045 int    WorldViews::input_separation_max_enforce=False;
00046 double WorldViews::input_separation_min=Uninitialized;
00047 int    WorldViews::input_separation_min_enforce=False;
00048 
00049 
00050 
00051 
00052 void  WorldViews::register_params_and_commands( void )
00053 {
00054   /*
00055     Ensure that this routine is only called once; 
00056     valid since all the parameters are constant or static
00057   */
00058   static bool been_called=false;
00059   if (been_called) return;
00060   been_called=true;
00061   
00062   params_define_param("input_current_eye",PARAM_INT,True,(char*)&current_eye);  
00063   params_define_doc("input_current_eye",
00064           "Read-only parameter which reports the eye in which an object is currently\n"
00065           "being drawn, cleared, etc., e.g. by input_draw.  This can be useful for\n"
00066           "writing equations which place inputs at different but regularly-spaced\n"
00067           "positions, angles, etc. in each eye.\n\n"
00068           
00069           "This value is available during the command input_define, but it is not\n"
00070           "currently useful there because all subsequent eyes link directly to the\n"
00071           "values in the first eye (with or without uncorrelation), and thus any\n"
00072           "value computed for a parameter in the higher eyes is ignored.  There may\n"
00073           "be some way to circumvent this limitation.");
00074   SETFN_DEFINE(input_current_eye,read_only_param_setfn);
00075  
00076   PARAM_II(PARAM_STRING,input_default_clone_name,&default_clone_name,0,MAX_INPUT_DEFAULT_LENGTH,
00077           "Name of default object to clone when none is specified.  The default is to\n"
00078           "clone the entire contents of the retina, which can be useful for\n"
00079           "input_present_object to show all objects in their reset state.  However,\n"
00080           "when using input_define without specifying the name of the object to clone,\n"
00081           "the name should ordinarily be specified via this parameter.");
00082 
00083   PARAM_II(PARAM_STRING,input_default_image_filename,&default_image_filename,0,MAX_INPUT_DEFAULT_LENGTH,
00084           "Default filename used by Input_PGM when none is specified explicitly\n"
00085           "in a call to input_define.");
00086 
00087   PARAM_II(PARAM_STRING,input_default_command,&default_command,0,CMD_MAX_LINE_LENGTH,
00088           "Default command used to construct retinal objects when none are created\n"
00089           "explicitly by a call to input_define.  Usually just calls \"input_define\"\n"
00090           "\"inputs_pereye\" times, but can be changed to do something else, e.g. by\n"
00091           "setting the distribution parameter.");
00092 
00093   PARAM_II(PARAM_STRING,input_default_type,&default_type,0,MAX_INPUT_DEFAULT_LENGTH,
00094           "Default type of retinal object to construct.  Accepts any of the possibilities\n"
00095           "for the <objtype> parameter of input_define.");
00096 
00097   PARAM_II(PARAM_STRING,input_default_angle,&default_angle,0,MAX_INPUT_DEFAULT_LENGTH,
00098           "Default theta used to construct most retinal objects when none is\n"
00099           "specified explicitly in a call to input_define.  Usually a randomly\n"
00100           "chosen angle from the full range for a symmetric stimulus (0..PI)\n"
00101           "each presentation.");
00102 
00103   PARAM_II(PARAM_STRING,input_default_position,&default_position,0,MAX_INPUT_DEFAULT_LENGTH,
00104           "Default x and y center used to construct most retinal objects when none is\n"
00105           "specified explicitly in a call to input_define.  Usually a randomly chosen\n"
00106           "location on the full retina [0,RN) each presentation (for a persistent\n"
00107           "object defined with input_define), defaulting to the center of the retina\n"
00108           "(for temporary objects created with input_draw.)\n\n");
00109           
00110   PARAM_II(PARAM_STRING,input_default_scale,&default_scale,0,MAX_INPUT_DEFAULT_LENGTH,
00111           "Default intensity scale used to construct most retinal objects when none is\n"
00112           "specified explicitly in a call to input_define.");
00113 
00114   PARAM_II(PARAM_STRING,input_default_offset,&default_offset,0,MAX_INPUT_DEFAULT_LENGTH,
00115           "Default intensity offset used to construct most retinal objects when none is\n"
00116           "specified explicitly in a call to input_define.");
00117 
00118   PARAM_II(PARAM_STRING,input_default_xsigma,&default_xsigma,0,MAX_INPUT_DEFAULT_LENGTH,
00119           "Default xsigma used to construct most retinal objects when none is\n"
00120           "specified explicitly in a call to input_define.  Defaults to be a\n"
00121           "pointer to the global value of xsigma, so it will change any time\n"
00122           "that parameter does.");
00123 
00124   PARAM_II(PARAM_STRING,input_default_ysigma,&default_ysigma,0,MAX_INPUT_DEFAULT_LENGTH,
00125           "Default ysigma used to construct most retinal objects when none is\n"
00126           "specified explicitly in a call to input_define.  Defaults to be a\n"
00127           "pointer to the global value of ysigma, so it will change any time\n"
00128           "that parameter does.");
00129 
00130   PARAM_II(PARAM_STRING,input_default_phase,&default_phase,0,MAX_INPUT_DEFAULT_LENGTH,
00131           "Default phase used to construct some retinal objects when none is\n"
00132           "specified explicitly in a call to input_define.");
00133 
00134   PARAM_II(PARAM_STRING,input_default_size_scale,&default_size_scale,0,MAX_INPUT_DEFAULT_LENGTH,
00135           "Default size_scale for input objects taking that parameter.");
00136 
00137   PARAM_II(PARAM_BOOL,  input_log,&input_log,False,True,
00138           "If true, saves some information about the inputs presented at each iteration\n"
00139           "to the log file so that e.g. the input distribution can be analyzed.");
00140 
00141   PARAM_N(PARAM_DOUBLE,scale_input,
00142           "Input scaling factor.  The input level can be scaled to prevent saturating\n"  
00143           "the network.  See also input_offset.");
00144   
00145   PARAM_LL(PARAM_INT,   input_seed,&random_seed,0,                  
00146           "Value to which to reset the random number generator in input_reset.");
00147 
00148   PARAM_LL(PARAM_DOUBLE,input_separation_max,&input_separation_max,0,
00149           "When input_separation_max_enforce is true, the maximum allowable\n"
00150           "distance between input centers.");
00151   params_define_default_expr("input_separation_max","3.0*rf_radius"); /* Empirical */
00152 
00153   PARAM_II(PARAM_BOOL,  input_separation_max_enforce,&input_separation_max_enforce,False,True,
00154           "Whether or not to ensure that input centers are separated by at most\n"
00155           "input_separation_max.");
00156 
00157   PARAM_LL(PARAM_DOUBLE,input_separation_min,&input_separation_min,0,
00158           "When input_separation_min_enforce is true, the minimum allowable\n"
00159           "distance between input centers.");
00160   params_define_default_expr("input_separation_min","2.2*rf_radius"); /* Empirical */
00161 
00162 
00163   PARAM_II(PARAM_BOOL,  input_separation_min_enforce,&input_separation_min_enforce,False,True,
00164           "Whether or not to ensure that input centers are separated by at least\n"
00165           "input_separation_min.");
00166 
00167   PARAM_II(PARAM_INT,   distribution,&distribution,Uninitialized,70,
00168           "Ordinarily, input distributions are defined using input_define or are\n"
00169           "generated automatically based on the defaults, but this parameter allows\n"
00170           "simple selection of a few that have historically been common.  If there\n"
00171           "is any doubt about their meaning, just use input_define explicitly.\n\n"
00172 
00173           "Unless otherwise noted, all distribute positions randomly and correlate\n"
00174           "them between the eyes using the uncorrelation parameter, all\n"
00175           "distribute angles randomly in the range [0..PI] radians, and keep all\n"
00176           "other parameters constant.\n\n"
00177 
00178 
00179           " 0 Uniformly random noise ranging from input_offset to (input_offset+\n"
00180           "   scale_input) at every location on the retina.\n\n\n"
00181 
00182 
00183           "13 Circular gaussian input.\n"
00184           "   (Typical distribution for ocular dominance maps.)\n\n\n"
00185 
00186           
00187           "14 Circular gaussian input with randomly chosen sigma.\n\n\n"
00188 
00189 
00190           "20 Ellipsoidal gaussian input.\n"
00191           "   (Default distribution; typical for orientation maps.)\n\n\n"
00192 
00193 
00194           "21 Ellipsoidal gaussian input with random eccentricities.  The\n"
00195           "   mean xsigma and ysigma are kept the same as in distribution 20.\n\n\n"
00196 
00197 
00198           "22 Ellipsoidal gaussian input, all parallel to each other.\n\n\n"
00199 
00200 
00201           "23 Same as 20 with input_separation_min_enforce=True.\n\n\n"
00202 
00203           
00204           "24 Same as 22 with input_separation_min=True.\n\n\n"
00205 
00206 
00207           "25 Same as 23 with input_separation_max_enforce=True also.\n\n\n"
00208           
00209 
00210           "26 Same as 24 with input_separation_max_enforce=True also.\n\n\n"
00211           
00212 
00213           "60 Same as 20 except that all inputs are fixed at the center of the\n"
00214           "   retina. (Typical distribution for tilt aftereffect tests.)");
00215   /* Note that no setfn should be installed here for the distribution
00216      parameter since one is already installed for it in the Eyes class. */
00217 
00218   PARAM_NN(PARAM_INT,   input_accum_type,&input_accum_type,
00219           "Accumulation type for the retina.  See Accum_Max, Accum_Min, Accum_Add, etc.");
00220 
00221   PARAM_II(PARAM_STRING,imagepath,&imagepath,1,CMD_MAX_LINE_LENGTH,
00222           "Space-separated list of paths to search for images to read.  The current\n"
00223           "directory is always searched first.");
00224   
00225   PARAM_NN(PARAM_DOUBLE,input_offset,&input_offset,
00226           "Constant value to add to each retinal input pixel.  See also scale_input.");
00227 
00228   PARAM_LL(PARAM_INT,   inputs_pereye,&inputs_pereye,0,
00229            "Default number of input items to create per eye, if none are explicitly\n"
00230            "defined by input_define.  When changed after the network has been\n"
00231            "initialized, undefines all current inputs and regenerates a new set\n"
00232            "using input_default_command.");
00233   /* Note that no setfn should be installed here for the inputs_pereye
00234      parameter since one is already installed for it in the Eyes class. */
00235 
00236    PARAM_LL(PARAM_DOUBLE,xsigma,&xsigma,0,
00237            "Default X sigma (the semi-major axis, approximately half the\n"
00238            "horizontal width at half-height) of ellipsoidal input Gaussian\n"
00239            "or similar patterns.  When changed after the network has been\n"
00240            "initialized, undefines all current inputs and regenerates a new\n"
00241            "set using input_default_command.");
00242 
00243    PARAM_LL(PARAM_DOUBLE,ysigma,&ysigma,0,
00244            "Default Y sigma (the semi-minor axis, approximately half the\n"
00245            "vertical width at half-height) of ellipsoidal input Gaussian\n"
00246            "or similar patterns.  When changed after the network has been\n"
00247            "initialized, undefines all current inputs and regenerates a new\n"
00248            "set using input_default_command.");
00249 
00250    CONST_I(Accum_Max,Retinal_Composite::Max,False,
00251            "Input_Composite objects using this accumulation_type determine\n"
00252            "their activities at a given retinal location by taking the\n"
00253            "maximum of their childrens' activities at this location.  This\n"
00254            "makes it easier to combine objects from overlapping pieces.");
00255 
00256    CONST_I(Accum_Min,Retinal_Composite::Min,False,
00257            "Input_Composite objects using this accumulation_type determine\n"
00258            "their activities at a given retinal location by taking the\n"
00259            "minimum of their childrens' activities at this location.  This\n"
00260            "makes it easier to combine objects which are on in the background\n"
00261            "and off in the foreground.");
00262 
00263    CONST_I(Accum_Add,Retinal_Composite::Add,False,
00264            "Input_Composite objects using this accumulation_type determine\n"
00265            "their activities at a given retinal location by adding their\n"
00266            "childrens' activities at this location.  This facilitates construction\n"
00267            "of objects using Boolean specifications, such as punching out holes from\n"
00268            "a larger object.");
00269 
00270 
00271    CONST_I(Accum_OneHot,Retinal_Composite::OneHot,False,
00272            "Input_Composite objects using this accumulation_type select\n"
00273            "only a single child each iteration, as chosen by the <hot-specifier>\n"
00274            "parameter to Input_Composite.\n\n"
00275 
00276            "This accumulation type is useful for selecting one object (randomly, or in\n"
00277            "order) from a set of predefined stimuli.\n\n"
00278 
00279            "The <hot-specifier> should be a ValueGenerator in the range [0,1.0];\n"
00280            "it is used to generate an index in the range [0,number_of_children-1].\n"
00281            "Values outside of that range are wrapped back inside using a modulo\n"
00282            "operator, so e.g. a continuously incrementing value will cycle through\n"
00283            "all elements in order.  The default <hot-specifier> results in a random\n"
00284            "order.");
00285 
00286 
00287   CONST_S(Input_Composite,False,
00288           "Input object (see command input_define) with parameters:\n"
00289           "  [<theta> [<cx> [<cy> [<size_scale> [<scale> [<offset> [<accum_type>] [<hot-specifier>]]]]]]]\n\n"
00290           
00291           "Container for other objects, allowing a group of them to be moved\n"
00292           "and rotated as a unit.  Only makes sense for input_define rather than\n"
00293           "input_draw, at present.  The <name> parameter supplied in the call may\n"
00294           "henceforth serve as the name of the parent for a newly-defined object;\n"
00295           "the position, angle, and size of the newly-defined child object become\n"
00296           "relative to that of the composite.\n\n"
00297 
00298           "Parameter <accum_type> may be one of the following (prefixed with Accum_):\n"
00299           "Max, Min, Add, OneHot.  See Accum_OneHot for a description of the\n"
00300           "<hot-specifier>, and see Input_Gaussian for descriptions of the other\n"
00301           "parameters.  Example:\n\n"
00302           
00303           "input_define Face     \"\"   Input_Composite \"Normal PI/2 PI/18\"\n"
00304           "input_define Mask     Face Input_Gaussian   0  0  0.0 7.00 5  1\n"
00305           "input_define LeftEye  Face Input_Gaussian   0 -1 +2.5 1.25 2 -1\n"
00306           "input_define RightEye Face Input_Gaussian   0 -1 -2.5 1.25 2 -1\n"
00307           "input_define Mouth    Face Input_Gaussian   0 +5  0.0 1.25 2 -1");
00308   
00309   CONST_S(Input_UniformRandomNoise,False,
00310           "Input object (see command input_define) with parameters:\n"
00311           "  [<scale> [<offset>]]\n\n"
00312 
00313           "The activation of each receptor in the retina is chosen randomly from\n"
00314           "a uniform distribution in the range <offset> to <offset>+<scale>.");
00315   
00316   CONST_S(Input_Gaussian,False,
00317           "Input object (see command input_define) with parameters:\n"
00318           "  [<theta> [<cx> [<cy> [<xsigma> [<ysigma> [<scale> [<offset>]]]]]]]\n\n"
00319 
00320           "Two-dimensional Gaussian-shaped input object, i.e. a blob, with the\n"
00321           "indicated parameters:\n\n"
00322           
00323           "theta         angle in radians, measured upwards from the left\n"
00324           "              horizontal axis (contrary to standard\n"
00325           "              mathematical usage, for historical reasons))\n"
00326           "              (Defaults to input_default_angle.)\n\n"
00327           
00328           "(cx,cy)       location on retina (or parent object) of center\n"
00329           "              relative to an origin at the upper left corner,\n"
00330           "              extending downwards in the Y direction and to the\n"
00331           "              right in the X direction.  Values are floating-\n"
00332           "              point, with receptor (i,j) encompassing an area\n"
00333           "              starting at an upper left corner (i,j) and ending\n"
00334           "              just before the lower right corner (i+1,j+1).\n"
00335           "              Thus to center an item directly over receptor\n"
00336           "              (i,j), place it at (i+0.5,j+0.5).\n"
00337           "              (Defaults to input_default_position.)\n\n"
00338           
00339           "xsigma        sigma of the Gaussian in the X direction (the semi-\n"
00340           "              major axis, i.e. one-half its width at half-intensity.\n"
00341           "              (Defaults to input_default_xsigma.)\n\n"
00342           
00343           "ysigma        sigma of the Gaussian in the Y direction (the semi-\n"
00344           "              minor axis, i.e. one-half its width at half-intensity.\n"
00345           "              (Defaults to input_default_ysigma.)\n\n"
00346           
00347           "scale         intensity scale (Defaults to 1.0, full intensity.)\n\n"
00348           
00349           "offset        intensity offset (Defaults to 0.0, no offset.)\n\n\n"
00350 
00351 
00352           "Example:\n"
00353           "  input_define Spot1    \"\" Input_Gaussian  \"Random PI/2 PI/2\" RN/4 RN/4 xsigma/2 ysigma 1.0 0.0\n");
00354 
00355   CONST_S(Input_Rectangle,False,
00356           "Input object (see command input_define) with parameters:\n"
00357           "  [<cx> [<cy> [<xsigma> [<ysigma> [<scale>] [<offset>]]]]]\n\n"
00358           
00359           "Axis-aligned rectangle centered at <cx>,<cy> with width 2*<xsigma>,\n"
00360           "height 2*<ysigma>, and brightness <scale>.\n\n"
00361 
00362           "Depending on where the center falls on the grid, the actual length\n"
00363           "(height or width) may be larger or smaller than the nominal length by one\n"
00364           "pixel.  To get e.g. an odd width (e.g. 3), you should specify a <cx> at the\n"
00365           "center of a pixel (e.g. 1.5); this will ensure that the center pixel\n"
00366           "plus equal numbers of pixels on either side are included.  To get an even\n"
00367           "width, you should specify a pixel boundary instead (e.g. 2.0) so that an\n"
00368           "equal number of pixels are included on each side.\n\n"
00369 
00370           "This object type can be useful for drawing a pattern pixel-by-pixel.  To e.g.\n"
00371           "specify that the pixel at (3,1) should have activation 0.7, use:\n"
00372           "  Input_Rectangle  3.5 1.5 0.5 0.5 scale=0.7");
00373   
00374   CONST_S(Input_CircularGaussian,False,
00375           "Input object (see command input_define) with parameters:\n"
00376           "  [<cx> [<cy> [<xsigma> [<scale> [<offset>]]]]]\n\n"
00377           
00378           "Two-dimensional circular Gaussian with radial half-width <xsigma>,\n"
00379           "which defaults to be a pointer to the global xsigma.\n"
00380           "See Input_Gaussian for descriptions of the other parameters.");
00381   
00382   CONST_S(Input_SineGrating,False,
00383           "Input object (see command input_define) with parameters:\n"
00384           "  [<theta> [<freq> [<phase> [<scale> [<offset>]]]]]\n\n"
00385           
00386           "Sine grating input object which covers the entire retina.  The\n"
00387           "frequency and phase of the sine wave are set by <freq> and <phase>.\n"
00388           "The phase defaults to zero, and the frequency has an arbitrary default.\n"
00389           "Note that (for the default offset) the sine grating is half-rectified\n"
00390           "since negative activations are ignored; to get a full sine wave in the\n"
00391           "standard activity range 0-1, use an offset of 0.5 and a scale of 0.5.");
00392 
00393   CONST_S(Input_Gabor,False,
00394           "Input object (see command input_define) with parameters:\n"
00395           "  [<theta> [<cx> [<cy> [<xsigma> [<ysigma> [<freq> [<phase> [<scale> [<offset>]]]]]]]]]\n\n"
00396           "Gabor-shaped input object, i.e. a sine grating masked by a Gaussian.\n"
00397           "See Input_Gaussian and Input_SineGrating for descriptions of the\n"
00398           "parameters.");
00399   
00400   CONST_S(Input_FuzzyLine,False,
00401           "Input object (see command input_define) with parameters:\n"
00402           "  [<theta> [<cx> [<cy> [<ysigma> [<center_width> [<scale> [<offset>]]]]]]]\n\n"
00403           
00404           "Infinite line of width <center_width> with one-dimensional Gaussian\n"
00405           "falloff (half-width <ysigma>) as distance increases from that point.\n"
00406           "(Full brightness is maintained for the entire <center_width>, after\n"
00407           "which the brightness decreases according to a Gaussian of half-width\n"
00408           "ysigma.)  The <center_width> defaults to zero and the <ysigma> defaults\n"
00409           "to be a pointer to the global ysigma.");
00410 
00411   CONST_S(Input_FuzzyRing,False,
00412           "Input object (see command input_define) with parameters:\n"
00413           "  [<cx> [<cy> [<ysigma> [<center_width> [<radius> [<scale> [<offset>]]]]]]]\n\n"
00414           
00415           "Circular ring (torus) of the given <radius> whose brightness is\n"
00416           "maximal for a distance of <center_width> around the radius, then\n"
00417           "falls off according to a one-dimensional Gaussian of half-width\n"
00418           "<ysigma> as radial distance increases from that point.  The\n"
00419           "<center_width> defaults to zero and the <ysigma> defaults to\n"
00420           "be a pointer to the global ysigma.");
00421 
00422   CONST_S(Input_PGM,False,
00423           "Input object (see command input_define) with parameters:\n"
00424           "  [<filename> [<theta> [<cx> [<cy> [<size_scale> [<scale> [<offset>]]]]]]]\n\n"
00425 
00426           "Reads input from the specified PGM-format file.  The size_scale changes\n"
00427           "the effective size of the image on the retina.  One common use is to work\n"
00428           "with images larger than the final desired size, oversampling them to avoid\n"
00429           "pixellation effects when doing rotations, etc.  E.g. double-size\n"
00430           "images can be used with a size_scale of 0.5 and a world_size_scale of\n"
00431           "2.0, with the same results as single-sized images would have except\n"
00432           "that (with proper input convolution) aliasing should be reduced.  See\n"
00433           "the documentation for Input_Gaussian for information about the other\n"
00434           "parameters.\n\n"
00435 
00436           "The parameters default to the defaults of Input_Gaussian for images\n"
00437           "smaller than the retina in any dimension, i.e. any images that can\n"
00438           "be placed at an arbitrary location and angle.  All larger images default\n"
00439           "to being upright with no angle variation, and to vary in position only\n"
00440           "as much as is possible without ever showing a border.  This distinction\n"
00441           "reflects differences in the primary uses of image objects -- they can\n"
00442           "act as regular objects which happen to be defined in an image file, or as\n"
00443           "literal specification of the entire contents of the retina.\n\n"
00444 
00445           "If you have a set of images that you want to present as the entire contents\n"
00446           "of the retina, e.g. to play a movie recorded from video, you can define\n"
00447           "hooks to clear the input and read in the appropriate frame each time. For\n"
00448           "example, assume that you have 1000 frames stored in PGM files named\n"
00449           "image_1.pgm, image_2.pgm, ..., image_1000.pgm.  To present the appropriate\n"
00450           "file at each iteration, you could use these commands:\n\n"
00451 
00452           "  hook before_input 1-1000 input_undefine\n"
00453           "  hook before_input 1-1000 input_define Image '' Input_PGM 'image_$iteration.pgm' PI/2 RN/2 RN/2 1.0\n\n"
00454 
00455           "Here the Input_PGM parameters are used to force the images to appear upright\n"
00456           "in the center of the retina at the same size each time, which is appropriate\n"
00457           "for full-retina images.");
00458   
00459   CONST_S(Input_Clone,False,
00460           "Input object (see command input_define) with parameters:\n"
00461           "  [<name_of_original>]\n\n"
00462           
00463           "Defines an object that is a clone of the object with the given name.\n"
00464           "Any ValueGenerators the object has are cloned too, such that the clone\n"
00465           "has the same value distribution but different actual values.  The original\n"
00466           "object name (i.e. the object to clone) defaults to the value of\n"
00467           "input_default_clone_name; see that parameter's documentation for more\n"
00468           "details.  Named ValueGenerator arguments appropriate for the cloned\n"
00469           "object may be passed in after the name of the original object; these\n"
00470           "will be applied after cloning to override the inherited settings.\n\n"
00471           
00472           "The semantics of this operation are extremely tricky, and in fact it is\n"
00473           "only partially implemented.  Specifically, in the case when num_eyes>1\n"
00474           "and uncorrelation!=0, a cloned object will differ from the original\n"
00475           "by not having any uncorrelation introduced.  This difference is for\n"
00476           "very technical reasons having to do with how a cloned object is\n"
00477           "constructed for eyes other than the first, which is to clone the\n"
00478           "existing object in the current eye and replace its ValueGenerator\n"
00479           "parameter links to point to the newly cloned object in the first eye.\n"
00480           "This consideration is important only for input_define; input_draw\n"
00481           "always uses the starting state of the objects and thus is not\n"
00482           "affected by uncorrelation.");
00483 }
00484 
00485 
00486 
00489 void WorldViews::init( void )
00490 {
00491   /* Define each eye */
00492   define();
00493   
00494   /* Generate default contents for each eye if none have been defined yet */
00495   if (!count_if(ISEQ(contents),not1(mem_fun(&Retinal_Composite::is_empty)))) {
00496     /* Execute input_default_command relatively silently */ 
00497     const int oldverbosity = ipc_msg_level;
00498     const int newverbosity = IPC_SUMMARY;
00499     if (ipc_msg_level > newverbosity) ipc_msg_level=newverbosity;
00500     cmddefs_exec_str(default_command);
00501     if (ipc_msg_level==newverbosity)  ipc_msg_level=oldverbosity;
00502   }
00503 }
00504 
00505 
00506 
00507 bool WorldViews::next(void)
00508 {
00509   /* Update parameters for this presentation */
00510   if (input_log)
00511     ipc_log(IPC_ONE,"Iteration: %06d",iteration);
00512   
00513   for (int eye=0; eye<num_eyes; eye++) {
00514     if (!contents[eye]->next())
00515       ipc_notify(IPC_ONE,IPC_CAUTION,
00516                  "Failed to generate valid position for object in eye %d at iteration %06d",
00517                  eye,iteration);
00518     else if (input_log) {
00519       string str=contents[eye]->stringrep();
00520       ipc_log(IPC_ONE,"  [%s]",str.c_str());
00521     }
00522   }
00523   ipc_log(IPC_ONE,"\n");
00524   return true;
00525 }
00526 
00527 
00529 void WorldViews::define( unsigned n_eyes )
00530 {
00531   /* Return quickly if nothing to do */
00532   if (contents.size()>=n_eyes) return;
00533   
00534   Retinal_Object::VarMap  vars;
00535   vars.set("hot",new UR_VGen(0.5,0.5));
00536   vars.set("size_scale",new VGen(1.0));
00537   vars.set("scale",new VGen(&scale_input));
00538   vars.set("offset",new VGen(&input_offset));
00539   
00540   /* Define all eyes up to and including this one */
00541   for (unsigned e=contents.size(); e<n_eyes; e++) {
00542     if (e!=0)
00543       vars.set("hot",new VGen(contents[0]->get_varptr("hot")));
00544     
00545     const string e_str = String::stringrep(e);
00546     Retinal_AnchoredManagedComposite newobj("Eye"+e_str,
00547                      &input_separation_min_enforce,   &input_separation_min,
00548                      &input_separation_max_enforce,   &input_separation_max,
00549                      Retinal_Composite::AccumulationType(input_accum_type),
00550                      vars);
00551 
00552     /* This dynamic_cast can be removed once the Cray compiler supports
00553        derived-class virtual function return types. */
00554     contents.push_back(dynamic_cast<value_type>(newobj.clone()));
00555   }
00556 }
00557 
00558 
00559 
00561 bool WorldViews::create_object(StringArgs args, const string& name,
00562                                WorldViews& reference_contents,
00563                                bool link_eyes) // Should be made const
00564 {
00565   DistributedValueGeneratorFactory<Retinal_Object::Variable> vgf;
00566   RetinalObjectStringArgs::DefaultsMap defaults; 
00567   
00568   /* ValueGenerators */
00569   defaults["theta"]            = "${input_default_angle}";
00570   defaults["cx"]               = "${input_default_position}";
00571   defaults["cy"]               = "${input_default_position}";
00572   defaults["xsigma"]           = "${input_default_xsigma}";
00573   defaults["ysigma"]           = "${input_default_ysigma}";
00574   defaults["radius"]           = "RN/4"; // Arbitrary
00575   defaults["scale"]            = "${input_default_scale}";
00576   defaults["offset"]           = "${input_default_offset}";
00577   defaults["hot"]              = "Random 0.5 0.5";
00578   defaults["size_scale"]       = "${input_default_size_scale}";
00579   defaults["phase"]            = "${input_default_phase}";
00580   defaults["freq"]             = "0.5"; // Defaults to size comparable to default Gaussian
00581   defaults["center_width"]     = "0";   // Defaults to being Gaussian cross-section only
00582   /* Other parameters */
00583   defaults["clone_name"]       = "${input_default_clone_name}";
00584   defaults["image_filename"]   = "${input_default_image_filename}";
00585   defaults["image_paths"]      = "${imagepath}";
00586   defaults["type"]             = "${input_default_type}";
00587   defaults["accum_type"]       = "Accum_Add";
00588 
00589   RetinalObjectFactory rof;
00590   
00591   /* Adds the new object to the specified parent(s), if any are found */
00592   Retinal_Object* masterobj=0;  
00593   for (unsigned int e=0; e<contents.size(); e++) {
00594     WorldViews::set_current_eye(e);
00595     StringArgs arglist = args; // Reset for each loop iteration
00596     
00597     const string parent  = arglist.next(string(""));
00598     Retinal_Composite* parentptr = dynamic_cast<Retinal_Composite*>(contents[e]->find(parent));
00599 
00600     if (parentptr) {
00601       /*
00602         Linking objects between eyes can get very messy.  Currently
00603         the first eye for which an object is defined is considered the
00604         master eye, to which others link or uncorrelate.  For simple
00605         objects, the relationships are usually straightforward.
00606         However, if an existing object is being cloned, one must clone
00607         the object in the current eye and then replace the links to
00608         point to the new clone in the master eye.  In such cases no
00609         Uncorrelation is introduced, since that would be too difficult
00610         to reconstruct.  Call with link_eyes=false to get more
00611         predictable behavior, but of course then each eye will be
00612         independent.
00613       */
00614       RetinalObjectStringArgs sa(arglist, vgf, defaults, (link_eyes ? masterobj : 0));
00615       Retinal_Composite* basecomposite = reference_contents.contents[(link_eyes && masterobj) ? e : 0];
00616       Retinal_Object* newobj = rof.create(name, sa, basecomposite, RN, RN );
00617       if (newobj) {
00618         parentptr->add(newobj);
00619         
00620         /*
00621           The first object defined (i.e., the object in the first eye
00622           found) is called the master; the others are linked or
00623           correlated with that one (if at all)
00624         */
00625         if (!masterobj) masterobj = newobj;
00626       }
00627     }
00628   }
00629 
00630   if (masterobj==0) {
00631     ipc_notify(IPC_ONE,IPC_ERROR,"Could not define input object");
00632     return 1;
00633   }
00634   
00635   return 0;
00636 }
00637 
00638 
00640 void WorldViews::remove_object(const string& parent, const string& name)
00641 {
00642   for (unsigned int e=0; e<contents.size(); e++) {
00643     set_current_eye(e);
00644     Retinal_Composite* parentptr =
00645       dynamic_cast<Retinal_Composite*>(contents[e]->find(cmds(parent.c_str())));
00646     
00647     if (parentptr) parentptr->remove(cmds(name.c_str()));
00648   }
00649 }
00650   
00651 
00653 void WorldViews::print_object(const string& parent, const string& name) const
00654 {
00655   for (unsigned int e=0; e<contents.size(); e++) {
00656     set_current_eye(e);
00657     Retinal_Object* parentptr = contents[e]->find(cmds(parent.c_str()));
00658 
00659     if (parentptr) {
00660       Retinal_Object* childptr = parentptr->find(cmds(name.c_str()));
00661       if (childptr)
00662         ipc_notify(IPC_ONE,IPC_SUMMARY,childptr->stringrep().c_str());
00663     }
00664   }
00665 }
00666   
00667 
00669 cmdstat WorldViews::set_distribution(int dist, bool& changed)
00670 {  
00671   /* Define objects */
00672   string cmdstr="for i=0 i<inputs_pereye i=i+1 input_define";
00673   switch (dist) {
00674   case 0:
00675     cmdstr+=" noise \"\" Input_UniformRandomNoise &scale_input &input_offset";
00676     break;
00677     
00678   case 13:
00679     cmdstr+=" \"\" \"\" Input_CircularGaussian";
00680     break;
00681     
00682   case 14:
00683     cmdstr+=" \"\" \"\" Input_CircularGaussian \""
00684       + string(WorldViews::default_position) + "\" \"" +  WorldViews::default_position
00685       + "\" \"Random (ysigma-xsigma)/2 (ysigma-xsigma)/2\"";
00686     break;
00687     
00688   case 20: case 23: case 25: case 61:
00689     cmdstr+="";
00690     break;
00691     
00692   case 21:
00693     /*
00694       Originally this was handled by:
00695       
00696       * The mean X and Y sigmas are kept the same as in previous; *
00697       * generates variance uniformly distributed in 0.2 to 2*(xsigma^2) *
00698       local_xsigma = 0.2 + 2.0 * xsigma * my_random();
00699       local_ysigma = 0.2 + 2.0 * ysigma * my_random();
00700       
00701       It's not clear if the same behavior will result as it has been
00702       redefined here:
00703     */
00704     cmdstr+=" \"\" \"\" Input_Gaussian \""
00705       + string(WorldViews::default_angle) + "\" \"" + WorldViews::default_position + "\" \"" +  WorldViews::default_position
00706       + "\" \"Random xsigma 2*xsigma*xsigma\" \"Random ysigma 2*ysigma*ysigma\"";
00707     break;
00708     
00709   case 22: case 24: case 26:
00710     cmddefs_exec_str("input_define_generator parallel_angle \"Random PI/2 PI/2\"");
00711     cmdstr+=" \"\" \"\" Input_Gaussian &parallel_angle";
00712     break;
00713       
00714   case 60: 
00715     cmdstr+=" \"\" \"\" Input_Gaussian \""
00716       + string(WorldViews::default_angle) + "\" RN/2 RN/2";
00717     break;
00718     
00719   case Uninitialized: /* No-op */
00720     return CMD_NO_ERROR;
00721 
00722   default:
00723     ipc_notify(IPC_ONE,IPC_ERROR,"Don't know anything about distribution %d",dist);
00724     return CMD_PARAMETER_ERROR;
00725   }
00726   strncpy(WorldViews::default_command,cmdstr.c_str(),CMD_MAX_LINE_LENGTH);
00727   WorldViews::distribution=dist;
00728 
00729 
00730   /* Set general parameters */
00731   WorldViews::input_separation_min_enforce = (dist==23 || dist==24 || dist==25 || dist==26);
00732   WorldViews::input_separation_max_enforce =                         (dist==25 || dist==26);
00733 
00734   /* Declare that any existing input would need to be regenerated */
00735   changed=true;
00736   
00737   return CMD_NO_ERROR;
00738 }

Generated at Mon Aug 21 00:30:55 2000 for RF-LISSOM by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000