Help understanding this function

C

Chris Saunders

I'm attempting to understand this function. I'm attempting to adapt it to
another language - Eiffel. It seems to me that the function doesn't work
correctly. Here is the function:

template <typename T> inline Complex<T> Complex<T>::sqrt() const {
T srss = std::sqrt( r*r + i*i );

return Complex<T>(
std::sqrt( 2*(srss + r) ),
0.5*Complex<T>( i, -r ).csgn()*std::sqrt( 2*( srss - r ) )
);
}

First I'll explain the csgn() function. If the complex number is zero it
returns 0.0 otherwise it returns the sign of r which is the real part of the
complex number. csgn()'s return value is a double. Now if the the
imaginary part of the complex number is 0.0 and the real part is less than
zero it seems to me that the imaginary part of the result will be 0.0 which
must be incorrect because the square root of a negative real number will
have its imaginary part set to the square root of -r. Note that csgn(i, -r)
returns 0.0 in this case.

I'm going to include the csgn() function here on the small possibility that
I am not interpreting is correctly:

template <typename T> inline T Complex<T>::csgn() const {
return is_zero() ? 0 : Support<T>::sign( r );
}

Consider Support<T>::sign to be a regular sign function.
Thanks for any assistance.

Regards
Chris Saunders
 
V

Victor Bazarov

Chris said:
I'm attempting to understand this function. I'm attempting to adapt it
to another language - Eiffel. It seems to me that the function doesn't
work correctly. Here is the function:

template <typename T> inline Complex<T> Complex<T>::sqrt() const {
T srss = std::sqrt( r*r + i*i );

Considering that 'r' and 'i' are the real and imaginary parts of the
complex number, 'srss' is the hypotenuse, that's simple, right?
return Complex<T>(
std::sqrt( 2*(srss + r) ),
0.5*Complex<T>( i, -r ).csgn()*std::sqrt( 2*( srss - r ) )
);

According to my sources(*), given the hypotenuse calculated before, the
[complex] square root of a complex number is calculated according to
this formula

sqrt(x + iy) = sqrt(0.5)*[sqrt(hyp + x) + i*sgn(y)*sqrt(hyp - x)]

where 'sgn' is a simple sign function. It would seem that there is an
unnecessary creation of a temporary of type 'Complex<T>' and a factor
incorrect. I'd write the expression in the 'return' statement as

Complex said:
}

First I'll explain the csgn() function.

There seems to be no need in it.
> If the complex number is zero
it returns 0.0 otherwise it returns the sign of r which is the real part
of the complex number. csgn()'s return value is a double. Now if the
the imaginary part of the complex number is 0.0 and the real part is
less than zero it seems to me that the imaginary part of the result will
be 0.0 which must be incorrect because the square root of a negative
real number will have its imaginary part set to the square root of -r.
Note that csgn(i, -r) returns 0.0 in this case.

I'm going to include the csgn() function here on the small possibility
that I am not interpreting is correctly:

template <typename T> inline T Complex<T>::csgn() const {
return is_zero() ? 0 : Support<T>::sign( r );

There is no need to test 'is_zero'. Just return Support<T>::sign(r),
no? The point is that if the complex number is 0, its real part is
zero, and 'Support::sign' will return that zero, right? Or does
Support::sign consider the sign of 0 positive?

Again, you can safely ignore it, I think.
Consider Support<T>::sign to be a regular sign function.

How regular? Assuming that the sign of 0 is 0, so the function should be

template <typename T> inline Complex<T> Complex<T>::sqrt() const {
T srss = std::sqrt( r*r + i*i );

return Complex<T>(
std::sqrt( 0.5*(srss + r) ),
Support<T>::sign(i)*std::sqrt( 0.5*( srss - r ) )
);
}

Do test it please.

(*) http://mathworld.wolfram.com/SquareRoot.html

V
 
C

Chris Saunders

Thanks very much for the assistance Victor. It's late where I am and I need
some sleep. I will attempt to try your suggestion tomorrow and I will get
back to you.

Regards
Chris Saunders

Victor Bazarov said:
Chris said:
I'm attempting to understand this function. I'm attempting to adapt it
to another language - Eiffel. It seems to me that the function doesn't
work correctly. Here is the function:

template <typename T> inline Complex<T> Complex<T>::sqrt() const {
T srss = std::sqrt( r*r + i*i );

Considering that 'r' and 'i' are the real and imaginary parts of the
complex number, 'srss' is the hypotenuse, that's simple, right?
return Complex<T>(
std::sqrt( 2*(srss + r) ),
0.5*Complex<T>( i, -r ).csgn()*std::sqrt( 2*( srss - r ) )
);

According to my sources(*), given the hypotenuse calculated before, the
[complex] square root of a complex number is calculated according to this
formula

sqrt(x + iy) = sqrt(0.5)*[sqrt(hyp + x) + i*sgn(y)*sqrt(hyp - x)]

where 'sgn' is a simple sign function. It would seem that there is an
unnecessary creation of a temporary of type 'Complex<T>' and a factor
incorrect. I'd write the expression in the 'return' statement as

Complex said:
}

First I'll explain the csgn() function.

There seems to be no need in it.
If the complex number is zero
it returns 0.0 otherwise it returns the sign of r which is the real part
of the complex number. csgn()'s return value is a double. Now if the
the imaginary part of the complex number is 0.0 and the real part is less
than zero it seems to me that the imaginary part of the result will be
0.0 which must be incorrect because the square root of a negative real
number will have its imaginary part set to the square root of -r. Note
that csgn(i, -r) returns 0.0 in this case.

I'm going to include the csgn() function here on the small possibility
that I am not interpreting is correctly:

template <typename T> inline T Complex<T>::csgn() const {
return is_zero() ? 0 : Support<T>::sign( r );

There is no need to test 'is_zero'. Just return Support<T>::sign(r), no?
The point is that if the complex number is 0, its real part is zero, and
'Support::sign' will return that zero, right? Or does Support::sign
consider the sign of 0 positive?

Again, you can safely ignore it, I think.
Consider Support<T>::sign to be a regular sign function.

How regular? Assuming that the sign of 0 is 0, so the function should be

template <typename T> inline Complex<T> Complex<T>::sqrt() const {
T srss = std::sqrt( r*r + i*i );

return Complex<T>(
std::sqrt( 0.5*(srss + r) ),
Support<T>::sign(i)*std::sqrt( 0.5*( srss - r ) )
);
}

Do test it please.

(*) http://mathworld.wolfram.com/SquareRoot.html

V
 
V

Vladimir Jovic

Chris said:
Thanks very much for the assistance Victor. It's late where I am and I
need some sleep. I will attempt to try your suggestion tomorrow and I
will get back to you.

Regards
Chris Saunders

[snip,snip,snip]


I always find this funny :)
 
C

Chris Saunders

Well, thanks for the original help Victor. I personally hate bottom posted
messages. However, I do not consider it proper for me (or you) to control a
persons style preferences. Might be worth a little thought. Thanks again
and sorry for offending you. I will not pursue communicating with you
again. I can't let you know yet about how I did with the code you sent as I
am a diabetic and had medical problems today.

Regards
Chris Saunders

Vladimir Jovic said:
Chris said:
Thanks very much for the assistance Victor. It's late where I am and I
need some sleep. I will attempt to try your suggestion tomorrow and I
will get back to you.

Regards
Chris Saunders

[snip,snip,snip]


I always find this funny :)
 
