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

履歴 編集

function template
<linalg>

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

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

  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); // (2)
}

概要

アンダーフローとオーバーフローが起きないようスケールされた、ベクトルの成分の2乗和を計算する。すなわち、戻り値をresultとし、説明用の関数

  template<class Scalar>
  Scalar get_sum_of_squares(sum_of_squares_result<Scalar> result) {
    return std::pow(result.scaling_factor, 2) * result.scaled_sum_of_squares;
  }

を定義すると、以下の式が成り立つように計算する。

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

ただし、nvの次元である。

適格要件

効果

  • (1): 以下の条件を満たすsum_of_squares_result<Scalar>型の値resultを返す。
    • result.scaling_factorinit.scaling_factorと$\max_{i = 0, \dots, n - 1}|\verb|v[|i\verb|]||$の最大値。ただし、nvの次元である。
    • 概要に記載した式を満たす。
  • (2): (1)の並列アルゴリズム版。

戻り値

sum_of_squares_result<Scalar>

備考

  • init.scaled_sum_of_squaresは0以上でなければならない。
  • もしInVec::value_typeScalarがどちらも浮動小数点数型またはstd::complexの特殊化で、ScalarInVec::value_typeより精度が高い場合、和の各項はScalarまたはより高い精度の型が使われる。

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

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


template<class Scalar>
Scalar get_sum_of_squares(std::linalg::sum_of_squares_result<Scalar> result) {
  return std::pow(result.scaling_factor, 2) * result.scaled_sum_of_squares;
}


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);
  }

  auto init = std::linalg::sum_of_squares_result<double>{.scaling_factor = 1.0 / 5,
                                                         .scaled_sum_of_squares = 1.0};

  std::cout << get_sum_of_squares(
                std::linalg::vector_sum_of_squares(v, init))                              // (1)
            << get_sum_of_squares(
                std::linalg::vector_sum_of_squares(std::execution::par, v, init)) << '\n' // (2)
            << get_sum_of_squares(
                std::linalg::vector_sum_of_squares(v)) << '\n'                            // (3)
            << get_sum_of_squares(
                std::linalg::vector_sum_of_squares(std::execution::par, v)) << '\n';      // (4)

  return 0;
}

出力

1.46361
1.46361
1.42361
1.42361

バージョン

言語

  • C++26

処理系

関連項目

参照