Reputation: 5067
I'm working through a large R (v3.6.0) codebase and trying to understand what it is doing. To do this, I'm translating some of the R code into Python (v3.6.5) using Numpy (v1.14.3). I have a piece of R code that appears to work just fine:
> v<-c(1,1,1,1)
> qrout<-qr(v)
> qr.Q(qrout)
[,1]
[1,] -0.5
[2,] -0.5
[3,] -0.5
[4,] -0.5
> qr.R(qrout)
[,1]
[1,] -2
The Python equivalent is not fine :
>>> import numpy as np
>>> v=np.ones(4)
>>> v
array([1., 1., 1., 1.])
>>> np.linalg.qr(v)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/python/3.6.5/lib/python3.6/site-packages/numpy/linalg/linalg.py", line 753, in qr
_assertRank2(a)
File "/opt/python/3.6.5/lib/python3.6/site-packages/numpy/linalg/linalg.py", line 195, in _assertRank2
'two-dimensional' % a.ndim)
numpy.linalg.linalg.LinAlgError: 1-dimensional array given. Array must be two-dimensional
Looking at the docs it appears that in R uses LAPACK's DQRDC(2)
/DGEQP3
/ZGEQP3
, while Numpy uses LAPACK's dgeqrf
, zgeqrf
, dorgqr
, and zungqr
. Clearly R is happy with a 1 dimensional matrix, while Numpy is not.
QUESTION
How do I replicate R's QR factorization using Numpy?
Upvotes: 1
Views: 487
Reputation: 25033
As stated in the error message
Array must be two-dimensional
In [7]: qr(v[:,None])
Out[7]:
(array([[-0.5],
[-0.5],
[-0.5],
[-0.5]]), array([[-2.]]))
Edit
What follows is not different from the striked code above, but who knows...
In [28]: from numpy.linalg import qr
...: from numpy import ones
In [29]: v = ones(4) ; print(v.shape) ; print(v[:,None].shape) # adding a dimension
(4,)
(4, 1)
In [30]: q, r = qr(v[:, None])
In [31]: print(q) ; print() ; print(r)
[[-0.5]
[-0.5]
[-0.5]
[-0.5]]
[[-2.]]
In [32]:
In Python/Numpy arrays can have just one dimension, but qr
requires a 2-dimensional array.
E.g., in Python transposition doesn't modify the dimensions of what is, in its essence, a 1D vector.
In [9]: print(v); print(v.T)
[1 1 1 1]
[1 1 1 1]
[10]: print(v.shape); print((v.T).shape)
(4,)
(4,)
In R, qr()
attempts to coerce its input to a 2-dimensional array (matrix), so qr()
does this step for you, while in Python you have to do it explicitly.
The most idiomatic way to add a dimension to a Numpy array being to use None
in a slice object to signify the addition of a dummy dimension to it.
Upvotes: 1