- n-ary roots from complex numbers... - 15 Updates
- Range types - 3 Updates
- My C++ exercise for today (2017-03-30) - 1 Update
- Behavior for out-of-memory - 1 Update
- Importing absolute symbols as constexpr - 2 Updates
- My following projects were updated - 2 Updates
- storing/loading n-ary data via complex numbers... - 1 Update
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 13 10:28AM -0700 On 4/12/2017 5:57 AM, Manfred wrote: > numerical algorithms to calculate both values simultaneously in > significantly less time than the two separate calls. > I think it is a pity that sincos() was not included (was it considered?) That would have been a nice function to have. > used on 32-bit x86 > - on x86_64 it requires more work, but still the core numerical > algorithm (e.g. a Newton expansion) can be easily adapted to this. Nice. Well, I think that std::polar has the best chance of using sincos(). Need to check the implementation. |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 11 12:13PM -0700 On 4/10/2017 10:41 PM, Christian Gollwitzer wrote: > functions. Concerning accuracy, your algorithm is more accurate if you > compute roots of very high order (say 1e10) - probably not for useful > cases. Here is a function I wrote that uses your algorithm: _________________________________ ct_float cg_roots( ct_complex const& z, ct_int p, ct_complex_vec& out ) { assert(p != 0); /* Per: Christian Gollwitzer's untested code at: https://groups.google.com/d/msg/comp.lang.c++/05XwgswUnDg/gm_uqbcwAgAJ std::vector<ct_complex> myroots; ct_complex baseroot = std::pow(z, 1.0/p); myroots.push_back(baseroot); ct_complex root = baseroot; ct_complex phasor = baseroot / std::abs(baseroot); for (int i=1; i<n; i++) { root *= phasor; myroots.push_back(root); } */ // Did I fuc% up his code! Read here: ct_complex baseroot = std::pow(z, 1.0 / p); out.push_back(baseroot); ct_complex root = baseroot; ct_complex phasor = baseroot / std::abs(baseroot); ct_uint n = std::abs(p); ct_float avg_err = 0.0; for (ct_uint i = 1; i < n; ++i) { root *= phasor; out.push_back(root); // Raise our root the the power... ct_complex raised = std::pow(root, p); ct_complex_uint raised_rounded = ct_round_uint(raised); // Output... std::cout << "ct_roots_fast::raised[" << i << "]:" << raised << "\n"; std::cout << "ct_roots_fast::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; } _________________________________ When I change the call in main to ct_roots to cg_roots in main wrt the function in: _________________________________ 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); ct_float avg_err = cg_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; } _________________________________ I get the following incorrect output in the sense that it does show all of the roots: z:(94143178827,0) - 94143178827 ********************************************** ct_roots_fast::raised[1]:(94143178827,0) ct_roots_fast::raised_rounded[1]:(94143178827,0) ___________________________________ ct_roots_fast::raised[2]:(94143178827,0) ct_roots_fast::raised_rounded[2]:(94143178827,0) ___________________________________ ct_roots_fast::raised[3]:(94143178827,0) ct_roots_fast::raised_rounded[3]:(94143178827,0) ___________________________________ ct_roots_fast::raised[4]:(94143178827,0) ct_roots_fast::raised_rounded[4]:(94143178827,0) ___________________________________ ct_roots_fast::raised[5]:(94143178827,0) ct_roots_fast::raised_rounded[5]:(94143178827,0) ___________________________________ ct_roots_fast::raised[6]:(94143178827,0) ct_roots_fast::raised_rounded[6]:(94143178827,0) ___________________________________ ct_roots_fast::raised[7]:(94143178827,0) ct_roots_fast::raised_rounded[7]:(94143178827,0) ___________________________________ ct_roots_fast::raised[8]:(94143178827,0) ct_roots_fast::raised_rounded[8]:(94143178827,0) ___________________________________ ct_roots_fast::raised[9]:(94143178827,0) ct_roots_fast::raised_rounded[9]:(94143178827,0) ___________________________________ ct_roots_fast::raised[10]:(94143178827,0) ct_roots_fast::raised_rounded[10]:(94143178827,0) ___________________________________ ct_roots_fast::raised[11]:(94143178827,0) ct_roots_fast::raised_rounded[11]:(94143178827,0) ___________________________________ ct_roots_fast::raised[12]:(94143178827,0) ct_roots_fast::raised_rounded[12]:(94143178827,0) ___________________________________ ct_roots_fast::raised[13]:(94143178827,0) ct_roots_fast::raised_rounded[13]:(94143178827,0) ___________________________________ ct_roots_fast::raised[14]:(94143178827,0) ct_roots_fast::raised_rounded[14]:(94143178827,0) ___________________________________ ct_roots_fast::raised[15]:(94143178827,0) ct_roots_fast::raised_rounded[15]:(94143178827,0) ___________________________________ ct_roots_fast::raised[16]:(94143178827,0) ct_roots_fast::raised_rounded[16]:(94143178827,0) ___________________________________ ct_roots_fast::raised[17]:(94143178827,0) ct_roots_fast::raised_rounded[17]:(94143178827,0) ___________________________________ ct_roots_fast::raised[18]:(94143178827,0) ct_roots_fast::raised_rounded[18]:(94143178827,0) ___________________________________ ct_roots_fast::raised[19]:(94143178827,0) ct_roots_fast::raised_rounded[19]:(94143178827,0) ___________________________________ ct_roots_fast::raised[20]:(94143178827,0) ct_roots_fast::raised_rounded[20]:(94143178827,0) ___________________________________ ct_roots_fast::raised[21]:(94143178827,0) ct_roots_fast::raised_rounded[21]:(94143178827,0) ___________________________________ ct_roots_fast::raised[22]:(94143178827,0) ct_roots_fast::raised_rounded[22]:(94143178827,0) ___________________________________ avg_err:0 ___________________________________ root[0]:(3,0) - 3 root[1]:(3,0) - 3 root[2]:(3,0) - 3 root[3]:(3,0) - 3 root[4]:(3,0) - 3 root[5]:(3,0) - 3 root[6]:(3,0) - 3 root[7]:(3,0) - 3 root[8]:(3,0) - 3 root[9]:(3,0) - 3 root[10]:(3,0) - 3 root[11]:(3,0) - 3 root[12]:(3,0) - 3 root[13]:(3,0) - 3 root[14]:(3,0) - 3 root[15]:(3,0) - 3 root[16]:(3,0) - 3 root[17]:(3,0) - 3 root[18]:(3,0) - 3 root[19]:(3,0) - 3 root[20]:(3,0) - 3 root[21]:(3,0) - 3 root[22]:(3,0) - 3 ___________________________________ Fin, hit <ENTER> to exit... Notice the roots are all (3, 0)? This is not correct. Please try to find an error I may have created in my implementation of your code Christian Gollwitzer, wrt the cg_roots function. Sorry if I fuc%ed it up man... ;^o Fwiw, here is the output I get from using the original, slow trig infested original of mine: z:(94143178827,0) - 94143178827 ********************************************** ct_roots::raised[0]:(94143178827,0) ct_roots::raised_rounded[0]:(94143178827,0) ___________________________________ ct_roots::raised[1]:(94143178826.999603,6.0557511273702414e-05) ct_roots::raised_rounded[1]:(94143178827,0) ___________________________________ ct_roots::raised[2]:(94143178827.000259,-4.6116857044817097e-05) ct_roots::raised_rounded[2]:(94143178827,0) ___________________________________ ct_roots::raised[3]:(94143178827.000259,-6.9175285567225643e-05) ct_roots::raised_rounded[3]:(94143178827,0) ___________________________________ ct_roots::raised[4]:(94143178827.000259,-9.2233714089634195e-05) ct_roots::raised_rounded[4]:(94143178827,0) ___________________________________ ct_roots::raised[5]:(94143178826.999603,-0.00044975590179648512) ct_roots::raised_rounded[5]:(94143178827,0) ___________________________________ ct_roots::raised[6]:(94143178826.999603,-0.00013835057113445031) ct_roots::raised_rounded[6]:(94143178827,0) ___________________________________ ct_roots::raised[7]:(94143178827.000259,-0.00016140899965685982) ct_roots::raised_rounded[7]:(94143178827,0) ___________________________________ ct_roots::raised[8]:(94143178827.000259,-0.00018446742817926839) ct_roots::raised_rounded[8]:(94143178827,0) ___________________________________ ct_roots::raised[9]:(94143178827.000259,-0.00087645337507056794) ct_roots::raised_rounded[9]:(94143178827,0) ___________________________________ ct_roots::raised[10]:(94143178827.000259,-0.00089951180359297653) ct_roots::raised_rounded[10]:(94143178827,0) ___________________________________ ct_roots::raised[11]:(94143178827.000259,0.00041528480462239701) ct_roots::raised_rounded[11]:(94143178827,0) ___________________________________ ct_roots::raised[12]:(94143178827.000259,-0.00041528480462239701) ct_roots::raised_rounded[12]:(94143178827,0) ___________________________________ ct_roots::raised[13]:(94143178827.000259,-0.0011072707515136966) ct_roots::raised_rounded[13]:(94143178827,0) ___________________________________ ct_roots::raised[14]:(94143178826.999603,-0.00046140166166721089) ct_roots::raised_rounded[14]:(94143178827,0) ___________________________________ ct_roots::raised[15]:(94143178827.000259,0.00018446742817926839) ct_roots::raised_rounded[15]:(94143178827,0) ___________________________________ ct_roots::raised[16]:(94143178827.000259,-0.00050751851871203122) ct_roots::raised_rounded[16]:(94143178827,0) ___________________________________ ct_roots::raised[17]:(94143178827.000259,-0.0005305769472344397) ct_roots::raised_rounded[17]:(94143178827,0) ___________________________________ ct_roots::raised[18]:(94143178827.000259,-0.00088809913494129387) ct_roots::raised_rounded[18]:(94143178827,0) ___________________________________ ct_roots::raised[19]:(94143178827.000259,-0.0012456213226481479) ct_roots::raised_rounded[19]:(94143178827,0) ___________________________________ ct_roots::raised[20]:(94143178827.000259,-0.0012686797511705563) ct_roots::raised_rounded[20]:(94143178827,0) ___________________________________ ct_roots::raised[21]:(94143178827.000259,4.6116857044817097e-05) ct_roots::raised_rounded[21]:(94143178827,0) ___________________________________ ct_roots::raised[22]:(94143178827.000259,-0.00031140533066203698) ct_roots::raised_rounded[22]:(94143178827,0) ___________________________________ avg_err:0.00056815732700208645 ___________________________________ root[0]:(3,0) - 3 root[1]:(2.8887518620433976,0.80939031347107282) - 2.9999999999999996 root[2]:(2.5632582136394655,1.5587518501063007) - 3 root[3]:(2.0476594296559623,2.1925078928343722) - 3 root[4]:(1.3801951131934567,2.6636556552071258) - 3 root[5]:(0.61036803915790194,2.9372522630469682) - 2.9999999999999996 root[6]:(-0.20472724009401264,2.9930063075716173) - 2.9999999999999996 root[7]:(-1.0046388365129584,2.8267827663564615) - 3 root[8]:(-1.7300409663446012,2.4509096790313265) - 3 root[9]:(-2.3271338721132588,1.893263832978159) - 3 root[10]:(-2.7516339045163587,1.1952032695387254) - 3 root[11]:(-2.9720578381089924,0.40849994728873995) - 3 root[12]:(-2.9720578381089924,-0.40849994728873917) - 3 root[13]:(-2.7516339045163596,-1.1952032695387236) - 3 root[14]:(-2.3271338721132593,-1.8932638329781581) - 2.9999999999999996 root[15]:(-1.7300409663446015,-2.4509096790313261) - 3 root[16]:(-1.0046388365129593,-2.8267827663564611) - 3 root[17]:(-0.20472724009401405,-2.9930063075716173) - 3 root[18]:(0.61036803915789994,-2.9372522630469691) - 3 root[19]:(1.3801951131934547,-2.6636556552071267) - 3 root[20]:(2.0476594296559609,-2.1925078928343735) - 3 root[21]:(2.5632582136394655,-1.5587518501063007) - 3 root[22]:(2.8887518620433976,-0.80939031347107315) - 3 ___________________________________ Fin, hit <ENTER> to exit... The shows all of the roots. Yours only shows the primary root. Please correct me if I am totally wrong. ;^o |
Ralf Goertz <me@myprovider.invalid>: Apr 14 11:42AM +0200 Am Wed, 12 Apr 2017 14:57:52 +0200 > single call on platforms that allow that. This makes use of the power > of numerical algorithms to calculate both values simultaneously in > significantly less time than the two separate calls. Do you know where I can read more about that efficient algorithm. Sine being odd and cos even means that their Taylor serieses don't share any common powers of x. So I am a bit puzzled how that is accomplished. > be used on 32-bit x86 > - on x86_64 it requires more work, but still the core numerical > algorithm (e.g. a Newton expansion) can be easily adapted to this. Hm, I just experimented a bit. Calculating 10 Million sines and cosine separately takes as long as doing it in one go using sincos on my linux x86_64 architecture. Is it because the glibc sincos function is bogus here? |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 13 11:40AM -0700 On 4/13/2017 11:38 AM, Chris M. Thomasson wrote: >> e^2iπ.(j/n) for j = 0 .. n-1. > Makes sense to me. Thank you. Will this have the precision that cos/sin > has? raising e to gain the base angle, is very fast, and I need to test it to see if I can store the same amount of data vs the slow trig version. If I cannot, then the precision loss of the fast method should be closely examined. > The higher the precision, the more data we can store in a complex > number. [...] |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 13 11:48AM -0700 On 4/13/2017 11:19 AM, David Brown wrote: >> :^) > There are, I think, two big issues here. First, you have started the > coding before really understanding the maths. I am not a mathematician David! Fwiw, I thank you for your comments. [...] |
David Brown <david.brown@hesbynett.no>: Apr 13 08:19PM +0200 On 11/04/17 01:09, Chris M. Thomasson wrote: > 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: <snip> > ratio? Any ideas? > Will post more context later on tonight or tommorw. > :^) There are, I think, two big issues here. First, you have started the coding before really understanding the maths. Second, you can an iterative algorithm in floating point arithmetic - the errors there will always build up. Finding the nth roots of a complex number z is easy in polar coordinates. Express z = r.e^it, where r = abs(z). Find the real nth root of r, call it q. All your complex roots of z will have this magnitude. Then consider the angle. Your original angle is t. Let s = t / n. This is the angle for your principle root, which is then q.e^is. All your other roots are this principle root multiplied by the n roots of unity, e^2iπ.(j/n) for j = 0 .. n-1. This means that you can easily calculate all the nth roots of your original number directly, rather than iteratively, and thus avoid any cumulative floating point rounding errors. |
bitrex <bitrex@de.lete.earthlink.net>: Apr 14 04:16PM -0400 On 04/14/2017 04:05 PM, bitrex wrote: >> - Alf (baffled, again :) ) > e^(i*x) = cos(x) + i*sin(x). > HTH ;) The proof is, roughly speaking, given certain assumptions two functions that are the homogeneous solution to the same linear ordinary differential equation and have the same Taylor series coefficients over some domain must be the same function. Here the domain is actually the entire set of complex numbers, z, of which the real numbers are a subset. |
bitrex <bitrex@de.lete.earthlink.net>: Apr 14 04:05PM -0400 On 04/11/2017 02:23 AM, Alf P. Steinbach wrote: > I've been thinking about this also in my younger days. > Cheers!, > - Alf (baffled, again :) ) e^(i*x) = cos(x) + i*sin(x). HTH ;) |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 13 11:38AM -0700 On 4/13/2017 11:19 AM, David Brown wrote: > is the angle for your principle root, which is then q.e^is. All your > other roots are this principle root multiplied by the n roots of unity, > e^2iπ.(j/n) for j = 0 .. n-1. Makes sense to me. Thank you. Will this have the precision that cos/sin has? The higher the precision, the more data we can store in a complex number. Also, for the ct_store function, link you said, I do not need to return all of the roots. Just the n'th root. So I do not need to return a vector of all the roots in the ct_store function. I need to make two functions. One that returns all the roots, and one that returns a single targeted root. Its easy, and should be done today. The parametric nature can be exploited in ct_store. However, I am not sure how to avoid returning all the roots in the ct_load function. Thanks again David. > This means that you can easily calculate all the nth roots of your > original number directly, rather than iteratively, and thus avoid any > cumulative floating point rounding errors. I can make two functions. One for targeting the n'th root, and one that returns all the roots. ct_store uses the targeted version, ct_load uses the other one to lookup the correct symbol in the roots. Any more very interesting thoughts? :^) |
Ralf Goertz <me@myprovider.invalid>: Apr 14 10:04AM +0200 Am Thu, 13 Apr 2017 10:28:02 -0700 > Nice. Well, I think that std::polar has the best chance of using > sincos(). Need to check the implementation. It doesn't use it here :-( template<typename _Tp> inline complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta) { __glibcxx_assert( __rho >= 0 ); return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } > g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/6/lto-wrapper Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada,go --enable-offload-targets=hsa --enable-checking=release --with-gxx-include-dir=/usr/include/c++/6 --enable-ssp --disable-libssp --disable-libvtv --disable-libcc1 --enable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-6 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux Thread model: posix gcc version 6.3.1 20170202 [gcc-6-branch revision 245119] (SUSE Linux) |
Christian Gollwitzer <auriocus@gmx.de>: Apr 14 02:26PM +0200 Am 14.04.17 um 11:42 schrieb Ralf Goertz: > Do you know where I can read more about that efficient algorithm. Sine > being odd and cos even means that their Taylor serieses don't share > any common powers of x. So I am a bit puzzled how that is accomplished. There are ways to do it together, e.g. if an algorithm is involved which is based upon rotation like CORDIC. Here is another paper: https://arxiv.org/abs/cs/0406049 > Hm, I just experimented a bit. Calculating 10 Million sines and cosine > separately takes as long as doing it in one go using sincos on my linux x86_64 > architecture. Is it because the glibc sincos function is bogus here? 1) sincos only exists in (deprecated) 8087 math, so the instruction is no longer used for SSE math 2) Have you run the sin and cos in spearate loops or in two consecutive lines? gcc may have optimized it to a single call to _sincos - check the disassembly to be sure Christian |
Ralf Goertz <me@myprovider.invalid>: Apr 14 03:39PM +0200 Am Fri, 14 Apr 2017 14:26:07 +0200 > There are ways to do it together, e.g. if an algorithm is involved > which is based upon rotation like CORDIC. Here is another paper: > https://arxiv.org/abs/cs/0406049 Thanks, I'll have a look. > 2) Have you run the sin and cos in spearate loops or in two > consecutive lines? gcc may have optimized it to a single call to > _sincos - check the disassembly to be sure diff'ing the two assembler files I get: < movl $_ZZ7mypolarIdESt7complexIT_ERKS1_S4_E1c, %esi < movl $_ZZ7mypolarIdESt7complexIT_ERKS1_S4_E1s, %edi 1084c1082,1091 < call sincos --- > call cos > movq %xmm0, %rax > movq %rax, _ZZ7mypolarIdESt7complexIT_ERKS1_S4_E1c(%rip) So I guess g++ is not that clever. The function (mypolar) I used was defined according to the std::polar function I posted elsewhere in this thread: template<typename T> inline complex<T> mypolar(const T& rho, const T& theta) { static T s,c; sincos(theta,&s,&c); //s=sin(theta); //c=cos(theta); return complex<T>(rho*c,rho*s); } The 10 million runs of the loop take about 350 ms. The loop does nothing but replacing the appropriate element of a vector<complex<double>> (vc) with the result of the mypolar call: for (auto &i:vc) { i=mypolar(1.0,i.real()); } I had placed [0, M_2_PI)-uniformly distributed angles into the real components of the elements of vc beforehand. |
David Brown <david.brown@hesbynett.no>: Apr 17 10:25PM +0200 On 13/04/17 20:38, Chris M. Thomasson wrote: >> e^2iπ.(j/n) for j = 0 .. n-1. > Makes sense to me. Thank you. Will this have the precision that cos/sin > has? Yes. > The higher the precision, the more data we can store in a complex > number. Storing data in a floating point or complex number is possible in theory with infinitely accurate real numbers - but totally and utterly useless in practice. So don't worry about such details - if you think this is fun to play with, then go ahead and play with it. Such experimentation is fun and educational. Just don't be surprised when your double precision numbers can't hold more than a couple of chars after manipulation. > Also, for the ct_store function, link you said, I do not need to > return all of the roots. Just the n'th root. Doing the calculations in polar coordinates is perfect for this. You can jump straight to the n'th root without going through any of the ones in between. |
David Brown <david.brown@hesbynett.no>: Apr 17 10:29PM +0200 On 13/04/17 20:48, Chris M. Thomasson wrote: >> There are, I think, two big issues here. First, you have started the >> coding before really understanding the maths. > I am not a mathematician David! Fwiw, I thank you for your comments. No problem. As with many of your experiments, I cannot be optimistic that you will get anything useful or practical in the end - but the maths and the coding on the journey there can be fun and educational. So enjoy the road, and don't feel disappointed about the destination. <https://en.wikipedia.org/wiki/Complex_number#Polar_form> |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 17 02:53PM -0700 On 4/17/2017 1:29 PM, David Brown wrote: >> I am not a mathematician David! Fwiw, I thank you for your comments. > No problem. As with many of your experiments, I cannot be optimistic > that you will get anything useful or practical in the end - Totally fair enough. For instance, the size of the "ciphertext" wrt storing the encoding of a plaintext in complex numbers is not all that practical. However, it just might being useful in the sense of providing security. Wrt somebody working in a niche field saying "I do not care about the large ciphertext..." > but the > maths and the coding on the journey there can be fun and educational. So > enjoy the road, Oh the journey is very enlightening indeed! Coding the math is just great and vise-versa. I have always thought is was neat when one of my teachers accepted my homework as a series of little programs in AppleSoft BASIC. Fwiw, this neat little site has an online emulator: http://www.calormen.com/jsbasic It brings back some memories. > and don't feel disappointed about the destination. Never. I need to hear from all the smart people out there. If you find something iffy, let me know! I try to not get mad about being wrong, and having to learn new things. Afaict, this is the essence of life! Learning is fun, and a computer is a fun tool to have. Thanks again David. > <https://en.wikipedia.org/wiki/Complex_number#Polar_form> Love the polar form. Can you think of a fast way to add two complex numbers together in polar form? I always have to convert them back to Cartesian to perform the addition. If this can be avoided, wrt gaining the roots (z-c)^(1/n) from z^n+c, well, that would be great. Converting back and forth between polar and Cartesian on every iteration is very slow. Any more clever thoughts? :^) |
Robert Wessel <robertwessel2@yahoo.com>: Apr 15 12:47AM -0500 On 14 Apr 2017 20:38:29 GMT, ram@zedat.fu-berlin.de (Stefan Ram) wrote: >sizeof instance.i > should be just 1, because one byte is enough to store > one out of 10 values. While only a rough outline, a template with conversion operators, like the following, should provide a start. This does require the actual storage type to be explicitly specified, I'm not sure how you'd generate that automatically from the range. #include <stdexcept> template<typename T, long MN, long MX> class rangetype { T v; void setv(long a) { if (a < MN || a > MX) throw std::out_of_range("blah"); v=a-MN; } public: rangetype& operator=(long a) {setv(a); return *this;} operator long() {return v+MN;} }; int main() { int a; char b; rangetype<char, 100, 200> q; rangetype<int, 100, 2000> r; q = 3; q = 3.14; a = q; b = q; r = q; } |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 14 11:57PM +0200 On 14-Apr-17 10:38 PM, Stefan Ram wrote: > sizeof instance.i > should be just 1, because one byte is enough to store > one out of 10 values. The problem is just all the boilerplate code to support arithmetic and comparisons. Boost has a little macro-based (I think it was) thing to generate that code. Cheers!, - Alf |
Robert Wessel <robertwessel2@yahoo.com>: Apr 17 02:08AM -0500 On Sat, 15 Apr 2017 20:03:45 +0200, Winfied Valentin > > ... >> operator long() {return v+MN;} >Why Du you substract MN? That's useless. The OP wanted to store the range [2000000000..2000000010] in a single byte. |
Robert Wessel <robertwessel2@yahoo.com>: Apr 17 02:06AM -0500 On Sun, 16 Apr 2017 13:36:02 -0700, Tim Rentsch >number of duplicate solutions (a factor of 8 factorial, IIANM). >One easy way around that problem is to put the k'th queen in >the k'th row, since any solution must have one queen in each row. A better approach is to simply keep track of free rows, columns and diagonals (both). One of the [rows,columns] gets handled by the obvious loop (you don't try placing two queens on one of those). For simplicity I'll assume columns. The others just need a bitmap for each row or diagonal. There are 8* rows, and 15* (#rows*2-1) diagonals in each of two directions. Assume the columns are numbered 0-7, right-to-left, the rows 0-7, top-to-bottom, and the diagonals (D1 and D2) are numbered 0-14, top-to-bottom (D1 represents to upper-left to lower-right diagonals, D2 the lower-left to upper-right). Assume you're working in column C, and are attempting to place in queen in row R. You can just check the row bitmap to check for a conflict on a row. You can trivially compute the two diagonals the prospective queen is on (D1=(7-C)+R and D2=C+R), and then just those two bits in each bitmap to check for conflicts on the diagonals. If you find a possible location, mark the appropriate row and (both) diagonal bits, and move on to the next column. As you backtrack, unmark the R/D1/D2 bits. Total storage is linear in the size of a side of the board. So you end up with something like: Column[0..7] =0 Rbitmap[0..7]=0 D1bitmap[0..14]=0 D2bitmap[0..14]=0 main() PlaceNextColumn(0) PlaceNextColumn(C) for(R=0..7) Column[C]=R Try(R,C) Try(R,C) D1=(7-C)+R D2=C+R if (Rbitmap[R]) return //conflict if (D1bitmap[D1]) return //conflict if (D2bitmap[D2]) return //conflict // (no conflict) Rbitmap[R]=1 D1bitmap[D1]=1 D2bitmap[D2]=1 if(C==7) OutputSolution() else PlaceNextColumn(C+1) Rbitmap[R]=0 D1bitmap[D1]=0 D2bitmap[D2]=0 OutputSolution() printf("\nSolution: ") for(C=0..7) printf("Queen in column %i, on row %i ", C, Column[C]) *Assuming a standard chessboard - the approach generalizes to other sizes, and rectangular boards |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 07 01:07PM >missing memory. But is this the most specific sentence >about the behavior of »push_back« (and similar functions) >in the case of lack of (dynamic) memory in the standard? Found this: 20.10.9 The default allocator [default.allocator] ... 20.10.9.1 allocator members [allocator.members] ... T* allocate(size_t n); ... 4 Throws: bad_alloc if the storage cannot be obtained. |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Apr 13 10:55PM +0200 On 13.04.17 18.24, Alf P. Steinbach wrote: > Why can't you just provide the definition in a header file? Of course, I can generate a matching header with hard coded constants. But C++ compilation time on a Pi 1 is pure pain. So I favor just to link the executable when the GPU code changes. Marcel |
Ian Collins <ian-news@hotmail.com>: Apr 14 10:14AM +1200 On 04/14/17 08:55 AM, Marcel Mueller wrote: > Of course, I can generate a matching header with hard coded constants. > But C++ compilation time on a Pi 1 is pure pain. So I favor just to link > the executable when the GPU code changes. Use a cross-compiler? -- Ian |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 07 01:01PM -0700 On 4/6/2017 12:47 PM, Bonita Montero wrote: >> I have tested them thoroughly and they are more stable and fast now. > Don't trust in someone who claims to know how to write synchronization > -facilities who doesn't even understand simple condidtion-variables. Totally Agreed 100% Bonita!!! |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 07 01:00PM -0700 On 4/6/2017 3:13 PM, fir wrote: > 1) you got much many cores there (even up to 10k parallel float channels there on the best cards) > 2) heavy computational task concentrates in hot loops (thousands of parralel 'fibers' of the same computations not few of very different) and gpu model is more suitable for this > if our idiot ramine will begin to write and optimise opencl kernels we could start talking GPU is really suited for so-called embarrassingly parallel computations. That's fine, and they really work well. Fwiw, check this out, (needs WebGL): http://funwithfractals.atspace.cc/ct_gfield_test/3d_user/ct_wormhole_exp.html http://funwithfractals.atspace.cc/ct_gfield_test/ct_3dgfield_anime_test/ http://webpages.charter.net/appcore/fractal/webglx/ct_complex_field.html (clicking on a part of the fractal will zoom in) Love the GPU! Just love it. :^D |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 14 10:45AM -0700 On 4/12/2017 9:51 PM, Chris M. Thomasson wrote: > "n-ary roots from complex numbers..." > https://groups.google.com/d/topic/comp.lang.c++/05XwgswUnDg/discussion > to actually store data. [...] > Btw, I am wondering if you can run it and perhaps post some of the > output? It would be interesting to compare the results I get on to other > systems. [...] > __________________________________________ [...] > __________________________________________ Fwiw, here are the outputs of the ct_store function I am getting from two different compilers, MSVC and GCC: MSVC 2015 ________________________________________ Storing Data... stored:z_origin:(-0.75,0.059999999999999998) stored[0]:(-0.89756758958883731,0.41826246336621364) stored[1]:(-0.8048304823068565,-0.59293470672819726) stored[2]:(0.86792869817386908,-0.49666532554878623) stored[3]:(-0.73820338609537295,-0.67457761324417354) stored[4]:(0.95549545746010056,-0.29500576779591425) store_avg_err:6.8460152306934853e-15 ________________________________________ GCC version 5.1.0 (tdm64-1) ________________________________________ Storing Data... stored:z_origin:(-0.75,0.059999999999999998) stored[0]:(-0.89756758958883731,0.41826246336621364) stored[1]:(-0.8048304823068565,-0.59293470672819726) stored[2]:(0.86792869817386908,-0.49666532554878623) stored[3]:(-0.73820338609537295,-0.67457761324417354) stored[4]:(0.95549545746010056,-0.29500576779591425) store_avg_err:6.8460152306934853e-15 ________________________________________ If you run this and get different numbers, I would be interested in looking at them. For instance, when this is executed online at: http://cpp.sh I get: ________________________________________ Storing Data... stored:z_origin:(-0.75,0.059999999999999998) stored[0]:(-0.89756758958883731,0.41826246336621364) stored[1]:(-0.8048304823068565,-0.59293470672819726) stored[2]:(0.86792869817386908,-0.49666532554878623) stored[3]:(-0.73820338609537295,-0.67457761324417354) stored[4]:(0.95549545746010056,-0.29500576779591425) store_avg_err:6.1392213260039921e-15 ________________________________________ The store_avg_err is different! |
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