Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
6d7f649
Require Nx 0.13
RicardoSantos-99 Aug 9, 2026
c43a656
Update doctests for the f32 inspect change in Nx 0.13
RicardoSantos-99 Aug 9, 2026
2342a84
Fix remaining doctests for the f32 inspect change in Nx 0.13
RicardoSantos-99 Aug 22, 2026
037d836
Update PCA doctests for Nx 0.13's eigh fix
RicardoSantos-99 Aug 22, 2026
3a630be
Update KernelPCA doctests for Nx 0.13's eigh fix
RicardoSantos-99 Aug 22, 2026
e3c24b7
Update TruncatedSVD fixtures for Nx 0.13's eigh fix
RicardoSantos-99 Aug 23, 2026
0848564
Update LinearRegression doctest for Nx 0.13's precision
RicardoSantos-99 Aug 23, 2026
b9c9266
Update RidgeRegression doctests for Nx 0.13's precision
RicardoSantos-99 Aug 23, 2026
1aba311
Update PolynomialRegression doctests for Nx 0.13's precision
RicardoSantos-99 Aug 23, 2026
4536a86
Update TSNE fixtures for Nx 0.13
RicardoSantos-99 Aug 23, 2026
c406e53
Update BezierSpline fixtures for Nx 0.13's precision
RicardoSantos-99 Aug 23, 2026
0fe9ac8
Fix remaining LedoitWolf doctests for the f32 inspect change
RicardoSantos-99 Aug 23, 2026
497beff
Fix remaining ShrunkCovariance doctest for the f32 inspect change
RicardoSantos-99 Aug 23, 2026
ea51254
Fix remaining Classification metrics doctests for the f32 inspect change
RicardoSantos-99 Aug 23, 2026
fcc1ba3
Fix LinearRegression giving a spurious coefficient on near-degenerate…
RicardoSantos-99 Aug 23, 2026
47eef4c
Fix PLSSVD losing orthonormality on ill-conditioned cross-covariance
RicardoSantos-99 Aug 23, 2026
6686724
Fix RidgeRegression's default :svd solver on ill-conditioned input
RicardoSantos-99 Aug 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
- elixir: "1.19.4"
otp: "27.3"
lint: true
- elixir: "1.15.8"
otp: "26.1"
- elixir: "1.17.3"
otp: "26.2"
steps:
- uses: actions/checkout@v2

Expand Down
24 changes: 12 additions & 12 deletions lib/scholar/covariance/ledoit_wolf.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ defmodule Scholar.Covariance.LedoitWolf do
#Nx.Tensor<
f32[2][2]
[
[0.3557686507701874, 0.17340737581253052],
[0.17340737581253052, 1.0300586223602295]
[0.35576865, 0.17340738],
[0.17340738, 1.0300586]
]
>
iex> model.shrinkage
#Nx.Tensor<
f32
0.15034137666225433
0.15034138
>
iex> model.location
#Nx.Tensor<
f32[2]
[0.17184630036354065, 0.3276958167552948]
[0.1718463, 0.32769582]
>

iex> key = Nx.Random.key(0)
Expand All @@ -76,20 +76,20 @@ defmodule Scholar.Covariance.LedoitWolf do
#Nx.Tensor<
f32[3][3]
[
[2.5945029258728027, 1.5078359842300415, 1.1623677015304565],
[1.5078359842300415, 2.106797456741333, 1.1812156438827515],
[1.1623677015304565, 1.1812156438827515, 1.4606266021728516]
[2.594503, 1.507836, 1.1623677],
[1.507836, 2.1067975, 1.1812156],
[1.1623677, 1.1812156, 1.4606266]
]
>
iex> model.shrinkage
#Nx.Tensor<
f32
0.1908363401889801
0.19083634
>
iex> model.location
#Nx.Tensor<
f32[3]
[1.1228725910186768, 0.5419300198554993, 0.8678852319717407]
[1.1228726, 0.54193, 0.86788523]
>

