ハードウェア効率に優れた Real Burst QR Decomposition の実装
この例では、Real Burst QR Decomposition ブロックを使用して、ハードウェア効率に優れた QR 分解を実装する方法を示します。
サイズを抑えた QR 分解
Real Burst QR Decomposition ブロックは、最小二乗行列方程式 AX = B を解く最初のステップとして A をインプレースで R に変換し、B をインプレースで C = Q'B に変換してから、変換したシステム RX = C を解きます。ここで、QR は A の直交三角分解です。
スタンドアロンの QR 分解を計算するために、この例では、B を Real Burst 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 = 'RealBurstQRModel';
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 Burst 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 Burst QR Decomposition ブロックは一度に 1 行ずつデータを出力します。結果の行が出力されると、ブロックは validOut
を true に設定します。行列 R と C の行は後退代入に合わせて逆の順序で出力されるため、結果を解釈するにはデータを再構成しなければなりません。出力データから行列 R と C を再構成するには、補助関数 qrModelOutputToArray
を使用します。
[C,R] = fixed.example.qrModelOutputToArray(out.C,out.R,m,n,p,numSamples);
サイズを抑えた 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 Burst QR Decomposition ブロックの精度を評価するには、相対誤差を計算します。
relative_error = norm(double(Q*R - A))/norm(double(A))
relative_error = 1.5208e-06
mlint の警告は非表示にします。
%#ok<*NOPTS>