Closed dselivanov closed 6 years ago
Can you give an example code that's breaking? It should return a float:
library(float)
set.seed(1234)
x = flrnorm(10, 3)
QR = qr(x)
qr.Q(QR)
## # A float32 matrix: 10x3
## [,1] [,2] [,3]
## [1,] -0.14802432 0.39461002 -0.075990766
## [2,] -0.30969775 -0.04993335 -0.263598472
## [3,] -0.24079260 -0.31019425 -0.156482309
## [4,] 0.01999501 0.73036253 0.008359464
## [5,] 0.29763341 -0.16934457 -0.210273698
## [6,] -0.03421037 -0.15402134 -0.614522934
## [7,] -0.15851428 0.19833231 0.174357086
## [8,] -0.28265125 0.20427391 -0.568394244
## [9,] -0.25968921 0.20711732 -0.111747116
## [10,] 0.74938786 0.18915167 -0.335218400
Sorry for not providing it - it would help me to understand that there was a mistake on my side!
I think this happened because I've not loaded float
and R dispatched qr.Q
from base:
U = float::flrnorm(10, 3)
U = qr.Q(float::qr(U))
# num [1:10, 1:3] -0.0473 0.0692 0.5123 -0.0916 0.015 ...
However I'm curious now why the remaining S4 methods worked properly.
This is a very interesting example. Basically it's defaulting to base::qr.Q()
, which constructs a numeric Dvec
(when the Dvec
argument is missing). In float, I always cast things to the highest precision, so once it hits qr.qy()
it goes to float::qr.qy()
which eventually promotes to double. Kind of amusing that it even works.
A quick fix is to call float::qr.Q()
. This will work even if the input is numeric
.
set.seed(1234)
s = float::flrnorm(3, 3)
x = as.numeric(s)
float::qr.Q(float::qr(x))
## [,1] [,2] [,3]
## [1,] -0.7332419 -0.65954086 -0.16541508
## [2,] 0.1685267 0.05940792 -0.98390521
## [3,] 0.6587527 -0.74931739 0.06758985
float::qr.Q(float::qr(s))
## # A float32 matrix: 3x3
## [,1] [,2] [,3]
## [1,] -0.9622459 -0.2717418 0.01546986
## [2,] 0.1760344 -0.6646785 -0.72609526
## [3,] 0.2075929 -0.6959589 0.68742007
Thank you for explanation. But why did remaining S4 method work? (for example %*%
, diag
, etc) Can't find any good reference on this...
I wouldn't think that diag()
would work. %*%
should because it's generic. qr()
is generic, but qr.Q()
isn't, so my guess is it searches the methods table for the former, but not the latter. If you install float from source, you'll see a message like
Creating a generic function for ‘qr.Q’ from package ‘base’ in package ‘float’
So that method will only be available if the full float namespace is attached, I guess.
I'm not 100% sure I know what's happening, but I think that explanation is in the ballpark of being correct.
Thanks a lot! I think in my case it will be better to load float
- otherwise will be many non-obvious edge cases.
Hi here. Seems
qr.Q
on float32 matrix returns double matrix. Not sure if it is hard to calculate and integrate properly, but would be nice at least to convert it from double to float before returning (in order to have type-safe calculations).