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

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