[linalg.algs.blas3.trsm]

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

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

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

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

[1](#1)

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

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

[3](#3)

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

*Mandates*: 

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

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

- [(3.3)](#3.3)

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

[4](#4)

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

*Preconditions*: 

- [(4.1)](#4.1)

*multipliable*(A, X, 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#L15784)

*Effects*: Computes Xâ² such that AXâ²=B,
and assigns each element of Xâ² to the corresponding element of X[.](#5.sentence-1)

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

[6](#6)

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

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

[7](#7)

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

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

[11](#11)

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

*Mandates*: 

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

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

- [(11.3)](#11.3)

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

[12](#12)

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

*Preconditions*: 

- [(12.1)](#12.1)

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

- [(12.2)](#12.2)

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

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

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

[14](#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](#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[.](#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](#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](#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>{});
