This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Ready status.
vector_two_norm and matrix_frob_normSection: 29.9.13.9 [linalg.algs.blas1.nrm2], 29.9.13.12 [linalg.algs.blas1.matfrobnorm] Status: Ready Submitter: Mark Hoemmen Opened: 2025-08-14 Last modified: 2025-10-27
Priority: Not Prioritized
View all issues with Ready status.
Discussion:
Addresses US 171-274
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.
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.
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.
Previous resolution [SUPERSEDED]:
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.]
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_typeandScalarare either a floating-point type, or a specialization ofcomplex. -2- Mandates: Letabeabs-if-needed(declval<typename InVec::value_type>()). Then,decltype(init + a * a)is convertible toScalar. -3- Returns: The square root of the sum of the square ofinitand the squares of the absolute values of the elements ofv. [Note 2: Forinitequal to zero, this is the Euclidean norm (also called 2-norm) of the vectorv. — end note] -4- Remarks: IfInVec::value_type, andScalarare all floating-point types or specializations ofcomplex, and ifScalarhas higher precision thanInVec::value_type, then intermediate terms in the sum useScalar's precision or greater. [Note 3: An implementation of this function for floating-point typesTcan use thescaled_sum_of_squaresresultfrom vector_sum_of_squares(x, {.scaling_factor=1.0, .scaled_sum_of_squares=init}). — end note]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:
-2- Mandates: LetInVec::value_typeandScalarare either a floating-point type, or a specialization ofcomplex.abeabs-if-needed(declval<typename InMat::value_type>()). Then,decltype(init + a * a)is convertible toScalar. -3- Returns: The square root of the sum of squares ofinitand the absolute values of the elements ofA. [Note 2: Forinitequal to zero, this is the Frobenius norm of the matrixA. — end note] -4- Remarks: IfInMat::value_typeandScalarare all floating-point types or specializations ofcomplex, and ifScalarhas higher precision thanInMat::value_type, then intermediate terms in the sum useScalar's precision or greater.
[LWG telecon 2025-10-10; Update proposed resolution after review]
Use Mandates: for the new requirements, because we plan to change this later so want to make it ill-formed, not something that is statically checkable as part of the API.
[LWG telecon 2025-10-10; Status updated New → Ready]
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.]
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]
-2- Mandates:InVec::value_typeandScalarare either a floating-point type, or a specialization ofcomplex. Letabeabs-if-needed(declval<typename InVec::value_type>()). Then,decltype(init + a * a)is convertible toScalar. -3- Returns: The square root of the sum of the square ofinitand the squares of the absolute values of the elements ofv. [Note 2: Forinitequal to zero, this is the Euclidean norm (also called 2-norm) of the vectorv. — end note] -4- Remarks: IfInVec::value_type, andScalarare all floating-point types or specializations ofcomplex, and ifScalarhas higher precision thanInVec::value_type, then intermediate terms in the sum useScalar's precision or greater. [Note 3: An implementation of this function for floating-point typesTcan use thescaled_sum_of_squaresresultfrom vector_sum_of_squares(x, {.scaling_factor=1.0, .scaled_sum_of_squares=init}). — end note]
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);-2- Mandates:
-3- Returns: The square root of the sum of squares ofInVec::value_typeandScalarare either a floating-point type, or a specialization ofcomplex. Letabeabs-if-needed(declval<typename InMat::value_type>()). Then,decltype(init + a * a)is convertible toScalar.initand the absolute values of the elements ofA. [Note 2: Forinitequal to zero, this is the Frobenius norm of the matrixA. — end note] -4- Remarks: IfInMat::value_typeandScalarare all floating-point types or specializations ofcomplex, and ifScalarhas higher precision thanInMat::value_type, then intermediate terms in the sum useScalar's precision or greater.