-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathEfficientSymbiont.h
More file actions
295 lines (257 loc) · 8.91 KB
/
Copy pathEfficientSymbiont.h
File metadata and controls
295 lines (257 loc) · 8.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#ifndef EFFSYM_H
#define EFFSYM_H
#include "../default_mode/Symbiont.h"
#include "EfficientWorld.h"
#include "EfficientHost.h"
#include <optional>
class EfficientSymbiont: public Symbiont {
protected:
/**
*
* Purpose: Represents the efficiency of a symbiont. This has a multiplicable impact on a
* symbiont's resource collection.
*
*/
double efficiency;
/**
*
* Purpose: Represents the standard deviation of the values
* chosen as mutations of a symbiont's interaction value when
* horizontal transmission is occuring. .
*
*/
double ht_mut_size = 0.002;
/**
*
* Purpose: Represents the probability (0-1) of mutation occurring
* during horizontal transmission.
*
*/
double ht_mut_rate = 0;
/**
*
* Purpose: Represents the probability (0-1) of mutation occurring
* during horizontal transmission for the efficiency trait.
*
*/
double eff_mut_rate = 0;
/**
*
* Purpose: Represents the world that the efficient symbionts are living in.
*
*/
emp::Ptr<EfficientWorld> my_world = NULL;
/**
*
* Purpose: Holds all configuration settings and points to same configuration
* object as my_config from superclass, but with the correct subtype.
*
*/
emp::Ptr<SymConfigEfficient> efficient_config = NULL;
public:
/**
* The constructor for efficient symbiont
*/
EfficientSymbiont(emp::Ptr<emp::Random> _random, emp::Ptr<EfficientWorld> _world, emp::Ptr<SymConfigEfficient> _config, double _intval=0.0, double _points = 0.0, double _efficient = 0.1) : Symbiont(_random, _world, _config, _intval, _points) {
efficiency = _efficient;
my_world = _world;
efficient_config = _config;
if (efficient_config->HORIZ_MUTATION_RATE() < 0) {
ht_mut_rate = efficient_config->MUTATION_RATE();
} else {
ht_mut_rate = efficient_config->HORIZ_MUTATION_RATE();
}
if (efficient_config->HORIZ_MUTATION_SIZE() < 0) {
ht_mut_size = efficient_config->MUTATION_SIZE();
} else {
ht_mut_size = efficient_config->HORIZ_MUTATION_SIZE();
}
}
/**
* Input: None
*
* Output: None
*
* Purpose: To force a copy constructor to be generated by the compiler.
*/
EfficientSymbiont(const EfficientSymbiont &) = default;
/**
* Input: None
*
* Output: None
*
* Purpose: To force a move constructor to be generated by the compiler
*/
EfficientSymbiont(EfficientSymbiont &&) = default;
/**
* Input: None
*
* Output: None
*
* Purpose: To tell the compiler to use its default generated variants of the constructor
*/
EfficientSymbiont() = default;
/**
* Input: None
*
* Output: Name of class as string, EfficientSymbiont
*
* Purpose: To know which subclass the object is
*/
std::string const GetName() const {
return "EfficientSymbiont";
}
/**
* Input: Efficiency value
*
* Output: None
*
* Purpose: Setting an efficient symbiont's efficiency value.
*/
void SetEfficiency(double _in) {
if (_in > 1 || _in < 0) throw "Invalid efficiency chance. Must be between 0 and 1 (inclusive)";
efficiency = _in;
}
/**
* Input: None
*
* Output: A double representing the symbiont's efficiency.
*
* Purpose: Getting an efficient symbiont's efficiency value.
*/
double GetEfficiency() const { return efficiency; }
/**
* Input: A double representing the amount to be incremented to a symbiont's points.
*
* Output: None
*
* Purpose: Incrementing an efficient symbiont's points.
* The points are adjusted by the efficiency of the symbiont.
*/
void AddPoints(double _in) {points += (_in * efficiency);}
/**
* Input: String indicating mode, either "vertical" or "horizontal"
*
* Output: None
*
* Purpose: Mutating the efficiency of an efficient symbiont based upon the config
* setting for mutation size.
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
void Mutate(const std::string& mode) {
double local_size;
double local_rate;
double int_rate;
if (mode == "vertical") {
local_rate = efficient_config->MUTATION_RATE();
local_size = efficient_config->MUTATION_SIZE();
} else if (mode == "horizontal") {
local_rate = ht_mut_rate;
local_size = ht_mut_size;
} else {
throw "Illegal argument passed to mutate in EfficientSymbiont";
}
if (efficient_config->EFFICIENCY_MUT_RATE() >= 0) {
eff_mut_rate = efficient_config->EFFICIENCY_MUT_RATE();
} else {
eff_mut_rate = local_rate;
}
if (efficient_config->INT_VAL_MUT_RATE() >= 0) {
int_rate = efficient_config->INT_VAL_MUT_RATE();
} else {
int_rate = local_rate;
}
if (random->GetDouble(0.0, 1.0) <= int_rate) {
interaction_val += random->GetNormal(0.0, local_size);
if (interaction_val < -1) interaction_val = -1;
else if (interaction_val > 1) interaction_val = 1;
//also modify infection chance, which is between 0 and 1
if (efficient_config->FREE_LIVING_SYMS()) {
infection_chance += random->GetNormal(0.0, local_size);
if (infection_chance < 0) infection_chance = 0;
else if (infection_chance > 1) infection_chance = 1;
}
}
if (random->GetDouble(0.0, 1.0) <= eff_mut_rate) {
efficiency += random->GetNormal(0.0, local_size);
if (efficiency < 0) efficiency = 0;
else if (efficiency > 1) efficiency = 1;
}
}
#pragma clang diagnostic pop
/**
* Input: None.
*
* Output: A new bacterium with same properties as this bacterium.
*
* Purpose: To avoid creating an organism via constructor in other methods.
*/
emp::Ptr<Organism> MakeNew() {
emp::Ptr<EfficientSymbiont> sym_baby = emp::NewPtr<EfficientSymbiont>(random, my_world, efficient_config, GetIntVal());
sym_baby->SetInfectionChance(GetInfectionChance());
sym_baby->SetEfficiency(GetEfficiency());
return sym_baby;
}
/**
* Input: String to indicate the mode of transmission, either vertical or horizontal
*
* Output: The pointer to the newly created organism
*
* Purpose: To produce a new symbiont
*/
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
emp::Ptr<Organism> Reproduce(const std::string& mode) {
emp::Ptr<Organism> sym_baby = MakeNew();
sym_baby->Mutate(mode);
return sym_baby;
}
#pragma clang diagnostic pop
/**
* Input: The pointer to the organism that is the new host baby
*
* Output: None
*
* Purpose: To allow for vertical transmission to occur
*/
std::optional<emp::Ptr<Organism>> VerticalTransmission(emp::Ptr<Organism> host_baby) {
bool success = false;
emp::Ptr<Organism> sym_baby;
if ((my_world->WillTransmit()) && GetPoints() >= efficient_config->SYM_VERT_TRANS_RES()) { //if the world permits vertical tranmission and the sym has enough resources, transmit!
sym_baby = Reproduce("vertical");
success = host_baby->AddSymbiont(sym_baby) > 0;
//vertical transmission data node
emp::DataMonitor<double, emp::data::Histogram>& data_node_attempts_verttrans = my_world->GetVerticalTransmissionAttemptCount();
data_node_attempts_verttrans.AddDatum(GetIntVal());
}
return (success) ? std::optional<emp::Ptr<Organism>>{sym_baby} : std::nullopt;
}
/**
* Input: The location of the organism as a WorldPosition
*
* Output: None
*
* Purpose: To check and allow for horizontal transmission to occur
*/
void IndependentReproduction(emp::WorldPosition location) {
//TODO: streamline with default mode's split up ind repro if we revisit this mode
if (efficient_config->HORIZ_TRANS()) { //non-lytic horizontal transmission enabled
if (GetPoints() >= efficient_config->SYM_HORIZ_TRANS_RES()) {
// symbiont reproduces independently (horizontal transmission) if it has enough resources
// new symbiont in this host with mutated value
SetPoints(0); //TODO: test just subtracting points instead of setting to 0
emp::Ptr<Organism> sym_baby = Reproduce("horizontal");
emp::WorldPosition new_pos = my_world->SymDoBirth(sym_baby, this, location);
//horizontal transmission data nodes
emp::DataMonitor<double, emp::data::Histogram>& data_node_attempts_horiztrans = my_world->GetHorizontalTransmissionAttemptCount();
data_node_attempts_horiztrans.AddDatum(GetIntVal());
emp::DataMonitor<double, emp::data::Histogram>& data_node_successes_horiztrans = my_world->GetHorizontalTransmissionSuccessCount();
if (new_pos.IsValid()) {
data_node_successes_horiztrans.AddDatum(GetIntVal());
}
}
}
}
};
#endif