主要内容

在收缩系统阵列中使用Cordic实现硬件有效的QR分解

这个例子展示了如何在Simulink®中使用硬件高效的MATLAB®代码来计算矩阵的QR分解。金宝app

用QR分解来求解方程组或计算矩阵方程AX = B的最小二乘解,计算R和Q'B,其中QR = a, RX = Q'B。R是一个上三角矩阵Q是一个正交矩阵。如果你只想要Q和R,那么让B是单位矩阵。

在该示例中,通过使用CORDIC算法应用Givens变换来从矩阵A计算R.C = Q'B通过应用相同的GIVENS转换从矩阵B计算。该算法仅使用迭代移位和添加来执行这些计算。

有关此示例中使用的算法的更多信息,请参见使用Cordic执行QR分解

概述

本例中使金宝app用的Simulink模型是:

fxpdemo_real_4x4_systolic_array_QR_model

要输入您自己的输入矩阵A和B,请在左边打开相应启用的子系统块的块参数。仿真之后,模型将计算出的输出矩阵C = Q'B和R返回到工作空间。您可以在转置(Q)*B, R 4x4 Real CORDIC Systolic Array子系统的块参数中指定CORDIC迭代的数量。如果输入为固定点,则CORDIC迭代次数必须小于字长。每次迭代的计算精度提高一位,直到输入的字长。

该模型将使用固定点,双倍和单数据类型。

要了解算法如何执行分解,请在转置(Q)* B,R 4x4真正的Cortic Systolic阵列子系统的掩码下。注释指示正在运行哪个矩阵的行以零零对角线元素。收缩系统阵列设置为4×4矩阵A,但可以通过按照相同的模式扩展到任何尺寸。此实现仅适用于实际输入矩阵。

要查看使用CORDIC执行给定转换的MATLAB函数块中的MATLAB代码,请继续查看块掩码下面的代码。

在本例中,A的行数和列数必须为4。矩阵B必须有4行和任意数量的列。

使用QR求解矩阵方程AX = B.

求解矩阵方程AX = B的第一步是计算Rx = Q'B,其中R是上三角形,Q是正交的,Q * r = a。

以下输入是双精度浮点类型,因此将迭代的数量设置为52,这是双重的脚步的位数。

格式remodeofcordicicerations = 52;a = 2 * rand(4,4)-1;b = 2 * rand(4,4)-1;

模拟模型以计算R和C = Q'B。

sim卡fxpdemo_real_4x4_systolic_array_QR_modelr C.
r = 1.5149 -0.0519 1.7292-0.3224 0 0.9593 -0.0259 -0.0879 0 0 0.2565 1.0888 0 0 0.2565 1.0888 0 0 0 0 -0.6429 C = 0.5942 -0.2382 0.0676 -0.9370 -0.8887 0.6146 -0.5758 0.3051 0.1725 0.7339 0.5409 0.5374 0.8540 1.1078-0.8540 1.1078 -0.2183 -0.5620

验证用R和C = Q'B进行回代得到与MATLAB相同的结果。

x = r \ c x_should_be = a \ b
X = -7.1245 -12.1131 -0.6637 1.4236 -0.8779 0.7572 -0.5511 0.3545 6.3113 10.1759 0.6673 -1.6155 -1.3283 -1.7231 0.3396 0.8741 X_should_be = -7.1245 -12.1131 -0.6637 1.4236 -0.8779 0.7572 -0.5511 0.3545 6.3113 10.1759 0.6673 -1.6155 -1.3283 -1.72310.3396 0.8741

内置MATLAB与CORDIC QR溶液之间的差异的规范应该很小。

规范(X - X_should_be)
ans = 2.6739 e-14

计算q和r

为了计算Q和R,让B等于单位矩阵。当B等于单位矩阵,那么Q = C'。

numberofcordicicerations = 52;a = 2 * rand(4,4)-1;B =眼睛(大小(a,1),'喜欢',);sim卡fxpdemo_real_4x4_systolic_array_QR_modelq = c';

理论的QR分解是QR==A,所以计算出来的QR和A之间的差异应该很小。

规范(Q * R - A)
ans = 2.2861 e15汽油

QR不是唯一的

QR分解只有R的行和q的列的符号是唯一的你可以通过让R的对角线元素都为正来做一个唯一的QR分解。

d =诊断(符号(DIAG(R)));qunique = q * d runique = d * r
Qunique = -0.3086 0.1224 -0.1033 -0.9376 -0.6277 -0.7636 -0.0952 0.1174 -0.5573 0.3930 0.7146 0.1559 0.4474 -0.4975 0.6852 -0.2877与runique = 1.4459 -0.8090 0.1547 0.3977 0 1.1441 0.0809 -0.2494 0 0 0.8193 0.1894 0 0 0 0.4836

然后,您可以将计算的QR与模型从模型进行比较到内置MATLAB QR函数。

[Q0,R0] = QR(A);d0 = diag(符号(diag(r0)));Q0 = Q0 * D0 R0 = D0 * R0
Q0 = -0.3086 0.1224 -0.1033 -0.9376 -0.6277 -0.7636 -0.0952 0.1174 -0.5573 0.3930 0.7146 0.1559 0.4474 -0.4975 0.6852 -0.2877 R0 = 1.4459 -0.8090 0.1547 0.3977 0 1.1441 0.0809 -0.2494 0 0 0.8193 0.1894 0 0 0 0.4836

使用定点实现硬件效率高

使用定点输入数据类型为ASIC和FPGA设备产生高效的HDL代码。

有关如何选择不会溢出的固定点数据类型的详细信息,请参阅示例使用Cordic执行QR分解

您可以通过制作A和B 3维数组来通过模型运行许多测试输入。

n_test_inputs = 100;

以下部分为矩阵A和B的随机输入定义了在-1和1之间缩放的矩阵A和B,因此将定点字长度设置为18位和分数长度为14位,以允许在QR分解和中间计算中的增长。CORDIC算法。

word_length = 18;fraction_length = 14;

CORDIC迭代的最佳精度是字长减1。如果将CORDIC迭代的次数设置为小于word_length - 1,则到下一个ready信号的延迟时间和时钟节拍将会更短,但它将不那么准确。不应该将CORDIC迭代的数量设置得更大,因为生成的代码不支持大于定点类型的字长的移位。金宝app

numberofcordicicerations = word_length  -  1
numberofcordicicerations = 17.

随机测试输入被串联起来,这样在时间k,输入是A(:,:,k)和B(:,:,k)。A和B的每个元素都是-1到+1之间的统一随机变量。

a = 2 * rand(4,4,n_test_inputs)-1;

选择B作为单位矩阵,所以Q=C'

B =眼(4);B = repmat (B, 1, 1, n_test_inputs);

铸造A到固定点,并像A一样铸造B.

= fi(1、word_length fraction_length);B =投(B,'喜欢',);

模拟模型

sim卡fxpdemo_real_4x4_systolic_array_QR_model

计算并绘制错误

rang_error =零(1,尺寸(r,3));k = 1:尺寸(R, 3) Q_times_R_minus_A =双(C (:,:, k))的*双(R (:,:, k)) -双((:,:,k));norm_error (k) =规范(Q_times_R_minus_A);结束

误差应该是10的3次方。

clf情节(norm_error“啊——”)网格标题('常态(QR  -  A)')

% #好< * NASGU, * NOPTS >