test-FOE_ViSTARS.C

Go to the documentation of this file.
00001 /*!@file Robots/Beobot2/Navigation/FOE_Navigation/test-FOE_ViSTARS.C
00002   find the FOE using Browning 2009 */
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00034 // $HeadURL: $
00035 // $Id: $
00036 
00037 //
00038 
00039 #define NUM_DIRS        8   
00040 #define NUM_CS          2
00041  
00042 // OpenCV must be first to avoid conflicting defs of int64, uint64
00043 #include "Image/OpenCVUtil.H"
00044 
00045 #include "Component/ModelManager.H"
00046 #include "Media/FrameSeries.H"
00047 
00048 #include "Image/Image.H"
00049 #include "Image/CutPaste.H"
00050 #include "Image/ColorOps.H"
00051 #include "Image/MathOps.H"
00052 #include "Image/FilterOps.H"
00053 #include "Image/ShapeOps.H"
00054 #include "Image/Pixels.H"
00055 #include "Raster/Raster.H"
00056 #include "Image/MatrixOps.H"
00057 
00058 
00059 
00060 #include "Util/Timer.H"
00061 
00062 #include <stdio.h>
00063 
00064 #include "Robots/Beobot2/Navigation/FOE_Navigation/FoeDetector.H"
00065 #include "Robots/Beobot2/Navigation/FOE_Navigation/MotionOps.H"
00066 
00067 // ######################################################################
00068 struct ViSTARSmodelState
00069 {
00070   ViSTARSmodelState() { };
00071 
00072   std::vector<std::vector<Image<double> > > I;
00073   std::vector<std::vector<Image<double> > > a;
00074   std::vector<std::vector<Image<double> > > b;
00075   std::vector<std::vector<Image<double> > > x;
00076   std::vector<std::vector<Image<double> > > y;
00077   std::vector<std::vector<Image<double> > > z;
00078 
00079   std::vector<std::vector<std::vector<Image<double> > > > c;
00080   std::vector<std::vector<std::vector<Image<double> > > > e;
00081   std::vector<std::vector<Image<double> > > f;
00082 
00083   std::vector<Image<double> > q;  
00084   std::vector<Image<double> > Q;  // MT outputs
00085   std::vector<Image<double> > m;  
00086 
00087   std::vector<double> r;
00088 
00089   // Heading firing rate
00090   std::vector<double> R; 
00091 };
00092 
00093 struct ViSTARSmodel
00094 {
00095   ViSTARSmodel() { };
00096 
00097   // SortObj(const rutz::shared_ptr<VisualObject> _obj,
00098   //         const Point2D<int> _objOffset,
00099   //         const uint _fNum,
00100   //         const uint _sNum) :
00101   //   obj(_obj),
00102   //   objOffset(_objOffset),
00103   //   fNum(_fNum),
00104   //   sNum(_sNum)
00105   // {  }
00106 
00107   uint p_NumSpeeds;
00108 
00109   // Level 1
00110   double p_A1; 
00111   double p_B1;
00112   double p_C1;
00113   double p_D1;
00114   double p_phi1;
00115   double p_E1;
00116   Image<double> p_Fxy; // Fxy is a 2D symmetric Gaussian with sigma = 1
00117   double p_G1;
00118 
00119   // Level 2
00120   double p_A2;
00121   double p_B2;
00122   double p_C2;
00123   double p_D2;
00124   double p_K2;
00125 
00126   // Level 3
00127   double p_A3;
00128   double p_B3;
00129   double p_C3;
00130   double p_K3;
00131   double p_A4;
00132   double p_B4;
00133   double p_C4;
00134   double p_K4;
00135 
00136   // Level 4
00137   double p_A5;
00138   double p_B5;
00139   double p_C5;
00140 
00141   // Level 5 & 6
00142   double p_A6;   
00143   double p_B6;
00144   double p_C6;
00145   double p_D6;
00146   double p_theta6;  
00147   std::vector<double> p_vdD;
00148 
00149   double p_A7;
00150   double p_B7;
00151   double p_C7;
00152   double p_D7;
00153   double p_E7;
00154   double p_G7;
00155   double p_theta7;
00156   rutz::shared_ptr<std::vector<std::vector<Image<double> > > > p_w; 
00157   double p_M; 
00158   double p_N;
00159   rutz::shared_ptr<std::vector<Image<double> > > p_L; 
00160 
00161   std::vector<Point2D<int> > Rlocs;
00162 
00163   rutz::shared_ptr<ViSTARSmodelState> state;
00164 };
00165 
00166 // return the Focus of Expansion
00167 Point2D<int> getFOE(ViSTARSmodel &model, Image<double> stim);
00168 void updateFrame(ViSTARSmodel &model, Image<double> stim);
00169 
00170 Point2D<int> bgm_2007(ViSTARSmodel &model);
00171 
00172 std::vector< Image<double> > 
00173 sumFxyI(Image<double> F, std::vector<Image<double> > I);
00174 
00175 Image<double> combine(Image<double> y, double f);
00176 
00177 std::vector<Image<double> > 
00178 sumLxy(rutz::shared_ptr<std::vector<Image<double> > > L, 
00179        std::vector<Image<double> > I);
00180 
00181 std::vector<Image<double> > 
00182 sumRz(std::vector<double> R, 
00183       rutz::shared_ptr<std::vector<std::vector<Image<double> > > > w);
00184 
00185 std::vector<Image<double> >
00186 sumvD(std::vector<double>v, std::vector<Image<double> > I);
00187 
00188 int dof(int x);
00189 
00190 Image<double> filter2(Image<double> f, Image<double> d);
00191 
00192 void report(ViSTARSmodel &model);
00193 
00194 
00195 ViSTARSmodel setupParams(uint comp, Dims size); 
00196 
00197 //
00198 //rutz::shared_ptr<std::vector<std::vector<Image<double> > > > 
00199 std::pair<rutz::shared_ptr<std::vector<std::vector<Image<double> > > >,
00200           std::vector<Point2D<int> > >
00201 generate_w (Dims sz, std::vector<double> vert_pos, uint horz_spac, uint scale);
00202 
00203 //
00204 rutz::shared_ptr<std::vector<Image<double> > > 
00205 generate_L(double l, double sigx, double sigy, double k);
00206 
00207 void initializeModel(ViSTARSmodel &model, Image<double> stim);
00208 
00209 Image<double> shrink(Image<double> y, double f);
00210 
00211 double min(double a, double b)
00212 {
00213   if(a<b) return a;
00214   else    return b;
00215 }
00216 
00217 double max(double a, double b)
00218 {
00219   if(a>b) return a;
00220   else    return b;
00221 }
00222 
00223 double tstep = .1;
00224 
00225 // ######################################################################
00226 int main(const int argc, const char **argv)
00227 {
00228   MYLOGVERB = LOG_INFO;  // suppress debug messages
00229 
00230   // instantiate a model manager:
00231   ModelManager manager("Test Optic Flow");
00232 
00233   nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00234   manager.addSubComponent(ifs);
00235 
00236   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00237   manager.addSubComponent(ofs);
00238 
00239   // FIXXX: probably wants to do this later for the ViSTARS code
00240   //nub::ref<FoeDetector> fd(new FoeDetector(manager));
00241   //manager.addSubComponent(fd);
00242 
00243   manager.exportOptions(MC_RECURSE);
00244 
00245   if (manager.parseCommandLine((const int)argc, (const char**)argv,
00246                                "", 0, 0) == false)
00247     return(1);
00248 
00249   // get some options
00250   // if(manager.numExtraArgs() >  0)
00251   //   {
00252   //     outFilename = manager.getExtraArg(0);
00253   //     LINFO("save to: %s", outFilename.c_str());
00254   //   }
00255 
00256   // let's do it!
00257   manager.start();
00258 
00259   Timer timer(1000000);
00260   timer.reset();  // reset the timer
00261   int frame = 0;
00262   bool keepGoing = true;
00263   const FrameState is = ifs->updateNext();
00264 
00265   ViSTARSmodel model = setupParams(1, ifs->peekDims()); 
00266   Image< PixRGB<byte> > image;
00267   Image<double> stim;
00268   if (is == FRAME_COMPLETE) keepGoing = false;
00269   else 
00270     {
00271       image = ifs->readRGB();
00272       stim = luminance(image)/255.0;
00273 
00274       // model initialization
00275       initializeModel(model, stim);
00276     }
00277 
00278   while (keepGoing)
00279     {
00280       if (ofs->becameVoid())
00281         {
00282           LINFO("quitting because output stream was closed or became void");
00283           break;
00284         }
00285 
00286       Point2D<int> pt = getFOE(model, stim);      
00287       Image<PixRGB<byte> > disp = image;
00288       drawFilledRect
00289         (disp,Rectangle::tlbrI(pt.j, pt.i, pt.j+4, pt.i+4), 
00290          PixRGB<byte>(255,0,0));
00291 
00292       ofs->writeRGB(disp, "Optic Flow");
00293       const FrameState os = ofs->updateNext();
00294       //Raster::waitForKey();
00295 
00296       //Raster::WriteRGB(currImage, sformat("image%d.ppm",frame));
00297 
00298       if (os == FRAME_FINAL) break;
00299 
00300       const FrameState is = ifs->updateNext();
00301       if (is == FRAME_COMPLETE) break; // done receiving frames
00302       image = ifs->readRGB();
00303       stim  = luminance(image)/255.0;
00304       frame++;
00305     }
00306 
00307   // stop all our ModelComponents
00308   manager.stop();
00309 
00310   // all done!
00311   return 0;
00312 }
00313 
00314 // ######################################################################
00315 ViSTARSmodel setupParams(uint comp, Dims size)
00316 {
00317   ViSTARSmodel model;
00318   model.p_NumSpeeds = 3;
00319 
00320   // Level 1
00321   model.p_A1   = 0.001;
00322   model.p_B1   = 1.0;
00323   model.p_C1   = 2.0;
00324   model.p_D1   = 0.25;
00325   model.p_phi1 = 0.1;
00326   model.p_E1   = 10.225;    // 10, K3 1 , K4 1 gets good ogl results not yosem
00327 
00328   // Fxy is a 2D symmetric Gaussian with sigma = 1
00329 
00330   // x = meshgrid(-3:3);
00331   Image<double> xImg(7,7,ZEROS);
00332   for(int i = 0; i < 7; i++)
00333     {
00334       int x = i - 3;
00335       for(int j = 0; j < 7; j++) xImg.setVal(i,j, x);
00336     }
00337 
00338   // xx = sqrt(x.^2 + (x').^2);
00339   Image<double> txImg = transpose(xImg);
00340   Image<double> xxImg = toPower(xImg*xImg + txImg*txImg, .5);
00341 
00342   // model.p.Fxy = (model.p.E1/(2*pi))*exp(-xx.^2)';  
00343   Image<double> xxxImg = transpose(exp(xxImg*xxImg*-1.0)*(model.p_E1/(2*M_PI)));  
00344   model.p_Fxy = xxxImg;
00345 
00346       // LINFO("xxxImage");
00347       // for(int y = 0; y < xxxImg.getHeight(); y++)
00348       //   {
00349       //     for(int x = 0; x < xxxImg.getWidth(); x++)
00350       //       printf("%10.4f ", xxxImg.getVal(x,y));
00351       //     printf("\n");
00352       //   }
00353 
00354 
00355   model.p_G1 = 0.031623;
00356 
00357   // Level 2
00358   model.p_A2 = 10.0;
00359   model.p_B2 = 1.0;
00360   model.p_C2 = 2.0;
00361   model.p_D2 = 0.01;
00362   model.p_K2 = 20.0;
00363 
00364   // Level 3
00365   model.p_A3 = 1.0;
00366   model.p_B3 = 1.0;
00367   model.p_C3 = 1.0;
00368   model.p_K3 = 2.0;
00369   model.p_A4 = 10.0;
00370   model.p_B4 = 1.0;
00371   model.p_C4 = 1.0;
00372   model.p_K4 = 2.0;
00373   
00374   // Level 4
00375   model.p_A5 = 0.1;
00376   model.p_B5 = 1.0;
00377   model.p_C5 = 0.01;
00378 
00379   // Level 5 & 6
00380   model.p_A6 = 0.5;   
00381   model.p_B6 = 1.0;
00382   model.p_C6 = 0.5;
00383   model.p_D6 = 0.5;
00384   model.p_theta6 = 0.2;
00385 
00386   
00387   if(comp == 0)
00388     {
00389       // [0 0 0 0 0]
00390       model.p_vdD.push_back(0.0);
00391       model.p_vdD.push_back(0.0);
00392       model.p_vdD.push_back(0.0);
00393       model.p_vdD.push_back(0.0);
00394       model.p_vdD.push_back(0.0);
00395     }
00396   else if(comp == 1) 
00397     {
00398       // [0 0.5 1 1 10]; 
00399       model.p_vdD.push_back(0.0);
00400       model.p_vdD.push_back(0.5);
00401       model.p_vdD.push_back(1.0);
00402       model.p_vdD.push_back(1.0);
00403       model.p_vdD.push_back(10.0);
00404     }
00405   else if(comp == 2)
00406     {
00407       // [0 0 0 0 5];
00408       model.p_vdD.push_back(0.0);
00409       model.p_vdD.push_back(0.0);
00410       model.p_vdD.push_back(0.0);
00411       model.p_vdD.push_back(0.0);
00412       model.p_vdD.push_back(5.0);
00413     }
00414   else if(comp == 3)
00415     {
00416       // [0.25 0.25 1 0.25 10];
00417       model.p_vdD.push_back(0.25);
00418       model.p_vdD.push_back(0.25);
00419       model.p_vdD.push_back(1.0);
00420       model.p_vdD.push_back(0.25);
00421       model.p_vdD.push_back(10.0);
00422     }
00423   else LFATAL("no such competitive environment");
00424 
00425   model.p_A7 = 0.5;
00426   model.p_B7 = 1.0;
00427   model.p_C7 = 4.0;
00428   model.p_D7 = 0.25;
00429   model.p_E7 = 0.25;
00430   model.p_G7 = 0.1;
00431   model.p_theta7 = 0.2;
00432   
00433   Dims sz(size.w()/(pow(2, model.p_NumSpeeds-1)),
00434           size.h()/(pow(2, model.p_NumSpeeds-1)) );
00435 
00436   // ORIGINAL
00437   //vert_pos.push_back(.5);    //1/2
00438   //vert_pos.push_back(.625);    //5/8
00439   //uint horz_spac = 3;
00440 
00441   // BROWNING
00442   std::vector<double> vert_pos;
00443   vert_pos.push_back(.25);    //1/4
00444   vert_pos.push_back(5.0/16.0);    //5/16
00445   vert_pos.push_back(.375);  //3/8 
00446   uint horz_spac = 5;
00447 
00448   // std::vector<double> vert_pos;
00449   // vert_pos.push_back(.5);    //1/2
00450   // vert_pos.push_back(9.0/16.0);    //9/16
00451   // vert_pos.push_back(.625);  //5/8 
00452   // uint horz_spac = 5;
00453 
00454   std::pair<rutz::shared_ptr<std::vector<std::vector<Image<double> > > >,
00455     std::vector<Point2D<int> > > temp =
00456   generate_w(sz, vert_pos, horz_spac, uint(pow(2, model.p_NumSpeeds-1)));
00457   model.p_w   = temp.first; 
00458   model.Rlocs = temp.second;
00459   model.p_M = vert_pos.size() * (sz.w()/horz_spac); 
00460 
00461   rutz::shared_ptr<std::vector<std::vector<Image<double> > > > p_w 
00462     = model.p_w;
00463   double min = 0;
00464   for(uint l = 0; l < model.p_w->size(); l++)
00465     {
00466       double total = 0;
00467       for(uint dir = 0; dir < 8; dir++)
00468         total += sum((*p_w)[l][dir]);
00469       if(total < min || l == 0)  min = total; 
00470     }
00471   model.p_N = min;
00472 
00473   model.p_L = generate_L(2,2,3,0.25);
00474 
00475   return model;
00476 }
00477 
00478 // ######################################################################
00479 // SUB FUNCTION: generate_L, generates the long-range filter.
00480 //function [L Nl err] = generate_L(l, sigx, sigy, k)
00481  rutz::shared_ptr<std::vector<Image<double> > > 
00482 generate_L(double l, double sigx, double sigy, double k)
00483  {
00484    // FIX: hard coded information!!!
00485     int wid = 25;
00486     int mid = 13;
00487     double th = 0.005;
00488 
00489     // L = zeros(wid,wid, 8);
00490     rutz::shared_ptr<std::vector<Image<double> > > 
00491       L(new std::vector<Image<double> >());
00492 
00493     // rot45 = [cos(45*(pi/180)) -sin(45*(pi/180)); 
00494     //          sin(45*(pi/180))  cos(45*(pi/180))];
00495     Image<double> rot45(Dims(2,2),NO_INIT);
00496     rot45.setVal(0,0,  cos(45*(M_PI/180)));
00497     rot45.setVal(1,0, -sin(45*(M_PI/180)));
00498     rot45.setVal(0,1,  sin(45*(M_PI/180)));
00499     rot45.setVal(1,1,  cos(45*(M_PI/180)));
00500 
00501     Image<double> temp1(wid, wid, ZEROS);
00502     Image<double> temp8(wid, wid, ZEROS);
00503     for(int i = 0; i < wid; i++)
00504       {
00505         for(int j = 0; j < wid; j++)
00506           {
00507             int x = i-mid+1; int y = j-mid+1;
00508 
00509             // L(i,j,1) = (l/(2*pi*sigx*sigy))*exp(-k*((x/sigx)^2 + (y/sigy)^2));
00510             double val =
00511               (l/(2*M_PI*sigx*sigy))*exp(-k*(pow(x/sigx, 2.0) + pow(y/sigy, 2.0)));
00512             temp1.setVal(j,i, val); // MATLAB: (row, column) coordinate system
00513 
00514             // nxy = round(sqrt(2)*rot45*[x;y])+mid;
00515             Image<double> t(1,2,NO_INIT);
00516             t.setVal(0,0, x); t.setVal(0,1, y);
00517             Image<double> nxy = matrixMult(rot45,t)*sqrt(2.0);
00518             double v1 = nxy.getVal(0,0); double v2 = nxy.getVal(0,1);
00519             nxy.setVal(0,0, round(v1)+ mid);
00520             nxy.setVal(0,1, round(v2)+ mid);
00521 
00522             //L(max(min(nxy(1)-x ,wid),1),max(min(nxy(2) ,wid),1),8) = L(i,j,1);
00523             uint i8 = uint(max(min(double(nxy.getVal(0)-x), double(wid)),1))-1; 
00524             uint j8 = uint(max(min(double(nxy.getVal(1)  ), double(wid)),1))-1;
00525             temp8.setVal(j8,i8, val);
00526           }
00527       }
00528 
00529     // L(:,:,1) = (L(:,:,1)>th).*L(:,:,1);
00530     for(int i = 0; i < wid; i++)
00531       for(int j = 0; j < wid; j++)
00532         {
00533           double val  = temp1.getVal(i,j);
00534           temp1.setVal(i,j, (val>th)*val);
00535         }
00536 
00537     // L(:,:,8) = (L(:,:,8)>th).*L(:,:,8);
00538     for(int i = 0; i < wid; i++)
00539       for(int j = 0; j < wid; j++)
00540         {
00541           double val  = temp8.getVal(i,j);
00542           temp8.setVal(i,j, (val>th)*val);
00543         }
00544 
00545     // err = sum(sum(L(:,:,1)))-sum(sum(L(:,:,8)));
00546 
00547     // L(:,:,5) = L(:,:,1); L(:,:,3) = rot90(L(:,:,1)); L(:,:,7) = L(:,:,3);
00548     Image<double> temp5 = temp1;
00549     Image<double> temp3(wid,wid,NO_INIT);
00550     int w2 = wid/2;
00551     for(int i = 0; i < wid; i++)
00552       for(int j = 0; j < wid; j++)
00553         temp3.setVal(w2 + (j - w2), w2 - (i - w2), temp1.getVal(i,j));
00554     Image<double> temp7 = temp3;
00555 
00556     // L(:,:,4) = L(:,:,8); L(:,:,2) = fliplr(L(:,:,8)); L(:,:,6) = L(:,:,2);
00557     Image<double> temp4 = temp8;
00558     Image<double> temp2(wid,wid,NO_INIT);
00559     for(int i = 0; i < wid; i++)
00560       for(int j = 0; j < wid; j++)
00561         temp2.setVal(int(wid-1) - i, j, temp8.getVal(i,j));
00562     Image<double> temp6 = temp2;
00563 
00564     L->push_back(temp1);
00565     L->push_back(temp2);
00566     L->push_back(temp3);
00567     L->push_back(temp4);
00568     L->push_back(temp5);
00569     L->push_back(temp6);
00570     L->push_back(temp7);
00571     L->push_back(temp8);
00572 
00573     return L;
00574  }
00575    
00576 // ######################################################################
00577 // SUB FUNCTION: generate_w, generates the template weight matrices
00578 //function [w M N] = generate_w(sz, vert_pos, horz_spac)
00579 std::pair<rutz::shared_ptr<std::vector<std::vector<Image<double> > > >,
00580           std::vector<Point2D<int> > >
00581 generate_w
00582 (Dims sz, std::vector<double> vert_pos, uint horz_spac, uint scale)
00583 {
00584   int smax = sz.w(); if(smax < sz.h()) smax = sz.h();
00585   int sizx = round(2*smax);
00586 
00587   Image<double> U(sizx*2+1, sizx*2+1, NO_INIT);
00588   Image<double> V(sizx*2+1, sizx*2+1, NO_INIT); 
00589 
00590   // FIX MESHGRID
00591   // [U, V] = meshgrid(-sizx:sizx, -sizx:sizx); 
00592   for(int i = 0; i < sizx*2+1; i++)
00593     {
00594       int x = i - sizx;
00595       for(int j = 0; j < sizx*2+1; j++)
00596         {
00597           U.setVal(i,j, x);
00598           V.setVal(j,i, x);
00599         }
00600     }
00601 
00602    // d = (4*atan2(V,U)/pi+1); d= d+(d<1)*8;
00603    Image<double> d(sizx*2+1, sizx*2+1, NO_INIT);
00604    for(int i = 0; i < sizx*2+1; i++)
00605      {
00606        for(int j = 0; j < sizx*2+1; j++)
00607          {
00608            double val = 
00609              4*atan2(V.getVal(i,j),U.getVal(i,j))/M_PI + 1.0;
00610            double val2 = val + (val<1)*8;
00611            d.setVal(i,j, val2);
00612          }
00613      }
00614 
00615    // convert to 8 directions
00616    std::vector<Image<double> > tw;
00617    Image<double> res(sizx*2+1, sizx*2+1, NO_INIT);
00618    // tw(:,:,1,1) = double(d<2).*(2-d) + double(d > 8).*(d-8); 
00619    for(int i = 0; i < sizx*2+1; i++)
00620      {
00621        for(int j = 0; j < sizx*2+1; j++)
00622          {
00623            double val  = d.getVal(i,j);
00624            double val2 = double(val<2)*(2-val) + double(val>8)*(val-8);
00625            res.setVal(i,j, val2);
00626          }
00627      }
00628    tw.push_back(res);
00629 
00630    // tw(:,:,1,2) = double(d<3&d>=2).*(3-d) + double(d>1&d<2).*(d-1);
00631    for(int i = 0; i < sizx*2+1; i++)
00632      {
00633        for(int j = 0; j < sizx*2+1; j++)
00634          {
00635            double val  = d.getVal(i,j);
00636            double val2 = double((val<3)&(val>=2))*(3-val) + 
00637              double((val>1)&(val<2))*(val-1);
00638            res.setVal(i,j, val2);
00639          }
00640      }
00641    tw.push_back(res);
00642 
00643    // tw(:,:,1,3) = double(d<4&d>=3).*(4-d) + double(d>2&d<3).*(d-2);
00644    for(int i = 0; i < sizx*2+1; i++)
00645      {
00646        for(int j = 0; j < sizx*2+1; j++)
00647          {
00648            double val  = d.getVal(i,j);
00649            double val2 = double((val<4)&(val>=3))*(4-val) + 
00650              double((val>2)&(val<3))*(val-2);
00651            res.setVal(i,j, val2);
00652          }
00653      }
00654    tw.push_back(res);
00655 
00656    // tw(:,:,1,4) = double(d<5&d>=4).*(5-d) + double(d>3&d<4).*(d-3);
00657    for(int i = 0; i < sizx*2+1; i++)
00658      {
00659        for(int j = 0; j < sizx*2+1; j++)
00660          {
00661            double val  = d.getVal(i,j);
00662            double val2 = double((val<5)&(val>=4))*(5-val) + 
00663              double((val>3)&(val<4))*(val-3);
00664            res.setVal(i,j, val2);
00665          }
00666      }
00667    tw.push_back(res);
00668 
00669    // tw(:,:,1,5) = double(d<6&d>=5).*(6-d) + double(d>4&d<5).*(d-4);
00670    for(int i = 0; i < sizx*2+1; i++)
00671      {
00672        for(int j = 0; j < sizx*2+1; j++)
00673          {
00674            double val  = d.getVal(i,j);
00675            double val2 = double((val<6)&(val>=5))*(6-val) + 
00676              double((val>4)&(val<5))*(val-4);
00677            res.setVal(i,j, val2);
00678          }
00679      }
00680    tw.push_back(res);
00681 
00682    // tw(:,:,1,6) = double(d<7&d>=6).*(7-d) + double(d>5&d<6).*(d-5);
00683    for(int i = 0; i < sizx*2+1; i++)
00684      {
00685        for(int j = 0; j < sizx*2+1; j++)
00686          {
00687            double val  = d.getVal(i,j);
00688            double val2 = double((val<7)&(val>=6))*(7-val) + 
00689              double((val>5)&(val<6))*(val-5);
00690            res.setVal(i,j, val2);
00691          }
00692      }
00693    tw.push_back(res);
00694 
00695    // tw(:,:,1,7) = double(d<8&d>=7).*(8-d) + double(d>6&d<7).*(d-6);
00696    for(int i = 0; i < sizx*2+1; i++)
00697      {
00698        for(int j = 0; j < sizx*2+1; j++)
00699          {
00700            double val  = d.getVal(i,j);
00701            double val2 = double((val<8)&(val>=7))*(8-val) + 
00702              double((val>6)&(val<7))*(val-6);
00703            res.setVal(i,j, val2);
00704          }
00705      }
00706    tw.push_back(res);
00707 
00708    // tw(:,:,1,8) = double(d>=8).*(9-d) + double(d>7&d<8).*(d-7);
00709    for(int i = 0; i < sizx*2+1; i++)
00710      {
00711        for(int j = 0; j < sizx*2+1; j++)
00712          {
00713            double val  = d.getVal(i,j);
00714            double val2 = double(val>=8)*(9-val) + 
00715              double((val>7)&(val<8))*(val-7);
00716            res.setVal(i,j, val2);
00717          }
00718      }
00719    tw.push_back(res);
00720 
00721    // for d=1:8, tw(sizx+1, sizx+1,1,d) = 1; end
00722    for(uint i = 0; i < 8; i++) tw[i].setVal(sizx,sizx, 1.0);
00723 
00724    // counter = 0;
00725    // w=zeros(sz(1), sz(2), 1, 8);
00726    rutz::shared_ptr<std::vector<std::vector<Image<double> > > > 
00727      w(new std::vector<std::vector<Image<double> > >());
00728 
00729    std::vector<Point2D<int> > rlocs;
00730 
00731    uint maxVert = vert_pos.size();  
00732    uint maxHorz = sz.w()/horz_spac;
00733    // for vert=[round(vert_pos*sz(1))]
00734    //     for horz=round(horz_spac/2):horz_spac:sz(2)
00735    //         counter = counter + 1;
00736    for(uint i = 0; i < maxVert; i++)
00737      {
00738        int  vert = round(vert_pos[i]*sz.h());
00739        for(uint j = 0; j < maxHorz; j++)
00740          {
00741            int horz = (horz_spac/2) + j*horz_spac;
00742 
00743            std::vector<Image<double> > temp;
00744 
00745            // w(:,:, counter,:) =  tw(sizx-vert   : sizx+((size(w,1)-1)-vert), 
00746            //                         sizx-horz+2 : sizx+((size(w,2)-1)-horz+2),
00747            //                         1, :);
00748            int t = sizx-vert - 1;
00749            int b = sizx+((sz.h()-1) -vert) - 1;
00750            int l = sizx-horz+0;
00751            int r = sizx+((sz.w()-1) - horz+0);
00752            for(uint k = 0; k < 8; k++)
00753              {
00754                temp.push_back(crop(tw[k],Rectangle::tlbrI(t,l,b,r)));
00755              }
00756            //LINFO("[sizx: %d vert:%d horz:%d] t:%d b:%d l:%d r:%d", 
00757            //  sizx, vert, horz, t,b,l,r);
00758            w->push_back(temp);
00759 
00760            rlocs.push_back(Point2D<int>(horz*scale, vert*scale));
00761            //LINFO("scale: %d [%3d %3d]", scale, horz*scale, vert*scale);
00762          }
00763      }
00764 
00765    std::pair<rutz::shared_ptr<std::vector<std::vector<Image<double> > > >,
00766     std::vector<Point2D<int> > > temp(w, rlocs);   
00767   return temp;
00768 }
00769 
00770 // ######################################################################
00771 void initializeModel(ViSTARSmodel &model, Image<double> stim)
00772 {
00773   rutz::shared_ptr<ViSTARSmodelState> 
00774     state( new ViSTARSmodelState());
00775 
00776   uint ws = 0, hs = 0;
00777   for(uint i = 0; i < model.p_NumSpeeds; i++)
00778     {
00779       // shrink the image properly
00780       // s = ['s' num2str(ss)];
00781       // if ss == 1, model.I.(s)(:,:,1) = stim(:,:,1);
00782       // else model.I.(s)(:,:,1) = shrink(stim(:,:,1), 2^(ss-1));
00783       // end
00784       // model.I.(s)(:,:,2) =  1-model.I.(s)(:,:,1);
00785       std::vector<Image<double> > tI;
00786       if(i == 0) 
00787         {
00788           // the stimuli and its negative
00789           tI.push_back(stim);
00790           tI.push_back((stim*-1.0) + 1.0);
00791         }
00792       else   
00793         {
00794           Image<double> temp = shrink(stim, pow(2, i));
00795           tI.push_back(temp);
00796           tI.push_back((temp*-1.0) + 1.0);
00797         }
00798 
00799       // uint sj = 0, ej = 20, si = 0, ei = 20;
00800       // LINFO("s[%d] cs[%d]", i, 0);
00801       // for(uint y = sj; y < ej; y++)
00802       //   {
00803       //     for(uint x = si; x < ei; x++)
00804       //       printf("%10.4f ", tI[0].getVal(x,y));
00805       //     printf("\n");
00806       //   }
00807       // LINFO("s[%d] cs[%d]", i, 1);
00808       // for(uint y = sj; y < ej; y++)
00809       //   {
00810       //     for(uint x = si; x < ei; x++)
00811       //       printf("%10.4f ", tI[1].getVal(x,y));
00812       //     printf("\n");
00813       //   }
00814       // Raster::waitForKey();
00815       
00816 
00817       state->I.push_back(tI);
00818       
00819       uint width  = tI[0].getWidth();
00820       uint height = tI[0].getHeight();
00821 
00822       // model.a.(s) = zeros(size(model.I.(s),1), size(model.I.(s),2), 2);
00823       std::vector<Image<double> > tA;
00824       Image<double> tA1(width, height, ZEROS);
00825       Image<double> tA2(width, height, ZEROS);
00826       tA.push_back(tA1);
00827       tA.push_back(tA2);
00828       state->a.push_back(tA);
00829 
00830       // model.b.(s) = model.a.(s);
00831       std::vector<Image<double> > tB;
00832       Image<double> tB1(width, height, ZEROS);
00833       Image<double> tB2(width, height, ZEROS);
00834       tB.push_back(tB1);
00835       tB.push_back(tB2);
00836       state->b.push_back(tB);
00837 
00838       // model.x.(s) = model.a.(s); 
00839       std::vector<Image<double> > tX;
00840       Image<double> tX1(width, height, ZEROS);
00841       Image<double> tX2(width, height, ZEROS);
00842       tX.push_back(tX1);
00843       tX.push_back(tX2);
00844       state->x.push_back(tX);
00845 
00846       // model.y.(s) = model.a.(s);
00847       std::vector<Image<double> > tY;
00848       Image<double> tY1(width, height, ZEROS);
00849       Image<double> tY2(width, height, ZEROS);
00850       tY.push_back(tY1);
00851       tY.push_back(tY2);
00852       state->y.push_back(tY);
00853 
00854       // model.z.(s) = ones(size(model.I.(s),1), size(model.I.(s),2), 2);
00855       std::vector<Image<double> > tZ;
00856       Image<double> tZ1(width, height, ZEROS);
00857       Image<double> tZ2(width, height, ZEROS);
00858       tZ.push_back(tZ1+1.0);
00859       tZ.push_back(tZ2+1.0);
00860       state->z.push_back(tZ);
00861 
00862       // model.c.(s) = zeros(size(model.I.(s),1), size(model.I.(s),2), 2, 8);
00863       std::vector<std::vector<Image<double> > > tC;
00864       for(uint j = 0; j < NUM_DIRS; j++)
00865         {
00866           std::vector<Image<double> > tC1;
00867 
00868           Image<double> tC11(width, height, ZEROS);
00869           Image<double> tC12(width, height, ZEROS);
00870           tC1.push_back(tC11);
00871           tC1.push_back(tC12);
00872 
00873           tC.push_back(tC1);
00874         }
00875       state->c.push_back(tC);
00876       
00877       // model.e.(s) = model.c.(s);
00878       std::vector<std::vector<Image<double> > > tE;
00879       for(uint j = 0; j < NUM_DIRS; j++)
00880         {
00881           std::vector<Image<double> > tE1;
00882 
00883           Image<double> tE11(width, height, ZEROS);
00884           Image<double> tE12(width, height, ZEROS);
00885           tE1.push_back(tE11);
00886           tE1.push_back(tE12);
00887 
00888           tE.push_back(tE1);
00889         }
00890       state->e.push_back(tE);
00891 
00892       // model.f.(s) = zeros(size(model.I.(s),1), size(model.I.(s),2), 1, 8);
00893       std::vector<Image<double> > tF;
00894       for(uint j = 0; j < NUM_DIRS; j++)
00895         {
00896           Image<double> tF1(width, height, ZEROS);
00897           tF.push_back(tF1);
00898         }
00899       state->f.push_back(tF);
00900 
00901       if(i == model.p_NumSpeeds-1)
00902         {
00903           ws = width;
00904           hs = height;
00905         }
00906     }
00907 
00908   // model.q = zeros(size(model.I.(s),1), size(model.I.(s),2), 1, 8);
00909   std::vector<Image<double> > tq;
00910   for(uint i = 0; i < NUM_DIRS; i++)
00911     {
00912       Image<double> tq1(ws, hs, ZEROS);
00913       tq.push_back(tq1);
00914     }
00915   state->q = tq;
00916 
00917   // model.Q = model.q;
00918   std::vector<Image<double> > tQ;
00919   for(uint i = 0; i < NUM_DIRS; i++)
00920     {
00921       Image<double> tQ1(ws, hs, ZEROS);
00922       tQ.push_back(tQ1);
00923     }
00924   state->Q = tQ;
00925 
00926   // model.m = model.q;
00927   std::vector<Image<double> > tm;
00928   for(uint i = 0; i < NUM_DIRS; i++)
00929     {
00930       Image<double> tm1(ws, hs, ZEROS);
00931       tm.push_back(tm1);
00932     }
00933   state->m = tm;
00934 
00935   // model.r = zeros(model.p.M, 1);
00936   state->r = std::vector<double>(model.p_M);
00937   for(uint i = 0; i < model.p_M; i++)
00938     state->r[i] = 0.0;
00939 
00940   // model.R = model.r;
00941   state->R = std::vector<double>(model.p_M);
00942   for(uint i = 0; i < model.p_M; i++)
00943     state->R[i] = 0.0;
00944 
00945   model.state = state;
00946 }
00947 
00948 // ######################################################################
00949 // SUB FUNCTION: shrink is used to sum over groups of cells to shrink the array.
00950 // function x = shrink(y, f)
00951 Image<double> shrink(Image<double> y, double f)
00952 {
00953   //if f > 1, ff = 1/f; 
00954   // else ff = f; f = 1/ff; end
00955   double ff;
00956   if(f> 1) { ff = 1/f; }
00957   else     { ff = f; f = 1/ff; } 
00958 
00959   uint w = y.getWidth();
00960   uint h = y.getHeight();
00961   uint width  = floor(w*ff);
00962   uint height = floor(h*ff);
00963   Image<double> x(width, height, NO_INIT);
00964 
00965   //LINFO("f: %f, ff:%f width: %d height: %d", f,ff,width,height);
00966 
00967   // SKIP this dimension: for t = 1:size(y,3) --> it's 1
00968 
00969   //for i=1:floor(size(y,1)*ff)
00970   //  for j=1:floor(size(y,2)*ff)
00971   for(uint i = 0; i < width; i++)
00972     for(uint j = 0; j < height; j++)
00973       {       
00974         // x(i,j,t,:) = sum(sum(y(i*f-f+1:i*f, j*f-f+1:j*f, t, :)))/f^2;
00975         double val = 0.0;
00976         uint sk = uint((i+1)*f-f);
00977         uint ek = uint((i+1)*f);
00978 
00979         uint sl = uint((j+1)*f-f);
00980         uint el = uint((j+1)*f);
00981         
00982         for(uint k = sk; k < ek; k++)
00983           for(uint l = sl; l < el; l++)
00984               val += y.getVal(k,l);
00985         //LINFO("val  %f", val);
00986         val /= (f*f);
00987         //LINFO("%f val/f2  %f", f*f, val/(f*f));
00988         x.setVal(i,j,val);       
00989 
00990         //LINFO("sk:%d ek:%d sl:%d el:%d : %f", sk, ek, sl, el,val);
00991         //Raster::waitForKey();
00992       }
00993 
00994   return x;
00995 }
00996 
00997 // ######################################################################
00998 Point2D<int> getFOE(ViSTARSmodel &model, Image<double> stim)
00999 {  
01000   // update the frame
01001   updateFrame(model, stim);
01002 
01003   Point2D<int> foe;
01004   uint nstep = uint(1.0/tstep);
01005   for(uint i = 0; i < nstep; i++)
01006     {
01007       // run model
01008       foe = bgm_2007(model);
01009 
01010       // logging, reporting, scripts etc
01011       report(model); 
01012     }
01013 
01014   FILE *fp;      
01015   LINFO("FOE%d %d", foe.i, foe.j);
01016   if((fp = fopen("BMG_walking.txt","at")) == NULL) LFATAL("not found");
01017   fputs(sformat("%d %d \n", foe.i, foe.j).c_str(), fp);
01018   fclose (fp);  
01019 
01020   return foe;
01021 }
01022 
01023 // ######################################################################
01024 void updateFrame(ViSTARSmodel &model, Image<double> stim)
01025 {
01026   //     for ss=1:model.p.NumSpeeds
01027   std::vector<std::vector<Image<double> > > tI(model.p_NumSpeeds);
01028   for(uint i = 0; i < model.p_NumSpeeds; i++)
01029     {
01030       // shrink the image properly
01031       // s = ['s' num2str(ss)];
01032       // if ss == 1, model.I.(s)(:,:,1) = stim(:,:,1);
01033       // else model.I.(s)(:,:,1) = shrink(stim(:,:,1), 2^(ss-1));
01034       // end
01035       // model.I.(s)(:,:,2) =  1-model.I.(s)(:,:,1);
01036       std::vector<Image<double> > tIcs;
01037       if(i == 0) 
01038         {
01039           // the stimuli and its negative
01040           tIcs.push_back(stim);
01041           tIcs.push_back((stim*-1.0) + 1.0);
01042         }
01043       else   
01044         {
01045           Image<double> temp = shrink(stim, pow(2, i));
01046           tIcs.push_back(temp);
01047           tIcs.push_back((temp*-1.0) + 1.0);
01048         }
01049       tI[i] = tIcs;
01050     }
01051   model.state->I = tI;
01052 }
01053 
01054 uint mainIndex = 0;
01055 // ######################################################################
01056 Point2D<int> bgm_2007(ViSTARSmodel &model)
01057 {
01058   // Since s corresponds to the scale of the input it cannot be easily
01059   // incorporated into a higher dimensional matrix, therefore a structure is
01060   // used, indexes i and j are the first 2 dimensions of the matrix, on-off
01061   // index (p) is the 3rd dimension of the matrix, direction index(d) is
01062   // included as the 4th dimension of the matrix
01063 
01064   // get the parameters from the input and reduce notation
01065   //p = in.p; o.p = p;
01066   
01067   // run the simulation
01068   //for ss=1:p.NumSpeeds
01069   //   s = ['s' num2str(ss)];
01070 
01071   std::vector<std::vector<Image<double> > > oI(model.p_NumSpeeds);
01072   std::vector<std::vector<Image<double> > > oa(model.p_NumSpeeds);
01073   std::vector<std::vector<Image<double> > > ob(model.p_NumSpeeds);
01074   std::vector<std::vector<Image<double> > > ox(model.p_NumSpeeds);
01075   std::vector<std::vector<Image<double> > > oy(model.p_NumSpeeds);
01076   std::vector<std::vector<Image<double> > > oz(model.p_NumSpeeds);
01077   std::vector<std::vector<std::vector<Image<double> > > > oc(model.p_NumSpeeds);
01078   std::vector<std::vector<std::vector<Image<double> > > > oe(model.p_NumSpeeds);
01079   std::vector<std::vector<Image<double> > > of(model.p_NumSpeeds);
01080   std::vector<Image<double> > om(NUM_DIRS);
01081       
01082   for(uint s = 0; s < model.p_NumSpeeds; s++)
01083     {
01084       // The input needs to be scaled and the on-off channels need to be
01085       // segregated such that in.I.s holds the scaled inputs
01086      
01087       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
01088       // Level 1, On-Center-Off-Surround Processing for Boundaries
01089       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01090       //I = in.I.(s); a = in.a.(s); b = in.b.(s); o.I.(s) = I;
01091       std::vector<Image<double> > I   = model.state->I[s];
01092       std::vector<Image<double> > a   = model.state->a[s];
01093       std::vector<Image<double> > b   = model.state->b[s];
01094       std::vector<Image<double> > oIs = model.state->I[s];
01095       std::vector<Image<double> > oas(NUM_CS);
01096       std::vector<Image<double> > obs(NUM_CS);
01097 
01098       std::vector<Image<double> > sumfxy = sumFxyI(model.p_Fxy,I);
01099       for(uint cs = 0; cs < NUM_CS; cs++)
01100         {
01101           // o.a.(s) = a + tstep*(-p.A1*a + (p.B1 - a).*I*p.C1 - 
01102           //                      (p.D1 + a).*sumFxyI(p.Fxy, I)   ); % 1.1
01103           oas[cs] = a[cs] +  ((a[cs]*-model.p_A1) + 
01104                               ((a[cs]*-1.0) + model.p_B1)*I[cs]*model.p_C1 -
01105                               (a[cs] + model.p_D1)*sumfxy[cs]
01106                               )*tstep;
01107 
01108           // tr = max(o.a.(s)-in.p.phi1, 0).^2
01109           uint w = oas[cs].getWidth();
01110           uint h = oas[cs].getHeight();
01111           Image<double> temp = oas[cs] - model.p_phi1;
01112           Image<double> temp2(w, h, ZEROS);
01113           Image<double> temp3 = takeMax(temp,temp2);
01114           Image<double> tr = temp3*temp3;
01115 
01116  // LINFO("I s[%d] cs[%d]", s, cs);
01117  // uint sj = 0, ej = 20, si = 0, ei = 20;
01118  // for(uint y = sj; y < ej; y++)
01119  //   {
01120  //     for(uint x = si; x < ei; x++)
01121  //       printf("%10.4f ", I[cs].getVal(x,y));
01122  //     printf("\n");
01123  //   }
01124  //  Raster::waitForKey();
01125  // LINFO("a s[%d] cs[%d]", s, cs);
01126  // //uint sj = 0, ej = 20, si = 0, ei = 20;
01127  // for(uint y = sj; y < ej; y++)
01128  //   {
01129  //     for(uint x = si; x < ei; x++)
01130  //       printf("%10.4f ", a[cs].getVal(x,y));
01131  //     printf("\n");
01132  //   }
01133  // Raster::waitForKey();
01134 
01135 
01136  //  LINFO("p_A1: %f", model.p_A1);
01137  //  LINFO("p_B1: %f", model.p_B1);
01138  //  LINFO("p_C1: %f", model.p_C1);
01139  //  LINFO("p_D1: %f", model.p_D1);
01140                     
01141 
01142 
01143  //  Image<double> sfxy = sumfxy[cs];
01144  // LINFO("sfxy");
01145  // //uint sj = 0, ej = 20, si = 0, ei = 20;
01146  // for(uint y = sj; y < ej; y++)
01147  //   {
01148  //     for(uint x = si; x < ei; x++)
01149  //       printf("%10.4f ", sfxy.getVal(x,y));
01150  //     printf("\n");
01151  //   }
01152  // Raster::waitForKey();
01153 
01154 
01155  // LINFO("oas s[%d] cs[%d]", s, cs);
01156  // //uint sj = 0, ej = 20, si = 0, ei = 20;
01157  // for(uint y = sj; y < ej; y++)
01158  //   {
01159  //     for(uint x = si; x < ei; x++)
01160  //       printf("%10.4f ", oas[cs].getVal(x,y));
01161  //     printf("\n");
01162  //   }
01163  // Raster::waitForKey();
01164        
01165  // LINFO("I %20.10f ", I[cs].getVal(0,19));
01166  // LINFO("a %20.10f ", a[cs].getVal(0,19));
01167  // LINFO("s %20.10f ", sfxy.getVal(0,19));
01168  // LINFO("o %20.10f ", oas[cs].getVal(0,19));
01169 
01170  // LINFO("%20.10f %20.10f %20.10f %20.10f ", 
01171  //       model.p_A1, model.p_B1, model.p_C1, model.p_D1);
01172 
01173  // Image<double> aaa = a[cs]*-model.p_A1;
01174  // Image<double> bbb = ((a[cs]*-1.0) + model.p_B1)*I[cs]*model.p_C1;
01175  // Image<double> ccc = (a[cs] + model.p_D1)*sumfxy[cs];
01176 
01177  // LINFO("aaa %20.10f ", aaa.getVal(0,19));
01178  // LINFO("bbb %20.10f ", bbb.getVal(0,19));
01179  // LINFO("ccc %20.10f ", ccc.getVal(0,19));
01180 
01181           // LINFO("temp s[%d] cs[%d]", s, cs);
01182           // for(uint y = sj; y < ej; y++)
01183           //   {
01184           //     for(uint x = si; x < ei; x++)
01185           //       printf("%10.4f ", temp.getVal(x,y));
01186           //     printf("\n");
01187           //   }
01188 
01189           // Raster::waitForKey();
01190 
01191 
01192           // LINFO("temp3 s[%d] cs[%d]", s, cs);
01193           // for(uint y = sj; y < ej; y++)
01194           //   {
01195           //     for(uint x = si; x < ei; x++)
01196           //       printf("%10.4f ", temp3.getVal(x,y));
01197           //     printf("\n");
01198           //   }
01199           // Raster::waitForKey();
01200          
01201           // LINFO("tr s[%d] cs[%d]", s, cs);
01202           // for(uint y = sj; y < ej; y++)
01203           //   {
01204           //     for(uint x = si; x < ei; x++)
01205           //       printf("%10.4f ", tr.getVal(x,y));
01206           //     printf("\n");
01207           //   }
01208           // Raster::waitForKey();
01209 
01210 
01211           //o.b.(s) = tr ./ (p.G1^2 + tr);                           % 1.3
01212           obs[cs] = tr / (tr + pow(model.p_G1,2.0));
01213 
01214   // LINFO("obs s[%d] cs[%d]", s, cs);
01215   // //uint sj = 0, ej = 20, si = 0, ei = 20;
01216   // for(uint y = sj; y < ej; y++)
01217   //   {
01218   //     for(uint x = si; x < ei; x++)
01219   //       printf("%10.4f ", obs[cs].getVal(x,y));
01220   //     printf("\n");
01221   //   }
01222   // Raster::waitForKey();
01223  
01224 
01225 
01226 
01227 
01228 
01229 
01230 
01231         }
01232       //clear I a tr;
01233 
01234 
01235       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01236       // Level 2, Transient Cells
01237       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01238       //x = in.x.(s); z = in.z.(s); y = in.y.(s);
01239       std::vector<Image<double> > x  = model.state->x[s];
01240       std::vector<Image<double> > y  = model.state->y[s];
01241       std::vector<Image<double> > z  = model.state->z[s];
01242 
01243       std::vector<Image<double> > oxs(NUM_CS);
01244       std::vector<Image<double> > oys(NUM_CS);
01245       std::vector<Image<double> > ozs(NUM_CS);
01246 
01247       for(uint cs = 0; cs < NUM_CS; cs++)
01248         {
01249           //uint sj = 0, ej = 20, si = 0, ei = 20;
01250  // LINFO("(((((((((((((())))))))))))))))x s[%d] cs[%d]", s, cs);
01251  // for(uint j = sj; j < ej; j++)
01252  //   {
01253  //     for(uint i = si; i < ei; i++)
01254  //       printf("%10.4f ", x[cs].getVal(i,j));
01255  //     printf("\n");
01256  //   }
01257  // Raster::waitForKey();
01258 
01259  // LINFO("b s[%d] cs[%d]", s, cs);
01260  // for(uint j = sj; j < ej; j++)
01261  //   {
01262  //     for(uint i = si; i < ei; i++)
01263  //       printf("%10.4f ", b[cs].getVal(i,j));
01264  //     printf("\n");
01265  //   }
01266  // Raster::waitForKey();
01267 
01268 
01269 
01270 
01271 
01272 
01273 
01274 
01275 
01276 
01277 
01278           //o.x.(s) = x + tstep*(p.A2*(-p.B2*x + (p.C2-x).*b));       % 2.1
01279           oxs[cs] =  x[cs] + (((x[cs]*-model.p_B2) + 
01280                                ((x[cs]*-1.0) + model.p_C2)*b[cs])*model.p_A2)*tstep;
01281 
01282           // double first = x[cs].getVal(0,0);
01283           // double secon = b[cs].getVal(0,0);
01284 
01285           // double val = x[cs].getVal(0,0) + (((x[cs].getVal(0,0)*-model.p_B2) + 
01286           //                                   ((x[cs].getVal(0,0)*-1.0) + model.p_C2)*b[cs].getVal(0,0))*model.p_A2)*tstep;
01287           // LINFO("x: %f b: %f p: A2: %f B2: %f C2: %f val: %f ", first, secon, model.p_A2, model.p_B2, model.p_C2, val);
01288 
01289 
01290  // Raster::waitForKey();
01291 
01292 
01293 
01294 
01295 
01296           
01297           //o.z.(s) = z + tstep*(p.D2*(1 - z - p.K2*x.*z));           % 2.2
01298           ozs[cs] =  z[cs] + (((z[cs]*-1.0) - (x[cs]*z[cs]*model.p_K2) + 1.0)*model.p_D2)*tstep;          
01299 
01300           //o.y.(s) = max(o.x.(s).*o.z.(s),0);                        % 2.3
01301           uint w = oxs[cs].getWidth();
01302           uint h = oxs[cs].getHeight();
01303           Image<double> temp(w, h, ZEROS);
01304           oys[cs] = takeMax(oxs[cs]*ozs[cs], temp);
01305 
01306 
01307  // LINFO("oxs s[%d] cs[%d]", s, cs);
01308  // for(uint j = sj; j < ej; j++)
01309  //   {
01310  //     for(uint i = si; i < ei; i++)
01311  //       printf("%10.4f ", oxs[cs].getVal(i,j));
01312  //     printf("\n");
01313  //   }
01314 
01315  // LINFO("oys s[%d] cs[%d]", s, cs);
01316  // for(uint j = sj; j < ej; j++)
01317  //   {
01318  //     for(uint i = si; i < ei; i++)
01319  //       printf("%10.4f ", oys[cs].getVal(i,j));
01320  //     printf("\n");
01321  //   }
01322 
01323  // LINFO("ozs s[%d] cs[%d]", s, cs);
01324  // for(uint j = sj; j < ej; j++)
01325  //   {
01326  //     for(uint i = si; i < ei; i++)
01327  //       printf("%10.4f ", ozs[cs].getVal(i,j));
01328  //     printf("\n");
01329  //   }
01330 
01331 
01332  // LINFO("oxs %20.10f ", oxs[cs].getVal(0,76));
01333  // LINFO("oys %20.10f ", oxs[cs].getVal(0,76));
01334  // LINFO("ozs %20.10f ", oxs[cs].getVal(0,76));
01335  // LINFO("b   %20.10f ",   b[cs].getVal(0,76));
01336 
01337 
01338         }
01339 
01340       //clear b x z;
01341       
01342       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01343       // Level 3, Directional Transient Cells 
01344       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01345       //c = in.c.(s); e = in.e.(s); 
01346       std::vector<std::vector<Image<double> > > c  = model.state->c[s];
01347       std::vector<std::vector<Image<double> > > e  = model.state->e[s];
01348 
01349       std::vector<std::vector<Image<double> > >ocs(NUM_DIRS);
01350       std::vector<std::vector<Image<double> > >oes(NUM_DIRS);
01351       
01352       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01353       // It is possible to do this algorithmically as shown in this
01354       // commented code but it's faster to hard code each direction as
01355       // implemented below.
01356       //      for d=1:8
01357       //      if d < 5, D =d+4; else D = d-4; end
01358       //      theta = (d-1)*(2*pi/8); xd =round(cos(theta)); yd=round(sin(theta));
01359       //
01360       //      XY = [zeros((yd==-1), size(I,2)); 
01361       //            zeros(size(I,1)-(yd~=0), xd==-1) c((yd==1)+1:end-(yd==-1),(xd==1)+1:end-(xd==-1),t,D) zeros(size(I,1)-(yd~=0), xd==1); 
01362       //            zeros((yd==1), size(I,2))];
01363       //
01364       //      c(:,:,t+1, d) = max(c(:,:,t,d) + tstep*(Ac*(-Bc*c(:,:,t,d)+Cc*I(:,:,it) - Kc*XY )),0);
01365       //      e(:,:,t+1, d) = max(e(:,:,t,d) + tstep*(Ae*(-Be*e(:,:,t,d)+Ce*I(:,:,it) - Ke*XY )),0);
01366       //   end
01367       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01368 
01369       for(uint cs = 0; cs < NUM_CS; cs++)
01370         {
01371 
01372           // LINFO("c   %20.10f ", c[0][cs].getVal(0,19));
01373           // LINFO("e   %20.10f ", e[0][cs].getVal(0,19));
01374 
01375           //nm = size(c);
01376           uint cWidth  = c[0][cs].getWidth();
01377           uint cHeight = c[0][cs].getHeight();
01378 
01379           // Rightward direction
01380           //XY = max( [c(:,2:end,:,5) zeros(nm(1), 1,2)],0);
01381           Image<double> XY0(cWidth,cHeight,ZEROS);
01382           for(uint i = 0; i < cWidth-1; i++)
01383             for(uint j = 0; j < cHeight; j++)
01384               {
01385                 double v = c[4][cs].getVal(i+1,j);
01386                 double val = 0.0;
01387                 if(v > 0.0) val = v;
01388                 XY0.setVal(i,j, val);
01389               }
01390 
01391           //o.c.(s)(:,:,:,1) = 
01392           //  c(:,:,:,1) + 
01393           //  tstep*(p.A3*(-p.B3*c(:,:,:,1) + p.C3*y - p.K3*XY));  % 3.1
01394           ocs[0].push_back
01395             (c[0][cs] + 
01396              (((c[0][cs]*-model.p_B3) + 
01397                y[cs]*model.p_C3 - XY0*model.p_K3)*model.p_A3)*tstep);
01398 
01399           //o.e.(s)(:,:,:,1) = 
01400           //  e(:,:,:,1) + 
01401           //  tstep*(p.A4*(-p.B4*e(:,:,:,1) + p.C4*y - p.K4*XY));  % 3.2
01402           oes[0].push_back
01403             (e[0][cs] + 
01404              (((e[0][cs]*-model.p_B4) + 
01405                y[cs]*model.p_C4 - XY0*model.p_K4)*model.p_A4)*tstep);          
01406 
01407           // UP-Rightward direction
01408           //XY = max( [c(2:end,2:end,:,6) zeros(nm(1)-1, 1,2); 
01409           //           zeros(1, nm(2),2)],0);
01410           Image<double> XY1(cWidth,cHeight,ZEROS);
01411           for(uint i = 0; i < cWidth-1; i++)
01412             for(uint j = 0; j < cHeight-1; j++)
01413               {
01414                 double v = c[5][cs].getVal(i+1,j+1);
01415                 double val = 0.0;
01416                 if(v > 0.0) val = v;
01417                 XY1.setVal(i,j, val);
01418               }
01419 
01420           //o.c.(s)(:,:,:,2) = 
01421           //  c(:,:,:,2) + 
01422           //  tstep*(p.A3*(-p.B3*c(:,:,:,2) + p.C3*y - p.K3*XY));  % 3.1 
01423           ocs[1].push_back
01424             (c[1][cs] + 
01425              (((c[1][cs]*-model.p_B3) + 
01426                y[cs]*model.p_C3 - XY1*model.p_K3)*model.p_A3)*tstep);
01427 
01428           //o.e.(s)(:,:,:,2) = 
01429           //  e(:,:,:,2) + 
01430           //  tstep*(p.A4*(-p.B4*e(:,:,:,2) + p.C4*y - p.K4*XY));  % 3.2
01431           oes[1].push_back
01432             (e[1][cs] + 
01433              (((e[1][cs]*-model.p_B4) + 
01434                y[cs]*model.p_C4 - XY1*model.p_K4)*model.p_A4)*tstep);          
01435                     
01436           // Upward direction
01437           //XY = max( [c(2:end,:,:,7); zeros(1, nm(2),2) ],0);
01438           Image<double> XY2(cWidth,cHeight,ZEROS);
01439           for(uint i = 0; i < cWidth; i++)
01440             for(uint j = 0; j < cHeight-1; j++)
01441               {
01442                 double v = c[6][cs].getVal(i,j+1);
01443                 double val = 0.0;
01444                 if(v > 0.0) val = v;
01445                 XY2.setVal(i,j, val);
01446               }
01447 
01448           //o.c.(s)(:,:,:,3) = 
01449           //  c(:,:,:,3) + 
01450           //  tstep*(p.A3*(-p.B3*c(:,:,:,3) + p.C3*y - p.K3*XY));  % 3.1 
01451           ocs[2].push_back
01452             (c[2][cs] + 
01453              (((c[2][cs]*-model.p_B3) + 
01454                y[cs]*model.p_C3 - XY2*model.p_K3)*model.p_A3)*tstep);
01455 
01456           //o.e.(s)(:,:,:,3) = 
01457           //  e(:,:,:,3) + 
01458           //  tstep*(p.A4*(-p.B4*e(:,:,:,3) + p.C4*y - p.K4*XY));  % 3.2
01459           oes[2].push_back
01460             (e[2][cs] + 
01461              (((e[2][cs]*-model.p_B4) + 
01462                y[cs]*model.p_C4 - XY2*model.p_K4)*model.p_A4)*tstep);          
01463                     
01464           // Up-Leftward direction
01465           //XY = max( [zeros(nm(1)-1, 1,2) c(2:end,1:end-1,:,8); 
01466           //           zeros(1, nm(2),2) ],0);
01467           Image<double> XY3(cWidth,cHeight,ZEROS);
01468           for(uint i = 1; i < cWidth; i++)
01469             for(uint j = 0; j < cHeight-1; j++)
01470               {
01471                 double v = c[7][cs].getVal(i-1,j+1);
01472                 double val = 0.0;
01473                 if(v > 0.0) val = v;
01474                 XY3.setVal(i,j, val);
01475               }
01476 
01477           //o.c.(s)(:,:,:,4) = 
01478           //  c(:,:,:,4) + 
01479           //  tstep*(p.A3*(-p.B3*c(:,:,:,4) + p.C3*y - p.K3*XY));  % 3.1 
01480           ocs[3].push_back
01481             (c[3][cs] + 
01482              (((c[3][cs]*-model.p_B3) + 
01483                y[cs]*model.p_C3 - XY3*model.p_K3)*model.p_A3)*tstep);
01484 
01485           //o.e.(s)(:,:,:,4) = 
01486           //  e(:,:,:,4) + 
01487           //  tstep*(p.A4*(-p.B4*e(:,:,:,4) + p.C4*y - p.K4*XY));  % 3.2
01488           oes[3].push_back
01489             (e[3][cs] + 
01490              (((e[3][cs]*-model.p_B4) + 
01491                y[cs]*model.p_C4 - XY3*model.p_K4)*model.p_A4)*tstep);
01492           
01493           // Leftward direction
01494           //XY =  max( [zeros(nm(1), 1,2) c(:,1:end-1,:,1) ],0);
01495           Image<double> XY4(cWidth,cHeight,ZEROS);
01496           for(uint i = 1; i < cWidth; i++)
01497             for(uint j = 0; j < cHeight; j++)
01498               {
01499                 double v = c[0][cs].getVal(i-1,j);
01500                 double val = 0.0;
01501                 if(v > 0.0) val = v;
01502                 XY4.setVal(i,j, val);
01503               }
01504 
01505           //o.c.(s)(:,:,:,5) = 
01506           //  c(:,:,:,5) + 
01507           //  tstep*(p.A3*(-p.B3*c(:,:,:,5) + p.C3*y - p.K3*XY));  % 3.1 
01508           ocs[4].push_back
01509             (c[4][cs] + 
01510              (((c[4][cs]*-model.p_B3) + 
01511                y[cs]*model.p_C3 - XY4*model.p_K3)*model.p_A3)*tstep);
01512 
01513           //o.e.(s)(:,:,:,5) = 
01514           //  e(:,:,:,5) + 
01515           //  tstep*(p.A4*(-p.B4*e(:,:,:,5) + p.C4*y - p.K4*XY));  % 3.2
01516           oes[4].push_back
01517             (e[4][cs] + 
01518              (((e[4][cs]*-model.p_B4) + 
01519                y[cs]*model.p_C4 - XY4*model.p_K4)*model.p_A4)*tstep);          
01520 
01521           // Down-Leftward direction
01522           //XY = max( [zeros(1, nm(2),2); zeros(nm(1)-1, 1,2) 
01523           //          c(1:end-1,1:end-1,:,2) ],0);
01524           Image<double> XY5(cWidth,cHeight,ZEROS);
01525           for(uint i = 1; i < cWidth; i++)
01526             for(uint j = 1; j < cHeight; j++)
01527               {
01528                 double v = c[1][cs].getVal(i-1,j-1);
01529                 double val = 0.0;
01530                 if(v > 0.0) val = v;
01531                 XY5.setVal(i,j, val);
01532               }
01533 
01534           //o.c.(s)(:,:,:,6) = 
01535           //  c(:,:,:,6) + 
01536           //  tstep*(p.A3*(-p.B3*c(:,:,:,6) + p.C3*y - p.K3*XY));  % 3.1 
01537           ocs[5].push_back
01538             (c[5][cs] + 
01539              (((c[5][cs]*-model.p_B3) + 
01540                y[cs]*model.p_C3 - XY5*model.p_K3)*model.p_A3)*tstep);
01541 
01542           //o.e.(s)(:,:,:,6) = 
01543           //  e(:,:,:,6) + 
01544           //  tstep*(p.A4*(-p.B4*e(:,:,:,6) + p.C4*y - p.K4*XY));  % 3.2
01545           oes[5].push_back
01546             (e[5][cs] + 
01547              (((e[5][cs]*-model.p_B4) + 
01548                y[cs]*model.p_C4 - XY5*model.p_K4)*model.p_A4)*tstep);          
01549           
01550           // Downward direction
01551           //XY = max( [zeros(1, nm(2),2); c(1:end-1,:,:,3) ],0);
01552           Image<double> XY6(cWidth,cHeight,ZEROS);
01553           for(uint i = 0; i < cWidth; i++)
01554             for(uint j = 1; j < cHeight; j++)
01555               {
01556                 double v = c[2][cs].getVal(i,j-1);
01557                 double val = 0.0;
01558                 if(v > 0.0) val = v;
01559                 XY6.setVal(i,j, val);
01560               }
01561 
01562           //o.c.(s)(:,:,:,7) = 
01563           //  c(:,:,:,7) + 
01564           //  tstep*(p.A3*(-p.B3*c(:,:,:,7) + p.C3*y - p.K3*XY));  % 3.1 
01565           ocs[6].push_back
01566             (c[6][cs] + 
01567              (((c[6][cs]*-model.p_B3) + 
01568                y[cs]*model.p_C3 - XY6*model.p_K3)*model.p_A3)*tstep);
01569 
01570           //o.e.(s)(:,:,:,7) = 
01571           //  e(:,:,:,7) + 
01572           //  tstep*(p.A4*(-p.B4*e(:,:,:,7) + p.C4*y - p.K4*XY));  % 3.2
01573           oes[6].push_back
01574             (e[6][cs] + 
01575              (((e[6][cs]*-model.p_B4) + 
01576                y[cs]*model.p_C4 - XY6*model.p_K4)*model.p_A4)*tstep);          
01577           
01578           // Downward-Rightward direction
01579           //XY = max( [zeros(1, nm(2),2); c(1:end-1,2:end,:,4) 
01580           //          zeros(nm(1)-1, 1,2) ],0); 
01581           Image<double> XY7(cWidth,cHeight,ZEROS);
01582           for(uint i = 0; i < cWidth-1; i++)
01583             for(uint j = 1; j < cHeight; j++)
01584               {
01585                 double v = c[3][cs].getVal(i+1,j-1);
01586                 double val = 0.0;
01587                 if(v > 0.0) val = v;
01588                 XY7.setVal(i,j, val);
01589               }
01590 
01591           //o.c.(s)(:,:,:,8) = 
01592           //  c(:,:,:,8) + 
01593           //  tstep*(p.A3*(-p.B3*c(:,:,:,8) + p.C3*y - p.K3*XY));  % 3.1 
01594           ocs[7].push_back
01595             (c[7][cs] + 
01596              (((c[7][cs]*-model.p_B3) + 
01597                y[cs]*model.p_C3 - XY7*model.p_K3)*model.p_A3)*tstep);
01598 
01599           //o.e.(s)(:,:,:,8) = 
01600           //  e(:,:,:,8) + 
01601           //  tstep*(p.A4*(-p.B4*e(:,:,:,8) + p.C4*y - p.K4*XY));  % 3.2
01602           oes[7].push_back
01603             (e[7][cs] + 
01604              (((e[7][cs]*-model.p_B4) + 
01605                y[cs]*model.p_C4 - XY7*model.p_K4)*model.p_A4)*tstep);          
01606    
01607           // NOT CODED:
01608           //%o.c.(s) = max(o.c.(s), 0);
01609           //%o.e.(s) = max(o.e.(s), 0);
01610         }
01611       //clear XY y c;
01612 
01613       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01614       // Level 4, Feature Enhancement via Directional Competition
01615       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01616       
01617       //f = in.f.(s); 
01618       std::vector<Image<double> > f  = model.state->f[s];      
01619       std::vector<Image<double> > ofs(NUM_DIRS);
01620 
01621       uint w = f[0].getWidth();
01622       uint h = f[0].getHeight();
01623       std::vector<Image<double> > sump(NUM_DIRS);
01624       Image<double> sumDp(w,h, ZEROS);
01625       //sump = sum(m ax(e,0),3); sumDp = sum(sump ,4);
01626       for(uint dir = 0; dir < NUM_DIRS; dir++)
01627         {
01628           Image<double> temp(w,h,ZEROS);
01629           for(uint cs = 0; cs < NUM_CS; cs++)
01630             {
01631               Image<double> temp2(w,h, ZEROS);
01632               Image<double> temp3 = takeMax(temp2, e[dir][cs]);
01633               temp += temp3;
01634             }
01635           sump[dir] = temp;
01636           sumDp += temp;
01637           //LINFO("acc s [%d]  %20.10f %20.10f", 
01638           //      dir, sumDp.getVal(0,76), temp.getVal(0,76));
01639         }
01640 
01641       //for d = 1:8, sumDnedSump(:,:,:,d) = sumDp - sump(:,:,:,d); end
01642       std::vector<Image<double> > sumDnedSump(NUM_DIRS);
01643       for(uint dir = 0; dir < NUM_DIRS; dir++)
01644         {
01645           sumDnedSump[dir] = sumDp - sump[dir];
01646           // LINFO("s [%d]  %20.10f ", dir, sumDp.getVal(0,76));
01647           // LINFO("s [%d]  %20.10f ", dir, sump[dir].getVal(0,76));
01648           // LINFO("sd[%d]  %20.10f ", dir, sumDnedSump[dir].getVal(0,76));
01649 
01650         }
01651       
01652       //o.f.(s) = f + 
01653       //  tstep*(-p.A5*f + (p.B5-f).*sump - (p.C5+f).*sumDnedSump); % 4.1
01654       for(uint dir = 0; dir < NUM_DIRS; dir++)
01655         {
01656           ofs[dir] = f[dir] + ((f[dir]*-model.p_A5) + 
01657                                ((f[dir]*-1.0)+model.p_B5)*sump[dir] - 
01658                                (f[dir]+model.p_C5)*sumDnedSump[dir])*tstep;
01659         }
01660 
01661 
01662       //uint sj = 0, ej = 20, si = 0, ei = 20;  
01663       // LINFO("f");
01664       // for(uint y = sj; y < ej; y++)
01665       //   {
01666       //     for(uint x = si; x < ei; x++)
01667       //       printf("%10.5f ", f[0].getVal(x,y));
01668       //     printf("\n");
01669       //   }
01670 
01671       // LINFO("sump");
01672       // for(uint y = sj; y < ej; y++)
01673       //   {
01674       //     for(uint x = si; x < ei; x++)
01675       //       printf("%10.5f ", sump[0].getVal(x,y));
01676       //     printf("\n");
01677       //   }
01678 
01679       // LINFO("sumDp");
01680       // for(uint y = sj; y < ej; y++)
01681       //   {
01682       //     for(uint x = si; x < ei; x++)
01683       //       printf("%10.5f ", sumDp.getVal(x,y));
01684       //     printf("\n");
01685       //   }
01686 
01687       // LINFO("sumDnedSump");
01688       // for(uint y = sj; y < ej; y++)
01689       //   {
01690       //     for(uint x = si; x < ei; x++)
01691       //       printf("%10.5f ", sumDnedSump[0].getVal(x,y));
01692       //     printf("\n");
01693       //   }
01694 
01695 //  LINFO("ofs");
01696 //  for(uint y = sj; y < ej; y++)
01697 //    {
01698 //      for(uint x = si; x < ei; x++)
01699 //        printf("%10.5f ", ofs[0].getVal(x,y));
01700 //      printf("\n");
01701 //    }
01702 
01703 
01704 //   Image<double> sump0        = sump[0];
01705 //   Image<double> sumDnedSump0 = sumDnedSump[0];
01706 
01707 //   LINFO("s0  %20.10f ", sump0.getVal(0,76));
01708 //   LINFO("sd0 %20.10f ", sumDnedSump0.getVal(0,76));
01709 //   LINFO("f0 %20.10f ", f[0].getVal(0,76));
01710 
01711 //   LINFO("param: %20.10f %20.10f %20.10f", 
01712 //         model.p_A5, model.p_B5, model.p_C5);
01713 
01714 //   Image<double> aaa = f[0]*-model.p_A5;
01715 //   Image<double> bbb = ((f[0]*-1.0)+model.p_B5)*sump[0];
01716 //   Image<double> ccc = (f[0]+model.p_C5)*sumDnedSump[0];
01717 
01718 //   LINFO("aaa %20.10f ", aaa.getVal(0,76));
01719 //   LINFO("bbb %20.10f ", bbb.getVal(0,76));
01720 //   LINFO("ccc %20.10f ", ccc.getVal(0,76));
01721 
01722 
01723 // LINFO("ofs   %20.10f ", ofs[0].getVal(0,76));
01724 
01725 
01726 
01727 
01728       // Raster::waitForKey();
01729 
01730 
01731       
01732       //clear e sump sumDp sumDnedSump f;
01733 
01734       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01735       // Levels 5 & 6 are not scale specific, resize and combine scales
01736       // this is a combination of eqn 5.1 and the sum over s in 5.2
01737       // shrink function is implemented in functions section below
01738       //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01739       //n = 2^(p.NumSpeeds-ss);
01740       uint n = uint(pow(2.0, model.p_NumSpeeds - s - 1));
01741       
01742       for(uint dir = 0; dir < NUM_DIRS; dir++)
01743         {
01744           //if ss == 1 
01745           if(s == 0)
01746             {
01747               // first speed so initialize o.m
01748               //  o.m = (1/n)*combine(max(o.f.(s),0), n); 
01749               om[dir] = 
01750                 combine(takeMax(ofs[dir],Image<double>(w,h,ZEROS)), n)*(1.0/n);
01751             }
01752           //elseif ss == p.NumSpeeds
01753           else if(s == model.p_NumSpeeds-1)
01754             {
01755               // last speed so no need to resize
01756               //  o.m = o.m + (1/n)*max(o.f.(s),0);      
01757               om[dir] = 
01758                 om[dir] + takeMax(ofs[dir],Image<double>(w,h,ZEROS))*(1.0/n);
01759             }
01760           // else
01761           else
01762             {
01763               // resize and sum across scales
01764               //  o.m = o.m + (1/n)*combine(max(o.f.(s),0), n); 
01765               om[dir] = 
01766                 om[dir] + 
01767                 combine(takeMax(ofs[dir],Image<double>(w,h,ZEROS)), n)*(1.0/n);
01768             }
01769         }
01770 
01771 
01772 
01773 
01774 
01775 
01776  //      uint sj = 0, ej = 20, si = 0, ei = 20;  
01777  //  LINFO("INSIDE om");
01778  //  for(uint y = sj; y < ej; y++)
01779  //    {
01780  //      for(uint x = si; x < ei; x++)
01781  //        printf("%10.5f ", om[0].getVal(x,y));
01782  //      printf("\n");
01783  //    }
01784  // LINFO("om   %20.10f ", om[0].getVal(0,19));
01785 
01786 
01787 
01788 
01789       oI[s] = oIs;
01790       oa[s] = oas;
01791       ob[s] = obs;
01792       ox[s] = oxs;
01793       oy[s] = oys;
01794       oz[s] = ozs;
01795       oc[s] = ocs;
01796       oe[s] = oes;
01797       of[s] = ofs;
01798     }
01799 
01800  // LINFO("om");
01801  // uint sj = 0, ej = 20, si = 0, ei = 20;  
01802  // for(uint y = sj; y < ej; y++)
01803  //  {
01804  //    for(uint x = si; x < ei; x++)
01805  //      printf("%10.5f ", om[0].getVal(x,y));
01806  //    printf("\n");
01807  //  }
01808  // LINFO("om   %20.10f ", om[0].getVal(0,19));
01809  
01810 
01811   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01812   // % there is edge effect from the directional transients 1 pixel wide
01813   // % around the array, remove this
01814   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01815   // o.m([1 end], :, :, :) = 0;
01816   // o.m(:, [1 end], :, :) = 0;
01817   uint wom = om[0].getWidth();
01818   uint hom = om[0].getHeight();
01819   for(uint dir = 0; dir < NUM_DIRS; dir++)
01820     {
01821       // take out top and bottom edge
01822       for(uint i = 0; i < wom; i++)
01823         {
01824           om[dir].setVal(i, 0    , 0.0);
01825           om[dir].setVal(i, hom-1, 0.0);
01826         }
01827 
01828       // take out left and right edge
01829       for(uint j = 0; j < hom; j++)
01830         {
01831           om[dir].setVal(0    , j, 0.0);
01832           om[dir].setVal(wom-1, j, 0.0);
01833         }
01834     }
01835 
01836   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01837   // % Level 5, MT+      Optic Flow
01838   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01839   // q=in.q; r = in.r; Q = in.Q; R = in.R;
01840   std::vector<Image<double> > q = model.state->q;
01841   std::vector<Image<double> > Q = model.state->Q;
01842   std::vector<double> r = model.state->r;
01843   std::vector<double> R = model.state->R;
01844 
01845   std::vector<Image<double> > oq(NUM_DIRS);
01846   std::vector<Image<double> > oQ(NUM_DIRS);
01847   std::vector<Image<double> > qEx(NUM_DIRS);
01848 
01849   std::vector<Image<double> > m = model.state->m;
01850 
01851   // qEx = sumLxy(p.L, in.m).*((p.C6/p.M)*sumRz(R,p.w)+1) + p.D6*Q;
01852   std::vector<Image<double> > sumrz  = sumRz(R, model.p_w);
01853   std::vector<Image<double> > sumlxy = sumLxy(model.p_L, m);
01854   for(uint dir = 0; dir < NUM_DIRS; dir++)
01855     {
01856       qEx[dir] = sumlxy[dir] * (sumrz[dir]*(model.p_C6/model.p_M) +1.0) + 
01857         Q[dir]*model.p_D6; 
01858     }
01859 
01860   // o.q = q + tstep*(-p.A6*q + (p.B6-q).*qEx - q.*sumvD(p.vdD, Q));     % 5.2
01861   std::vector<Image<double> > sumvd = sumvD(model.p_vdD, Q);
01862   for(uint dir = 0; dir < NUM_DIRS; dir++)
01863     {
01864       oq[dir] =  q[dir] + 
01865         ((q[dir]*-model.p_A6) + ((q[dir]*-1.0)+model.p_B6) * 
01866          qEx[dir] - q[dir]*sumvd[dir])*tstep; 
01867     }
01868 
01869   // o.Q = max(q-p.theta6, 0).^2;                                        % 5.3
01870   uint wq = q[0].getWidth(); 
01871   uint hq = q[0].getHeight(); 
01872   for(uint dir = 0; dir < NUM_DIRS; dir++)
01873     {
01874       oQ[dir] = toPower(takeMax(q[dir]-model.p_theta6, 
01875                                 Image<double>(wq,hq,ZEROS)), 2.0);
01876     }
01877 
01878 
01879  //   LINFO("qEx   %20.10f ", qEx[0].getVal(0,19));
01880  //   LINFO("srz   %20.10f ", sumrz[0].getVal(0,19));
01881  //   LINFO("sumvd %20.10f ", sumvd[0].getVal(0,19));
01882  //   LINFO("q     %20.10f ", q[0].getVal(0,19));
01883  //   LINFO("Q     %20.10f ", Q[0].getVal(0,19));
01884 
01885  //   LINFO("param: %20.10f %20.10f %20.10f %20.10f", 
01886  //         model.p_A6, model.p_B6, model.p_C6, model.p_D6);
01887 
01888  //   Image<double> aaa = q[0]*-model.p_A6;
01889  //   Image<double> bbb = ((q[0]*-1.0)+model.p_B6) * qEx[0];
01890  //   Image<double> ccc = q[0]*sumvd[0];
01891 
01892  //   LINFO("aaa %20.10f ", aaa.getVal(0,19));
01893  //   LINFO("bbb %20.10f ", bbb.getVal(0,19));
01894  //   LINFO("ccc %20.10f ", ccc.getVal(0,19));
01895 
01896 
01897  // LINFO("oQ   %20.10f \n\n\n", oQ[0].getVal(0,19));
01898 
01899 
01900 
01901 
01902   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01903   // % Level 6, MSTd     Heading
01904   // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01905   //for ri = 1:size(p.w,3)
01906   std::vector<double> rEx(model.p_w->size());
01907   for(uint ri = 0; ri < model.p_w->size(); ri++)
01908     {
01909       double total = 0.0;
01910       for(uint dir = 0; dir < NUM_DIRS; dir++)
01911         {            
01912           // w = p.w(:,:,ri,:);
01913           // rEx(ri,1) = w(1:end)*Q(1:end)';
01914           for(uint i = 0; i < wq; i++)
01915             for(uint j = 0; j < hq; j++)
01916               total += (*model.p_w)[ri][dir].getVal(i,j)*Q[dir].getVal(i,j);
01917         }
01918       rEx[ri] = total;
01919       //LINFO("total[%d]: %f ", ri, total);
01920 
01921     }
01922 
01923   // o.r = r + 
01924   //   tstep*(-p.A7*r + (p.B7-r).*((p.C7/p.N)*rEx + p.D7*R) - 
01925   //          p.E7*r.*(sum(R)-R));  % 5.6
01926   std::vector<double> orr(r.size());
01927   double sumR = 0.0;
01928   for(uint i = 0; i < r.size(); i++) sumR += R[i];  
01929 
01930   for(uint i = 0; i < r.size(); i++)
01931     {
01932       orr[i] = r[i] + tstep*(-model.p_A7*r[i] + 
01933                             (model.p_B7-r[i])*((model.p_C7/model.p_N)*rEx[i] + 
01934                                                model.p_D7*R[i]) 
01935                              - model.p_E7*r[i]*(sumR-R[i])); 
01936       // if(i ==0)
01937       //   {
01938       //     LINFO("[%d] r[i]: %f tstep: %f A7: %f B7: %f C7: %f E7: %f N: %f "
01939       //           "rEx[i]: %f sumR: %f R[i]: %f",
01940       //           i, r[i], tstep, model.p_A7, model.p_B7, model.p_C7, model.p_E7, 
01941       //           model.p_N, rEx[i], sumR, R[i]);
01942       //     LINFO("orr[%d]: %f", i, orr[i]);
01943       //   }
01944     }
01945 
01946    // LINFO("rEx   %20.10f ", rEx[19]);
01947    // LINFO("sumR  %20.10f ", sumR);
01948    // LINFO("r     %20.10f ", r[19]);
01949    // LINFO("R     %20.10f ", R[19]);
01950 
01951    // LINFO("param: %20.10f %20.10f %20.10f %20.10f %20.10f", 
01952    //       model.p_A7, model.p_B7, model.p_C7, model.p_E7, model.p_N);
01953 
01954    // double aaaa = (model.p_B7-r[19]);
01955    // double bbbb = (model.p_C7/model.p_N)*rEx[19]; 
01956    // double cccc = model.p_D7*r[19];
01957 
01958    // LINFO("aaaa %20.10f ", aaaa);
01959    // LINFO("bbbb %20.10f ", bbbb);
01960    // LINFO("cccc %20.10f ", cccc);
01961    // LINFO("orr  %20.10f ", orr[19]);
01962 
01963   
01964   // rminth = max(o.r-p.theta7, 0).^2;
01965   std::vector<double> rminth(r.size());
01966   for(uint i = 0; i < r.size(); i++)
01967     {
01968       rminth[i] = pow(max(orr[i]-model.p_theta7,0.0), 2.0);
01969 
01970       //LINFO("rminth[%d]: %f",i, rminth[i]);
01971     }
01972   
01973   // o.R = rminth ./ (p.G7^2 + rminth); 
01974   std::vector<double> oR(r.size());
01975   for(uint i = 0; i < r.size(); i++)
01976     {
01977       oR[i] =  rminth[i]/(pow(model.p_G7, 2.0) + rminth[i]);
01978 
01979       //LINFO("oR[%d]: %f", i, oR[i]);
01980     }
01981 
01982   // save it to the model
01983   model.state->a = oa;
01984   model.state->b = ob;
01985   model.state->x = ox;
01986   model.state->y = oy;
01987   model.state->z = oz;
01988   model.state->c = oc;
01989   model.state->e = oe;
01990   model.state->f = of;
01991   model.state->q = oq;
01992   model.state->Q = oQ;
01993   model.state->m = om;
01994   model.state->r = orr;
01995   model.state->R = oR;
01996 
01997 
01998 
01999 
02000 
02001 
02002 
02003 
02004 
02005   //==================================================================
02006   // Debug
02007   //uint sj = 0, ej = 20, si = 0, ei = 20;
02008  // LINFO("oI[0][0]");
02009  // for(uint y = sj; y < ej; y++)
02010  //   {
02011  //     for(uint x = si; x < ei; x++)
02012  //       printf("%10.4f ", oI[0][0].getVal(x,y));
02013  //     printf("\n");
02014  //   }
02015  // //Raster::waitForKey();
02016 
02017  // LINFO("oa[0][0]");
02018  // for(uint y = sj; y < ej; y++)
02019  //   {
02020  //     for(uint x = si; x < ei; x++)
02021  //       printf("%10.4f ", oa[0][0].getVal(x,y));
02022  //     printf("\n");
02023  //   }
02024  // Raster::waitForKey();
02025 
02026   // LINFO("ob[0][0]");
02027   // for(uint y = sj; y < ej; y++)
02028   //   {
02029   //     for(uint x = si; x < ei; x++)
02030   //       printf("%10.4f ", ob[0][0].getVal(x,y));
02031   //     printf("\n");
02032   //   }
02033   // Raster::waitForKey();
02034 
02035  // LINFO("ox[0][0]");
02036  // for(uint y = sj; y < ej; y++)
02037  //   {
02038  //     for(uint x = si; x < ei; x++)
02039  //     printf("%10.4f ", ox[0][0].getVal(x,y));
02040  //     printf("\n");
02041  //   }
02042  // Raster::waitForKey();
02043 
02044  // LINFO("oy[0][0]");
02045  // for(uint y = sj; y < ej; y++)
02046  //   {
02047  //     for(uint x = si; x < ei; x++)
02048  //     printf("%10.4f ", oy[0][0].getVal(x,y));
02049  //     printf("\n");
02050  //   }
02051  // //Raster::waitForKey();
02052  // LINFO("oy  %20.10f ", oy[0][0].getVal(0,76));
02053 
02054   // LINFO("oz[0][0]");
02055   // for(uint y = sj; y < ej; y++)
02056   //   {
02057   //     for(uint x = si; x < ei; x++)
02058   //       printf("%10.4f ", oz[0][0].getVal(x,y));
02059   //     printf("\n");
02060   //   }
02061   // //Raster::waitForKey();
02062 
02063 
02064   // LINFO("oc");
02065   // for(uint y = sj; y < ej; y++)
02066   //   {
02067   //     for(uint x = si; x < ei; x++)
02068   //       printf("%10.5f ", oc[0][0][0].getVal(x,y));
02069   //     printf("\n");
02070   //   }
02071 
02072   // LINFO("oe");
02073   // for(uint y = sj; y < ej; y++)
02074   //   {
02075   //     for(uint x = si; x < ei; x++)
02076   //       printf("%10.5f ", oe[0][0][0].getVal(x,y));
02077   //     printf("\n");
02078   //   }
02079 
02080   // LINFO("of");
02081   // for(uint y = sj; y < ej; y++)
02082   //   {
02083   //     for(uint x = si; x < ei; x++)
02084   //       printf("%10.5f ", of[0][0].getVal(x,y));
02085   //     printf("\n");
02086   //   }
02087 
02088  // LINFO("om");
02089  // for(uint y = sj; y < ej; y++)
02090  //  {
02091  //    for(uint x = si; x < ei; x++)
02092  //      printf("%10.5f ", om[0].getVal(x,y));
02093  //    printf("\n");
02094  //  }
02095  // LINFO("om   %20.10f ", om[0].getVal(0,19));
02096   
02097   // LINFO("oq");
02098   // for(uint y = sj; y < ej; y++)
02099   //   {
02100   //     for(uint x = si; x < ei; x++)
02101   //       printf("%10.5f ", oq[0].getVal(x,y));
02102   //     printf("\n");
02103   //   }
02104 
02105 //  LINFO("oQ");
02106 //  for(uint y = sj; y < ej; y++)
02107 //    {
02108 //      for(uint x = si; x < ei; x++)
02109 //        printf("%10.5f ", oQ[0].getVal(x,y));
02110 //      printf("\n");
02111 //    }
02112 //  LINFO("oQ  %20.10f ", oQ[0].getVal(0,19));
02113 
02114 // LINFO("orr  %20.10f ", orr[19]);
02115 // LINFO("rEx  %20.10f ", rEx[19]);
02116 // LINFO("oR   %20.10f ",  oR[19]);
02117 
02118  // LINFO("or");
02119  // for(uint x = si; x < 20; x++)
02120  //   printf("%20.10f ", orr[x]);
02121  // printf("\n");
02122 
02123  // LINFO("rEx");
02124  // for(uint x = si; x < 20; x++)
02125  //   printf("%20.10f ", rEx[x]);
02126  // printf("\n");
02127 
02128  // LINFO("oR");
02129  // for(uint x = si; x < 20; x++)
02130  //   printf("%20.10f ", oR[x]);
02131  // printf("\n");
02132 
02133 
02134   //Raster::waitForKey();
02135 
02136           // uint sj = 0, ej = 20, si = 0, ei = 20;         
02137           // for(uint y = sj; y < ej; y++)
02138           //   {
02139           //     for(uint x = si; x < ei; x++)
02140           //       printf("%10.5f ", stim.getVal(x,y));
02141           //     printf("\n");
02142           //   }
02143           // LINFO("wow");
02144 
02145 
02146   // Heading
02147   uint hind = 0; double max= oR[0];
02148   for(uint i = 0; i < oR.size(); i++)
02149     if(max<oR[i]){ max = oR[i]; hind = i; }
02150 
02151   LINFO("[[%d]]heading[%d]:(%3d %3d) %f ", 
02152         mainIndex, hind, model.Rlocs[hind].i, model.Rlocs[hind].j, max);
02153   mainIndex++;
02154 
02155   return model.Rlocs[hind];
02156 }
02157 
02158 // ######################################################################
02159 // sumFxy is used in the on-center off-surround networks to create a
02160 // Guassian cell neighborhood
02161 //function out = sumFxyI(F, I)
02162 std::vector<Image<double> > sumFxyI(Image<double> F, std::vector<Image<double> > I)
02163 {
02164   // 2D Gaussian Filter (F) across input (I), implemented as 2 1D filtering
02165   // operations for efficiency.
02166 
02167   std::vector<Image<double> > out;
02168 
02169   // for o = 1:2  % input has both on and off channels
02170   for(uint o = 0; o < NUM_CS; o++)
02171     {
02172       uint fw = F.getWidth();
02173       uint fh = F.getHeight();
02174 
02175       // scalar filter
02176       if(fw*fh == 1) 
02177         {
02178           LFATAL("NOT YET TESTED");
02179           LERROR("SumFxyI: filter is scalar.");
02180           out.push_back(matrixMult(F,I[o]));        
02181         }
02182       // Allow F to be passed as a 1D Gaussian and then filter as 2D
02183       else if((fw == 1)||(fh == 1))    
02184         {
02185           LFATAL("NOT YET TESTED");
02186           Image<double> temp = filter2(F/sum(F), I[o]);
02187           out.push_back(filter2(transpose((F/sum(F))), temp));
02188         }
02189       else // 2D Filter
02190         out.push_back(filter2(F, I[o]));
02191     }
02192   return out;
02193 }
02194 
02195 // ######################################################################
02196 Image<double> filter2(Image<double> f, Image<double> d)
02197 {
02198   uint fw = f.getWidth();
02199   uint fh = f.getHeight();
02200 
02201   uint fwh = fw/2;
02202   uint fhh = fh/2;
02203 
02204   uint dw = d.getWidth();
02205   uint dh = d.getHeight();
02206   
02207   Image<double> ret(dw, dh, NO_INIT);
02208 
02209   // 
02210   for(uint di = 0; di < dw; di++)
02211     for(uint dj = 0; dj < dh; dj++)
02212       {
02213         double val = 0.0;
02214         for(uint fi = 0; fi < fw; fi++)
02215           for(uint fj = 0; fj < fh; fj++)
02216             {
02217               int i = di+fi-fwh;
02218               int j = dj+fj-fhh;
02219               if(i >= 0 && j >= 0 && i < int(dw) && j < int(dh)) 
02220                 {
02221                   val += d.getVal(i,j)*f.getVal(fi,fj);
02222                   
02223                   //LINFO("d[%3d %3d]f[%3d %3d] --> [%3d %3d]: %10.4f x %10.4f = %10.4f -> val: %10.4f", 
02224                   //      di,dj,fi,fj, i,j, 1.0, f.getVal(fi,fj), 1.0*f.getVal(fi,fj), val);
02225                 }
02226             }       
02227         ret.setVal(di,dj, val);
02228       }
02229   return ret;
02230 }
02231 
02232 // ######################################################################
02233 // combine is used to sum over groups of cells to shrink the array.
02234 //function x = combine(y, f)
02235 Image<double> combine(Image<double> y, double f)
02236 {
02237   //if f > 1, ff = 1/f; 
02238   // else ff = f; f = 1/ff; end
02239   double ff;
02240   if(f > 1) { ff = 1/f; }
02241   else      { ff = f; f = 1/ff; } 
02242 
02243   uint w = y.getWidth();
02244   uint h = y.getHeight();
02245   uint width  = floor(w*ff);
02246   uint height = floor(h*ff);
02247   Image<double> x(width, height, NO_INIT);
02248 
02249   // SKIP this dimension: for t = 1:size(y,3) --> it's 1
02250 
02251   //for i=1:floor(size(y,1)*ff)
02252   // for j=1:floor(size(y,2)*ff)
02253   for(uint i = 0; i < width; i++)
02254     for(uint j = 0; j < height; j++)
02255       {
02256         // x(i,j,t,:) = sum(sum(y(i*f-f+1:i*f, j*f-f+1:j*f, t, :)));
02257         double val = 0.0;
02258         uint sk = uint((i+1)*f-f);
02259         uint ek = uint((i+1)*f);
02260 
02261         uint sl = uint((j+1)*f-f);
02262         uint el = uint((j+1)*f);
02263 
02264         for(uint k = sk; k < ek; k++)
02265           for(uint l = sl; l < el; l++)
02266             {
02267               val += y.getVal(k,l);
02268               // if(i == 0 && j == 19)
02269               //   {
02270               //     LINFO("[%3d %3d]: %20.10f -> val: %20.10f", 
02271               //           k,l,y. getVal(k,l), val);
02272                   
02273               //   }              
02274             }
02275 
02276 
02277         x.setVal(i,j,val);
02278 
02279       }
02280 
02281 
02282   // LINFO("om   %20.10f ", x.getVal(0,19));
02283 
02284   return x;
02285 }
02286 
02287 // ######################################################################
02288 // sumLxy is used for the long range filter in MT
02289 //function out = sumLxy(L, I)
02290 std::vector<Image<double> > 
02291 sumLxy(rutz::shared_ptr<std::vector<Image<double> > > L, 
02292        std::vector<Image<double> > I)
02293 {
02294   std::vector<Image<double> > out(NUM_DIRS);
02295   // can't split the diagonal filters without rotating the input which
02296   // introduces other issues so use the full 2D filter
02297   //  for d=1:8
02298   for(uint dir = 0; dir < NUM_DIRS; dir++)
02299     {
02300       //     out(:,:,1,d)  = filter2(L(:,:,d), I(:,:,1,d), 'same');
02301       out[dir] = filter2((*L)[dir],I[dir]);
02302     }
02303   return out;
02304 }
02305 
02306 // ######################################################################
02307 // sumRz is used for the feedback from MSTd to MT
02308 //function out = sumRz(R,w)
02309 std::vector<Image<double> > 
02310 sumRz(std::vector<double> R, 
02311       rutz::shared_ptr<std::vector<std::vector<Image<double> > > > w)
02312 {
02313   //out(:,:,1,:) = zeros(size(w,1), size(w,2), 1, 8);
02314   std::vector<Image<double> > out(NUM_DIRS);
02315   uint width  = (*w)[0][0].getWidth();
02316   uint height = (*w)[0][0].getHeight();
02317   for(uint dir = 0; dir < NUM_DIRS; dir++)
02318     out[dir] = Image<double>(width, height, ZEROS);
02319 
02320   //  for z = 1:length(R)
02321   for(uint dir = 0; dir < NUM_DIRS; dir++)
02322     for(uint z = 0; z < R.size(); z++)
02323       // out(:,:,1,:) = out(:,:,1,:) + R(z)*w(:,:,z,:);
02324       out[dir] = out[dir] + (*w)[z][dir]*R[z]; 
02325 
02326   return out;
02327 }
02328 
02329 // ######################################################################
02330 // sumvD is used for competititive interactions in MT
02331 //function out = sumvD(v,I)
02332 std::vector<Image<double> >
02333 sumvD(std::vector<double>v, std::vector<Image<double> > I)
02334 {
02335   std::vector<Image<double> > out(NUM_DIRS);
02336 
02337   //for d = 1:8
02338   for(uint dir = 0; dir < NUM_DIRS; dir++)
02339     {
02340       int d = int(dir)+1;
02341       
02342       // LINFO("boom[%d] + (%d + %d) + (%d + %d) + (%d + %d) + %d",
02343       //       dir, 
02344       //       dof(d+1)-1, dof(d-1)-1,
02345       //       dof(d+2)-1, dof(d-2)-1,
02346       //       dof(d+3)-1, dof(d-3)-1,
02347       //       dof(d+4)-1);
02348 
02349       // out(:,:,1,d) = v(1)*I(:,:,:,d) + 
02350       //                v(2)*sum(I(:,:,:,dof([d+1 d-1])),4) + 
02351       //                v(3)*sum(I(:,:,:,dof([d+2 d-2])),4) + 
02352       //                v(4)*sum(I(:,:,:,dof([d+3 d-3])),4) + 
02353       //                v(5)*I(:,:,:,dof([d+4]));
02354       out[dir] = 
02355         I[dir]*v[0] + 
02356         (I[dof(d+1)-1] + I[dof(d-1)-1])*v[1] + 
02357         (I[dof(d+2)-1] + I[dof(d-2)-1])*v[2] + 
02358         (I[dof(d+3)-1] + I[dof(d-3)-1])*v[3] + 
02359         (I[dof(d+4)-1])*v[4];
02360 
02361       //LINFO("baam[%d]",dir);
02362 
02363     }
02364 
02365   return out;
02366 }
02367 
02368 // ######################################################################
02369 // function y = dof(x)
02370 int dof(int x)
02371 {
02372   // y = mod(x,8);
02373   int y = (x+8)%8;
02374   //LINFO("x: %d -> mod(x,8) = %d", x, y);
02375 
02376   // y = (y==0)*8+y;
02377   y = (y==0)*8 + y;
02378   //LINFO("(y==0)*8 + y; = %d", y);
02379 
02380   return y;
02381 }    
02382 
02383 // ######################################################################
02384 void report(ViSTARSmodel &model)
02385 {
02386   // xs = size(model.I.s3);
02387   //model.state->I[model.p_NumSpeeds-1][0]
02388 
02389     // the actual heading that the network selected
02390   // heading(:,t) = [2:3:xs(2) 2:3:xs(2)]*[model.R==max(model.R)];
02391 
02392   // ocos(:,:,t) = model.b.s2(:,:,1)-model.b.s2(:,:,2);
02393 
02394   // trans(:,:, t) = model.y.s2(:,:,1) - model.y.s2(:,:,2);
02395 
02396   // dir(:,:,t, :) = model.f.s2(:,:,1, :);
02397 
02398   // MT(:,:,t, :) = model.Q;
02399 
02400   // MSTd(:,t) = model.R;
02401 
02402   // model.heading = heading;
02403   // model.ocos = ocos;
02404   // model.trans = trans;
02405   // model.dir = dir;
02406   // model.MT = MT;
02407   // model.MSTd = MSTd;
02408 
02409   // show_res1(model);
02410   // show_res(model, model.heading);
02411 }
02412            //  uint sj = 0, ej = 20, si = 0, ei = 20;
02413            // for(uint i = 0; i < 8; i++)
02414            //   {
02415            //     LINFO("Dir: %d", i);
02416            //     for(uint y = sj; y < ej; y++)
02417            //       {
02418            //         for(uint x = si; x < ei; x++)
02419            //           printf("%10.5f ", temp[i].getVal(x,y));
02420            //         printf("\n");
02421            //       }
02422            //   }
02423            // Raster::waitForKey();
02424 
02425 
02426 // ######################################################################
02427 /* So things look consistent in everyone's emacs... */
02428 /* Local Variables: */
02429 /* indent-tabs-mode: nil */
02430 /* End: */
Generated on Sun May 8 08:05:36 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3