Steven G. Kargl <
s...@removetroutmask.apl.washington.edu> wrote:
(snip, someone wrote)
>> I do not see any bug in my program. If you find one,
>> I would appreciate very much to know where.
> What is the kind type parameter for a value returned by CMPLX()?
> xpc2 = ( -b2 + sqrt(cmplx(discr2,0.0_rk2) ) )/(2*a2)
That is true, but it isn't the problem. Note that the single and
double complex give the same result, but significanlty different
from the single and double real result.
As to the OP, note that COMPLEX functions can easily give different
results from the corresponding REAL functions.
For one if, CABS(Z) = SQRT(REAL(Z)**2+AIMAG(Z)**2)
then it can easily overflow in cases where ABS(REAL(Z)) wouldn't.
(As a side note, I will complain about the use of REAL and CMPLX
functions for two different uses: One for converting to/from complex
values (the Fortran 77 sense), and for converting to the appropriate
Fortran data type and kind.)
According to the library with source nearby:
* COMPLEX SQUARE ROOT FUNCTION (SHORT)
* 1. THE PRINCIPLE BRANCH OF THE SQUARE ROOT IS TAKEN,
* I.E., THE REAL PART OF THE ANSWER IS POSITIVE.
* 2. WRITE SQRT(X+IY) = U+IV, WHERE U IS REAL, AND V IS
* IMAGINARY. IF X=Y=0, U=V=0.
* 3. IF X IS NON-NEGATIVE, U = SQRT((/X/+/X+IY/)/2) AND
* V = Y/(2*U).
* 4. IF X IS NEGATIVE, U = Y/(2*V) AND
* V = SIGN(Y)*SQRT((/X/+/X+IY/)/2).
Where the /X/ is the absolute value of X.
It then computes, conceptually, U=SQRT((X+SQRT(X**2+Y**2))/2).
Now, the actual program where I got that does a somewhat more
detailed calculation to avoid some intermediate underflow and
overflow, but you can see that, in the case of cancellation,
that the results could easily be different.
The actual calculation done in this case is:
A=MAX(X,Y), B=MIN(X,Y)
(If B is zero, or enough less than A, skip much of the computation.)
Otherwise, computes D=B/A, then F=SQRT(0.25+D*D/4) and /X+IY/=2*A*F.
Then more complication to avoid rounding problems computing
(/X/)/2+A*F, (/X/)+2*A*F, or (/X/)/4+A*F/2.
Note that the error source in computing CSQRT() are similar
to those in the quadratic formula, in the cases that can result
in cancellation from subtraction of nearly equal values.
In addition to all above, on systems with x87 floating point,
some intermediates might be computed in 80 bit registers,
while others are stored as 64 bits. That can easily result in
differences for the same expression in the same program.
-- glen