@@ -90,15 +90,15 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
9090 iex> model.y_std
9191 #Nx.Tensor<
9292 f32[2]
93- [5.467098712921143 , 5.661198616027832 ]
93+ [5.4670987 , 5.6611986 ]
9494 >
9595 iex> model.x_weights
9696 #Nx.Tensor<
9797 f32[3][2]
9898 [
99- [0.521888256072998 , -0.11256571859121323 ],
100- [0.6170258522033691 , 0.7342619299888611 ],
101- [0.5889922380447388 , -0.6694686412811279 ]
99+ [0.5218878 , -0.11256802 ],
100+ [0.6170291 , 0.7342591 ],
101+ [0.58898926 , -0.66947126 ]
102102 ]
103103 >
104104 """
@@ -115,7 +115,15 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
115115
116116 c = Nx . dot ( x , [ 0 ] , y , [ 0 ] )
117117
118- { u , _s , vt } = Nx.LinAlg . svd ( c , full_matrices?: false )
118+ # full_matrices?: true on purpose: the false path forms the Gram matrix
119+ # CᵀC to avoid the larger QR/Halley iteration, which squares the
120+ # condition number and can cost the smaller singular vectors real
121+ # precision (Nx.LinAlg.svd's own docs call this out). C here is the
122+ # cross-covariance of two already small, already centered and scaled
123+ # blocks, so its singular values are routinely far apart, exactly the
124+ # regime that trade-off hurts. true costs more but keeps x_weights and
125+ # y_weights properly orthonormal.
126+ { u , _s , vt } = Nx.LinAlg . svd ( c , full_matrices?: true )
119127 u = Nx . slice_along_axis ( u , 0 , num_components , axis: 1 )
120128 vt = Nx . slice_along_axis ( vt , 0 , num_components , axis: 0 )
121129 { u , vt } = Scholar.Decomposition.Utils . flip_svd ( u , vt )
@@ -171,20 +179,20 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
171179 #Nx.Tensor<
172180 f32[4][2]
173181 [
174- [-1.397004246711731 , -0.10283949971199036 ],
175- [-1.1967883110046387 , 0.17159013450145721 ],
176- [0.5603229403495789 , -0.10849219560623169 ],
177- [2.0334696769714355 , 0.039741579443216324 ]
182+ [-1.3970047 , -0.10283327 ],
183+ [-1.1967875 , 0.17159548 ],
184+ [0.56032246 , -0.10849468 ],
185+ [2.0334697 , 0.039732467 ]
178186 ]
179187 >
180188 iex> y
181189 #Nx.Tensor<
182190 f32[4][2]
183191 [
184- [-1.2260178327560425 , -0.019306711852550507 ],
185- [-0.9602956175804138 , 0.04015407711267471 ],
186- [0.3249155580997467 , -0.04311027377843857 ],
187- [1.8613981008529663 , 0.022262824699282646 ]
192+ [-1.226018 , -0.019301286 ],
193+ [-0.9602954 , 0.040158324 ],
194+ [0.32491535 , -0.043111708 ],
195+ [1.8613981 , 0.022254586 ]
188196 ]
189197 >
190198
@@ -252,20 +260,20 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
252260 #Nx.Tensor<
253261 f32[4][2]
254262 [
255- [-1.397004246711731 , -0.10283949971199036 ],
256- [-1.1967883110046387 , 0.17159013450145721 ],
257- [0.5603229403495789 , -0.10849219560623169 ],
258- [2.0334696769714355 , 0.039741579443216324 ]
263+ [-1.3970047 , -0.10283327 ],
264+ [-1.1967875 , 0.17159548 ],
265+ [0.56032246 , -0.10849468 ],
266+ [2.0334697 , 0.039732467 ]
259267 ]
260268 >
261269 iex> y
262270 #Nx.Tensor<
263271 f32[4][2]
264272 [
265- [-1.2260178327560425 , -0.019306711852550507 ],
266- [-0.9602956175804138 , 0.04015407711267471 ],
267- [0.3249155580997467 , -0.04311027377843857 ],
268- [1.8613981008529663 , 0.022262824699282646 ]
273+ [-1.226018 , -0.019301286 ],
274+ [-0.9602954 , 0.040158324 ],
275+ [0.32491535 , -0.043111708 ],
276+ [1.8613981 , 0.022254586 ]
269277 ]
270278 >
271279
0 commit comments