最終更新日時(UTC): 2025年07月11日 17時16分44秒
Koichi Murase が更新

履歴 編集

function template
<linalg>

# std::linalg::vector_two_norm(C++26)

    namespace std::linalg {
      template<in-vector InVec, class Scalar>
      Scalar vector_two_norm(InVec v, Scalar init);          // (1)

      template<class ExecutionPolicy,
               in-vector InVec,
               class Scalar>
      Scalar vector_two_norm(ExecutionPolicy&& exec,
                             InVec v,
                             Scalar init);                   // (2)

      template<in-vector InVec>
      auto vector_two_norm(InVec v);                         // (3)

      template<class ExecutionPolicy, in-vector InVec>
      auto vector_two_norm(ExecutionPolicy&& exec, InVec v); // (4)
    }

## 概要

ベクトルのユークリッドノルムを計算する。

- (1): 逐次実行する。
- (2): 指定された実行ポリシーに応じて実行する。
- (3): (1)で`init`に`InVec::value_type`のデフォルト値を与えて逐次実行する。
- (4): (2)で`init`に`InVec::value_type`のデフォルト値を与えて、指定された実行ポリシーに応じて実行する。

## 適格要件

- (1), (2): `decltype(init + abs-if-needed(declval<typename InVec::value_type>()) * abs-if-needed(declval<typename InVec::value_type>()))`が`Scalar`に変換可能。
- (2), (4): `is_execution_policy<ExecutionPolicy>::value`が`true`

## 効果

- (3), (4): `T`を`decltype(abs-if-needed(declval<typename InVec::value_type>()) * abs-if-needed(declval<typename InVec::value_type>()))`とすると、
  - (3): `vector_two_norm(v, T{})`を返す。
  - (4): `vector_two_norm(std::forward<ExecutionPolicy>(exec), v, T{})`を返す。

## 戻り値

- (1), (2): `n`を`v`の次元とすると、以下の式の値を返す。

$$ \sqrt{\sum_{i = 0}^{n - 1} |\verb|v[|i\verb|]||^2 + \verb|init|^2} $$

- (3), (4): `T`を`decltype(abs-if-needed(declval<typename InVec::value_type>()) * abs-if-needed(declval<typename InVec::value_type>()))`とすると、
  - (3): `vector_two_norm(v, T{})`を返す。
  - (4): `vector_two_norm(std::forward<ExecutionPolicy>(exec), v, T{})`を返す。

## 備考

- (1), (2): もし`InVec::value_type`と`Scalar`がどちらも浮動小数点数型または`std::complex`の特殊化で、`Scalar`が`InVec::value_type`より精度が高い場合、和の各項は`Scalar`またはより高い精度の型が使われる。

## 例

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

    #include <array>
    #include <cmath>
    #include <execution>
    #include <iostream>
    #include <linalg>
    #include <mdspan>

    int main()
    {
      constexpr size_t N = 4;

      std::array<double, N> vec;

      std::mdspan v(vec.data(), N);

      for(int i = 0; i < v.extent(0); ++i) {
        v[i] = std::pow(-1.0, i) / (i + 1);
      }

      std::cout << std::linalg::vector_two_norm(v, 1.0 / 5) << '\n'                      // (1)
                << std::linalg::vector_two_norm(std::execution::par, v, 1.0 / 5) << '\n' // (2)
                << std::linalg::vector_two_norm(v) << '\n'                                // (3)
                << std::linalg::vector_two_norm(std::execution::par, v) << '\n';          // (4)

      return 0;
    }

### 出力

    1.46361
    1.46361
    1.42361
    1.42361

## バージョン

### 言語

- C++26

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??

## 関連項目

- `execution`
- `mdspan`

## 参照

- P1673R13 A free function linear algebra interface based on the BLAS
- LAPACK: dnrm2