- n-ary roots from complex numbers... - 1 Update
- Behavior for out-of-memory - 1 Update
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 10 04:09PM -0700 The goal of this crude sample code is to take the n-ary roots of a complex number. Iterating a complex number z to all of its z^(1/n) roots. This code derives the polar form from z, and iterates all of the roots. This is an essential part of providing the ability of storing n-ary tokens in a set of iterated roots. We can map the n roots, to a token table, and store data. I will explain more later, however, please take a look at the code, run it, tear it apart, and give me pointers on how to make it better, please? Thank you all for your time. The function at the heart of this is the function ct_roots that breaks apart a complex number into its n-ary roots. Here is the code: ______________________________ #include <complex> #include <iostream> #include <vector> #include <limits> #include <cstdint> // want to work with 64-bit numbers #include <cassert> // want to sanity check run time... // Well, I need some consistent typenames... ;^) typedef std::int64_t ct_int; typedef std::uint64_t ct_uint; typedef double ct_float; typedef std::numeric_limits<ct_float> ct_float_nlim; typedef std::complex<ct_float> ct_complex; typedef std::complex<ct_uint> ct_complex_uint; typedef std::vector<ct_complex> ct_complex_vec; #define CT_PI 3.14159265358979323846 // Round up and convert the real and imaginary // parts of z to unsigned integers of type ct_uint // return a complex number with unsigned integer parts ct_complex_uint ct_round_uint( ct_complex const& z ) { ct_uint re = (ct_uint)std::floor(std::abs(z.real()) + .5); ct_uint im = (ct_uint)std::floor(std::abs(z.imag()) + .5); return ct_complex_uint(re, im); } // the integer p shall not be zero // create abs(p) roots of z wrt z^(1/p); // store them in out, and return the average error. ct_float ct_roots( ct_complex const& z, ct_int p, ct_complex_vec& out ) { assert(p != 0); // Gain the basics ct_float radius = std::pow(std::abs(z), 1.0 / p); ct_float angle_base = std::arg(z) / p; ct_float angle_step = (CT_PI * 2.0) / p; // Setup the iteration ct_uint n = std::abs(p); ct_float avg_err = 0.0; // Calculate the n roots... for (ct_uint i = 0; i < n; ++i) { // our angle ct_float angle = angle_step * i; // our point ct_complex c = { std::cos(angle_base + angle) * radius, std::sin(angle_base + angle) * radius }; // output data out.push_back(c); // Raise our root the the power... ct_complex raised = std::pow(c, p); ct_complex_uint raised_rounded = ct_round_uint(raised); // Output... std::cout << "ct_roots::raised[" << i << "]:" << raised << "\n"; std::cout << "ct_roots::raised_rounded[" << i << "]:" << raised_rounded << "\n"; std::cout << "___________________________________\n"; // Sum up the Go% damn floating point errors! avg_err = avg_err + std::abs(raised - z); } // gain the average error sum... ;^o return avg_err / n; } int main() { std::cout.precision(ct_float_nlim::max_digits10); { // Our origin point z ct_complex z = { 94143178827, 0 }; std::cout << "z:" << z << " - " << std::abs(z) << "\n"; std::cout << "**********************************************\n\n"; // The call to ct_roots... ct_complex_vec roots; ct_float avg_err = ct_roots(z, 23, roots); std::cout << "\n\navg_err:" << avg_err << "\n"; // Output std::cout << "___________________________________\n"; for (unsigned int i = 0; i < roots.size(); ++i) { ct_complex& root = roots[i]; std::cout << "root[" << i << "]:" << root << " - " << std::abs(root) << "\n"; } std::cout << "___________________________________\n"; } // Fin... std::cout << "\n\nFin, hit <ENTER> to exit...\n"; std::fflush(stdout); std::cin.get(); return 0; } ______________________________ Can you run this? BTW, what about possibly reducing the average error ratio? Any ideas? Will post more context later on tonight or tommorw. :^) |
Vir Campestris <vir.campestris@invalid.invalid>: Apr 10 09:06PM +0100 On 07/04/2017 14:07, Stefan Ram wrote: > T* allocate(size_t n); > .... > 4 Throws: bad_alloc if the storage cannot be obtained. Except of course Linux will say "Yes, you can have a gigabyte". Then fail at page fault time. I don't think apps can cope with that. AIUI you can turn overcommit off. Its mere existence tells us how small a problem true out-of-memory is on desktop class and above. Andy |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment