I have the following python code for QR factorization. At line of Q[:,i] = u / norm
, I get the error mentioned in the title. Can anyone help, please?
Q
is has the shape (3,3),u
is expected to has the shape (3,1)norm
is a scalar
The error message is:
could not broadcast input array from shape (3,1) into shape (3,)
The expected output is the matrix Q with the shape (3,3).
import numpy as np
def QRfactorization(A):
# getting the size of the matrix
N = len(A)
# preallocating Q
Q = np.zeros((N, N))
for i in range(N):
u = A[:,i]
for j in range(i):
# calculating the projection
h = np.vdot(u,Q[:,j])
u = u - h*Q[:,j]
norm = np.linalg.norm(u)
Q[:,i] = u / norm
#getting R matrix
R = Q.T*A
return Q , R
def main():
# input is an square matrix A
A = np.matrix([[1,2,3],[4,5,6],[1,2,3]])
Q = QRfactorization(A)
print(Q)
main()
CodePudding user response:
The use of numpy.matrix
is discouraged, and using numpy.array
also fixes this issue:
def main():
# input is an square matrix A
A = np.array([[1,2,3],[4,5,6],[1,2,3]])
Q = QRfactorization(A)
print(Q)
CodePudding user response:
You can avoid writing your own and do this directly with numpy.linalg.qr
https://numpy.org/doc/stable/reference/generated/numpy.linalg.qr.html
def main():
# input is an square matrix A
A = np.matrix([[1,2,3],[4,5,6],[1,2,3]])
q, r = np.linalg.qr(A)
print(q)
print(r)
BEWARE, you are not calculating the R-portion completely/correctly if it matters to your result, as it should be an upper-triangular matrix
results with @Nils Werner's .array()
change to your method
(results are combined into a single array)
(array([[ 0.23570226, 0.66666667, -0.23570226],
[ 0.94280904, -0.33333333, -0.94280904],
[ 0.23570226, 0.66666667, -0.23570226]]), array([[ 0.23570226, 1.88561808, 0.70710678],
[ 2.66666667, -1.66666667, 4. ],
[-0.23570226, -1.88561808, -0.70710678]]))
results from naive np.linalg.qr
(same for "complete" and "reduced" mode
s)
[[-2.35702260e-01 6.66666667e-01 -7.07106781e-01]
[-9.42809042e-01 -3.33333333e-01 2.22044605e-16]
[-2.35702260e-01 6.66666667e-01 7.07106781e-01]]
[[-4.24264069 -5.65685425 -7.07106781]
[ 0. 1. 2. ]
[ 0. 0. 0. ]]