Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Proposed algorithm
We an algorithm for the reciprocal scaling of a complex vector
X
by a complex numberA
. We use the notationAR
andAI
to denote the real and imaginary parts ofA
, respectively. The algorithm is as follows:AI
is zero, then call{CS,ZD}RSCL
(currently in LAPACK) usingAR
.AR
is zero, then ifAI
is in the safe range, callSCAL
with the numberCMPLX( ZERO, -ONE / AI )
. Otherwise, do the proper scaling by a power of two similarly toCSRSCL
.A
are nonzero, then we computeUR
andUI
such thatCMPLX( ONE / UR, - ONE / UI )
is the reciprocal ofA
, i.e.,UR
andUI
are always different from zero. NaNs only appear if either:AR
orAI
is a NaN.AR
andAI
are both infinite, in which case it makes sense to propagate a NaN.Now, we have three cases:
UR
andUI
are both in the safe range, then callSCAL
with the numberCMPLX( ONE / UR, - ONE / UI )
.UR
orUI
are smaller thanSFMIN
, it means that bothUR
andUI
are small numbers. In fact, we can prove that they should be both smaller thanSFMIN(1+1/EPSILON)
Therefore, it makes sense to scalex
byCMPLX( SFMIN / UR, - SFMIN / UI )
, and then scale the result byONE / SFMIN
. UseSCAL
to do both scalings.UR
orUI
are greater thanONE / SFMIN
, then we must check a few things:AR
orAI
is infinite, thenUR
andUI
are either both infinite or both NaNs. Therefore, we scale byCMPLX( ONE / UR, - ONE / UI )
usingSCAL
.UR
orUI
is infinite andAR
andAI
are finite, then the algorithm generated infinite numbers that can be avoided. In this case, recompute scaled versions ofUR
andUI
usingSFMIN
. Then, scalex
bySFMIN
, and then scale the result byCMPLX( ONE / UR, - ONE / UI )
. UseSCAL
to do both scalings.x
bySFMIN
, and then scale the result byCMPLX( ONE / (SFMIN*UR), - ONE / (SFMIN*UI) )
. UseSCAL
to do both scalings.Some comments about the algorithm:
AR
andAI
to the result. Moreover, it propagates NaNs ifAR
andAI
are both infinite. It does not generate NaNs in other cases.A
is zero.A
. This is done by treating cases whereUR
orUI
are infinite numbers.A
.