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.

4315. Insufficient specification of 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: 2025-08-14 Last modified: 2025-08-22

Priority: Not Prioritized

View all issues with New status.

Discussion:

The Returns clauses of vector_two_norm 29.9.13.9 [linalg.algs.blas1.nrm2] and matrix_frob_norm 29.9.13.12 [linalg.algs.blas1.matfrobnorm] say that the functions return the "square root" of the sum of squares of the initial value and the absolute values of the elements of the input mdspan. However, nowhere in 29.9 [linalg] explains how to compute a square root.

  1. The input mdspan's value_type and the initial value type are not constrained in a way that would ensure that calling std::sqrt on this expression would be well-formed.

  2. There is no provision to find sqrt via argument-dependent lookup, even though 29.9 [linalg] has provisions to find abs, conj, real, and imag via argument-dependent lookup. There is no "sqrt-if-needed" analog to abs-if-needed, conj-if-needed, real-if-needed, and imag-if-needed.

The easiest fix for both issues is just to Constrain both Scalar and the input mdspan's value_type to be floating-point numbers or specializations of std::complex for these two functions. This presumes that relaxing this Constraint and fixing the above two issues later would be a non-breaking change. If that is not the case, then I would suggest removing the two functions entirely.

Proposed resolution:

This wording is relative to N5014.

[Drafting note: As a drive-by fix the proposed wording adds a missing closing parentheses in 29.9.13.9 [linalg.algs.blas1.nrm2] p2.]

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

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

    -1- [Note 1: […] — end note]

    -?- Constraints: InVec::value_type and Scalar are either a floating-point type, or a specialization of complex.

    -2- Mandates: Let a be abs-if-needed(declval<typename InVec::value_type>()). Then, decltype(init + 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.

    [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 InVec::value_type, and Scalar are all floating-point types or specializations of complex, and if Scalar has higher precision than InVec::value_type, then intermediate terms in the sum use Scalar's precision or greater.

    [Note 3: An implementation of this function for floating-point types T can use the scaled_sum_of_squares result from vector_sum_of_squares(x, {.scaling_factor=1.0, .scaled_sum_of_squares=init}). — end note]

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

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

    -?- Constraints: InVec::value_type and Scalar are either a floating-point type, or a specialization of complex.

    -2- Mandates: Let a be abs-if-needed(declval<typename InMat::value_type>()). Then, decltype(init + a * a) is convertible to Scalar.

    -3- Returns: The square root of the sum of squares of init and 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 InMat::value_type and Scalar are all floating-point types or specializations of complex, and if Scalar has higher precision than InMat::value_type, then intermediate terms in the sum use Scalar's precision or greater.