iex> key = Nx.Random.key(0)
Expand All @@ -99,9 +99,9 @@ defmodule Scholar.Covariance.LedoitWolf do
#Nx.Tensor<
f32[3][3]
[
[3.8574986457824707, 2.2048025131225586, 2.1504499912261963],
[2.2048025131225586, 2.4572863578796387, 1.7215262651443481],
[2.1504499912261963, 1.7215262651443481, 2.154898166656494]
[3.8574986, 2.2048025, 2.15045],
[2.2048025, 2.4572864, 1.7215263],
[2.15045, 1.7215263, 2.1548982]
]
>
"""
Expand Down
12 changes: 6 additions & 6 deletions lib/scholar/covariance/shrunk_covariance.ex
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ defmodule Scholar.Covariance.ShrunkCovariance do
#Nx.Tensor<
f32[2][2]
[
[0.7721845507621765, 0.19141492247581482],
[0.19141492247581482, 0.33952537178993225]
[0.77218455, 0.19141492],
[0.19141492, 0.33952537]
]
>
iex> model.location
#Nx.Tensor<
f32[2]
[0.18202415108680725, -0.09216632694005966]
[0.18202415, -0.09216633]
>
iex> key = Nx.Random.key(0)
iex> {x, _new_key} = Nx.Random.multivariate_normal(key, Nx.tensor([0.0, 0.0]), Nx.tensor([[0.8, 0.3], [0.2, 0.4]]), shape: {10}, type: :f32)
Expand All @@ -67,14 +67,14 @@ defmodule Scholar.Covariance.ShrunkCovariance do
#Nx.Tensor<
f32[2][2]
[
[0.7000747323036194, 0.1276099532842636],
[0.1276099532842636, 0.41163527965545654]
[0.70007473, 0.12760995],
[0.12760995, 0.41163528]
]
>
iex> model.location
#Nx.Tensor<
f32[2]
[0.18202415108680725, -0.09216632694005966]
[0.18202415, -0.09216633]
>
"""

