1、豪斯霍尔德变换
一般地,对给定的 m m m维向量 a a a,考虑分块 a = [ a 1 a 2 ] a=\left[ \begin{matrix} {{a}_{1}} \\ {{a}_{2}} \\ \end{matrix} \right] a=[a1a2],其中 a 1 {{a}_{1}} a1是 ( k − 1 ) (k-1) (k−1)维向量, 1 ≤ k < m 1\le k
2、伪代码
3、Matlab实现
%% Matlab 2018b——用豪斯霍尔德变换进行矩阵的QR分解:A→R(上三角阵)
A=[1,0,0;0,1,0;0,0,1;-1,1,0;-1,0,1;0,-1,1];
% b=[1237,1941,2417,711,1177,475];
% A=[A,b'];
[m,n]=size(A);
alpha=zeros(1,n);
beta=alpha;
gama=alpha;
v=zeros(m,n);
E=eye(m,n);
for i=1:n
alpha(i)=-1*sign(A(i,i))*sqrt(sum(A(i:m,i).*A(i:m,i)));
v(:,i)=[zeros(i-1,1);A(i:m,i)]-alpha(i).*E(:,i);
beta(i)=v(:,i)'*v(:,i);
if beta(i)==0
continue;
end
for j=i:n
gama(j)=v(:,i)'*A(:,j);
A(:,j)=A(:,j)-(2*gama(j)/beta(i)).*v(:,i);
end
end
R=A;
4、OpenCV实现
// OpenCV 4.5.0——用豪斯霍尔德变换进行矩阵的QR分解:A→R(上三角阵)
#include
#include
using namespace std;
using namespace cv;
int main()
{
Mat A = (Mat_<float>(6, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 1, 0, -1, 0, 1, 0, -1, 1);
Size n = A.size();
Mat alpha = Mat::zeros(1, n.width, CV_32FC1);
Mat V = Mat::zeros(n, CV_32FC1);
Mat E = Mat::eye(n, CV_32FC1);
Mat beta = alpha.clone(), gama = alpha.clone();
Mat temp, temp1; // 过程暂存变量
for (int i = 0; i < n.width; i++)
{
temp = A(Range(i, n.height), Range(i, i + 1)).clone();
temp1 = temp.mul(temp); // 各项求平方
reduce(temp1, temp1, 0, REDUCE_SUM); // 平方和
alpha.at<float>(i) = -1 * A.at<float>(i, i) / fabsf(A.at<float>(i, i)) * sqrt(temp1.at<float>(0));
vconcat(Mat::zeros(i, 1, CV_32FC1), temp, temp);
V.col(i) = temp - alpha.at<float>(i)*E.col(i);
temp1 = V.col(i).t()*V.col(i);
beta.at<float>(i) = temp1.at<float>(0);
if (beta.at<float>(i) == 0)
continue;
for (int j = i; j < n.width; j++)
{
temp = V.col(i).t()*A.col(j);
gama.at<float>(j) = temp.at<float>(0);
A.col(j) = A.col(j) - (2 * gama.at<float>(j) / beta.at<float>(i))*V.col(i);
}
}
cout << A << endl;
getchar();
return 0;
}
参考文献:《科学计算导论》(第2版)——Michael T. Health 著 张威等 译