4961 lines
291 KiB
Markdown
4961 lines
291 KiB
Markdown
[linalg]
|
||
|
||
# 29 Numerics library [[numerics]](./#numerics)
|
||
|
||
## 29.9 Basic linear algebra algorithms [linalg]
|
||
|
||
### [29.9.1](#overview) Overview [[linalg.overview]](linalg.overview)
|
||
|
||
[1](#overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L10920)
|
||
|
||
Subclause [linalg] defines basic linear algebra algorithms[.](#overview-1.sentence-1)
|
||
|
||
The algorithms that access the elements of arrays
|
||
view those elements through mdspan ([[views.multidim]](views.multidim "23.7.3 Multidimensional access"))[.](#overview-1.sentence-2)
|
||
|
||
### [29.9.2](#syn) Header <linalg> synopsis [[linalg.syn]](linalg.syn)
|
||
|
||
[ð](#header:%3clinalg%3e)
|
||
|
||
namespace std::linalg {// [[linalg.tags.order]](#tags.order "29.9.5.1 Storage order tags"), storage order tagsstruct column_major_t; inline constexpr column_major_t column_major; struct row_major_t; inline constexpr row_major_t row_major; // [[linalg.tags.triangle]](#tags.triangle "29.9.5.2 Triangle tags"), triangle tagsstruct upper_triangle_t; inline constexpr upper_triangle_t upper_triangle; struct lower_triangle_t; inline constexpr lower_triangle_t lower_triangle; // [[linalg.tags.diagonal]](#tags.diagonal "29.9.5.3 Diagonal tags"), diagonal tagsstruct implicit_unit_diagonal_t; inline constexpr implicit_unit_diagonal_t implicit_unit_diagonal; struct explicit_diagonal_t; inline constexpr explicit_diagonal_t explicit_diagonal; // [[linalg.layout.packed]](#layout.packed "29.9.6 Layouts for packed matrix types"), class template layout_blas_packedtemplate<class Triangle, class StorageOrder>class layout_blas_packed; // [[linalg.helpers]](#helpers "29.9.7 Exposition-only helpers"), exposition-only helpers// [[linalg.helpers.concepts]](#helpers.concepts "29.9.7.5 Argument concepts"), linear algebra argument conceptstemplate<class T>constexpr bool *is-mdspan* = *see below*; // *exposition only*template<class T>concept [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*template<class T>concept [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") = *see below*; // *exposition only*// [[linalg.scaled]](#scaled "29.9.8 Scaled in-place transformation"), scaled in-place transformation// [[linalg.scaled.scaledaccessor]](#scaled.scaledaccessor "29.9.8.2 Class template scaled_accessor"), class template scaled_accessortemplate<class ScalingFactor, class NestedAccessor>class scaled_accessor; // [[linalg.scaled.scaled]](#scaled.scaled "29.9.8.3 Function template scaled"), function template scaledtemplate<class ScalingFactor, class ElementType, class Extents, class Layout, class Accessor>constexpr auto scaled(ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x); // [[linalg.conj]](#conj "29.9.9 Conjugated in-place transformation"), conjugated in-place transformation// [[linalg.conj.conjugatedaccessor]](#conj.conjugatedaccessor "29.9.9.2 Class template conjugated_accessor"), class template conjugated_accessortemplate<class NestedAccessor>class conjugated_accessor; // [[linalg.conj.conjugated]](#conj.conjugated "29.9.9.3 Function template conjugated"), function template conjugatedtemplate<class ElementType, class Extents, class Layout, class Accessor>constexpr auto conjugated(mdspan<ElementType, Extents, Layout, Accessor> a); // [[linalg.transp]](#transp "29.9.10 Transpose in-place transformation"), transpose in-place transformation// [[linalg.transp.layout.transpose]](#transp.layout.transpose "29.9.10.3 Class template layout_transpose"), class template layout_transposetemplate<class Layout>class layout_transpose; // [[linalg.transp.transposed]](#transp.transposed "29.9.10.4 Function template transposed"), function template transposedtemplate<class ElementType, class Extents, class Layout, class Accessor>constexpr auto transposed(mdspan<ElementType, Extents, Layout, Accessor> a); // [[linalg.conjtransposed]](#conjtransposed "29.9.11 Conjugate transpose in-place transform"), conjugated transpose in-place transformationtemplate<class ElementType, class Extents, class Layout, class Accessor>constexpr auto conjugate_transposed(mdspan<ElementType, Extents, Layout, Accessor> a); // [[linalg.algs.blas1]](#algs.blas1 "29.9.13 BLAS 1 algorithms"), BLAS 1 algorithms// [[linalg.algs.blas1.givens]](#algs.blas1.givens "29.9.13.2 Givens rotations"), Givens rotations// [[linalg.algs.blas1.givens.lartg]](#algs.blas1.givens.lartg "29.9.13.2.1 Compute Givens rotation"), compute Givens rotationtemplate<class Real>struct setup_givens_rotation_result { Real c;
|
||
Real s;
|
||
Real r; }; template<class Real>struct setup_givens_rotation_result<complex<Real>> { Real c;
|
||
complex<Real> s;
|
||
complex<Real> r; }; template<class Real> setup_givens_rotation_result<Real> setup_givens_rotation(Real a, Real b) noexcept; template<class Real> setup_givens_rotation_result<complex<Real>> setup_givens_rotation(complex<Real> a, complex<Real> b) noexcept; // [[linalg.algs.blas1.givens.rot]](#algs.blas1.givens.rot "29.9.13.2.2 Apply a computed Givens rotation to vectors"), apply computed Givens rotationtemplate<[*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, Real s); template<class ExecutionPolicy, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>void apply_givens_rotation(ExecutionPolicy&& exec,
|
||
InOutVec1 x, InOutVec2 y, Real c, Real s); template<[*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, complex<Real> s); template<class ExecutionPolicy, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>void apply_givens_rotation(ExecutionPolicy&& exec,
|
||
InOutVec1 x, InOutVec2 y, Real c, complex<Real> s); // [[linalg.algs.blas1.swap]](#algs.blas1.swap "29.9.13.3 Swap matrix or vector elements"), swap elementstemplate<[*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj1, [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj2>void swap_elements(InOutObj1 x, InOutObj2 y); template<class ExecutionPolicy, [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj1, [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj2>void swap_elements(ExecutionPolicy&& exec,
|
||
InOutObj1 x, InOutObj2 y); // [[linalg.algs.blas1.scal]](#algs.blas1.scal "29.9.13.4 Multiply the elements of an object in place by a scalar"), multiply elements by scalartemplate<class Scalar, [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj>void scale(Scalar alpha, InOutObj x); template<class ExecutionPolicy, class Scalar, [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj>void scale(ExecutionPolicy&& exec,
|
||
Scalar alpha, InOutObj x); // [[linalg.algs.blas1.copy]](#algs.blas1.copy "29.9.13.5 Copy elements of one matrix or vector into another"), copy elementstemplate<[*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj, [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>void copy(InObj x, OutObj y); template<class ExecutionPolicy, [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj, [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>void copy(ExecutionPolicy&& exec,
|
||
InObj x, OutObj y); // [[linalg.algs.blas1.add]](#algs.blas1.add "29.9.13.6 Add vectors or matrices elementwise"), add elementwisetemplate<[*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj1, [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj2, [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>void add(InObj1 x, InObj2 y, OutObj z); template<class ExecutionPolicy, [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj1, [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj2, [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>void add(ExecutionPolicy&& exec,
|
||
InObj1 x, InObj2 y, OutObj z); // [[linalg.algs.blas1.dot]](#algs.blas1.dot "29.9.13.7 Dot product of two vectors"), dot product of two vectorstemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar> Scalar dot(InVec1 v1, InVec2 v2, Scalar init); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar> Scalar dot(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2, Scalar init); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>auto dot(InVec1 v1, InVec2 v2); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>auto dot(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar> Scalar dotc(InVec1 v1, InVec2 v2, Scalar init); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar> Scalar dotc(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2, Scalar init); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>auto dotc(InVec1 v1, InVec2 v2); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>auto dotc(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2); // [[linalg.algs.blas1.ssq]](#algs.blas1.ssq "29.9.13.8 Scaled sum of squares of a vector"), scaled sum of squares of a vector's elementstemplate<class Scalar>struct sum_of_squares_result { Scalar scaling_factor;
|
||
Scalar scaled_sum_of_squares; }; template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> sum_of_squares_result<Scalar> vector_sum_of_squares(InVec v, sum_of_squares_result<Scalar> init); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> sum_of_squares_result<Scalar> vector_sum_of_squares(ExecutionPolicy&& exec,
|
||
InVec v, sum_of_squares_result<Scalar> init); // [[linalg.algs.blas1.nrm2]](#algs.blas1.nrm2 "29.9.13.9 Euclidean norm of a vector"), Euclidean norm of a vectortemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> Scalar vector_two_norm(InVec v, Scalar init); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>auto vector_two_norm(InVec v); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>auto vector_two_norm(ExecutionPolicy&& exec, InVec v); // [[linalg.algs.blas1.asum]](#algs.blas1.asum "29.9.13.10 Sum of absolute values of vector elements"), sum of absolute values of vector elementstemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> Scalar vector_abs_sum(InVec v, Scalar init); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar> Scalar vector_abs_sum(ExecutionPolicy&& exec, InVec v, Scalar init); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>auto vector_abs_sum(InVec v); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>auto vector_abs_sum(ExecutionPolicy&& exec, InVec v); // [[linalg.algs.blas1.iamax]](#algs.blas1.iamax "29.9.13.11 Index of maximum absolute value of vector elements"), index of maximum absolute value of vector elementstemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>typename InVec::extents_type vector_idx_abs_max(InVec v); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>typename InVec::extents_type vector_idx_abs_max(ExecutionPolicy&& exec, InVec v); // [[linalg.algs.blas1.matfrobnorm]](#algs.blas1.matfrobnorm "29.9.13.12 Frobenius norm of a matrix"), Frobenius norm of a matrixtemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_frob_norm(InMat A, Scalar init); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_frob_norm(InMat A); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_frob_norm(ExecutionPolicy&& exec, InMat A); // [[linalg.algs.blas1.matonenorm]](#algs.blas1.matonenorm "29.9.13.13 One norm of a matrix"), one norm of a matrixtemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_one_norm(InMat A, Scalar init); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_one_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_one_norm(InMat A); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_one_norm(ExecutionPolicy&& exec, InMat A); // [[linalg.algs.blas1.matinfnorm]](#algs.blas1.matinfnorm "29.9.13.14 Infinity norm of a matrix"), infinity norm of a matrixtemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_inf_norm(InMat A, Scalar init); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar> Scalar matrix_inf_norm(ExecutionPolicy&& exec, InMat A, Scalar init); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_inf_norm(InMat A); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>auto matrix_inf_norm(ExecutionPolicy&& exec, InMat A); // [[linalg.algs.blas2]](#algs.blas2 "29.9.14 BLAS 2 algorithms"), BLAS 2 algorithms// [[linalg.algs.blas2.gemv]](#algs.blas2.gemv "29.9.14.1 General matrix-vector product"), general matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void matrix_vector_product(InMat A, InVec x, OutVec y); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, InVec x, OutVec y); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void matrix_vector_product(InMat A, InVec1 x, InVec2 y, OutVec z); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, InVec1 x, InVec2 y, OutVec z); // [[linalg.algs.blas2.symv]](#algs.blas2.symv "29.9.14.2 Symmetric matrix-vector product"), symmetric matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void symmetric_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec x, OutVec y); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void symmetric_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z); // [[linalg.algs.blas2.hemv]](#algs.blas2.hemv "29.9.14.3 Hermitian matrix-vector product"), Hermitian matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void hermitian_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec x, OutVec y); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void hermitian_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z); // [[linalg.algs.blas2.trmv]](#algs.blas2.trmv "29.9.14.4 Triangular matrix-vector product"), triangular matrix-vector product// Overwriting triangular matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InVec x,
|
||
OutVec y); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InVec x,
|
||
OutVec y); // In-place triangular matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InOutVec y); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutVec y); // Updating triangular matrix-vector producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d,
|
||
InVec1 x, InVec2 y, OutVec z); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InVec1 x, InVec2 y, OutVec z); // [[linalg.algs.blas2.trsv]](#algs.blas2.trsv "29.9.14.5 Solve a triangular linear system"), solve a triangular linear system// Solve a triangular linear system, not in placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec, class BinaryDivideOp>void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec, class BinaryDivideOp>void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x); // Solve a triangular linear system, in placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec, class BinaryDivideOp>void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutVec b, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec, class BinaryDivideOp>void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutVec b, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d, InOutVec b); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutVec b); // [[linalg.algs.blas2.rank1]](#algs.blas2.rank1 "29.9.14.6 Rank-1 (outer product) update of a matrix"), nonsymmetric rank-1 matrix updatetemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void matrix_rank_1_update(InVec1 x, InVec2 y, InOutMat A); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void matrix_rank_1_update_c(InVec1 x, InVec2 y, InOutMat A); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void matrix_rank_1_update_c(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A); // [[linalg.algs.blas2.symherrank1]](#algs.blas2.symherrank1 "29.9.14.7 Symmetric or Hermitian Rank-1 (outer product) update of a matrix"), symmetric or Hermitian rank-1 matrix updatetemplate<class Scalar, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); template<class ExecutionPolicy, class Scalar, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InVec x, InOutMat A, Triangle t); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
InVec x, InOutMat A, Triangle t); template<class Scalar, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t); template<class ExecutionPolicy, class Scalar, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InVec x, InOutMat A, Triangle t); template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_1_update(InVec x, InOutMat A, Triangle t); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
InVec x, InOutMat A, Triangle t); // [[linalg.algs.blas2.rank2]](#algs.blas2.rank2 "29.9.14.8 Symmetric and Hermitian rank-2 matrix updates"), symmetric and Hermitian rank-2 matrix updates// symmetric rank-2 matrix updatetemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A, Triangle t); // Hermitian rank-2 matrix updatetemplate<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t); template<class ExecutionPolicy, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A, Triangle t); // [[linalg.algs.blas3]](#algs.blas3 "29.9.15 BLAS 3 algorithms"), BLAS 3 algorithms// [[linalg.algs.blas3.gemm]](#algs.blas3.gemm "29.9.15.1 General matrix-matrix product"), general matrix-matrix producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void matrix_product(InMat1 A, InMat2 B, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void matrix_product(InMat1 A, InMat2 B, InMat3 E, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, InMat3 E, OutMat C); // [[linalg.algs.blas3.xxmm]](#algs.blas3.xxmm "29.9.15.2 Symmetric, Hermitian, and triangular matrix-matrix product"), symmetric, Hermitian, and triangular matrix-matrix producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
|
||
OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
|
||
OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
|
||
OutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
|
||
OutMat C); // [[linalg.algs.blas3.trmm]](#algs.blas3.trmm "29.9.15.3 In-place triangular matrix-matrix product"), in-place triangular matrix-matrix producttemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_left_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_left_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutMat C); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_right_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_right_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutMat C); // [[linalg.algs.blas3.rankk]](#algs.blas3.rankk "29.9.15.4 Rank-k update of a symmetric or Hermitian matrix"), rank-k update of a symmetric or Hermitian matrix// rank-k symmetric matrix updatetemplate<class Scalar, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); template<class ExecutionPolicy, class Scalar, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InMat A, InOutMat C, Triangle t); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
InMat A, InOutMat C, Triangle t); // rank-k Hermitian matrix updatetemplate<class Scalar, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t); template<class ExecutionPolicy, class Scalar, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InMat A, InOutMat C, Triangle t); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_k_update(InMat A, InOutMat C, Triangle t); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
InMat A, InOutMat C, Triangle t); // [[linalg.algs.blas3.rank2k]](#algs.blas3.rank2k "29.9.15.5 Rank-2k update of a symmetric or Hermitian matrix"), rank-2k update of a symmetric or Hermitian matrix// rank-2k symmetric matrix updatetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, InOutMat C, Triangle t); // rank-2k Hermitian matrix updatetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, InOutMat C, Triangle t); // [[linalg.algs.blas3.trsm]](#algs.blas3.trsm "29.9.15.6 Solve multiple triangular linear systems"), solve multiple triangular linear systems// solve multiple triangular systems on the left, not-in-placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>void triangular_matrix_matrix_left_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_matrix_left_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X); // solve multiple triangular systems on the right, not-in-placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>void triangular_matrix_matrix_right_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_matrix_right_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X); // solve multiple triangular systems on the left, in-placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B); // solve multiple triangular systems on the right, in-placetemplate<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide); template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B); template<class ExecutionPolicy, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B);}
|
||
|
||
### [29.9.3](#general) General [[linalg.general]](linalg.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11642)
|
||
|
||
For the effects of all functions in [linalg],
|
||
when the effects are described as
|
||
âcomputes R=Eâ or âcompute R=Eâ
|
||
(for some R and mathematical expression E),
|
||
the following apply:
|
||
|
||
- [(1.1)](#general-1.1)
|
||
|
||
E has
|
||
the conventional mathematical meaning as written[.](#general-1.1.sentence-1)
|
||
|
||
- [(1.2)](#general-1.2)
|
||
|
||
The pattern xT should be read as
|
||
âthe transpose of x[.](#general-1.2.sentence-1)â
|
||
|
||
- [(1.3)](#general-1.3)
|
||
|
||
The pattern xH should be read as
|
||
âthe conjugate transpose of x[.](#general-1.3.sentence-1)â
|
||
|
||
- [(1.4)](#general-1.4)
|
||
|
||
When R is the same name as a function parameter
|
||
whose type is a template parameter with Out in its name,
|
||
the intent is that the result of the computation
|
||
is written to the elements of the function parameter R[.](#general-1.4.sentence-1)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11665)
|
||
|
||
Some of the functions and types in [linalg] distinguish between
|
||
the ârowsâ and the âcolumnsâ of a matrix[.](#general-2.sentence-1)
|
||
|
||
For a matrix A and a multidimensional index i, j in A.extents(),
|
||
|
||
- [(2.1)](#general-2.1)
|
||
|
||
[*row*](#def:row) i of A is the set of elements A[i, k1] for all k1 such that i, k1 is in A.extents(); and
|
||
|
||
- [(2.2)](#general-2.2)
|
||
|
||
[*column*](#def:column) j of A is the set of elements A[k0, j] for all k0 such that k0, j is in A.extents()[.](#general-2.sentence-2)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11678)
|
||
|
||
Some of the functions in [linalg] distinguish between
|
||
the âupper triangle,â âlower triangle,â and âdiagonalâ of a matrix[.](#general-3.sentence-1)
|
||
|
||
- [(3.1)](#general-3.1)
|
||
|
||
The [*diagonal*](#def:diagonal "29.9.3 General [linalg.general]") is the set of all elements of A accessed by A[i,i] for 0 ⤠i < min(A.extent(0), A.extent(1))[.](#general-3.1.sentence-1)
|
||
|
||
- [(3.2)](#general-3.2)
|
||
|
||
The [*upper triangle*](#def:triangle,upper "29.9.3 General [linalg.general]") of a matrix A is the set of all elements of A accessed by A[i,j] with i ⤠j[.](#general-3.2.sentence-1)
|
||
It includes the diagonal[.](#general-3.2.sentence-2)
|
||
|
||
- [(3.3)](#general-3.3)
|
||
|
||
The [*lower triangle*](#def:triangle,lower "29.9.3 General [linalg.general]") of A is the set of all elements of A accessed by A[i,j] with i ⥠j[.](#general-3.3.sentence-1)
|
||
It includes the diagonal[.](#general-3.3.sentence-2)
|
||
|
||
[4](#general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11693)
|
||
|
||
For any function F that takes
|
||
a parameter named t,t applies to accesses done through the parameter preceding t in the parameter list of F[.](#general-4.sentence-1)
|
||
|
||
Let m be such an access-modified function parameter[.](#general-4.sentence-2)
|
||
|
||
F will only access the triangle of m specified by t[.](#general-4.sentence-3)
|
||
|
||
For accesses m[i, j] outside the triangle specified by t,F will use the value
|
||
|
||
- [(4.1)](#general-4.1)
|
||
|
||
*conj-if-needed*(m[j, i]) if the name of F starts with hermitian,
|
||
|
||
- [(4.2)](#general-4.2)
|
||
|
||
m[j, i] if the name of F starts with symmetric, or
|
||
|
||
- [(4.3)](#general-4.3)
|
||
|
||
the additive identity if the name of F starts with triangular[.](#general-4.sentence-4)
|
||
|
||
[*Example [1](#general-example-1)*:
|
||
|
||
Small vector product accessing only specified triangle[.](#general-4.sentence-5)
|
||
|
||
It would not be a precondition violation for the non-accessed
|
||
matrix element to be non-zero[.](#general-4.sentence-6)
|
||
|
||
template<class Triangle>void triangular_matrix_vector_2x2_product( mdspan<const float, extents<int, 2, 2>> m,
|
||
Triangle t,
|
||
mdspan<const float, extents<int, 2>> x,
|
||
mdspan<float, extents<int, 2>> y) {static_assert(is_same_v<Triangle, lower_triangle_t> || is_same_v<Triangle, upper_triangle_t>); if constexpr (is_same_v<Triangle, lower_triangle_t>) { y[0] = m[0,0] * x[0]; // + 0 * x[1] y[1] = m[1,0] * x[0] + m[1,1] * x[1]; } else { // upper_triangle_t y[0] = m[0,0] * x[0] + m[0,1] * x[1];
|
||
y[1] = /* 0 * x[0] + */ m[1,1] * x[1]; }} â *end example*]
|
||
|
||
[5](#general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11735)
|
||
|
||
For any function F that takes a parameter named d,d applies to accesses done through
|
||
the previous-of-the-previous parameter of d in the parameter list of F[.](#general-5.sentence-1)
|
||
|
||
Let m be such an access-modified function parameter[.](#general-5.sentence-2)
|
||
|
||
If d specifies that an implicit unit diagonal is to be assumed, then
|
||
|
||
- [(5.1)](#general-5.1)
|
||
|
||
F will not access the diagonal of m; and
|
||
|
||
- [(5.2)](#general-5.2)
|
||
|
||
the algorithm will interpret m as if it has a unit diagonal, that is,
|
||
a diagonal each of whose elements behaves as a two-sided multiplicative identity
|
||
(even if m's value type does not have
|
||
a two-sided multiplicative identity)[.](#general-5.sentence-3)
|
||
|
||
Otherwise,
|
||
if d specifies that an explicit diagonal is to be assumed,
|
||
then F will access the diagonal of m[.](#general-5.sentence-4)
|
||
|
||
[6](#general-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11755)
|
||
|
||
Within all the functions in [linalg],
|
||
any calls to abs, conj, imag, and real are unqualified[.](#general-6.sentence-1)
|
||
|
||
[7](#general-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11760)
|
||
|
||
Two mdspan objects x and y [*alias*](#def:alias) each other,
|
||
if they have the same extents e, and
|
||
for every pack of integers i which is a multidimensional index in e,x[i...] and y[i...] refer to the same element[.](#general-7.sentence-1)
|
||
|
||
[*Note [1](#general-note-1)*:
|
||
|
||
This means thatx and y view the same elements in the same order[.](#general-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[8](#general-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11771)
|
||
|
||
Two mdspan objects x and y [*overlap*](#def:overlap) each other,
|
||
if for some pack of integers i that is a multidimensional index in x.extents(),
|
||
there exists a pack of integers j that is a multidimensional index in y.extents(),
|
||
such that x[i...] and y[j...] refer to the same element[.](#general-8.sentence-1)
|
||
|
||
[*Note [2](#general-note-2)*:
|
||
|
||
Aliasing is a special case of overlapping[.](#general-8.sentence-2)
|
||
|
||
If x and y do not overlap,
|
||
then they also do not alias each other[.](#general-8.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
### [29.9.4](#reqs) Requirements [[linalg.reqs]](linalg.reqs)
|
||
|
||
#### [29.9.4.1](#reqs.val) Linear algebra value types [[linalg.reqs.val]](linalg.reqs.val)
|
||
|
||
[1](#reqs.val-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11788)
|
||
|
||
Throughout [linalg],
|
||
the following types are[*linear algebra value types*](#def:value_type,linear_algebra "29.9.4.1 Linear algebra value types [linalg.reqs.val]"):
|
||
|
||
- [(1.1)](#reqs.val-1.1)
|
||
|
||
the value_type type alias of
|
||
any input or output mdspan parameter(s) of
|
||
any function in [linalg]; and
|
||
|
||
- [(1.2)](#reqs.val-1.2)
|
||
|
||
the Scalar template parameter (if any) of
|
||
any function or class in [linalg][.](#reqs.val-1.sentence-1)
|
||
|
||
[2](#reqs.val-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11802)
|
||
|
||
Linear algebra value types shall model [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#reqs.val-2.sentence-1)
|
||
|
||
[3](#reqs.val-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11805)
|
||
|
||
A value-initialized object of linear algebra value type
|
||
shall act as the additive identity[.](#reqs.val-3.sentence-1)
|
||
|
||
#### [29.9.4.2](#reqs.alg) Algorithm and class requirements [[linalg.reqs.alg]](linalg.reqs.alg)
|
||
|
||
[1](#reqs.alg-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11811)
|
||
|
||
[[linalg.reqs.alg]](#reqs.alg "29.9.4.2 Algorithm and class requirements") lists common requirements for
|
||
all algorithms and classes in [linalg][.](#reqs.alg-1.sentence-1)
|
||
|
||
[2](#reqs.alg-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11815)
|
||
|
||
All of the following statements presume
|
||
that the algorithm's asymptotic complexity requirements, if any, are satisfied[.](#reqs.alg-2.sentence-1)
|
||
|
||
- [(2.1)](#reqs.alg-2.1)
|
||
|
||
The function may make arbitrarily many objects of any linear algebra value type,
|
||
value-initializing or direct-initializing them
|
||
with any existing object of that type[.](#reqs.alg-2.1.sentence-1)
|
||
|
||
- [(2.2)](#reqs.alg-2.2)
|
||
|
||
The [*triangular solve algorithms*](#def:triangular_solve_algorithms) in[[linalg.algs.blas2.trsv]](#algs.blas2.trsv "29.9.14.5 Solve a triangular linear system"),[[linalg.algs.blas3.trmm]](#algs.blas3.trmm "29.9.15.3 In-place triangular matrix-matrix product"),[[linalg.algs.blas3.trsm]](#algs.blas3.trsm "29.9.15.6 Solve multiple triangular linear systems"), and[[linalg.algs.blas3.inplacetrsm]](#algs.blas3.inplacetrsm "29.9.15.7 Solve multiple triangular linear systems in-place") either have
|
||
a BinaryDivideOp template parameter (see [[linalg.algs.reqs]](#algs.reqs "29.9.12 Algorithm requirements based on template parameter name")) and
|
||
a binary function object parameter divide of that type,
|
||
or they have effects equivalent to invoking such an algorithm[.](#reqs.alg-2.2.sentence-1)
|
||
Triangular solve algorithms interpret divide(a, b) asa times the multiplicative inverse of b[.](#reqs.alg-2.2.sentence-2)
|
||
Each triangular solve algorithm uses a sequence of evaluations of*, *=, divide,
|
||
unary +, binary +, +=,
|
||
unary -, binary -, -=,
|
||
and = operators
|
||
that would produce the result
|
||
specified by the algorithm's *Effects* and *Remarks* when operating on elements of a field with noncommutative multiplication[.](#reqs.alg-2.2.sentence-3)
|
||
It is a precondition of the algorithm that
|
||
any addend,
|
||
any subtrahend,
|
||
any partial sum of addends in any order
|
||
(treating any difference as a sum with the second term negated),
|
||
any factor,
|
||
any partial product of factors respecting their order,
|
||
any numerator (first argument of divide),
|
||
any denominator (second argument of divide),
|
||
and any assignment
|
||
is a well-formed expression[.](#reqs.alg-2.2.sentence-4)
|
||
|
||
- [(2.3)](#reqs.alg-2.3)
|
||
|
||
Each function in[[linalg.algs.blas1]](#algs.blas1 "29.9.13 BLAS 1 algorithms"), [[linalg.algs.blas2]](#algs.blas2 "29.9.14 BLAS 2 algorithms"), and [[linalg.algs.blas3]](#algs.blas3 "29.9.15 BLAS 3 algorithms") that is not a triangular solve algorithm
|
||
will use a sequence of evaluations of*, *=, +, +=, and = operators
|
||
that would produce the result
|
||
specified by the algorithm's *Effects* and *Remarks* when operating on elements of a semiring with noncommutative multiplication[.](#reqs.alg-2.3.sentence-1)
|
||
It is a precondition of the algorithm that
|
||
any addend,
|
||
any partial sum of addends in any order,
|
||
any factor,
|
||
any partial product of factors respecting their order,
|
||
and any assignment
|
||
is a well-formed expression[.](#reqs.alg-2.3.sentence-2)
|
||
|
||
- [(2.4)](#reqs.alg-2.4)
|
||
|
||
If the function has an output mdspan,
|
||
then all addends,
|
||
subtrahends (for the triangular solve algorithms),
|
||
or results of the divide parameter on intermediate terms
|
||
(if the function takes a divide parameter)
|
||
are assignable and convertible to
|
||
the output mdspan's value_type[.](#reqs.alg-2.4.sentence-1)
|
||
|
||
- [(2.5)](#reqs.alg-2.5)
|
||
|
||
The function may reorder addends and partial sums arbitrarily[.](#reqs.alg-2.5.sentence-1)
|
||
[*Note [1](#reqs.alg-note-1)*:
|
||
Factors in each product are not reordered;
|
||
multiplication is not necessarily commutative[.](#reqs.alg-2.5.sentence-2)
|
||
â *end note*]
|
||
|
||
[*Note [2](#reqs.alg-note-2)*:
|
||
|
||
The above requirements do not prohibit
|
||
implementation approaches and optimization techniques
|
||
which are not user-observable[.](#reqs.alg-2.sentence-2)
|
||
|
||
In particular, if for all input and output arguments
|
||
the value_type is a floating-point type,
|
||
implementers are free to leverage approximations,
|
||
use arithmetic operations not explicitly listed above, and
|
||
compute floating point sums in any way that improves their accuracy[.](#reqs.alg-2.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[3](#reqs.alg-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11896)
|
||
|
||
[*Note [3](#reqs.alg-note-3)*:
|
||
|
||
For all functions in [linalg],
|
||
suppose that all input and output mdspan have as value_type a floating-point type, and
|
||
any Scalar template argument has a floating-point type[.](#reqs.alg-3.sentence-1)
|
||
|
||
Then, functions can do all of the following:
|
||
|
||
- [(3.1)](#reqs.alg-3.1)
|
||
|
||
compute floating-point sums in any way
|
||
that improves their accuracy for arbitrary input;
|
||
|
||
- [(3.2)](#reqs.alg-3.2)
|
||
|
||
perform additional arithmetic operations
|
||
(other than those specified by the function's wording and [[linalg.reqs.alg]](#reqs.alg "29.9.4.2 Algorithm and class requirements"))
|
||
in order to improve performance or accuracy; and
|
||
|
||
- [(3.3)](#reqs.alg-3.3)
|
||
|
||
use approximations
|
||
(that might not be exact even if computing with real numbers),
|
||
instead of computations that would be exact
|
||
if it were possible to compute without rounding error;
|
||
|
||
as long as
|
||
|
||
- [(3.4)](#reqs.alg-3.4)
|
||
|
||
the function satisfies the complexity requirements; and
|
||
|
||
- [(3.5)](#reqs.alg-3.5)
|
||
|
||
the function is logarithmically stable,
|
||
as defined in Demmel 2007[[bib]](bibliography#bib:linalg-stable "Bibliography")[.](#reqs.alg-3.sentence-2)
|
||
Strassen's algorithm for matrix-matrix multiply
|
||
is an example of a logarithmically stable algorithm[.](#reqs.alg-3.5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [29.9.5](#tags) Tag classes [[linalg.tags]](linalg.tags)
|
||
|
||
#### [29.9.5.1](#tags.order) Storage order tags [[linalg.tags.order]](linalg.tags.order)
|
||
|
||
[1](#tags.order-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11933)
|
||
|
||
The storage order tags describe
|
||
the order of elements in an mdspan withlayout_blas_packed ([[linalg.layout.packed]](#layout.packed "29.9.6 Layouts for packed matrix types")) layout[.](#tags.order-1.sentence-1)
|
||
|
||
[ð](#tags.order-itemdecl:1)
|
||
|
||
`struct [column_major_t](#lib:column_major_t "29.9.5.1 Storage order tags [linalg.tags.order]") {
|
||
explicit column_major_t() = default;
|
||
};
|
||
inline constexpr column_major_t [column_major](#lib:column_major "29.9.5.1 Storage order tags [linalg.tags.order]"){};
|
||
|
||
struct [row_major_t](#lib:row_major_t "29.9.5.1 Storage order tags [linalg.tags.order]") {
|
||
explicit row_major_t() = default;
|
||
};
|
||
inline constexpr row_major_t [row_major](#lib:row_major "29.9.5.1 Storage order tags [linalg.tags.order]"){};
|
||
`
|
||
|
||
[2](#tags.order-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11950)
|
||
|
||
column_major_t indicates a column-major order,
|
||
and row_major_t indicates a row-major order[.](#tags.order-2.sentence-1)
|
||
|
||
#### [29.9.5.2](#tags.triangle) Triangle tags [[linalg.tags.triangle]](linalg.tags.triangle)
|
||
|
||
[ð](#tags.triangle-itemdecl:1)
|
||
|
||
`struct [upper_triangle_t](#lib:upper_triangle_t "29.9.5.2 Triangle tags [linalg.tags.triangle]") {
|
||
explicit upper_triangle_t() = default;
|
||
};
|
||
inline constexpr upper_triangle_t [upper_triangle](#lib:upper_triangle "29.9.5.2 Triangle tags [linalg.tags.triangle]"){};
|
||
|
||
struct [lower_triangle_t](#lib:lower_triangle_t "29.9.5.2 Triangle tags [linalg.tags.triangle]") {
|
||
explicit lower_triangle_t() = default;
|
||
};
|
||
inline constexpr lower_triangle_t [lower_triangle](#lib:lower_triangle "29.9.5.2 Triangle tags [linalg.tags.triangle]"){};
|
||
`
|
||
|
||
[1](#tags.triangle-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11970)
|
||
|
||
These tag classes specify whether
|
||
algorithms and other users of a matrix (represented as an mdspan)
|
||
access the
|
||
upper triangle (upper_triangle_t) or
|
||
lower triangle (lower_triangle_t)
|
||
of the matrix (see also [[linalg.general]](#general "29.9.3 General"))[.](#tags.triangle-1.sentence-1)
|
||
|
||
This is also subject to the restrictions of implicit_unit_diagonal_t if that tag is also used as a function argument; see below[.](#tags.triangle-1.sentence-2)
|
||
|
||
#### [29.9.5.3](#tags.diagonal) Diagonal tags [[linalg.tags.diagonal]](linalg.tags.diagonal)
|
||
|
||
[ð](#tags.diagonal-itemdecl:1)
|
||
|
||
`struct [implicit_unit_diagonal_t](#lib:implicit_unit_diagonal_t "29.9.5.3 Diagonal tags [linalg.tags.diagonal]") {
|
||
explicit implicit_unit_diagonal_t() = default;
|
||
};
|
||
inline constexpr implicit_unit_diagonal_t [implicit_unit_diagonal](#lib:implicit_unit_diagonal "29.9.5.3 Diagonal tags [linalg.tags.diagonal]"){};
|
||
|
||
struct [explicit_diagonal_t](#lib:explicit_diagonal_t "29.9.5.3 Diagonal tags [linalg.tags.diagonal]") {
|
||
explicit explicit_diagonal_t() = default;
|
||
};
|
||
inline constexpr explicit_diagonal_t [explicit_diagonal](#lib:explicit_diagonal "29.9.5.3 Diagonal tags [linalg.tags.diagonal]"){};
|
||
`
|
||
|
||
[1](#tags.diagonal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L11996)
|
||
|
||
These tag classes specify whether algorithms
|
||
access the matrix's diagonal entries, and if not,
|
||
then how algorithms interpret
|
||
the matrix's implicitly represented diagonal values[.](#tags.diagonal-1.sentence-1)
|
||
|
||
[2](#tags.diagonal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12002)
|
||
|
||
The implicit_unit_diagonal_t tag indicates that
|
||
an implicit unit diagonal is to be assumed ([[linalg.general]](#general "29.9.3 General"))[.](#tags.diagonal-2.sentence-1)
|
||
|
||
[3](#tags.diagonal-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12006)
|
||
|
||
The explicit_diagonal_t tag indicates that
|
||
an explicit diagonal is used ([[linalg.general]](#general "29.9.3 General"))[.](#tags.diagonal-3.sentence-1)
|
||
|
||
### [29.9.6](#layout.packed) Layouts for packed matrix types [[linalg.layout.packed]](linalg.layout.packed)
|
||
|
||
#### [29.9.6.1](#layout.packed.overview) Overview [[linalg.layout.packed.overview]](linalg.layout.packed.overview)
|
||
|
||
[1](#layout.packed.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12015)
|
||
|
||
layout_blas_packed is an mdspan layout mapping policy
|
||
that represents a square matrix that stores only the entries in one
|
||
triangle, in a packed contiguous format[.](#layout.packed.overview-1.sentence-1)
|
||
|
||
Its Triangle template parameter determines
|
||
whether an mdspan with this layout
|
||
stores the upper or lower triangle of the matrix[.](#layout.packed.overview-1.sentence-2)
|
||
|
||
Its StorageOrder template parameter determines
|
||
whether the layout packs the matrix's elements
|
||
in column-major or row-major order[.](#layout.packed.overview-1.sentence-3)
|
||
|
||
[2](#layout.packed.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12026)
|
||
|
||
A StorageOrder of column_major_t indicates column-major ordering[.](#layout.packed.overview-2.sentence-1)
|
||
|
||
This packs matrix elements
|
||
starting with the leftmost (least column index) column, and
|
||
proceeding column by column, from the top entry (least row index)[.](#layout.packed.overview-2.sentence-2)
|
||
|
||
[3](#layout.packed.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12033)
|
||
|
||
A StorageOrder of row_major_t indicates row-major ordering[.](#layout.packed.overview-3.sentence-1)
|
||
|
||
This packs matrix elements
|
||
starting with the topmost (least row index) row, and
|
||
proceeding row by row, from the leftmost (least column index) entry[.](#layout.packed.overview-3.sentence-2)
|
||
|
||
[4](#layout.packed.overview-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12040)
|
||
|
||
[*Note [1](#layout.packed.overview-note-1)*:
|
||
|
||
layout_blas_packed describes the data layout used by
|
||
the BLAS'
|
||
Symmetric Packed (SP), Hermitian Packed (HP), and Triangular Packed (TP)
|
||
matrix types[.](#layout.packed.overview-4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
namespace std::linalg {template<class Triangle, class StorageOrder>class [layout_blas_packed](#lib:layout_blas_packed "29.9.6.1 Overview [linalg.layout.packed.overview]") {public:using triangle_type = Triangle; using storage_order_type = StorageOrder; template<class Extents>struct mapping {public:using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_blas_packed; // [[linalg.layout.packed.cons]](#layout.packed.cons "29.9.6.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>& other) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[linalg.layout.packed.obs]](#layout.packed.obs "29.9.6.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; template<class Index0, class Index1>constexpr index_type operator() (Index0 ind0, Index1 ind1) const noexcept; static constexpr bool is_always_unique() noexcept {return (extents_type::static_extent(0) != dynamic_extent && extents_type::static_extent(0) < 2) ||(extents_type::static_extent(1) != dynamic_extent && extents_type::static_extent(1) < 2); }static constexpr bool is_always_exhaustive() noexcept { return true; }static constexpr bool is_always_strided() noexcept{ return is_always_unique(); }constexpr bool is_unique() const noexcept {return *extents_*.extent(0) < 2; }constexpr bool is_exhaustive() const noexcept { return true; }constexpr bool is_strided() const noexcept {return *extents_*.extent(0) < 2; }constexpr index_type stride(rank_type) const noexcept; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*}; };}
|
||
|
||
[5](#layout.packed.overview-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12113)
|
||
|
||
*Mandates*:
|
||
|
||
- [(5.1)](#layout.packed.overview-5.1)
|
||
|
||
Triangle is either upper_triangle_t or lower_triangle_t,
|
||
|
||
- [(5.2)](#layout.packed.overview-5.2)
|
||
|
||
StorageOrder is either column_major_t or row_major_t,
|
||
|
||
- [(5.3)](#layout.packed.overview-5.3)
|
||
|
||
Extents is a specialization of std::extents,
|
||
|
||
- [(5.4)](#layout.packed.overview-5.4)
|
||
|
||
Extents::rank() equals 2,
|
||
|
||
- [(5.5)](#layout.packed.overview-5.5)
|
||
|
||
one ofextents_type::static_extent(0) == dynamic_extent, extents_type::static_extent(1) == dynamic_extent, or extents_type::static_extent(0) == extents_type::static_extent(1) is true, and
|
||
|
||
- [(5.6)](#layout.packed.overview-5.6)
|
||
|
||
if Extents::rank_dynamic() == 0 is true,
|
||
let Ns be equal to Extents::static_extent(0); then,NsÃ(Ns+1) is representable as a value of type index_type[.](#layout.packed.overview-5.sentence-1)
|
||
|
||
[6](#layout.packed.overview-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12138)
|
||
|
||
layout_blas_packed<T, SO>::mapping<E> is a trivially copyable type
|
||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each T, SO, and E[.](#layout.packed.overview-6.sentence-1)
|
||
|
||
#### [29.9.6.2](#layout.packed.cons) Constructors [[linalg.layout.packed.cons]](linalg.layout.packed.cons)
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,constructor)
|
||
|
||
`constexpr mapping(const extents_type& e) noexcept;
|
||
`
|
||
|
||
[1](#layout.packed.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12151)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(1.1)](#layout.packed.cons-1.1)
|
||
|
||
Let N be equal to e.extent(0)[.](#layout.packed.cons-1.1.sentence-1)
|
||
Then, NÃ(N+1) is representable as
|
||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#layout.packed.cons-1.1.sentence-2)
|
||
|
||
- [(1.2)](#layout.packed.cons-1.2)
|
||
|
||
e.extent(0) equals e.extent(1)[.](#layout.packed.cons-1.2.sentence-1)
|
||
|
||
[2](#layout.packed.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12162)
|
||
|
||
*Effects*: Direct-non-list-initializes *extents_* with e[.](#layout.packed.cons-2.sentence-1)
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,constructor_)
|
||
|
||
`template<class OtherExtents>
|
||
explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||
constexpr mapping(const mapping<OtherExtents>& other) noexcept;
|
||
`
|
||
|
||
[3](#layout.packed.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12175)
|
||
|
||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#layout.packed.cons-3.sentence-1)
|
||
|
||
[4](#layout.packed.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12179)
|
||
|
||
*Preconditions*: Let N be other.extents().extent(0)[.](#layout.packed.cons-4.sentence-1)
|
||
|
||
Then, NÃ(N+1) is representable as
|
||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#layout.packed.cons-4.sentence-2)
|
||
|
||
[5](#layout.packed.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12185)
|
||
|
||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#layout.packed.cons-5.sentence-1)
|
||
|
||
#### [29.9.6.3](#layout.packed.obs) Observers [[linalg.layout.packed.obs]](linalg.layout.packed.obs)
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,required_span_size)
|
||
|
||
`constexpr index_type required_span_size() const noexcept;
|
||
`
|
||
|
||
[1](#layout.packed.obs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12198)
|
||
|
||
*Returns*: *extents_*.extent(0) * (*extents_*.extent(0) + 1)/2[.](#layout.packed.obs-1.sentence-1)
|
||
|
||
[*Note [1](#layout.packed.obs-note-1)*:
|
||
|
||
For example, a 5 x 5 packed matrix
|
||
only stores 15 matrix elements[.](#layout.packed.obs-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,operator())
|
||
|
||
`template<class Index0, class Index1>
|
||
constexpr index_type operator() (Index0 ind0, Index1 ind1) const noexcept;
|
||
`
|
||
|
||
[2](#layout.packed.obs-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12214)
|
||
|
||
*Constraints*:
|
||
|
||
- [(2.1)](#layout.packed.obs-2.1)
|
||
|
||
is_convertible_v<Index0, index_type> is true,
|
||
|
||
- [(2.2)](#layout.packed.obs-2.2)
|
||
|
||
is_convertible_v<Index1, index_type> is true,
|
||
|
||
- [(2.3)](#layout.packed.obs-2.3)
|
||
|
||
is_nothrow_constructible_v<index_type, Index0> is true, and
|
||
|
||
- [(2.4)](#layout.packed.obs-2.4)
|
||
|
||
is_nothrow_constructible_v<index_type, Index1> is true[.](#layout.packed.obs-2.sentence-1)
|
||
|
||
[3](#layout.packed.obs-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12227)
|
||
|
||
Let i be extents_type::*index-cast*(ind0), and
|
||
let j be extents_type::*index-cast*(ind1)[.](#layout.packed.obs-3.sentence-1)
|
||
|
||
[4](#layout.packed.obs-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12231)
|
||
|
||
*Preconditions*: i, j is a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#layout.packed.obs-4.sentence-1)
|
||
|
||
[5](#layout.packed.obs-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12236)
|
||
|
||
*Returns*: Let N be *extents_*.extent(0)[.](#layout.packed.obs-5.sentence-1)
|
||
|
||
Then
|
||
|
||
- [(5.1)](#layout.packed.obs-5.1)
|
||
|
||
(*this)(j, i) if i > j is true; otherwise
|
||
|
||
- [(5.2)](#layout.packed.obs-5.2)
|
||
|
||
i + j * (j + 1)/2 ifis_same_v<StorageOrder, column_major_t> && is_same_v<Triangle, upper_triangle_t> is true oris_same_v<StorageOrder, row_major_t> && is_same_v<Triangle, lower_triangle_t> is true; otherwise
|
||
|
||
- [(5.3)](#layout.packed.obs-5.3)
|
||
|
||
j + N * i - i * (i + 1)/2[.](#layout.packed.obs-5.sentence-2)
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,stride)
|
||
|
||
`constexpr index_type stride(rank_type r) const noexcept;
|
||
`
|
||
|
||
[6](#layout.packed.obs-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12264)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(6.1)](#layout.packed.obs-6.1)
|
||
|
||
is_strided() is true, and
|
||
|
||
- [(6.2)](#layout.packed.obs-6.2)
|
||
|
||
r < extents_type::rank() is true[.](#layout.packed.obs-6.sentence-1)
|
||
|
||
[7](#layout.packed.obs-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12273)
|
||
|
||
*Returns*: 1[.](#layout.packed.obs-7.sentence-1)
|
||
|
||
[ð](#lib:layout_blas_packed::mapping,operator==)
|
||
|
||
`template<class OtherExtents>
|
||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
|
||
`
|
||
|
||
[8](#layout.packed.obs-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12285)
|
||
|
||
*Effects*: Equivalent to: return x.extents() == y.extents();
|
||
|
||
### [29.9.7](#helpers) Exposition-only helpers [[linalg.helpers]](linalg.helpers)
|
||
|
||
#### [29.9.7.1](#helpers.abs) *abs-if-needed* [[linalg.helpers.abs]](linalg.helpers.abs)
|
||
|
||
[1](#helpers.abs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12294)
|
||
|
||
The name *abs-if-needed* denotes an exposition-only function object[.](#helpers.abs-1.sentence-1)
|
||
|
||
The expression *abs-if-needed*(E) for a subexpression E whose type is T is expression-equivalent to:
|
||
|
||
- [(1.1)](#helpers.abs-1.1)
|
||
|
||
E if T is an unsigned integer;
|
||
|
||
- [(1.2)](#helpers.abs-1.2)
|
||
|
||
otherwise, std::abs(E) if T is an arithmetic type,
|
||
|
||
- [(1.3)](#helpers.abs-1.3)
|
||
|
||
otherwise, abs(E),
|
||
if that expression is valid,
|
||
with overload resolution performed in a context that includes the declarationtemplate<class U> U abs(U) = delete;
|
||
If the function selected by overload resolution
|
||
does not return the absolute value of its input,
|
||
the program is ill-formed, no diagnostic required[.](#helpers.abs-1.3.sentence-2)
|
||
|
||
#### [29.9.7.2](#helpers.conj) *conj-if-needed* [[linalg.helpers.conj]](linalg.helpers.conj)
|
||
|
||
[1](#helpers.conj-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12317)
|
||
|
||
The name *conj-if-needed* denotes an exposition-only function object[.](#helpers.conj-1.sentence-1)
|
||
|
||
The expression *conj-if-needed*(E) for a subexpression E whose type is T is expression-equivalent to:
|
||
|
||
- [(1.1)](#helpers.conj-1.1)
|
||
|
||
conj(E),
|
||
if T is not an arithmetic type and
|
||
the expression conj(E) is valid,
|
||
with overload resolution performed in a context that includes the declarationtemplate<class U> U conj(const U&) = delete;
|
||
If the function selected by overload resolution
|
||
does not return the complex conjugate of its input,
|
||
the program is ill-formed, no diagnostic required;
|
||
|
||
- [(1.2)](#helpers.conj-1.2)
|
||
|
||
otherwise, E[.](#helpers.conj-1.sentence-2)
|
||
|
||
#### [29.9.7.3](#helpers.real) *real-if-needed* [[linalg.helpers.real]](linalg.helpers.real)
|
||
|
||
[1](#helpers.real-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12339)
|
||
|
||
The name *real-if-needed* denotes an exposition-only function object[.](#helpers.real-1.sentence-1)
|
||
|
||
The expression *real-if-needed*(E) for a subexpression E whose type is T is expression-equivalent to:
|
||
|
||
- [(1.1)](#helpers.real-1.1)
|
||
|
||
real(E),
|
||
if T is not an arithmetic type and
|
||
the expression real(E) is valid,
|
||
with overload resolution performed in a context that includes the declarationtemplate<class U> U real(const U&) = delete;
|
||
If the function selected by overload resolution
|
||
does not return the real part of its input,
|
||
the program is ill-formed, no diagnostic required;
|
||
|
||
- [(1.2)](#helpers.real-1.2)
|
||
|
||
otherwise, E[.](#helpers.real-1.sentence-2)
|
||
|
||
#### [29.9.7.4](#helpers.imag) *imag-if-needed* [[linalg.helpers.imag]](linalg.helpers.imag)
|
||
|
||
[1](#helpers.imag-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12361)
|
||
|
||
The name *imag-if-needed* denotes an exposition-only function object[.](#helpers.imag-1.sentence-1)
|
||
|
||
The expression *imag-if-needed*(E) for a subexpression E whose type is T is expression-equivalent to:
|
||
|
||
- [(1.1)](#helpers.imag-1.1)
|
||
|
||
imag(E),
|
||
if T is not an arithmetic type and the expression imag(E) is valid, with overload resolution performed in a context
|
||
that includes the declarationtemplate<class U> U imag(const U&) = delete;
|
||
If the function selected by overload resolution
|
||
does not return the imaginary part of its input,
|
||
the program is ill-formed, no diagnostic required;
|
||
|
||
- [(1.2)](#helpers.imag-1.2)
|
||
|
||
otherwise, ((void)E, T{})[.](#helpers.imag-1.sentence-2)
|
||
|
||
#### [29.9.7.5](#helpers.concepts) Argument concepts [[linalg.helpers.concepts]](linalg.helpers.concepts)
|
||
|
||
[1](#helpers.concepts-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12383)
|
||
|
||
The exposition-only concepts defined in this section
|
||
constrain the algorithms in [linalg][.](#helpers.concepts-1.sentence-1)
|
||
|
||
template<class T>constexpr bool *is-mdspan* = false;
|
||
|
||
template<class ElementType, class Extents, class Layout, class Accessor>constexpr bool *is-mdspan*<mdspan<ElementType, Extents, Layout, Accessor>> = true;
|
||
|
||
template<class T>concept [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 1;
|
||
|
||
template<class T>concept [*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 1 && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
template<class T>concept [*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 1 && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
template<class T>concept [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 2;
|
||
|
||
template<class T>concept [*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 2 && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
template<class T>concept [*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 2 && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
template<class T>constexpr bool *is-layout-blas-packed* = false; // *exposition only*template<class Triangle, class StorageOrder>constexpr bool *is-layout-blas-packed*<layout_blas_packed<Triangle, StorageOrder>> = true;
|
||
|
||
template<class T>concept [*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && T::rank() == 2 && is_assignable_v<typename T::reference, typename T::element_type> &&(T::is_always_unique() || *is-layout-blas-packed*<typename T::layout_type>);
|
||
|
||
template<class T>concept [*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && (T::rank() == 1 || T::rank() == 2);
|
||
|
||
template<class T>concept [*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && (T::rank() == 1 || T::rank() == 2) && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
template<class T>concept [*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") =*is-mdspan*<T> && (T::rank() == 1 || T::rank() == 2) && is_assignable_v<typename T::reference, typename T::element_type> && T::is_always_unique();
|
||
|
||
[2](#helpers.concepts-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12448)
|
||
|
||
If a function in [linalg] accesses the elements
|
||
of a parameter constrained by[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]"), or[*in-object*](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),
|
||
those accesses will not modify the elements[.](#helpers.concepts-2.sentence-1)
|
||
|
||
[3](#helpers.concepts-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12456)
|
||
|
||
Unless explicitly permitted, any[*inout-vector*](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*inout-matrix*](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*inout-object*](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*out-vector*](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*out-matrix*](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]"),[*out-object*](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]"), or[*possibly-packed-inout-matrix*](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") parameter of a function in [linalg]
|
||
shall not overlap any other mdspan parameter of the function[.](#helpers.concepts-3.sentence-1)
|
||
|
||
#### [29.9.7.6](#helpers.mandates) Mandates [[linalg.helpers.mandates]](linalg.helpers.mandates)
|
||
|
||
[1](#helpers.mandates-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12470)
|
||
|
||
[*Note [1](#helpers.mandates-note-1)*:
|
||
|
||
These exposition-only helper functions use
|
||
the less constraining input concepts even for the output arguments,
|
||
because the additional constraint for assignability of elements
|
||
is not necessary, and
|
||
they are sometimes used in a context
|
||
where the third argument is an input type too[.](#helpers.mandates-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
template<class MDS1, class MDS2>requires(*is-mdspan*<MDS1> && *is-mdspan*<MDS2>)constexprbool *compatible-static-extents*(size_t r1, size_t r2) { // *exposition only*return MDS1::static_extent(r1) == dynamic_extent || MDS2::static_extent(r2) == dynamic_extent || MDS1::static_extent(r1) == MDS2::static_extent(r2); }template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") In1, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") In2, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") Out>constexpr bool *possibly-addable*() { // *exposition only*return *compatible-static-extents*<Out, In1>(0, 0) &&*compatible-static-extents*<Out, In2>(0, 0) &&*compatible-static-extents*<In1, In2>(0, 0); }template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") In1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") In2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") Out>constexpr bool *possibly-addable*() { // *exposition only*return *compatible-static-extents*<Out, In1>(0, 0) &&*compatible-static-extents*<Out, In1>(1, 1) &&*compatible-static-extents*<Out, In2>(0, 0) &&*compatible-static-extents*<Out, In2>(1, 1) &&*compatible-static-extents*<In1, In2>(0, 0) &&*compatible-static-extents*<In1, In2>(1, 1); }template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>constexpr bool *possibly-multipliable*() { // *exposition only*return *compatible-static-extents*<OutVec, InMat>(0, 0) &&*compatible-static-extents*<InMat, InVec>(1, 0); }template<[*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>constexpr bool *possibly-multipliable*() { // *exposition only*return *compatible-static-extents*<OutVec, InMat>(0, 1) &&*compatible-static-extents*<InMat, InVec>(0, 0); }template<[*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>constexpr bool *possibly-multipliable*() { // *exposition only*return *compatible-static-extents*<OutMat, InMat1>(0, 0) &&*compatible-static-extents*<OutMat, InMat2>(1, 1) &&*compatible-static-extents*<InMat1, InMat2>(1, 0); }
|
||
|
||
#### [29.9.7.7](#helpers.precond) Preconditions [[linalg.helpers.precond]](linalg.helpers.precond)
|
||
|
||
[1](#helpers.precond-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12529)
|
||
|
||
[*Note [1](#helpers.precond-note-1)*:
|
||
|
||
These exposition-only helper functions use
|
||
the less constraining input concepts even for the output arguments,
|
||
because the additional constraint for assignability of elements
|
||
is not necessary, and
|
||
they are sometimes used in a context
|
||
where the third argument is an input type too[.](#helpers.precond-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
constexpr bool *addable*( // *exposition only*const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in1, const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in2, const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& out) {return out.extent(0) == in1.extent(0) && out.extent(0) == in2.extent(0);}constexpr bool *addable*( // *exposition only*const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in1, const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in2, const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& out) {return out.extent(0) == in1.extent(0) && out.extent(1) == in1.extent(1) && out.extent(0) == in2.extent(0) && out.extent(1) == in2.extent(1);}constexpr bool *multipliable*( // *exposition only*const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_mat, const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_vec, const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& out_vec) {return out_vec.extent(0) == in_mat.extent(0) && in_mat.extent(1) == in_vec.extent(0);}constexpr bool *multipliable*( // *exposition only*const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_vec, const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_mat, const [*in-vector*](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& out_vec) {return out_vec.extent(0) == in_mat.extent(1) && in_mat.extent(0) == in_vec.extent(0);}constexpr bool *multipliable*( // *exposition only*const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_mat1, const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& in_mat2, const [*in-matrix*](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") auto& out_mat) {return out_mat.extent(0) == in_mat1.extent(0) && out_mat.extent(1) == in_mat2.extent(1) && in_mat1.extent(1) == in_mat2.extent(0);}
|
||
|
||
### [29.9.8](#scaled) Scaled in-place transformation [[linalg.scaled]](linalg.scaled)
|
||
|
||
#### [29.9.8.1](#scaled.intro) Introduction [[linalg.scaled.intro]](linalg.scaled.intro)
|
||
|
||
[1](#scaled.intro-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12572)
|
||
|
||
The scaled function
|
||
takes a value alpha and an mdspan x, and
|
||
returns a new read-only mdspan that represents
|
||
the elementwise product of alpha with each element of x[.](#scaled.intro-1.sentence-1)
|
||
|
||
[*Example [1](#scaled.intro-example-1)*: using Vec = mdspan<double, dextents<size_t, 1>>;
|
||
|
||
// z = alpha * x + yvoid z_equals_alpha_times_x_plus_y(double alpha, Vec x, Vec y, Vec z) { add(scaled(alpha, x), y, z);}// z = alpha * x + beta * yvoid z_equals_alpha_times_x_plus_beta_times_y(double alpha, Vec x, double beta, Vec y, Vec z) { add(scaled(alpha, x), scaled(beta, y), z);} â *end example*]
|
||
|
||
#### [29.9.8.2](#scaled.scaledaccessor) Class template scaled_accessor [[linalg.scaled.scaledaccessor]](linalg.scaled.scaledaccessor)
|
||
|
||
[1](#scaled.scaledaccessor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12596)
|
||
|
||
The class template scaled_accessor is an mdspan accessor policy
|
||
which upon access produces scaled elements[.](#scaled.scaledaccessor-1.sentence-1)
|
||
|
||
It is part of the implementation of scaled ([[linalg.scaled.scaled]](#scaled.scaled "29.9.8.3 Function template scaled"))[.](#scaled.scaledaccessor-1.sentence-2)
|
||
|
||
namespace std::linalg {template<class ScalingFactor, class NestedAccessor>class [scaled_accessor](#lib:scaled_accessor "29.9.8.2 Class template scaled_accessor [linalg.scaled.scaledaccessor]") {public:using element_type = add_const_t<decltype(declval<ScalingFactor>() * declval<NestedAccessor::element_type>())>; using reference = remove_const_t<element_type>; using data_handle_type = NestedAccessor::data_handle_type; using offset_policy = scaled_accessor<ScalingFactor, NestedAccessor::offset_policy>; constexpr scaled_accessor() = default; template<class OtherNestedAccessor>explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)constexpr scaled_accessor(const scaled_accessor<ScalingFactor,
|
||
OtherNestedAccessor>& other); constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a); constexpr reference access(data_handle_type p, size_t i) const; constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const; constexpr const ScalingFactor& scaling_factor() const noexcept { return *scaling-factor*; }constexpr const NestedAccessor& nested_accessor() const noexcept { return *nested-accessor*; }private: ScalingFactor *scaling-factor*{}; // *exposition only* NestedAccessor *nested-accessor*{}; // *exposition only*};}
|
||
|
||
[2](#scaled.scaledaccessor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12631)
|
||
|
||
*Mandates*:
|
||
|
||
- [(2.1)](#scaled.scaledaccessor-2.1)
|
||
|
||
element_type is valid and denotes a type,
|
||
|
||
- [(2.2)](#scaled.scaledaccessor-2.2)
|
||
|
||
is_copy_constructible_v<reference> is true,
|
||
|
||
- [(2.3)](#scaled.scaledaccessor-2.3)
|
||
|
||
is_reference_v<element_type> is false,
|
||
|
||
- [(2.4)](#scaled.scaledaccessor-2.4)
|
||
|
||
ScalingFactor models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]"), and
|
||
|
||
- [(2.5)](#scaled.scaledaccessor-2.5)
|
||
|
||
NestedAccessor meets the accessor policy requirements ([[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2 Requirements"))[.](#scaled.scaledaccessor-2.sentence-1)
|
||
|
||
[ð](#lib:scaled_accessor,constructor)
|
||
|
||
`template<class OtherNestedAccessor>
|
||
explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)
|
||
constexpr scaled_accessor(const scaled_accessor<ScalingFactor, OtherNestedAccessor>& other);
|
||
`
|
||
|
||
[3](#scaled.scaledaccessor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12654)
|
||
|
||
*Constraints*: is_constructible_v<NestedAccessor, const OtherNestedAccessor&> is true[.](#scaled.scaledaccessor-3.sentence-1)
|
||
|
||
[4](#scaled.scaledaccessor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12658)
|
||
|
||
*Effects*:
|
||
|
||
- [(4.1)](#scaled.scaledaccessor-4.1)
|
||
|
||
Direct-non-list-initializes *scaling-factor* with other.scaling_factor(), and
|
||
|
||
- [(4.2)](#scaled.scaledaccessor-4.2)
|
||
|
||
direct-non-list-initializes *nested-accessor* with other.nested_accessor()[.](#scaled.scaledaccessor-4.sentence-1)
|
||
|
||
[ð](#lib:scaled_accessor,constructor_)
|
||
|
||
`constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a);
|
||
`
|
||
|
||
[5](#scaled.scaledaccessor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12676)
|
||
|
||
*Effects*:
|
||
|
||
- [(5.1)](#scaled.scaledaccessor-5.1)
|
||
|
||
Direct-non-list-initializes *scaling-factor* with s, and
|
||
|
||
- [(5.2)](#scaled.scaledaccessor-5.2)
|
||
|
||
direct-non-list-initializes *nested-accessor* with a[.](#scaled.scaledaccessor-5.sentence-1)
|
||
|
||
[ð](#lib:scaled_accessor,access)
|
||
|
||
`constexpr reference access(data_handle_type p, size_t i) const;
|
||
`
|
||
|
||
[6](#scaled.scaledaccessor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12692)
|
||
|
||
*Returns*: scaling_factor() * NestedAccessor::element_type(*nested-accessor*.access(p, i))
|
||
|
||
[ð](#lib:scaled_accessor,offset)
|
||
|
||
`constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
|
||
`
|
||
|
||
[7](#scaled.scaledaccessor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12705)
|
||
|
||
*Returns*: *nested-accessor*.offset(p, i)
|
||
|
||
#### [29.9.8.3](#scaled.scaled) Function template scaled [[linalg.scaled.scaled]](linalg.scaled.scaled)
|
||
|
||
[1](#scaled.scaled-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12712)
|
||
|
||
The scaled function template takes
|
||
a scaling factor alpha and
|
||
an mdspan x, and
|
||
returns a new read-only mdspan with the same domain as x,
|
||
that represents the elementwise product of alpha with each element of x[.](#scaled.scaled-1.sentence-1)
|
||
|
||
[ð](#lib:scaled)
|
||
|
||
` template<class ScalingFactor,
|
||
class ElementType, class Extents, class Layout, class Accessor>
|
||
constexpr auto scaled(ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x);
|
||
`
|
||
|
||
[2](#scaled.scaled-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12728)
|
||
|
||
Let SA be scaled_accessor<ScalingFactor, Accessor>[.](#scaled.scaled-2.sentence-1)
|
||
|
||
[3](#scaled.scaled-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12731)
|
||
|
||
*Returns*: mdspan<typename SA::element_type, Extents, Layout, SA>(x.data_handle(), x.mapping(),
|
||
SA(alpha, x.accessor()))
|
||
|
||
[4](#scaled.scaled-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12739)
|
||
|
||
[*Example [1](#scaled.scaled-example-1)*: void test_scaled(mdspan<double, extents<int, 10>> x){auto x_scaled = scaled(5.0, x); for (int i = 0; i < x.extent(0); ++i) { assert(x_scaled[i] == 5.0 * x[i]); }} â *end example*]
|
||
|
||
### [29.9.9](#conj) Conjugated in-place transformation [[linalg.conj]](linalg.conj)
|
||
|
||
#### [29.9.9.1](#conj.intro) Introduction [[linalg.conj.intro]](linalg.conj.intro)
|
||
|
||
[1](#conj.intro-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12756)
|
||
|
||
The conjugated function takes an mdspan x,
|
||
and returns a new read-only mdspan y with the same domain as x,
|
||
whose elements are the complex conjugates
|
||
of the corresponding elements of x[.](#conj.intro-1.sentence-1)
|
||
|
||
#### [29.9.9.2](#conj.conjugatedaccessor) Class template conjugated_accessor [[linalg.conj.conjugatedaccessor]](linalg.conj.conjugatedaccessor)
|
||
|
||
[1](#conj.conjugatedaccessor-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12765)
|
||
|
||
The class template conjugated_accessor is an mdspan accessor policy
|
||
which upon access produces conjugate elements[.](#conj.conjugatedaccessor-1.sentence-1)
|
||
|
||
It is part of the implementation ofconjugated ([[linalg.conj.conjugated]](#conj.conjugated "29.9.9.3 Function template conjugated"))[.](#conj.conjugatedaccessor-1.sentence-2)
|
||
|
||
namespace std::linalg {template<class NestedAccessor>class [conjugated_accessor](#lib:conjugated_accessor "29.9.9.2 Class template conjugated_accessor [linalg.conj.conjugatedaccessor]") {public:using element_type = add_const_t<decltype(*conj-if-needed*(declval<NestedAccessor::element_type>()))>; using reference = remove_const_t<element_type>; using data_handle_type = typename NestedAccessor::data_handle_type; using offset_policy = conjugated_accessor<NestedAccessor::offset_policy>; constexpr conjugated_accessor() = default; template<class OtherNestedAccessor>explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>>)constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other); constexpr reference access(data_handle_type p, size_t i) const; constexpr typename offset_policy::data_handle_type
|
||
offset(data_handle_type p, size_t i) const; constexpr const NestedAccessor& nested_accessor() const noexcept { return *nested-accessor_*; }private: NestedAccessor *nested-accessor_*{}; // *exposition only*};}
|
||
|
||
[2](#conj.conjugatedaccessor-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12801)
|
||
|
||
*Mandates*:
|
||
|
||
- [(2.1)](#conj.conjugatedaccessor-2.1)
|
||
|
||
element_type is valid and denotes a type,
|
||
|
||
- [(2.2)](#conj.conjugatedaccessor-2.2)
|
||
|
||
is_copy_constructible_v<reference> is true,
|
||
|
||
- [(2.3)](#conj.conjugatedaccessor-2.3)
|
||
|
||
is_reference_v<element_type> is false, and
|
||
|
||
- [(2.4)](#conj.conjugatedaccessor-2.4)
|
||
|
||
NestedAccessor meets the accessor policy requirements ([[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2 Requirements"))[.](#conj.conjugatedaccessor-2.sentence-1)
|
||
|
||
[ð](#lib:conjugated_accessor,constructor)
|
||
|
||
`constexpr conjugated_accessor(const NestedAccessor& acc);
|
||
`
|
||
|
||
[3](#conj.conjugatedaccessor-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12820)
|
||
|
||
*Effects*: Direct-non-list-initializes*nested-accessor_* with acc[.](#conj.conjugatedaccessor-3.sentence-1)
|
||
|
||
[ð](#lib:conjugated_accessor,constructor_)
|
||
|
||
`template<class OtherNestedAccessor>
|
||
explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>>)
|
||
constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other);
|
||
`
|
||
|
||
[4](#conj.conjugatedaccessor-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12834)
|
||
|
||
*Constraints*: is_constructible_v<NestedAccessor, const OtherNestedAccessor&> is true[.](#conj.conjugatedaccessor-4.sentence-1)
|
||
|
||
[5](#conj.conjugatedaccessor-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12839)
|
||
|
||
*Effects*: Direct-non-list-initializes *nested-accessor_* with other.nested_accessor()[.](#conj.conjugatedaccessor-5.sentence-1)
|
||
|
||
[ð](#lib:conjugated_accessor,access)
|
||
|
||
`constexpr reference access(data_handle_type p, size_t i) const;
|
||
`
|
||
|
||
[6](#conj.conjugatedaccessor-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12851)
|
||
|
||
*Returns*: *conj-if-needed*(NestedAccessor::element_type(*nested-accessor_*.access(p, i)))
|
||
|
||
[ð](#lib:conjugated_accessor,offset)
|
||
|
||
`constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
|
||
`
|
||
|
||
[7](#conj.conjugatedaccessor-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12862)
|
||
|
||
*Returns*: *nested-accessor_*.offset(p, i)
|
||
|
||
#### [29.9.9.3](#conj.conjugated) Function template conjugated [[linalg.conj.conjugated]](linalg.conj.conjugated)
|
||
|
||
[ð](#conj.conjugated-itemdecl:1)
|
||
|
||
` template<class ElementType, class Extents, class Layout, class Accessor>
|
||
constexpr auto [conjugated](#lib:conjugated "29.9.9.3 Function template conjugated [linalg.conj.conjugated]")(mdspan<ElementType, Extents, Layout, Accessor> a);
|
||
`
|
||
|
||
[1](#conj.conjugated-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12875)
|
||
|
||
Let A be
|
||
|
||
- [(1.1)](#conj.conjugated-1.1)
|
||
|
||
remove_cvref_t<decltype(a.accessor().nested_accessor())> if Accessor is a specialization of conjugated_accessor;
|
||
|
||
- [(1.2)](#conj.conjugated-1.2)
|
||
|
||
otherwise,Accessor if remove_cvref_t<ElementType> is an arithmetic type;
|
||
|
||
- [(1.3)](#conj.conjugated-1.3)
|
||
|
||
otherwise,conjugated_accessor<Accessor> if the expression conj(E) is valid for any subexpression E whose type is remove_cvref_t<ElementType> with overload resolution performed in a context that includes the declarationtemplate<class U> U conj(const U&) = delete;;
|
||
|
||
- [(1.4)](#conj.conjugated-1.4)
|
||
|
||
otherwise,Accessor[.](#conj.conjugated-1.sentence-1)
|
||
|
||
[2](#conj.conjugated-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12896)
|
||
|
||
*Returns*: Let MD be mdspan<typename A::element_type, Extents, Layout, A>[.](#conj.conjugated-2.sentence-1)
|
||
|
||
- [(2.1)](#conj.conjugated-2.1)
|
||
|
||
MD(a.data_handle(), a.mapping(), a.accessor().nested_accessor()) if Accessor is a
|
||
specialization of conjugated_accessor;
|
||
|
||
- [(2.2)](#conj.conjugated-2.2)
|
||
|
||
otherwise,a, if is_same_v<A, Accessor> is true;
|
||
|
||
- [(2.3)](#conj.conjugated-2.3)
|
||
|
||
otherwise,MD(a.data_handle(), a.mapping(), conjugated_accessor(a.accessor())).
|
||
|
||
[3](#conj.conjugated-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12912)
|
||
|
||
[*Example [1](#conj.conjugated-example-1)*: void test_conjugated_complex(mdspan<complex<double>, extents<int, 10>> a) {auto a_conj = conjugated(a); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj[i] == conj(a[i]); }auto a_conj_conj = conjugated(a_conj); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj_conj[i] == a[i]); }}void test_conjugated_real(mdspan<double, extents<int, 10>> a) {auto a_conj = conjugated(a); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj[i] == a[i]); }auto a_conj_conj = conjugated(a_conj); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj_conj[i] == a[i]); }} â *end example*]
|
||
|
||
### [29.9.10](#transp) Transpose in-place transformation [[linalg.transp]](linalg.transp)
|
||
|
||
#### [29.9.10.1](#transp.intro) Introduction [[linalg.transp.intro]](linalg.transp.intro)
|
||
|
||
[1](#transp.intro-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12943)
|
||
|
||
layout_transpose is an mdspan layout mapping policy
|
||
that swaps the two indices, extents, and strides
|
||
of any unique mdspan layout mapping policy[.](#transp.intro-1.sentence-1)
|
||
|
||
[2](#transp.intro-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12948)
|
||
|
||
The transposed function takes an mdspan representing a matrix, and returns a new mdspan representing the transpose of the input matrix[.](#transp.intro-2.sentence-1)
|
||
|
||
#### [29.9.10.2](#transp.helpers) Exposition-only helpers for layout_transpose and transposed [[linalg.transp.helpers]](linalg.transp.helpers)
|
||
|
||
[1](#transp.helpers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12955)
|
||
|
||
The exposition-only *transpose-extents* function
|
||
takes an extents object representing the extents of a matrix,
|
||
and returns a new extents object
|
||
representing the extents of the transpose of the matrix[.](#transp.helpers-1.sentence-1)
|
||
|
||
[2](#transp.helpers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12961)
|
||
|
||
The exposition-only alias template*transpose-extents-t*<InputExtents> gives the type of *transpose-extents*(e) for a given extents object e of type InputExtents[.](#transp.helpers-2.sentence-1)
|
||
|
||
[ð](#transp.helpers-itemdecl:1)
|
||
|
||
`template<class IndexType, size_t InputExtent0, size_t InputExtent1>
|
||
constexpr extents<IndexType, InputExtent1, InputExtent0>
|
||
transpose-extents(const extents<IndexType, InputExtent0, InputExtent1>& in); // exposition only
|
||
`
|
||
|
||
[3](#transp.helpers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12973)
|
||
|
||
*Returns*: extents<IndexType, InputExtent1, InputExtent0>(in.extent(1), in.extent(0))
|
||
|
||
template<class InputExtents>using *transpose-extents-t* =decltype(*transpose-extents*(declval<InputExtents>())); // *exposition only*
|
||
|
||
#### [29.9.10.3](#transp.layout.transpose) Class template layout_transpose [[linalg.transp.layout.transpose]](linalg.transp.layout.transpose)
|
||
|
||
[1](#transp.layout.transpose-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L12986)
|
||
|
||
layout_transpose is an mdspan layout mapping policy
|
||
that swaps the two indices, extents, and strides
|
||
of any mdspan layout mapping policy[.](#transp.layout.transpose-1.sentence-1)
|
||
|
||
namespace std::linalg {template<class Layout>class [layout_transpose](#lib:layout_transpose "29.9.10.3 Class template layout_transpose [linalg.transp.layout.transpose]") {public:using nested_layout_type = Layout; template<class Extents>struct mapping {private:using *nested-mapping-type* =typename Layout::template mapping<*transpose-extents-t*<Extents>>; // *exposition only*public:using extents_type = Extents; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using layout_type = layout_transpose; constexpr explicit mapping(const *nested-mapping-type*&); constexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const{ return *nested-mapping_*.required_span_size(); template<class Index0, class Index1>constexpr index_type operator()(Index0 ind0, Index1 ind1) const{ return *nested-mapping_*(ind1, ind0); }constexpr const *nested-mapping-type*& nested_mapping() const noexcept{ return *nested-mapping_*; }static constexpr bool is_always_unique() noexcept{ return *nested-mapping-type*::is_always_unique(); }static constexpr bool is_always_exhaustive() noexcept{ return *nested-mapping-type*::is_always_exhaustive(); }static constexpr bool is_always_strided() noexcept{ return *nested-mapping-type*::is_always_strided(); }constexpr bool is_unique() const { return *nested-mapping_*.is_unique(); }constexpr bool is_exhaustive() const { return *nested-mapping_*.is_exhaustive(); }constexpr bool is_strided() const { return *nested-mapping_*.is_strided(); }constexpr index_type stride(size_t r) const; template<class OtherExtents>friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y); }; private:*nested-mapping-type* *nested-mapping_*; // *exposition only* extents_type *extents_*; // *exposition only*};}
|
||
|
||
[2](#transp.layout.transpose-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13049)
|
||
|
||
Layout shall meet
|
||
the layout mapping policy requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#transp.layout.transpose-2.sentence-1)
|
||
|
||
[3](#transp.layout.transpose-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13053)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#transp.layout.transpose-3.1)
|
||
|
||
Extents is a specialization of std::extents, and
|
||
|
||
- [(3.2)](#transp.layout.transpose-3.2)
|
||
|
||
Extents::rank() equals 2[.](#transp.layout.transpose-3.sentence-1)
|
||
|
||
[ð](#lib:layout_transpose::mapping,constructor)
|
||
|
||
`constexpr explicit mapping(const nested-mapping-type& map);
|
||
`
|
||
|
||
[4](#transp.layout.transpose-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13068)
|
||
|
||
*Effects*:
|
||
|
||
- [(4.1)](#transp.layout.transpose-4.1)
|
||
|
||
Initializes *nested-mapping_* with map, and
|
||
|
||
- [(4.2)](#transp.layout.transpose-4.2)
|
||
|
||
initializes *extents_* with *transpose-extents*(map.extents())[.](#transp.layout.transpose-4.sentence-1)
|
||
|
||
[ð](#lib:layout_transpose::mapping,stride)
|
||
|
||
`constexpr index_type stride(size_t r) const;
|
||
`
|
||
|
||
[5](#transp.layout.transpose-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13085)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(5.1)](#transp.layout.transpose-5.1)
|
||
|
||
is_strided() is true, and
|
||
|
||
- [(5.2)](#transp.layout.transpose-5.2)
|
||
|
||
r < 2 is true[.](#transp.layout.transpose-5.sentence-1)
|
||
|
||
[6](#transp.layout.transpose-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13094)
|
||
|
||
*Returns*: *nested-mapping_*.stride(r == 0 ? 1 : 0)
|
||
|
||
[ð](#lib:layout_transpose::mapping,operator==)
|
||
|
||
`template<class OtherExtents>
|
||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y);
|
||
`
|
||
|
||
[7](#transp.layout.transpose-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13106)
|
||
|
||
*Constraints*: The expressionx.*nested-mapping_* == y.*nested-mapping_* is well-formed and its result is convertible to bool[.](#transp.layout.transpose-7.sentence-1)
|
||
|
||
[8](#transp.layout.transpose-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13112)
|
||
|
||
*Returns*: x.*nested-mapping_* == y.*nested-mapping_*[.](#transp.layout.transpose-8.sentence-1)
|
||
|
||
#### [29.9.10.4](#transp.transposed) Function template transposed [[linalg.transp.transposed]](linalg.transp.transposed)
|
||
|
||
[1](#transp.transposed-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13119)
|
||
|
||
The transposed function
|
||
takes a rank-2 mdspan representing a matrix, and
|
||
returns a new mdspan representing the input matrix's transpose[.](#transp.transposed-1.sentence-1)
|
||
|
||
The input matrix's data are not modified, and
|
||
the returned mdspan accesses the input matrix's data in place[.](#transp.transposed-1.sentence-2)
|
||
|
||
[ð](#lib:transposed)
|
||
|
||
` template<class ElementType, class Extents, class Layout, class Accessor>
|
||
constexpr auto transposed(mdspan<ElementType, Extents, Layout, Accessor> a);
|
||
`
|
||
|
||
[2](#transp.transposed-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13132)
|
||
|
||
*Mandates*: Extents::rank() == 2 is true[.](#transp.transposed-2.sentence-1)
|
||
|
||
[3](#transp.transposed-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13136)
|
||
|
||
Let ReturnExtents be*transpose-extents-t*<Extents>[.](#transp.transposed-3.sentence-1)
|
||
|
||
Let R bemdspan<ElementType, ReturnExtents, ReturnLayout, Accessor>,
|
||
where ReturnLayout is:
|
||
|
||
- [(3.1)](#transp.transposed-3.1)
|
||
|
||
layout_right if Layout is layout_left;
|
||
|
||
- [(3.2)](#transp.transposed-3.2)
|
||
|
||
otherwise, layout_left if Layout is layout_right;
|
||
|
||
- [(3.3)](#transp.transposed-3.3)
|
||
|
||
otherwise, layout_right_padded<PaddingValue> if Layout is
|
||
layout_left_padded<PaddingValue> for some size_t value PaddingValue;
|
||
|
||
- [(3.4)](#transp.transposed-3.4)
|
||
|
||
otherwise, layout_left_padded<PaddingValue> if Layout is
|
||
layout_right_padded<PaddingValue> for some size_t value PaddingValue;
|
||
|
||
- [(3.5)](#transp.transposed-3.5)
|
||
|
||
otherwise, layout_stride if Layout is layout_stride;
|
||
|
||
- [(3.6)](#transp.transposed-3.6)
|
||
|
||
otherwise,layout_blas_packed<OppositeTriangle, OppositeStorageOrder>,
|
||
if Layout is
|
||
layout_blas_packed<Triangle, StorageOrder> for some Triangle and StorageOrder, where
|
||
* [(3.6.1)](#transp.transposed-3.6.1)
|
||
|
||
OppositeTriangle isconditional_t<is_same_v<Triangle, upper_triangle_t>,
|
||
lower_triangle_t, upper_triangle_t> and
|
||
|
||
* [(3.6.2)](#transp.transposed-3.6.2)
|
||
|
||
OppositeStorageOrder isconditional_t<is_same_v<StorageOrder, column_major_t>, row_major_t, column_major_t>
|
||
|
||
- [(3.7)](#transp.transposed-3.7)
|
||
|
||
otherwise, NestedLayout if Layout is layout_transpose<NestedLayout> for some NestedLayout;
|
||
|
||
- [(3.8)](#transp.transposed-3.8)
|
||
|
||
otherwise, layout_transpose<Layout>[.](#transp.transposed-3.sentence-2)
|
||
|
||
[4](#transp.transposed-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13185)
|
||
|
||
*Returns*: With ReturnMapping being
|
||
the type typename ReturnLayout::template mapping<ReturnExtents>:
|
||
|
||
- [(4.1)](#transp.transposed-4.1)
|
||
|
||
if Layout is layout_left, layout_right, or
|
||
a specialization of layout_blas_packed,R(a.data_handle(), ReturnMapping(*transpose-extents*(a.mapping().extents())),
|
||
a.accessor())
|
||
|
||
- [(4.2)](#transp.transposed-4.2)
|
||
|
||
otherwise,R(a.data_handle(), ReturnMapping(*transpose-extents*(a.mapping().extents()),
|
||
a.mapping().stride(1)), a.accessor()) if Layout is layout_left_padded<PaddingValue> for some size_t value PaddingValue;
|
||
|
||
- [(4.3)](#transp.transposed-4.3)
|
||
|
||
otherwise,R(a.data_handle(), ReturnMapping(*transpose-extents*(a.mapping().extents()),
|
||
a.mapping().stride(0)), a.accessor()) if Layout is layout_right_padded<PaddingValue> for some size_t value PaddingValue;
|
||
|
||
- [(4.4)](#transp.transposed-4.4)
|
||
|
||
otherwise, if Layout is layout_stride,R(a.data_handle(), ReturnMapping(*transpose-extents*(a.mapping().extents()),
|
||
array{a.mapping().stride(1), a.mapping().stride(0)}), a.accessor())
|
||
|
||
- [(4.5)](#transp.transposed-4.5)
|
||
|
||
otherwise, if Layout is a specialization of layout_transpose,R(a.data_handle(), a.mapping().nested_mapping(), a.accessor())
|
||
|
||
- [(4.6)](#transp.transposed-4.6)
|
||
|
||
otherwise,R(a.data_handle(), ReturnMapping(a.mapping()), a.accessor())
|
||
|
||
[5](#transp.transposed-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13232)
|
||
|
||
[*Example [1](#transp.transposed-example-1)*: void test_transposed(mdspan<double, extents<size_t, 3, 4>> a) {const auto num_rows = a.extent(0); const auto num_cols = a.extent(1); auto a_t = transposed(a);
|
||
assert(num_rows == a_t.extent(1));
|
||
assert(num_cols == a_t.extent(0));
|
||
assert(a.stride(0) == a_t.stride(1));
|
||
assert(a.stride(1) == a_t.stride(0)); for (size_t row = 0; row < num_rows; ++row) {for (size_t col = 0; col < num_rows; ++col) { assert(a[row, col] == a_t[col, row]); }}auto a_t_t = transposed(a_t);
|
||
assert(num_rows == a_t_t.extent(0));
|
||
assert(num_cols == a_t_t.extent(1));
|
||
assert(a.stride(0) == a_t_t.stride(0));
|
||
assert(a.stride(1) == a_t_t.stride(1)); for (size_t row = 0; row < num_rows; ++row) {for (size_t col = 0; col < num_rows; ++col) { assert(a[row, col] == a_t_t[row, col]); }}} â *end example*]
|
||
|
||
### [29.9.11](#conjtransposed) Conjugate transpose in-place transform [[linalg.conjtransposed]](linalg.conjtransposed)
|
||
|
||
[1](#conjtransposed-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13268)
|
||
|
||
The conjugate_transposed function
|
||
returns a conjugate transpose view of an object[.](#conjtransposed-1.sentence-1)
|
||
|
||
This combines the effects of transposed and conjugated[.](#conjtransposed-1.sentence-2)
|
||
|
||
[ð](#lib:conjugate_transposed)
|
||
|
||
` template<class ElementType, class Extents, class Layout, class Accessor>
|
||
constexpr auto conjugate_transposed(mdspan<ElementType, Extents, Layout, Accessor> a);
|
||
`
|
||
|
||
[2](#conjtransposed-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13279)
|
||
|
||
*Effects*: Equivalent to: return conjugated(transposed(a));
|
||
|
||
[3](#conjtransposed-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13284)
|
||
|
||
[*Example [1](#conjtransposed-example-1)*: void test_conjugate_transposed(mdspan<complex<double>, extents<size_t, 3, 4>> a) {const auto num_rows = a.extent(0); const auto num_cols = a.extent(1); auto a_ct = conjugate_transposed(a);
|
||
assert(num_rows == a_ct.extent(1));
|
||
assert(num_cols == a_ct.extent(0));
|
||
assert(a.stride(0) == a_ct.stride(1));
|
||
assert(a.stride(1) == a_ct.stride(0)); for (size_t row = 0; row < num_rows; ++row) {for (size_t col = 0; col < num_rows; ++col) { assert(a[row, col] == conj(a_ct[col, row])); }}auto a_ct_ct = conjugate_transposed(a_ct);
|
||
assert(num_rows == a_ct_ct.extent(0));
|
||
assert(num_cols == a_ct_ct.extent(1));
|
||
assert(a.stride(0) == a_ct_ct.stride(0));
|
||
assert(a.stride(1) == a_ct_ct.stride(1)); for (size_t row = 0; row < num_rows; ++row) {for (size_t col = 0; col < num_rows; ++col) { assert(a[row, col] == a_ct_ct[row, col]);
|
||
assert(conj(a_ct[col, row]) == a_ct_ct[row, col]); }}} â *end example*]
|
||
|
||
### [29.9.12](#algs.reqs) Algorithm requirements based on template parameter name [[linalg.algs.reqs]](linalg.algs.reqs)
|
||
|
||
[1](#algs.reqs-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13321)
|
||
|
||
Throughout[[linalg.algs.blas1]](#algs.blas1 "29.9.13 BLAS 1 algorithms"), [[linalg.algs.blas2]](#algs.blas2 "29.9.14 BLAS 2 algorithms"), and [[linalg.algs.blas3]](#algs.blas3 "29.9.15 BLAS 3 algorithms"),
|
||
where the template parameters are not constrained,
|
||
the names of template parameters are used to express the following constraints[.](#algs.reqs-1.sentence-1)
|
||
|
||
- [(1.1)](#algs.reqs-1.1)
|
||
|
||
is_execution_policy<ExecutionPolicy>::value is true ([[execpol.type]](execpol.type "26.3.6.2 Execution policy type trait"))[.](#algs.reqs-1.1.sentence-1)
|
||
|
||
- [(1.2)](#algs.reqs-1.2)
|
||
|
||
Real is any type such that complex<Real> is
|
||
specified ([[complex.numbers.general]](complex.numbers.general "29.4.1 General"))[.](#algs.reqs-1.2.sentence-1)
|
||
|
||
- [(1.3)](#algs.reqs-1.3)
|
||
|
||
Triangle is either upper_triangle_t or lower_triangle_t[.](#algs.reqs-1.3.sentence-1)
|
||
|
||
- [(1.4)](#algs.reqs-1.4)
|
||
|
||
DiagonalStorage is
|
||
either implicit_unit_diagonal_t or explicit_diagonal_t[.](#algs.reqs-1.4.sentence-1)
|
||
|
||
[*Note [1](#algs.reqs-note-1)*:
|
||
|
||
Function templates that have a template parameter named ExecutionPolicy are parallel algorithms ([[algorithms.parallel.defns]](algorithms.parallel.defns "26.3.1 Preamble"))[.](#algs.reqs-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [29.9.13](#algs.blas1) BLAS 1 algorithms [[linalg.algs.blas1]](linalg.algs.blas1)
|
||
|
||
#### [29.9.13.1](#algs.blas1.complexity) Complexity [[linalg.algs.blas1.complexity]](linalg.algs.blas1.complexity)
|
||
|
||
[1](#algs.blas1.complexity-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13348)
|
||
|
||
*Complexity*: All algorithms in [[linalg.algs.blas1]](#algs.blas1 "29.9.13 BLAS 1 algorithms") with mdspan parameters
|
||
perform a count of mdspan array accesses
|
||
and arithmetic operations that is linear in
|
||
the maximum product of extents of any mdspan parameter[.](#algs.blas1.complexity-1.sentence-1)
|
||
|
||
#### [29.9.13.2](#algs.blas1.givens) Givens rotations [[linalg.algs.blas1.givens]](linalg.algs.blas1.givens)
|
||
|
||
#### [29.9.13.2.1](#algs.blas1.givens.lartg) Compute Givens rotation [[linalg.algs.blas1.givens.lartg]](linalg.algs.blas1.givens.lartg)
|
||
|
||
[ð](#lib:setup_givens_rotation)
|
||
|
||
`template<class Real>
|
||
setup_givens_rotation_result<Real> setup_givens_rotation(Real a, Real b) noexcept;
|
||
|
||
template<class Real>
|
||
setup_givens_rotation_result<complex<Real>>
|
||
setup_givens_rotation(complex<Real> a, complex<Real> b) noexcept;
|
||
`
|
||
|
||
[1](#algs.blas1.givens.lartg-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13370)
|
||
|
||
These functions compute the Givens plane rotation
|
||
represented by the two values c and s such that the 2 x 2 system of equations
|
||
[cs⯯¯sc]â[ab]=[r0]
|
||
|
||
holds, where c is always a real scalar, and c2+|s|2=1[.](#algs.blas1.givens.lartg-1.sentence-2)
|
||
|
||
That is, c and s represent a 2 x 2 matrix,
|
||
that when multiplied by the right by the input vector
|
||
whose components are a and b,
|
||
produces a result vector
|
||
whose first component r is the Euclidean norm of the input vector, and
|
||
whose second component is zero[.](#algs.blas1.givens.lartg-1.sentence-3)
|
||
|
||
[*Note [1](#algs.blas1.givens.lartg-note-1)*:
|
||
|
||
These functions correspond to the LAPACK function xLARTG[[bib]](bibliography#bib:lapack "Bibliography")[.](#algs.blas1.givens.lartg-1.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.givens.lartg-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13402)
|
||
|
||
*Returns*: c, s, r,
|
||
where c and s form the Givens plane rotation
|
||
corresponding to the input a and b,
|
||
and r is the Euclidean norm of the two-component vector
|
||
formed by a and b[.](#algs.blas1.givens.lartg-2.sentence-1)
|
||
|
||
#### [29.9.13.2.2](#algs.blas1.givens.rot) Apply a computed Givens rotation to vectors [[linalg.algs.blas1.givens.rot]](linalg.algs.blas1.givens.rot)
|
||
|
||
[ð](#lib:apply_givens_rotation)
|
||
|
||
`template<[inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>
|
||
void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, Real s);
|
||
template<class ExecutionPolicy, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>
|
||
void apply_givens_rotation(ExecutionPolicy&& exec,
|
||
InOutVec1 x, InOutVec2 y, Real c, Real s);
|
||
template<[inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>
|
||
void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, complex<Real> s);
|
||
template<class ExecutionPolicy, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec1, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec2, class Real>
|
||
void apply_givens_rotation(ExecutionPolicy&& exec,
|
||
InOutVec1 x, InOutVec2 y, Real c, complex<Real> s);
|
||
`
|
||
|
||
[1](#algs.blas1.givens.rot-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13428)
|
||
|
||
[*Note [1](#algs.blas1.givens.rot-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xROT[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.givens.rot-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.givens.rot-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13433)
|
||
|
||
*Mandates*: *compatible-static-extents*<InOutVec1, InOutVec2>(0, 0) is true[.](#algs.blas1.givens.rot-2.sentence-1)
|
||
|
||
[3](#algs.blas1.givens.rot-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13437)
|
||
|
||
*Preconditions*: x.extent(0) equals y.extent(0)[.](#algs.blas1.givens.rot-3.sentence-1)
|
||
|
||
[4](#algs.blas1.givens.rot-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13441)
|
||
|
||
*Effects*: Applies the plane rotation
|
||
specified by c and s to
|
||
the input vectors x and y,
|
||
as if the rotation were a 2 x 2 matrix and
|
||
the input vectors were successive rows of a matrix with two rows[.](#algs.blas1.givens.rot-4.sentence-1)
|
||
|
||
#### [29.9.13.3](#algs.blas1.swap) Swap matrix or vector elements [[linalg.algs.blas1.swap]](linalg.algs.blas1.swap)
|
||
|
||
[ð](#lib:swap_elements)
|
||
|
||
`template<[inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj1, [inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj2>
|
||
void swap_elements(InOutObj1 x, InOutObj2 y);
|
||
template<class ExecutionPolicy, [inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj1, [inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj2>
|
||
void swap_elements(ExecutionPolicy&& exec, InOutObj1 x, InOutObj2 y);
|
||
`
|
||
|
||
[1](#algs.blas1.swap-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13461)
|
||
|
||
[*Note [1](#algs.blas1.swap-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xSWAP[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.swap-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.swap-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13466)
|
||
|
||
*Constraints*: x.rank() equals y.rank()[.](#algs.blas1.swap-2.sentence-1)
|
||
|
||
[3](#algs.blas1.swap-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13470)
|
||
|
||
*Mandates*: For all r in the range [0, x.rank()),*compatible-static-extents*<InOutObj1, InOutObj2>(r, r) is true[.](#algs.blas1.swap-3.sentence-1)
|
||
|
||
[4](#algs.blas1.swap-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13478)
|
||
|
||
*Preconditions*: x.extents() equals y.extents()[.](#algs.blas1.swap-4.sentence-1)
|
||
|
||
[5](#algs.blas1.swap-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13482)
|
||
|
||
*Effects*: Swaps all corresponding elements of x and y[.](#algs.blas1.swap-5.sentence-1)
|
||
|
||
#### [29.9.13.4](#algs.blas1.scal) Multiply the elements of an object in place by a scalar [[linalg.algs.blas1.scal]](linalg.algs.blas1.scal)
|
||
|
||
[ð](#lib:scale)
|
||
|
||
`template<class Scalar, [inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj>
|
||
void scale(Scalar alpha, InOutObj x);
|
||
template<class ExecutionPolicy, class Scalar, [inout-object](#concept:inout-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutObj>
|
||
void scale(ExecutionPolicy&& exec, Scalar alpha, InOutObj x);
|
||
`
|
||
|
||
[1](#algs.blas1.scal-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13498)
|
||
|
||
[*Note [1](#algs.blas1.scal-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xSCAL[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.scal-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.scal-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13503)
|
||
|
||
*Effects*: Overwrites x with the result of
|
||
computing the elementwise multiplication αx,
|
||
where the scalar α is alpha[.](#algs.blas1.scal-2.sentence-1)
|
||
|
||
#### [29.9.13.5](#algs.blas1.copy) Copy elements of one matrix or vector into another [[linalg.algs.blas1.copy]](linalg.algs.blas1.copy)
|
||
|
||
[ð](#lib:copy)
|
||
|
||
`template<[in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj, [out-object](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>
|
||
void copy(InObj x, OutObj y);
|
||
template<class ExecutionPolicy, [in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj, [out-object](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>
|
||
void copy(ExecutionPolicy&& exec, InObj x, OutObj y);
|
||
`
|
||
|
||
[1](#algs.blas1.copy-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13521)
|
||
|
||
[*Note [1](#algs.blas1.copy-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xCOPY[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.copy-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.copy-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13526)
|
||
|
||
*Constraints*: x.rank() equals y.rank()[.](#algs.blas1.copy-2.sentence-1)
|
||
|
||
[3](#algs.blas1.copy-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13530)
|
||
|
||
*Mandates*: For all r in the range [0,x.rank()),*compatible-static-extents*<InObj, OutObj>(r, r) is true[.](#algs.blas1.copy-3.sentence-1)
|
||
|
||
[4](#algs.blas1.copy-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13538)
|
||
|
||
*Preconditions*: x.extents() equals y.extents()[.](#algs.blas1.copy-4.sentence-1)
|
||
|
||
[5](#algs.blas1.copy-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13542)
|
||
|
||
*Effects*: Assigns each element of x to the corresponding element of y[.](#algs.blas1.copy-5.sentence-1)
|
||
|
||
#### [29.9.13.6](#algs.blas1.add) Add vectors or matrices elementwise [[linalg.algs.blas1.add]](linalg.algs.blas1.add)
|
||
|
||
[ð](#lib:add)
|
||
|
||
`template<[in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj1, [in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj2, [out-object](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>
|
||
void add(InObj1 x, InObj2 y, OutObj z);
|
||
template<class ExecutionPolicy, [in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj1, [in-object](#concept:in-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InObj2, [out-object](#concept:out-object "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutObj>
|
||
void add(ExecutionPolicy&& exec,
|
||
InObj1 x, InObj2 y, OutObj z);
|
||
`
|
||
|
||
[1](#algs.blas1.add-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13559)
|
||
|
||
[*Note [1](#algs.blas1.add-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xAXPY[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.add-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.add-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13564)
|
||
|
||
*Constraints*: x.rank(), y.rank(), and z.rank() are all equal[.](#algs.blas1.add-2.sentence-1)
|
||
|
||
[3](#algs.blas1.add-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13568)
|
||
|
||
*Mandates*: *possibly-addable*<InObj1, InObj2, OutObj>() is true[.](#algs.blas1.add-3.sentence-1)
|
||
|
||
[4](#algs.blas1.add-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13572)
|
||
|
||
*Preconditions*: *addable*(x,y,z) is true[.](#algs.blas1.add-4.sentence-1)
|
||
|
||
[5](#algs.blas1.add-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13576)
|
||
|
||
*Effects*: Computes z=x+y[.](#algs.blas1.add-5.sentence-1)
|
||
|
||
[6](#algs.blas1.add-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13580)
|
||
|
||
*Remarks*: z may alias x or y[.](#algs.blas1.add-6.sentence-1)
|
||
|
||
#### [29.9.13.7](#algs.blas1.dot) Dot product of two vectors [[linalg.algs.blas1.dot]](linalg.algs.blas1.dot)
|
||
|
||
[1](#algs.blas1.dot-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13587)
|
||
|
||
[*Note [1](#algs.blas1.dot-note-1)*:
|
||
|
||
The functions in this section correspond to the BLAS
|
||
functions xDOT, xDOTU, and xDOTC[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.dot-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.dot-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13593)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas1.dot]](#algs.blas1.dot "29.9.13.7 Dot product of two vectors")[.](#algs.blas1.dot-2.sentence-1)
|
||
|
||
[3](#algs.blas1.dot-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13596)
|
||
|
||
*Mandates*: *compatible-static-extents*<InVec1, InVec2>(0, 0) is true[.](#algs.blas1.dot-3.sentence-1)
|
||
|
||
[4](#algs.blas1.dot-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13600)
|
||
|
||
*Preconditions*: v1.extent(0) equals v2.extent(0)[.](#algs.blas1.dot-4.sentence-1)
|
||
|
||
[ð](#lib:dot)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar>
|
||
Scalar dot(InVec1 v1, InVec2 v2, Scalar init);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar>
|
||
Scalar dot(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2, Scalar init);
|
||
`
|
||
|
||
[5](#algs.blas1.dot-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13614)
|
||
|
||
These functions compute a non-conjugated dot product
|
||
with an explicitly specified result type[.](#algs.blas1.dot-5.sentence-1)
|
||
|
||
[6](#algs.blas1.dot-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13618)
|
||
|
||
*Returns*: Let N be v1.extent(0)[.](#algs.blas1.dot-6.sentence-1)
|
||
|
||
- [(6.1)](#algs.blas1.dot-6.1)
|
||
|
||
init if N is zero;
|
||
|
||
- [(6.2)](#algs.blas1.dot-6.2)
|
||
|
||
otherwise,*GENERALIZED_SUM*(plus<>(), init, v1[0]*v2[0], …, v1[N-1]*v2[N-1]).
|
||
|
||
[7](#algs.blas1.dot-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13629)
|
||
|
||
*Remarks*: If InVec1::value_type, InVec2::value_type, and Scalar are all floating-point types or specializations of complex,
|
||
and if Scalar has higher precision
|
||
than InVec1::value_type or InVec2::value_type,
|
||
then intermediate terms in the sum use Scalar's precision or greater[.](#algs.blas1.dot-7.sentence-1)
|
||
|
||
[ð](#lib:dot_)
|
||
|
||
` template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>
|
||
auto dot(InVec1 v1, InVec2 v2);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>
|
||
auto dot(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2);
|
||
`
|
||
|
||
[8](#algs.blas1.dot-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13648)
|
||
|
||
These functions compute a non-conjugated dot product with a default result type[.](#algs.blas1.dot-8.sentence-1)
|
||
|
||
[9](#algs.blas1.dot-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13651)
|
||
|
||
*Effects*: Let T bedecltype(declval<typename InVec1::value_type>() * declval<typename InVec2::value_type>())[.](#algs.blas1.dot-9.sentence-1)
|
||
|
||
Then,
|
||
|
||
- [(9.1)](#algs.blas1.dot-9.1)
|
||
|
||
the two-parameter overload is equivalent to:return dot(v1, v2, T{}); and
|
||
|
||
- [(9.2)](#algs.blas1.dot-9.2)
|
||
|
||
the three-parameter overload is equivalent to:return dot(std::forward<ExecutionPolicy>(exec), v1, v2, T{});
|
||
|
||
[ð](#lib:dotc)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar>
|
||
Scalar dotc(InVec1 v1, InVec2 v2, Scalar init);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, class Scalar>
|
||
Scalar dotc(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2, Scalar init);
|
||
`
|
||
|
||
[10](#algs.blas1.dot-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13682)
|
||
|
||
These functions compute a conjugated dot product
|
||
with an explicitly specified result type[.](#algs.blas1.dot-10.sentence-1)
|
||
|
||
[11](#algs.blas1.dot-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13686)
|
||
|
||
*Effects*:
|
||
|
||
- [(11.1)](#algs.blas1.dot-11.1)
|
||
|
||
The three-parameter overload is equivalent to:return dot(conjugated(v1), v2, init); and
|
||
|
||
- [(11.2)](#algs.blas1.dot-11.2)
|
||
|
||
the four-parameter overload is equivalent to:return dot(std::forward<ExecutionPolicy>(exec), conjugated(v1), v2, init);
|
||
|
||
[ð](#lib:dotc_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>
|
||
auto dotc(InVec1 v1, InVec2 v2);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2>
|
||
auto dotc(ExecutionPolicy&& exec,
|
||
InVec1 v1, InVec2 v2);
|
||
`
|
||
|
||
[12](#algs.blas1.dot-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13714)
|
||
|
||
These functions compute a conjugated dot product with a default result type[.](#algs.blas1.dot-12.sentence-1)
|
||
|
||
[13](#algs.blas1.dot-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13717)
|
||
|
||
*Effects*: Let T be decltype(*conj-if-needed*(declval<typename InVec1::value_type>()) * declval<typename InVec2::value_type>())[.](#algs.blas1.dot-13.sentence-1)
|
||
|
||
Then,
|
||
|
||
- [(13.1)](#algs.blas1.dot-13.1)
|
||
|
||
the two-parameter overload is equivalent to:return dotc(v1, v2, T{}); and
|
||
|
||
- [(13.2)](#algs.blas1.dot-13.2)
|
||
|
||
the three-parameter overload is equivalent toreturn dotc(std::forward<ExecutionPolicy>(exec), v1, v2, T{});
|
||
|
||
#### [29.9.13.8](#algs.blas1.ssq) Scaled sum of squares of a vector's elements [[linalg.algs.blas1.ssq]](linalg.algs.blas1.ssq)
|
||
|
||
[ð](#lib:vector_sum_of_squares)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
sum_of_squares_result<Scalar> vector_sum_of_squares(InVec v, sum_of_squares_result<Scalar> init);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
sum_of_squares_result<Scalar> vector_sum_of_squares(ExecutionPolicy&& exec,
|
||
InVec v, sum_of_squares_result<Scalar> init);
|
||
`
|
||
|
||
[1](#algs.blas1.ssq-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13748)
|
||
|
||
[*Note [1](#algs.blas1.ssq-note-1)*:
|
||
|
||
These functions correspond to the LAPACK function xLASSQ[[bib]](bibliography#bib:lapack "Bibliography")[.](#algs.blas1.ssq-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.ssq-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13753)
|
||
|
||
*Mandates*: decltype(*abs-if-needed*(declval<typename InVec::value_type>())) is convertible to Scalar[.](#algs.blas1.ssq-2.sentence-1)
|
||
|
||
[3](#algs.blas1.ssq-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13757)
|
||
|
||
*Effects*: Returns a value result such that
|
||
|
||
- [(3.1)](#algs.blas1.ssq-3.1)
|
||
|
||
result.scaling_factor is the maximum of init.scaling_factor and*abs-if-needed*(x[i]) for all i in the domain of v; and
|
||
|
||
- [(3.2)](#algs.blas1.ssq-3.2)
|
||
|
||
let s2init beinit.scaling_factor * init.scaling_factor * init.scaled_sum_of_squares then result.scaling_factor * result.scaling_factor * result.scaled_sum_of_squares equals the sum of s2init and
|
||
the squares of *abs-if-needed*(x[i]) for all i in the domain of v[.](#algs.blas1.ssq-3.sentence-1)
|
||
|
||
[4](#algs.blas1.ssq-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13776)
|
||
|
||
*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[.](#algs.blas1.ssq-4.sentence-1)
|
||
|
||
#### [29.9.13.9](#algs.blas1.nrm2) Euclidean norm of a vector [[linalg.algs.blas1.nrm2]](linalg.algs.blas1.nrm2)
|
||
|
||
[ð](#lib:vector_two_norm)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
Scalar vector_two_norm(InVec v, Scalar init);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init);
|
||
`
|
||
|
||
[1](#algs.blas1.nrm2-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13796)
|
||
|
||
[*Note [1](#algs.blas1.nrm2-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xNRM2[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.nrm2-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.nrm2-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13801)
|
||
|
||
*Mandates*: Let a be*abs-if-needed*(declval<typename InVec::value_type>())[.](#algs.blas1.nrm2-2.sentence-1)
|
||
|
||
Then, decltype(init + a * a is convertible to Scalar[.](#algs.blas1.nrm2-2.sentence-2)
|
||
|
||
[3](#algs.blas1.nrm2-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13807)
|
||
|
||
*Returns*: The square root of the sum of the square of init and the squares of the absolute values of the elements of v[.](#algs.blas1.nrm2-3.sentence-1)
|
||
|
||
[*Note [2](#algs.blas1.nrm2-note-2)*:
|
||
|
||
For init equal to zero, this is the Euclidean norm
|
||
(also called 2-norm) of the vector v[.](#algs.blas1.nrm2-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#algs.blas1.nrm2-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13815)
|
||
|
||
*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[.](#algs.blas1.nrm2-4.sentence-1)
|
||
|
||
[*Note [3](#algs.blas1.nrm2-note-3)*:
|
||
|
||
An implementation of this function for floating-point types T can use the scaled_sum_of_squares result fromvector_sum_of_squares(x, {.scaling_factor=1.0, .scaled_sum_of_squares=init})[.](#algs.blas1.nrm2-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:vector_two_norm_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
auto vector_two_norm(InVec v);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
auto vector_two_norm(ExecutionPolicy&& exec, InVec v);
|
||
`
|
||
|
||
[5](#algs.blas1.nrm2-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13838)
|
||
|
||
*Effects*: Let a be*abs-if-needed*(declval<typename InVec::value_type>())[.](#algs.blas1.nrm2-5.sentence-1)
|
||
|
||
Let T be decltype(a * a)[.](#algs.blas1.nrm2-5.sentence-2)
|
||
|
||
Then,
|
||
|
||
- [(5.1)](#algs.blas1.nrm2-5.1)
|
||
|
||
the one-parameter overload is equivalent to:return vector_two_norm(v, T{}); and
|
||
|
||
- [(5.2)](#algs.blas1.nrm2-5.2)
|
||
|
||
the two-parameter overload is equivalent to:return vector_two_norm(std::forward<ExecutionPolicy>(exec), v, T{});
|
||
|
||
#### [29.9.13.10](#algs.blas1.asum) Sum of absolute values of vector elements [[linalg.algs.blas1.asum]](linalg.algs.blas1.asum)
|
||
|
||
[ð](#lib:vector_abs_sum)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
Scalar vector_abs_sum(InVec v, Scalar init);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, class Scalar>
|
||
Scalar vector_abs_sum(ExecutionPolicy&& exec, InVec v, Scalar init);
|
||
`
|
||
|
||
[1](#algs.blas1.asum-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13870)
|
||
|
||
[*Note [1](#algs.blas1.asum-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsSASUM, DASUM, SCASUM, and DZASUM[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.asum-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.asum-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13876)
|
||
|
||
*Mandates*: decltype(init + *abs-if-needed*(*real-if-needed*(declval<typename InVec::value_type>())) +*abs-if-needed*(*imag-if-needed*(declval<typename InVec::value_type>()))) is convertible to Scalar[.](#algs.blas1.asum-2.sentence-1)
|
||
|
||
[3](#algs.blas1.asum-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13884)
|
||
|
||
*Returns*: Let N be v.extent(0)[.](#algs.blas1.asum-3.sentence-1)
|
||
|
||
- [(3.1)](#algs.blas1.asum-3.1)
|
||
|
||
init if N is zero;
|
||
|
||
- [(3.2)](#algs.blas1.asum-3.2)
|
||
|
||
otherwise, if InVec::value_type is an arithmetic type,*GENERALIZED_SUM*(plus<>(), init, *abs-if-needed*(v[0]), …, *abs-if-needed*(v[N-1]))
|
||
|
||
- [(3.3)](#algs.blas1.asum-3.3)
|
||
|
||
otherwise,*GENERALIZED_SUM*(plus<>(), init, *abs-if-needed*(*real-if-needed*(v[0])) + *abs-if-needed*(*imag-if-needed*(v[0])),
|
||
…, *abs-if-needed*(*real-if-needed*(v[N-1])) + *abs-if-needed*(*imag-if-needed*(v[N-1])))
|
||
|
||
[4](#algs.blas1.asum-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13905)
|
||
|
||
*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[.](#algs.blas1.asum-4.sentence-1)
|
||
|
||
[ð](#lib:vector_abs_sum_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
auto vector_abs_sum(InVec v);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
auto vector_abs_sum(ExecutionPolicy&& exec, InVec v);
|
||
`
|
||
|
||
[5](#algs.blas1.asum-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13923)
|
||
|
||
*Effects*: Let T be typename InVec::value_type[.](#algs.blas1.asum-5.sentence-1)
|
||
|
||
Then,
|
||
|
||
- [(5.1)](#algs.blas1.asum-5.1)
|
||
|
||
the one-parameter overload is equivalent to:return vector_abs_sum(v, T{}); and
|
||
|
||
- [(5.2)](#algs.blas1.asum-5.2)
|
||
|
||
the two-parameter overload is equivalent to:return vector_abs_sum(std::forward<ExecutionPolicy>(exec), v, T{});
|
||
|
||
#### [29.9.13.11](#algs.blas1.iamax) Index of maximum absolute value of vector elements [[linalg.algs.blas1.iamax]](linalg.algs.blas1.iamax)
|
||
|
||
[ð](#lib:vector_idx_abs_max)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
typename InVec::extents_type vector_idx_abs_max(InVec v);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec>
|
||
typename InVec::extents_type vector_idx_abs_max(ExecutionPolicy&& exec, InVec v);
|
||
`
|
||
|
||
[1](#algs.blas1.iamax-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13953)
|
||
|
||
[*Note [1](#algs.blas1.iamax-note-1)*:
|
||
|
||
These functions correspond to the BLAS function IxAMAX[[bib]](bibliography#bib:blas1 "Bibliography")[.](#algs.blas1.iamax-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas1.iamax-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13958)
|
||
|
||
Let T bedecltype(*abs-if-needed*(*real-if-needed*(declval<typename InVec::value_type>())) +*abs-if-needed*(*imag-if-needed*(declval<typename InVec::value_type>())))
|
||
|
||
[3](#algs.blas1.iamax-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13965)
|
||
|
||
*Mandates*: declval<T>() < declval<T>() is a valid expression[.](#algs.blas1.iamax-3.sentence-1)
|
||
|
||
[4](#algs.blas1.iamax-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13969)
|
||
|
||
*Returns*:
|
||
|
||
- [(4.1)](#algs.blas1.iamax-4.1)
|
||
|
||
numeric_limits<typename InVec::size_type>::max() if v has zero elements;
|
||
|
||
- [(4.2)](#algs.blas1.iamax-4.2)
|
||
|
||
otherwise, the index of the first element of v having largest absolute value,
|
||
if InVec::value_type is an arithmetic type;
|
||
|
||
- [(4.3)](#algs.blas1.iamax-4.3)
|
||
|
||
otherwise, the index of the first element ve of v for which*abs-if-needed*(*real-if-needed*(ve)) + *abs-if-needed*(*imag-if-needed*(ve)) has the largest value[.](#algs.blas1.iamax-4.sentence-1)
|
||
|
||
#### [29.9.13.12](#algs.blas1.matfrobnorm) Frobenius norm of a matrix [[linalg.algs.blas1.matfrobnorm]](linalg.algs.blas1.matfrobnorm)
|
||
|
||
[1](#algs.blas1.matfrobnorm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L13991)
|
||
|
||
[*Note [1](#algs.blas1.matfrobnorm-note-1)*:
|
||
|
||
These functions exist in the BLAS standard[[bib]](bibliography#bib:blas-std "Bibliography") but are not part of the reference implementation[.](#algs.blas1.matfrobnorm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:matrix_frob_norm)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_frob_norm(InMat A, Scalar init);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
|
||
`
|
||
|
||
[2](#algs.blas1.matfrobnorm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14007)
|
||
|
||
*Mandates*: Let a be*abs-if-needed*(declval<typename InMat::value_type>())[.](#algs.blas1.matfrobnorm-2.sentence-1)
|
||
|
||
Then, decltype(init + a * a) is convertible to Scalar[.](#algs.blas1.matfrobnorm-2.sentence-2)
|
||
|
||
[3](#algs.blas1.matfrobnorm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14014)
|
||
|
||
*Returns*: The square root of the sum of squares
|
||
of init and the absolute values of the elements of A[.](#algs.blas1.matfrobnorm-3.sentence-1)
|
||
|
||
[*Note [2](#algs.blas1.matfrobnorm-note-2)*:
|
||
|
||
For init equal to zero,
|
||
this is the Frobenius norm of the matrix A[.](#algs.blas1.matfrobnorm-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#algs.blas1.matfrobnorm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14023)
|
||
|
||
*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[.](#algs.blas1.matfrobnorm-4.sentence-1)
|
||
|
||
[ð](#lib:matrix_frob_norm_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_frob_norm(InMat A);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_frob_norm(ExecutionPolicy&& exec, InMat A);
|
||
`
|
||
|
||
[5](#algs.blas1.matfrobnorm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14041)
|
||
|
||
*Effects*: Let a be*abs-if-needed*(declval<typename InMat::value_type>())[.](#algs.blas1.matfrobnorm-5.sentence-1)
|
||
|
||
Let T bedecltype(a * a)[.](#algs.blas1.matfrobnorm-5.sentence-2)
|
||
|
||
Then,
|
||
|
||
- [(5.1)](#algs.blas1.matfrobnorm-5.1)
|
||
|
||
the one-parameter overload is equivalent to:return matrix_frob_norm(A, T{}); and
|
||
|
||
- [(5.2)](#algs.blas1.matfrobnorm-5.2)
|
||
|
||
the two-parameter overload is equivalent to:return matrix_frob_norm(std::forward<ExecutionPolicy>(exec), A, T{});
|
||
|
||
#### [29.9.13.13](#algs.blas1.matonenorm) One norm of a matrix [[linalg.algs.blas1.matonenorm]](linalg.algs.blas1.matonenorm)
|
||
|
||
[1](#algs.blas1.matonenorm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14065)
|
||
|
||
[*Note [1](#algs.blas1.matonenorm-note-1)*:
|
||
|
||
These functions exist in the BLAS standard[[bib]](bibliography#bib:blas-std "Bibliography") but are not part of the reference implementation[.](#algs.blas1.matonenorm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:matrix_one_norm)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_one_norm(InMat A, Scalar init);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_one_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
|
||
`
|
||
|
||
[2](#algs.blas1.matonenorm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14080)
|
||
|
||
*Mandates*: decltype(*abs-if-needed*(declval<typename InMat::value_type>())) is convertible to Scalar[.](#algs.blas1.matonenorm-2.sentence-1)
|
||
|
||
[3](#algs.blas1.matonenorm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14085)
|
||
|
||
*Returns*:
|
||
|
||
- [(3.1)](#algs.blas1.matonenorm-3.1)
|
||
|
||
init if A.extent(1) is zero;
|
||
|
||
- [(3.2)](#algs.blas1.matonenorm-3.2)
|
||
|
||
otherwise, the sum of init and the one norm of the matrix A[.](#algs.blas1.matonenorm-3.sentence-1)
|
||
|
||
[*Note [2](#algs.blas1.matonenorm-note-2)*:
|
||
|
||
The one norm of the matrix A is the maximum over all columns of A,
|
||
of the sum of the absolute values of the elements of the column[.](#algs.blas1.matonenorm-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#algs.blas1.matonenorm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14099)
|
||
|
||
*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[.](#algs.blas1.matonenorm-4.sentence-1)
|
||
|
||
[ð](#lib:matrix_one_norm_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_one_norm(InMat A);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_one_norm(ExecutionPolicy&& exec, InMat A);
|
||
`
|
||
|
||
[5](#algs.blas1.matonenorm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14117)
|
||
|
||
*Effects*: Let T bedecltype(*abs-if-needed*(declval<typename InMat::value_type>())[.](#algs.blas1.matonenorm-5.sentence-1)
|
||
|
||
Then,
|
||
|
||
- [(5.1)](#algs.blas1.matonenorm-5.1)
|
||
|
||
the one-parameter overload is equivalent to:return matrix_one_norm(A, T{}); and
|
||
|
||
- [(5.2)](#algs.blas1.matonenorm-5.2)
|
||
|
||
the two-parameter overload is equivalent to:return matrix_one_norm(std::forward<ExecutionPolicy>(exec), A, T{});
|
||
|
||
#### [29.9.13.14](#algs.blas1.matinfnorm) Infinity norm of a matrix [[linalg.algs.blas1.matinfnorm]](linalg.algs.blas1.matinfnorm)
|
||
|
||
[1](#algs.blas1.matinfnorm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14139)
|
||
|
||
[*Note [1](#algs.blas1.matinfnorm-note-1)*:
|
||
|
||
These functions exist in the BLAS standard[[bib]](bibliography#bib:blas-std "Bibliography") but are not part of the reference implementation[.](#algs.blas1.matinfnorm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:matrix_inf_norm)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_inf_norm(InMat A, Scalar init);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Scalar>
|
||
Scalar matrix_inf_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
|
||
`
|
||
|
||
[2](#algs.blas1.matinfnorm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14154)
|
||
|
||
*Mandates*: decltype(*abs-if-needed*(declval<typename InMat::value_type>())) is convertible to Scalar[.](#algs.blas1.matinfnorm-2.sentence-1)
|
||
|
||
[3](#algs.blas1.matinfnorm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14159)
|
||
|
||
*Returns*:
|
||
|
||
- [(3.1)](#algs.blas1.matinfnorm-3.1)
|
||
|
||
init if A.extent(0) is zero;
|
||
|
||
- [(3.2)](#algs.blas1.matinfnorm-3.2)
|
||
|
||
otherwise,
|
||
the sum of init and the infinity norm of the matrix A[.](#algs.blas1.matinfnorm-3.sentence-1)
|
||
|
||
[*Note [2](#algs.blas1.matinfnorm-note-2)*:
|
||
|
||
The infinity norm of the matrix A is the maximum over all rows of A,
|
||
of the sum of the absolute values
|
||
of the elements of the row[.](#algs.blas1.matinfnorm-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#algs.blas1.matinfnorm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14175)
|
||
|
||
*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[.](#algs.blas1.matinfnorm-4.sentence-1)
|
||
|
||
[ð](#lib:matrix_inf_norm_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_inf_norm(InMat A);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat>
|
||
auto matrix_inf_norm(ExecutionPolicy&& exec, InMat A);
|
||
`
|
||
|
||
[5](#algs.blas1.matinfnorm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14194)
|
||
|
||
*Effects*: Let T bedecltype(*abs-if-needed*(declval<typename InMat::value_type>())[.](#algs.blas1.matinfnorm-5.sentence-1)
|
||
|
||
Then,
|
||
|
||
- [(5.1)](#algs.blas1.matinfnorm-5.1)
|
||
|
||
the one-parameter overload is equivalent to:return matrix_inf_norm(A, T{}); and
|
||
|
||
- [(5.2)](#algs.blas1.matinfnorm-5.2)
|
||
|
||
the two-parameter overload is equivalent to:return matrix_inf_norm(std::forward<ExecutionPolicy>(exec), A, T{});
|
||
|
||
### [29.9.14](#algs.blas2) BLAS 2 algorithms [[linalg.algs.blas2]](linalg.algs.blas2)
|
||
|
||
#### [29.9.14.1](#algs.blas2.gemv) General matrix-vector product [[linalg.algs.blas2.gemv]](linalg.algs.blas2.gemv)
|
||
|
||
[1](#algs.blas2.gemv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14218)
|
||
|
||
[*Note [1](#algs.blas2.gemv-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xGEMV[.](#algs.blas2.gemv-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.gemv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14223)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.gemv]](#algs.blas2.gemv "29.9.14.1 General matrix-vector product")[.](#algs.blas2.gemv-2.sentence-1)
|
||
|
||
[3](#algs.blas2.gemv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14226)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.gemv-3.1)
|
||
|
||
*possibly-multipliable*<decltype(A), decltype(x), decltype(y)>() is true, and
|
||
|
||
- [(3.2)](#algs.blas2.gemv-3.2)
|
||
|
||
*possibly-addable*<decltype(x), decltype(y), decltype(z)>() is true for those overloads that take a z parameter[.](#algs.blas2.gemv-3.sentence-1)
|
||
|
||
[4](#algs.blas2.gemv-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14237)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.gemv-4.1)
|
||
|
||
*multipliable*(A,x,y) is true, and
|
||
|
||
- [(4.2)](#algs.blas2.gemv-4.2)
|
||
|
||
*addable*(x,y,z) is true for those overloads that take a z parameter[.](#algs.blas2.gemv-4.sentence-1)
|
||
|
||
[5](#algs.blas2.gemv-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14246)
|
||
|
||
*Complexity*: O(x.extent(0)ÃA.extent(1))[.](#algs.blas2.gemv-5.sentence-1)
|
||
|
||
[ð](#lib:matrix_vector_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void matrix_vector_product(InMat A, InVec x, OutVec y);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void matrix_vector_product(ExecutionPolicy&& exec, InMat A, InVec x, OutVec y);
|
||
`
|
||
|
||
[6](#algs.blas2.gemv-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14259)
|
||
|
||
These functions perform an overwriting matrix-vector product[.](#algs.blas2.gemv-6.sentence-1)
|
||
|
||
[7](#algs.blas2.gemv-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14262)
|
||
|
||
*Effects*: Computes y=Ax[.](#algs.blas2.gemv-7.sentence-1)
|
||
|
||
[*Example [1](#algs.blas2.gemv-example-1)*: constexpr size_t num_rows = 5;constexpr size_t num_cols = 6;
|
||
|
||
// y = 3.0 * A * xvoid scaled_matvec_1(mdspan<double, extents<size_t, num_rows, num_cols>> A,
|
||
mdspan<double, extents<size_t, num_cols>> x, mdspan<double, extents<size_t, num_rows>> y) { matrix_vector_product(scaled(3.0, A), x, y);}// z = 7.0 times the transpose of A, times yvoid scaled_transposed_matvec(mdspan<double, extents<size_t, num_rows, num_cols>> A,
|
||
mdspan<double, extents<size_t, num_rows>> y, mdspan<double, extents<size_t, num_cols>> z) { matrix_vector_product(scaled(7.0, transposed(A)), y, z);} â *end example*]
|
||
|
||
[ð](#lib:matrix_vector_product_)
|
||
|
||
` template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void matrix_vector_product(InMat A, InVec1 x, InVec2 y, OutVec z);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, InVec1 x, InVec2 y, OutVec z);
|
||
`
|
||
|
||
[8](#algs.blas2.gemv-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14297)
|
||
|
||
These functions perform an updating matrix-vector product[.](#algs.blas2.gemv-8.sentence-1)
|
||
|
||
[9](#algs.blas2.gemv-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14300)
|
||
|
||
*Effects*: Computes z=y+Ax[.](#algs.blas2.gemv-9.sentence-1)
|
||
|
||
[10](#algs.blas2.gemv-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14304)
|
||
|
||
*Remarks*: z may alias y[.](#algs.blas2.gemv-10.sentence-1)
|
||
|
||
[*Example [2](#algs.blas2.gemv-example-2)*: // y = 3.0 * A * x + 2.0 * yvoid scaled_matvec_2(mdspan<double, extents<size_t, num_rows, num_cols>> A,
|
||
mdspan<double, extents<size_t, num_cols>> x, mdspan<double, extents<size_t, num_rows>> y) { matrix_vector_product(scaled(3.0, A), x, scaled(2.0, y), y);} â *end example*]
|
||
|
||
#### [29.9.14.2](#algs.blas2.symv) Symmetric matrix-vector product [[linalg.algs.blas2.symv]](linalg.algs.blas2.symv)
|
||
|
||
[1](#algs.blas2.symv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14321)
|
||
|
||
[*Note [1](#algs.blas2.symv-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYMV and xSPMV[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.symv-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.symv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14327)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.symv]](#algs.blas2.symv "29.9.14.2 Symmetric matrix-vector product")[.](#algs.blas2.symv-2.sentence-1)
|
||
|
||
[3](#algs.blas2.symv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14330)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.symv-3.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.symv-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;
|
||
|
||
- [(3.3)](#algs.blas2.symv-3.3)
|
||
|
||
*possibly-multipliable*<decltype(A), decltype(x), decltype(y)>() is true; and
|
||
|
||
- [(3.4)](#algs.blas2.symv-3.4)
|
||
|
||
*possibly-addable*<decltype(x), decltype(y), decltype(z)>() is true for those overloads that take a z parameter[.](#algs.blas2.symv-3.sentence-1)
|
||
|
||
[4](#algs.blas2.symv-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14347)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.symv-4.1)
|
||
|
||
A.extent(0) equals A.extent(1),
|
||
|
||
- [(4.2)](#algs.blas2.symv-4.2)
|
||
|
||
*multipliable*(A,x,y) is true, and
|
||
|
||
- [(4.3)](#algs.blas2.symv-4.3)
|
||
|
||
*addable*(x,y,z) is true for those overloads that take a z parameter[.](#algs.blas2.symv-4.sentence-1)
|
||
|
||
[5](#algs.blas2.symv-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14359)
|
||
|
||
*Complexity*: O(x.extent(0)ÃA.extent(1))[.](#algs.blas2.symv-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_vector_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void symmetric_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec x, OutVec y);
|
||
`
|
||
|
||
[6](#algs.blas2.symv-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14375)
|
||
|
||
These functions perform an overwriting symmetric matrix-vector product,
|
||
taking into account the Triangle parameter
|
||
that applies to the symmetric matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symv-6.sentence-1)
|
||
|
||
[7](#algs.blas2.symv-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14380)
|
||
|
||
*Effects*: Computes y=Ax[.](#algs.blas2.symv-7.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_vector_product_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void symmetric_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
|
||
`
|
||
|
||
[8](#algs.blas2.symv-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14396)
|
||
|
||
These functions perform an updating symmetric matrix-vector product,
|
||
taking into account the Triangle parameter
|
||
that applies to the symmetric matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symv-8.sentence-1)
|
||
|
||
[9](#algs.blas2.symv-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14401)
|
||
|
||
*Effects*: Computes z=y+Ax[.](#algs.blas2.symv-9.sentence-1)
|
||
|
||
[10](#algs.blas2.symv-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14405)
|
||
|
||
*Remarks*: z may alias y[.](#algs.blas2.symv-10.sentence-1)
|
||
|
||
#### [29.9.14.3](#algs.blas2.hemv) Hermitian matrix-vector product [[linalg.algs.blas2.hemv]](linalg.algs.blas2.hemv)
|
||
|
||
[1](#algs.blas2.hemv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14412)
|
||
|
||
[*Note [1](#algs.blas2.hemv-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxHEMV and xHPMV[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.hemv-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.hemv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14418)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.hemv]](#algs.blas2.hemv "29.9.14.3 Hermitian matrix-vector product")[.](#algs.blas2.hemv-2.sentence-1)
|
||
|
||
[3](#algs.blas2.hemv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14421)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.hemv-3.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument
|
||
has the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.hemv-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;
|
||
|
||
- [(3.3)](#algs.blas2.hemv-3.3)
|
||
|
||
*possibly-multipliable*<decltype(A), decltype(x), decltype(y)>() is true; and
|
||
|
||
- [(3.4)](#algs.blas2.hemv-3.4)
|
||
|
||
*possibly-addable*<decltype(x), decltype(y), decltype(z)>() is true for those overloads that take a z parameter[.](#algs.blas2.hemv-3.sentence-1)
|
||
|
||
[4](#algs.blas2.hemv-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14439)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.hemv-4.1)
|
||
|
||
A.extent(0) equals A.extent(1),
|
||
|
||
- [(4.2)](#algs.blas2.hemv-4.2)
|
||
|
||
*multipliable*(A, x, y) is true, and
|
||
|
||
- [(4.3)](#algs.blas2.hemv-4.3)
|
||
|
||
*addable*(x, y, z) is true for those overloads that take a z parameter[.](#algs.blas2.hemv-4.sentence-1)
|
||
|
||
[5](#algs.blas2.hemv-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14450)
|
||
|
||
*Complexity*: O(x.extent(0)ÃA.extent(1))[.](#algs.blas2.hemv-5.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_vector_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void hermitian_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec x, OutVec y);
|
||
`
|
||
|
||
[6](#algs.blas2.hemv-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14465)
|
||
|
||
These functions perform an overwriting Hermitian matrix-vector product,
|
||
taking into account the Triangle parameter
|
||
that applies to the Hermitian matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.hemv-6.sentence-1)
|
||
|
||
[7](#algs.blas2.hemv-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14470)
|
||
|
||
*Effects*: Computes y=Ax[.](#algs.blas2.hemv-7.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_vector_product_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void hermitian_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
|
||
`
|
||
|
||
[8](#algs.blas2.hemv-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14486)
|
||
|
||
These functions perform an updating Hermitian matrix-vector product,
|
||
taking into account the Triangle parameter
|
||
that applies to the Hermitian matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.hemv-8.sentence-1)
|
||
|
||
[9](#algs.blas2.hemv-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14491)
|
||
|
||
*Effects*: Computes z=y+Ax[.](#algs.blas2.hemv-9.sentence-1)
|
||
|
||
[10](#algs.blas2.hemv-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14495)
|
||
|
||
*Remarks*: z may alias y[.](#algs.blas2.hemv-10.sentence-1)
|
||
|
||
#### [29.9.14.4](#algs.blas2.trmv) Triangular matrix-vector product [[linalg.algs.blas2.trmv]](linalg.algs.blas2.trmv)
|
||
|
||
[1](#algs.blas2.trmv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14502)
|
||
|
||
[*Note [1](#algs.blas2.trmv-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxTRMV and xTPMV[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.trmv-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.trmv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14508)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.trmv]](#algs.blas2.trmv "29.9.14.4 Triangular matrix-vector product")[.](#algs.blas2.trmv-2.sentence-1)
|
||
|
||
[3](#algs.blas2.trmv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14511)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.trmv-3.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.trmv-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;
|
||
|
||
- [(3.3)](#algs.blas2.trmv-3.3)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(y)>(0, 0) is true;
|
||
|
||
- [(3.4)](#algs.blas2.trmv-3.4)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(x)>(0, 0) is true for those overloads that take an x parameter; and
|
||
|
||
- [(3.5)](#algs.blas2.trmv-3.5)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(z)>(0, 0) is true for those overloads that take a z parameter[.](#algs.blas2.trmv-3.sentence-1)
|
||
|
||
[4](#algs.blas2.trmv-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14532)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.trmv-4.1)
|
||
|
||
A.extent(0) equals A.extent(1),
|
||
|
||
- [(4.2)](#algs.blas2.trmv-4.2)
|
||
|
||
A.extent(0) equals y.extent(0),
|
||
|
||
- [(4.3)](#algs.blas2.trmv-4.3)
|
||
|
||
A.extent(0) equals x.extent(0) for those overloads that take an x parameter, and
|
||
|
||
- [(4.4)](#algs.blas2.trmv-4.4)
|
||
|
||
A.extent(0) equals z.extent(0) for those overloads that take a z parameter[.](#algs.blas2.trmv-4.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec,
|
||
[out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InVec x, OutVec y);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec,
|
||
[out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InVec x, OutVec y);
|
||
`
|
||
|
||
[5](#algs.blas2.trmv-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14559)
|
||
|
||
These functions perform
|
||
an overwriting triangular matrix-vector product,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.trmv-5.sentence-1)
|
||
|
||
[6](#algs.blas2.trmv-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14565)
|
||
|
||
*Effects*: Computes y=Ax[.](#algs.blas2.trmv-6.sentence-1)
|
||
|
||
[7](#algs.blas2.trmv-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14569)
|
||
|
||
*Complexity*: O(x.extent(0)ÃA.extent(1))[.](#algs.blas2.trmv-7.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_product_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>
|
||
void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InOutVec y);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>
|
||
void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutVec y);
|
||
`
|
||
|
||
[8](#algs.blas2.trmv-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14586)
|
||
|
||
These functions perform an in-place triangular matrix-vector product,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.trmv-8.sentence-1)
|
||
|
||
[*Note [2](#algs.blas2.trmv-note-2)*:
|
||
|
||
Performing this operation in place hinders parallelization[.](#algs.blas2.trmv-8.sentence-2)
|
||
|
||
However, other ExecutionPolicy specific optimizations,
|
||
such as vectorization, are still possible[.](#algs.blas2.trmv-8.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[9](#algs.blas2.trmv-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14596)
|
||
|
||
*Effects*: Computes a vector yâ² such that yâ²=Ay,
|
||
and assigns each element of yâ² to the corresponding element of y[.](#algs.blas2.trmv-9.sentence-1)
|
||
|
||
[10](#algs.blas2.trmv-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14601)
|
||
|
||
*Complexity*: O(y.extent(0)ÃA.extent(1))[.](#algs.blas2.trmv-10.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_product__)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d,
|
||
InVec1 x, InVec2 y, OutVec z);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InVec1 x, InVec2 y, OutVec z);
|
||
`
|
||
|
||
[11](#algs.blas2.trmv-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14620)
|
||
|
||
These functions perform an updating triangular matrix-vector product,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.trmv-11.sentence-1)
|
||
|
||
[12](#algs.blas2.trmv-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14625)
|
||
|
||
*Effects*: Computes z=y+Ax[.](#algs.blas2.trmv-12.sentence-1)
|
||
|
||
[13](#algs.blas2.trmv-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14629)
|
||
|
||
*Complexity*: O(x.extent(0)ÃA.extent(1))[.](#algs.blas2.trmv-13.sentence-1)
|
||
|
||
[14](#algs.blas2.trmv-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14633)
|
||
|
||
*Remarks*: z may alias y[.](#algs.blas2.trmv-14.sentence-1)
|
||
|
||
#### [29.9.14.5](#algs.blas2.trsv) Solve a triangular linear system [[linalg.algs.blas2.trsv]](linalg.algs.blas2.trsv)
|
||
|
||
[1](#algs.blas2.trsv-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14640)
|
||
|
||
[*Note [1](#algs.blas2.trsv-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxTRSV and xTPSV[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.trsv-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.trsv-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14646)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.trsv]](#algs.blas2.trsv "29.9.14.5 Solve a triangular linear system")[.](#algs.blas2.trsv-2.sentence-1)
|
||
|
||
[3](#algs.blas2.trsv-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14649)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.trsv-3.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.trsv-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;
|
||
|
||
- [(3.3)](#algs.blas2.trsv-3.3)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(b)>(0, 0) is true; and
|
||
|
||
- [(3.4)](#algs.blas2.trsv-3.4)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(x)>(0, 0) is true for those overloads that take an x parameter[.](#algs.blas2.trsv-3.sentence-1)
|
||
|
||
[4](#algs.blas2.trsv-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14667)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.trsv-4.1)
|
||
|
||
A.extent(0) equals A.extent(1),
|
||
|
||
- [(4.2)](#algs.blas2.trsv-4.2)
|
||
|
||
A.extent(0) equals b.extent(0), and
|
||
|
||
- [(4.3)](#algs.blas2.trsv-4.3)
|
||
|
||
A.extent(0) equals x.extent(0) for those overloads that take an x parameter[.](#algs.blas2.trsv-4.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve)
|
||
|
||
` template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec, class BinaryDivideOp>
|
||
void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec, class BinaryDivideOp>
|
||
void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InVec b, OutVec x, BinaryDivideOp divide);
|
||
`
|
||
|
||
[5](#algs.blas2.trsv-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14694)
|
||
|
||
These functions perform
|
||
a triangular solve,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.trsv-5.sentence-1)
|
||
|
||
[6](#algs.blas2.trsv-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14700)
|
||
|
||
*Effects*: Computes a vector xâ² such that b=Axâ²,
|
||
and assigns each element of xâ² to the corresponding element of x[.](#algs.blas2.trsv-6.sentence-1)
|
||
|
||
If no such xâ² exists,
|
||
then the elements of x are valid but unspecified[.](#algs.blas2.trsv-6.sentence-2)
|
||
|
||
[7](#algs.blas2.trsv-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14707)
|
||
|
||
*Complexity*: O(A.extent(1)Ãb.extent(0))[.](#algs.blas2.trsv-7.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d, InVec b, OutVec x);
|
||
`
|
||
|
||
[8](#algs.blas2.trsv-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14720)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_vector_solve(A, t, d, b, x, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve__)
|
||
|
||
`template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [out-vector](#concept:out-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutVec>
|
||
void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InVec b, OutVec x);
|
||
`
|
||
|
||
[9](#algs.blas2.trsv-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14737)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_vector_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, b, x, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve___)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec, class BinaryDivideOp>
|
||
void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutVec b, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec, class BinaryDivideOp>
|
||
void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutVec b, BinaryDivideOp divide);
|
||
`
|
||
|
||
[10](#algs.blas2.trsv-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14760)
|
||
|
||
These functions perform an in-place triangular solve,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.trsv-10.sentence-1)
|
||
|
||
[*Note [2](#algs.blas2.trsv-note-2)*:
|
||
|
||
Performing triangular solve in place hinders parallelization[.](#algs.blas2.trsv-10.sentence-2)
|
||
|
||
However, other ExecutionPolicy specific optimizations,
|
||
such as vectorization, are still possible[.](#algs.blas2.trsv-10.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[11](#algs.blas2.trsv-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14770)
|
||
|
||
*Effects*: Computes a vector xâ² such that b=Axâ²,
|
||
and assigns each element of xâ² to the corresponding element of b[.](#algs.blas2.trsv-11.sentence-1)
|
||
|
||
If no such xâ² exists,
|
||
then the elements of b are valid but unspecified[.](#algs.blas2.trsv-11.sentence-2)
|
||
|
||
[12](#algs.blas2.trsv-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14777)
|
||
|
||
*Complexity*: O(A.extent(1)Ãb.extent(0))[.](#algs.blas2.trsv-12.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve____)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>
|
||
void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d, InOutVec b);
|
||
`
|
||
|
||
[13](#algs.blas2.trsv-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14789)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_vector_solve(A, t, d, b, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_vector_solve_____)
|
||
|
||
`template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-vector](#concept:inout-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutVec>
|
||
void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutVec b);
|
||
`
|
||
|
||
[14](#algs.blas2.trsv-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14806)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_vector_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, b, divides<void>{});
|
||
|
||
#### [29.9.14.6](#algs.blas2.rank1) Rank-1 (outer product) update of a matrix [[linalg.algs.blas2.rank1]](linalg.algs.blas2.rank1)
|
||
|
||
[ð](#lib:matrix_rank_1_update)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void matrix_rank_1_update(InVec1 x, InVec2 y, InOutMat A);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void matrix_rank_1_update(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A);
|
||
`
|
||
|
||
[1](#algs.blas2.rank1-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14826)
|
||
|
||
These functions perform a nonsymmetric nonconjugated rank-1 update[.](#algs.blas2.rank1-1.sentence-1)
|
||
|
||
[*Note [1](#algs.blas2.rank1-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxGER (for real element types) andxGERU (for complex element types)[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.rank1-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.rank1-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14834)
|
||
|
||
*Mandates*: *possibly-multipliable*<InOutMat, InVec2, InVec1>() is true[.](#algs.blas2.rank1-2.sentence-1)
|
||
|
||
[3](#algs.blas2.rank1-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14839)
|
||
|
||
*Preconditions*: *multipliable*(A, y, x) is true[.](#algs.blas2.rank1-3.sentence-1)
|
||
|
||
[4](#algs.blas2.rank1-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14843)
|
||
|
||
*Effects*: Computes a matrix Aâ² such that Aâ²=A+xyT,
|
||
and assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.rank1-4.sentence-1)
|
||
|
||
[5](#algs.blas2.rank1-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14848)
|
||
|
||
*Complexity*: O(x.extent(0)Ãy.extent(0))[.](#algs.blas2.rank1-5.sentence-1)
|
||
|
||
[ð](#lib:matrix_rank_1_update_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void matrix_rank_1_update_c(InVec1 x, InVec2 y, InOutMat A);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void matrix_rank_1_update_c(ExecutionPolicy&& exec, InVec1 x, InVec2 y, InOutMat A);
|
||
`
|
||
|
||
[6](#algs.blas2.rank1-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14862)
|
||
|
||
These functions perform a nonsymmetric conjugated rank-1 update[.](#algs.blas2.rank1-6.sentence-1)
|
||
|
||
[*Note [2](#algs.blas2.rank1-note-2)*:
|
||
|
||
These functions correspond to the BLAS functionsxGER (for real element types) andxGERC (for complex element types)[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.rank1-6.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[7](#algs.blas2.rank1-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14870)
|
||
|
||
*Effects*:
|
||
|
||
- [(7.1)](#algs.blas2.rank1-7.1)
|
||
|
||
For the overloads without an ExecutionPolicy argument,
|
||
equivalent to:matrix_rank_1_update(x, conjugated(y), A);
|
||
|
||
- [(7.2)](#algs.blas2.rank1-7.2)
|
||
|
||
otherwise, equivalent to:matrix_rank_1_update(std::forward<ExecutionPolicy>(exec), x, conjugated(y), A);
|
||
|
||
#### [29.9.14.7](#algs.blas2.symherrank1) Symmetric or Hermitian Rank-1 (outer product) update of a matrix [[linalg.algs.blas2.symherrank1]](linalg.algs.blas2.symherrank1)
|
||
|
||
[1](#algs.blas2.symherrank1-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14889)
|
||
|
||
[*Note [1](#algs.blas2.symherrank1-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYR, xSPR, xHER, and xHPR[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.symherrank1-1.sentence-1)
|
||
|
||
They have overloads taking a scaling factor alpha,
|
||
because it would be impossible to express the updateA=AâxxT otherwise[.](#algs.blas2.symherrank1-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.symherrank1-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14898)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.symherrank1]](#algs.blas2.symherrank1 "29.9.14.7 Symmetric or Hermitian Rank-1 (outer product) update of a matrix")[.](#algs.blas2.symherrank1-2.sentence-1)
|
||
|
||
[3](#algs.blas2.symherrank1-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14901)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.symherrank1-3.1)
|
||
|
||
If InOutMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.symherrank1-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true; and
|
||
|
||
- [(3.3)](#algs.blas2.symherrank1-3.3)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(x)>(0, 0) is true[.](#algs.blas2.symherrank1-3.sentence-1)
|
||
|
||
[4](#algs.blas2.symherrank1-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14916)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.symherrank1-4.1)
|
||
|
||
A.extent(0) equals A.extent(1), and
|
||
|
||
- [(4.2)](#algs.blas2.symherrank1-4.2)
|
||
|
||
A.extent(0) equals x.extent(0)[.](#algs.blas2.symherrank1-4.sentence-1)
|
||
|
||
[5](#algs.blas2.symherrank1-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14925)
|
||
|
||
*Complexity*: O(x.extent(0)Ãx.extent(0))[.](#algs.blas2.symherrank1-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_1_update)
|
||
|
||
`template<class Scalar, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
class Scalar, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InVec x, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[6](#algs.blas2.symherrank1-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14940)
|
||
|
||
These functions perform
|
||
a symmetric rank-1 update of the symmetric matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symherrank1-6.sentence-1)
|
||
|
||
[7](#algs.blas2.symherrank1-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14946)
|
||
|
||
*Effects*: Computes a matrix Aâ² such thatAâ²=A+αxxT, where the scalar α is alpha,
|
||
and assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.symherrank1-7.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_1_update_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_1_update(InVec x, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[8](#algs.blas2.symherrank1-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14963)
|
||
|
||
These functions perform
|
||
a symmetric rank-1 update of the symmetric matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symherrank1-8.sentence-1)
|
||
|
||
[9](#algs.blas2.symherrank1-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14969)
|
||
|
||
*Effects*: Computes a matrix Aâ² such that Aâ²=A+xxT and assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.symherrank1-9.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_1_update)
|
||
|
||
`template<class Scalar, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
class Scalar, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InVec x, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[10](#algs.blas2.symherrank1-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14986)
|
||
|
||
These functions perform
|
||
a Hermitian rank-1 update of the Hermitian matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symherrank1-10.sentence-1)
|
||
|
||
[11](#algs.blas2.symherrank1-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L14992)
|
||
|
||
*Effects*: Computes Aâ² such thatAâ²=A+αxxH, where the scalar α is alpha,
|
||
and assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.symherrank1-11.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_1_update_)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_1_update(InVec x, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec, InVec x, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[12](#algs.blas2.symherrank1-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15009)
|
||
|
||
These functions perform
|
||
a Hermitian rank-1 update of the Hermitian matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.symherrank1-12.sentence-1)
|
||
|
||
[13](#algs.blas2.symherrank1-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15015)
|
||
|
||
*Effects*: Computes a matrix Aâ² such that Aâ²=A+xxH and
|
||
assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.symherrank1-13.sentence-1)
|
||
|
||
#### [29.9.14.8](#algs.blas2.rank2) Symmetric and Hermitian rank-2 matrix updates [[linalg.algs.blas2.rank2]](linalg.algs.blas2.rank2)
|
||
|
||
[1](#algs.blas2.rank2-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15023)
|
||
|
||
[*Note [1](#algs.blas2.rank2-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYR2,xSPR2, xHER2 and xHPR2[[bib]](bibliography#bib:blas2 "Bibliography")[.](#algs.blas2.rank2-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas2.rank2-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15029)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas2.rank2]](#algs.blas2.rank2 "29.9.14.8 Symmetric and Hermitian rank-2 matrix updates")[.](#algs.blas2.rank2-2.sentence-1)
|
||
|
||
[3](#algs.blas2.rank2-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15032)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas2.rank2-3.1)
|
||
|
||
If InOutMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas2.rank2-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true; and
|
||
|
||
- [(3.3)](#algs.blas2.rank2-3.3)
|
||
|
||
*possibly-multipliable*<decltype(A), decltype(x), decltype(y)>() is true[.](#algs.blas2.rank2-3.sentence-1)
|
||
|
||
[4](#algs.blas2.rank2-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15047)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas2.rank2-4.1)
|
||
|
||
A.extent(0) equals A.extent(1), and
|
||
|
||
- [(4.2)](#algs.blas2.rank2-4.2)
|
||
|
||
*multipliable*(A, x, y) is true[.](#algs.blas2.rank2-4.sentence-1)
|
||
|
||
[5](#algs.blas2.rank2-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15056)
|
||
|
||
*Complexity*: O(x.extent(0)Ãy.extent(0))[.](#algs.blas2.rank2-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_2_update)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[6](#algs.blas2.rank2-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15072)
|
||
|
||
These functions perform
|
||
a symmetric rank-2 update of the symmetric matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.rank2-6.sentence-1)
|
||
|
||
[7](#algs.blas2.rank2-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15078)
|
||
|
||
*Effects*: Computes Aâ² such that Aâ²=A+xyT+yxT and
|
||
assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.rank2-7.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_2_update)
|
||
|
||
`template<[in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t);
|
||
template<class ExecutionPolicy, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec1, [in-vector](#concept:in-vector "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InVec2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec,
|
||
InVec1 x, InVec2 y, InOutMat A, Triangle t);
|
||
`
|
||
|
||
[8](#algs.blas2.rank2-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15096)
|
||
|
||
These functions perform
|
||
a Hermitian rank-2 update of the Hermitian matrix A,
|
||
taking into account the Triangle parameter
|
||
that applies to A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas2.rank2-8.sentence-1)
|
||
|
||
[9](#algs.blas2.rank2-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15102)
|
||
|
||
*Effects*: Computes Aâ² such that Aâ²=A+xyH+yxH and
|
||
assigns each element of Aâ² to the corresponding element of A[.](#algs.blas2.rank2-9.sentence-1)
|
||
|
||
### [29.9.15](#algs.blas3) BLAS 3 algorithms [[linalg.algs.blas3]](linalg.algs.blas3)
|
||
|
||
#### [29.9.15.1](#algs.blas3.gemm) General matrix-matrix product [[linalg.algs.blas3.gemm]](linalg.algs.blas3.gemm)
|
||
|
||
[1](#algs.blas3.gemm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15112)
|
||
|
||
[*Note [1](#algs.blas3.gemm-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xGEMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.gemm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas3.gemm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15117)
|
||
|
||
The following elements apply
|
||
to all functions in [[linalg.algs.blas3.gemm]](#algs.blas3.gemm "29.9.15.1 General matrix-matrix product") in addition to function-specific elements[.](#algs.blas3.gemm-2.sentence-1)
|
||
|
||
[3](#algs.blas3.gemm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15122)
|
||
|
||
*Mandates*: *possibly-multipliable*<decltype(A), decltype(B), decltype(C)>() is true[.](#algs.blas3.gemm-3.sentence-1)
|
||
|
||
[4](#algs.blas3.gemm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15127)
|
||
|
||
*Preconditions*: *multipliable*(A, B, C) is true[.](#algs.blas3.gemm-4.sentence-1)
|
||
|
||
[5](#algs.blas3.gemm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15131)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#algs.blas3.gemm-5.sentence-1)
|
||
|
||
[ð](#lib:matrix_product)
|
||
|
||
` template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void matrix_product(InMat1 A, InMat2 B, OutMat C);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void matrix_product(ExecutionPolicy&& exec, InMat1 A, InMat2 B, OutMat C);
|
||
`
|
||
|
||
[6](#algs.blas3.gemm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15144)
|
||
|
||
*Effects*: Computes C=AB[.](#algs.blas3.gemm-6.sentence-1)
|
||
|
||
[ð](#lib:matrix_product_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void matrix_product(InMat1 A, InMat2 B, InMat3 E, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void matrix_product(ExecutionPolicy&& exec, InMat1 A, InMat2 B, InMat3 E, OutMat C);
|
||
`
|
||
|
||
[7](#algs.blas3.gemm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15159)
|
||
|
||
*Mandates*: *possibly-addable*<InMat3, InMat3, OutMat>() is true[.](#algs.blas3.gemm-7.sentence-1)
|
||
|
||
[8](#algs.blas3.gemm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15163)
|
||
|
||
*Preconditions*: *addable*(E, E, C) is true[.](#algs.blas3.gemm-8.sentence-1)
|
||
|
||
[9](#algs.blas3.gemm-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15167)
|
||
|
||
*Effects*: Computes C=E+AB[.](#algs.blas3.gemm-9.sentence-1)
|
||
|
||
[10](#algs.blas3.gemm-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15171)
|
||
|
||
*Remarks*: C may alias E[.](#algs.blas3.gemm-10.sentence-1)
|
||
|
||
#### [29.9.15.2](#algs.blas3.xxmm) Symmetric, Hermitian, and triangular matrix-matrix product [[linalg.algs.blas3.xxmm]](linalg.algs.blas3.xxmm)
|
||
|
||
[1](#algs.blas3.xxmm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15178)
|
||
|
||
[*Note [1](#algs.blas3.xxmm-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYMM, xHEMM, and xTRMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.xxmm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas3.xxmm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15184)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas3.xxmm]](#algs.blas3.xxmm "29.9.15.2 Symmetric, Hermitian, and triangular matrix-matrix product") in addition to function-specific elements[.](#algs.blas3.xxmm-2.sentence-1)
|
||
|
||
[3](#algs.blas3.xxmm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15188)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas3.xxmm-3.1)
|
||
|
||
*possibly-multipliable*<decltype(A), decltype(B), decltype(C)>() is true, and
|
||
|
||
- [(3.2)](#algs.blas3.xxmm-3.2)
|
||
|
||
*possibly-addable*<decltype(E), decltype(E), decltype(C)>() is true for those overloads that take an E parameter[.](#algs.blas3.xxmm-3.sentence-1)
|
||
|
||
[4](#algs.blas3.xxmm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15199)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas3.xxmm-4.1)
|
||
|
||
*multipliable*(A, B, C) is true, and
|
||
|
||
- [(4.2)](#algs.blas3.xxmm-4.2)
|
||
|
||
*addable*(E, E, C) is true for those overloads that take an E parameter[.](#algs.blas3.xxmm-4.sentence-1)
|
||
|
||
[5](#algs.blas3.xxmm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15209)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#algs.blas3.xxmm-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(ExecutionPolicy&& exec, InMat1 A, Triangle t, InMat2 B, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(ExecutionPolicy&& exec, InMat1 A, Triangle t, InMat2 B, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C);
|
||
`
|
||
|
||
[6](#algs.blas3.xxmm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15237)
|
||
|
||
These functions perform a matrix-matrix multiply,
|
||
taking into account
|
||
the Triangle and DiagonalStorage (if applicable) parameters
|
||
that apply to the symmetric, Hermitian, or triangular (respectively) matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.xxmm-6.sentence-1)
|
||
|
||
[7](#algs.blas3.xxmm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15243)
|
||
|
||
*Mandates*:
|
||
|
||
- [(7.1)](#algs.blas3.xxmm-7.1)
|
||
|
||
If InMat1 has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument; and
|
||
|
||
- [(7.2)](#algs.blas3.xxmm-7.2)
|
||
|
||
*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#algs.blas3.xxmm-7.sentence-1)
|
||
|
||
[8](#algs.blas3.xxmm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15254)
|
||
|
||
*Preconditions*: A.extent(0) == A.extent(1) is true[.](#algs.blas3.xxmm-8.sentence-1)
|
||
|
||
[9](#algs.blas3.xxmm-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15258)
|
||
|
||
*Effects*: Computes C=AB[.](#algs.blas3.xxmm-9.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_product_)
|
||
|
||
` template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C);
|
||
`
|
||
|
||
[10](#algs.blas3.xxmm-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15290)
|
||
|
||
These functions perform a matrix-matrix multiply,
|
||
taking into account
|
||
the Triangle and DiagonalStorage (if applicable) parameters
|
||
that apply to the symmetric, Hermitian, or triangular (respectively) matrix B ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.xxmm-10.sentence-1)
|
||
|
||
[11](#algs.blas3.xxmm-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15296)
|
||
|
||
*Mandates*:
|
||
|
||
- [(11.1)](#algs.blas3.xxmm-11.1)
|
||
|
||
If InMat2 has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument; and
|
||
|
||
- [(11.2)](#algs.blas3.xxmm-11.2)
|
||
|
||
*compatible-static-extents*<InMat2, InMat2>(0, 1) is true[.](#algs.blas3.xxmm-11.sentence-1)
|
||
|
||
[12](#algs.blas3.xxmm-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15307)
|
||
|
||
*Preconditions*: B.extent(0) == B.extent(1) is true[.](#algs.blas3.xxmm-12.sentence-1)
|
||
|
||
[13](#algs.blas3.xxmm-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15311)
|
||
|
||
*Effects*: Computes C=AB[.](#algs.blas3.xxmm-13.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_product__)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
|
||
OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
|
||
OutMat C);
|
||
`
|
||
|
||
[14](#algs.blas3.xxmm-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15349)
|
||
|
||
These functions perform
|
||
a potentially overwriting matrix-matrix multiply-add,
|
||
taking into account the Triangle and DiagonalStorage (if applicable) parameters
|
||
that apply to the symmetric, Hermitian, or triangular (respectively) matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.xxmm-14.sentence-1)
|
||
|
||
[15](#algs.blas3.xxmm-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15355)
|
||
|
||
*Mandates*:
|
||
|
||
- [(15.1)](#algs.blas3.xxmm-15.1)
|
||
|
||
If InMat1 has layout_blas_packed layout, then the
|
||
layout's Triangle template argument has the same type as
|
||
the function's Triangle template argument; and
|
||
|
||
- [(15.2)](#algs.blas3.xxmm-15.2)
|
||
|
||
*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#algs.blas3.xxmm-15.sentence-1)
|
||
|
||
[16](#algs.blas3.xxmm-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15366)
|
||
|
||
*Preconditions*: A.extent(0) == A.extent(1) is true[.](#algs.blas3.xxmm-16.sentence-1)
|
||
|
||
[17](#algs.blas3.xxmm-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15370)
|
||
|
||
*Effects*: Computes C=E+AB[.](#algs.blas3.xxmm-17.sentence-1)
|
||
|
||
[18](#algs.blas3.xxmm-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15374)
|
||
|
||
*Remarks*: C may alias E[.](#algs.blas3.xxmm-18.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_product___)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void symmetric_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
|
||
[out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void hermitian_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
|
||
|
||
template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
|
||
OutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_product(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
|
||
OutMat C);
|
||
`
|
||
|
||
[19](#algs.blas3.xxmm-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15412)
|
||
|
||
These functions perform
|
||
a potentially overwriting matrix-matrix multiply-add,
|
||
taking into account
|
||
the Triangle and DiagonalStorage (if applicable) parameters
|
||
that apply to the symmetric, Hermitian, or triangular (respectively) matrix B ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.xxmm-19.sentence-1)
|
||
|
||
[20](#algs.blas3.xxmm-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15419)
|
||
|
||
*Mandates*:
|
||
|
||
- [(20.1)](#algs.blas3.xxmm-20.1)
|
||
|
||
If InMat2 has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument; and
|
||
|
||
- [(20.2)](#algs.blas3.xxmm-20.2)
|
||
|
||
*compatible-static-extents*<InMat2, InMat2>(0, 1) is true[.](#algs.blas3.xxmm-20.sentence-1)
|
||
|
||
[21](#algs.blas3.xxmm-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15430)
|
||
|
||
*Preconditions*: B.extent(0) == B.extent(1) is true[.](#algs.blas3.xxmm-21.sentence-1)
|
||
|
||
[22](#algs.blas3.xxmm-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15434)
|
||
|
||
*Effects*: Computes C=E+AB[.](#algs.blas3.xxmm-22.sentence-1)
|
||
|
||
[23](#algs.blas3.xxmm-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15438)
|
||
|
||
*Remarks*: C may alias E[.](#algs.blas3.xxmm-23.sentence-1)
|
||
|
||
#### [29.9.15.3](#algs.blas3.trmm) In-place triangular matrix-matrix product [[linalg.algs.blas3.trmm]](linalg.algs.blas3.trmm)
|
||
|
||
[1](#algs.blas3.trmm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15445)
|
||
|
||
These functions perform
|
||
an in-place matrix-matrix multiply,
|
||
taking into account
|
||
the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.trmm-1.sentence-1)
|
||
|
||
[*Note [1](#algs.blas3.trmm-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xTRMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.trmm-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:triangular_matrix_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_left_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_left_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutMat C);
|
||
`
|
||
|
||
[2](#algs.blas3.trmm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15466)
|
||
|
||
*Mandates*:
|
||
|
||
- [(2.1)](#algs.blas3.trmm-2.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(2.2)](#algs.blas3.trmm-2.2)
|
||
|
||
*possibly-multipliable*<InMat, InOutMat, InOutMat>() is true; and
|
||
|
||
- [(2.3)](#algs.blas3.trmm-2.3)
|
||
|
||
*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#algs.blas3.trmm-2.sentence-1)
|
||
|
||
[3](#algs.blas3.trmm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15480)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(3.1)](#algs.blas3.trmm-3.1)
|
||
|
||
*multipliable*(A, C, C) is true, and
|
||
|
||
- [(3.2)](#algs.blas3.trmm-3.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.trmm-3.sentence-1)
|
||
|
||
[4](#algs.blas3.trmm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15489)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=AC and
|
||
assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.trmm-4.sentence-1)
|
||
|
||
[5](#algs.blas3.trmm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15494)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#algs.blas3.trmm-5.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_right_product)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_right_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_right_product(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d, InOutMat C);
|
||
`
|
||
|
||
[6](#algs.blas3.trmm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15510)
|
||
|
||
*Mandates*:
|
||
|
||
- [(6.1)](#algs.blas3.trmm-6.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(6.2)](#algs.blas3.trmm-6.2)
|
||
|
||
*possibly-multipliable*<InOutMat, InMat, InOutMat>() is true; and
|
||
|
||
- [(6.3)](#algs.blas3.trmm-6.3)
|
||
|
||
*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#algs.blas3.trmm-6.sentence-1)
|
||
|
||
[7](#algs.blas3.trmm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15524)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(7.1)](#algs.blas3.trmm-7.1)
|
||
|
||
*multipliable*(C, A, C) is true, and
|
||
|
||
- [(7.2)](#algs.blas3.trmm-7.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.trmm-7.sentence-1)
|
||
|
||
[8](#algs.blas3.trmm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15533)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=CA and
|
||
assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.trmm-8.sentence-1)
|
||
|
||
[9](#algs.blas3.trmm-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15538)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#algs.blas3.trmm-9.sentence-1)
|
||
|
||
#### [29.9.15.4](#algs.blas3.rankk) Rank-k update of a symmetric or Hermitian matrix [[linalg.algs.blas3.rankk]](linalg.algs.blas3.rankk)
|
||
|
||
[1](#algs.blas3.rankk-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15545)
|
||
|
||
[*Note [1](#algs.blas3.rankk-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYRK and xHERK[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.rankk-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas3.rankk-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15551)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas3.rankk]](#algs.blas3.rankk "29.9.15.4 Rank-k update of a symmetric or Hermitian matrix")[.](#algs.blas3.rankk-2.sentence-1)
|
||
|
||
[3](#algs.blas3.rankk-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15554)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas3.rankk-3.1)
|
||
|
||
If InOutMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas3.rankk-3.2)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;
|
||
|
||
- [(3.3)](#algs.blas3.rankk-3.3)
|
||
|
||
*compatible-static-extents*<decltype(C), decltype(C)>(0, 1) is true; and
|
||
|
||
- [(3.4)](#algs.blas3.rankk-3.4)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(C)>(0, 0) is true[.](#algs.blas3.rankk-3.sentence-1)
|
||
|
||
[4](#algs.blas3.rankk-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15572)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas3.rankk-4.1)
|
||
|
||
A.extent(0) equals A.extent(1),
|
||
|
||
- [(4.2)](#algs.blas3.rankk-4.2)
|
||
|
||
C.extent(0) equals C.extent(1), and
|
||
|
||
- [(4.3)](#algs.blas3.rankk-4.3)
|
||
|
||
A.extent(0) equals C.extent(0)[.](#algs.blas3.rankk-4.sentence-1)
|
||
|
||
[5](#algs.blas3.rankk-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15583)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#algs.blas3.rankk-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_k_update)
|
||
|
||
` template<class Scalar, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy, class Scalar,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InMat A, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[6](#algs.blas3.rankk-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15598)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+αAAT,
|
||
where the scalar α is alpha,
|
||
and assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rankk-6.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_k_update_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_k_update(InMat A, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
InMat A, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[7](#algs.blas3.rankk-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15616)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+AAT, and
|
||
assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rankk-7.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_k_update)
|
||
|
||
`template<class Scalar, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
class Scalar, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
Scalar alpha, InMat A, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[8](#algs.blas3.rankk-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15633)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+αAAH,
|
||
where the scalar α is alpha,
|
||
and assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rankk-8.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_k_update_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_k_update(InMat A, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
|
||
InMat A, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[9](#algs.blas3.rankk-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15651)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+AAH, and
|
||
assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rankk-9.sentence-1)
|
||
|
||
#### [29.9.15.5](#algs.blas3.rank2k) Rank-2k update of a symmetric or Hermitian matrix [[linalg.algs.blas3.rank2k]](linalg.algs.blas3.rank2k)
|
||
|
||
[1](#algs.blas3.rank2k-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15659)
|
||
|
||
[*Note [1](#algs.blas3.rank2k-note-1)*:
|
||
|
||
These functions correspond to the BLAS functionsxSYR2K and xHER2K[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.rank2k-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[2](#algs.blas3.rank2k-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15665)
|
||
|
||
The following elements apply to all functions in [[linalg.algs.blas3.rank2k]](#algs.blas3.rank2k "29.9.15.5 Rank-2k update of a symmetric or Hermitian matrix")[.](#algs.blas3.rank2k-2.sentence-1)
|
||
|
||
[3](#algs.blas3.rank2k-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15668)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas3.rank2k-3.1)
|
||
|
||
If InOutMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas3.rank2k-3.2)
|
||
|
||
*possibly-addable*<decltype(A), decltype(B), decltype(C)>() is true; and
|
||
|
||
- [(3.3)](#algs.blas3.rank2k-3.3)
|
||
|
||
*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true[.](#algs.blas3.rank2k-3.sentence-1)
|
||
|
||
[4](#algs.blas3.rank2k-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15683)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas3.rank2k-4.1)
|
||
|
||
*addable*(A, B, C) is true, and
|
||
|
||
- [(4.2)](#algs.blas3.rank2k-4.2)
|
||
|
||
A.extent(0) equals A.extent(1)[.](#algs.blas3.rank2k-4.sentence-1)
|
||
|
||
[5](#algs.blas3.rank2k-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15692)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#algs.blas3.rank2k-5.sentence-1)
|
||
|
||
[ð](#lib:symmetric_matrix_rank_2k_update)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[6](#algs.blas3.rank2k-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15708)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+ABT+BAT,
|
||
and assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rank2k-6.sentence-1)
|
||
|
||
[ð](#lib:hermitian_matrix_rank_2k_update)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
|
||
[possibly-packed-inout-matrix](#concept:possibly-packed-inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class Triangle>
|
||
void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec,
|
||
InMat1 A, InMat2 B, InOutMat C, Triangle t);
|
||
`
|
||
|
||
[7](#algs.blas3.rank2k-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15727)
|
||
|
||
*Effects*: Computes a matrix Câ² such that Câ²=C+ABH+BAH,
|
||
and assigns each element of Câ² to the corresponding element of C[.](#algs.blas3.rank2k-7.sentence-1)
|
||
|
||
#### [29.9.15.6](#algs.blas3.trsm) Solve multiple triangular linear systems [[linalg.algs.blas3.trsm]](linalg.algs.blas3.trsm)
|
||
|
||
[1](#algs.blas3.trsm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15735)
|
||
|
||
[*Note [1](#algs.blas3.trsm-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xTRSM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.trsm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_left_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide);
|
||
`
|
||
|
||
[2](#algs.blas3.trsm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15755)
|
||
|
||
These functions perform multiple matrix solves,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.trsm-2.sentence-1)
|
||
|
||
[3](#algs.blas3.trsm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15760)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas3.trsm-3.1)
|
||
|
||
If InMat1 has layout_blas_packed layout, then the
|
||
layout's Triangle template argument has the same type as
|
||
the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas3.trsm-3.2)
|
||
|
||
*possibly-multipliable*<InMat1, OutMat, InMat2>() is true; and
|
||
|
||
- [(3.3)](#algs.blas3.trsm-3.3)
|
||
|
||
*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#algs.blas3.trsm-3.sentence-1)
|
||
|
||
[4](#algs.blas3.trsm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15775)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas3.trsm-4.1)
|
||
|
||
*multipliable*(A, X, B) is true, and
|
||
|
||
- [(4.2)](#algs.blas3.trsm-4.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.trsm-4.sentence-1)
|
||
|
||
[5](#algs.blas3.trsm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15784)
|
||
|
||
*Effects*: Computes Xâ² such that AXâ²=B,
|
||
and assigns each element of Xâ² to the corresponding element of X[.](#algs.blas3.trsm-5.sentence-1)
|
||
|
||
If no such Xâ² exists,
|
||
then the elements of X are valid but unspecified[.](#algs.blas3.trsm-5.sentence-2)
|
||
|
||
[6](#algs.blas3.trsm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15791)
|
||
|
||
*Complexity*: O(A.extent(0)ÃX.extent(1)ÃX.extent(1))[.](#algs.blas3.trsm-6.sentence-1)
|
||
|
||
[7](#algs.blas3.trsm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15796)
|
||
|
||
[*Note [2](#algs.blas3.trsm-note-2)*:
|
||
|
||
Since the triangular matrix is on the left,
|
||
the desired divide implementation
|
||
in the case of noncommutative multiplication
|
||
is mathematically equivalent to yâ1x,
|
||
where x is the first argument and y is the second argument,
|
||
and yâ1 denotes the multiplicative inverse of y[.](#algs.blas3.trsm-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_matrix_left_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X);
|
||
`
|
||
|
||
[8](#algs.blas3.trsm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15815)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_left_solve(A, t, d, B, X, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve__)
|
||
|
||
`template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X);
|
||
`
|
||
|
||
[9](#algs.blas3.trsm-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15833)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_left_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, B, X, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_right_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X, BinaryDivideOp divide);
|
||
`
|
||
|
||
[10](#algs.blas3.trsm-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15858)
|
||
|
||
These functions perform multiple matrix solves,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.trsm-10.sentence-1)
|
||
|
||
[11](#algs.blas3.trsm-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15863)
|
||
|
||
*Mandates*:
|
||
|
||
- [(11.1)](#algs.blas3.trsm-11.1)
|
||
|
||
If InMat1 has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(11.2)](#algs.blas3.trsm-11.2)
|
||
|
||
*possibly-multipliable*<OutMat, InMat1, InMat2>() is true; and
|
||
|
||
- [(11.3)](#algs.blas3.trsm-11.3)
|
||
|
||
*compatible-static-extents*<InMat1, InMat1>(0,1) is true[.](#algs.blas3.trsm-11.sentence-1)
|
||
|
||
[12](#algs.blas3.trsm-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15876)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(12.1)](#algs.blas3.trsm-12.1)
|
||
|
||
*multipliable*(X, A, B) is true, and
|
||
|
||
- [(12.2)](#algs.blas3.trsm-12.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.trsm-12.sentence-1)
|
||
|
||
[13](#algs.blas3.trsm-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15885)
|
||
|
||
*Effects*: Computes Xâ² such that Xâ²A=B,
|
||
and assigns each element of Xâ² to the corresponding element of X[.](#algs.blas3.trsm-13.sentence-1)
|
||
|
||
If no such Xâ² exists,
|
||
then the elements of X are valid but unspecified[.](#algs.blas3.trsm-13.sentence-2)
|
||
|
||
[14](#algs.blas3.trsm-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15892)
|
||
|
||
*Complexity*: O( B.extent(0) â B.extent(1) â A.extent(1) )
|
||
|
||
[*Note [3](#algs.blas3.trsm-note-3)*:
|
||
|
||
Since the triangular matrix is on the right,
|
||
the desired divide implementation
|
||
in the case of noncommutative multiplication
|
||
is mathematically equivalent to xyâ1,
|
||
where x is the first argument and y is the second argument,
|
||
and yâ1 denotes the multiplicative inverse of y[.](#algs.blas3.trsm-14.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve_)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_matrix_right_solve(InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X);
|
||
`
|
||
|
||
[15](#algs.blas3.trsm-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15914)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_right_solve(A, t, d, B, X, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve__)
|
||
|
||
`template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](#concept:out-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") OutMat>
|
||
void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat1 A, Triangle t, DiagonalStorage d,
|
||
InMat2 B, OutMat X);
|
||
`
|
||
|
||
[16](#algs.blas3.trsm-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15932)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_right_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, B, X, divides<void>{});
|
||
|
||
#### [29.9.15.7](#algs.blas3.inplacetrsm) Solve multiple triangular linear systems in-place [[linalg.algs.blas3.inplacetrsm]](linalg.algs.blas3.inplacetrsm)
|
||
|
||
[1](#algs.blas3.inplacetrsm-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15943)
|
||
|
||
[*Note [1](#algs.blas3.inplacetrsm-note-1)*:
|
||
|
||
These functions correspond to the BLAS function xTRSM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#algs.blas3.inplacetrsm-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve___)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide);
|
||
`
|
||
|
||
[2](#algs.blas3.inplacetrsm-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15962)
|
||
|
||
These functions perform multiple in-place matrix solves,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.inplacetrsm-2.sentence-1)
|
||
|
||
[*Note [2](#algs.blas3.inplacetrsm-note-2)*:
|
||
|
||
This algorithm makes it possible
|
||
to compute factorizations like Cholesky and LU in place[.](#algs.blas3.inplacetrsm-2.sentence-2)
|
||
|
||
Performing triangular solve in place hinders parallelization[.](#algs.blas3.inplacetrsm-2.sentence-3)
|
||
|
||
However, other ExecutionPolicy specific optimizations,
|
||
such as vectorization, are still possible[.](#algs.blas3.inplacetrsm-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[3](#algs.blas3.inplacetrsm-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15974)
|
||
|
||
*Mandates*:
|
||
|
||
- [(3.1)](#algs.blas3.inplacetrsm-3.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(3.2)](#algs.blas3.inplacetrsm-3.2)
|
||
|
||
*possibly-multipliable*<InMat, InOutMat, InOutMat>() is true; and
|
||
|
||
- [(3.3)](#algs.blas3.inplacetrsm-3.3)
|
||
|
||
*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#algs.blas3.inplacetrsm-3.sentence-1)
|
||
|
||
[4](#algs.blas3.inplacetrsm-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15989)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(4.1)](#algs.blas3.inplacetrsm-4.1)
|
||
|
||
*multipliable*(A, B, B) is true, and
|
||
|
||
- [(4.2)](#algs.blas3.inplacetrsm-4.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.inplacetrsm-4.sentence-1)
|
||
|
||
[5](#algs.blas3.inplacetrsm-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15998)
|
||
|
||
*Effects*: Computes Xâ² such that AXâ²=B,
|
||
and assigns each element of Xâ² to the corresponding element of B[.](#algs.blas3.inplacetrsm-5.sentence-1)
|
||
|
||
If so such Xâ² exists,
|
||
then the elements of B are valid but unspecified[.](#algs.blas3.inplacetrsm-5.sentence-2)
|
||
|
||
[6](#algs.blas3.inplacetrsm-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16005)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#algs.blas3.inplacetrsm-6.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve____)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B);
|
||
`
|
||
|
||
[7](#algs.blas3.inplacetrsm-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16018)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_left_solve(A, t, d, B, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_left_solve_____)
|
||
|
||
` template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B);
|
||
`
|
||
|
||
[8](#algs.blas3.inplacetrsm-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16036)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_left_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, B, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve___)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide);
|
||
template<class ExecutionPolicy, [in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
|
||
[inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat, class BinaryDivideOp>
|
||
void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B, BinaryDivideOp divide);
|
||
`
|
||
|
||
[9](#algs.blas3.inplacetrsm-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16059)
|
||
|
||
These functions perform multiple in-place matrix solves,
|
||
taking into account the Triangle and DiagonalStorage parameters
|
||
that apply to the triangular matrix A ([[linalg.general]](#general "29.9.3 General"))[.](#algs.blas3.inplacetrsm-9.sentence-1)
|
||
|
||
[*Note [3](#algs.blas3.inplacetrsm-note-3)*:
|
||
|
||
This algorithm makes it possible
|
||
to compute factorizations like Cholesky and LU in place[.](#algs.blas3.inplacetrsm-9.sentence-2)
|
||
|
||
Performing triangular solve in place hinders parallelization[.](#algs.blas3.inplacetrsm-9.sentence-3)
|
||
|
||
However, other ExecutionPolicy specific optimizations,
|
||
such as vectorization, are still possible[.](#algs.blas3.inplacetrsm-9.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[10](#algs.blas3.inplacetrsm-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16071)
|
||
|
||
*Mandates*:
|
||
|
||
- [(10.1)](#algs.blas3.inplacetrsm-10.1)
|
||
|
||
If InMat has layout_blas_packed layout,
|
||
then the layout's Triangle template argument has
|
||
the same type as the function's Triangle template argument;
|
||
|
||
- [(10.2)](#algs.blas3.inplacetrsm-10.2)
|
||
|
||
*possibly-multipliable*<InOutMat, InMat, InOutMat>() is true; and
|
||
|
||
- [(10.3)](#algs.blas3.inplacetrsm-10.3)
|
||
|
||
*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#algs.blas3.inplacetrsm-10.sentence-1)
|
||
|
||
[11](#algs.blas3.inplacetrsm-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16085)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(11.1)](#algs.blas3.inplacetrsm-11.1)
|
||
|
||
*multipliable*(B, A, B) is true, and
|
||
|
||
- [(11.2)](#algs.blas3.inplacetrsm-11.2)
|
||
|
||
A.extent(0) == A.extent(1) is true[.](#algs.blas3.inplacetrsm-11.sentence-1)
|
||
|
||
[12](#algs.blas3.inplacetrsm-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16094)
|
||
|
||
*Effects*: Computes Xâ² such that Xâ²A=B,
|
||
and assigns each element of Xâ² to the corresponding element of B[.](#algs.blas3.inplacetrsm-12.sentence-1)
|
||
|
||
If so such Xâ² exists,
|
||
then the elements of B are valid but unspecified[.](#algs.blas3.inplacetrsm-12.sentence-2)
|
||
|
||
[13](#algs.blas3.inplacetrsm-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16101)
|
||
|
||
*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#algs.blas3.inplacetrsm-13.sentence-1)
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve____)
|
||
|
||
`template<[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d, InOutMat B);
|
||
`
|
||
|
||
[14](#algs.blas3.inplacetrsm-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16113)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_right_solve(A, t, d, B, divides<void>{});
|
||
|
||
[ð](#lib:triangular_matrix_matrix_right_solve_____)
|
||
|
||
`template<class ExecutionPolicy,
|
||
[in-matrix](#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](#concept:inout-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InOutMat>
|
||
void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
|
||
InMat A, Triangle t, DiagonalStorage d,
|
||
InOutMat B);
|
||
`
|
||
|
||
[15](#algs.blas3.inplacetrsm-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16131)
|
||
|
||
*Effects*: Equivalent to:triangular_matrix_matrix_right_solve(std::forward<ExecutionPolicy>(exec),
|
||
A, t, d, B, divides<void>{});
|