V

Victor Bazarov

red said:
Chris said:
Well, thanks for the original help Victor. I personally hate bottom
posted messages. However, I do not consider it proper for me (or you)
to control a persons style preferences. Might be worth a little
thought.
[remainder redacted]

Top-posting in this forum is not a personal style preference. See
FAQ 5.4 http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4

For some reason (must be the diabetes acting up) the OP thought the
top-posting offends me. It doesn't. I just don't reply to top-posted
messages. That's *my personal preference*. And I let everybody know in
advance. What's wrong with that? Not imposing or anything...

Moving on...

V
 
C

Chris Saunders

"For some reason (must be the diabetes acting up) the OP thought the
top-posting offends me."

Well, in your response to my post, you found it necessary to insult me. I
was not being affected by diabetes at the time of the response (and am not
now). I have read
"http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4" and
disagree with it. I do resent what I quoted above but am still grateful for
the original response.

Regards
Chris Saunders

Victor Bazarov said:
red said:
Chris said:
Well, thanks for the original help Victor. I personally hate bottom
posted messages. However, I do not consider it proper for me (or you)
to control a persons style preferences. Might be worth a little
thought.
[remainder redacted]

Top-posting in this forum is not a personal style preference. See
FAQ 5.4 http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4

For some reason (must be the diabetes acting up) the OP thought the
top-posting offends me. It doesn't. I just don't reply to top-posted
messages. That's *my personal preference*. And I let everybody know in
advance. What's wrong with that? Not imposing or anything...

Moving on...

V
 
L

Lionel B

I have read "http://www.parashift.com/c++-faq-lite/how-to-
post.html#faq-5.4" and disagree with it.

In that case it seems you have the following choices:

1) Respect the netiquette of this group and learn to live with bottom-
posting

2) Continue to top-post here (but prepare to be ignored, or to attract
hostility from users of this group who prefer that the netiquette be
respected)

3) Don't post here anymore
 
R

REH

"For some reason (must be the diabetes acting up) the OP thought the
top-posting offends me."

Well, in your response to my post, you found it necessary to insult me.  I
was not being affected by diabetes at the time of the response (and am not
now).  I have read
"http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4" and
disagree with it.  I do resent what I quoted above but am still grateful for
the original response.

I think you are confusing his signature tag line with a message
directly targeting you. No where in his response did Victor insult
you.

REH
 
C

Chris Saunders

The line in quotes was taken from the body of Victor's message. I don't
think I am mistaken, but if I am, I owe and offer Victor an apology.

I personally would never withhold assistance to someone who posts in a style
that I dislike nor would I comment on my dislike of that persons style. I'm
just guessing, but I bet lots of people in this newsgroup feel the same. I
am wary of "thought police".

Regards
Chris Saunders
 
C

Chris Saunders

Sherm Pendley said:
Nor would I.

But I would, and do, choose to ignore those who think that the rules for
etiquette and manners are mere "style," and don't apply to them.

*plonk*

sherm--

I am bottom posting this message because, although I am not convinced, the
argument given is somewhat convincing to me. I do not know the meaning of
"*plonk*" but it seems to me that it has a negative connotation. I would
not have continued posting on this subject had I not received what I
considered to be an insulting comment regarding the fact that I suffer from
sugar diabetes. Your argument deserves further thought and I will give it
some. Please note that I have attempted to remain polite even I considered
myself to have been offended.

Regards
Chris Saunders
 
R

REH

The line in quotes was taken from the body of Victor's message.  I don't
think I am mistaken, but if I am, I owe and offer Victor an apology.

Look again. The line quoted was taken from his signature.

REH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top