Expand Down
50 changes: 29 additions & 21 deletions lib/scholar/cross_decomposition/pls_svd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
iex> model.y_std
#Nx.Tensor<
f32[2]
[5.467098712921143, 5.661198616027832]
[5.4670987, 5.6611986]
>
iex> model.x_weights
#Nx.Tensor<
f32[3][2]
[
[0.521888256072998, -0.11256571859121323],
[0.6170258522033691, 0.7342619299888611],
[0.5889922380447388, -0.6694686412811279]
[0.5218878, -0.11256802],
[0.6170291, 0.7342591],
[0.58898926, -0.66947126]
]
>
"""
Expand All @@ -115,7 +115,15 @@ defmodule Scholar.CrossDecomposition.PLSSVD do

c = Nx.dot(x, [0], y, [0])

{u, _s, vt} = Nx.LinAlg.svd(c, full_matrices?: false)
# full_matrices?: true on purpose: the false path forms the Gram matrix
# CᵀC to avoid the larger QR/Halley iteration, which squares the
# condition number and can cost the smaller singular vectors real
# precision (Nx.LinAlg.svd's own docs call this out). C here is the
# cross-covariance of two already small, already centered and scaled
# blocks, so its singular values are routinely far apart, exactly the
# regime that trade-off hurts. true costs more but keeps x_weights and
# y_weights properly orthonormal.
{u, _s, vt} = Nx.LinAlg.svd(c, full_matrices?: true)
u = Nx.slice_along_axis(u, 0, num_components, axis: 1)
vt = Nx.slice_along_axis(vt, 0, num_components, axis: 0)
{u, vt} = Scholar.Decomposition.Utils.flip_svd(u, vt)
Expand Down Expand Up @@ -171,20 +179,20 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
#Nx.Tensor<
f32[4][2]
[
[-1.397004246711731, -0.10283949971199036],
[-1.1967883110046387, 0.17159013450145721],
[0.5603229403495789, -0.10849219560623169],
[2.0334696769714355, 0.039741579443216324]
[-1.3970047, -0.10283327],
[-1.1967875, 0.17159548],
[0.56032246, -0.10849468],
[2.0334697, 0.039732467]
]
>
iex> y
#Nx.Tensor<
f32[4][2]
[
[-1.2260178327560425, -0.019306711852550507],
[-0.9602956175804138, 0.04015407711267471],
[0.3249155580997467, -0.04311027377843857],
[1.8613981008529663, 0.022262824699282646]
[-1.226018, -0.019301286],
[-0.9602954, 0.040158324],
[0.32491535, -0.043111708],
[1.8613981, 0.022254586]
]
>

Expand Down Expand Up @@ -252,20 +260,20 @@ defmodule Scholar.CrossDecomposition.PLSSVD do
#Nx.Tensor<
f32[4][2]
[
[-1.397004246711731, -0.10283949971199036],
[-1.1967883110046387, 0.17159013450145721],
[0.5603229403495789, -0.10849219560623169],
[2.0334696769714355, 0.039741579443216324]
[-1.3970047, -0.10283327],
[-1.1967875, 0.17159548],
[0.56032246, -0.10849468],
[2.0334697, 0.039732467]
]
>
iex> y
#Nx.Tensor<
f32[4][2]
[
[-1.2260178327560425, -0.019306711852550507],
[-0.9602956175804138, 0.04015407711267471],
[0.3249155580997467, -0.04311027377843857],
[1.8613981008529663, 0.022262824699282646]
[-1.226018, -0.019301286],
[-0.9602954, 0.040158324],
[0.32491535, -0.043111708],
[1.8613981, 0.022254586]
]
>

Expand Down
12 changes: 6 additions & 6 deletions lib/scholar/decomposition/kernel_pca.ex
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ defmodule Scholar.Decomposition.KernelPCA do
iex> x = Nx.tensor([[0.5, 0.2, 0.8], [1.0, 0.5, 0.2], [0.3, 1.0, 0.7], [0.9, 0.1, 1.0]])
iex> kpca = Scholar.Decomposition.KernelPCA.fit(x, num_components: 2, kernel: :rbf)
iex> kpca.eigenvalues
Nx.tensor([0.3644833564758301, 0.2607457637786865])
Nx.tensor([0.3644834, 0.26074564])
"""
deftransform fit(x, opts \\ []) do
opts = NimbleOptions.validate!(opts, @opts_schema)
Expand Down Expand Up @@ -164,7 +164,7 @@ defmodule Scholar.Decomposition.KernelPCA do
iex> Scholar.Decomposition.KernelPCA.transform(kpca, Nx.tensor([[0.5, 0.5, 0.5]]))
Nx.tensor(
[
[0.12500187754631042, 0.02909737080335617]
[0.12497942, 0.029221743]
]
)
"""
Expand Down Expand Up @@ -216,10 +216,10 @@ defmodule Scholar.Decomposition.KernelPCA do
iex> Scholar.Decomposition.KernelPCA.fit_transform(x, num_components: 2, kernel: :rbf)
Nx.tensor(
[
[-0.13561572134494781, -0.16519643366336823],
[0.021601030603051186, 0.44114425778388977],
[0.4687873423099518, -0.1576462835073471],
[-0.3547726571559906, -0.1183016300201416]
[-0.13543777, -0.16535977],
[0.021126157, 0.44115686],
[0.4689568, -0.15726776],
[-0.3546452, -0.1185294]
]
)
"""
Expand Down
37 changes: 18 additions & 19 deletions lib/scholar/decomposition/pca.ex
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ defmodule Scholar.Decomposition.PCA do
iex> pca.components
Nx.tensor(
[
[0.36182016134262085, -0.08202514797449112, 0.8565111756324768, 0.3588128685951233],
[0.6585038900375366, 0.7275884747505188, -0.17632202804088593, -0.07679986208677292]
[0.36158934, -0.082268484, 0.8565728, 0.35884288],
[0.65654594, 0.72970587, -0.17576799, -0.074712664]
]
)
iex> pca.singular_values
Nx.tensor([25.089859008789062, 6.007821559906006])
Nx.tensor([25.089865, 6.007852])
"""
deftransform fit(x, opts \\ []) do
opts = NimbleOptions.validate!(opts, @opts_schema)
Expand Down Expand Up @@ -210,12 +210,12 @@ defmodule Scholar.Decomposition.PCA do
iex> pca.components
Nx.tensor(
[
[-0.33354005217552185, 0.1048964187502861, -0.8618107080105579, -0.3674643635749817],
[-0.5862125754356384, -0.7916879057884216, 0.15874788165092468, -0.06621300429105759]
[-0.3331483, 0.105326004, -0.86190677, -0.36747244],
[-0.58288467, -0.79399943, 0.15797591, -0.06967129]
]
)
iex> pca.singular_values
Nx.tensor([77.05782028025969, 10.137848854064941])
Nx.tensor([77.05691, 10.158366])
"""
deftransform incremental_fit(batches, opts) do
opts = NimbleOptions.validate!(opts, @opts_schema)
Expand All @@ -242,12 +242,12 @@ defmodule Scholar.Decomposition.PCA do
iex> pca.components
Nx.tensor(
[
[-0.3229745328426361, 0.09587063640356064, -0.8628664612770081, -0.37677285075187683],
[-0.6786625981330872, -0.7167785167694092, 0.14237160980701447, 0.07332050055265427]
[-0.32289746, 0.095940694, -0.8628819, -0.37678596],
[-0.67544055, -0.7201917, 0.141901, 0.070487075]
]
)
iex> pca.singular_values
Nx.tensor([166.141845703125, 6.078948020935059])
Nx.tensor([166.14182, 6.078579])
"""
deftransform partial_fit(model, x) do
if Nx.rank(x) != 2 do
Expand Down Expand Up @@ -373,9 +373,9 @@ defmodule Scholar.Decomposition.PCA do
iex> Scholar.Decomposition.PCA.transform(pca, x_transform)
Nx.tensor(
[
[-1.4739344120025635, -0.48932668566703796],
[0.28113049268722534, 0.2337251454591751],
[2.0361955165863037, 0.9567767977714539]
[-1.4737695, -0.49078038],
[0.28105056, 0.23384926],
[2.0358706, 0.9584787]
]
)
"""
Expand Down Expand Up @@ -442,13 +442,12 @@ defmodule Scholar.Decomposition.PCA do
iex> Scholar.Decomposition.PCA.fit_transform(x, num_components: 2)
Nx.tensor(
[
[0.16441848874092102, 0.028548287227749825],
[-0.32804328203201294, 0.20709986984729767],
[-0.3284338414669037, -0.08318747580051422],
[-0.42237386107444763, -0.0735677033662796],
[0.17480169236660004, -0.11189625412225723],
[0.7396301627159119, 0.03300142288208008
]
[0.16341472, -0.017230444],
[-0.33249766, 0.1893504],
[-0.32686582, -0.10110473],
[-0.42023695, -0.005525116],
[0.1768687, -0.14014886],
[0.7393165, 0.074657336]
]
)
"""
Expand Down
24 changes: 12 additions & 12 deletions lib/scholar/decomposition/truncated_svd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ defmodule Scholar.Decomposition.TruncatedSVD do
#Nx.Tensor<
f32[2][2]
[
[0.6871105432510376, 0.7265529036521912],
[0.7265529036521912, -0.6871105432510376]
[0.68631727, 0.72730225],
[0.72730225, -0.68631727]
]
>
iex> tsvd.singular_values
#Nx.Tensor<
f32[2]
[7.528080940246582, 0.7601959705352783]
[7.5280886, 0.7601881]
>

"""
Expand Down Expand Up @@ -119,10 +119,10 @@ defmodule Scholar.Decomposition.TruncatedSVD do
f32[5][2]
[
[0.0, 0.0],
[0.6871105432510376, 0.7265529036521912],
[1.413663387298584, 0.039442360401153564],
[4.240990161895752, 0.1183270812034607],
[6.017930030822754, -0.18578583002090454]
[0.68631727, 0.72730225],
[1.4136195, 0.04098499],
[4.2408586, 0.122954965],
[6.0181293, -0.17921868]
]
>
iex> key = Nx.Random.key(0)
Expand All @@ -131,11 +131,11 @@ defmodule Scholar.Decomposition.TruncatedSVD do
#Nx.Tensor<
f32[5][2]
[
[1.9478826522827148, 2.260593891143799],
[2.481153964996338, 1.906071662902832],
[3.023407220840454, 1.352442979812622],
[5.174456596374512, -0.46385863423347473],
[6.521108150482178, -1.6488237380981445]
[1.9499695, 2.258082],
[2.4829183, 1.9048187],
[3.024655, 1.3492495],
[5.1740265, -0.46841517],
[6.5195804, -1.655032]
]
>
"""
Expand Down
6 changes: 3 additions & 3 deletions lib/scholar/interpolation/bezier_spline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ defmodule Scholar.Interpolation.BezierSpline do
[
[
[0.0, 2.0],
[0.3333331048488617, 1.0333333015441895],
[0.6666665077209473, 0.06666667759418488],
[0.33333334, 1.0333333],
[0.66666675, 0.06666667],
[1.0, 0.0]
],
[
[1.0, 0.0],
[1.3333334922790527, -0.06666667759418488],
[1.3333333, -0.06666667],
[1.6666665077209473, 0.7666666507720947],
[2.0, 1.0]
],
Expand Down
Loading
Loading