55 std::complex<double> x) {
56 double real = 0.f, imag = 0.f;
62 for (n = 0; n < coeffs.size(); n++) {
63 std::complex<double> tmp =
64 coeffs[n] * std::pow(x, coeffs.size() - n - 1);
69 return std::complex<double>(real, imag);
111 const std::valarray<double> &coeffs,
112 std::valarray<std::complex<double>> *roots,
bool write_log =
false) {
113 long double tol_condition = 1;
116 std::ofstream log_file;
122 log_file.open(
"durand_kerner.log.csv");
123 if (!log_file.is_open()) {
124 perror(
"Unable to create a storage log file!");
125 std::exit(EXIT_FAILURE);
127 log_file <<
"iter#,";
129 for (n = 0; n < roots->size(); n++) log_file <<
"root_" << n <<
",";
131 log_file <<
"avg. correction";
133 for (n = 0; n < roots->size(); n++)
137 bool break_loop =
false;
144 if (log_file.is_open())
145 log_file <<
"\n" << iter <<
",";
148#pragma omp parallel for shared(break_loop, tol_condition)
150 for (n = 0; n < roots->size(); n++) {
154 std::complex<double> numerator, denominator;
157 for (
int i = 0; i < roots->size(); i++)
159 denominator *= (*roots)[n] - (*roots)[i];
161 std::complex<long double> delta = numerator / denominator;
163 if (std::isnan(std::abs(delta)) || std::isinf(std::abs(delta))) {
164 std::cerr <<
"\n\nOverflow/underrun error - got value = "
165 << std::abs(delta) <<
"\n";
170 (*roots)[n] -= delta;
175 tol_condition = std::max(tol_condition, std::abs(std::abs(delta)));
182 if (log_file.is_open()) {
183 for (n = 0; n < roots->size(); n++)
187#if defined(DEBUG) || !defined(NDEBUG)
188 if (iter % 500 == 0) {
189 std::cout <<
"Iter: " << iter <<
"\t";
190 for (n = 0; n < roots->size(); n++)
192 std::cout <<
"\t\tabsolute average change: " << tol_condition
197 if (log_file.is_open())
198 log_file << tol_condition;
201 return std::pair<uint32_t, long double>(iter, tol_condition);
209 const std::valarray<double> coeffs = {1, 0, 4};
210 std::valarray<std::complex<double>> roots(2);
211 std::valarray<std::complex<double>> expected = {
212 std::complex<double>(0., 2.),
213 std::complex<double>(0., -2.)
217 for (
int n = 0; n < roots.size(); n++) {
218 roots[n] = std::complex<double>(std::rand() % 100, std::rand() % 100);
225 for (
int i = 0; i < roots.size(); i++) {
229 for (
int j = 0; j < roots.size(); j++)
230 err1 |= std::abs(std::abs(roots[i] - expected[j])) < 1e-3;
234 std::cout <<
"Test 1 passed! - " << result.first <<
" iterations, "
235 << result.second <<
" accuracy"
244 const std::valarray<double> coeffs = {
245 1. / 64., 0., 0., -1.};
246 std::valarray<std::complex<double>> roots(3);
247 const std::valarray<std::complex<double>> expected = {
248 std::complex<double>(4., 0.), std::complex<double>(-2., 3.46410162),
249 std::complex<double>(-2., -3.46410162)
253 for (
int n = 0; n < roots.size(); n++) {
254 roots[n] = std::complex<double>(std::rand() % 100, std::rand() % 100);
261 for (
int i = 0; i < roots.size(); i++) {
265 for (
int j = 0; j < roots.size(); j++)
266 err1 |= std::abs(std::abs(roots[i] - expected[j])) < 1e-3;
270 std::cout <<
"Test 2 passed! - " << result.first <<
" iterations, "
271 << result.second <<
" accuracy"