[linalg.algs.blas3.inplacetrsm]

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

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

### 29.9.15 BLAS 3 algorithms [[linalg.algs.blas3]](linalg.algs.blas3#inplacetrsm)

#### 29.9.15.7 Solve multiple triangular linear systems in-place [linalg.algs.blas3.inplacetrsm]

[1](#1)

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

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

These functions correspond to the BLAS function xTRSM[[bib]](bibliography#bib:blas3 "Bibliography")[.](#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](#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"))[.](#2.sentence-1)

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

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

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

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

â *end note*]

[3](#3)

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

*Mandates*: 

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

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

- [(3.3)](#3.3)

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

[4](#4)

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

*Preconditions*: 

- [(4.1)](#4.1)

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

- [(4.2)](#4.2)

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

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

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

[6](#6)

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

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#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](#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](#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](#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"))[.](#9.sentence-1)

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

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

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

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

â *end note*]

[10](#10)

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

*Mandates*: 

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

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

- [(10.3)](#10.3)

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

[11](#11)

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

*Preconditions*: 

- [(11.1)](#11.1)

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

- [(11.2)](#11.2)

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

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

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

[13](#13)

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

*Complexity*: O(A.extent(0)ÃA.extent(1)ÃB.extent(1))[.](#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](#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](#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>{});
