28.9 Basic linear algebra algorithms [linalg]
namespace std::linalg {
  
  struct column_major_t;
  inline constexpr column_major_t column_major;
  struct row_major_t;
  inline constexpr row_major_t row_major;
  
  struct upper_triangle_t;
  inline constexpr upper_triangle_t upper_triangle;
  struct lower_triangle_t;
  inline constexpr lower_triangle_t lower_triangle;
  
  struct implicit_unit_diagonal_t;
  inline constexpr implicit_unit_diagonal_t implicit_unit_diagonal;
  struct explicit_diagonal_t;
  inline constexpr explicit_diagonal_t explicit_diagonal;
  
  template<class Triangle, class StorageOrder>
    class layout_blas_packed;
  
  
  template<class T>
    constexpr bool is-mdspan = see below;               
  template<class T>
    concept in-vector = see below;                      
  template<class T>
    concept out-vector = see below;                     
  template<class T>
    concept inout-vector = see below;                   
  template<class T>
    concept in-matrix = see below;                      
  template<class T>
    concept out-matrix = see below;                     
  template<class T>
    concept inout-matrix = see below;                   
  template<class T>
    concept possibly-packed-inout-matrix = see below;   
  template<class T>
    concept in-object = see below;                      
  template<class T>
    concept out-object = see below;                     
  template<class T>
    concept inout-object = see below;                   
  
  
  template<class ScalingFactor, class NestedAccessor>
    class scaled_accessor;
  
  template<class ScalingFactor,
           class ElementType, class Extents, class Layout, class Accessor>
    constexpr auto scaled(ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x);
  
  
  template<class NestedAccessor>
    class conjugated_accessor;
  
  template<class ElementType, class Extents, class Layout, class Accessor>
    constexpr auto conjugated(mdspan<ElementType, Extents, Layout, Accessor> a);
  
  
  template<class Layout>
    class layout_transpose;
  
  template<class ElementType, class Extents, class Layout, class Accessor>
    constexpr auto transposed(mdspan<ElementType, Extents, Layout, Accessor> a);
  
  template<class ElementType, class Extents, class Layout, class Accessor>
    constexpr auto conjugate_transposed(mdspan<ElementType, Extents, Layout, Accessor> a);
  
  
  
  template<class Real>
    struct setup_givens_rotation_result {
      Real c;
      Real s;
      Real r;
    };
  template<class Real>
    struct setup_givens_rotation_result<complex<Real>> {
      Real c;
      complex<Real> s;
      complex<Real> r;
    };
  template<class Real>
    setup_givens_rotation_result<Real> setup_givens_rotation(Real a, Real b) noexcept;
  template<class Real>
    setup_givens_rotation_result<complex<Real>>
      setup_givens_rotation(complex<Real> a, complex<Real> b) noexcept;
  
