00001 
00012 #include "RetinotopicOrientationConnectionPredicate.h"
00013 
00014 #include <iostream>
00015 using std::cout;
00016 using std::cerr;
00017 using std::endl;
00018 
00019 
00020 RetinotopicOrientationConnectionPredicate::RetinotopicOrientationConnectionPredicate(
00021     double C,
00022     int max_input_syn,
00023     int src_shape_x, int src_shape_y,
00024     double src_scale,
00025     RandomDistribution &nsub,
00026     RandomDistribution &phi,
00027     RandomDistribution &f,
00028     double aspectratio_min,
00029     double aspectratio_max)
00030     : m_C(C)
00031     , m_max_input_syn(max_input_syn)
00032     , m_distance(false, 0,
00033                  src_shape_x, src_shape_y,
00034                  1, 1,
00035                  src_scale,
00036                  1.0,
00037                  Point2D<double>((src_shape_x-1)/2.0, (src_shape_y-1)/2.0),
00038                  Point2D<double>(0.0, 0.0))
00039     , m_nsub(nsub.clone())
00040     , m_phi(phi.clone())
00041     , m_f(f.clone())
00042     , m_aspectratio_min(aspectratio_min)
00043     , m_aspectratio_max(aspectratio_max)
00044     , m_unirnd(0,1)
00045 {
00046 }
00047 
00048 
00049 void RetinotopicOrientationConnectionPredicate::init(SimObjectPopulation const& src, SimObjectPopulation const& dst, RandomEngine *rnd)
00050 {
00051     AugmentedConnectionDecisionPredicate::init(src, dst, rnd);
00052 
00053     size_t nidx, sidx;
00054     double pi = acos(0.0) * 2;             
00055 
00056     for(nidx=0; nidx < m_destinationPopulation->size(); nidx++)
00057     {
00058         const SimObjectAttributes & dst_attr = m_destinationPopulation->getAttributes(nidx);
00059         Point2D<double> d(m_destinationPopulation->getLocation(nidx));
00060 
00061         Point2D<double> dfp(dst_attr.get<double>(string("feature_pos_x")),
00062                             dst_attr.get<double>(string("feature_pos_y")));
00063 
00064         double theta = dst_attr.get<double>(string("orientation"));
00065         double preference = dst_attr.get<double>(string("preference"));
00066         double aspectratio = preference*(m_aspectratio_max-m_aspectratio_min) + m_aspectratio_min;
00067 
00068         double nsub = (*m_nsub)(*rnd);
00069         double phi = (*m_phi)(*rnd);
00070         double f = (*m_f)(*rnd);
00071 
00072         
00073         double lambda_x = nsub/2.448/4.0/f;
00074         double lambda_y = aspectratio/2.448/4.0/f;
00075 
00076         vector<double> gabor(m_sourcePopulation->size());
00077         double z_min=0;
00078 
00079         for(sidx=0; sidx < m_sourcePopulation->size(); sidx++)
00080         {               
00081             Point3D<double> spos(m_sourcePopulation->getLocation(sidx));
00082 
00083             if(sidx==0)
00084                 z_min=spos.z();
00085             z_min=min(z_min, spos.z());
00086 
00087             Point2D<double> s(spos);
00088             Point2D<double> vpos = m_distance.diff(s, dfp);
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097           
00098 
00099             double Phi = 2.0*pi*f * (vpos.x()*cos(theta) + vpos.y()*sin(theta)) + phi;
00100 
00101             vpos.rotate(theta);
00102             double edist2 = vpos.x()*vpos.x()/(lambda_x*lambda_x) + vpos.y()*vpos.y()/(lambda_y*lambda_y);
00103             gabor[sidx] = exp(-edist2/2.0) * cos(Phi);
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118             
00119         }
00120 
00121         vector<double> prob(m_sourcePopulation->size());
00122         double p_sum=0.0;
00123         for(sidx=0; sidx < m_sourcePopulation->size(); sidx++)
00124         {
00125             Point3D<double> spos(m_sourcePopulation->getLocation(sidx));
00126             if (spos.z() == z_min || spos.z() == z_min+2)                    
00127                 prob[sidx]= (gabor[sidx] > 0.0) ? gabor[sidx] : 0.0;
00128             else                                                         
00129                 prob[sidx]= (gabor[sidx] < 0.0) ? fabs(gabor[sidx]) : 0.0;
00130 
00131             p_sum += prob[sidx];
00132 
00133 
00134 
00135 
00136 
00137 
00138         }
00139         
00140         for(sidx=0; sidx < m_sourcePopulation->size(); sidx++)
00141         {
00142 
00143 
00144 
00145 
00146 
00147 
00148               
00149                 
00150             if (m_unirnd(*rnd) < m_C*prob[sidx]/p_sum*m_max_input_syn)
00151                 m_connections.insert(pair<size_t, size_t>(sidx, nidx));
00152         }
00153     }
00154 }