A = NP.array([1,-1,-1])
As = SXMatrix(A)
Q = SXMatrix.zeros(1)
R = SXMatrix.zeros(1)
qr(As,Q,R)
print Q,R
>> [0.57735,-0.57735,-0.57735] 1.73205
So I want to find the QR decomposition of a 3-by-1 matrix A, which should return a 3-by-3 Q and a 3-by-1 R. The right part of Q, i.e., the last 2 columns, are then a basis for the null space of A transpose. The qr method however, returns a 3-by-1 Q which is only the first column.
If you would do the same in Matlab, you get this:
>> [Q,R] = qr([1 -1 -1]')
Q =
-0.5774 0.5774 0.5774
0.5774 0.7887 -0.2113
0.5774 -0.2113 0.7887
R =
-1.7321
0
0
with the right part of Q the null space of [1 -1 -1]:
>> null([1 -1 -1])
ans =
0.5774 0.5774
0.7887 -0.2113
-0.2113 0.7887
% Golub, Van Loan: Matrix Computations, 4th edition
% QR Factorization using Givens rotation (Algorithm 5.2.4)
function [Q,R] = qrgivens(A)
import casadi.*
[m,n] = size(A);
Q = SX.eye(m);
R = SX(A);
for j = 1:n
for i = m:-1:j+1
[c,s] = givensrotation( R(j,j),R(i,j) );
G = [c s; -s c];
R([j i],j:n) = G'*R([j i],j:n);
R(i,j) = 0; % rewrite small number by zero
Q(j:n,[j i]) = Q(j:n,[j i])*G;
end
end
end
% Givens rotation (Algorithm 5.1.3)
function [c,s] = givensrotation(a,b)
% Givens rotation
import casadi.*
r = if_else(abs(b) > abs(a), -a/b, -b/a);
c = if_else(b == 0, 1, if_else(abs(b) > abs(a), (1/sqrt(1+r^2))*r, 1/sqrt(1+r^2)));
s = if_else(b == 0, 0, if_else(abs(b) > abs(a), 1/sqrt(1+r^2), (1/sqrt(1+r^2))*r));
end