- Range types - 2 Updates
- Range types - 1 Update
- n-ary roots from complex numbers... - 6 Updates
- storing/loading n-ary data via complex numbers... - 1 Update
ram@zedat.fu-berlin.de (Stefan Ram): Apr 14 08:38PM Some other languages (like Pascal or COBOL) provide types for ranges and enumerations, and I wonder to which extend one can create such types in C++. For example, struct example { range<2'000'000'000,2'000'000'010> i; }; . The implementation should emit an error message (a compile-time error message if possible) when one tries to instance.i = 0; , and, if possible, sizeof instance.i should be just 1, because one byte is enough to store one out of 10 values. |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 14 10:09PM Newsgroups: comp.lang.c,comp.lang.c++ > 55 > > (loop for i from 1 below 10 sum i) > 45 C++ (after appropriate definitions): int main() { auto sum { 0 }; for( auto const i : from{ 1, below( 3 )} )sum += i; ::std::cout << sum << '\n'; } . And, BTW, the variable declaration and the whole loop are being compiled here into just movl $3, %edx , that is, all the looping is done at compile time! However, my current, simplistic, definitions are not prepared for other increments than »+1«. (See full C++ code at the end of this post.) JavaScript is closer to Lisp, so you can get the value of the sum /as the value of the loop/ in JavaScript, just as in Common Lisp. function * from_below( from, top ) { let i = from; while ( i < top )yield i++; } console.log ( eval( "sum = 0; for( let i of from_below( 1, 3 ))sum += i;" )); (prints »3«). Full C++ source code: #include <initializer_list> #include <iostream> #include <ostream> struct intref { int i = 0; constexpr explicit intref( int const i ): i{ i } {} constexpr int operator * () const { return i; } constexpr intref & operator ++ () { ++i; return *this; } constexpr bool operator != ( intref const other ) const { return this->i != other.i; }}; struct from { intref const first; intref const top; constexpr from( int const first, int const top ): first{ first }, top{ top } {} constexpr intref const begin() const { return first; } constexpr intref const end() const { return top; }}; constexpr int below( int const i ) { return i; } constexpr int including( int const i ) { return i + 1; } int main() { auto sum { 0 }; for( auto const i : from{ 1, below( 3 )} )sum += i; ::std::cout << sum << '\n'; } . I am not an experienced writer of C++ classes, so I appreciate all comments on my C++ source code with a Followup-To header for the newsgroup comp.lang.c++. My most frequent error when summing up, is forgetting to initialize the sum variable. Using »auto« above means that I can't forget this! Of course, one could define the abstractions so as to force the user to use one of »below« or »including«. Newsgroups: comp.lang.c,comp.lang.c++ |
"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 |
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) |
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? |
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. |
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 ;) |
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. |
"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