• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    function template
    <linalg>

    std::linalg::triangular_matrix_product

    namespace std::linalg {
      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); // (1)
    
      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); // (2)
    
      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); // (3)
    
      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); // (4)
    
      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); // (5)
    
      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); // (6)
    
      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); // (7)
    
      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); // (8)
    }
    

    概要

    三角行列と行列の積を計算する。

    • (1): 三角行列Aと行列Bに対し、CAB
    • (2): (1)を指定された実行ポリシーで実行する。
    • (3): 行列Aと三角行列Bに対し、CAB
    • (4): (3)を指定された実行ポリシーで実行する。
    • (5): 三角行列Aと行列Bに対し、CE+AB
    • (6): (5)を指定された実行ポリシーで実行する。
    • (7): 行列Aと三角行列Bに対し、CE+AB
    • (8): (7)を指定された実行ポリシーで実行する。

    適格要件

    事前条件

    • 共通
    • (1), (2), (5), (6): A.extent(0) == A.extent(1)
    • (3), (4), (7), (8): B.extent(0) == B.extent(1)
    • (5), (6), (7), (8): addable(E, E, C) == true

    効果

    • (1), (2): 三角行列Aと行列Bに対し、CAB
    • (3), (4): 行列Aと三角行列Bに対し、CAB
    • (5), (6): 三角行列Aと行列Bに対し、CE+AB
    • (7), (8): 行列Aと三角行列Bに対し、CE+AB

    戻り値

    なし

    計算量

    O(A.extent(0)×A.extent(1)×B.extent(1))

    備考

    • (5), (6), (7), (8): CEを入れても良い。

    [注意] 処理系にあるコンパイラで確認していないため、間違っているかもしれません。

    #include <array>
    #include <iostream>
    #include <linalg>
    #include <mdspan>
    #include <vector>
    
    template <class Matrix>
    void print_mat(const Matrix& A) {
      for(int i = 0; i < A.extent(0); ++i) {
        for(int j = 0; j < A.extent(1) - 1; ++j) {
          std::cout << A[i, j] << ' ';
        }
        std::cout << A[i, A.extent(1) - 1] << '\n';
      }
    }
    
    template <class Matrix>
    void init_mat(Matrix& A, typename Matrix::value_type geta = 1) {
      for(int i = 0; i < A.extent(0); ++i) {
        for(int j = 0; j < A.extent(1); ++j) {
          A[i, j] = i * A.extent(1) + j + geta;
        }
      }
    }
    
    template <class Matrix>
    void init_tria_mat(Matrix& A) {
      for(int i = 0; i < A.extent(0); ++i) {
        for(int j = i + 1; j < A.extent(1); ++j) {
          A[i, j] = i * A.extent(1) + j;
        }
      }
    }
    
    int main()
    {
      constexpr size_t N = 2;
    
      using Scalar = double;
      using Vector = std::vector<Scalar>;
      using TriangularMatrix = std::mdspan<
          Scalar,
          std::extents<size_t, N, N>,
          std::linalg::layout_blas_packed<
            std::linalg::upper_triangle_t,
            std::linalg::row_major_t>
        >;
    
      Vector A_vec(N * N);
      Vector B_vec(N * N);
      Vector C_vec(N * N);
      Vector E_vec(N * N);
    
      std::mdspan C(C_vec.data(), N, N);
      std::mdspan E(E_vec.data(), N, N);
    
      init_mat(E, N * N);
    
      {
        TriangularMatrix A(A_vec.data());
        std::mdspan      B(B_vec.data(), N, N);
    
        init_tria_mat(A);
        init_mat(B);
    
        // (1)
        std::cout << "(1)\n";
        std::linalg::triangular_matrix_product(
          A,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          B,
          C);
        print_mat(C);
    
        // (2)
        std::cout << "(2)\n";
        std::linalg::triangular_matrix_product(
          std::execution::par,
          A,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          B,
          C);
        print_mat(C);
      }
    
      {
        std::mdspan      A(A_vec.data(), N, N);
        TriangularMatrix B(B_vec.data());
    
        init_mat(A);
        init_tria_mat(B);
    
        // (3)
        std::cout << "(3)\n";
        std::linalg::triangular_matrix_product(
          A,
          B,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          C);
        print_mat(C);
    
        // (4)
        std::cout << "(4)\n";
        std::linalg::triangular_matrix_product(
          std::execution::par,
          A,
          B,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          C);
        print_mat(C);
      }
    
      {
        TriangularMatrix A(A_vec.data());
        std::mdspan      B(B_vec.data(), N, N);
    
        init_tria_mat(A);
        init_mat(B);
    
        // (5)
        std::cout << "(5)\n";
        std::linalg::triangular_matrix_product(
          A,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          B,
          E,
          C);
        print_mat(C);
    
        // (6)
        std::cout << "(6)\n";
        std::linalg::triangular_matrix_product(
          std::execution::par,
          A,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          B,
          E,
          C);
        print_mat(C);
      }
    
      {
        std::mdspan      A(A_vec.data(), N, N);
        TriangularMatrix B(B_vec.data());
    
        init_mat(A);
        init_tria_mat(B);
    
        // (7)
        std::cout << "(7)\n";
        std::linalg::triangular_matrix_product(
          A,
          B,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          E,
          C);
        print_mat(C);
    
        // (8)
        std::cout << "(8)\n";
        std::linalg::triangular_matrix_product(
          std::execution::par,
          A,
          B,
          std::linalg::upper_triangle,
          std::linalg::implicit_unit_diagonal,
          E,
          C);
        print_mat(C);
      }
    
      return 0;
    }
    

    出力

    (1)
    4 6
    3 4
    (2)
    4 6
    3 4
    (3)
    1 3
    3 7
    (4)
    1 3
    3 7
    (5)
    8 11
    9 11
    (6)
    8 11
    9 11
    (7)
    5 8
    9 14
    (8)
    5 8
    9 14
    

    バージョン

    言語

    • C++26

    処理系

    関連項目

    参照