Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

P1673: `vector_sum_of_squares`: Rescaling algorithm may not be correct

オープン
#141 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
cpp
領域
hpc

調査の方向性

include/experimental/__p1673_bits/blas1_vector_sum_of_squares.hpp と vector_sum_of_squares の再スケーリングループから始めます。quotient と scale の更新を、P1673 のセクション 16.9.2.7 およびリンクされている LAPACK dlassq のリファレンスと比較します。実装が、初期値を含め、記載されたスケーリング係数の不変条件を満たせば完了です。

索引モデルが issue の本文から書いたものです。

説明

@mhoemmen
I was looking at this and it seems to me this is wrong?

  Scalar scale = init.scaling_factor;
  Scalar ssq = init.scaled_sum_of_squares;
  for (extents<>::size_type i = 0; i < x.extent(0); ++i) {
    if (abs(x(i)) != 0.0) {
      const auto absxi = abs(x(i));
      const auto quotient = scale / absxi;
      if (scale < absxi) {
          ssq = Scalar(1.0) + ssq * quotient * quotient;
          scale = absxi;
      }
      else {
        ssq = ssq + quotient * quotient;
      }
    }
  }
  • why does scale change along the way?

  • also, shouldn't scale / absxi; instead be absxi/scale? Looking at the spec, section 16.9.2.7:

    Constraints: For all i in the domain of v, and for f and ssq of type T, the expression ssq = ssq + (abs(x[i]) / f)*(abs(x[i]) / f) is well formed.
    

    It says abs(x[i])/f should be well-formed, but not f/abs(x[i]).

  • also, if things are correct, in theory one should have that:

    scaling_factor * scaling_factor * scaled_sum_of_squares = sum of squares of abs(x[i]) plus init.scaling_factor * 
    init.scaling_factor * init.scaled_sum_of_squares.
    

    see dlassq. But that does not work for the impl above.


So i tried something on my end:

{ 
  using std::abs;
  using std::max;

  T scale = init.scaling_factor;
  for (std::size_t i = 0; i < x.extent(0); ++i) {
    scale = max(scale, abs(x(i)));
  }

  T ssq = (init.scaling_factor*init.scaling_factor*init.scaled_sum_of_squares)/(scale*scale);
  T s= {};
  for (std::size_t i = 0; i < x.extent(0); ++i) {
    const auto absxi = abs(x(i));
    const auto quotient = absxi/scale;
    ssq = ssq + quotient * quotient;
    s += absxi*absxi;
  }

  std::experimental::linalg::sum_of_squares_result<T> result;
  result.scaled_sum_of_squares = ssq;
  result.scaling_factor = scale;

  // verify that things are consistent according to definition
  const auto lhs = scale*scale*ssq;
  const auto rhs = s+init.scaling_factor*init.scaling_factor*init.scaled_sum_of_squares;
  std::cout << lhs << " " << rhs << '\n';
  EXPECT_NEAR(lhs, rhs, 1e-9);
}

and this works, in the sense that it satisfies:

  scaling_factor * scaling_factor * scaled_sum_of_squares = sum of squares of abs(x[i]) plus init.scaling_factor * 
  init.scaling_factor * init.scaled_sum_of_squares.
主要言語
C++
スター
167
フォーク
31
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

kokkos/stdBLAS のほかの issue

kokkos/stdBLAS の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。