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

履歴 編集

function template
<linalg>

std::linalg::dotc(C++26)

namespace std::linalg {
  template<in-vector InVec1,
           in-vector InVec2,
           class Scalar>
  Scalar dotc(InVec1 v1,
              InVec2 v2,
              Scalar init); // (1)

  template<class ExecutionPolicy,
           in-vector InVec1,
           in-vector InVec2,
           class Scalar>
  Scalar dotc(ExecutionPolicy&& exec,
              InVec1 v1,
              InVec2 v2,
              Scalar init); // (2)

  template<in-vector InVec1,
           in-vector InVec2>
  auto dotc(InVec1 v1,
            InVec2 v2); // (3)

  template<class ExecutionPolicy,
           in-vector InVec1,
           in-vector InVec2>
  auto dotc(ExecutionPolicy&& exec,
            InVec1 v1,
            InVec2 v2); // (4)
}

概要

2つのベクトルv1v2のエルミート内積を計算する。

適格要件

事前条件

2つのベクトルの次元が同じであること。

  • v1.extent(0) == v2.extent(0)

効果

  • (1): dot(conjugated(v1), v2, init)を返す。
  • (2): dot(std::forward<ExecutionPolicy>(exec), conjugated(v1), v2, init)を返す。
  • (3), (4): Tを各ベクトルの値型の積の型decltype(conj-if-needed(declval<typename InVec1::value_type>()) * declval<typename InVec2::value_type>())とする。
    • (3): dotc(v1, v2, T{})を返す。
    • (4): dotc(std::forward<ExecutionPolicy>(exec), v1, v2, T{})を返す。

戻り値

2つのベクトルの次元をNとする。

  • (1): もしNが0ならinitを返す。そうでない場合は、共役を取らない内積、つまり以下の式のScalar型の値を返す。

$$ \verb|init| + \sum_{i = 0}^{N - 1} \overline{\verb|v1|[i]} * \verb|v2|[i] $$

  • (2): (1)の並列アルゴリズム版。
  • (3): (1)のinitを和の各項の型のデフォルト値に置き換えて計算する。
  • (4): (3)の並列アルゴリズム版。

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

#include <cmath>
#include <complex>
#include <execution>
#include <iostream>
#include <linalg>
#include <mdspan>
#include <numbers>
#include <vector>

int main()
{
  constexpr size_t N = 4;

  std::vector<std::complex<double>> a_vec(N);
  std::mdspan a(a_vec.data(), N);

  for(int i = 0; i < a.extent(0); ++i) {
    auto sign = i % 2 == 0 ? 1.0 : -1.0;
    a[i].real(sign / (2 * i + 1));
    a[i].imag(-sign / (2 * (i + 1)));
  }

  std::vector<std::complex<double>> b_vec(a_vec);
  std::mdspan b(b_vec.data(), N);

  std::cout << std::linalg::dotc(a, b, std::complex<double>(-std::numbers::pi * std::numbers::pi / 6, 0)) << '\n'                      // (1)
            << std::linalg::dotc(std::execution::par, a, b, std::complex<double>(-std::numbers::pi * std::numbers::pi / 6, 0)) << '\n' // (2)
            << std::linalg::dotc(a, b) << '\n'                                // (3)
            << std::linalg::dotc(std::execution::par, a, b) << '\n';          // (4)

  return 0;
}

出力

(-0.117512,-4.62593e-19)
(-0.117512,0)
(1.52742,-4.62593e-19)
(1.52742,0)

バージョン

言語

  • C++26

処理系

関連項目

参照