Created on 2025-08-14.00:00:00 last changed 1 week ago
Proposed resolution:
This wording is relative to N5014.
[Drafting note: As a drive-by fix the proposed wording adds a missing closing parentheses in [linalg.algs.blas1.nrm2] p2.]
Modify [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]
Modify [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.
The Returns clauses of `vector_two_norm` [linalg.algs.blas1.nrm2] and `matrix_frob_norm` [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 [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 [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.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-08-22 16:04:01 | admin | set | messages: + msg14942 |
2025-08-14 00:00:00 | admin | create |