1 //
2 // cMigrationMatrix.cc
3 // Avida-Core
4 //
5 // Created by Chad Byers on 2/16/12.
6 // Copyright (c) 2012 Michigan State University. All rights reserved.
7 //
8
9 #include "cMigrationMatrix.h"
10
11 #include "avida/core/Feedback.h"
12 #include "cInitFile.h"
13 #include "cString.h"
14 #include "cStringUtil.h"
15
cMigrationMatrix()16 cMigrationMatrix::cMigrationMatrix(){
17
18 };
19
~cMigrationMatrix()20 cMigrationMatrix::~cMigrationMatrix(){
21
22 }
23
GetOffspringCountAt(int from_deme_id,int to_deme_id)24 int cMigrationMatrix::GetOffspringCountAt(int from_deme_id, int to_deme_id){
25 assert(from_deme_id >= 0 && from_deme_id < m_offspring_migration_counts.GetSize());
26 assert(to_deme_id >= 0 && to_deme_id < m_offspring_migration_counts[from_deme_id].GetSize());
27 return m_offspring_migration_counts[from_deme_id][to_deme_id];
28 };
29
GetParasiteCountAt(int from_deme_id,int to_deme_id)30 int cMigrationMatrix::GetParasiteCountAt(int from_deme_id, int to_deme_id){
31 assert(from_deme_id >= 0 && from_deme_id < m_parasite_migration_counts.GetSize());
32 assert(to_deme_id >= 0 && to_deme_id < m_parasite_migration_counts[from_deme_id].GetSize());
33 return m_parasite_migration_counts[from_deme_id][to_deme_id];
34 };
35
AlterConnectionWeight(const int from_deme_id,const int to_deme_id,const double alter_amount)36 bool cMigrationMatrix::AlterConnectionWeight(const int from_deme_id, const int to_deme_id, const double alter_amount){
37 m_migration_matrix[from_deme_id][to_deme_id] += alter_amount;
38 m_row_connectivity_sums[from_deme_id] += alter_amount;
39 double row_sum = 0.0;
40 for(int col = 0; col < m_migration_matrix[from_deme_id].GetSize();col++){
41 row_sum += m_migration_matrix[from_deme_id][col];
42 }
43 if(m_migration_matrix[from_deme_id][to_deme_id] < 0.0 || row_sum <= 0.0){
44 return false;
45 }
46 else
47 return true;
48 };
49
GetProbabilisticDemeID(const int from_deme_id,cRandom & p_rng,bool p_is_parasite_migration)50 int cMigrationMatrix::GetProbabilisticDemeID(const int from_deme_id,cRandom& p_rng,bool p_is_parasite_migration){
51 assert(0 <= from_deme_id && from_deme_id < m_migration_matrix.GetSize());
52 double row_range_sum = 0.0;
53 double rand_dbl_value_in_range = p_rng.GetDouble(m_row_connectivity_sums[from_deme_id]);
54 for(int col = 0; col < m_migration_matrix[from_deme_id].GetSize(); col++){
55 rand_dbl_value_in_range -= m_migration_matrix[from_deme_id][col];
56 if(rand_dbl_value_in_range <= 0.0){
57 if(p_is_parasite_migration)
58 m_parasite_migration_counts[from_deme_id][col] += 1;
59 else
60 m_offspring_migration_counts[from_deme_id][col] += 1;
61
62 return col;
63 }
64 }
65 // Should never get to this point
66 assert(false);
67 };
68
Load(const int num_demes,const cString & filename,const cString & working_dir,bool p_count_parasites,bool p_count_offspring,bool p_is_reload,Feedback & feedback)69 bool cMigrationMatrix::Load(const int num_demes, const cString& filename, const cString& working_dir,bool p_count_parasites, bool p_count_offspring, bool p_is_reload, Feedback& feedback){
70 m_migration_matrix.ResizeClear(0);
71 m_row_connectivity_sums.ResizeClear(0);
72 cInitFile infile(filename, working_dir);
73 if (!infile.WasOpened()) {
74 for (int i = 0; i < infile.GetFeedback().GetNumMessages(); i++) {
75 switch (infile.GetFeedback().GetMessageType(i)) {
76 case cUserFeedback::UF_ERROR:
77 feedback.Error(infile.GetFeedback().GetMessage(i));
78 break;
79 case cUserFeedback::UF_WARNING:
80 feedback.Warning(infile.GetFeedback().GetMessage(i));
81 break;
82 default:
83 feedback.Notify(infile.GetFeedback().GetMessage(i));
84 }
85 }
86 feedback.Error("failed to load migration matrix '%s'", (const char*)filename);
87 return false;
88 }
89
90 tSmartArray<double> f_temp_row;
91 for (int line_id = 0; line_id < infile.GetNumLines(); line_id++) {
92 // Load the next line from the file.
93 f_temp_row.ResizeClear(0);
94 cString f_curr_line = infile.GetLine(line_id);
95 double f_row_sum = 0.0;
96 while(!f_curr_line.IsEmpty()){
97 double val = f_curr_line.Pop(',').AsDouble();
98 if(val < 0.0){
99 feedback.Error("Cannot have a negative connection in connection matrix");
100 return false;
101 }
102 f_row_sum += val;
103 f_temp_row.Push(val);
104 }
105 if(f_row_sum == 0.0){
106 feedback.Error("Cannot have a row sum of 0.0 in connection matrix");
107 return false;
108 }
109 else{
110 m_row_connectivity_sums.Push(f_row_sum);
111 }
112 m_migration_matrix.Push(f_temp_row);
113 }
114
115 if(num_demes != m_migration_matrix.GetSize()){
116 feedback.Error("The number of demes in the migration matrix (%i) did not match the NUM_DEMES (%i) parameter in avida.cfg.",m_migration_matrix.GetSize(),num_demes);
117 return false;
118 }
119 for(int f_row = 0; f_row < m_migration_matrix.GetSize(); f_row++){
120 if(m_migration_matrix[f_row].GetSize() != m_migration_matrix.GetSize()){
121 feedback.Error("The number of columns in row %i did not match total number of demes",f_row);
122 return false;
123 }
124 if(m_migration_matrix[f_row].GetSize() != num_demes){
125 feedback.Error("The number of demes in the migration matrix (%i) did not match the NUM_DEMES (%i) parameter in avida.cfg.",m_migration_matrix.GetSize(),num_demes);
126 return false;
127 }
128 }
129
130 if(p_count_parasites && !p_is_reload){
131 m_parasite_migration_counts.Resize(num_demes, tSmartArray<int>(num_demes,0));
132 ResetParasiteCounts();
133 }
134
135 if(p_count_offspring && !p_is_reload){
136 m_offspring_migration_counts.Resize(num_demes, tSmartArray<int>(num_demes,0));
137 ResetOffspringCounts();
138 }
139
140 return true;
141 }
142
Print()143 void cMigrationMatrix::Print(){
144 for(int row = 0; row < m_migration_matrix.GetSize(); row++){
145 for(int col = 0; col < m_migration_matrix[row].GetSize(); col++){
146 std::cout << m_migration_matrix[row][col];
147 if(col + 1 < m_migration_matrix[row].GetSize())
148 std::cout << ",";
149 }
150 std::cout << std::endl;
151 }
152 };
153
ResetParasiteCounts()154 void cMigrationMatrix::ResetParasiteCounts(){
155 for(int row = 0; row < m_parasite_migration_counts.GetSize(); row++){
156 for(int col = 0; col < m_parasite_migration_counts[row].GetSize(); col++){
157 m_parasite_migration_counts[row][col] = 0;
158 }
159 }
160 };
161
ResetOffspringCounts()162 void cMigrationMatrix::ResetOffspringCounts(){
163 for(int row = 0; row < m_offspring_migration_counts.GetSize(); row++){
164 for(int col = 0; col < m_offspring_migration_counts[row].GetSize(); col++){
165 m_offspring_migration_counts[row][col] = 0;
166 }
167 }
168 };
169