#
For the effects of all functions in [linalg], when the effects are described as “computes
2
#
Some of the functions and types in [linalg] distinguish between the “rows” and the “columns” of a matrix.
For a matrix A and a multidimensional index i, j in A.extents(),
  • row i of A is the set of elements A[i, k1] for all k1 such that i, k1 is in A.extents(); and
  • column j of A is the set of elements A[k0, j] for all k0 such that k0, j is in A.extents().
Some of the functions in [linalg] distinguish between the “upper triangle,” “lower triangle,” and “diagonal” of a matrix.
  • The diagonal is the set of all elements of A accessed by A[i,i] for 0  ≤  i < min(A.extent(0), A.extent(1)).
  • The upper triangle of a matrix A is the set of all elements of A accessed by A[i,j] with i  ≤  j.
    It includes the diagonal.
  • The lower triangle of A is the set of all elements of A accessed by A[i,j] with i  ≥  j.
    It includes the diagonal.
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.
Let m be such an access-modified function parameter.
F will only access the triangle of m specified by t.
For accesses of diagonal elements m[i, i], F will use the value real-if-needed(m[i, i]) if the name of F starts with hermitian.
For accesses m[i, j] outside the triangle specified by t, F will use the value
  • conj-if-needed(m[j, i]) if the name of F starts with hermitian,
  • m[j, i] if the name of F starts with symmetric, or
  • the additive identity if the name of F starts with triangular.
[Example 1: 
Small vector product accessing only specified triangle.
It would not be a precondition violation for the non-accessed matrix element to be non-zero.
template<class Triangle> void triangular_matrix_vector_2x2_product( mdspan<const float, extents<int, 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]
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.
Let m be such an access-modified function parameter.
If d specifies that an implicit unit diagonal is to be assumed, then
  • F will not access the diagonal of m; and
  • 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).
Otherwise, if d specifies that an explicit diagonal is to be assumed, then F will access the diagonal of m.
Within all the functions in [linalg], any calls to abs, conj, imag, and real are unqualified.
Two mdspan objects x and y 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.
[Note 1: 
This means that x and y view the same elements in the same order.
— end note]
Two mdspan objects x and y 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.
[Note 2: 
Aliasing is a special case of overlapping.
If x and y do not overlap, then they also do not alias each other.
— end note]

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant