From d933aaeae6af5de9ae122f8fee9869ba28ba78dd Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Mon, 17 Nov 2025 17:18:49 +0100 Subject: [PATCH] P3371R5 Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS Fixes NB US 168-277 (C++26 CD). --- source/numerics.tex | 924 +++++++++++++++++++++++++++++++------------- source/support.tex | 2 +- 2 files changed, 666 insertions(+), 260 deletions(-) diff --git a/source/numerics.tex b/source/numerics.tex index c4310e62fb..95dadc3f14 100644 --- a/source/numerics.tex +++ b/source/numerics.tex @@ -10990,7 +10990,7 @@ concept @\exposconcept{inout-matrix}@ = @\seebelow@; // \expos template - concept @\exposconcept{possibly-packed-inout-matrix}@ = @\seebelow@; // \expos + concept @\exposconcept{possibly-packed-out-matrix}@ = @\seebelow@; // \expos template concept @\exposconcept{in-object}@ = @\seebelow@; // \expos @@ -11001,6 +11001,9 @@ template concept @\exposconcept{inout-object}@ = @\seebelow@; // \expos + template + concept @\exposconcept{scalar}@ = @\seebelow@; // \expos + // \ref{linalg.scaled}, scaled in-place transformation // \ref{linalg.scaled.scaledaccessor}, class template \tcode{scaled_accessor} @@ -11081,9 +11084,9 @@ void swap_elements(ExecutionPolicy&& exec, InOutObj1 x, InOutObj2 y); // \ref{linalg.algs.blas1.scal}, multiply elements by scalar - template + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{inout-object}@ InOutObj> void scale(Scalar alpha, InOutObj x); - template + template void scale(ExecutionPolicy&& exec, Scalar alpha, InOutObj x); // \ref{linalg.algs.blas1.copy}, copy elements @@ -11099,18 +11102,18 @@ void add(ExecutionPolicy&& exec, InObj1 x, InObj2 y, OutObj z); // \ref{linalg.algs.blas1.dot}, dot product of two vectors - template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, class Scalar> + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{scalar}@ Scalar> Scalar dot(InVec1 v1, InVec2 v2, Scalar init); - template + template Scalar dot(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2, Scalar init); template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2> auto dot(InVec1 v1, InVec2 v2); template auto dot(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2); - template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, class Scalar> + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{scalar}@ Scalar> Scalar dotc(InVec1 v1, InVec2 v2, Scalar init); - template + template Scalar dotc(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2, Scalar init); template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2> auto dotc(InVec1 v1, InVec2 v2); @@ -11118,23 +11121,23 @@ auto dotc(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2); // \ref{linalg.algs.blas1.ssq}, scaled sum of squares of a vector's elements - template + template<@\exposconcept{scalar}@ Scalar> struct sum_of_squares_result { Scalar scaling_factor; Scalar scaled_sum_of_squares; }; - template<@\exposconcept{in-vector}@ InVec, class Scalar> + template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> sum_of_squares_result vector_sum_of_squares(InVec v, sum_of_squares_result init); - template + template sum_of_squares_result vector_sum_of_squares(ExecutionPolicy&& exec, InVec v, sum_of_squares_result init); // \ref{linalg.algs.blas1.nrm2}, Euclidean norm of a vector - template<@\exposconcept{in-vector}@ InVec, class Scalar> + template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> Scalar vector_two_norm(InVec v, Scalar init); - template + template Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init); template<@\exposconcept{in-vector}@ InVec> auto vector_two_norm(InVec v); @@ -11142,9 +11145,9 @@ auto vector_two_norm(ExecutionPolicy&& exec, InVec v); // \ref{linalg.algs.blas1.asum}, sum of absolute values of vector elements - template<@\exposconcept{in-vector}@ InVec, class Scalar> + template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> Scalar vector_abs_sum(InVec v, Scalar init); - template + template Scalar vector_abs_sum(ExecutionPolicy&& exec, InVec v, Scalar init); template<@\exposconcept{in-vector}@ InVec> auto vector_abs_sum(InVec v); @@ -11158,9 +11161,9 @@ typename InVec::extents_type vector_idx_abs_max(ExecutionPolicy&& exec, InVec v); // \ref{linalg.algs.blas1.matfrobnorm}, Frobenius norm of a matrix - template<@\exposconcept{in-matrix}@ InMat, class Scalar> + template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_frob_norm(InMat A, Scalar init); - template + template Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<@\exposconcept{in-matrix}@ InMat> auto matrix_frob_norm(InMat A); @@ -11168,9 +11171,9 @@ auto matrix_frob_norm(ExecutionPolicy&& exec, InMat A); // \ref{linalg.algs.blas1.matonenorm}, one norm of a matrix - template<@\exposconcept{in-matrix}@ InMat, class Scalar> + template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_one_norm(InMat A, Scalar init); - template + template Scalar matrix_one_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<@\exposconcept{in-matrix}@ InMat> auto matrix_one_norm(InMat A); @@ -11178,9 +11181,9 @@ auto matrix_one_norm(ExecutionPolicy&& exec, InMat A); // \ref{linalg.algs.blas1.matinfnorm}, infinity norm of a matrix - template<@\exposconcept{in-matrix}@ InMat, class Scalar> + template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_inf_norm(InMat A, Scalar init); - template + template Scalar matrix_inf_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<@\exposconcept{in-matrix}@ InMat> auto matrix_inf_norm(InMat A); @@ -11305,60 +11308,112 @@ InMat A, Triangle t, DiagonalStorage d, InOutVec b); // \ref{linalg.algs.blas2.rank1}, nonsymmetric rank-1 matrix update - template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{inout-matrix}@ InOutMat> - void matrix_rank_1_update(InVec1 x, InVec2 y, InOutMat A); - template - void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A); - template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{inout-matrix}@ InOutMat> - void matrix_rank_1_update_c(InVec1 x, InVec2 y, InOutMat A); - template - void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A); + // overwriting nonsymmetric rank-1 matrix update + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update(InVec1 x, InVec2 y, OutMat A); + template + void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, OutMat A); + + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update_c(InVec1 x, InVec2 y, OutMat A); + template + void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, OutMat A); + + // updating nonsymmetric rank-1 matrix update + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{in-matrix}@ InMat, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update(InVec1 x, InVec2 y, InMat E, OutMat A); + template + void matrix_rank_1_update(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, InMat E, OutMat A); + + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{in-matrix}@ InMat, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update_c(InVec1 x, InVec2 y, InMat E, OutMat A); + template + void matrix_rank_1_update_c(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, InMat E, OutMat A); // \ref{linalg.algs.blas2.symherrank1}, symmetric or Hermitian rank-1 matrix update - template - void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); + + // overwriting symmetric rank-1 matrix update + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, OutMat A, Triangle t); template + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, - Scalar alpha, InVec x, InOutMat A, Triangle t); - template<@\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); - template - void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t); + Scalar alpha, InVec x, OutMat A, Triangle t); - template - void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); + // overwriting Hermitian rank-1 matrix update + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, OutMat A, Triangle t); template + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, - Scalar alpha, InVec x, InOutMat A, Triangle t); - template<@\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); + Scalar alpha, InVec x, OutMat A, Triangle t); + + // updating symmetric rank-1 matrix update + template + void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); template - void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t); + class Scalar, @\exposconcept{in-vector InVec}@, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, + class Triangle> + void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, + Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); + + // updating Hermitian rank-1 matrix update + template + void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); + template + void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, + Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); // \ref{linalg.algs.blas2.rank2}, symmetric and Hermitian rank-2 matrix updates - // symmetric rank-2 matrix update + // overwriting symmetric rank-2 matrix update + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, OutMat A, Triangle t); + template + void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, OutMat A, Triangle t); + + // overwriting Hermitian rank-2 matrix update + template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, OutMat A, Triangle t); + template + void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, OutMat A, Triangle t); + + // updating symmetric rank-2 matrix update template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); template + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec, - InVec1 x, InVec2 y, InOutMat A, Triangle t); + InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); - // Hermitian rank-2 matrix update + // updating Hermitian rank-2 matrix update template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); template + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec, - InVec1 x, InVec2 y, InOutMat A, Triangle t); + InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); // \ref{linalg.algs.blas3}, BLAS 3 algorithms @@ -11499,57 +11554,103 @@ // \ref{linalg.algs.blas3.rankk}, rank-k update of a symmetric or Hermitian matrix - // rank-k symmetric matrix update - template - void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); - template + // overwriting rank-k symmetric matrix update + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, OutMat C, Triangle t); + template void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, - Scalar alpha, InMat A, InOutMat C, Triangle t); + Scalar alpha, InMat A, OutMat C, Triangle t); - template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); + // overwriting rank-k Hermitian matrix update + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, OutMat C, Triangle t); template - void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, - InMat A, InOutMat C, Triangle t); - - // rank-k Hermitian matrix update - template - void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); - template + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec, - Scalar alpha, InMat A, InOutMat C, Triangle t); + Scalar alpha, InMat A, OutMat C, Triangle t); + + // updating rank-k symmetric matrix update + template + void symmetric_matrix_rank_k_update( + Scalar alpha, + InMat1 A, InMat2 E, OutMat C, Triangle t); + template + void symmetric_matrix_rank_k_update( + ExecutionPolicy&& exec, Scalar alpha, + InMat1 A, InMat2 E, OutMat C, Triangle t); + + // updating rank-k Hermitian matrix update + template + void hermitian_matrix_rank_k_update( + Scalar alpha, + InMat1 A, InMat2 E, OutMat C, Triangle t); + template + void hermitian_matrix_rank_k_update( + ExecutionPolicy&& exec, Scalar alpha, + InMat1 A, InMat2 E, OutMat C, Triangle t); - template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); + // \ref{linalg.algs.blas3.rank2k}, rank-2k update of a symmetric or Hermitian matrix + + // overwriting rank-2k symmetric matrix update + template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, OutMat C, Triangle t); template - void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec, - InMat A, InOutMat C, Triangle t); + @\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec, + InMat1 A, InMat2 B, OutMat C, Triangle t); - // \ref{linalg.algs.blas3.rank2k}, rank-2k update of a symmetric or Hermitian matrix + // overwriting rank-2k Hermitian matrix update + template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, OutMat C, Triangle t); + template + void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec, + InMat1 A, InMat2 B, OutMat C, Triangle t); - // rank-2k symmetric matrix update + // updating symmetric rank-2k matrix update template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); + @\exposconcept{in-matrix}@ InMat3, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InMat3 E, OutMat C, Triangle t); template + @\exposconcept{in-matrix}@ InMat3, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec, - InMat1 A, InMat2 B, InOutMat C, Triangle t); + InMat1 A, InMat2 B, InMat3 E, OutMat C, Triangle t); - // rank-2k Hermitian matrix update + // updating Hermitian rank-2k matrix update template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); + @\exposconcept{in-matrix}@ InMat3, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InMat3 E, OutMat C, Triangle t); template + @\exposconcept{in-matrix}@ InMat3, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec, - InMat1 A, InMat2 B, InOutMat C, Triangle t); + InMat1 A, InMat2 B, InMat3 E, OutMat C, Triangle t); // \ref{linalg.algs.blas3.trsm}, solve multiple triangular linear systems @@ -11802,7 +11903,7 @@ \end{itemize} \pnum -Linear algebra value types shall model \libconcept{semiregular}. +Linear algebra value types shall model \exposconcept{scalar}. \pnum A value-initialized object of linear algebra value type @@ -12427,7 +12528,7 @@ constexpr bool @\exposid{is-layout-blas-packed}@> = true; template - concept @\defexposconcept{possibly-packed-inout-matrix}@ = + concept @\defexposconcept{possibly-packed-out-matrix}@ = @\exposid{is-mdspan}@ && T::rank() == 2 && is_assignable_v && (T::is_always_unique() || @\exposid{is-layout-blas-packed}@); @@ -12445,6 +12546,10 @@ concept @\defexposconcept{inout-object}@ = @\exposid{is-mdspan}@ && (T::rank() == 1 || T::rank() == 2) && is_assignable_v && T::is_always_unique(); + +template + concept @\defexposconcept{scalar}@ = + @\libconcept{semiregular}@ && (!@\exposconcept{is-mdspan}@) && (!is_execution_policy_v); \end{codeblock} \pnum @@ -12463,7 +12568,7 @@ \exposconcept{out-vector}, \exposconcept{out-matrix}, \exposconcept{out-object}, or -\exposconcept{possibly-packed-inout-matrix} +\exposconcept{possibly-packed-out-matrix} parameter of a function in \ref{linalg} shall not overlap any other \tcode{mdspan} parameter of the function. @@ -13491,9 +13596,9 @@ \indexlibraryglobal{scale}% \begin{itemdecl} -template +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{inout-object}@ InOutObj> void scale(Scalar alpha, InOutObj x); -template +template void scale(ExecutionPolicy&& exec, Scalar alpha, InOutObj x); \end{itemdecl} @@ -13606,9 +13711,9 @@ \indexlibraryglobal{dot}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, class Scalar> +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{scalar}@ Scalar> Scalar dot(InVec1 v1, InVec2 v2, Scalar init); -template +template Scalar dot(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2, Scalar init); \end{itemdecl} @@ -13673,9 +13778,9 @@ \indexlibraryglobal{dotc}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, class Scalar> +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{scalar}@ Scalar> Scalar dotc(InVec1 v1, InVec2 v2, Scalar init); -template +template Scalar dotc(ExecutionPolicy&& exec, InVec1 v1, InVec2 v2, Scalar init); \end{itemdecl} @@ -13740,9 +13845,9 @@ \indexlibraryglobal{vector_sum_of_squares}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, class Scalar> +template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> sum_of_squares_result vector_sum_of_squares(InVec v, sum_of_squares_result init); -template +template sum_of_squares_result vector_sum_of_squares(ExecutionPolicy&& exec, InVec v, sum_of_squares_result init); \end{itemdecl} @@ -13789,9 +13894,9 @@ \indexlibraryglobal{vector_two_norm}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, class Scalar> +template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> Scalar vector_two_norm(InVec v, Scalar init); -template +template Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init); \end{itemdecl} @@ -13863,9 +13968,9 @@ \indexlibraryglobal{vector_abs_sum}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, class Scalar> +template<@\exposconcept{in-vector}@ InVec, @\exposconcept{scalar}@ Scalar> Scalar vector_abs_sum(InVec v, Scalar init); -template +template Scalar vector_abs_sum(ExecutionPolicy&& exec, InVec v, Scalar init); \end{itemdecl} @@ -13999,9 +14104,9 @@ \indexlibraryglobal{matrix_frob_norm}% \begin{itemdecl} -template<@\exposconcept{in-matrix}@ InMat, class Scalar> +template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_frob_norm(InMat A, Scalar init); -template +template Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init); \end{itemdecl} @@ -14073,9 +14178,9 @@ \indexlibraryglobal{matrix_one_norm}% \begin{itemdecl} -template<@\exposconcept{in-matrix}@ InMat, class Scalar> +template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_one_norm(InMat A, Scalar init); -template +template Scalar matrix_one_norm(ExecutionPolicy&& exec, InMat A, Scalar init); \end{itemdecl} @@ -14147,9 +14252,9 @@ \indexlibraryglobal{matrix_inf_norm}% \begin{itemdecl} -template<@\exposconcept{in-matrix}@ InMat, class Scalar> +template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{scalar}@ Scalar> Scalar matrix_inf_norm(InMat A, Scalar init); -template +template Scalar matrix_inf_norm(ExecutionPolicy&& exec, InMat A, Scalar init); \end{itemdecl} @@ -14817,17 +14922,46 @@ \rSec3[linalg.algs.blas2.rank1]{Rank-1 (outer product) update of a matrix} +\pnum +The following elements apply to all functions in~\ref{linalg.algs.blas2.rank1}. + +\pnum +\mandates +\begin{itemize} +\item +\tcode{\exposconcept{possibly-multipliable}()} +is \tcode{true}, and +\item +\tcode{\exposconcept{possibly-addable}()} +is \tcode{true} for those overloads with an \tcode{E} parameter. +\end{itemize} + +\pnum +\expects +\begin{itemize} +\item +\tcode{\exposid{multipliable}(A, y, x)} +is \tcode{true}, and +\item +\tcode{\exposid{addable}(A, E, A)} +is \tcode{true} for those overloads with an \tcode{E} parameter. +\end{itemize} + +\pnum +\complexity +\bigoh{\tcode{x.extent(0)} \times \tcode{y.extent(0)}}. + \indexlibraryglobal{matrix_rank_1_update}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{inout-matrix}@ InOutMat> - void matrix_rank_1_update(InVec1 x, InVec2 y, InOutMat A); -template - void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A); +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update(InVec1 x, InVec2 y, OutMat A); +template + void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, OutMat A); \end{itemdecl} \begin{itemdescr} \pnum -These functions perform a nonsymmetric nonconjugated rank-1 update. +These functions perform an overwriting nonsymmetric nonconjugated rank-1 update. \begin{note} These functions correspond to the BLAS functions \tcode{xGER} (for real element types) and @@ -14835,35 +14969,48 @@ \end{note} \pnum -\mandates -\tcode{\exposid{possibly-multipliable}()} -is \tcode{true}. +\effects +Computes $A = x y^T$. +\end{itemdescr} +\indexlibraryglobal{matrix_rank_1_update}% +\begin{itemdecl} +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{in-matrix}@ InMat, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update(InVec1 x, InVec2 y, InMat E, OutMat A); +template + void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InMat E, OutMat A); +\end{itemdecl} + +\begin{itemdescr} \pnum -\expects -\tcode{\exposid{multipliable}(A, y, x)} is \tcode{true}. +These functions perform an updating nonsymmetric nonconjugated rank-1 update. +\begin{note} +These functions correspond to the BLAS functions +\tcode{xGER} (for real element types) and +\tcode{xGERU} (for complex element types)\supercite{blas2}. +\end{note} \pnum \effects -Computes a matrix $A'$ such that $A' = A + x y^T$, -and assigns each element of $A'$ to the corresponding element of $A$. +Computes $A = E + x y^T$. \pnum -\complexity -\bigoh{\tcode{x.extent(0)} \times \tcode{y.extent(0)}}. +\remarks +\tcode{A} may alias \tcode{E}. \end{itemdescr} -\indexlibraryglobal{matrix_rank_1_update}% +\indexlibraryglobal{matrix_rank_1_update_c}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{inout-matrix}@ InOutMat> - void matrix_rank_1_update_c(InVec1 x, InVec2 y, InOutMat A); -template - void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A); +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update_c(InVec1 x, InVec2 y, OutMat A); +template + void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, OutMat A); \end{itemdecl} \begin{itemdescr} \pnum -These functions perform a nonsymmetric conjugated rank-1 update. +These functions perform an overwriting nonsymmetric conjugated rank-1 update. \begin{note} These functions correspond to the BLAS functions \tcode{xGER} (for real element types) and @@ -14887,6 +15034,41 @@ \end{itemize} \end{itemdescr} +\indexlibraryglobal{matrix_rank_1_update_c}% +\begin{itemdecl} +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, @\exposconcept{in-matrix}@ InMat, @\exposconcept{out-matrix}@ OutMat> + void matrix_rank_1_update_c(InVec1 x, InVec2 y, InMat E, OutMat A); +template + void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InMat E, OutMat A); +\end{itemdecl} + +\begin{itemdescr} +\pnum +These functions perform an updating nonsymmetric conjugated rank-1 update. +\begin{note} +These functions correspond to the BLAS functions +\tcode{xGER} (for real element types) and +\tcode{xGERC} (for complex element types)\supercite{blas2}. +\end{note} + +\pnum +\effects +\begin{itemize} +\item +For the overloads without an \tcode{ExecutionPolicy} argument, +equivalent to: +\begin{codeblock} +matrix_rank_1_update(x, conjugated(y), A); +\end{codeblock} +\item +otherwise, equivalent to: +\begin{codeblock} +matrix_rank_1_update(std::forward(exec), x, conjugated(y), E, A); +\end{codeblock} +\end{itemize} +\end{itemdescr} + \rSec3[linalg.algs.blas2.symherrank1]{Symmetric or Hermitian Rank-1 (outer product) update of a matrix} \pnum @@ -14895,34 +15077,61 @@ \tcode{xSYR}, \tcode{xSPR}, \tcode{xHER}, and \tcode{xHPR}\supercite{blas2}. They have overloads taking a scaling factor \tcode{alpha}, because it would be impossible to express the update -$A = A - x x^T$ otherwise. +$A = A - x x^T$ in noncomplex arithmetic otherwise. \end{note} \pnum The following elements apply to all functions in \ref{linalg.algs.blas2.symherrank1}. +\pnum +For any function \tcode{F} in this subclause with +a parameter named \tcode{t}, +an \tcode{InMat} template parameter, and +a function parameter \tcode{InMat E}, +\tcode{t} applies to accesses done through the parameter \tcode{E}. +\tcode{F} only accesses the triangle of \tcode{E} specified by \tcode{t}. +For accesses of diagonal elements \tcode{E[i, i]}, +\tcode{F} only uses the value \tcode{\exposid{real-if-needed}(E[i, i])} +if the name of \tcode{F} starts with \tcode{hermitian}. +For accesses \tcode{E[i, j]} outside the triangle specified by \tcode{t}, +\tcode{F} only uses the value +\begin{itemize} +\item +\tcode{\exposid{conj-if-needed}(E[j, i])} +if the name of F starts with \tcode{hermitian}, or +\item +\tcode{E[j, i]} +if the name of \tcode{F} starts with \tcode{symmetric}. +\end{itemize} + \pnum \mandates \begin{itemize} \item -If \tcode{InOutMat} has \tcode{layout_blas_packed} layout, +If \tcode{OutMat} has \tcode{layout_blas_packed} layout, then the layout's \tcode{Triangle} template argument has the same type as the function's \tcode{Triangle} template argument; \item \tcode{\exposid{compatible-static-extents}(0, 1)} -is \tcode{true}; and +is \tcode{true}; \item \tcode{\exposid{compatible-static-extents}(0, 0)} -is \tcode{true}. +is \tcode{true}; and +\item +\tcode{\exposid{possibly-addable}()} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \expects \begin{itemize} \item -\tcode{A.extent(0)} equals \tcode{A.extent(1)}, and +\tcode{A.extent(0)} equals \tcode{A.extent(1)}, +\item +\tcode{A.extent(0)} equals \tcode{x.extent(0)}, and \item -\tcode{A.extent(0)} equals \tcode{x.extent(0)}. +\tcode{\exposid{addable}(A, E, A)} is \tcode{true} +for those overloads with an \tcode{E} parameter. \end{itemize} \pnum @@ -14931,94 +15140,103 @@ \indexlibraryglobal{symmetric_matrix_rank_1_update}% \begin{itemdecl} -template - void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, OutMat A, Triangle t); template + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, - Scalar alpha, InVec x, InOutMat A, Triangle t); + Scalar alpha, InVec x, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a symmetric rank-1 update of the symmetric matrix \tcode{A}, +an overwriting symmetric rank-1 update of the symmetric matrix \tcode{A}, taking into account the \tcode{Triangle} parameter that applies to \tcode{A}\iref{linalg.general}. \pnum \effects -Computes a matrix $A'$ such that -$A' = A + \alpha x x^T$, where the scalar $\alpha$ is \tcode{alpha}, -and assigns each element of $A'$ to the corresponding element of $A$. +Computes a matrix $A = \alpha x x^T$, +where the scalar $\alpha$ is \tcode{alpha}. \end{itemdescr} \indexlibraryglobal{symmetric_matrix_rank_1_update}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, + class Triangle> + void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); template - void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t); + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, + Scalar alpha, InVec x, InMat E, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a symmetric rank-1 update of the symmetric matrix \tcode{A}, +an updating symmetric rank-1 update of the symmetric matrix \tcode{A} +using the symmetric matrix \tcode{E}, taking into account the \tcode{Triangle} parameter -that applies to \tcode{A}\iref{linalg.general}. +that applies to \tcode{A} and \tcode{E}\iref{linalg.general}. \pnum \effects -Computes a matrix $A'$ such that $A' = A + x x^T$ -and assigns each element of $A'$ to the corresponding element of $A$. +Computes $A = E + \alpha x x^T$, +where the scalar $\alpha$ is \tcode{alpha}. + +\pnum +\remarks +\tcode{A} may alias \tcode{E}. \end{itemdescr} \indexlibraryglobal{hermitian_matrix_rank_1_update}% \begin{itemdecl} -template - void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, OutMat A, Triangle t); template + @\exposconcept{scalar}@ Scalar, @\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, - Scalar alpha, InVec x, InOutMat A, Triangle t); + Scalar alpha, InVec x, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a Hermitian rank-1 update of the Hermitian matrix \tcode{A}, +an overwriting Hermitian rank-1 update of the Hermitian matrix \tcode{A}, taking into account the \tcode{Triangle} parameter that applies to \tcode{A}\iref{linalg.general}. \pnum \effects -Computes $A'$ such that -$A' = A + \alpha x x^H$, where the scalar $\alpha$ is \tcode{alpha}, -and assigns each element of $A'$ to the corresponding element of $A$. +Computes $A = \alpha x x^H$, +where the scalar $\alpha$ is \tcode{\exposid{real-if-needed}(alpha)}. \end{itemdescr} \indexlibraryglobal{hermitian_matrix_rank_1_update}% \begin{itemdecl} -template<@\exposconcept{in-vector}@ InVec, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_1_update(InVec x, OutMat A, Triangle t); template - void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t); + @\exposconcept{scalar}@ Scalar, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a Hermitian rank-1 update of the Hermitian matrix \tcode{A}, +an updating Hermitian rank-1 update of the Hermitian matrix \tcode{E}, taking into account the \tcode{Triangle} parameter -that applies to \tcode{A}\iref{linalg.general}. +that applies to \tcode{A} and \tcode{E}\iref{linalg.general}. \pnum \effects -Computes a matrix $A'$ such that $A' = A + x x^H$ and -assigns each element of $A'$ to the corresponding element of $A$. +Computes a matrix $A = E + \alpha x x^H$, +where the scalar $\alpha$ is \tcode{\exposid{real-if-needed}(alpha)}. + +\pnum +\remarks +\tcode{A} may alias \tcode{E}. \end{itemdescr} \rSec3[linalg.algs.blas2.rank2]{Symmetric and Hermitian rank-2 matrix updates} @@ -15032,28 +15250,56 @@ \pnum The following elements apply to all functions in \ref{linalg.algs.blas2.rank2}. +\pnum +For any function \tcode{F} in this subclause with +a parameter named \tcode{t}, +an \tcode{InMat} template parameter, and +a function parameter \tcode{InMat E}, +\tcode{t} applies to accesses done through the parameter \tcode{E}. +\tcode{F} only accesses the triangle of \tcode{E} specified by \tcodee{t}. +For accesses of diagonal elements \tcode{E[i, i]}, +\tcode{F} only uses the value \tcode{\exposid{real-if-needed}(E[i, i])} +if the name of \tcode{F} starts with \tcode{hermitian}. +For accesses \tcode{E[i, j]} outside the triangle specified by \tcode{t}, +\tcode{F} only uses the value +\begin{itemize} +\item \tcode{\exposid{conj-if-needed}(E[j, i])} if the name of F starts with hermitian, or +\item \tcode{E[j, i]} if the name of F starts with symmetric. +\end{itemize} + \pnum \mandates \begin{itemize} \item -If \tcode{InOutMat} has \tcode{layout_blas_packed} layout, +If \tcode{OutMat} has \tcode{layout_blas_packed} layout, +then the layout's \tcode{Triangle} template argument has +the same type as the function's \tcode{Triangle} template argument; +\item +If the function has an \tcode{InMat} template parameter and +\tcode{InMat} has \tcode{layout_blas_packed} layout, then the layout's \tcode{Triangle} template argument has the same type as the function's \tcode{Triangle} template argument; \item \tcode{\exposid{compatible-static-extents}(0, 1)} -is \tcode{true}; and +is \tcode{true}; \item \tcode{\exposid{possibly-multipliable}()} -is \tcode{true}. +is \tcode{true}; and +\item +\tcode{\exposid{possibly-addable}()} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \expects \begin{itemize} \item -\tcode{A.extent(0)} equals \tcode{A.extent(1)}, and +\tcode{A.extent(0)} equals \tcode{A.extent(1)}, +\item +\tcode{\exposid{multipliable}(A, x, y)} is \tcode{true}, and \item -\tcode{\exposid{multipliable}(A, x, y)} is \tcode{true}. +\tcode{\exposid{addable}(A, E, A)} is \tcode{true} +for those overloads with an \tcode{E} parameter. \end{itemize} \pnum @@ -15063,49 +15309,107 @@ \indexlibraryglobal{symmetric_matrix_rank_2_update}% \begin{itemdecl} template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, OutMat A, Triangle t); template + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec, - InVec1 x, InVec2 y, InOutMat A, Triangle t); + InVec1 x, InVec2 y, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a symmetric rank-2 update of the symmetric matrix \tcode{A}, +an overwriting symmetric rank-2 update of the symmetric matrix \tcode{A}, taking into account the \tcode{Triangle} parameter that applies to \tcode{A}\iref{linalg.general}. \pnum \effects -Computes $A'$ such that $A' = A + x y^T + y x^T$ and -assigns each element of $A'$ to the corresponding element of $A$. +Computes $A = x y^T + y x^T$. +\end{itemdescr} + +\indexlibraryglobal{symmetric_matrix_rank_2_update}% +\begin{itemdecl} +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); +template + void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +These functions perform +an updating symmetric rank-2 update of the symmetric matrix \tcode{A} +using the symmetric matrix \tcode{E}, +taking into account the \tcode{Triangle} parameter +that applies to \tcode{A} and \tcode{E}\iref{linalg.general}. + +\pnum +\effects +Computes $A = E + x y^T + y x^T$. + +\pnum +\remarks +\tcode{A} may alias \tcode{E}. \end{itemdescr} \indexlibraryglobal{hermitian_matrix_rank_2_update}% \begin{itemdecl} template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, OutMat A, Triangle t); template + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec, - InVec1 x, InVec2 y, InOutMat A, Triangle t); + InVec1 x, InVec2 y, OutMat A, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum These functions perform -a Hermitian rank-2 update of the Hermitian matrix \tcode{A}, +an overwriting Hermitian rank-2 update of the Hermitian matrix \tcode{A}, taking into account the \tcode{Triangle} parameter that applies to \tcode{A}\iref{linalg.general}. \pnum \effects -Computes $A'$ such that $A' = A + x y^H + y x^H$ and -assigns each element of $A'$ to the corresponding element of $A$. +Computes $A = x y^H + y x^H$. +\end{itemdescr} + +\indexlibraryglobal{hermitian_matrix_rank_2_update}% +\begin{itemdecl} +template<@\exposconcept{in-vector}@ InVec1, @\exposconcept{in-vector}@ InVec2, + @\exposconcept{in-matrix}@ InMat, + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); +template + void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec, + InVec1 x, InVec2 y, InMat E, OutMat A, Triangle t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +These functions perform +an updating Hermitian rank-2 update of the Hermitian matrix \tcode{A} +using the Hermitian matrix \tcode{E}, +taking into account the \tcode{Triangle} parameter +that applies to \tcode{A} and \tcode{E}\iref{linalg.general}. + +\pnum +\effects +Computes $A = E + x y^H + y x^H$. + +\pnum +\remarks +\tcode{A} my alias \tcode{E}. \end{itemdescr} \rSec2[linalg.algs.blas3]{BLAS 3 algorithms} @@ -15554,107 +15858,120 @@ \pnum The following elements apply to all functions in \ref{linalg.algs.blas3.rankk}. +\pnum +For any function \tcode{F} in this subclause with +a parameter named \tcode{t}, +an \tcode{InMat2} template parameter, and +a function parameter \tcode{InMat2 E}, +\tcode{t} applies to accesses done through the parameter \tcode{E}. +\tcode{F} only accesses the triangle of \tcode{E} specified by \tcode{t}. +For accesses of diagonal elements \tcode{E[i, i]}, +\tcode{F} only uses the value \tcode{\exposid{real-if-needed}(E[i, i])} +if the name of \tcode{F} starts with \tcode{hermitian}. +For accesses \tcode{E[i, j]} outside the triangle specified by \tcode{t}, +\tcode{F} only uses the value +\begin{itemize} +\item +\tcode{\exposid{conj-if-needed}(E[j, i])} +if the name of \tcode{F} starts with \tcode{hermitian}, or +\item +\tcode{E[j, i]} +if the name of \tcode{F} starts with \tcode{symmetric}. +\end{itemize} + \pnum \mandates \begin{itemize} \item -If \tcode{InOutMat} has \tcode{layout_blas_packed} layout, +If \tcode{OutMat} has \tcode{layout_blas_packed} layout, then the layout's \tcode{Triangle} template argument has the same type as the function's \tcode{Triangle} template argument; \item -\tcode{\exposid{compatible-static-extents}(0, 1)} -is \tcode{true}; +If the function has an \tcode{InMat2} template parameter and +if \tcode{InMat2} has \tcode{layout_blas_packed} layout, +then the layout's \tcode{Triangle} template argument has +the same type as the function's \tcode{Triangle} template argument; \item -\tcode{\exposid{compatible-static-extents}(0, 1)} +\tcode{\exposid{possibly-multipliable}()} is \tcode{true}; and \item -\tcode{\exposid{compatible-static-extents}(0, 0)} -is \tcode{true}. +\tcode{\exposid{possibly-addable}()} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \expects \begin{itemize} \item -\tcode{A.extent(0)} equals \tcode{A.extent(1)}, -\item -\tcode{C.extent(0)} equals \tcode{C.extent(1)}, and +\tcode{\exposid{multipliable}(A, transposed(A), C)} +is \tcode{true}; +\begin{note} +This implies that \tcode{C} is square. +\end{note} \item -\tcode{A.extent(0)} equals \tcode{C.extent(0)}. +\tcode{\exposid{addable}(C, E, C)} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \complexity -\bigoh{\tcode{A.extent(0)} \times \tcode{A.extent(1)} \times \tcode{C.extent(0)}}. +\bigoh{\tcode{A.extent(0)} \times \tcode{A.extent(1)} \times \tcode{A.extent(0)}}. -\indexlibraryglobal{symmetric_matrix_rank_k_update}% -\begin{itemdecl} - template - void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); - template - void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, - Scalar alpha, InMat A, InOutMat C, Triangle t); -\end{itemdecl} - -\begin{itemdescr} \pnum -\effects -Computes a matrix $C'$ such that $C' = C + \alpha A A^T$, -where the scalar $\alpha$ is \tcode{alpha}, -and assigns each element of $C'$ to the corresponding element of $C$. -\end{itemdescr} +\remarks +\tcode{C} may alias \tcode{E} for those overloads with an \tcode{E} parameter. \indexlibraryglobal{symmetric_matrix_rank_k_update}% \begin{itemdecl} -template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); -template - void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, - InMat A, InOutMat C, Triangle t); + template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, OutMat C, Triangle t); + template + void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, + Scalar alpha, InMat A, OutMat C, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum \effects -Computes a matrix $C'$ such that $C' = C + A A^T$, and -assigns each element of $C'$ to the corresponding element of $C$. +Computes $C = \alpha A A^T$, +where the scalar $\alpha$ is \tcode{alpha}. \end{itemdescr} -\indexlibraryglobal{hermitian_matrix_rank_k_update}% +\indexlibraryglobal{symmetric_matrix_rank_k_update}% \begin{itemdecl} -template - void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); -template - void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec, - Scalar alpha, InMat A, InOutMat C, Triangle t); +template<@\exposconcept{scalar}@ Scalar, @\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, @\exposconcept{possibly-packed-out-matrix}@ OutMat, + class Triangle> +void symmetric_matrix_rank_k_update(Scalar alpha, InMat1 A, InMat2 E, OutMat C, Triangle t); +template +void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec, Scalar alpha, InMat1 A, InMat2 E, + OutMat C, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum \effects -Computes a matrix $C'$ such that $C' = C + \alpha A A^H$, -where the scalar $\alpha$ is \tcode{alpha}, -and assigns each element of $C'$ to the corresponding element of $C$. +Computes $C = E + \alpha A A^T$, +where the scalar $\alpha$ is \tcode{alpha}. \end{itemdescr} \indexlibraryglobal{hermitian_matrix_rank_k_update}% \begin{itemdecl} -template<@\exposconcept{in-matrix}@ InMat, @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); -template - void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec, - InMat A, InOutMat C, Triangle t); +template +void hermitian_matrix_rank_k_update(Scalar alpha, InMat1 A, InMat2 E, OutMat C, Triangle t); +template +void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec, Scalar alpha, InMat1 A, InMat2 E, + OutMat C, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum \effects -Computes a matrix $C'$ such that $C' = C + A A^H$, and -assigns each element of $C'$ to the corresponding element of $C$. +Computes $C = E + \alpha A A^H$, +where the scalar $\alpha$ is \tcode{\exposid{real-if-needed}(alpha)}. \end{itemdescr} \rSec3[linalg.algs.blas3.rank2k]{Rank-2k update of a symmetric or Hermitian matrix} @@ -15668,69 +15985,158 @@ \pnum The following elements apply to all functions in \ref{linalg.algs.blas3.rank2k}. +\pnum +For any function \tcode{F} in this subclause with +a parameter named \tcode{t}, +an \tcode{InMat3} template parameter, and +a function parameter \tcode{InMat3 E}, +\tcode{t} applies to accesses done through the parameter \tcode{E}. +\tcode{F} only accesses the triangle of \tcode{E} specified by \tcode{t}. +For accesses of diagonal elements \tcode{E[i, i]}, +\tcode{F} only uses the value \tcode{\exposid{real-if-needed}(E[i, i])} +if the name of \tcode{F} starts with \tcode{hermitian}. +For accesses \tcode{E[i, j]} outside the triangle specified by \tcode{t}, +\tcode{F} only uses the value +\begin{itemize} +\item +\tcode{\exposid{conj-if-needed}(E[j, i])} +if the name of \tcode{F} starts with \tcode{hermitian}, or +\item +\tcode{E[j, i]} +if the name of \tcode{F} starts with \tcode{symmetric}. +\end{itemize} + \pnum \mandates \begin{itemize} \item -If \tcode{InOutMat} has \tcode{layout_blas_packed} layout, +If \tcode{OutMat} has \tcode{layout_blas_packed} layout, then the layout's \tcode{Triangle} template argument has the same type as the function's \tcode{Triangle} template argument; \item -\tcode{\exposid{possibly-addable}()} +If the function has an \tcode{InMat3} template parameter and +if \tcode{InMat3} has \tcode{layout_blas_packed} layout, +then the layout's \tcode{Triangle} template argument has +the same type as the function's \tcode{Triangle} template argument; +\item +\tcode{\exposid{possibly-multipliable}()} +is \tcode{true}; +\item +\tcode{\exposid{possibly-multipliable}()} is \tcode{true}; and \item -\tcode{\exposid{compatible-static-extents}(0, 1)} -is \tcode{true}. +\tcode{\exposid{possibly-addable}()} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \expects \begin{itemize} \item -\tcode{\exposid{addable}(A, B, C)} is \tcode{true}, and +\tcode{\exposid{multipliable}(A, transposed(B), C)} +is \tcode{true}, \item -\tcode{A.extent(0)} equals \tcode{A.extent(1)}. +\tcode{multipliable(B, transposed(A), C)} +is \tcode{true}, and +\begin{note} +This and the previous imply that \tcode{C} is square. +\end{note} +\item +\tcode{\exposid{addable}(C, E, C)} +is \tcode{true} for those overloads with an \tcode{E} parameter. \end{itemize} \pnum \complexity -\bigoh{\tcode{A.extent(0)} \times \tcode{A.extent(1)} \times \tcode{C.extent(0)}}. +\bigoh{\tcode{A.extent(0)} \times \tcode{A.extent(1)} \times \tcode{B.extent(0)}}. + +\pnum +\remarks +\tcode{C} may alias \tcode{E} for those overloads with an \tcode{E} parameter. \indexlibraryglobal{symmetric_matrix_rank_2k_update}% \begin{itemdecl} template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, OutMat C, Triangle t); template + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec, - InMat1 A, InMat2 B, InOutMat C, Triangle t); + InMat1 A, InMat2 B, OutMat C, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum \effects -Computes a matrix $C'$ such that $C' = C + A B^T + B A^T$, -and assigns each element of $C'$ to the corresponding element of $C$. +Computes $C = A B^T + B A^T$. \end{itemdescr} \indexlibraryglobal{hermitian_matrix_rank_2k_update}% \begin{itemdecl} template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, - @\exposconcept{possibly-packed-inout-matrix}@ InOutMat, class Triangle> - void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> + void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, OutMat C, Triangle t); template + @\exposconcept{possibly-packed-out-matrix}@ OutMat, class Triangle> void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec, - InMat1 A, InMat2 B, InOutMat C, Triangle t); + InMat1 A, InMat2 B, OutMat C, Triangle t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Computes $C = A B^H + B A^H$. +\end{itemdescr} + +\indexlibraryglobal{symmetric_matrix_rank_2k_update}% +\begin{itemdecl} +template +void symmetric_matrix_rank_2k_update( + InMat1 A, + InMat2 B, + InMat3 E, + OutMat C, + Triangle t); +template +void symmetric_matrix_rank_2k_update( + ExecutionPolicy&& exec, + InMat1 A, + InMat2 B, + InMat3 E, + OutMat C, + Triangle t); +\end{itemdecl} + +\begin{itemdescr} +Computes $C = E + A B^T + B A^T$. +\end{itemdescr} + +\indexlibraryglobal{hermitian_matrix_rank_2k_update}% +\begin{itemdecl} +template<@\exposconcept{in-matrix}@ InMat1, @\exposconcept{in-matrix}@ InMat2, @\exposconcept{in-matrix}@ InMat3, @\exposconcept{possibly-packed-out-matrix}@ OutMat, + class Triangle> +void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InMat3 E, OutMat C, Triangle t); +template +void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec, InMat1 A, InMat2 B, InMat3 E, + OutMat C, Triangle t); \end{itemdecl} \begin{itemdescr} \pnum \effects -Computes a matrix $C'$ such that $C' = C + A B^H + B A^H$, -and assigns each element of $C'$ to the corresponding element of $C$. +Computes $C = E + A B^H + B A^H$. \end{itemdescr} \rSec3[linalg.algs.blas3.trsm]{Solve multiple triangular linear systems} diff --git a/source/support.tex b/source/support.tex index c6929d58ff..965c96b45a 100644 --- a/source/support.tex +++ b/source/support.tex @@ -748,7 +748,7 @@ #define @\defnlibxname{cpp_lib_jthread}@ 201911L // also in \libheader{stop_token}, \libheader{thread} #define @\defnlibxname{cpp_lib_latch}@ 201907L // also in \libheader{latch} #define @\defnlibxname{cpp_lib_launder}@ 201606L // freestanding, also in \libheader{new} -#define @\defnlibxname{cpp_lib_linalg}@ 202412L // also in \libheader{linalg} +#define @\defnlibxname{cpp_lib_linalg}@ 202511L // also in \libheader{linalg} #define @\defnlibxname{cpp_lib_list_remove_return_type}@ 201806L // also in \libheader{forward_list}, \libheader{list} #define @\defnlibxname{cpp_lib_logical_traits}@ 201510L // freestanding, also in \libheader{type_traits} #define @\defnlibxname{cpp_lib_make_from_tuple}@ 201606L // freestanding, also in \libheader{tuple}