Skip to content

Commit ea13f4b

Browse files
author
Eduardo Izquierdo
committed
v1
1 parent 141ee25 commit ea13f4b

18 files changed

+1409475
-0
lines changed

Diff for: Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
main: main.o Worm.o WormBody.o NervousSystem.o StretchReceptor.o Muscles.o TSearch.o random.o
2+
g++ -pthread -o main main.o Worm.o WormBody.o NervousSystem.o StretchReceptor.o Muscles.o TSearch.o random.o
3+
random.o: random.cpp random.h VectorMatrix.h
4+
g++ -c -O3 -flto random.cpp
5+
TSearch.o: TSearch.cpp TSearch.h
6+
g++ -c -O3 -flto TSearch.cpp
7+
Worm.o: Worm.cpp Worm.h
8+
g++ -c -O3 -flto Worm.cpp
9+
WormBody.o: WormBody.cpp WormBody.h
10+
g++ -c -O3 -flto WormBody.cpp
11+
NervousSystem.o: NervousSystem.cpp NervousSystem.h VectorMatrix.h random.h
12+
g++ -c -O3 -flto NervousSystem.cpp
13+
StretchReceptor.o: StretchReceptor.cpp StretchReceptor.h
14+
g++ -c -O3 -flto StretchReceptor.cpp
15+
Muscles.o: Muscles.cpp Muscles.h VectorMatrix.h random.h
16+
g++ -c -O3 -flto Muscles.cpp
17+
main.o: main.cpp Worm.h WormBody.h StretchReceptor.h Muscles.h TSearch.h
18+
g++ -c -O3 -flto main.cpp
19+
clean:
20+
rm *.o main

Diff for: Muscles.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// Muscles.cpp
3+
// one
4+
//
5+
// Created by Eduardo Izquierdo on 3/26/15.
6+
// Copyright (c) 2015 Eduardo Izquierdo. All rights reserved.
7+
//
8+
9+
#include "Muscles.h"
10+
11+
Muscles::Muscles(int nmuscles, double t_muscle)
12+
{
13+
SetMuscleParams(nmuscles, t_muscle);
14+
}
15+
16+
void Muscles::SetMuscleParams(int nmuscles, double t_muscle)
17+
{
18+
Nmuscles = nmuscles;
19+
T_muscle = t_muscle;
20+
V_muscle.SetBounds(1,Nmuscles,1,2);
21+
V_input.SetBounds(1,Nmuscles,1,2);
22+
}
23+
24+
void Muscles::InitializeMuscleState()
25+
{
26+
V_muscle.FillContents(0.0);
27+
V_input.FillContents(0.0);
28+
}
29+
30+
void Muscles::EulerStep(double StepSize)
31+
{
32+
for (int i = 1; i <= Nmuscles; i++)
33+
{
34+
V_muscle[i][1] += StepSize*((V_input[i][1] - V_muscle[i][1])/T_muscle);
35+
V_muscle[i][2] += StepSize*((V_input[i][2] - V_muscle[i][2])/T_muscle);
36+
}
37+
}

Diff for: Muscles.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//
2+
// LocomotionCircuit.h
3+
//
4+
// Copyright (c) 2015 Eduardo Izquierdo. All rights reserved.
5+
//
6+
7+
#include "VectorMatrix.h"
8+
#include "random.h"
9+
#include <cmath>
10+
using namespace std;
11+
12+
class Muscles {
13+
public:
14+
15+
Muscles(int nmuscles = 24, double t_muscle = 0.1);
16+
17+
void SetMuscleParams(int nmuscles, double t_muscle);
18+
19+
void InitializeMuscleState();
20+
21+
void EulerStep(double StepSize);
22+
23+
void SetDorsalMuscleInput(int muscle, double input){V_input[muscle][1] = input;};
24+
void SetVentralMuscleInput(int muscle, double input){V_input[muscle][2] = input;};
25+
26+
void SetDorsalMuscleActivation(int muscle, double activation){V_muscle[muscle][1] = activation;};
27+
void SetVentralMuscleActivation(int muscle, double activation){V_muscle[muscle][2] = activation;};
28+
29+
double DorsalMuscleOutput(int muscle){return V_muscle[muscle][1];};
30+
double VentralMuscleOutput(int muscle){return V_muscle[muscle][2];};
31+
32+
TMatrix<double> V_muscle;
33+
TMatrix<double> V_input;
34+
35+
double T_muscle;
36+
int Nmuscles;
37+
};

