[linalg.algs.blas3]

# 29 Numerics library [[numerics]](./#numerics)

## 29.9 Basic linear algebra algorithms [[linalg]](linalg#algs.blas3)

### 29.9.15 BLAS 3 algorithms [linalg.algs.blas3]

#### [29.9.15.1](#gemm) General matrix-matrix product [[linalg.algs.blas3.gemm]](linalg.algs.blas3.gemm)

[1](#gemm-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15112)

[*Note [1](#gemm-note-1)*:

These functions correspond to the BLAS function xGEMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#gemm-1.sentence-1)

â *end note*]

[2](#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]](#gemm "29.9.15.1 General matrix-matrix product") in addition to function-specific elements[.](#gemm-2.sentence-1)

[3](#gemm-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15122)

*Mandates*: *possibly-multipliable*<decltype(A), decltype(B), decltype(C)>() is true[.](#gemm-3.sentence-1)

[4](#gemm-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15127)

*Preconditions*: *multipliable*(A, B, C) is true[.](#gemm-4.sentence-1)

[5](#gemm-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15131)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#gemm-5.sentence-1)

[ð](#lib:matrix_product)

`  template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#gemm-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15144)

*Effects*: Computes C=AB[.](#gemm-6.sentence-1)

[ð](#lib:matrix_product_)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](#gemm-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15159)

*Mandates*: *possibly-addable*<InMat3, InMat3, OutMat>() is true[.](#gemm-7.sentence-1)

[8](#gemm-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15163)

*Preconditions*: *addable*(E, E, C) is true[.](#gemm-8.sentence-1)

[9](#gemm-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15167)

*Effects*: Computes C=E+AB[.](#gemm-9.sentence-1)

[10](#gemm-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15171)

*Remarks*: C may alias E[.](#gemm-10.sentence-1)

#### [29.9.15.2](#xxmm) Symmetric, Hermitian, and triangular matrix-matrix product [[linalg.algs.blas3.xxmm]](linalg.algs.blas3.xxmm)

[1](#xxmm-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15178)

[*Note [1](#xxmm-note-1)*:

These functions correspond to the BLAS functionsxSYMM, xHEMM, and xTRMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#xxmm-1.sentence-1)

â *end note*]

[2](#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]](#xxmm "29.9.15.2 Symmetric, Hermitian, and triangular matrix-matrix product") in addition to function-specific elements[.](#xxmm-2.sentence-1)

[3](#xxmm-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15188)

*Mandates*: 

- [(3.1)](#xxmm-3.1)

*possibly-multipliable*<decltype(A), decltype(B), decltype(C)>() is true, and

- [(3.2)](#xxmm-3.2)

*possibly-addable*<decltype(E), decltype(E), decltype(C)>() is true for those overloads that take an E parameter[.](#xxmm-3.sentence-1)

[4](#xxmm-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15199)

*Preconditions*: 

- [(4.1)](#xxmm-4.1)

*multipliable*(A, B, C) is true, and

- [(4.2)](#xxmm-4.2)

*addable*(E, E, C) is true for those overloads that take an E parameter[.](#xxmm-4.sentence-1)

[5](#xxmm-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15209)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#xxmm-5.sentence-1)

[ð](#lib:symmetric_matrix_product)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#xxmm-6.sentence-1)

[7](#xxmm-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15243)

*Mandates*: 

- [(7.1)](#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)](#xxmm-7.2)

*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#xxmm-7.sentence-1)

[8](#xxmm-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15254)

*Preconditions*: A.extent(0) == A.extent(1) is true[.](#xxmm-8.sentence-1)

[9](#xxmm-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15258)

*Effects*: Computes C=AB[.](#xxmm-9.sentence-1)

[ð](#lib:symmetric_matrix_product_)

`  template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
           [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
           [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#xxmm-10.sentence-1)

[11](#xxmm-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15296)

*Mandates*: 

- [(11.1)](#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)](#xxmm-11.2)

*compatible-static-extents*<InMat2, InMat2>(0, 1) is true[.](#xxmm-11.sentence-1)

[12](#xxmm-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15307)

*Preconditions*: B.extent(0) == B.extent(1) is true[.](#xxmm-12.sentence-1)

[13](#xxmm-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15311)

*Effects*: Computes C=AB[.](#xxmm-13.sentence-1)

[ð](#lib:symmetric_matrix_product__)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#xxmm-14.sentence-1)

[15](#xxmm-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15355)

*Mandates*: 

- [(15.1)](#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)](#xxmm-15.2)

*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#xxmm-15.sentence-1)

[16](#xxmm-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15366)

*Preconditions*: A.extent(0) == A.extent(1) is true[.](#xxmm-16.sentence-1)

[17](#xxmm-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15370)

*Effects*: Computes C=E+AB[.](#xxmm-17.sentence-1)

[18](#xxmm-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15374)

*Remarks*: C may alias E[.](#xxmm-18.sentence-1)

[ð](#lib:symmetric_matrix_product___)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3,
         [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat3, [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#xxmm-19.sentence-1)

[20](#xxmm-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15419)

*Mandates*: 

- [(20.1)](#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)](#xxmm-20.2)

*compatible-static-extents*<InMat2, InMat2>(0, 1) is true[.](#xxmm-20.sentence-1)

[21](#xxmm-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15430)

*Preconditions*: B.extent(0) == B.extent(1) is true[.](#xxmm-21.sentence-1)

[22](#xxmm-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15434)

*Effects*: Computes C=E+AB[.](#xxmm-22.sentence-1)

[23](#xxmm-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15438)

*Remarks*: C may alias E[.](#xxmm-23.sentence-1)

#### [29.9.15.3](#trmm) In-place triangular matrix-matrix product [[linalg.algs.blas3.trmm]](linalg.algs.blas3.trmm)

[1](#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]](linalg.general "29.9.3 General"))[.](#trmm-1.sentence-1)

[*Note [1](#trmm-note-1)*:

These functions correspond to the BLAS function xTRMM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#trmm-1.sentence-2)

â *end note*]

[ð](#lib:triangular_matrix_product)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#trmm-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15466)

*Mandates*: 

- [(2.1)](#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)](#trmm-2.2)

*possibly-multipliable*<InMat, InOutMat, InOutMat>() is true; and

- [(2.3)](#trmm-2.3)

*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#trmm-2.sentence-1)

[3](#trmm-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15480)

*Preconditions*: 

- [(3.1)](#trmm-3.1)

*multipliable*(A, C, C) is true, and

- [(3.2)](#trmm-3.2)

A.extent(0) == A.extent(1) is true[.](#trmm-3.sentence-1)

[4](#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[.](#trmm-4.sentence-1)

[5](#trmm-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15494)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#trmm-5.sentence-1)

[ð](#lib:triangular_matrix_right_product)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#trmm-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15510)

*Mandates*: 

- [(6.1)](#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)](#trmm-6.2)

*possibly-multipliable*<InOutMat, InMat, InOutMat>() is true; and

- [(6.3)](#trmm-6.3)

*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#trmm-6.sentence-1)

[7](#trmm-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15524)

*Preconditions*: 

- [(7.1)](#trmm-7.1)

*multipliable*(C, A, C) is true, and

- [(7.2)](#trmm-7.2)

A.extent(0) == A.extent(1) is true[.](#trmm-7.sentence-1)

[8](#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[.](#trmm-8.sentence-1)

[9](#trmm-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15538)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#trmm-9.sentence-1)

#### [29.9.15.4](#rankk) Rank-k update of a symmetric or Hermitian matrix [[linalg.algs.blas3.rankk]](linalg.algs.blas3.rankk)

[1](#rankk-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15545)

[*Note [1](#rankk-note-1)*:

These functions correspond to the BLAS functionsxSYRK and xHERK[[bib]](bibliography#bib:blas3 "Bibliography")[.](#rankk-1.sentence-1)

â *end note*]

[2](#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]](#rankk "29.9.15.4 Rank-k update of a symmetric or Hermitian matrix")[.](#rankk-2.sentence-1)

[3](#rankk-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15554)

*Mandates*: 

- [(3.1)](#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)](#rankk-3.2)

*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true;

- [(3.3)](#rankk-3.3)

*compatible-static-extents*<decltype(C), decltype(C)>(0, 1) is true; and

- [(3.4)](#rankk-3.4)

*compatible-static-extents*<decltype(A), decltype(C)>(0, 0) is true[.](#rankk-3.sentence-1)

[4](#rankk-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15572)

*Preconditions*: 

- [(4.1)](#rankk-4.1)

A.extent(0) equals A.extent(1),

- [(4.2)](#rankk-4.2)

C.extent(0) equals C.extent(1), and

- [(4.3)](#rankk-4.3)

A.extent(0) equals C.extent(0)[.](#rankk-4.sentence-1)

[5](#rankk-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15583)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#rankk-5.sentence-1)

[ð](#lib:symmetric_matrix_rank_k_update)

`  template<class Scalar, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rankk-6.sentence-1)

[ð](#lib:symmetric_matrix_rank_k_update_)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rankk-7.sentence-1)

[ð](#lib:hermitian_matrix_rank_k_update)

`template<class Scalar, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rankk-8.sentence-1)

[ð](#lib:hermitian_matrix_rank_k_update_)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rankk-9.sentence-1)

#### [29.9.15.5](#rank2k) Rank-2k update of a symmetric or Hermitian matrix [[linalg.algs.blas3.rank2k]](linalg.algs.blas3.rank2k)

[1](#rank2k-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15659)

[*Note [1](#rank2k-note-1)*:

These functions correspond to the BLAS functionsxSYR2K and xHER2K[[bib]](bibliography#bib:blas3 "Bibliography")[.](#rank2k-1.sentence-1)

â *end note*]

[2](#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]](#rank2k "29.9.15.5 Rank-2k update of a symmetric or Hermitian matrix")[.](#rank2k-2.sentence-1)

[3](#rank2k-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15668)

*Mandates*: 

- [(3.1)](#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)](#rank2k-3.2)

*possibly-addable*<decltype(A), decltype(B), decltype(C)>() is true; and

- [(3.3)](#rank2k-3.3)

*compatible-static-extents*<decltype(A), decltype(A)>(0, 1) is true[.](#rank2k-3.sentence-1)

[4](#rank2k-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15683)

*Preconditions*: 

- [(4.1)](#rank2k-4.1)

*addable*(A, B, C) is true, and

- [(4.2)](#rank2k-4.2)

A.extent(0) equals A.extent(1)[.](#rank2k-4.sentence-1)

[5](#rank2k-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15692)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃC.extent(0))[.](#rank2k-5.sentence-1)

[ð](#lib:symmetric_matrix_rank_2k_update)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
         [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
         [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rank2k-6.sentence-1)

[ð](#lib:hermitian_matrix_rank_2k_update)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
         [possibly-packed-inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2,
         [possibly-packed-inout-matrix](linalg.helpers.concepts#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](#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[.](#rank2k-7.sentence-1)

#### [29.9.15.6](#trsm) Solve multiple triangular linear systems [[linalg.algs.blas3.trsm]](linalg.algs.blas3.trsm)

[1](#trsm-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15735)

[*Note [1](#trsm-note-1)*:

These functions correspond to the BLAS function xTRSM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#trsm-1.sentence-1)

â *end note*]

[ð](#lib:triangular_matrix_matrix_left_solve)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#trsm-2.sentence-1)

[3](#trsm-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15760)

*Mandates*: 

- [(3.1)](#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)](#trsm-3.2)

*possibly-multipliable*<InMat1, OutMat, InMat2>() is true; and

- [(3.3)](#trsm-3.3)

*compatible-static-extents*<InMat1, InMat1>(0, 1) is true[.](#trsm-3.sentence-1)

[4](#trsm-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15775)

*Preconditions*: 

- [(4.1)](#trsm-4.1)

*multipliable*(A, X, B) is true, and

- [(4.2)](#trsm-4.2)

A.extent(0) == A.extent(1) is true[.](#trsm-4.sentence-1)

[5](#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[.](#trsm-5.sentence-1)

If no such Xâ² exists,
then the elements of X are valid but unspecified[.](#trsm-5.sentence-2)

[6](#trsm-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15791)

*Complexity*: O(A.extent(0)ÃX.extent(1)ÃX.extent(1))[.](#trsm-6.sentence-1)

[7](#trsm-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15796)

[*Note [2](#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[.](#trsm-7.sentence-1)

â *end note*]

[ð](#lib:triangular_matrix_matrix_left_solve_)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#trsm-10.sentence-1)

[11](#trsm-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15863)

*Mandates*: 

- [(11.1)](#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)](#trsm-11.2)

*possibly-multipliable*<OutMat, InMat1, InMat2>() is true; and

- [(11.3)](#trsm-11.3)

*compatible-static-extents*<InMat1, InMat1>(0,1) is true[.](#trsm-11.sentence-1)

[12](#trsm-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15876)

*Preconditions*: 

- [(12.1)](#trsm-12.1)

*multipliable*(X, A, B) is true, and

- [(12.2)](#trsm-12.2)

A.extent(0) == A.extent(1) is true[.](#trsm-12.sentence-1)

[13](#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[.](#trsm-13.sentence-1)

If no such Xâ² exists,
then the elements of X are valid but unspecified[.](#trsm-13.sentence-2)

[14](#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](#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[.](#trsm-14.sentence-1)

â *end note*]

[ð](#lib:triangular_matrix_matrix_right_solve_)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat1, class Triangle, class DiagonalStorage,
         [in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat2, [out-matrix](linalg.helpers.concepts#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](#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](#inplacetrsm) Solve multiple triangular linear systems in-place [[linalg.algs.blas3.inplacetrsm]](linalg.algs.blas3.inplacetrsm)

[1](#inplacetrsm-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15943)

[*Note [1](#inplacetrsm-note-1)*:

These functions correspond to the BLAS function xTRSM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#inplacetrsm-1.sentence-1)

â *end note*]

[ð](#lib:triangular_matrix_matrix_left_solve___)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
         [inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
         [inout-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#inplacetrsm-2.sentence-1)

[*Note [2](#inplacetrsm-note-2)*:

This algorithm makes it possible
to compute factorizations like Cholesky and LU in place[.](#inplacetrsm-2.sentence-2)

Performing triangular solve in place hinders parallelization[.](#inplacetrsm-2.sentence-3)

However, other ExecutionPolicy specific optimizations,
such as vectorization, are still possible[.](#inplacetrsm-2.sentence-4)

â *end note*]

[3](#inplacetrsm-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15974)

*Mandates*: 

- [(3.1)](#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)](#inplacetrsm-3.2)

*possibly-multipliable*<InMat, InOutMat, InOutMat>() is true; and

- [(3.3)](#inplacetrsm-3.3)

*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#inplacetrsm-3.sentence-1)

[4](#inplacetrsm-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L15989)

*Preconditions*: 

- [(4.1)](#inplacetrsm-4.1)

*multipliable*(A, B, B) is true, and

- [(4.2)](#inplacetrsm-4.2)

A.extent(0) == A.extent(1) is true[.](#inplacetrsm-4.sentence-1)

[5](#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[.](#inplacetrsm-5.sentence-1)

If so such Xâ² exists,
then the elements of B are valid but unspecified[.](#inplacetrsm-5.sentence-2)

[6](#inplacetrsm-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16005)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#inplacetrsm-6.sentence-1)

[ð](#lib:triangular_matrix_matrix_left_solve____)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
         [inout-matrix](linalg.helpers.concepts#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage,
         [inout-matrix](linalg.helpers.concepts#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](#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]](linalg.general "29.9.3 General"))[.](#inplacetrsm-9.sentence-1)

[*Note [3](#inplacetrsm-note-3)*:

This algorithm makes it possible
to compute factorizations like Cholesky and LU in place[.](#inplacetrsm-9.sentence-2)

Performing triangular solve in place hinders parallelization[.](#inplacetrsm-9.sentence-3)

However, other ExecutionPolicy specific optimizations,
such as vectorization, are still possible[.](#inplacetrsm-9.sentence-4)

â *end note*]

[10](#inplacetrsm-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16071)

*Mandates*: 

- [(10.1)](#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)](#inplacetrsm-10.2)

*possibly-multipliable*<InOutMat, InMat, InOutMat>() is true; and

- [(10.3)](#inplacetrsm-10.3)

*compatible-static-extents*<InMat, InMat>(0, 1) is true[.](#inplacetrsm-10.sentence-1)

[11](#inplacetrsm-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16085)

*Preconditions*: 

- [(11.1)](#inplacetrsm-11.1)

*multipliable*(B, A, B) is true, and

- [(11.2)](#inplacetrsm-11.2)

A.extent(0) == A.extent(1) is true[.](#inplacetrsm-11.sentence-1)

[12](#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[.](#inplacetrsm-12.sentence-1)

If so such Xâ² exists,
then the elements of B are valid but unspecified[.](#inplacetrsm-12.sentence-2)

[13](#inplacetrsm-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16101)

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#inplacetrsm-13.sentence-1)

[ð](#lib:triangular_matrix_matrix_right_solve____)

`template<[in-matrix](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#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](linalg.helpers.concepts#concept:in-matrix "29.9.7.5 Argument concepts [linalg.helpers.concepts]") InMat, class Triangle, class DiagonalStorage, [inout-matrix](linalg.helpers.concepts#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](#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>{});
