This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4514. Missing absolute value of init in vector_two_norm and matrix_frob_norm

Section: 29.9.13.9 [linalg.algs.blas1.nrm2], 29.9.13.12 [linalg.algs.blas1.matfrobnorm] Status: New Submitter: Mark Hoemmen Opened: 2026-01-28 Last modified: 2026-01-31

Priority: Not Prioritized

View all other issues in [linalg.algs.blas1.nrm2].

View all issues with New status.

Discussion:

This pull request discussion points out two issues with the current wording of vector_two_norm:

  1. If Scalar is the complex number 1 + i, then the current wording would make vector_two_norm return sqrt(2i + nonnegative_real_number). This would have nonzero imaginary part.

  2. If Scalar is the real number -1.0, then the current wording would make vector_two_norm return sqrt(-1.0 + nonnegative_real_number). If nonnegative_real_number is less than 1, then the result would be imaginary.

The analogous issues would also apply to matrix_frob_norm.

It's acceptable for the return type Scalar to be complex. However, the point of letting init be nonzero is to support computing the 2-norm of a vector (or the Frobenius norm of a matrix) in multiple steps. The value of init should thus always represent a valid 2-norm (or Frobenius norm) result.

There are two ways to fix this:

  1. Impose a precondition on init, that it have nonnegative real part and zero imaginary part.

  2. Change the Returns element to take the absolute value of init. (The 29.9 [linalg] clause generally uses "absolute value" to mean the magnitude of a complex number, or the absolute value of a non-complex number.)

We offer (2) as the Proposed Fix, as it is consistent with the approach we took for fixing LWG 4136(i).

Proposed resolution:

This wording is relative to N5032.

  1. Modify 29.9.13.9 [linalg.algs.blas1.nrm2] as indicated:

    [Drafting note: As a drive-by fix the missing closing parenthesis of the decltype form has been added.]

    template<in-vector InVec, scalar Scalar>
      Scalar vector_two_norm(InVec v, Scalar init);
    template<class ExecutionPolicy, in-vector InVec, scalar Scalar>
      Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init);
    

    -1- [Note 1: These functions correspond to the BLAS function xNRM2[17]. — end note]

    -2- Mandates: InVec::value_type and Scalar are either a floating-point type, or a specialization of complex. Let a be abs-if-needed(declval<typename InVec::value_type>()) and let init_abs be abs-if-needed(init). Then, decltype(init_abs * init_abs + a * a) is convertible to Scalar.

    -3- Returns: The square root of the sum of the square of init and the squares of the absolute values of the elements of v.whose terms are the following:

    • (3.1) — the square of the absolute value of init, and

    • (3.2) — the squares of the absolute values of the elements of v.

    [Note 2: For init equal to zero, this is the Euclidean norm (also called 2-norm) of the vector v. — end note]

    -4- Remarks: If Scalar has higher precision than InVec::value_type, then intermediate terms in the sum use Scalar's precision or greater.

  2. Modify 29.9.13.12 [linalg.algs.blas1.matfrobnorm] as indicated:

    [Drafting note: As a drive-by fix one spurious InVec has been changed to InMat]

    template<in-matrix InMat, scalar Scalar>
      Scalar matrix_frob_norm(InMat A, Scalar init);
    template<class ExecutionPolicy, in-matrix InMat, scalar Scalar>
      Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
    

    -2- Mandates: InVecInMat::value_type and Scalar are either a floating-point type, or a specialization of complex. Let a be abs-if-needed(declval<typename InMat::value_type>()) and let init_abs be abs-if-needed(init). Then, decltype(init_abs * init_abs + a * a) is convertible to Scalar.

    -3- Returns: The square root of the sum of the squares of init and the absolute values of the elements of A.whose terms are the following:

    • (3.1) — the square of the absolute value of init, and

    • (3.2) — the squares of the absolute values of the elements of A.

    [Note 2: For init equal to zero, this is the Frobenius norm of the matrix A. — end note]

    -4- Remarks: If Scalar has higher precision than InMat::value_type, then intermediate terms in the sum use Scalar's precision or greater.