diff --git a/CMakeLists.txt b/CMakeLists.txt index a9c4691..1888485 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,33 +1,35 @@ cmake_minimum_required (VERSION 2.6) project(NeuroProject) set(CMAKE_CXX_FLAGS "-W -Wall -pedantic -std=c++11") add_subdirectory(googletest) enable_testing() include_directories(${gtest_SOURCE_DIR}/include ${guest_SOURCE_DIR}) add_executable ( Neuro Partie3/Src/main.cpp Partie3/Src/neurone.hpp Partie3/Src/neurone.cpp Partie3/Src/network.hpp Partie3/Src/network.cpp Partie3/Src/ringbuffer.hpp Partie3/Src/ringbuffer.cpp ) add_executable ( UnitTest Partie3/Src/neurone.hpp Partie3/Src/neurone.cpp Partie3/Src/network.hpp Partie3/Src/network.cpp Partie3/Src/ringbuffer.hpp Partie3/Src/ringbuffer.cpp Partie3/Test/UnitTest.cpp ) target_link_libraries (UnitTest gtest gtest_main) -add_test (UnitTest UnitTest) \ No newline at end of file +add_test (UnitTest UnitTest) + + diff --git a/Partie3/Src/constant.h b/Partie3/Src/constant.h index 499b2af..bf472ab 100644 --- a/Partie3/Src/constant.h +++ b/Partie3/Src/constant.h @@ -1,23 +1,24 @@ +#include + const double Spike_Treshold(0.020); //V -const double Tau(0.02); //s +const double Tau(0.020); //s const double TauR(0.002); //s (temps de repos après spike) const double DeltaTime(0.0001); //pas de temps -const double Resistance(0.020); //Ohm +const double Resistance(20e6); //Ohm const double Standard_potential(0); //V const int mV(1000); //transform mV into V -const int ms(1000); +const int ms(1000); //transform ms into s const double toMs(0.001); //transform second into ms -const int bufferSize(16); //1+synaptic_delay (en pas de temps) -const int synaptic_delay(15); -const double J(0.001); //V -const double Je(0.001); -const double Ji(-0.005); +const int bufferSize(16); //1+synaptic_delay +const int synaptic_delay(15); //delay before the spike is recorded by the receiving neurone +const int g(5); +const double Je(0.0001); +const double Ji(-g*Je); const int Ne(10000); //Excitatory neurons const int Ni(2500); //Inhibitory neurons const int Ce(1000); //Connected Excitatory neurons const int Ci(250); //Connected Inhibitory neurons -const int Cext(250); //Connections from outside the network +const int Cext(1000); //Connections from outside the network +const int MeanByDeltaTime(2); //Mean of spikes from the outside of the network by unit of time -const double Vext(0.020); //1/ms -const double T_ext(0.050); //ms -const double MeanByDeltaTime(2); //DeltaTime/T_ext (5) +const double c1 (exp(-DeltaTime/Tau)); //constant for the calculation of the new potential \ No newline at end of file diff --git a/Partie3/Src/main.cpp b/Partie3/Src/main.cpp index ef5881d..31677a5 100644 --- a/Partie3/Src/main.cpp +++ b/Partie3/Src/main.cpp @@ -1,53 +1,51 @@ #include #include #include "neurone.hpp" #include "network.hpp" #include "constant.h" #include #include using namespace std; double AskForTime(); int main () { double temps_f(0.0); do { temps_f = AskForTime(); } while (temps_f <= 0 ); ofstream donnees ("donnees.txt", ios::out); - unsigned int t (std::round((temps_f)/DeltaTime)); + unsigned int t (std::round(temps_f/DeltaTime)); Network network; network.initialize(); - network.ConnectEachNeurone(); - network.update(t); network.printSpikeTimes(donnees, t); donnees.close(); return 0; } double AskForTime() { double duree (0); std::cout << "Entrez la durée de la simulation (en ms) : " << std::endl; cin >> duree; return duree*toMs; } diff --git a/Partie3/Src/network.cpp b/Partie3/Src/network.cpp index 399bfb4..5b5737a 100644 --- a/Partie3/Src/network.cpp +++ b/Partie3/Src/network.cpp @@ -1,94 +1,97 @@ #include #include #include #include "network.hpp" #include "constant.h" #include Network::Network() {} Network::~Network() { for (auto& neu : neurones_) { delete neu; neu=nullptr; } neurones_.clear(); } void Network::initialize() { for (size_t i(0); i < Ne; ++i) { neurones_.push_back(new Neurone(Excitatory)); } for (size_t i(0); i < Ni; ++i) { neurones_.push_back(new Neurone(Inhibitory)); } + ConnectEachNeurone(); } void Network::addNeurone(Neurone* neurone) { if (neurone != nullptr) { neurones_.push_back(neurone); } } void Network::update(unsigned int time_f) { unsigned int t(0); while (t < time_f) { if (not neurones_.empty()) { int delay (t+synaptic_delay); for (auto& neu : neurones_) { bool spike(false); spike=neu->update(t); // Verify for each neurone if it spikes if (spike) { neu->sendInformation(delay); } - } - std::cout<> AllSpikeTimes = std::vector> (time_f); for(size_t i(0); i < neurones_.size(); ++i) { + if (not (neurones_[i]->getStatus()==Inhibitory)) { if (neurones_[i]->getSpikeTimes().empty()) { //We do nothing } else { for(size_t j(0); j < (neurones_[i]->getSpikeTimes()).size(); ++j) { AllSpikeTimes[(neurones_[i]->getSpikeTimes())[j]].push_back(i); } } } + } char tab = '\t'; unsigned int i(0); for(auto SpikeTime : AllSpikeTimes) { for (auto neu : SpikeTime) { donnees << i << tab << neu << std::endl; } ++i; } } void Network::ConnectEachNeurone() { for (size_t i(0); i < neurones_.size(); ++i) { neurones_[i]->MakeConnections(neurones_,i); } } std::vector& Network::getNeurones() { return neurones_; } diff --git a/Partie3/Src/neurone.cpp b/Partie3/Src/neurone.cpp index 3f7a27f..8b9f986 100644 --- a/Partie3/Src/neurone.cpp +++ b/Partie3/Src/neurone.cpp @@ -1,182 +1,181 @@ #include "neurone.hpp" #include "constant.h" #include #include #include Neurone::Neurone(Status status) : status_(status), membrane_potential_(Standard_potential), clock_rest_time_(0.0), I_ext_(0.0), test_(false) {} Neurone::~Neurone() {} bool Neurone::update(unsigned int t) { bool spike(false); spike=Spike(t); // 1) make the neurone spike and set it refractory (if necessary) double new_potential(0.0); if(not isInRest()) { - new_potential = exp(-DeltaTime/Tau)*(membrane_potential_); - new_potential += I_ext_*(Resistance)*(1-exp(-DeltaTime/Tau)); + new_potential = c1*(membrane_potential_); + new_potential += I_ext_*(Resistance)*(1-c1); // 2) calculate the new potential new_potential += outsideInput(); // 3) add the potential created by other neurones if (not test_) { new_potential += BackgroundInput(); } // 4) add the potential created by the background membrane_potential_=new_potential; // 5) update the membrane potential if (membrane_potential_<0.0) { membrane_potential_=0.0; } } else { membrane_potential_=0.0; } buffer_.update(); return spike; } double Neurone::getMembranePotential () const { return membrane_potential_-0.070; // -0.070 because we use a 0 origin for the membrane potential } bool Neurone::isInRest() { if (not (clock_rest_time_ <= 0.0)) { clock_rest_time_-=DeltaTime; // retires an unit of time return true; } return false; } bool Neurone::Spike(unsigned int t) { bool spike(false); if(membrane_potential_ >= Spike_Treshold) { spikes_times_.push_back(t); // 1) stores the spike time membrane_potential_=Standard_potential; // 2) reinitialize the membrane potential clock_rest_time_=TauR; // 3) set the rest time spike=true; }; - return spike; } std::vector Neurone::getSpikeTimes() const { return spikes_times_; } void Neurone::receive(int D, Status status) { if (status==Excitatory) { - buffer_.addValue(D,Je); + buffer_.addValue(D,Je); } if (status==Inhibitory) { buffer_.addValue(D,Ji); } } double Neurone::outsideInput() const { double input(buffer_.valueFor()); return input; } void Neurone::setIext(double I) { I_ext_=I; } void Neurone::MakeConnections(std::vector& neurones, int neuroneNumber) { std::mt19937 rng(time(NULL)); int newNeuroneNumber(0); for(size_t i(0); i < Ce ; ++i) { do { std::uniform_int_distribution distribution(0, Ne-1); newNeuroneNumber = distribution(rng); } while (newNeuroneNumber == neuroneNumber); neurones[newNeuroneNumber]->addConnection(neurones,neuroneNumber); } for (size_t i(0); i < Ci ; ++i) { - do{ + do { std::uniform_int_distribution distribution(0, Ni-1); newNeuroneNumber = distribution(rng) + Ne; } while (newNeuroneNumber == neuroneNumber); neurones[newNeuroneNumber]->addConnection(neurones, neuroneNumber); } } double Neurone::BackgroundInput() const { std::random_device rd; std::mt19937 gen(rd()); std::poisson_distribution<> d(MeanByDeltaTime); - return (d(rd))*J; + return (d(rd))*Je; } Status Neurone::getStatus() const { return status_; } void Neurone::sendInformation (int t) const { for (auto neu : targets_) { neu->receive(t,status_); } } void Neurone::setTestMode() { test_=true; } void Neurone::addConnection(std::vector& neurones, int targetNumber) { targets_.push_back(neurones[targetNumber]); } int Neurone::countConnection(int i,std::vector& neurones,int& InCounteur, int& ExCounteur) { int counter(0); for(auto neu : targets_) { if (neu==neurones[i]) { if (status_==Excitatory) { ++ExCounteur; } else { ++InCounteur; } ++counter; } } return counter; } \ No newline at end of file diff --git a/Partie3/Test/UnitTest.cpp b/Partie3/Test/UnitTest.cpp index 6c6c655..71a2650 100644 --- a/Partie3/Test/UnitTest.cpp +++ b/Partie3/Test/UnitTest.cpp @@ -1,165 +1,166 @@ #include #include #include "../Src/neurone.hpp" #include "../Src/network.hpp" #include "../../googletest/include/gtest/gtest.h" #include "../Src/constant.h" TEST (NeuroneTest , PotentialInitialisation) { Neurone neurone(Excitatory); EXPECT_EQ(-0.070, neurone.getMembranePotential()); } TEST (NeuronTest , SpikeTimes) { Neurone neurone(Excitatory); neurone.setTestMode(); - neurone.setIext(1.01); + neurone.setIext(1.01e-9); for (unsigned int i(0); i < 3000 ; ++i) { neurone.update(i); } std::vector SpikeTimes (neurone.getSpikeTimes()); EXPECT_EQ(924, SpikeTimes[0]); EXPECT_EQ(1868, SpikeTimes[1]); EXPECT_EQ(2812, SpikeTimes[2]); } TEST (NeuronTest, Doesnt_reach_treshold) { Neurone neurone(Excitatory); neurone.setTestMode(); - neurone.setIext(1.0); + neurone.setIext(1.0e-9); for (unsigned int i(0); i < 10000 ; ++i) { neurone.update(i); } std::vector SpikeTimes(neurone.getSpikeTimes()); unsigned int size (0); EXPECT_EQ(size, SpikeTimes.size()); } TEST (TwoNeurones, ReceiveTime) { Neurone neurone1(Excitatory); - neurone1.setIext(1.01); + neurone1.setIext(1.01e-9); neurone1.setTestMode(); Neurone neurone2(Excitatory); neurone2.setTestMode(); for (unsigned int i (0) ; i < 925 + synaptic_delay; ++i) { if (neurone1.update(i)) { neurone2.receive(i+synaptic_delay,Excitatory); EXPECT_EQ(-0.070, neurone1.getMembranePotential()); } neurone2.update(i); } - EXPECT_EQ(-0.069,neurone2.getMembranePotential()); + EXPECT_EQ(-0.0699,neurone2.getMembranePotential()); } TEST (TwoNeurones , Neurone2_Spike) { Neurone neurone1(Excitatory); - neurone1.setIext(1.01); + neurone1.setIext(1.01e-9); neurone1.setTestMode(); Neurone neurone2(Excitatory); - neurone2.setIext(1.0); + neurone2.setIext(1.0e-9); neurone2.setTestMode(); - for (unsigned int i (0) ; i < 925 + synaptic_delay; ++i) { + for (unsigned int i (0) ; i < 1869 + synaptic_delay; ++i) { if (neurone1.update(i)) { neurone2.receive(i+synaptic_delay,Excitatory); EXPECT_EQ(-0.070, neurone1.getMembranePotential()); } bool update; update = neurone2.update(i); } //just before neurone 2 spikes unsigned long int size = 0; EXPECT_EQ(size,(neurone2.getSpikeTimes()).size()); bool update; - update = neurone2.update(925+synaptic_delay); + update = neurone2.update(1869+synaptic_delay); + size = 1; EXPECT_EQ(-0.070, neurone2.getMembranePotential()); EXPECT_EQ(size,(neurone2.getSpikeTimes()).size()); } TEST (TwoNeurones, Inhibitory_Excitatory_Test) { RingBuffer buffer; buffer.addValue(0,Ji); - EXPECT_EQ(-0.005, buffer.valueFor()); + EXPECT_EQ(-0.0005, buffer.valueFor()); buffer.addValue(0,Je); - EXPECT_EQ(-0.004,buffer.valueFor()); + EXPECT_EQ(-0.0004,buffer.valueFor()); buffer.addValue(0,4*Je); - EXPECT_EQ(0.000,buffer.valueFor()); + EXPECT_EQ(0.0000,buffer.valueFor()); } TEST(NetworkTest, NetworkNumbers) { Network network; network.initialize(); std::vector neurones; neurones = network.getNeurones(); int Icompteur(0); int Ecompteur(0); int NeuronesCompteur(0); for (auto neu : neurones) { if (neu->getStatus()==Excitatory) { ++Ecompteur; } else { ++Icompteur; } ++NeuronesCompteur; } EXPECT_EQ(12500,NeuronesCompteur); EXPECT_EQ(10000,Ecompteur); EXPECT_EQ(2500,Icompteur); } TEST(NetworkTest, Verify_Excitatory_Connection) { Network network; network.initialize(); std::vector neurones; neurones = network.getNeurones(); neurones[0]->addConnection(neurones,1); neurones[0]->sendInformation(0); - EXPECT_EQ(0.001,neurones[1]->outsideInput()); + EXPECT_EQ(0.0001,neurones[1]->outsideInput()); } TEST (NetworkTest, Verify_Inhibitory_Connection) { Network network; network.initialize(); std::vector neurones; neurones = network.getNeurones(); neurones[10000]->addConnection(neurones,1); neurones[10000]->sendInformation(0); - EXPECT_EQ(-0.005,neurones[1]->outsideInput()); + EXPECT_EQ(-0.0005,neurones[1]->outsideInput()); } TEST (NetworkTest, Verify_Connection_Numbers) { Network network; network.initialize(); std::vector neurones; neurones = network.getNeurones(); network.ConnectEachNeurone(); std::vector targets; int connectionCompteur(0); int InCounteur(0); int ExCounteur(0); for (auto neu : neurones) { connectionCompteur+=neu->countConnection(0,neurones, InCounteur, ExCounteur); } EXPECT_EQ(1250,connectionCompteur); EXPECT_EQ(250, InCounteur); EXPECT_EQ(1000, ExCounteur); } int main (int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } \ No newline at end of file