Main Content

ハードウェア効率に優れた Real Partial-Systolic QR Decomposition の実装

この例では、Real Partial-Systolic QR Decomposition ブロックを使用して、ハードウェア効率に優れた QR 分解を実装する方法を示します。

サイズを抑えた QR 分解

Real Partial-Systolic QR Decomposition ブロックは、最小二乗行列方程式 AX = B を解く最初のステップとして A をインプレースで R に変換し、B をインプレースで C = Q'B に変換してから、変換したシステム RX = C を解きます。ここで、QR は A の直交三角分解です。

スタンドアロンの QR 分解を計算するために、この例では、B を Real Partial-Systolic QR Decomposition ブロックの出力が上三角 R で C = Q' となる単位行列に設定します。

行列の次元の定義

行列 A と B の行数、行列 A の列数、および行列 B の列数を指定します。この例では、B を A の行数と同じサイズの単位行列として設定します。

m = 10; % Number of rows in matrices A and B
n = 3;  % Number of columns in matrix A
p = m;  % Number of columns in matrix B

行列 A と B の生成

補助関数 realUniformRandomArray を使用して、乱数行列 A を生成します。A の要素は -1 ~ +1、A のランクはフル ランクとします。行列 B は単位行列です。

rng('default')
A = fixed.example.realUniformRandomArray(-1,1,m,n);
B = eye(m);

固定小数点データ型の選択

補助関数 qrFixedpointTypes を使用して、行列 A と B に対して、A から R へのインプレースの変換と B から C = Q'B へのインプレースの変換でオーバーフローが発生しないことを保証する固定小数点データ型を選択します。

max_abs_A = 1;  % Upper bound on max(abs(A(:))
max_abs_B = 1;  % Upper bound on max(abs(B(:))
precisionBits = 24;  % Number of bits of precision
T = fixed.qrFixedpointTypes(m,max_abs_A,max_abs_B,precisionBits);
A = cast(A,'like',T.A);
B = cast(B,'like',T.B);

モデルを開く

model = 'RealPartialSystolicQRModel';
open_system(model);

このモデルの Data Handler サブシステムは、実数行列 A と B を入力として取ります。A と B の行を AMBA AXI ハンドシェイク プロトコルを使用して QR ブロックに送ります。validIn 信号はデータが使用可能であることを示します。ready 信号はブロックでデータを受け入れ可能であることを示します。validIn 信号と ready 信号の両方が High の場合にのみデータの転送が行われます。Data Handler に A の行が送られてから B の行が送られるまでの遅延を設定して、上流のブロックの処理時間をエミュレートできます。rowDelay が 0 に設定されているときは、Data Handler に使用可能なデータが常にあることを示すため、validIn は High のままになります。

モデル ワークスペースの変数の設定

補助関数 setModelWorkspace を使用して、上記で定義された変数をモデル ワークスペースに追加します。これらの変数は、Real Partial-Systolic QR Decomposition ブロックのブロック パラメーターに対応します。

numSamples = 1; % Number of sample matrices
rowDelay = 1; % Delay of clock cycles between feeding in rows of A and B
fixed.example.setModelWorkspace(model,'A',A,'B',B,'m',m,'n',n,'p',p,...
    'numSamples',numSamples,'rowDelay',rowDelay);

モデルのシミュレーション

out = sim(model);

出力データからの解の構成

Real Partial-Systolic QR Decomposition ブロックは、各タイム ステップで行列 R と C を出力します。有効な結果の行列が出力されると、ブロックは validOut を true に設定します。

R = out.R;
C = out.C;

サイズを抑えた Q の抽出

ブロックは C = Q'B を計算します。この例では、B は単位行列であるため、Q = C' はサイズを抑えた QR 分解の直交因子です。

Q = C';

Q が直交で R が上三角であることの確認

Q は直交であるため、Q'Q は丸め範囲内の単位行列です。

I = Q'*Q
I = 

    1.0000   -0.0000   -0.0000
   -0.0000    1.0000   -0.0000
   -0.0000   -0.0000    1.0000

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 62
        FractionLength: 48

R は上三角行列です。

R
R = 

    2.2180    0.8559   -0.5607
         0    2.0578   -0.4017
         0         0    1.7117

          DataTypeMode: Fixed-point: binary point scaling
            Signedness: Signed
            WordLength: 29
        FractionLength: 24
isequal(R,triu(R))
ans =

  logical

   1

出力の精度の検証

Real Partial-Systolic QR Decomposition ブロックの精度を評価するには、相対誤差を計算します。

relative_error = norm(double(Q*R - A))/norm(double(A))
relative_error =

   1.5208e-06

mlint の警告は非表示にします。

%#ok<*NOPTS>