/**
 * Computes the Givens rotation coefficients (c, s) such that
 *
 *     [  c  s ] [ a ]   [ r ]
 *     [ -s  c ] [ b ] = [ 0 ]
 *
 * with c^2 + s^2 = 1 (so the matrix is a proper rotation).
 *
 * Signs are not pinned down — `r` may be either +sqrt(a^2 + b^2) or its
 * negation depending on the branch taken. Callers that care about the sign
 * of `r` must apply the rotation explicitly and read the rotated value.
 *
 * Writes c to out[0] and s to out[1]. Designed to take an out-param rather
 * than return an object: returning a freshly-allocated {c, s} pair would
 * cost an allocation per call, which matters when this is invoked inside a
 * tight QR-update loop.
 *
 * Source: Golub & Van Loan, Matrix Computations 2nd ed., p. 216.
 *
 * @param {number} a
 * @param {number} b
 * @param {Float64Array|number[]} out length >= 2; receives [c, s]
 */
export function givens_rotation_coefficients(a, b, out) {
    if (b === 0.0) {
        out[0] = 1.0;
        out[1] = 0.0;
    } else if (Math.abs(b) > Math.abs(a)) {
        const t = a / b;
        const s = 1 / Math.sqrt(1 + t * t);
        out[0] = s * t;
        out[1] = s;
    } else {
        const t = b / a;
        const c = 1 / Math.sqrt(1 + t * t);
        out[0] = c;
        out[1] = c * t;
    }
}
