enable complex @ int

View: New views
16 Messages — Rating Filter:   Alert me  

enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I use this patch to traits.hpp:

***************
*** 40,45 ****
--- 41,81 ----
 
  namespace boost { namespace numeric { namespace ublas {
 
+ typedef std::complex<double> complex_t;
+
+ inline complex_t operator+ (int in1, complex_t in2) {
+   return double(in1) + in2;
+ }
+
+ inline complex_t operator+ (complex_t in1, int in2) {
+   return in1 + double(in2);
+ }
+
+ inline complex_t operator- (int in1, complex_t in2) {
+   return double(in1) - in2;
+ }
+
+ inline complex_t operator- (complex_t in1, int in2) {
+   return in1 - double(in2);
+ }
+
+ inline complex_t operator* (int in1, complex_t in2) {
+   return double(in1) * in2;
+ }
+
+ inline complex_t operator* (complex_t in1, int in2) {
+   return in1 * double(in2);
+ }
+
+ inline complex_t operator/ (int in1, complex_t in2) {
+   return double(in1) / in2;
+ }
+
+ inline complex_t operator/ (complex_t in1, int in2) {
+   return in1 / double(in2);
+ }
+
+

_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Matwey V. Kornilov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Neal Becker wrote:

> I use this patch to traits.hpp:
>
> ***************
> *** 40,45 ****
> --- 41,81 ----
>  
>   namespace boost { namespace numeric { namespace ublas {
>  
> + typedef std::complex<double> complex_t;
> +
> + inline complex_t operator+ (int in1, complex_t in2) {
> +   return double(in1) + in2;
> + }

I think it would be better to write in such way:

template<R> std::complex<R> operator+ (int in1, const std::complex<R>& in2 ){
    return typename std::complex<R>::value_type(in1) + in2;
}



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Matwey V. Kornilov wrote:

> Neal Becker wrote:
>
>> I use this patch to traits.hpp:
>>
>> ***************
>> *** 40,45 ****
>> --- 41,81 ----
>>  
>>   namespace boost { namespace numeric { namespace ublas {
>>  
>> + typedef std::complex<double> complex_t;
>> +
>> + inline complex_t operator+ (int in1, complex_t in2) {
>> +   return double(in1) + in2;
>> + }
>
> I think it would be better to write in such way:
>
> template<R> std::complex<R> operator+ (int in1, const std::complex<R>& in2
> ){
>     return typename std::complex<R>::value_type(in1) + in2;
> }
>
>
That wouldn't conflict with stdlib?

_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Matwey V. Kornilov :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>> I think it would be better to write in such way:
>>
>> template<R> std::complex<R> operator+ (int in1, const std::complex<R>&
>> in2 ){
>>     return typename std::complex<R>::value_type(in1) + in2;
>> }
>>
>>
> That wouldn't conflict with stdlib?

It is just your version that has been extended for both complex<float> and
complex<double>.


_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Jesse Perla :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Just be careful... I am using using this with autodifferentiation  
which uses adl, it's own types, and specialized operations


-Jesse

On Sep 29, 2009, at 9:17 AM, "Matwey V. Kornilov" <matwey.kornilov@...
 > wrote:

>
>>> I think it would be better to write in such way:
>>>
>>> template<R> std::complex<R> operator+ (int in1, const  
>>> std::complex<R>&
>>> in2 ){
>>>    return typename std::complex<R>::value_type(in1) + in2;
>>> }
>>>
>>>
>> That wouldn't conflict with stdlib?
>
> It is just your version that has been extended for both  
> complex<float> and
> complex<double>.
>
>
> _______________________________________________
> ublas mailing list
> ublas@...
> http://lists.boost.org/mailman/listinfo.cgi/ublas
> Sent to: jesseperla@...
_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

namespace boost { namespace numeric { namespace ublas {

      template<typename R> std::complex<R> inline operator+ (int in1,
std::complex<R> const& in2 ) {
        return R (in1) + in2;
      }

      template<typename R> std::complex<R> inline operator+ (std::complex<R>
const& in1, int in2) {
        return in1 + R (in2);
      }

      template<typename R> std::complex<R> inline operator- (int in1,
std::complex<R> const& in2) {
        return R (in1) - in2;
      }

      template<typename R> std::complex<R> inline operator- (std::complex<R>
const& in1, int in2) {
        return in1 - R (in2);
      }

      template<typename R> std::complex<R> inline operator* (int in1,
std::complex<R> const& in2) {
        return R (in1) * in2;
      }

      template<typename R> std::complex<R> inline operator* (std::complex<R>
const& in1, int in2) {
        return in1 * R(in2);
      }

      template<typename R> std::complex<R> inline operator/ (int in1,
std::complex<R> const& in2) {
        return R(in1) / in2;
      }

      template<typename R> std::complex<R> inline operator/ (std::complex<R>
const& in1, int in2) {
        return in1 / R (in2);
      }



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There is one problem with that more generic version, if you use
std::complex<int> you will get a conflict:

/usr/local/src/boost.hg/boost/numeric/ublas/traits.hpp:96: error: ambiguous
overload for 'operator+' in 'std::complex<int>(((const int&)((const int*)
(&0))), ((const int&)((const int*)(&0)))) + 0'
/usr/local/src/boost.hg/boost/numeric/ublas/traits.hpp:48: note: candidates
are: std::complex<_Tp> boost::numeric::ublas::operator+(const
std::complex<_Tp>&, int) [with R = int]
/usr/lib/gcc/x86_64-redhat-
linux/4.4.1/../../../../include/c++/4.4.1/complex:328: note:                
std::complex<_Tp> std::operator+(const std::complex<_Tp>&, const _Tp&) [with
_Tp = int]

_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


namespace boost { namespace numeric { namespace ublas {

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type
inline operator+ (int in1, std::complex<R> const& in2 ) {
        return R (in1) + in2;
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type
inline operator+ (std::complex<R> const& in1, int in2) {
        return in1 + R (in2);
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  
inline operator- (int in1, std::complex<R> const& in2) {
        return R (in1) - in2;
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  
inline operator- (std::complex<R> const& in1, int in2) {
        return in1 - R (in2);
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  
inline operator* (int in1, std::complex<R> const& in2) {
        return R (in1) * in2;
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type
inline operator* (std::complex<R> const& in1, int in2) {
        return in1 * R(in2);
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  
inline operator/ (int in1, std::complex<R> const& in2) {
        return R(in1) / in2;
      }

      template<typename R>
      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  
inline operator/ (std::complex<R> const& in1, int in2) {
        return in1 / R (in2);
      }



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Gunter Winkler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Am Tuesday 29 September 2009 schrieb Neal Becker:
> There is one problem with that more generic version, if you use
> std::complex<int> you will get a conflict:

Maybe this can be solved using enable_if in the return type. But, is
std::complex<int> of any use? I'd put these overloads in a separate
header and leave the decision whether it is included to the developer.

What do you think?



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

signature.asc (204 bytes) Download Attachment

Re: enable complex @ int

by Alfredo Correa-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Sep 29, 2009 at 3:22 PM, Gunter Winkler <guwi17@...> wrote:
> Maybe this can be solved using enable_if in the return type. But, is
> std::complex<int> of any use?

I have no idea if this contributes at all, but there is something
called Gaussian Numbers
(http://en.wikipedia.org/wiki/Gaussian_integer). I am not even sure if
std::complex<int> (with the proper considerations with respect to
division) is the appropriate way to implement Gaussian Intergers, it
might.
The only point at which I saw a serius application for it was in a
topology class. (sorry, I don't remember the context).

Thanks,
Alfredo
_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Gunter Winkler wrote:

> Am Tuesday 29 September 2009 schrieb Neal Becker:
>> There is one problem with that more generic version, if you use
>> std::complex<int> you will get a conflict:
>
> Maybe this can be solved using enable_if in the return type. But, is
> std::complex<int> of any use? I'd put these overloads in a separate
> header and leave the decision whether it is included to the developer.
>
> What do you think?

I've used it for signal processing work.  It is convenient when moving from
a floating point algorithm to a 'fixed pt' (integer) version.

_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

How do you feel about adding my patch?

_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Gunter Winkler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Am Friday 02 October 2009 schrieb Neal Becker:
> How do you feel about adding my patch?

good idea: https://svn.boost.org/trac/boost/ticket/3514

We need a somehow general solution like the one suggested by Matwey. But
we should of course provide a robust solution, too.

Could you please make a short unit test (similar to the nice tests for
the new free functions)?

mfg
Gunter



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

signature.asc (204 bytes) Download Attachment

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Gunter Winkler wrote:

> Am Friday 02 October 2009 schrieb Neal Becker:
>> How do you feel about adding my patch?
>
> good idea: https://svn.boost.org/trac/boost/ticket/3514
>
> We need a somehow general solution like the one suggested by Matwey. But
> we should of course provide a robust solution, too.
>
> Could you please make a short unit test (similar to the nice tests for
> the new free functions)?
>
> mfg
> Gunter
How about:
      template<typename R, typename I>
      typename boost::enable_if<
        mpl::and_<
          boost::is_float<R>,
          boost::is_integral<I>
          >,
            std::complex<R> >::type inline operator+ (I in1, std::complex<R> const&
in2 ) {
        return R (in1) + in2;
      }


_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Attached is the complete patch.  Acceptable?
[traits.diff]

diff -r dcee1338df33 boost/numeric/ublas/traits.hpp
--- a/boost/numeric/ublas/traits.hpp Tue Sep 29 15:01:07 2009 -0400
+++ b/boost/numeric/ublas/traits.hpp Fri Oct 09 08:50:15 2009 -0400
@@ -26,6 +26,8 @@
 #include <boost/typeof/typeof.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_float.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/mpl/and.hpp>
 
 // anonymous namespace to avoid ADL issues
 namespace {
@@ -43,43 +45,83 @@
 
 namespace boost { namespace numeric { namespace ublas {
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type inline operator+ (int in1, std::complex<R> const& in2 ) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) {
  return R (in1) + in2;
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type inline operator+ (std::complex<R> const& in1, int in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) {
  return in1 + R (in2);
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  inline operator- (int in1, std::complex<R> const& in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) {
  return R (in1) - in2;
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  inline operator- (std::complex<R> const& in1, int in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) {
  return in1 - R (in2);
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  inline operator* (int in1, std::complex<R> const& in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) {
  return R (in1) * in2;
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type inline operator* (std::complex<R> const& in1, int in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) {
  return in1 * R(in2);
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  inline operator/ (int in1, std::complex<R> const& in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) {
  return R(in1) / in2;
       }
 
-      template<typename R>
-      typename boost::enable_if<boost::is_float<R>, std::complex<R> >::type  inline operator/ (std::complex<R> const& in1, int in2) {
+      template<typename R, typename I>
+      typename boost::enable_if<
+ mpl::and_<
+  boost::is_float<R>,
+  boost::is_integral<I>
+  >,
+ std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) {
  return in1 / R (in2);
       }
 



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: enable complex @ int

by Neal Becker :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Patch to add tests:

[test11.cpp.diff]

diff -r dcee1338df33 libs/numeric/ublas/test/test11.cpp
--- a/libs/numeric/ublas/test/test11.cpp Tue Sep 29 15:01:07 2009 -0400
+++ b/libs/numeric/ublas/test/test11.cpp Fri Oct 09 11:41:57 2009 -0400
@@ -92,7 +92,10 @@
         v2 = v1 * value_type (1.);
         std::cout << "v1 * 1. = " << v2 << std::endl;
         v2 = v1 * t;
-        std::cout << "v1 * N = " << v2 << std::endl;
+        std::cout << "v1 * value_type(N) = " << v2 << std::endl;
+ // test interop with integer
+ v2 = v1 * N;
+ std::cout << "v1 * N = " << v2 << std::endl;
 
         // Some assignments
         initialize_vector (v1);
@@ -108,6 +111,9 @@
         v1 *= value_type (1.);
         std::cout << "v1 *= 1. = " << v1 << std::endl;
         v1 *= t;
+        std::cout << "v1 *= value_type(N) = " << v1 << std::endl;
+ // test interop with integer
+ v1 *= N;
         std::cout << "v1 *= N = " << v1 << std::endl;
 
         // Unary vector operations resulting in a scalar



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...