  template<inout-vector InOutVec1, inout-vector InOutVec2, class Real>
    void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, Real s);
  template<class ExecutionPolicy, inout-vector InOutVec1, inout-vector InOutVec2, class Real>
    void apply_givens_rotation(ExecutionPolicy&& exec,
                               InOutVec1 x, InOutVec2 y, Real c, Real s);
  template<inout-vector InOutVec1, inout-vector InOutVec2, class Real>
    void apply_givens_rotation(InOutVec1 x, InOutVec2 y, Real c, complex<Real> s);
  template<class ExecutionPolicy, inout-vector InOutVec1, inout-vector InOutVec2, class Real>
    void apply_givens_rotation(ExecutionPolicy&& exec,
                               InOutVec1 x, InOutVec2 y, Real c, complex<Real> s);
  
  template<inout-object InOutObj1, inout-object InOutObj2>
    void swap_elements(InOutObj1 x, InOutObj2 y);
  template<class ExecutionPolicy, inout-object InOutObj1, inout-object InOutObj2>
    void swap_elements(ExecutionPolicy&& exec,
                       InOutObj1 x, InOutObj2 y);
  
  template<class Scalar, inout-object InOutObj>
    void scale(Scalar alpha, InOutObj x);
  template<class ExecutionPolicy, class Scalar, inout-object InOutObj>
    void scale(ExecutionPolicy&& exec,
               Scalar alpha, InOutObj x);
  
  template<in-object InObj, out-object OutObj>
    void copy(InObj x, OutObj y);
  template<class ExecutionPolicy, in-object InObj, out-object OutObj>
    void copy(ExecutionPolicy&& exec,
              InObj x, OutObj y);
  
  template<in-object InObj1, in-object InObj2, out-object OutObj>
    void add(InObj1 x, InObj2 y, OutObj z);
  template<class ExecutionPolicy, in-object InObj1, in-object InObj2, out-object OutObj>
    void add(ExecutionPolicy&& exec,
             InObj1 x, InObj2 y, OutObj z);
  
  template<in-vector InVec1, in-vector InVec2, class Scalar>
    Scalar dot(InVec1 v1, InVec2 v2, Scalar init);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2, class Scalar>
    Scalar dot(ExecutionPolicy&& exec,
               InVec1 v1, InVec2 v2, Scalar init);
  template<in-vector InVec1, in-vector InVec2>
    auto dot(InVec1 v1, InVec2 v2);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2>
    auto dot(ExecutionPolicy&& exec,
             InVec1 v1, InVec2 v2);
  template<in-vector InVec1, in-vector InVec2, class Scalar>
    Scalar dotc(InVec1 v1, InVec2 v2, Scalar init);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2, class Scalar>
    Scalar dotc(ExecutionPolicy&& exec,
                InVec1 v1, InVec2 v2, Scalar init);
  template<in-vector InVec1, in-vector InVec2>
    auto dotc(InVec1 v1, InVec2 v2);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2>
    auto dotc(ExecutionPolicy&& exec,
              InVec1 v1, InVec2 v2);
  
  template<class Scalar>
    struct sum_of_squares_result {
      Scalar scaling_factor;
      Scalar scaled_sum_of_squares;
    };
  template<in-vector InVec, class Scalar>
    sum_of_squares_result<Scalar>
      vector_sum_of_squares(InVec v, sum_of_squares_result<Scalar> init);
  template<class ExecutionPolicy, in-vector InVec, class Scalar>
    sum_of_squares_result<Scalar>
      vector_sum_of_squares(ExecutionPolicy&& exec,
                            InVec v, sum_of_squares_result<Scalar> init);
  
  template<in-vector InVec, class Scalar>
    Scalar vector_two_norm(InVec v, Scalar init);
  template<class ExecutionPolicy, in-vector InVec, class Scalar>
    Scalar vector_two_norm(ExecutionPolicy&& exec, InVec v, Scalar init);
  template<in-vector InVec>
    auto vector_two_norm(InVec v);
  template<class ExecutionPolicy, in-vector InVec>
    auto vector_two_norm(ExecutionPolicy&& exec, InVec v);
  
  template<in-vector InVec, class Scalar>
    Scalar vector_abs_sum(InVec v, Scalar init);
  template<class ExecutionPolicy, in-vector InVec, class Scalar>
    Scalar vector_abs_sum(ExecutionPolicy&& exec, InVec v, Scalar init);
  template<in-vector InVec>
    auto vector_abs_sum(InVec v);
  template<class ExecutionPolicy, in-vector InVec>
    auto vector_abs_sum(ExecutionPolicy&& exec, InVec v);
  
  template<in-vector InVec>
    typename InVec::extents_type vector_idx_abs_max(InVec v);
  template<class ExecutionPolicy, in-vector InVec>
    typename InVec::extents_type vector_idx_abs_max(ExecutionPolicy&& exec, InVec v);
  
  template<in-matrix InMat, class Scalar>
    Scalar matrix_frob_norm(InMat A, Scalar init);
  template<class ExecutionPolicy, in-matrix InMat, class Scalar>
    Scalar matrix_frob_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
  template<in-matrix InMat>
    auto matrix_frob_norm(InMat A);
  template<class ExecutionPolicy, in-matrix InMat>
    auto matrix_frob_norm(ExecutionPolicy&& exec, InMat A);
  
  template<in-matrix InMat, class Scalar>
    Scalar matrix_one_norm(InMat A, Scalar init);
  template<class ExecutionPolicy, in-matrix InMat, class Scalar>
    Scalar matrix_one_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
  template<in-matrix InMat>
    auto matrix_one_norm(InMat A);
  template<class ExecutionPolicy, in-matrix InMat>
    auto matrix_one_norm(ExecutionPolicy&& exec, InMat A);
  
  template<in-matrix InMat, class Scalar>
    Scalar matrix_inf_norm(InMat A, Scalar init);
  template<class ExecutionPolicy, in-matrix InMat, class Scalar>
    Scalar matrix_inf_norm(ExecutionPolicy&& exec, InMat A, Scalar init);
  template<in-matrix InMat>
    auto matrix_inf_norm(InMat A);
  template<class ExecutionPolicy, in-matrix InMat>
    auto matrix_inf_norm(ExecutionPolicy&& exec, InMat A);
  
  
  template<in-matrix InMat, in-vector InVec, out-vector OutVec>
    void matrix_vector_product(InMat A, InVec x, OutVec y);
  template<class ExecutionPolicy, in-matrix InMat, in-vector InVec, out-vector OutVec>
    void matrix_vector_product(ExecutionPolicy&& exec,
                               InMat A, InVec x, OutVec y);
  template<in-matrix InMat, in-vector InVec1, in-vector InVec2, out-vector OutVec>
    void matrix_vector_product(InMat A, InVec1 x, InVec2 y, OutVec z);
  template<class ExecutionPolicy,
           in-matrix InMat, in-vector InVec1, in-vector InVec2, out-vector OutVec>
    void matrix_vector_product(ExecutionPolicy&& exec,
                               InMat A, InVec1 x, InVec2 y, OutVec z);
  
  template<in-matrix InMat, class Triangle, in-vector InVec, out-vector OutVec>
    void symmetric_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, in-vector InVec, out-vector OutVec>
    void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
                                         InMat A, Triangle t, InVec x, OutVec y);
  template<in-matrix InMat, class Triangle, in-vector InVec1, in-vector InVec2,
           out-vector OutVec>
    void symmetric_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, in-vector InVec1, in-vector InVec2,
           out-vector OutVec>
    void symmetric_matrix_vector_product(ExecutionPolicy&& exec,
                                         InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
  
  template<in-matrix InMat, class Triangle, in-vector InVec, out-vector OutVec>
    void hermitian_matrix_vector_product(InMat A, Triangle t, InVec x, OutVec y);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, in-vector InVec, out-vector OutVec>
    void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
                                         InMat A, Triangle t, InVec x, OutVec y);
  template<in-matrix InMat, class Triangle, in-vector InVec1, in-vector InVec2,
           out-vector OutVec>
    void hermitian_matrix_vector_product(InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, in-vector InVec1, in-vector InVec2,
           out-vector OutVec>
    void hermitian_matrix_vector_product(ExecutionPolicy&& exec,
                                         InMat A, Triangle t, InVec1 x, InVec2 y, OutVec z);
  
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage, in-vector InVec,
           out-vector OutVec>
    void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InVec x,
                                          OutVec y);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, in-vector InVec,
           out-vector OutVec>
    void triangular_matrix_vector_product(ExecutionPolicy&& exec,
                                          InMat A, Triangle t, DiagonalStorage d, InVec x,
                                          OutVec y);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-vector InOutVec>
    void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d, InOutVec y);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-vector InOutVec>
    void triangular_matrix_vector_product(ExecutionPolicy&& exec,
                                          InMat A, Triangle t, DiagonalStorage d, InOutVec y);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec1, in-vector InVec2, out-vector OutVec>
    void triangular_matrix_vector_product(InMat A, Triangle t, DiagonalStorage d,
                                          InVec1 x, InVec2 y, OutVec z);
  template<class ExecutionPolicy, in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec1, in-vector InVec2, out-vector OutVec>
    void triangular_matrix_vector_product(ExecutionPolicy&& exec,
                                          InMat A, Triangle t, DiagonalStorage d,
                                          InVec1 x, InVec2 y, OutVec z);
  
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec, out-vector OutVec, class BinaryDivideOp>
    void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
                                        InVec b, OutVec x, BinaryDivideOp divide);
  template<class ExecutionPolicy, in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec, out-vector OutVec, class BinaryDivideOp>
    void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
                                        InMat A, Triangle t, DiagonalStorage d,
                                        InVec b, OutVec x, BinaryDivideOp divide);
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec, out-vector OutVec>
    void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
                                        InVec b, OutVec x);
  template<class ExecutionPolicy, in-matrix InMat, class Triangle, class DiagonalStorage,
           in-vector InVec, out-vector OutVec>
    void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
                                        InMat A, Triangle t, DiagonalStorage d,
                                        InVec b, OutVec x);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-vector InOutVec, class BinaryDivideOp>
    void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d,
                                        InOutVec b, BinaryDivideOp divide);
  template<class ExecutionPolicy, in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-vector InOutVec, class BinaryDivideOp>
    void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
                                        InMat A, Triangle t, DiagonalStorage d,
                                        InOutVec b, BinaryDivideOp divide);
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-vector InOutVec>
    void triangular_matrix_vector_solve(InMat A, Triangle t, DiagonalStorage d, InOutVec b);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-vector InOutVec>
    void triangular_matrix_vector_solve(ExecutionPolicy&& exec,
                                        InMat A, Triangle t, DiagonalStorage d, InOutVec b);
  
  template<in-vector InVec1, in-vector InVec2, inout-matrix InOutMat>
    void matrix_rank_1_update(InVec1 x, InVec2 y, InOutMat A);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2, inout-matrix InOutMat>
    void matrix_rank_1_update(ExecutionPolicy&& exec,
                              InVec1 x, InVec2 y, InOutMat A);
  template<in-vector InVec1, in-vector InVec2, inout-matrix InOutMat>
    void matrix_rank_1_update_c(InVec1 x, InVec2 y, InOutMat A);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2, inout-matrix InOutMat>
    void matrix_rank_1_update_c(ExecutionPolicy&& exec,
                                InVec1 x, InVec2 y, InOutMat A);
  
  template<class Scalar, in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t);
  template<class ExecutionPolicy,
           class Scalar, in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec,
                                        Scalar alpha, InVec x, InOutMat A, Triangle t);
  template<in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_1_update(InVec x, InOutMat A, Triangle t);
  template<class ExecutionPolicy,
           in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_1_update(ExecutionPolicy&& exec,
                                        InVec x, InOutMat A, Triangle t);
  template<class Scalar, in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_1_update(Scalar alpha, InVec x, InOutMat A, Triangle t);
  template<class ExecutionPolicy,
           class Scalar, in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec,
                                        Scalar alpha, InVec x, InOutMat A, Triangle t);
  template<in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_1_update(InVec x, InOutMat A, Triangle t);
  template<class ExecutionPolicy,
           in-vector InVec, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_1_update(ExecutionPolicy&& exec,
                                        InVec x, InOutMat A, Triangle t);
  
  
  template<in-vector InVec1, in-vector InVec2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_2_update(ExecutionPolicy&& exec,
                                        InVec1 x, InVec2 y, InOutMat A, Triangle t);
  
  template<in-vector InVec1, in-vector InVec2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_2_update(InVec1 x, InVec2 y, InOutMat A, Triangle t);
  template<class ExecutionPolicy, in-vector InVec1, in-vector InVec2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_2_update(ExecutionPolicy&& exec,
                                        InVec1 x, InVec2 y, InOutMat A, Triangle t);
  
  
  template<in-matrix InMat1, in-matrix InMat2, out-matrix OutMat>
    void matrix_product(InMat1 A, InMat2 B, OutMat C);
  template<class ExecutionPolicy, in-matrix InMat1, in-matrix InMat2, out-matrix OutMat>
    void matrix_product(ExecutionPolicy&& exec,
                        InMat1 A, InMat2 B, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, in-matrix InMat3, out-matrix OutMat>
    void matrix_product(InMat1 A, InMat2 B, InMat3 E, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, in-matrix InMat3, out-matrix OutMat>
    void matrix_product(ExecutionPolicy&& exec,
                        InMat1 A, InMat2 B, InMat3 E, OutMat C);
  
  template<in-matrix InMat1, class Triangle, in-matrix InMat2, out-matrix OutMat>
    void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, in-matrix InMat2, out-matrix OutMat>
    void symmetric_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, Triangle t, InMat2 B, OutMat C);
  template<in-matrix InMat1, class Triangle, in-matrix InMat2, out-matrix OutMat>
    void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, in-matrix InMat2, out-matrix OutMat>
    void hermitian_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, Triangle t, InMat2 B, OutMat C);
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_product(ExecutionPolicy&& exec,
                                   InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, out-matrix OutMat>
    void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, out-matrix OutMat>
    void symmetric_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, InMat2 B, Triangle t, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, out-matrix OutMat>
    void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, out-matrix OutMat>
    void hermitian_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, InMat2 B, Triangle t, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, class DiagonalStorage,
           out-matrix OutMat>
    void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, class DiagonalStorage,
           out-matrix OutMat>
    void triangular_matrix_product(ExecutionPolicy&& exec,
                                   InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, OutMat C);
  template<in-matrix InMat1, class Triangle, in-matrix InMat2, in-matrix InMat3,
           out-matrix OutMat>
    void symmetric_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, in-matrix InMat2, in-matrix InMat3,
           out-matrix OutMat>
    void symmetric_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
  template<in-matrix InMat1, class Triangle, in-matrix InMat2, in-matrix InMat3,
           out-matrix OutMat>
    void hermitian_matrix_product(InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, in-matrix InMat2, in-matrix InMat3,
           out-matrix OutMat>
    void hermitian_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, Triangle t, InMat2 B, InMat3 E, OutMat C);
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, in-matrix InMat3, out-matrix OutMat>
    void triangular_matrix_product(InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
                                   OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, in-matrix InMat3, out-matrix OutMat>
    void triangular_matrix_product(ExecutionPolicy&& exec,
                                   InMat1 A, Triangle t, DiagonalStorage d, InMat2 B, InMat3 E,
                                   OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, in-matrix InMat3,
           out-matrix OutMat>
    void symmetric_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, in-matrix InMat3,
           out-matrix OutMat>
    void symmetric_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, in-matrix InMat3,
           out-matrix OutMat>
    void hermitian_matrix_product(InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, in-matrix InMat3,
           out-matrix OutMat>
    void hermitian_matrix_product(ExecutionPolicy&& exec,
                                  InMat1 A, InMat2 B, Triangle t, InMat3 E, OutMat C);
  template<in-matrix InMat1, in-matrix InMat2, class Triangle, class DiagonalStorage,
           in-matrix InMat3, out-matrix OutMat>
    void triangular_matrix_product(InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
                                   OutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2, class Triangle, class DiagonalStorage,
           in-matrix InMat3, out-matrix OutMat>
    void triangular_matrix_product(ExecutionPolicy&& exec,
                                   InMat1 A, InMat2 B, Triangle t, DiagonalStorage d, InMat3 E,
                                   OutMat C);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_left_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_left_product(ExecutionPolicy&& exec,
                                        InMat A, Triangle t, DiagonalStorage d, InOutMat C);
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_right_product(InMat A, Triangle t, DiagonalStorage d, InOutMat C);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_right_product(ExecutionPolicy&& exec,
                                         InMat A, Triangle t, DiagonalStorage d, InOutMat C);
  
  
  template<class Scalar, in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t);
  template<class ExecutionPolicy, class Scalar,
           in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
                                        Scalar alpha, InMat A, InOutMat C, Triangle t);
  template<in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_k_update(InMat A, InOutMat C, Triangle t);
  template<class ExecutionPolicy,
           in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_k_update(ExecutionPolicy&& exec,
                                        InMat A, InOutMat C, Triangle t);
  
  template<class Scalar, in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_k_update(Scalar alpha, InMat A, InOutMat C, Triangle t);
  template<class ExecutionPolicy,
           class Scalar, in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
                                        Scalar alpha, InMat A, InOutMat C, Triangle t);
  template<in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_k_update(InMat A, InOutMat C, Triangle t);
  template<class ExecutionPolicy,
           in-matrix InMat, possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_k_update(ExecutionPolicy&& exec,
                                        InMat A, InOutMat C, Triangle t);
  
  
  template<in-matrix InMat1, in-matrix InMat2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void symmetric_matrix_rank_2k_update(ExecutionPolicy&& exec,
                                         InMat1 A, InMat2 B, InOutMat C, Triangle t);
  
  template<in-matrix InMat1, in-matrix InMat2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_2k_update(InMat1 A, InMat2 B, InOutMat C, Triangle t);
  template<class ExecutionPolicy,
           in-matrix InMat1, in-matrix InMat2,
           possibly-packed-inout-matrix InOutMat, class Triangle>
    void hermitian_matrix_rank_2k_update(ExecutionPolicy&& exec,
                                         InMat1 A, InMat2 B, InOutMat C, Triangle t);
  
  
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix 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 InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
                                             InMat1 A, Triangle t, DiagonalStorage d,
                                             InMat2 B, OutMat X, BinaryDivideOp divide);
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_matrix_left_solve(InMat1 A, Triangle t, DiagonalStorage d,
                                             InMat2 B, OutMat X);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
                                             InMat1 A, Triangle t, DiagonalStorage d,
                                             InMat2 B, OutMat X);
  
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix 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 InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
                                              InMat1 A, Triangle t, DiagonalStorage d,
                                              InMat2 B, OutMat X, BinaryDivideOp divide);
  template<in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_matrix_right_solve(InMat1 A, Triangle t, DiagonalStorage d,
                                              InMat2 B, OutMat X);
  template<class ExecutionPolicy,
           in-matrix InMat1, class Triangle, class DiagonalStorage,
           in-matrix InMat2, out-matrix OutMat>
    void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
                                              InMat1 A, Triangle t, DiagonalStorage d,
                                              InMat2 B, OutMat X);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-matrix InOutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
                                             InOutMat B, BinaryDivideOp divide);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-matrix InOutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
                                             InMat A, Triangle t, DiagonalStorage d,
                                             InOutMat B, BinaryDivideOp divide);
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_matrix_left_solve(InMat A, Triangle t, DiagonalStorage d,
                                             InOutMat B);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_matrix_left_solve(ExecutionPolicy&& exec,
                                             InMat A, Triangle t, DiagonalStorage d,
                                             InOutMat B);
  
  template<in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-matrix InOutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d,
                                              InOutMat B, BinaryDivideOp divide);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage,
           inout-matrix InOutMat, class BinaryDivideOp>
    void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
                                              InMat A, Triangle t, DiagonalStorage d,
                                              InOutMat B, BinaryDivideOp divide);
  template<in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_matrix_right_solve(InMat A, Triangle t, DiagonalStorage d,
                                              InOutMat B);
  template<class ExecutionPolicy,
           in-matrix InMat, class Triangle, class DiagonalStorage, inout-matrix InOutMat>
    void triangular_matrix_matrix_right_solve(ExecutionPolicy&& exec,
                                              InMat A, Triangle t, DiagonalStorage d,
                                              InOutMat B);
}