Skip to content

avoid large intermediates in complex LARTG#1245

Merged
langou merged 4 commits into
Reference-LAPACK:masterfrom
nakatamaho:fix/lartg-stable-complex-s
Jul 15, 2026
Merged

avoid large intermediates in complex LARTG#1245
langou merged 4 commits into
Reference-LAPACK:masterfrom
nakatamaho:fix/lartg-stable-complex-s

Conversation

@nakatamaho

Copy link
Copy Markdown
Contributor

This PR rewrites the complex sine computation in CLARTG and ZLARTG
to avoid forming unnecessarily large intermediate values.

The existing implementation uses expressions of the following form:

  s = conjg(g) * ( f / sqrt(f2*h2) )

and similarly in the scaled branch:

  s = conjg(gs) * ( fs / sqrt(f2*h2) )

The existing scaling and branch conditions already keep f2*h2 in a
safe range. Therefore, this is not primarily an overflow or underflow
fix for the product f2*h2 itself.

However, even when sqrt(f2*h2) is safely representable, the division

  f / sqrt(f2*h2)

can still create a large intermediate value before it is multiplied by
conjg(g). This is mathematically equivalent to multiplying normalized
factors instead:

  ( f / sqrt(f2) ) * ( conjg(g) / sqrt(h2) )

This PR applies that rewrite in both the unscaled and scaled branches of
CLARTG and ZLARTG.

The goal is to keep intermediate values closer to unit scale while
preserving the same mathematical result.

Updated files:

  • SRC/clartg.f90
  • SRC/zlartg.f90

Replace the literal 1.0 / 1.0D0 in the computation of
MU = SQRT(ONE - NU**2) so the BBCSD routines consistently use
the named parameter constants already defined in each source.

Also reorder the parameter declarations to match the PARAMETER list
and remove trailing blank lines at end of file.

No functional change intended.
Rewrite the complex sine computation in CLARTG and ZLARTG to avoid forming a large intermediate value before the final multiplication by the conjugate of g.

The existing scaling keeps f2*h2 in a safe range, so this is not an overflow or underflow fix for f2*h2 itself. However, expressions such as

    conjg(g) * ( f / sqrt(f2*h2) )

can still form a large intermediate value in the division before it is multiplied by conjg(g). Use the mathematically equivalent form

    ( f / sqrt(f2) ) * ( conjg(g) / sqrt(h2) )

so that the factors stay closer to unit scale. Apply the same rewrite to the scaled branch using fs and gs.

@langou langou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good idea. Thanks.

@langou

langou commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Note that, in addition to the LARTG fix, there are some cosmetic changes to BBCSD too in this PR.
These changes are good too.

@langou langou merged commit 379b30d into Reference-LAPACK:master Jul 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants