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 }