[linalg.general]

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

## 29.9 Basic linear algebra algorithms [[linalg]](linalg#general)

### 29.9.3 General [linalg.general]

[1](#1)

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

For the effects of all functions in [[linalg]](linalg "29.9 Basic linear algebra algorithms"),
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)](#1.1)

  E has
 the conventional mathematical meaning as written[.](#1.1.sentence-1)

- [(1.2)](#1.2)

  The pattern xT should be read as
 âthe transpose of x[.](#1.2.sentence-1)â

- [(1.3)](#1.3)

  The pattern xH should be read as
 âthe conjugate transpose of x[.](#1.3.sentence-1)â

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

[2](#2)

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

Some of the functions and types in [[linalg]](linalg "29.9 Basic linear algebra algorithms") distinguish between
the ârowsâ and the âcolumnsâ of a matrix[.](#2.sentence-1)

For a matrix A and a multidimensional index i, j in A.extents(),

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

[3](#3)

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

Some of the functions in [[linalg]](linalg "29.9 Basic linear algebra algorithms") distinguish between
the âupper triangle,â âlower triangle,â and âdiagonalâ of a matrix[.](#3.sentence-1)

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

- [(3.2)](#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[.](#3.2.sentence-1)
  It includes the diagonal[.](#3.2.sentence-2)

- [(3.3)](#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[.](#3.3.sentence-1)
  It includes the diagonal[.](#3.3.sentence-2)

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

Let m be such an access-modified function parameter[.](#4.sentence-2)

F will only access the triangle of m specified by t[.](#4.sentence-3)

For accesses m[i, j] outside the triangle specified by t,F will use the value

- [(4.1)](#4.1)

*conj-if-needed*(m[j, i]) if the name of F starts with hermitian,

- [(4.2)](#4.2)

m[j, i] if the name of F starts with symmetric, or

- [(4.3)](#4.3)

the additive identity if the name of F starts with triangular[.](#4.sentence-4)

[*Example [1](#example-1)*:

Small vector product accessing only specified triangle[.](#4.sentence-5)

It would not be a precondition violation for the non-accessed
matrix element to be non-zero[.](#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](#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[.](#5.sentence-1)

Let m be such an access-modified function parameter[.](#5.sentence-2)

If d specifies that an implicit unit diagonal is to be assumed, then

- [(5.1)](#5.1)

F will not access the diagonal of m; and

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

Otherwise,
if d specifies that an explicit diagonal is to be assumed,
then F will access the diagonal of m[.](#5.sentence-4)

[6](#6)

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

Within all the functions in [[linalg]](linalg "29.9 Basic linear algebra algorithms"),
any calls to abs, conj, imag, and real are unqualified[.](#6.sentence-1)

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

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

This means thatx and y view the same elements in the same order[.](#7.sentence-2)

â *end note*]

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

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

Aliasing is a special case of overlapping[.](#8.sentence-2)

If x and y do not overlap,
then they also do not alias each other[.](#8.sentence-3)

â *end note*]