Diff for: NervousSystem.cpp

+297
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
// ************************************************************
2+
// A nervous system class (based on the CTRNN class)
3+
//
4+
// RDB
5+
// 1/15 Created
6+
// ************************************************************
7+
8+
#include "NervousSystem.h"
9+
#include "random.h"
10+
#include <stdlib.h>
11+
12+
13+
// ****************************
14+
// Constructors and Destructors
15+
// ****************************
16+
17+
// The constructor
18+
19+
NervousSystem::NervousSystem(int newsize, int newmaxchemconns, int newmaxelecconns)
20+
{
21+
SetCircuitSize(newsize, newmaxchemconns, newmaxelecconns);
22+
}
23+
24+
25+
// The destructor
26+
27+
NervousSystem::~NervousSystem()
28+
{
29+
SetCircuitSize(0, 0, 0);
30+
}
31+
32+
33+
// *********
34+
// Utilities
35+
// *********
36+
37+
// Resize a circuit.
38+
39+
void NervousSystem::SetCircuitSize(int newsize, int newmaxchemconns, int newmaxelecconns)
40+
{
41+
size = newsize;
42+
if (newmaxchemconns == -1) maxchemconns = size;
43+
else maxchemconns = min(newmaxchemconns, size);
44+
if (newmaxelecconns == -1) maxelecconns = maxchemconns;
45+
else maxelecconns = min(newmaxelecconns, maxchemconns);
46+
states.SetBounds(1,size);
47+
states.FillContents(0.0);
48+
paststates.SetBounds(1,size);
49+
paststates.FillContents(0.0);
50+
outputs.SetBounds(1,size);
51+
outputs.FillContents(0.0);
52+
biases.SetBounds(1,size);
53+
biases.FillContents(0.0);
54+
gains.SetBounds(1,size);
55+
gains.FillContents(1.0);
56+
taus.SetBounds(1,size);
57+
taus.FillContents(1.0);
58+
Rtaus.SetBounds(1,size);
59+
Rtaus.FillContents(1.0);
60+
externalinputs.SetBounds(1,size);
61+
externalinputs.FillContents(0.0);
62+
NumChemicalConns.SetBounds(1,size);
63+
for (int i = 1; i <= size; i++)
64+
NumChemicalConns[i] = 0;
65+
chemicalweights.SetBounds(1,size,1,maxchemconns);
66+
NumElectricalConns.SetBounds(1,size);
67+
for (int i = 1; i <= size; i++)
68+
NumElectricalConns[i] = 0;
69+
electricalweights.SetBounds(1,size,1,maxelecconns);
70+
TempStates.SetBounds(1,size);
71+
TempOutputs.SetBounds(1,size);
72+
k1.SetBounds(1,size);
73+
k2.SetBounds(1,size);
74+
k3.SetBounds(1,size);
75+
k4.SetBounds(1,size);
76+
}
77+
78+
79+
// *********
80+
// Accessors
81+
// *********
82+
83+
double NervousSystem::ChemicalSynapseWeight(int from, int to)
84+
{
85+
for (int i = 1; i <= NumChemicalConns(to); i++) {
86+
if (chemicalweights[to][i].from == from)
87+
return chemicalweights[to][i].weight;
88+
}
89+
return 0.0;
90+
}
91+
92+
93+
void NervousSystem::SetChemicalSynapseWeight(int from, int to, double value)
94+
{
95+
// If the connection is already stored, just change its value
96+
for (int i = 1; i <= NumChemicalConns[to]; i++)
97+
if (chemicalweights[to][i].from == from) {
98+
chemicalweights[to][i].weight = value;
99+
return;
100+
};
101+
// Otherwise, make sure we have room for an additional connection ...
102+
if (NumChemicalConns[to] == maxchemconns) {
103+
cerr << "Maximum chemical synapses (" << maxchemconns << ") exceeded for neuron " << to << endl;
104+
exit(EXIT_FAILURE);
105+
}
106+
// ... and store it
107+
int i = ++NumChemicalConns[to];
108+
chemicalweights[to][i].from = from;
109+
chemicalweights[to][i].weight = value;
110+
}
111+
112+
113+
double NervousSystem::ElectricalSynapseWeight(int from, int to)
114+
{
115+
for (int i = 1; i <= NumElectricalConns(to); i++) {
116+
if (electricalweights[to][i].from == from)
117+
return electricalweights[to][i].weight;
118+
}
119+
return 0.0;
120+
}
121+
122+
123+
void NervousSystem::InternalSetElectricalSynapseWeight(int from, int to, double value)
124+
{
125+
// If the connection is already stored, just change its value
126+
for (int i = 1; i <= NumElectricalConns[to]; i++)
127+
if (electricalweights[to][i].from == from) {
128+
electricalweights[to][i].weight = value;
129+
return;
130+
};
131+
// Otherwise, make sure we have room for an additional connection ...
132+
if (NumElectricalConns[to] == maxelecconns) {
133+
cerr << "Maximum electrical synapses (" << maxelecconns << ") exceeded for neuron " << to << endl;
134+
exit(EXIT_FAILURE);
135+
}
136+
// ... and store it
137+
int i = ++NumElectricalConns[to];
138+
electricalweights[to][i].from = from;
139+
electricalweights[to][i].weight = value;
140+
}
141+
142+
void NervousSystem::SetElectricalSynapseWeight(int n1, int n2, double value)
143+
{
144+
if (value < 0) {
145+
cerr << "Electrical synapse weight between neurons " << n1 << " and " << n2 << " is negative: " << value << endl;
146+
exit(EXIT_FAILURE);
147+
}
148+
InternalSetElectricalSynapseWeight(n1, n2, value);
149+
InternalSetElectricalSynapseWeight(n2, n1, value);
150+
}
151+
152+
153+
// *******
154+
// Control
155+
// *******
156+
157+
// Randomize the states or outputs of a circuit.
158+
159+
void NervousSystem::RandomizeCircuitState(double lb, double ub)
160+
{
161+
for (int i = 1; i <= size; i++)
162+
SetNeuronState(i, UniformRandom(lb, ub));
163+
}
164+
165+
void NervousSystem::RandomizeCircuitState(double lb, double ub, RandomState &rs)
166+
{
167+
for (int i = 1; i <= size; i++)
168+
SetNeuronState(i, rs.UniformRandom(lb, ub));
169+
}
170+
171+
void NervousSystem::RandomizeCircuitOutput(double lb, double ub)
172+
{
173+
for (int i = 1; i <= size; i++)
174+
SetNeuronOutput(i, UniformRandom(lb, ub));
175+
}
176+
177+
void NervousSystem::RandomizeCircuitOutput(double lb, double ub, RandomState &rs)
178+
{
179+
for (int i = 1; i <= size; i++)
180+
SetNeuronOutput(i, rs.UniformRandom(lb, ub));
181+
}
182+
183+
184+
185+
// Integrate a circuit one step using Euler integration.
186+
void NervousSystem::EulerStep(double stepsize)
187+
{
188+
// Update past states (used for gap junctions)
189+
for (int i = 1; i <= size; i++){
190+
paststates[i] = states[i];
191+
}
192+
// Update the state of all neurons.
193+
for (int i = 1; i <= size; i++) {
194+
// External input
195+
double input = externalinputs[i];
196+
// Input from chemical synapses
197+
for (int j = 1; j <= NumChemicalConns[i]; j++)
198+
input += chemicalweights[i][j].weight * outputs[chemicalweights[i][j].from];
199+
// Input from electrical synapses
200+
for (int j = 1; j <= NumElectricalConns[i]; j++)
201+
input += electricalweights[i][j].weight * (paststates[electricalweights[i][j].from] - paststates[i]);
202+
// Take the step
203+
states[i] += stepsize * Rtaus[i] * (input - states[i]);
204+
}
205+
// Update the outputs of all neurons.
206+
for (int i = 1; i <= size; i++)
207+
outputs[i] = sigmoid(gains[i] * (states[i] + biases[i]));
208+
}
209+
210+
211+
// ****************
212+
// Input and Output
213+
// ****************
214+
215+
#include <iomanip>
216+
217+
ostream& operator<<(ostream& os, NervousSystem& c)
218+
{
219+
// Set the precision
220+
os << setprecision(32);
221+
// Write the size, maxchemconns and maxelecconns
222+
os << c.size << " " << c.maxchemconns << " " << c.maxelecconns << endl << endl;
223+
// Write the time constants
224+
for (int i = 1; i <= c.size; i++)
225+
os << c.taus[i] << " ";
226+
os << endl << endl;
227+
// Write the biases
228+
for (int i = 1; i <= c.size; i++)
229+
os << c.biases[i] << " ";
230+
os << endl << endl;
231+
// Write the gains
232+
for (int i = 1; i <= c.size; i++)
233+
os << c.gains[i] << " ";
234+
os << endl << endl;
235+
// Write the chemical weights in sparse format (N from1 weight1 ... fromN weightN)
236+
for (int i = 1; i <= c.size; i++) {
237+
cout << c.NumChemicalConns[i] << " ";
238+
for (int j = 1; j <= c.NumChemicalConns[i]; j++)
239+
os << c.chemicalweights[i][j].from << " " << c.chemicalweights[i][j].weight << " ";
240+
os << endl;
241+
}
242+
os << endl;
243+
// Write the electrical weights in sparse format (N from1 weight1 ... fromN weightN)
244+
for (int i = 1; i <= c.size; i++) {
245+
cout << c.NumElectricalConns[i] << " ";
246+
for (int j = 1; j <= c.NumElectricalConns[i]; j++)
247+
os << c.electricalweights[i][j].from << " " << c.electricalweights[i][j].weight << " ";
248+
os << endl;
249+
}
250+
// Return the ostream
251+
return os;
252+
}
253+
254+
255+
istream& operator>>(istream& is, NervousSystem& c)
256+
{
257+
// Read the sizes
258+
int size;
259+
is >> size;
260+
int maxchemconns;
261+
is >> maxchemconns;
262+
int maxelecconns;
263+
is >> maxelecconns;
264+
c.SetCircuitSize(size, maxchemconns, maxelecconns);
265+
// Read the time constants
266+
for (int i = 1; i <= size; i++) {
267+
is >> c.taus[i];
268+
c.Rtaus[i] = 1/c.taus[i];
269+
}
270+
// Read the biases
271+
for (int i = 1; i <= size; i++)
272+
is >> c.biases[i];
273+
// Read the gains
274+
for (int i = 1; i <= size; i++)
275+
is >> c.gains[i];
276+
// Read the chemical weights
277+
int n;
278+
for (int i = 1; i <= size; i++) {
279+
is >> n;
280+
for (int j = 1; j <= n; j++) {
281+
is >> c.chemicalweights[i][j].from;
282+
is >> c.chemicalweights[i][j].weight;
283+
c.NumChemicalConns[i]++;
284+
}
285+
}
286+
// Read the electrical weights
287+
for (int i = 1; i <= size; i++) {
288+
is >> n;
289+
for (int j = 1; j <= n; j++) {
290+
is >> c.electricalweights[i][j].from;
291+
is >> c.electricalweights[i][j].weight;
292+
c.NumElectricalConns[i]++;
293+
}
294+
}
295+
// Return the istream
296+
return is;
297+
}

0 commit comments

Comments
 (0)