Implements Durand Kerner iterative algorithm to compute all roots of a polynomial.
112 {
113 long double tol_condition = 1;
114 uint32_t iter = 0;
115 int n;
117
118 if (write_log) {
119
120
121
122 log_file.
open(
"durand_kerner.log.csv");
124 perror(
"Unable to create a storage log file!");
126 }
127 log_file << "iter#,";
128
129 for (n = 0; n < roots->size(); n++) log_file << "root_" << n << ",";
130
131 log_file << "avg. correction";
132 log_file << "\n0,";
133 for (n = 0; n < roots->size(); n++)
135 }
136
137 bool break_loop = false;
139 !break_loop) {
140 tol_condition = 0;
141 iter++;
142 break_loop = false;
143
145 log_file << "\n" << iter << ",";
146
147#ifdef _OPENMP
148#pragma omp parallel for shared(break_loop, tol_condition)
149#endif
150 for (n = 0; n < roots->size(); n++) {
151 if (break_loop)
152 continue;
153
156 denominator = 1.0;
157 for (int i = 0; i < roots->size(); i++)
158 if (i != n)
159 denominator *= (*roots)[n] - (*roots)[i];
160
162
164 std::cerr <<
"\n\nOverflow/underrun error - got value = "
165 << std::abs(delta) << "\n";
166
167 break_loop = true;
168 }
169
170 (*roots)[n] -= delta;
171
172#ifdef _OPENMP
173#pragma omp critical
174#endif
175 tol_condition =
std::max(tol_condition, std::abs(std::abs(delta)));
176 }
177
178
179 if (break_loop)
180 break;
181
183 for (n = 0; n < roots->size(); n++)
185 }
186
187#if defined(DEBUG) || !defined(NDEBUG)
188 if (iter % 500 == 0) {
190 for (n = 0; n < roots->size(); n++)
192 std::cout <<
"\t\tabsolute average change: " << tol_condition
193 << "\n";
194 }
195#endif
196
198 log_file << tol_condition;
199 }
200
202}
bool check_termination(long double delta)
Definition durand_kerner_roots.cpp:92
const char * complex_str(const std::complex< double > &x)
Definition durand_kerner_roots.cpp:77
std::complex< double > poly_function(const std::valarray< double > &coeffs, std::complex< double > x)
Definition durand_kerner_roots.cpp:54