complex numbers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Blair

    complex numbers

    could someone PLEASE tell me why this doesn't work...

    -----------------------------------------
    #include <complex>
    using namespace std;
    typedef complex<long double> cld;

    void main()
    {
    cld cmplx, temp;
    cmplx = cld(-1.0, 0.0);
    temp = pow(cmplx, 0.5);
    }
    --------------------------------------------
    the square root of -1 is j (or i) but why I debug this code temp is given as
    (1,0).

    or

    if I do this...
    void main()
    {
    cld cmplx, temp;
    cmplx = cld(-1.0, 0.0);
    temp = pow(cmplx, 0.5);
    }

    I get the same results. temp=(1, 0) when the real is 1 and the imaginary is
    0.

    So, what is wrong with the pow function? Why can't I use fractions as the
    exponent? (BTW, I need to find cube-roots. That's why I'm not using
    sqrt(...) )


    Thanks, Blair


  • Dan Cernat

    #2
    Re: complex numbers


    "Blair" <bfonville1@hot mail.com> wrote in message
    news:3ffcb5ce_2 @127.0.0.1...[color=blue]
    > could someone PLEASE tell me why this doesn't work...
    >
    > -----------------------------------------
    > #include <complex>
    > using namespace std;
    > typedef complex<long double> cld;
    >
    > void main()
    > {
    > cld cmplx, temp;
    > cmplx = cld(-1.0, 0.0);
    > temp = pow(cmplx, 0.5);
    > }
    > --------------------------------------------
    > the square root of -1 is j (or i) but why I debug this code temp is given[/color]
    as[color=blue]
    > (1,0).
    >
    > or
    >
    > if I do this...
    > void main()
    > {
    > cld cmplx, temp;
    > cmplx = cld(-1.0, 0.0);
    > temp = pow(cmplx, 0.5);
    > }
    >
    > I get the same results. temp=(1, 0) when the real is 1 and the imaginary[/color]
    is[color=blue]
    > 0.
    >
    > So, what is wrong with the pow function? Why can't I use fractions as the
    > exponent? (BTW, I need to find cube-roots. That's why I'm not using
    > sqrt(...) )
    >
    >
    > Thanks, Blair
    >
    >[/color]

    my first guess is that pow function (as is declared in <cmath>) gets the
    first argument converted to a double or float.

    dan


    Comment

    • Cy Edmunds

      #3
      Re: complex numbers

      "Blair" <bfonville1@hot mail.com> wrote in message
      news:3ffcb5ce_2 @127.0.0.1...[color=blue]
      > could someone PLEASE tell me why this doesn't work...
      >
      > -----------------------------------------
      > #include <complex>
      > using namespace std;
      > typedef complex<long double> cld;
      >
      > void main()
      > {
      > cld cmplx, temp;
      > cmplx = cld(-1.0, 0.0);
      > temp = pow(cmplx, 0.5);
      > }
      > --------------------------------------------
      > the square root of -1 is j (or i) but why I debug this code temp is given[/color]
      as[color=blue]
      > (1,0).
      >
      > or
      >
      > if I do this...
      > void main()
      > {
      > cld cmplx, temp;
      > cmplx = cld(-1.0, 0.0);
      > temp = pow(cmplx, 0.5);
      > }
      >
      > I get the same results. temp=(1, 0) when the real is 1 and the imaginary[/color]
      is[color=blue]
      > 0.
      >
      > So, what is wrong with the pow function? Why can't I use fractions as the
      > exponent? (BTW, I need to find cube-roots. That's why I'm not using
      > sqrt(...) )
      >
      >
      > Thanks, Blair
      >
      >[/color]

      Try

      temp = pow(cmplx, 0.5L);

      --
      Cy



      Comment

      • Victor Bazarov

        #4
        Re: complex numbers

        "Dan Cernat" <cernat@dan.com > wrote...[color=blue]
        >
        > "Blair" <bfonville1@hot mail.com> wrote in message
        > news:3ffcb5ce_2 @127.0.0.1...[color=green]
        > > could someone PLEASE tell me why this doesn't work...
        > >
        > > -----------------------------------------
        > > #include <complex>
        > > using namespace std;
        > > typedef complex<long double> cld;
        > >
        > > void main()
        > > {
        > > cld cmplx, temp;
        > > cmplx = cld(-1.0, 0.0);
        > > temp = pow(cmplx, 0.5);
        > > }
        > > --------------------------------------------
        > > the square root of -1 is j (or i) but why I debug this code temp is[/color][/color]
        given[color=blue]
        > as[color=green]
        > > (1,0).
        > >
        > > or
        > >
        > > if I do this...
        > > void main()
        > > {
        > > cld cmplx, temp;
        > > cmplx = cld(-1.0, 0.0);
        > > temp = pow(cmplx, 0.5);
        > > }
        > >
        > > I get the same results. temp=(1, 0) when the real is 1 and the imaginary[/color]
        > is[color=green]
        > > 0.
        > >
        > > So, what is wrong with the pow function? Why can't I use fractions as[/color][/color]
        the[color=blue][color=green]
        > > exponent? (BTW, I need to find cube-roots. That's why I'm not using
        > > sqrt(...) )
        > >
        > >
        > > Thanks, Blair
        > >
        > >[/color]
        >
        > my first guess is that pow function (as is declared in <cmath>) gets the
        > first argument converted to a double or float.[/color]

        <cmath> is not included and <complex> declares its own 'std::pow' (and
        actually the whole four of them).

        Got a second guess? :-)

        My first guess is that 'void main' causes it.

        Just kidding. Actually, as I found by trying, changing it to

        temp = pow(cmplx, cld(0.5, 0));

        gives the right result. Why it happens, I can't say, it's too late
        here for me to strain my brain :-[

        Victor


        Comment

        • CrayzeeWulf

          #5
          Re: complex numbers

          Blair wrote:
          [color=blue]
          > could someone PLEASE tell me why this doesn't work...
          >
          > -----------------------------------------
          > #include <complex>
          > using namespace std;
          > typedef complex<long double> cld;
          >
          > void main()
          > {
          > cld cmplx, temp;
          > cmplx = cld(-1.0, 0.0);
          > temp = pow(cmplx, 0.5);
          > }
          > --------------------------------------------
          > the square root of -1 is j (or i) but why I debug this code temp is given
          > as (1,0).
          >[/color]
          Hi Blair,

          There are four different versions of std::pow for complex<T> numbers:

          1. template<class T>
          complex<T> pow( const complex<T>& x, int y) ;

          2. template<class T>
          complex<T> pow( const complex<T>& x, const complex<T>& y) ;

          3. template<class T>
          complex<T> pow( const complex<T>& x, const T& y) ;

          4. template<class T>
          complext<T> pow( const T& x, const complex<T>& y ) ;

          In your case "T" is "long double". Hence, the call "pow(cmplx, 0.5)" does
          not directly match any of the above without requiring some implicit
          conversion. Overload resolution rules end up matching the call to prototype
          #1 in the above list when you really want to use #3. In order to match #3,
          you have to help the compiler a little bit by telling it that "0.5" in your
          function call is indeed a "long double":

          temp = pow( cmplx, 0.5L ) ;

          Another option is to use prototype #2 by converting "0.5" into a
          complex<long double>:

          temp = pow( cmplx, cld(0.5, 0.0) ) ;

          [color=blue]
          > if I do this...
          > void main()
          > {
          > cld cmplx, temp;
          > cmplx = cld(-1.0, 0.0);
          > temp = pow(cmplx, 0.5);
          > }
          >[/color]

          I do not see the difference between this and the version above.

          Later,
          --
          CrayzeeWulf

          Comment

          • Blair

            #6
            Re: complex numbers

            Cy and Victor,
            Thanks for the replies. They both worked for a real result case - ie. when
            cmplx=cld(4,0) then temp becomes 2. But neither answer works for imaginary
            results.

            PS. I made a mistake in my original post :) ... I wrote
            --------------------------------
            ....or

            if I do this...
            void main()
            {
            cld cmplx, temp;
            cmplx = cld(-1.0, 0.0);
            temp = pow(cmplx, 0.5);
            }
            -----------------------------------
            but that code is exactly the same as the first snippet of code that posted!
            I mean to say this...
            --------------------------------
            or

            if I do this...
            void main()
            {
            cld cmplx, temp;
            cmplx = cld(4.0, 0.0);
            temp = pow(cmplx, 0.5);
            }
            -----------------------------------
            to make cmplx = 4.0 + 0j
            then temp should = 2.0, but I was getting temp=1+0j. Now, both of your
            answers correct the case when sqrt(cmplx) is a real number. But it still
            fails when cmplx = -1. (which, of course, should make temp=0+j)

            Thanks,
            blair


            "Blair" <bfonville1@hot mail.com> wrote in message
            news:3ffcb5ce_2 @127.0.0.1...[color=blue]
            > could someone PLEASE tell me why this doesn't work...
            >
            > -----------------------------------------
            > #include <complex>
            > using namespace std;
            > typedef complex<long double> cld;
            >
            > void main()
            > {
            > cld cmplx, temp;
            > cmplx = cld(-1.0, 0.0);
            > temp = pow(cmplx, 0.5);
            > }
            > --------------------------------------------
            > the square root of -1 is j (or i) but why I debug this code temp is given[/color]
            as[color=blue]
            > (1,0).
            >
            > or
            >
            > if I do this...
            > void main()
            > {
            > cld cmplx, temp;
            > cmplx = cld(-1.0, 0.0);
            > temp = pow(cmplx, 0.5);
            > }
            >
            > I get the same results. temp=(1, 0) when the real is 1 and the imaginary[/color]
            is[color=blue]
            > 0.
            >
            > So, what is wrong with the pow function? Why can't I use fractions as the
            > exponent? (BTW, I need to find cube-roots. That's why I'm not using
            > sqrt(...) )
            >
            >
            > Thanks, Blair
            >
            >[/color]


            Comment

            • Blair

              #7
              Re: complex numbers

              "CrayzeeWul f" <crayzeewulf@no spam.gnudom.org > wrote in message
              news:MG3Lb.5945 9$Vs3.39840@twi ster.socal.rr.c om...[color=blue]
              > Blair wrote:
              >[color=green]
              > > could someone PLEASE tell me why this doesn't work...
              > >
              > > -----------------------------------------
              > > #include <complex>
              > > using namespace std;
              > > typedef complex<long double> cld;
              > >
              > > void main()
              > > {
              > > cld cmplx, temp;
              > > cmplx = cld(-1.0, 0.0);
              > > temp = pow(cmplx, 0.5);
              > > }
              > > --------------------------------------------
              > > the square root of -1 is j (or i) but why I debug this code temp is[/color][/color]
              given[color=blue][color=green]
              > > as (1,0).
              > >[/color]
              > Hi Blair,
              >
              > There are four different versions of std::pow for complex<T> numbers:
              >
              > 1. template<class T>
              > complex<T> pow( const complex<T>& x, int y) ;
              >
              > 2. template<class T>
              > complex<T> pow( const complex<T>& x, const complex<T>& y) ;
              >
              > 3. template<class T>
              > complex<T> pow( const complex<T>& x, const T& y) ;
              >
              > 4. template<class T>
              > complext<T> pow( const T& x, const complex<T>& y ) ;
              >
              > In your case "T" is "long double". Hence, the call "pow(cmplx, 0.5)" does
              > not directly match any of the above without requiring some implicit
              > conversion. Overload resolution rules end up matching the call to[/color]
              prototype[color=blue]
              > #1 in the above list when you really want to use #3. In order to match #3,
              > you have to help the compiler a little bit by telling it that "0.5" in[/color]
              your[color=blue]
              > function call is indeed a "long double":
              >
              > temp = pow( cmplx, 0.5L ) ;
              >
              > Another option is to use prototype #2 by converting "0.5" into a
              > complex<long double>:
              >
              > temp = pow( cmplx, cld(0.5, 0.0) ) ;
              >[/color]

              Hi, and thanks for the response. But, ...darn it... both suggestions were
              already posted and neither of them seemed to work for me for some reason. In
              fact, if I instead do this...

              void main()
              {
              cld cmplx, temp;
              cmplx = cld(-1.0, 0.0);
              temp = pow(cmplx, 0.5);
              }

              I get the result: temp = (-1.#IND000000000 , 0.0000000000000 0). HOWEVER, if I
              make the imaginary part of cmplx NON-ZERO, as in...

              typedef complex<long double> cld;
              void main()
              {
              cld cmplx, temp;
              cmplx = cld(-1.0, 1.0);
              temp = pow(cmplx, 0.5L);
              }

              I do get the correct answer: temp = (0.455089860562 23, 1.0986841134678 )!!!

              Strange, huh?

              Blair
              [color=blue]
              >[color=green]
              > > if I do this...
              > > void main()
              > > {
              > > cld cmplx, temp;
              > > cmplx = cld(-1.0, 0.0);
              > > temp = pow(cmplx, 0.5);
              > > }
              > >[/color]
              >
              > I do not see the difference between this and the version above.[/color]

              Yeah, :) sorry about that. I noticed that too. I posted a correction.
              [color=blue]
              >
              > Later,
              > --
              > CrayzeeWulf[/color]


              Comment

              • Cy Edmunds

                #8
                Re: complex numbers

                [snip]

                Here is my test program.

                void yowza()
                {
                std::complex<lo ng double> cmplx(-1.0, 0.0), temp;
                temp = std::pow(cmplx, 0.5L);
                std::cout << temp << '\n';
                }

                Output is:

                (6.12303e-017,1)

                Compiler is VC++.Nuts

                --
                Cy



                Comment

                • Blair

                  #9
                  Re: complex numbers

                  Crap, I messed up again... see correction below...

                  "Blair" <bfonville1@hot mail.com> wrote in message
                  news:3ffcce01_2 @127.0.0.1...[color=blue]
                  > "CrayzeeWul f" <crayzeewulf@no spam.gnudom.org > wrote in message
                  > news:MG3Lb.5945 9$Vs3.39840@twi ster.socal.rr.c om...[color=green]
                  > > Blair wrote:
                  > >[color=darkred]
                  > > > could someone PLEASE tell me why this doesn't work...
                  > > >
                  > > > -----------------------------------------
                  > > > #include <complex>
                  > > > using namespace std;
                  > > > typedef complex<long double> cld;
                  > > >
                  > > > void main()
                  > > > {
                  > > > cld cmplx, temp;
                  > > > cmplx = cld(-1.0, 0.0);
                  > > > temp = pow(cmplx, 0.5);
                  > > > }
                  > > > --------------------------------------------
                  > > > the square root of -1 is j (or i) but why I debug this code temp is[/color][/color]
                  > given[color=green][color=darkred]
                  > > > as (1,0).
                  > > >[/color]
                  > > Hi Blair,
                  > >
                  > > There are four different versions of std::pow for complex<T> numbers:
                  > >
                  > > 1. template<class T>
                  > > complex<T> pow( const complex<T>& x, int y) ;
                  > >
                  > > 2. template<class T>
                  > > complex<T> pow( const complex<T>& x, const complex<T>& y) ;
                  > >
                  > > 3. template<class T>
                  > > complex<T> pow( const complex<T>& x, const T& y) ;
                  > >
                  > > 4. template<class T>
                  > > complext<T> pow( const T& x, const complex<T>& y ) ;
                  > >
                  > > In your case "T" is "long double". Hence, the call "pow(cmplx, 0.5)"[/color][/color]
                  does[color=blue][color=green]
                  > > not directly match any of the above without requiring some implicit
                  > > conversion. Overload resolution rules end up matching the call to[/color]
                  > prototype[color=green]
                  > > #1 in the above list when you really want to use #3. In order to match[/color][/color]
                  #3,[color=blue][color=green]
                  > > you have to help the compiler a little bit by telling it that "0.5" in[/color]
                  > your[color=green]
                  > > function call is indeed a "long double":
                  > >
                  > > temp = pow( cmplx, 0.5L ) ;
                  > >
                  > > Another option is to use prototype #2 by converting "0.5" into a
                  > > complex<long double>:
                  > >
                  > > temp = pow( cmplx, cld(0.5, 0.0) ) ;
                  > >[/color]
                  >
                  > Hi, and thanks for the response. But, ...darn it... both suggestions were
                  > already posted and neither of them seemed to work for me for some reason.[/color]
                  In[color=blue]
                  > fact, if I instead do this...
                  >[/color]
                  ------insert the following line-------
                  typedef complex<double> cld; //i.e. I changed my "long double" to "double"
                  ------------------------------------[color=blue]
                  > void main()
                  > {
                  > cld cmplx, temp;
                  > cmplx = cld(-1.0, 0.0);
                  > temp = pow(cmplx, 0.5);
                  > }
                  >
                  > I get the result: temp = (-1.#IND000000000 , 0.0000000000000 0). HOWEVER, if[/color]
                  I[color=blue]
                  > make the imaginary part of cmplx NON-ZERO, as in...
                  >
                  > typedef complex<long double> cld;
                  > void main()
                  > {
                  > cld cmplx, temp;
                  > cmplx = cld(-1.0, 1.0);
                  > temp = pow(cmplx, 0.5L);
                  > }
                  >
                  > I do get the correct answer: temp = (0.455089860562 23, 1.0986841134678 )!!!
                  >
                  > Strange, huh?
                  >
                  > Blair
                  >[color=green]
                  > >[color=darkred]
                  > > > if I do this...
                  > > > void main()
                  > > > {
                  > > > cld cmplx, temp;
                  > > > cmplx = cld(-1.0, 0.0);
                  > > > temp = pow(cmplx, 0.5);
                  > > > }
                  > > >[/color]
                  > >
                  > > I do not see the difference between this and the version above.[/color]
                  >
                  > Yeah, :) sorry about that. I noticed that too. I posted a correction.
                  >[color=green]
                  > >
                  > > Later,
                  > > --
                  > > CrayzeeWulf[/color]
                  >
                  >[/color]


                  Comment

                  • Blair

                    #10
                    Re: complex numbers

                    So, it is a compiler issue. I get:

                    Output: (-1.#IND,0)

                    from your code.

                    Thanks for the help. I'd better investigate the compiler, I guess.

                    Blair

                    "Cy Edmunds" <cedmunds@spaml ess.rochester.r r.com> wrote in message
                    news:X74Lb.4127 4$Dq1.23274@twi ster.nyroc.rr.c om...[color=blue]
                    > [snip]
                    >
                    > Here is my test program.
                    >
                    > void yowza()
                    > {
                    > std::complex<lo ng double> cmplx(-1.0, 0.0), temp;
                    > temp = std::pow(cmplx, 0.5L);
                    > std::cout << temp << '\n';
                    > }
                    >
                    > Output is:
                    >
                    > (6.12303e-017,1)
                    >
                    > Compiler is VC++.Nuts
                    >
                    > --
                    > Cy
                    > http://home.rochester.rr.com/cyhome/
                    >
                    >[/color]


                    Comment

                    • Blair

                      #11
                      Re: complex numbers

                      > Compiler is VC++.Nuts

                      BTW, what do you mean by .Nuts? I am using VC++ 6.0 and it's not working.
                      What is .Nuts? Is that what I am missing?

                      Blair

                      "Cy Edmunds" <cedmunds@spaml ess.rochester.r r.com> wrote in message
                      news:X74Lb.4127 4$Dq1.23274@twi ster.nyroc.rr.c om...[color=blue]
                      > [snip]
                      >
                      > Here is my test program.
                      >
                      > void yowza()
                      > {
                      > std::complex<lo ng double> cmplx(-1.0, 0.0), temp;
                      > temp = std::pow(cmplx, 0.5L);
                      > std::cout << temp << '\n';
                      > }
                      >
                      > Output is:
                      >
                      > (6.12303e-017,1)
                      >
                      > Compiler is VC++.Nuts
                      >
                      > --
                      > Cy
                      > http://home.rochester.rr.com/cyhome/
                      >
                      >[/color]


                      Comment

                      • Victor Bazarov

                        #12
                        Re: complex numbers

                        "Blair" <bfonville1@hot mail.com> wrote...[color=blue][color=green]
                        > > Compiler is VC++.Nuts[/color]
                        >
                        > BTW, what do you mean by .Nuts? I am using VC++ 6.0 and it's not working.
                        > What is .Nuts? Is that what I am missing?[/color]

                        It's .Net, my guess. You're missing quite some improvements
                        in the Standard compliance if you're still using 6.0...


                        Comment

                        • Jim West

                          #13
                          Re: complex numbers

                          In article <MG3Lb.59459$Vs 3.39840@twister .socal.rr.com>, CrayzeeWulf wrote:[color=blue]
                          > Hi Blair,
                          >
                          > There are four different versions of std::pow for complex<T> numbers:
                          >
                          > 1. template<class T>
                          > complex<T> pow( const complex<T>& x, int y) ;
                          >
                          > 2. template<class T>
                          > complex<T> pow( const complex<T>& x, const complex<T>& y) ;
                          >
                          > 3. template<class T>
                          > complex<T> pow( const complex<T>& x, const T& y) ;
                          >
                          > 4. template<class T>
                          > complext<T> pow( const T& x, const complex<T>& y ) ;
                          >
                          > In your case "T" is "long double". Hence, the call "pow(cmplx, 0.5)" does
                          > not directly match any of the above without requiring some implicit
                          > conversion. Overload resolution rules end up matching the call to prototype
                          > #1 in the above list when you really want to use #3. In order to match #3,[/color]

                          Wow! This is potentially a big problem for someone who uses complex
                          numbers extensively. I changed the program to

                          using namespace std;
                          typedef complex<float> cld;

                          int main() {
                          cld cmplx, temp;
                          cmplx = cld(-1.0f, 0.0f);
                          temp = pow(cmplx, 0.5);
                          }

                          and ended up getting the same behavior. Dropping the f or L does not
                          strike me as all that unlikely. The GNU compiler at least warned that
                          it was passing a double to an int argument, but the Intel compiler
                          said nothing. There may be a lot of programs out there unknowingly
                          getting the wrong answer! Could this be considered a flaw in the
                          standard library definition of the complex pow() function? It would
                          be better if they left version 1 (with int) out altogether. It might
                          take longer some times, but at least no one would get the wrong answer
                          for using the wrong precision in the second argument.

                          Seriously, this is very, very scary.

                          Comment

                          • CrayzeeWulf

                            #14
                            Re: complex numbers

                            Blair wrote:
                            [color=blue]
                            >
                            > Hi, and thanks for the response. But, ...darn it... both suggestions were
                            > already posted and neither of them seemed to work for me for some reason.
                            > In fact, if I instead do this...
                            >[/color]
                            [color=blue]
                            >
                            > I do get the correct answer: temp = (0.455089860562 23, 1.0986841134678 )!!!
                            >
                            > Strange, huh?
                            >[/color]
                            Hi Blair,

                            It looks like a compiler issue. The code craps out with Microsoft Visual C++
                            6.0 but works fine with Microsoft Visual Studio .Net 2003. It also works as
                            expected with g++ 3.2.3. VC6 has always been buggy when it comes to the STL
                            (in my limited experience). I have not been able to find a workaround for
                            VC6, unfortunately.

                            Later,
                            --
                            CrayzeeWulf

                            Comment

                            • CrayzeeWulf

                              #15
                              Re: complex numbers

                              Jim West wrote:

                              [color=blue]
                              >
                              > Wow! This is potentially a big problem for someone who uses complex
                              > numbers extensively. I changed the program to
                              >
                              > There may be a lot of programs out there unknowingly
                              > getting the wrong answer! Could this be considered a flaw in the
                              > standard library definition of the complex pow() function?
                              >
                              > Seriously, this is very, very scary.[/color]

                              Yeah. It does not make sense. However, I have been looking through the
                              standard and am not yet convinced if VC.Net and G++ are doing the right
                              thing. For example, N. M. Josuttis's book (The C++ Standard Library, 3rd
                              Printing) explicitly states that "pow(c, 1.7)" should result in c^(1.7). Of
                              course, VC6 is definitely wrong.

                              Furthermore, this works without any warning under G++ 3.2.3 as well as
                              VC.Net 2003:

                              #include <complex>
                              #include <iostream>
                              using namespace std;
                              typedef complex<float> cld;

                              int main()
                              {
                              float half = 0.5 ;
                              cld cmplx, temp ;
                              cmplx = cld(-1.0, 0.0) ;
                              temp = pow(cmplx, half) ;
                              cout << temp << endl ;
                              return EXIT_SUCCESS ;
                              }


                              --
                              CrayzeeWulf

                              Comment

                              Working...