API Reference¶
Models¶
rbig.AnnealedRBIG
¶
Bases: TransformerMixin, BaseEstimator
Rotation-Based Iterative Gaussianization (RBIG).
RBIG is a density estimation and data transformation method that iteratively Gaussianizes multivariate data by alternating between:
- Marginal Gaussianization: mapping each feature to a Gaussian using its empirical CDF and the probit transform.
- Rotation: applying an orthogonal matrix (PCA or ICA) to de-correlate the Gaussianized features.
The process repeats until the total correlation (TC) of the transformed data converges. After fitting, the model represents a normalizing flow whose density is given by the change-of-variables formula:
log p(x) = log p_Z(f(x)) + log|det J_f(x)|
where f is the composition of all fitted layers and p_Z is a
standard multivariate Gaussian.
Parameters¶
n_layers : int, default=100
Maximum number of RBIG layers to apply. Early stopping via
patience may halt training before this limit.
rotation : str, default="pca"
Rotation method: "pca" (PCA without whitening — orthogonal),
"ica" (Independent Component Analysis), or "random"
(Haar-distributed orthogonal rotation).
patience : int, default=10
Number of consecutive layers showing a TC change smaller than
tol before training stops early. (Formerly zero_tolerance,
which is still accepted but deprecated.)
tol : float or "auto", default=1e-5
Convergence threshold for the per-layer change in total correlation:
|TC(k) − TC(k−1)| < tol. When set to "auto", the tolerance
is chosen adaptively based on the number of training samples using
an empirically calibrated lookup table.
random_state : int or None, default=None
Seed for the random number generator used by stochastic components
such as ICA or random rotations.
strategy : list or None, default=None
Optional per-layer override list. Each entry may be a string
(rotation name) or a (rotation_name, marginal_name) pair.
Entries cycle if the list is shorter than n_layers.
verbose : bool or int, default=False
Controls progress bar display. False (or 0) disables all
progress bars. True (or 1) shows a progress bar for the
fit loop. 2 additionally shows progress bars for
transform, inverse_transform, score_samples, and
jacobian.
Attributes¶
n_features_in_ : int
Number of features seen during fit.
layers_ : list of RBIGLayer
Fitted RBIG layers in application order.
tc_per_layer_ : list of float
Total correlation of the data at each stage. Index 0 is the TC
of the input data (before any layers); index k >= 1 is the TC
after layer k.
log_det_train_ : np.ndarray of shape (n_samples,)
Accumulated per-sample log-det-Jacobian over all layers,
computed on the training data during fit.
X_transformed_ : np.ndarray of shape (n_samples, n_features)
Training data after passing through all fitted layers.
Notes¶
Total correlation is defined as:
TC(X) = ∑ᵢ H(Xᵢ) − H(X)
where H(Xᵢ) is the marginal entropy of the i-th feature and H(X) is the joint entropy. For a fully Gaussianized, independent dataset, TC = 0.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: From ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537–549. https://doi.org/10.1109/TNN.2011.2106511
Examples¶
import numpy as np from rbig._src.model import AnnealedRBIG rng = np.random.default_rng(42) X = rng.standard_normal((300, 4)) model = AnnealedRBIG(n_layers=20, rotation="pca") model.fit(X)
Z = model.transform(X) Z.shape (300, 4) model.score(X) # mean log-likelihood in nats -5.65...
Source code in rbig/_src/model.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 | |
zero_tolerance
property
writable
¶
Deprecated alias for patience.
fit(X, y=None)
¶
Fit the RBIG model by iteratively Gaussianizing X.
At each layer k the algorithm:
- Builds a new :class:
RBIGLayerwith the configured marginal and rotation transforms. - Fits the layer on the current working copy
Xt. - Accumulates the per-sample log-det-Jacobian:
log_det_train_ += log|det J_k(Xt)|. - Advances
Xtthrough the layer:Xt = f_k(Xt). - Measures residual total correlation:
TC(Xt) = ∑ᵢ H(Xᵢ) − H(X). - Stops early when TC has not changed by more than
tolforpatienceconsecutive layers.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
self : AnnealedRBIG The fitted model.
Source code in rbig/_src/model.py
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | |
transform(X)
¶
Map X to the Gaussian latent space through all fitted layers.
Applies each fitted :class:RBIGLayer in order:
Z = fₖ(… f₂(f₁(x)) …).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Data in the approximately Gaussian latent space.
Source code in rbig/_src/model.py
inverse_transform(X)
¶
Map latent-space data back to the original input space.
Applies layers in reverse order:
x = f₁⁻¹(… fₖ₋₁⁻¹(fₖ⁻¹(z)) …).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the latent (approximately Gaussian) space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original input space.
Source code in rbig/_src/model.py
fit_transform(X, y=None)
¶
Fit the model to X and return the latent-space representation.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Transformed data in the latent space.
Source code in rbig/_src/model.py
score_samples(X)
¶
Per-sample log-likelihood under the fitted density model.
Uses the change-of-variables formula for normalizing flows:
log p(x) = log p_Z(f(x)) + log|det J_f(x)|
where p_Z = 𝒩(0, I) is the standard Gaussian base density,
f is the composition of all fitted layers, and J_f(x) is
the Jacobian of f at x.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data points at which to evaluate the log-likelihood.
Returns¶
log_prob : np.ndarray of shape (n_samples,) Per-sample log-likelihood in nats.
Notes¶
The log-det-Jacobian is accumulated layer by layer to avoid recomputing intermediate representations:
log|det J_f(x)| = ∑ₖ log|det J_fₖ(xₖ₋₁)|
Source code in rbig/_src/model.py
score(X, y=None)
¶
Mean log-likelihood of samples X under the fitted density.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data points to evaluate. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
mean_log_prob : float Average per-sample log-likelihood in nats.
Source code in rbig/_src/model.py
entropy()
¶
Differential entropy of the fitted distribution in nats.
Estimated from the training data using:
H(X) = −𝔼_X[log p(x)]
The expectation is approximated by the sample mean over the training
set. The log-likelihoods are obtained via the efficient cached path
:meth:score_samples_raw_ which reuses pre-computed quantities from
fit.
Returns¶
h : float Estimated entropy in nats. Always ≥ 0 for continuous distributions.
Notes¶
This is equivalent to -self.score(X_train) but avoids the cost
of re-passing training data through all layers.
Source code in rbig/_src/model.py
total_correlation_reduction()
¶
Total correlation removed by RBIG (RBIG-way TC estimation).
Uses the per-layer TC reduction approach from Laparra et al. (2011):
TC(X) = TC₀ − TCₖ = Σₖ ΔTCₖ
where TC₀ is the total correlation of the input and TCₖ is the residual TC after K layers of Gaussianization. When the model has converged, TCₖ ≈ 0 and the result equals TC₀.
Returns¶
tc : float Estimated total correlation in nats.
Source code in rbig/_src/model.py
entropy_reduction(X)
¶
Differential entropy via RBIG-way TC reduction.
Uses the identity H(X) = Σ_d H(X_d) − TC(X) where marginal entropies are estimated via KDE and TC is obtained from the cumulative per-layer TC reduction (Laparra et al. 2011).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data whose entropy is estimated (typically the training data).
Returns¶
h : float Estimated differential entropy in nats.
Source code in rbig/_src/model.py
score_samples_raw_()
¶
Log-likelihood for the stored training data without recomputing layers.
Reuses X_transformed_ and log_det_train_ cached during
:meth:fit, so the cost is a single Gaussian log-pdf evaluation
rather than a full forward pass through all layers.
Returns¶
log_prob : np.ndarray of shape (n_samples,) Per-sample log-likelihood of the training data in nats.
Source code in rbig/_src/model.py
sample(n_samples, random_state=None)
¶
Generate samples from the learned distribution.
Draws i.i.d. standard Gaussian samples in the latent space and maps them back to the data space via the inverse normalizing flow.
Parameters¶
n_samples : int
Number of samples to generate.
random_state : int or None, optional
Seed for the random number generator. If None, a random
seed is used.
Returns¶
X_new : np.ndarray of shape (n_samples, n_features_in_) Samples in the original data space.
Source code in rbig/_src/model.py
predict_proba(X, domain='input')
¶
Return probability density estimates for X.
Uses the change-of-variables formula via the full Jacobian matrix to compute the density in the requested domain.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data points to evaluate. domain : str, default="input" Which domain to return densities in:
- ``"input"`` — density in the original data space:
``p(x) = p_Z(f(x)) · |det J_f(x)|``
- ``"transform"`` — density in the Gaussian latent space:
``p_Z(f(x)) = ∏ᵢ φ(fᵢ(x))``
- ``"both"`` — returns a tuple ``(p_input, p_transform)``
Returns¶
proba : np.ndarray of shape (n_samples,) or tuple
Probability density estimates. When domain="both", returns
(p_input, p_transform).
Source code in rbig/_src/model.py
jacobian(X, return_X_transform=False)
¶
Compute the full Jacobian matrix of the RBIG transform.
For each sample, returns the (n_features, n_features) Jacobian
matrix df/dx of the composition of all fitted layers. Uses the
seed-dimension approach from the legacy implementation: for each input
dimension idim, a unit vector is propagated through the chain of
per-feature marginal derivatives and rotation matrices.
Parameters¶
X : np.ndarray of shape (n_samples, n_features)
Input data at which to evaluate the Jacobian.
return_X_transform : bool, default False
If True, also return the fully transformed data f(X) (computed
as a side-effect of the Jacobian calculation).
Returns¶
jac : np.ndarray of shape (n_samples, n_features, n_features)
Full Jacobian matrix per sample. jac[n, i, j] is the partial
derivative df_i/dx_j for the n-th sample.
X_transformed : np.ndarray of shape (n_samples, n_features)
Only returned when return_X_transform=True. The data after
passing through all layers.
Source code in rbig/_src/model.py
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 | |
rbig.RBIGLayer
dataclass
¶
Single RBIG layer: marginal Gaussianization followed by rotation.
One iteration of the RBIG algorithm applies two successive bijections:
-
Marginal Gaussianization – maps each feature independently to a standard Gaussian via its empirical CDF and the probit function:
z = Φ⁻¹(F̂ₙ(x))
where F̂ₙ is the estimated marginal CDF and Φ⁻¹ is the standard normal quantile function.
-
Rotation/whitening – applies a linear transform R (default: PCA whitening) to de-correlate the Gaussianized features:
y = R · z
The full single-layer transform is therefore:
y = R · Φ⁻¹(F̂ₙ(x))
Parameters¶
marginal : MarginalGaussianize, optional
Marginal Gaussianization transform (fitted per feature).
Defaults to a new MarginalGaussianize instance.
rotation : PCARotation, optional
Rotation transform applied after marginal Gaussianization.
Defaults to a new PCARotation instance.
Attributes¶
marginal : MarginalGaussianize Fitted marginal transform. rotation : PCARotation Fitted rotation transform.
Notes¶
The layer log-det-Jacobian is the sum of the marginal and rotation contributions:
log|det J_layer(x)| = log|det J_marginal(x)| + log|det J_rotation|
= ∑ᵢ log|Φ⁻¹′(F̂ₙ(xᵢ)) · f̂ₙ(xᵢ)| + log|det J_rotation|
The rotation term log|det J_rotation| is zero when the rotation is
strictly orthogonal (|det R| = 1). The default
PCARotation(whiten=False) is orthogonal, so its log-det is always
zero. PCARotation(whiten=True) includes per-component scaling by
1/√λ and is not orthogonal (non-zero log-det). Note that both
converge to identical results in practice because marginal
Gaussianization already produces near-unit-variance features.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: From ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537–549. https://doi.org/10.1109/TNN.2011.2106511
Examples¶
import numpy as np from rbig._src.model import RBIGLayer rng = np.random.default_rng(0) X = rng.standard_normal((500, 3)) layer = RBIGLayer() layer.fit(X) RBIGLayer(...) Z = layer.transform(X) Z.shape (500, 3)
Source code in rbig/_src/model.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | |
fit(X, y=None)
¶
Fit the marginal and rotation transforms to data X.
First fits the marginal Gaussianizer on X, applies it to obtain the intermediate Gaussianized representation, then fits the rotation on that intermediate representation.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
self : RBIGLayer The fitted layer.
Source code in rbig/_src/model.py
transform(X)
¶
Apply marginal Gaussianization then rotation: y = R · Φ⁻¹(F̂ₙ(x)).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Y : np.ndarray of shape (n_samples, n_features) Transformed data after Gaussianization and rotation.
Source code in rbig/_src/model.py
log_det_jacobian(X)
¶
Log |det J| for this layer at input X.
The total log-det-Jacobian is the sum of contributions from the marginal step and the rotation step:
log|det J_layer(x)| = log|det J_marginal(x)| + log|det J_rotation(z)|
For orthogonal rotations (e.g. RandomRotation,
PCARotation(whiten=False)), the rotation term is zero. For
PCARotation(whiten=True) the rotation includes a per-component
rescaling, so its term is generally non-zero.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points.
Returns¶
ldj : np.ndarray of shape (n_samples,) Per-sample log absolute determinant of the layer Jacobian.
Source code in rbig/_src/model.py
inverse_transform(X)
¶
Invert the layer: apply inverse rotation then inverse marginal.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the layer's output (latent) space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original input space.
Source code in rbig/_src/model.py
Marginal Transforms¶
rbig.MarginalUniformize
¶
Bases: BaseTransform
Transform each marginal to uniform [0, 1] using the empirical CDF.
For each feature dimension i, the empirical CDF is estimated from the training data with a mid-point (Hazen) continuity correction::
u_hat = F_hat_n(x) = (rank(x, X_train) + 0.5) / N
where rank is the number of training samples <= x (left-sided
searchsorted) and N is the number of training samples. The
+0.5 shift avoids the degenerate values 0 and 1 for in-sample
boundary points.
Parameters¶
bound_correct : bool, default True
If True, clip the output to [eps, 1 - eps] to prevent exact 0
or 1, which is useful when feeding the result into a probit or
logit function.
eps : float, default 1e-6
Half-width of the clipping margin when bound_correct=True.
Attributes¶
support_ : np.ndarray of shape (n_samples, n_features)
Column-wise sorted training data. Serves as empirical quantile
nodes for both the forward transform and piecewise-linear inversion.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The mid-point empirical CDF (Hazen plotting position) is::
F_hat_n(x) = (rank + 0.5) / N
The inverse is approximated by piecewise-linear interpolation between
the sorted support values and their corresponding uniform probabilities
np.linspace(0, 1, N).
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import MarginalUniformize rng = np.random.default_rng(0) X = rng.standard_normal((100, 2)) uni = MarginalUniformize().fit(X) U = uni.transform(X) U.shape (100, 2) bool(U.min() > 0.0) and bool(U.max() < 1.0) True Xr = uni.inverse_transform(U) Xr.shape (100, 2)
Source code in rbig/_src/marginal.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
fit(X, y=None)
¶
Fit the transform by storing sorted training values per feature.
When pdf_extension > 0, a histogram-based CDF pipeline is used
instead of the default empirical CDF. This extends the support by
pdf_extension percent of the data range and builds an interpolated,
monotonic CDF on a grid of pdf_resolution points.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data. Each column is sorted and stored as the empirical support (quantile nodes) for that feature.
Returns¶
self : MarginalUniformize Fitted transform instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Map each feature to [0, 1] via the mid-point empirical CDF.
Applies u = (rank + 0.5) / N to every column independently.
When pdf_extension > 0, uses interpolation with the stored
histogram-based CDF grid instead.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features)
Uniformized data in [0, 1] (or [eps, 1 - eps] when
bound_correct=True).
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Map uniform [0, 1] values back to the original space.
Uses piecewise-linear interpolation between the stored sorted support
values and their corresponding uniform probabilities
np.linspace(0, 1, N). When pdf_extension > 0, uses the
inverted histogram CDF grid instead.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the uniform [0, 1] space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space.
Source code in rbig/_src/marginal.py
rbig.MarginalGaussianize
¶
Bases: BaseTransform
Transform each marginal to standard Gaussian using empirical CDF + probit.
Combines a mid-point empirical CDF estimate with the Gaussian probit (quantile) function Phi^{-1} to map each feature to an approximately standard-normal marginal::
z = Phi ^ {-1}(F_hat_n(x))
where F_hat_n(x) = (rank + 0.5) / N is the mid-point empirical CDF
and Phi^{-1} is the inverse standard-normal CDF (probit).
Parameters¶
bound_correct : bool, default True
Clip the intermediate uniform value to [eps, 1 - eps] before
applying the probit to prevent +/-inf outputs at the tails.
eps : float, default 1e-6
Clipping margin for the uniform intermediate value.
Attributes¶
support_ : np.ndarray of shape (n_samples, n_features)
Column-wise sorted training data (empirical quantile nodes).
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The log-absolute Jacobian determinant needed for density estimation is::
log|dz/dx| = log f_hat_n(x) - log phi(Phi^{-1}(F_hat_n(x)))
where f_hat_n is the empirical density estimated from the spacing of
adjacent sorted training values, and phi is the standard-normal PDF.
This is computed in :meth:log_det_jacobian.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import MarginalGaussianize rng = np.random.default_rng(0) X = rng.standard_normal((200, 3)) mg = MarginalGaussianize().fit(X) Z = mg.transform(X) Z.shape (200, 3) abs(float(Z.mean())) < 0.5 True
Source code in rbig/_src/marginal.py
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | |
fit(X, y=None)
¶
Fit by storing the column-wise sorted training data.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data used to build the per-feature empirical CDF.
Returns¶
self : MarginalGaussianize Fitted transform instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Map each feature to N(0, 1) via empirical CDF then probit.
Applies z = Phi^{-1}(F_hat_n(x)) column by column.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Gaussianized data; each column has approximately N(0, 1) marginal.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Map standard-normal values back to the original space.
Applies the normal CDF Phi to obtain uniform values, then uses piecewise-linear interpolation through the sorted support to recover approximate original-space values.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized (standard-normal) space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space.
Source code in rbig/_src/marginal.py
log_det_jacobian(X)
¶
Log |det J| for marginal Gaussianization.
For g(x) = Phi^{-1}(F_n(x)): log|dg/dx| = log f_n(x_i) - log phi(g(x_i))
where f_n is estimated from a Gaussian KDE fitted to the training data for each feature.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data at which to evaluate the log-det-Jacobian.
Returns¶
log_jac : np.ndarray of shape (n_samples,) Per-sample sum of per-feature log-derivatives.
Notes¶
The empirical density is approximated via a Gaussian KDE (one per
feature) fitted during :meth:fit. Bandwidth is selected
automatically using Scott's rule (the default in
:func:scipy.stats.gaussian_kde). The KDE objects are cached
in self.kdes_ so that log_det_jacobian and repeated calls
to _per_feature_log_deriv do not re-fit the KDEs.
Source code in rbig/_src/marginal.py
rbig.MarginalKDEGaussianize
¶
Bases: BaseTransform
Transform each marginal to Gaussian using a KDE-estimated CDF.
A kernel density estimate (KDE) with a Gaussian kernel is fitted to each feature dimension. The cumulative integral of the KDE serves as a smooth approximation to the marginal CDF, which is then composed with the probit function Phi^{-1} to Gaussianize each dimension::
z = Phi ^ {-1}(F_KDE(x))
where F_KDE(x) = integral_{-inf}^{x} f_KDE(t) dt and f_KDE is
the Gaussian-kernel density estimate.
Parameters¶
bw_method : str, float, or None, default None
Bandwidth selection method passed to
:class:scipy.stats.gaussian_kde. None uses Scott's rule;
'silverman' uses Silverman's rule; a scalar sets the bandwidth
factor directly.
eps : float, default 1e-6
Clipping margin to prevent Phi^{-1}(0) = -inf or
Phi^{-1}(1) = +inf.
Attributes¶
kdes_ : list of scipy.stats.gaussian_kde
One fitted KDE object per feature dimension.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The inverse transform inverts the KDE CDF numerically via Brent's method
(:func:scipy.optimize.brentq) searching in [-100, 100]. Samples
outside this range default to 0.0.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import MarginalKDEGaussianize rng = np.random.default_rng(0) X = rng.standard_normal((50, 2)) kde_g = MarginalKDEGaussianize().fit(X) Z = kde_g.transform(X) Z.shape (50, 2)
Source code in rbig/_src/marginal.py
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | |
fit(X, y=None)
¶
Fit a Gaussian KDE to each feature dimension.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : MarginalKDEGaussianize Fitted transform instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Map each feature to N(0, 1) via KDE CDF then probit.
Computes z = Phi^{-1}(F_KDE(x)) per feature using numerical
integration of the fitted KDE.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Gaussianized data.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Map standard-normal values back to the original space.
Numerically inverts the KDE CDF via Brent's root-finding method. For each sample j and feature i, solves::
F_KDE(x) = Phi(z_j)
searching on the interval [-100, 100].
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space. Samples that fail root-finding are set to 0.0.
Source code in rbig/_src/marginal.py
rbig.SplineGaussianizer
¶
Bases: Bijector
Gaussianize each marginal using monotone PCHIP spline interpolation.
Estimates the marginal CDF from empirical quantiles and fits a shape-preserving (monotone) cubic Hermite spline (PCHIP) from original-space quantile values to the corresponding Gaussian quantiles. The forward transform is::
z = S(x)
where S is the fitted :class:scipy.interpolate.PchipInterpolator
mapping data values to standard-normal quantiles. Because PCHIP
preserves monotonicity, the mapping is guaranteed to be invertible.
Parameters¶
n_quantiles : int, default 200
Number of quantile nodes used to fit the splines. Capped at
n_samples when fewer training samples are available.
eps : float, default 1e-6
Clipping margin applied to the Gaussian quantile grid to keep
the spline endpoints finite (avoids +/-inf at boundary quantiles).
Attributes¶
splines_ : list of scipy.interpolate.PchipInterpolator
Forward splines (x -> z) per feature, mapping original-space
values to standard-normal quantiles.
inv_splines_ : list of scipy.interpolate.PchipInterpolator
Inverse splines (z -> x) per feature, mapping Gaussian quantiles
back to original-space values.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The log-det-Jacobian uses the analytic first derivative of the spline::
log|dz/dx| = log|S'(x)|
where S' is the first derivative of the PCHIP forward spline,
evaluated via spline(x, 1) (the derivative-order argument).
Duplicate x-values (arising from discrete or constant features) are removed before fitting to ensure strict monotonicity.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import SplineGaussianizer rng = np.random.default_rng(0) X = rng.standard_normal((300, 3)) sg = SplineGaussianizer(n_quantiles=100).fit(X) Z = sg.transform(X) Z.shape (300, 3) ldj = sg.get_log_det_jacobian(X) ldj.shape (300,)
Source code in rbig/_src/marginal.py
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 | |
fit(X, y=None)
¶
Fit forward and inverse PCHIP splines for each feature.
For each dimension, n_quantiles evenly-spaced probability levels
are mapped to their empirical quantile values in the data, and the
corresponding Gaussian quantile values Phi^{-1}(p) are computed.
PCHIP interpolants are then fitted in both directions.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : SplineGaussianizer Fitted bijector instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Apply the forward spline map: x -> z = S(x).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Gaussianized data with approximately standard-normal marginals.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Apply the inverse spline map: z -> x = S^{-1}(z).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space.
Source code in rbig/_src/marginal.py
get_log_det_jacobian(X)
¶
Compute log |det J| using the analytic spline first derivative.
Because the Jacobian is diagonal::
log|det J| = sum_i log|S'(x_i)|
where S' is the first derivative of the PCHIP forward spline,
evaluated via spline(x, 1) (the derivative order argument).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
log_det : np.ndarray of shape (n_samples,) Per-sample log absolute determinant.
Source code in rbig/_src/marginal.py
rbig.KDEGaussianizer
¶
Bases: Bijector
Gaussianize each marginal using a KDE-estimated CDF and probit.
Fits a Gaussian kernel density estimate (KDE) to each feature dimension, then maps samples to standard-normal values via::
z = Phi ^ {-1}(F_KDE(x))
where F_KDE(x) = integral_{-inf}^{x} f_KDE(t) dt is the smooth
KDE-based CDF and Phi^{-1} is the Gaussian probit (inverse CDF).
Parameters¶
bw_method : str, float, or None, default None
Bandwidth selection passed to :class:scipy.stats.gaussian_kde.
None uses Scott's rule; 'silverman' uses Silverman's rule;
a scalar sets the smoothing factor directly.
eps : float, default 1e-6
Clipping margin applied to the CDF value before the probit to
prevent Phi^{-1}(0) = -inf or Phi^{-1}(1) = +inf.
Attributes¶
kdes_ : list of scipy.stats.gaussian_kde
One fitted KDE per feature dimension.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The log-det-Jacobian uses the analytic KDE density::
log|dz/dx| = log f_KDE(x) - log phi(z)
where phi is the standard-normal PDF evaluated at the Gaussianized
value z = Phi^{-1}(F_KDE(x)).
The inverse transform uses Brent's root-finding algorithm to numerically
invert F_KDE(x) = Phi(z) on the interval [-100, 100].
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import KDEGaussianizer rng = np.random.default_rng(0) X = rng.standard_normal((100, 2)) kde = KDEGaussianizer().fit(X) Z = kde.transform(X) Z.shape (100, 2) ldj = kde.get_log_det_jacobian(X) ldj.shape (100,)
Source code in rbig/_src/marginal.py
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | |
fit(X, y=None)
¶
Fit a Gaussian KDE to each feature dimension.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : KDEGaussianizer Fitted bijector instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Map each feature to N(0, 1) via KDE CDF then probit.
Computes z = Phi^{-1}(F_KDE(x)) for each feature independently.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Gaussianized data with approximately standard-normal marginals.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Map standard-normal values back to the original space.
Numerically inverts F_KDE(x) = Phi(z) using Brent's method
on the interval [-100, 100] per sample and feature.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized (standard-normal) space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space. Samples for which root-finding fails default to 0.0.
Source code in rbig/_src/marginal.py
get_log_det_jacobian(X)
¶
Compute log |det J| using the analytic KDE density.
Because the Jacobian is diagonal (each feature transformed independently)::
log|det J| = sum_i log|dz_i/dx_i|
= sum_i [log f_KDE(x_i) - log phi(z_i)]
where phi is the standard-normal PDF evaluated at
z_i = Phi^{-1}(F_KDE(x_i)).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
log_det : np.ndarray of shape (n_samples,) Per-sample log absolute determinant.
Source code in rbig/_src/marginal.py
rbig.GMMGaussianizer
¶
Bases: Bijector
Gaussianize each marginal using a Gaussian Mixture Model (GMM) CDF.
Fits a univariate GMM with n_components Gaussian components to each
feature dimension, then maps samples to standard-normal values via the
analytic GMM CDF::
F_GMM(x) = sum_k w_k * Phi((x - mu_k) / sigma_k)
followed by the probit function::
z = Phi ^ {-1}(F_GMM(x))
where Phi is the standard-normal CDF, w_k are mixture weights,
and mu_k, sigma_k are the component means and standard deviations.
Parameters¶
n_components : int, default 5
Number of mixture components. Capped at
max(1, min(n_components, n_samples // 5, n_samples)) during
fit to avoid over-fitting on small data sets.
random_state : int or None, default 0
Seed for reproducible GMM initialisation.
Attributes¶
gmms_ : list of sklearn.mixture.GaussianMixture
One fitted 1-D GMM per feature dimension.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The log-det-Jacobian uses the analytic GMM density::
log|dz/dx| = log f_GMM(x) - log phi(z)
where f_GMM(x) = sum_k w_k * phi((x - mu_k) / sigma_k) / sigma_k
is the GMM PDF and phi is the standard-normal PDF.
The inverse transform numerically inverts the GMM CDF via Brent's method on [-50, 50]; samples outside this range default to 0.0.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import GMMGaussianizer rng = np.random.default_rng(0) X = rng.standard_normal((200, 2)) gmm = GMMGaussianizer(n_components=3).fit(X) Z = gmm.transform(X) Z.shape (200, 2) ldj = gmm.get_log_det_jacobian(X) ldj.shape (200,)
Source code in rbig/_src/marginal.py
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 | |
fit(X, y=None)
¶
Fit a univariate GMM to each feature dimension.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : GMMGaussianizer Fitted bijector instance.
Notes¶
The number of mixture components is capped at
max(1, min(n_components, n_samples // 5, n_samples)) to avoid
over-fitting when n_samples is small.
Source code in rbig/_src/marginal.py
transform(X)
¶
Map each feature to N(0, 1) via GMM CDF then probit.
Applies z = Phi^{-1}(F_GMM(x)) to each feature independently.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Gaussianized data with approximately standard-normal marginals.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Map standard-normal values back to the original space.
Numerically inverts F_GMM(x) = Phi(z) per sample via Brent's
method on the interval [-50, 50].
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized (standard-normal) space.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space. Samples for which root-finding fails default to 0.0.
Source code in rbig/_src/marginal.py
get_log_det_jacobian(X)
¶
Compute log |det J| using the analytic GMM density.
Because the Jacobian is diagonal (each feature transformed independently)::
log|det J| = sum_i log|dz_i/dx_i|
= sum_i [log f_GMM(x_i) - log phi(z_i)]
where z_i = Phi^{-1}(F_GMM(x_i)) and phi is the
standard-normal PDF.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
log_det : np.ndarray of shape (n_samples,) Per-sample log absolute determinant.
Source code in rbig/_src/marginal.py
rbig.QuantileGaussianizer
¶
Bases: Bijector
Gaussianize each marginal using sklearn's QuantileTransformer.
Wraps :class:sklearn.preprocessing.QuantileTransformer configured with
output_distribution='normal' to map each feature to an approximately
standard-normal distribution. The quantile transform is a step-function
CDF estimate that is particularly robust to outliers.
Parameters¶
n_quantiles : int, default 1000
Number of quantile nodes used to define the piecewise-linear mapping.
Capped at n_samples during fit to avoid requesting more
quantiles than there are training points.
random_state : int or None, default 0
Seed for reproducible subsampling inside QuantileTransformer.
Attributes¶
qt_ : sklearn.preprocessing.QuantileTransformer
Fitted quantile transformer with output_distribution='normal'.
n_features_ : int
Number of feature dimensions seen during fit.
Notes¶
The log-absolute-Jacobian is estimated via central finite differences::
dz_i/dx_i ~= (z_i(x + eps*e_i) - z_i(x - eps*e_i)) / (2*eps)
with eps = 1e-5. This approximation may be inaccurate near
discontinuities of the piecewise quantile function.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.marginal import QuantileGaussianizer rng = np.random.default_rng(0) X = rng.standard_normal((200, 3)) qg = QuantileGaussianizer().fit(X) Z = qg.transform(X) Z.shape (200, 3) Xr = qg.inverse_transform(Z) Xr.shape (200, 3)
Source code in rbig/_src/marginal.py
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 | |
fit(X, y=None)
¶
Fit the quantile transformer to the training data.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : QuantileGaussianizer Fitted bijector instance.
Source code in rbig/_src/marginal.py
transform(X)
¶
Apply the quantile transform: x -> z approximately N(0, 1).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Gaussianized data.
Source code in rbig/_src/marginal.py
inverse_transform(X)
¶
Invert the quantile transform: z -> x.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the Gaussianized (standard-normal) space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space.
Source code in rbig/_src/marginal.py
get_log_det_jacobian(X)
¶
Estimate log |det J| by finite differences on the quantile transform.
Uses a small perturbation eps = 1e-5 in each dimension::
dz_i/dx_i ~= (z_i(x + eps*e_i) - z_i(x - eps*e_i)) / (2*eps)
and sums the log-absolute-derivatives::
log|det J| = sum_i log|dz_i/dx_i|
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
log_det : np.ndarray of shape (n_samples,) Per-sample log absolute determinant approximation.
Notes¶
The quantile transform is piecewise-linear; the finite-difference derivative equals the local slope and is exact within each segment.
Source code in rbig/_src/marginal.py
Rotations¶
rbig.PCARotation
¶
Bases: BaseTransform
PCA-based rotation with optional whitening (decorrelation + rescaling).
Fits a standard PCA (via scikit-learn's :class:~sklearn.decomposition.PCA)
and uses it as a linear rotation transform. When whiten=True (default),
each principal component is additionally rescaled by the reciprocal square
root of its eigenvalue so the output has unit variance per component::
z = Lambda^{-1/2} V^T (x - mu)
where V in R^{D x K} is the matrix of leading eigenvectors (principal
axes), Lambda in R^{K x K} is the diagonal eigenvalue matrix, and
mu is the sample mean. When whiten=False, the rescaling is
omitted and the transform is a pure rotation::
z = V ^ T(x - mu)
Parameters¶
n_components : int or None, default None
Number of principal components to retain. If None, all D
components are kept.
whiten : bool, default True
If True, divide each component by sqrt(lambda_i) to decorrelate
and normalise variance. If False, only rotate (and center).
Attributes¶
pca_ : sklearn.decomposition.PCA Fitted PCA object containing eigenvectors, eigenvalues, and the sample mean.
Notes¶
The log-absolute-Jacobian determinant for the whitening transform is::
log|det J| = -1/2 * sum_i log(lambda_i)
because each whitening factor Lambda^{-1/2} contributes
-1/2 * log(lambda_i) per component. For a pure rotation
(whiten=False), the determinant is 1 and the log is 0.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import PCARotation rng = np.random.default_rng(0) X = rng.standard_normal((200, 4)) pca_rot = PCARotation(whiten=True).fit(X) Z = pca_rot.transform(X) Z.shape (200, 4) ldj = pca_rot.log_det_jacobian(X) ldj.shape (200,)
Source code in rbig/_src/rotation.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
fit(X, y=None)
¶
Fit PCA to the training data.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : PCARotation Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
Apply PCA rotation (and optional whitening) to X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_components) Rotated (and optionally whitened) data.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the PCA rotation (and optional whitening).
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Data in the PCA / whitened space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original input space.
Source code in rbig/_src/rotation.py
log_det_jacobian(X)
¶
Log absolute Jacobian determinant (constant for linear transforms).
For a whitening PCA the Jacobian determinant is constant::
log|det J| = -1/2 * sum_i log(lambda_i)
where lambda_i are the PCA eigenvalues (explained_variance_).
For a plain rotation (whiten=False), |det J| = 1 and the
log is 0.
.. note::
This method is only valid when the transform is square (i.e.
n_components is None or equals the number of input
features). A dimensionality-reducing PCA (n_components <
n_features) is not bijective and its Jacobian determinant is
undefined.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine the number of samples).
Returns¶
ldj : np.ndarray of shape (n_samples,) Constant per-sample log absolute Jacobian determinant.
Source code in rbig/_src/rotation.py
rbig.ICARotation
¶
Bases: BaseTransform
ICA-based rotation using the Picard algorithm or FastICA fallback.
Fits an Independent Component Analysis (ICA) model that learns a linear
unmixing matrix. When the optional picard package is available, it
is used for faster and more accurate convergence::
s = W K x
where K in R^{K x D} is a pre-whitening matrix and W in
R^{K x K} is the ICA unmixing matrix. The combined transform is
W K.
If picard is not installed, :class:sklearn.decomposition.FastICA
is used as a drop-in replacement.
Parameters¶
n_components : int or None, default None
Number of independent components. If None, all D components
are estimated (square unmixing matrix).
random_state : int or None, default None
Seed for reproducible ICA initialisation.
Attributes¶
K_ : np.ndarray of shape (n_components, n_features) or None
Pre-whitening matrix from the Picard solver. None when using
the FastICA fallback.
W_ : np.ndarray of shape (n_components, n_components) or None
ICA unmixing matrix from the Picard solver. None when using
FastICA.
ica_ : sklearn.decomposition.FastICA or None
Fitted FastICA object used when Picard is unavailable.
n_features_in_ : int
Number of input features (set only when using Picard).
Notes¶
The log-absolute-Jacobian determinant is::
log|det J| = log|det(W K)|
for the Picard path, or log|det(components_)| for FastICA. The
Jacobian is constant (independent of x) for any linear transform.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import ICARotation rng = np.random.default_rng(0) X = rng.standard_normal((200, 3)) ica = ICARotation(random_state=0).fit(X) S = ica.transform(X) S.shape (200, 3)
Source code in rbig/_src/rotation.py
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | |
fit(X, y=None)
¶
Fit the ICA model (Picard if available, otherwise FastICA).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : ICARotation Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
Apply the ICA unmixing to X.
When orthogonal=True (default), applies only the orthogonal
rotation W_ (skips whitening K_), giving s = W x. When
orthogonal=False, applies the full unmixing s = W K x.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original (mixed) space.
Returns¶
S : np.ndarray of shape (n_samples, n_components) Estimated independent components.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the ICA unmixing.
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Independent-component representation.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original mixed space.
Source code in rbig/_src/rotation.py
log_det_jacobian(X)
¶
Log absolute Jacobian determinant (constant for linear transforms).
Computes log|det(W K)| (Picard path) or
log|det(components_)| (FastICA path). The result is replicated
for every sample since the Jacobian of a linear transform is constant.
.. note::
This method is only valid when the unmixing matrix is square (i.e.
n_components is None or equals the number of input
features). A non-square unmixing matrix is not bijective and its
Jacobian determinant is undefined. A :exc:ValueError is raised
in that case.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine the number of samples).
Returns¶
ldj : np.ndarray of shape (n_samples,) Constant per-sample log absolute Jacobian determinant.
Raises¶
ValueError
If the unmixing matrix is not square (n_components != n_features).
Source code in rbig/_src/rotation.py
rbig.RandomRotation
¶
Bases: RotationBijector
Random orthogonal rotation drawn from the Haar measure via QR.
Generates a uniformly random orthogonal matrix Q in R^{D x D} by QR decomposing a matrix of i.i.d. standard-normal entries and applying a sign correction to ensure the result is Haar-uniform::
A ~ N(0, 1)^{D x D}, A = Q R, Q <- Q * diag(sign(diag(R)))
The sign correction guarantees that Q is sampled uniformly from the orthogonal group O(D) (the Haar measure).
Parameters¶
random_state : int or None, default None Seed for reproducible rotation matrix generation.
Attributes¶
rotation_matrix_ : np.ndarray of shape (n_features, n_features) The sampled orthogonal rotation matrix Q.
Notes¶
Because Q is orthogonal, |det Q| = 1 and::
log|det J| = log|det Q| = 0
This is the default implementation inherited from
:class:~rbig._src.base.RotationBijector.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import RandomRotation rng_data = np.random.default_rng(0) X = rng_data.standard_normal((100, 4)) rot = RandomRotation(random_state=42).fit(X) Z = rot.transform(X) Z.shape (100, 4) Xr = rot.inverse_transform(Z) np.allclose(X, Xr) True
Source code in rbig/_src/rotation.py
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | |
fit(X, y=None)
¶
Sample a Haar-uniform orthogonal rotation matrix of size D x D.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data (used only to infer the dimensionality D).
Returns¶
self : RandomRotation
Fitted transform instance with rotation_matrix_ set.
Source code in rbig/_src/rotation.py
transform(X)
¶
Rotate X by the sampled orthogonal matrix: z = Q x.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Rotated data.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the rotation: x = Q^T z = Q^{-1} z.
Because Q is orthogonal, its inverse equals its transpose.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Rotated data.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original space.
Source code in rbig/_src/rotation.py
rbig.PicardRotation
¶
Bases: RotationBijector
ICA rotation via the Picard algorithm with a FastICA fallback.
Fits an ICA model that learns maximally statistically-independent
sources. When the optional picard package is available, it solves::
K, W = picard(X^T)
s = W K x
where K in R^{K x D} is the pre-whitening matrix and W in
R^{K x K} is the Picard unmixing matrix. The log-det-Jacobian is::
log|det J| = log|det(W K)|
If picard is not installed (or incompatible), :class:sklearn
.decomposition.FastICA is used as a fallback.
Parameters¶
n_components : int or None, default None
Number of independent components K. If None, K = D.
extended : bool, default False
If True, use the extended Picard algorithm that can handle both
super- and sub-Gaussian sources (passed directly to picard).
random_state : int or None, default None
Seed for reproducible initialisation.
max_iter : int, default 500
Maximum number of ICA iterations.
tol : float, default 1e-5
Convergence tolerance for the ICA algorithm.
Attributes¶
K_ : np.ndarray of shape (n_components, n_features) or None
Pre-whitening matrix (Picard path). None when using FastICA.
W_ : np.ndarray of shape (n_components, n_components) or None
Unmixing matrix (Picard path). None when using FastICA.
use_picard_ : bool
True if the Picard solver was used; False if FastICA was used.
ica_ : sklearn.decomposition.FastICA or None
Fitted FastICA model (FastICA path only).
Notes¶
The log-det-Jacobian is::
log|det J| = log|det(W K)|
for the Picard path, or log|det(components_)| for the FastICA path.
The Jacobian is constant because the transform is linear.
:meth:get_log_det_jacobian raises :class:ValueError if the unmixing
matrix is not square (i.e. n_components != n_features).
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Ablin, P., Cardoso, J.-F., & Gramfort, A. (2018). Faster Independent Component Analysis by Preconditioning with Hessian Approximations. IEEE Transactions on Signal Processing, 66(15), 4040-4049.
Examples¶
import numpy as np from rbig._src.rotation import PicardRotation rng = np.random.default_rng(0) X = rng.standard_normal((200, 3)) pic = PicardRotation(random_state=0).fit(X) S = pic.transform(X) S.shape (200, 3)
Source code in rbig/_src/rotation.py
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 | |
fit(X, y=None)
¶
Fit ICA (Picard if available, otherwise FastICA).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : PicardRotation Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
Apply the ICA unmixing.
When orthogonal=True (default), applies only the orthogonal
rotation W_ (skips whitening K_). When orthogonal=False,
applies the full unmixing s = W K x.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original (mixed) space.
Returns¶
S : np.ndarray of shape (n_samples, n_components) Estimated independent components.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the ICA unmixing.
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Independent-component representation.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data approximately recovered in the original mixed space.
Source code in rbig/_src/rotation.py
get_log_det_jacobian(X)
¶
Log absolute Jacobian determinant (constant for linear transforms).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine n_samples).
Returns¶
ldj : np.ndarray of shape (n_samples,) Constant per-sample log absolute Jacobian determinant.
Raises¶
ValueError
If the unmixing matrix is not square
(n_components != n_features).
Source code in rbig/_src/rotation.py
rbig.RandomOrthogonalProjection
¶
Bases: RotationBijector
Semi-orthogonal random projection from D to K dimensions via QR.
Generates a semi-orthogonal matrix P in R^{D x K} (K <= D) whose columns are orthonormal, obtained by taking the first K columns of a QR decomposition of a random Gaussian matrix::
A ~ N(0, 1)^{D x K}, A = Q R, P = Q[:, :K]
The forward transform projects D-dimensional input to K dimensions::
z = X P where P in R^{D x K}
Parameters¶
n_components : int or None, default None
Output dimensionality K. If None, K = D (square case).
random_state : int or None, default None
Seed for reproducible matrix generation.
Attributes¶
projection_matrix_ : np.ndarray of shape (n_features, n_components) Semi-orthogonal projection matrix P with orthonormal columns. input_dim_ : int Input dimensionality D. output_dim_ : int Output dimensionality K.
Notes¶
When K = D the matrix is fully orthogonal and log|det J| = 0.
When K < D the transform is not invertible and both
:meth:inverse_transform and :meth:get_log_det_jacobian raise
:class:NotImplementedError.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import RandomOrthogonalProjection rng = np.random.default_rng(0) X = rng.standard_normal((100, 4)) proj = RandomOrthogonalProjection(random_state=0).fit(X) Z = proj.transform(X) Z.shape (100, 4)
Source code in rbig/_src/rotation.py
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | |
fit(X, y=None)
¶
Build the semi-orthogonal projection matrix P.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data (used only to infer D = n_features).
Returns¶
self : RandomOrthogonalProjection Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
Project X from D to K dimensions: z = X P.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_components) Projected data.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the projection (only valid for square case K = D).
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Projected data.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original space (exact only when K = D).
Raises¶
NotImplementedError
If n_components < n_features (projection is not invertible).
Source code in rbig/_src/rotation.py
get_log_det_jacobian(X)
¶
Return zeros for the square (bijective) case.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine n_samples).
Returns¶
ldj : np.ndarray of shape (n_samples,)
Zeros, because |det P| = 1 for a square orthogonal matrix.
Raises¶
NotImplementedError
If n_components < n_features (Jacobian determinant undefined).
Source code in rbig/_src/rotation.py
rbig.GaussianRandomProjection
¶
Bases: RotationBijector
Johnson-Lindenstrauss style random projection with Gaussian entries.
Constructs a random projection matrix M in R^{D x K} whose entries are drawn i.i.d. from N(0, 1/K)::
M_ij ~ N(0, 1/K)
The 1/K normalisation approximately preserves pairwise Euclidean distances (Johnson-Lindenstrauss lemma)::
(1 - eps)||x - y||^2 <= ||Mx - My||^2 <= (1 + eps)||x - y||^2
with high probability when K = O(eps^{-2} log n).
Parameters¶
n_components : int or None, default None
Output dimensionality K. If None, K = D (square case).
random_state : int or None, default None
Seed for reproducible matrix generation.
Attributes¶
matrix_ : np.ndarray of shape (n_features, n_components) The random projection matrix with entries ~ N(0, 1/K).
Notes¶
Unlike :class:RandomOrthogonalProjection, the columns of this matrix
are not orthogonal, so |det M| != 1 in general.
:meth:get_log_det_jacobian returns zeros as an approximation.
For density estimation where accuracy matters, prefer
:class:RandomOrthogonalProjection or :class:RandomRotation.
The inverse uses the Moore-Penrose pseudoinverse computed by
:func:numpy.linalg.pinv.
References¶
Johnson, W. B., & Lindenstrauss, J. (1984). Extensions of Lipschitz mappings into a Hilbert space. Contemporary Mathematics, 26, 189-206.
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import GaussianRandomProjection rng = np.random.default_rng(0) X = rng.standard_normal((100, 4)) grp = GaussianRandomProjection(random_state=0).fit(X) Z = grp.transform(X) Z.shape (100, 4)
Source code in rbig/_src/rotation.py
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | |
fit(X, y=None)
¶
Build the Gaussian random projection matrix.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data (used only to infer D = n_features).
Returns¶
self : GaussianRandomProjection Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
inverse_transform(X)
¶
Approximate inverse via the Moore-Penrose pseudoinverse.
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Projected data.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Approximately recovered original data.
Source code in rbig/_src/rotation.py
get_log_det_jacobian(X)
¶
Return zeros (approximation; Gaussian projections are not isometric).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine n_samples).
Returns¶
ldj : np.ndarray of shape (n_samples,) Zeros (approximate; the true log-det is generally non-zero).
Source code in rbig/_src/rotation.py
rbig.OrthogonalDimensionalityReduction
¶
Bases: RotationBijector
Full orthogonal rotation followed by optional dimension truncation.
Applies a D x D orthogonal rotation Q (drawn from the Haar measure via QR) and then retains only the first K <= D components::
z = (X Q^T)[:, :K]
The rotation is sampled fresh at fit time from a square
standard-normal matrix processed through QR with sign correction.
Parameters¶
n_components : int or None, default None
Number of output dimensions K. If None, K = D (no truncation).
random_state : int or None, default None
Seed for reproducible rotation matrix generation.
Attributes¶
rotation_matrix_ : np.ndarray of shape (n_features, n_features) Full D x D orthogonal rotation matrix Q. n_components_ : int Number of retained output dimensions K. input_dim_ : int Input dimensionality D.
Notes¶
When K = D the transform is a bijection and::
log|det J| = log|det Q| = 0
When K < D the transform is not invertible; both
:meth:inverse_transform and :meth:get_log_det_jacobian raise
:class:NotImplementedError.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: from ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537-549.
Examples¶
import numpy as np from rbig._src.rotation import OrthogonalDimensionalityReduction rng = np.random.default_rng(0) X = rng.standard_normal((100, 4)) odr = OrthogonalDimensionalityReduction(random_state=0).fit(X) Z = odr.transform(X) Z.shape (100, 4)
Source code in rbig/_src/rotation.py
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | |
fit(X, y=None)
¶
Sample a Haar-uniform D x D rotation matrix.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data (used only to infer D = n_features).
Returns¶
self : OrthogonalDimensionalityReduction Fitted transform instance.
Source code in rbig/_src/rotation.py
transform(X)
¶
Rotate then truncate: z = (X Q^T)[:, :K].
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_components) Rotated and (optionally) truncated data.
Source code in rbig/_src/rotation.py
inverse_transform(X)
¶
Invert the rotation (only valid for square case K = D).
Parameters¶
X : np.ndarray of shape (n_samples, n_components) Rotated data.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original space.
Raises¶
NotImplementedError
If n_components < n_features (not invertible).
Source code in rbig/_src/rotation.py
get_log_det_jacobian(X)
¶
Return zeros for the square (bijective) case.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine n_samples).
Returns¶
ldj : np.ndarray of shape (n_samples,)
Zeros, because |det Q| = 1 for any orthogonal Q.
Raises¶
NotImplementedError
If n_components < n_features (Jacobian determinant undefined).
Source code in rbig/_src/rotation.py
Parametric Transforms¶
rbig.BoxCoxTransform
¶
Bases: BaseTransform
Box-Cox power transform fitted independently to each feature.
The Box-Cox family of transforms is parameterised by λ (one per feature):
λ ≠ 0 : y = (xᵏ − 1) / λ
λ → 0 : y = log(x) (continuity limit)
λ values are estimated via maximum likelihood (scipy's boxcox).
Features with non-positive values are left unchanged (λ = 0 applied as
identity rather than log, since log requires positive inputs).
The inverse transform is:
λ ≠ 0 : x = (λy + 1)^{1/λ}
λ = 0 : x = exp(y)
The log-det of the Jacobian is:
λ ≠ 0 : ∑ᵢ (λ − 1) log xᵢ
λ = 0 : ∑ᵢ (−log xᵢ) (from d(log x)/dx = 1/x ⟹ log|dy/dx| = −log xᵢ)
.. note::
The current implementation uses −xᵢ (not −log xᵢ) for the
λ = 0 branch, matching the original code behaviour. This is an
approximation that differs from the exact analytical log-det.
Parameters¶
method : str, optional (default='mle') Fitting method passed conceptually; currently scipy MLE is always used regardless of this value.
Attributes¶
lambdas_ : np.ndarray of shape (n_features,)
Fitted λ values after calling fit.
Examples¶
import numpy as np from rbig._src.parametric import BoxCoxTransform rng = np.random.default_rng(1) X = rng.exponential(scale=2.0, size=(200, 3)) # strictly positive tr = BoxCoxTransform().fit(X) Y = tr.transform(X) X_rec = tr.inverse_transform(Y) np.allclose(X, X_rec, atol=1e-6) True
Source code in rbig/_src/parametric.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | |
fit(X, y=None)
¶
Estimate one Box-Cox λ per feature via MLE.
Parameters¶
X : np.ndarray of shape (n_samples, n_features)
Training data. Features that contain non-positive values are
assigned λ = 0 (no transform applied during transform).
Returns¶
self : BoxCoxTransform
Fitted instance with lambdas_ attribute set.
Source code in rbig/_src/parametric.py
transform(X)
¶
Apply the fitted Box-Cox transform to X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data. Features with λ = 0 and non-positive values are passed through unchanged.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Box-Cox transformed data.
Source code in rbig/_src/parametric.py
inverse_transform(X)
¶
Invert the Box-Cox transform.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Box-Cox transformed data.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Recovered original-scale data. Uses:
* λ = 0 : x = exp(y)
* λ ≠ 0 : x = (λy + 1)^{1/λ} (clamped to 0 for stability)
Source code in rbig/_src/parametric.py
log_det_jacobian(X)
¶
Compute per-sample log |det J| of the forward Box-Cox transform.
The Jacobian is diagonal; for each feature:
λ ≠ 0 : d/dx[(xᵏ−1)/λ] = x^{λ−1} ⟹ log = (λ−1) log x
λ = 0 : d/dx[log x] = 1/x ⟹ exact log = −log x
.. note::
The λ = 0 branch accumulates −xᵢ rather than the exact
−log xᵢ. This preserves the original implementation
behaviour.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data (pre-transform, original scale).
Returns¶
log_det : np.ndarray of shape (n_samples,) Sum of per-feature log Jacobian contributions.
Source code in rbig/_src/parametric.py
rbig.LogitTransform
¶
Bases: BaseTransform
Logit transform: bijectively maps the unit hypercube (0,1)ᵈ to ℝᵈ.
Each feature is transformed independently by the logit (log-odds) function:
Forward : y = log(x / (1 − x))
Inverse : x = σ(y) = 1 / (1 + e^{−y}) (sigmoid)
Log-det : ∑ᵢ [−log xᵢ − log(1 − xᵢ)]
The transform is useful as a pre-processing step when data lives in (0, 1), e.g. probabilities or proportions.
Examples¶
import numpy as np from rbig._src.parametric import LogitTransform rng = np.random.default_rng(0) X = rng.uniform(0.05, 0.95, size=(100, 3)) # data in (0, 1) tr = LogitTransform().fit(X) Y = tr.transform(X) # data now in ℝ X_rec = tr.inverse_transform(Y) np.allclose(X, X_rec, atol=1e-10) True
Source code in rbig/_src/parametric.py
fit(X, y=None)
¶
transform(X)
¶
Apply the logit map y = log(x / (1 − x)).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in (0, 1).
Returns¶
Y : np.ndarray of shape (n_samples, n_features) Log-odds transformed data in ℝ.
Source code in rbig/_src/parametric.py
inverse_transform(X)
¶
Apply the inverse sigmoid (logistic) map x = 1 / (1 + e^{−y}).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in ℝ.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Recovered data in (0, 1).
Source code in rbig/_src/parametric.py
log_det_jacobian(X)
¶
Compute per-sample log |det J| of the forward logit transform.
The Jacobian of logit is diagonal with entries d(logit xᵢ)/dxᵢ = 1/xᵢ + 1/(1−xᵢ), so:
log |det J| = ∑ᵢ [−log xᵢ − log(1 − xᵢ)]
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in (0, 1) (pre-transform).
Returns¶
log_det : np.ndarray of shape (n_samples,) Log absolute determinant of the Jacobian for each sample.
Source code in rbig/_src/parametric.py
rbig.QuantileTransform
¶
Bases: BaseTransform
Quantile transform that maps each feature to a target distribution.
Wraps sklearn.preprocessing.QuantileTransformer to provide a uniform
interface compatible with RBIG pipelines. By default, features are
mapped to a standard Gaussian distribution, which is a common
pre-processing step for Gaussianisation.
Parameters¶
n_quantiles : int, optional (default=1000)
Number of quantiles used to build the empirical CDF. Capped at
n_samples during fit.
output_distribution : str, optional (default='normal')
Target distribution for the transform. Accepted values are
'normal' (standard Gaussian) and 'uniform'.
Attributes¶
qt_ : sklearn.preprocessing.QuantileTransformer
Fitted sklearn transformer, available after calling fit.
Examples¶
import numpy as np from rbig._src.parametric import QuantileTransform rng = np.random.default_rng(42) X = rng.exponential(scale=1.0, size=(500, 2)) tr = QuantileTransform(n_quantiles=200).fit(X) Y = tr.transform(X) # approximately standard Gaussian Y.shape (500, 2)
Marginal means should be near zero, stds near 1¶
np.allclose(Y.mean(axis=0), 0, atol=0.1) True
Source code in rbig/_src/parametric.py
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
fit(X, y=None)
¶
Fit the quantile transform to the training data.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data.
Returns¶
self : QuantileTransform
Fitted instance with qt_ attribute set.
Source code in rbig/_src/parametric.py
transform(X)
¶
Apply the fitted quantile transform.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Y : np.ndarray of shape (n_samples, n_features) Data mapped to the target distribution.
Source code in rbig/_src/parametric.py
inverse_transform(X)
¶
Invert the quantile transform.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the target distribution space.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Recovered data in the original distribution space.
Source code in rbig/_src/parametric.py
Base Classes¶
rbig.BaseTransform
¶
Bases: TransformerMixin, BaseEstimator, ABC
Abstract base class for all RBIG transforms.
Defines the common interface shared by every learnable data transformation
in this library: fitting to data, forward mapping, and its inverse.
Subclasses that support density estimation should also implement
log_det_jacobian.
Notes¶
The change-of-variables formula for a normalizing flow relates the density
of the input x to a base density p_Z via a bijection f:
log p(x) = log p_Z(f(x)) + log|det J_f(x)|
where J_f(x) is the Jacobian of f evaluated at x.
Source code in rbig/_src/base.py
fit(X, y=None)
abstractmethod
¶
Fit the transform to data X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data used to estimate any internal parameters. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
self : BaseTransform The fitted transform instance.
Source code in rbig/_src/base.py
transform(X)
abstractmethod
¶
Apply the fitted forward transform to data X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data to transform.
Returns¶
Xt : np.ndarray of shape (n_samples, n_features) Transformed data.
Source code in rbig/_src/base.py
inverse_transform(X)
abstractmethod
¶
Apply the fitted inverse transform to data X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the transformed (latent) space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original input space.
Source code in rbig/_src/base.py
log_det_jacobian(X)
¶
Log absolute determinant of the Jacobian evaluated at X.
For a transform f, this returns log|det J_f(x)| per sample,
which is the volume-correction term required in the change-of-variables
formula for density estimation.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
ldj : np.ndarray of shape (n_samples,) Per-sample log absolute determinant of the Jacobian.
Raises¶
NotImplementedError If the subclass does not implement this method.
Source code in rbig/_src/base.py
rbig.Bijector
¶
Bases: TransformerMixin, BaseEstimator, ABC
Abstract base class for invertible transformations (bijectors).
A bijector implements a differentiable, invertible map f : ℝᵈ → ℝᵈ
and provides the log absolute determinant of its Jacobian. These are
the building blocks of normalizing flows.
The density of a random variable X = f⁻¹(Z) where Z ~ p_Z is:
log p(x) = log p_Z(f(x)) + log|det J_f(x)|
Notes¶
Concrete subclasses must implement :meth:fit, :meth:transform,
:meth:inverse_transform, and :meth:get_log_det_jacobian.
log_det_jacobian is provided as a convenience alias for the last
method, for compatibility with RBIGLayer.
References¶
Laparra, V., Camps-Valls, G., & Malo, J. (2011). Iterative Gaussianization: From ICA to Random Rotations. IEEE Transactions on Neural Networks, 22(4), 537–549. https://doi.org/10.1109/TNN.2011.2106511
Source code in rbig/_src/base.py
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
fit(X, y=None)
abstractmethod
¶
Fit the bijector to data X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
self : Bijector The fitted bijector.
Source code in rbig/_src/base.py
transform(X)
abstractmethod
¶
Apply the forward bijection f(x).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data in the original space.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Data mapped to the latent space.
Source code in rbig/_src/base.py
inverse_transform(X)
abstractmethod
¶
Apply the inverse bijection f⁻¹(z).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the latent space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original space.
Source code in rbig/_src/base.py
get_log_det_jacobian(X)
abstractmethod
¶
Compute log|det J_f(x)| per sample.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points at which to evaluate the log-det-Jacobian.
Returns¶
ldj : np.ndarray of shape (n_samples,) Per-sample log absolute determinant of the forward Jacobian J_f.
Source code in rbig/_src/base.py
log_det_jacobian(X)
¶
Alias for get_log_det_jacobian for compatibility with RBIGLayer.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points.
Returns¶
ldj : np.ndarray of shape (n_samples,) Per-sample log|det J_f(x)|.
Source code in rbig/_src/base.py
rbig.MarginalBijector
¶
Bases: Bijector
Abstract bijector for independent, per-dimension (marginal) transforms.
Each feature dimension is transformed by a separate invertible function. Because the transform is applied independently to each coordinate, the Jacobian is diagonal and its log-determinant is the sum of per-dimension log-derivatives:
log|det J_f(x)| = ∑ᵢ log|f′(xᵢ)|
Subclasses implement concrete marginal mappings such as empirical CDF Gaussianization, quantile transform, or kernel density estimation.
Notes¶
In RBIG, the marginal step maps each dimension to a standard Gaussian via
z = Φ⁻¹(F̂ₙ(x))
where F̂ₙ is the estimated marginal CDF and Φ⁻¹ is the standard normal quantile function (probit).
Source code in rbig/_src/base.py
rbig.RotationBijector
¶
Bases: Bijector
Abstract bijector for orthogonal rotation transforms.
Rotation matrices Q satisfy QᵀQ = I and |det Q| = 1, so the log-absolute-determinant of the Jacobian is exactly zero:
log|det J_Q(x)| = log|det Q| = log 1 = 0
This default implementation of get_log_det_jacobian returns a
zero vector of length n_samples, which concrete subclasses (e.g.
PCA, ICA, random orthogonal) can inherit without override.
Notes¶
In RBIG, the rotation step de-correlates the marginally Gaussianized data, driving the joint distribution closer to a standard multivariate Gaussian with each iteration.
Source code in rbig/_src/base.py
get_log_det_jacobian(X)
¶
Return zeros because |det Q| = 1 for any orthogonal matrix Q.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points (used only to determine n_samples).
Returns¶
ldj : np.ndarray of shape (n_samples,) Array of zeros; rotations do not change volume.
Source code in rbig/_src/base.py
rbig.CompositeBijector
¶
Bases: Bijector
A bijector that chains a sequence of bijectors in order.
Applies bijectors f₁, f₂, …, fₖ in sequence so that the composite
map is g = fₖ ∘ … ∘ f₂ ∘ f₁. The log-det-Jacobian of the
composition follows the chain rule:
log|det J_g(x)| = ∑ₖ log|det J_fₖ(xₖ₋₁)|
where xₖ₋₁ = fₖ₋₁ ∘ … ∘ f₁(x) is the input to the k-th bijector.
Parameters¶
bijectors : list of Bijector
Ordered list of bijectors to chain. They are applied left-to-right
during transform and right-to-left during inverse_transform.
Attributes¶
bijectors : list of Bijector The constituent bijectors in application order.
Notes¶
Fitting is done sequentially: each bijector is fitted to the output of
the previous one, so that the full model is trained in a single
fit call.
Examples¶
import numpy as np from rbig._src.base import CompositeBijector from rbig._src.marginal import MarginalGaussianize from rbig._src.rotation import PCARotation rng = np.random.default_rng(0) X = rng.standard_normal((200, 4)) cb = CompositeBijector([MarginalGaussianize(), PCARotation()]) cb.fit(X) # doctest: +ELLIPSIS
Z = cb.transform(X) Z.shape (200, 4)
Source code in rbig/_src/base.py
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
fit(X, y=None)
¶
Fit each bijector sequentially on the output of the previous one.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Training data. y : ignored Not used, present for sklearn pipeline compatibility.
Returns¶
self : CompositeBijector The fitted composite bijector.
Source code in rbig/_src/base.py
transform(X)
¶
Apply all bijectors left-to-right: g(x) = fₖ(… f₁(x) …).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input data.
Returns¶
Z : np.ndarray of shape (n_samples, n_features) Data after passing through every bijector in sequence.
Source code in rbig/_src/base.py
inverse_transform(X)
¶
Invert the composite map: g⁻¹(z) = f₁⁻¹(… fₖ⁻¹(z) …).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data in the latent space.
Returns¶
Xr : np.ndarray of shape (n_samples, n_features) Data recovered in the original input space.
Source code in rbig/_src/base.py
get_log_det_jacobian(X)
¶
Sum log|det Jₖ| over all bijectors (chain rule).
Uses the chain rule for Jacobian determinants:
log|det J_g(x)| = ∑ₖ log|det J_fₖ(xₖ₋₁)|
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Input points.
Returns¶
log_det : np.ndarray of shape (n_samples,) Per-sample sum of log-det-Jacobians across all bijectors.
Source code in rbig/_src/base.py
Information Theory¶
rbig.total_correlation_rbig(X)
¶
Estimate Total Correlation (multivariate mutual information) of X.
Total Correlation is defined as:
TC(X) = ∑ᵢ H(Xᵢ) − H(X)
where the marginal entropies H(Xᵢ) are estimated via KDE (using
marginal_entropy) and the joint entropy H(X) is estimated by fitting
a multivariate Gaussian to the data (joint_entropy_gaussian).
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data matrix.
Returns¶
tc : float Estimated total correlation in nats. Values close to zero indicate approximate statistical independence among the dimensions.
Notes¶
See :func:rbig._src.densities.total_correlation for identical logic.
This function is kept in metrics for API convenience.
Examples¶
import numpy as np from rbig._src.metrics import total_correlation_rbig rng = np.random.default_rng(0) X = rng.standard_normal((300, 4)) # independent Gaussians tc = total_correlation_rbig(X) tc >= -0.5 # should be near 0 True
Source code in rbig/_src/metrics.py
rbig.mutual_information_rbig(model_X, model_Y, model_XY)
¶
Estimate mutual information between X and Y via RBIG models.
Uses the identity:
MI(X; Y) = H(X) + H(Y) − H(X, Y)
where each entropy is estimated from a separately fitted RBIG model.
Parameters¶
model_X : AnnealedRBIG RBIG model fitted on samples from the marginal distribution of X. model_Y : AnnealedRBIG RBIG model fitted on samples from the marginal distribution of Y. model_XY : AnnealedRBIG RBIG model fitted on joint samples [X, Y] (i.e. columns concatenated).
Returns¶
mi : float Estimated mutual information MI(X; Y) in nats. Non-negative for well-calibrated models; small negative values may appear due to numerical imprecision.
Notes¶
Each model.entropy() call returns the differential entropy estimated
from the RBIG-transformed representation.
Examples¶
Assumes pre-fitted models; see AnnealedRBIG for fitting details.¶
mi = mutual_information_rbig(model_X, model_Y, model_XY) mi >= 0 # MI is non-negative True
Source code in rbig/_src/metrics.py
rbig.kl_divergence_rbig(model_P, X_Q)
¶
Estimate a divergence between distributions P and Q via a fitted RBIG model.
As implemented, this function returns:
−𝔼_Q[log p(x)] − H(P)
where 𝔼_Q is the expectation over samples X_Q from Q, log p
is the log-density of model_P, and H(P) is the entropy of P
estimated from the training data. Expanding H(P) = −𝔼_P[log p(x)]:
result = 𝔼_P[log p(x)] − 𝔼_Q[log p(x)]
.. note::
This quantity is not the standard KL divergence
KL(P ‖ Q) = 𝔼_P[log p(x)/q(x)], because Q's log-density
log q is never evaluated. The result is a measure of how
differently P's log-density scores the P-samples versus the
Q-samples. It equals zero when P and Q assign identical average
log-probability under P's model.
Parameters¶
model_P : AnnealedRBIG
RBIG model fitted on samples from distribution P. Must expose
score_samples(X) and entropy().
X_Q : np.ndarray of shape (n_samples, n_features)
Samples drawn from distribution Q against which P is compared.
Returns¶
divergence : float
Estimated 𝔼_P[log p(x)] − 𝔼_Q[log p(x)] in nats.
Examples¶
When P == Q the divergence should be near zero.¶
kl = kl_divergence_rbig(model_P, X_from_P) kl >= -0.1 # small negative values possible due to approximation True
Source code in rbig/_src/metrics.py
rbig.entropy_rbig(model, X)
¶
Estimate differential entropy of X using a fitted RBIG model.
Approximates the entropy via the plug-in estimator:
H(X) = −𝔼[log p(x)] ≈ −(1/N) ∑ᵢ log p(xᵢ)
where log p(xᵢ) is provided by model.score_samples.
Parameters¶
model : AnnealedRBIG
RBIG model fitted on data from the same distribution as X. Must
expose a score_samples(X) method returning per-sample log
probabilities.
X : np.ndarray of shape (n_samples, n_features)
Evaluation data used to compute the empirical expectation.
Returns¶
entropy : float Estimated differential entropy in nats.
Examples¶
Assumes a pre-fitted AnnealedRBIG model.¶
h = entropy_rbig(fitted_model, X_test) h > 0 # entropy is typically positive for continuous distributions True
Source code in rbig/_src/metrics.py
rbig.entropy_marginal(X)
¶
Per-dimension marginal entropy using the Vasicek spacing estimator.
Applies :func:entropy_univariate independently to each column of X.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data matrix.
Returns¶
entropies : np.ndarray of shape (n_features,) Vasicek entropy estimate (nats) for each feature dimension.
Examples¶
import numpy as np from rbig._src.metrics import entropy_marginal rng = np.random.default_rng(9) X = rng.standard_normal((800, 3)) h = entropy_marginal(X) h.shape (3,)
Source code in rbig/_src/metrics.py
rbig.negentropy(X)
¶
Compute per-dimension negentropy J(Xᵢ) = H_Gauss(Xᵢ) − H(Xᵢ).
Negentropy measures non-Gaussianity for each marginal:
J(Xᵢ) = H_Gauss(Xᵢ) − H(Xᵢ) ≥ 0
where H_Gauss(Xᵢ) = ½(1 + log 2π) + ½ log Var(Xᵢ) is the Gaussian entropy matched to the observed variance and H(Xᵢ) is estimated via KDE.
Parameters¶
X : np.ndarray of shape (n_samples, n_features) Data matrix.
Returns¶
neg_entropy : np.ndarray of shape (n_features,) Non-negative negentropy for each dimension. A value of 0 indicates that the marginal is Gaussian; larger values indicate more non-Gaussianity.
Notes¶
Negentropy is guaranteed non-negative by the maximum-entropy principle: among all distributions with a given variance, the Gaussian has the highest entropy.
Examples¶
import numpy as np from rbig._src.metrics import negentropy rng = np.random.default_rng(3) X_gauss = rng.standard_normal((500, 2)) J_gauss = negentropy(X_gauss) np.all(J_gauss >= -0.05) # nearly zero for Gaussian data True
Source code in rbig/_src/metrics.py
rbig.negative_log_likelihood(model, X)
¶
Average negative log-likelihood of X under the RBIG model.
Computes:
NLL = −(1/N) ∑ᵢ log p(xᵢ)
This is equivalent to :func:entropy_rbig but is exposed separately to
make its role as a loss / evaluation metric explicit.
Parameters¶
model : AnnealedRBIG
Fitted RBIG model. Must expose score_samples(X).
X : np.ndarray of shape (n_samples, n_features)
Evaluation data.
Returns¶
nll : float Average negative log-likelihood in nats.
Examples¶
nll = negative_log_likelihood(fitted_model, X_test) nll > 0 # NLL is positive for well-calibrated models True
Source code in rbig/_src/metrics.py
Parametric Distributions¶
rbig.gaussian(n_samples=1000, loc=0.0, scale=1.0, random_state=None)
¶
Sample from a univariate Gaussian (normal) distribution.
Parameters¶
n_samples : int, optional (default=1000) Number of samples to draw. loc : float, optional (default=0.0) Mean μ of the distribution. scale : float, optional (default=1.0) Standard deviation σ > 0 of the distribution. random_state : int or None, optional (default=None) Seed for the random number generator. Pass an integer for reproducible results.
Returns¶
samples : np.ndarray of shape (n_samples,) Independent draws from 𝒩(loc, scale²).
Examples¶
from rbig._src.parametric import gaussian x = gaussian(n_samples=500, loc=2.0, scale=0.5, random_state=0) x.shape (500,) import numpy as np np.isclose(x.mean(), 2.0, atol=0.1) True
Source code in rbig/_src/parametric.py
rbig.multivariate_gaussian(n_samples=1000, mean=None, cov=None, d=2, random_state=None)
¶
Sample from a multivariate Gaussian distribution.
Parameters¶
n_samples : int, optional (default=1000)
Number of samples to draw.
mean : np.ndarray of shape (d,) or None, optional
Mean vector μ. Defaults to the zero vector of length d.
cov : np.ndarray of shape (d, d) or None, optional
Covariance matrix Σ. Must be symmetric positive semi-definite.
Defaults to the identity matrix Iₐ.
d : int, optional (default=2)
Dimensionality used when mean is None. Ignored when
mean is provided (its length determines the dimension).
random_state : int or None, optional (default=None)
Seed for the random number generator.
Returns¶
samples : np.ndarray of shape (n_samples, d) Independent draws from 𝒩(mean, cov).
Examples¶
import numpy as np from rbig._src.parametric import multivariate_gaussian cov = np.array([[1.0, 0.8], [0.8, 1.0]]) X = multivariate_gaussian(n_samples=200, cov=cov, d=2, random_state=7) X.shape (200, 2) np.isclose(np.corrcoef(X.T)[0, 1], 0.8, atol=0.1) True
Source code in rbig/_src/parametric.py
rbig.total_correlation_gaussian(cov)
¶
Analytic Total Correlation of a multivariate Gaussian.
For a Gaussian with covariance Σ, the TC reduces to a function of the correlation matrix R = D^{-½} Σ D^{-½} (where D = diag(Σ)):
TC = ∑ᵢ H(Xᵢ) − H(X) = −½ log|R|
Equivalently, it measures how far the distribution is from being a product of its marginals.
Parameters¶
cov : np.ndarray of shape (d, d) Covariance matrix Σ. Coerced to at least 2-D.
Returns¶
tc : float
Total correlation in nats. Returns +inf if Σ is singular.
Notes¶
The computation uses:
TC = (∑ᵢ ½ log(2πe σᵢ²)) − ½(d(1 + log 2π) + log|Σ|)
= ½ ∑ᵢ log σᵢ² − ½ log|Σ|
= −½ log|corr(Σ)|
Examples¶
import numpy as np from rbig._src.parametric import total_correlation_gaussian
Identity covariance → all marginals independent → TC = 0¶
tc = total_correlation_gaussian(np.eye(3)) np.isclose(tc, 0.0) True
Correlated covariance → TC > 0¶
cov = np.array([[1.0, 0.9], [0.9, 1.0]]) total_correlation_gaussian(cov) > 0 True
Source code in rbig/_src/parametric.py
rbig.mutual_information_gaussian(cov_X, cov_Y, cov_XY)
¶
Analytic mutual information between two jointly Gaussian variables.
Uses the entropy identity:
MI(X; Y) = H(X) + H(Y) − H(X, Y)
where each entropy is computed analytically from the corresponding
covariance matrix via :func:entropy_gaussian.
Parameters¶
cov_X : np.ndarray of shape (d_X, d_X) Marginal covariance of X. cov_Y : np.ndarray of shape (d_Y, d_Y) Marginal covariance of Y. cov_XY : np.ndarray of shape (d_X + d_Y, d_X + d_Y) Joint covariance matrix of the concatenated variable [X, Y].
Returns¶
mi : float Mutual information in nats. Non-negative for valid covariance matrices; small negative values indicate numerical imprecision.
Notes¶
For Gaussians the MI can also be expressed as:
MI(X; Y) = −½ log(|Σ_{XX}| · |Σ_{YY}| / |Σ_{XY}|)
Examples¶
import numpy as np from rbig._src.parametric import mutual_information_gaussian
Block-diagonal joint covariance → MI = 0¶
cov_X = np.eye(2) cov_Y = np.eye(2) cov_XY = np.block([[cov_X, np.zeros((2, 2))], [np.zeros((2, 2)), cov_Y]]) mi = mutual_information_gaussian(cov_X, cov_Y, cov_XY) np.isclose(mi, 0.0, atol=1e-10) True
Source code in rbig/_src/parametric.py
rbig.kl_divergence_gaussian(mu0, cov0, mu1, cov1)
¶
Analytic KL divergence KL(P₀ ‖ P₁) between two multivariate Gaussians.
Both distributions are assumed to be multivariate Gaussian:
P₀ = 𝒩(μ₀, Σ₀) and P₁ = 𝒩(μ₁, Σ₁)
The closed-form KL divergence is:
KL(P₀ ‖ P₁) = ½ [ tr(Σ₁⁻¹Σ₀) + (μ₁ − μ₀)ᵀ Σ₁⁻¹ (μ₁ − μ₀)
− d + log(|Σ₁| / |Σ₀|) ]
Parameters¶
mu0 : np.ndarray of shape (d,) Mean of the source distribution P₀. cov0 : np.ndarray of shape (d, d) Covariance Σ₀ of the source distribution P₀. mu1 : np.ndarray of shape (d,) Mean of the target distribution P₁. cov1 : np.ndarray of shape (d, d) Covariance Σ₁ of the target distribution P₁.
Returns¶
kl : float KL divergence KL(P₀ ‖ P₁) in nats. Always non-negative for valid covariance matrices.
Notes¶
The matrix inverse Σ₁⁻¹ is computed via np.linalg.inv; for large d
a Cholesky-based approach would be more numerically stable.
Examples¶
import numpy as np from rbig._src.parametric import kl_divergence_gaussian
KL(P ‖ P) = 0 for identical distributions¶
mu = np.array([1.0, 2.0]) cov = np.array([[2.0, 0.5], [0.5, 1.5]]) kl = kl_divergence_gaussian(mu, cov, mu, cov) np.isclose(kl, 0.0, atol=1e-10) True
Source code in rbig/_src/parametric.py
rbig.entropy_gaussian(cov)
¶
Analytic differential entropy of a multivariate Gaussian.
Computes the closed-form entropy of 𝒩(μ, Σ):
H(X) = ½ log|2πeΣ| = ½ (d(1 + log 2π) + log|Σ|)
where d is the dimensionality and |·| denotes the matrix determinant. The mean μ does not affect the entropy.
Parameters¶
cov : np.ndarray of shape (d, d) or (1,) for scalar
Covariance matrix Σ (or variance for d=1). Coerced to at least 2-D
via np.atleast_2d.
Returns¶
entropy : float
Differential entropy in nats. Returns -inf if Σ is singular or
not positive definite.
Notes¶
np.linalg.slogdet is used for numerically stable log-determinant
computation.
Examples¶
import numpy as np from rbig._src.parametric import entropy_gaussian
2-D standard Gaussian: H = 0.5 * 2 * (1 + log 2π) ≈ 2.838 nats¶
h = entropy_gaussian(np.eye(2)) np.isclose(h, 0.5 * 2 * (1 + np.log(2 * np.pi))) True
Source code in rbig/_src/parametric.py
Image Processing¶
rbig.ImageRBIG
¶
RBIG orchestrator for image data.
Alternates between marginal Gaussianisation and an orthonormal spatial
rotation for n_layers steps, progressively pushing the joint
distribution of image pixels towards a multivariate Gaussian.
Each layer applies:
- :class:
~rbig._src.marginal.MarginalGaussianize— maps every feature dimension to a standard normal marginal distribution. - An orthonormal rotation selected by
strategy— decorrelates features without changing the differential entropy.
Parameters¶
n_layers : int, default 10
Number of (marginal + rotation) layer pairs to apply.
C : int, default 1
Number of image channels passed to the rotation layers.
H : int, default 8
Image height in pixels passed to the rotation layers.
W : int, default 8
Image width in pixels passed to the rotation layers.
strategy : str, default "dct"
Rotation strategy. One of:
* ``"dct"`` — Type-II orthonormal DCT (:class:`DCTRotation`).
* ``"hartley"`` — Discrete Hartley Transform
(:class:`HartleyRotation`).
* ``"random_channel"`` — Random orthogonal channel mixing
(:class:`RandomChannelRotation`).
Any unknown string falls back to ``"dct"``.
random_state : int or None, default None
Base seed for rotation layers that use randomness (random_channel).
Layer i uses seed random_state + i.
verbose : bool or int, default=False
Controls progress bar display. False (or 0) disables all
progress bars. True (or 1) shows a progress bar for the
fit loop. 2 additionally shows progress bars for
transform and inverse_transform.
Attributes¶
layers_ : list of tuple (MarginalGaussianize, ImageBijector)
Fitted (marginal, rotation) pairs in application order.
X_transformed_ : np.ndarray, shape (N, C*H*W)
Final transformed representation after the last layer.
Notes¶
The composed forward transform for a single sample :math:\mathbf{x} is
.. math::
\mathbf{z} = (R_L \circ G_L \circ \cdots \circ R_1 \circ G_1)(\mathbf{x})
where :math:G_\ell is marginal Gaussianisation and :math:R_\ell is an
orthonormal rotation at layer :math:\ell. Because each rotation is
orthonormal, the total log-determinant is determined entirely by the
marginal transforms.
Examples¶
import numpy as np rng = np.random.default_rng(0) X = rng.standard_normal((50, 64)) # 50 images, C=1, H=8, W=8 model = ImageRBIG(n_layers=3, C=1, H=8, W=8, strategy="dct", random_state=0) model.fit(X) # doctest: +ELLIPSIS ImageRBIG(...) Xt = model.transform(X) Xt.shape (50, 64) Xr = model.inverse_transform(Xt) Xr.shape (50, 64)
Source code in rbig/_src/image.py
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | |
fit(X, y=None)
¶
Fit all (marginal, rotation) layer pairs sequentially.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Training image batch in flattened format.
Returns¶
self : ImageRBIG
Source code in rbig/_src/image.py
transform(X)
¶
Apply all fitted layers in forward order.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Image batch to transform.
Returns¶
Xt : np.ndarray, shape (N, C*H*W)
Gaussianised representation.
Source code in rbig/_src/image.py
inverse_transform(X)
¶
Apply all fitted layers in reverse order.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Gaussianised representation to invert.
Returns¶
Xr : np.ndarray, shape (N, C*H*W)
Reconstructed image batch in the original domain.
Source code in rbig/_src/image.py
rbig.ImageBijector
¶
Bases: Bijector
Abstract base class for bijective image transforms.
Manages the conversion between the flattened representation
(N, C·H·W) expected by RBIG and the 4-D tensor (N, C, H, W)
used internally by spatial transforms.
Subclasses must implement :meth:fit, :meth:transform, and
:meth:inverse_transform. The default :meth:get_log_det_jacobian
returns zeros, which is correct for all orthonormal transforms defined
in this module (|det J| = 1).
Attributes¶
C_ : int
Number of channels (set during :meth:fit).
H_ : int
Image height in pixels (set during :meth:fit).
W_ : int
Image width in pixels (set during :meth:fit).
Notes¶
The two helper methods implement:
.. math::
\text{_to_tensor}: (N, C \cdot H \cdot W)
\longrightarrow (N, C, H, W)
\text{_to_flat}: (N, C, H, W)
\longrightarrow (N, C \cdot H \cdot W)
Source code in rbig/_src/image.py
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | |
get_log_det_jacobian(X)
¶
Return per-sample log |det J| = 0 (orthonormal transform).
Parameters¶
X : np.ndarray, shape (N, D)
Returns¶
log_det : np.ndarray, shape (N,)
All-zero array because the Jacobian determinant is ±1 for every
orthonormal linear map.
Source code in rbig/_src/image.py
rbig.DCTRotation
¶
Bases: ImageBijector
Type-II orthonormal 2-D Discrete Cosine Transform rotation.
Applies the 2-D DCT-II with orthonormal normalisation (norm="ortho")
to each spatial channel. Because the ortho-normalised DCT is an
orthogonal matrix, log|det J| = 0 for all inputs.
Parameters¶
C : int, default 1 Number of image channels. H : int, default 8 Image height in pixels. W : int, default 8 Image width in pixels.
Attributes¶
C_ : int Fitted number of channels. H_ : int Fitted image height. W_ : int Fitted image width.
Notes¶
For an orthonormal DCT matrix :math:\mathbf{D} acting on the
vectorised image :math:\mathbf{x}:
.. math::
\mathbf{y} = \mathbf{D}\,\mathbf{x},
\quad
\log |\det J| = \log |\det \mathbf{D}| = 0
because :math:\mathbf{D} is orthogonal (det = ±1).
Examples¶
import numpy as np rng = np.random.default_rng(0) X = rng.standard_normal((5, 64)) # N=5, C=1, H=8, W=8 layer = DCTRotation(C=1, H=8, W=8) layer.fit(X) # doctest: +ELLIPSIS DCTRotation(...) Xt = layer.transform(X) Xr = layer.inverse_transform(Xt) np.allclose(X, Xr, atol=1e-10) True
Source code in rbig/_src/image.py
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 | |
fit(X, y=None)
¶
transform(X)
¶
Apply orthonormal 2-D DCT-II to every image channel.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Flattened image batch.
Returns¶
Xt : np.ndarray, shape (N, C*H*W)
Orthonormal DCT-II coefficients.
Source code in rbig/_src/image.py
inverse_transform(X)
¶
Apply orthonormal 2-D inverse DCT (DCT-III scaled).
Parameters¶
X : np.ndarray, shape (N, C*H*W)
DCT coefficient batch from :meth:transform.
Returns¶
Xr : np.ndarray, shape (N, C*H*W)
Reconstructed image batch.
Source code in rbig/_src/image.py
rbig.HartleyRotation
¶
Bases: ImageBijector
Discrete Hartley Transform — real-to-real orthonormal rotation.
The 2-D Discrete Hartley Transform (DHT) is defined as
.. math::
H(\mathbf{x}) = \operatorname{Re}\bigl(\text{FFT}(\mathbf{x})\bigr)
- \operatorname{Im}\bigl(\text{FFT}(\mathbf{x})\bigr)
and is normalised by 1/√(H·W) to make it orthonormal (unitary).
Because the DHT is its own inverse (self-inverse), the same operation is
applied in both :meth:transform and :meth:inverse_transform.
Since the transform is orthonormal log|det J| = 0 for all inputs.
Parameters¶
C : int, default 1 Number of image channels. H : int, default 8 Image height in pixels. W : int, default 8 Image width in pixels.
Attributes¶
C_ : int Fitted number of channels. H_ : int Fitted image height. W_ : int Fitted image width.
Notes¶
The normalised DHT satisfies
.. math::
H(H(\mathbf{x})) = \mathbf{x}
making it a self-inverse bijection. The scaling factor is
:math:1 / \sqrt{H \cdot W}.
Examples¶
import numpy as np rng = np.random.default_rng(0) X = rng.standard_normal((5, 64)) # N=5, C=1, H=8, W=8 layer = HartleyRotation(C=1, H=8, W=8) layer.fit(X) # doctest: +ELLIPSIS HartleyRotation(...) Xt = layer.transform(X) Xr = layer.inverse_transform(Xt) np.allclose(X, Xr, atol=1e-10) True
Source code in rbig/_src/image.py
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 | |
fit(X, y=None)
¶
transform(X)
¶
Apply normalised 2-D DHT to every image channel.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Flattened image batch.
Returns¶
Xt : np.ndarray, shape (N, C*H*W)
DHT coefficients scaled by 1/√(H*W).
Source code in rbig/_src/image.py
inverse_transform(X)
¶
Apply the inverse DHT (identical to the forward transform).
The normalised DHT satisfies H(H(x)) = x, so the forward and
inverse transforms are the same function.
Parameters¶
X : np.ndarray, shape (N, C*H*W)
Returns¶
Xr : np.ndarray, shape (N, C*H*W)
Source code in rbig/_src/image.py
rbig.WaveletTransform
¶
Bases: BaseTransform
Multi-level 2-D wavelet decomposition for image data.
Wraps PyWavelets wavedec2 / waverec2 to provide the standard
fit / transform / inverse_transform interface expected by
RBIG pipeline components.
The forward transform maps each (H, W) image to a flat coefficient
vector of length H * W (for periodization boundary mode the coefficient
array has the same number of elements as the input image).
Requires PyWavelets (pip install PyWavelets).
Parameters¶
wavelet : str, default "haar"
Wavelet name accepted by :func:pywt.Wavelet, e.g. "haar",
"db2", "sym4".
level : int, default 1
Decomposition depth. Higher levels produce coarser approximation
sub-bands.
mode : str, default "periodization"
Signal extension mode passed to PyWavelets. "periodization"
ensures the output coefficient array has the same total size as the
input.
Attributes¶
original_shape_ : tuple of int
Shape (N, H, W) of the training data passed to :meth:fit.
coeff_slices_ : list
PyWavelets slicing metadata needed to pack/unpack the coefficient
array. Set during :meth:fit.
coeff_shape_ : tuple of int
Shape of the 2-D coefficient array produced by
:func:pywt.coeffs_to_array.
Notes¶
The mapping from image to coefficients is
.. math::
(N,\, H \cdot W) \xrightarrow{\text{wavedec2}}
(N,\, H \cdot W)
For level=1 and wavelet="haar" the four sub-bands are:
approximation (LL), horizontal detail (LH), vertical detail (HL), and
diagonal detail (HH).
Examples¶
import numpy as np rng = np.random.default_rng(0) X = rng.standard_normal((50, 8, 8)) # 50 grayscale 8×8 images wt = WaveletTransform(wavelet="haar", level=1) wt.fit(X) # doctest: +ELLIPSIS WaveletTransform(...) Xt = wt.transform(X) Xt.shape (50, 64) Xr = wt.inverse_transform(Xt) Xr.shape (50, 8, 8)
Source code in rbig/_src/image.py
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | |
fit(X, y=None)
¶
Compute and store coefficient layout from the first sample.
Parameters¶
X : np.ndarray, shape (N, H, W)
Training images. Only the first sample is used to determine the
coefficient array shape; the data values are not retained.
Returns¶
self : WaveletTransform
Source code in rbig/_src/image.py
transform(X)
¶
Decompose images into flattened wavelet coefficients.
Parameters¶
X : np.ndarray, shape (N, H, W)
Images to transform.
Returns¶
Xt : np.ndarray, shape (N, H*W)
Flattened coefficient vectors, one row per image.
Source code in rbig/_src/image.py
inverse_transform(X)
¶
Reconstruct images from flattened wavelet coefficients.
Parameters¶
X : np.ndarray, shape (N, H*W)
Flattened coefficient vectors produced by :meth:transform.
Returns¶
Xr : np.ndarray, shape (N, H, W)
Reconstructed images.
Source code in rbig/_src/image.py
Xarray Integration¶
rbig.XarrayRBIG
¶
RBIG model with an xarray-aware interface.
Wraps an :class:~rbig._src.model.AnnealedRBIG (or compatible class) so
that it can be fitted and applied directly to :class:xarray.DataArray /
:class:xarray.Dataset objects with spatiotemporal dimensions. The
underlying model operates on a 2-D (samples, features) matrix obtained
via :func:xr_st_to_matrix.
Parameters¶
n_layers : int, default 100
Maximum number of RBIG layers.
strategy : list or None, default None
Rotation strategy list passed to the underlying RBIG model. If
None, the default rotation of the model class is used.
tol : float, default 1e-5
Convergence tolerance for early stopping.
random_state : int or None, default None
Random seed for reproducibility.
rbig_class : class or None, default None
RBIG model class to instantiate. Defaults to
:class:~rbig._src.model.AnnealedRBIG when None.
rbig_kwargs : dict or None, default None
Additional keyword arguments forwarded to rbig_class.
verbose : bool or int, default=False
Controls progress bar display. Passed through to the underlying
RBIG model.
Attributes¶
model_ : AnnealedRBIG
The fitted underlying RBIG model.
meta_ : dict
xarray metadata captured during :meth:fit, used to reconstruct
output arrays.
Examples¶
import numpy as np import xarray as xr rng = np.random.default_rng(0) da = xr.DataArray( ... rng.standard_normal((30, 4, 5)), ... dims=["time", "lat", "lon"], ... ) xrbig = XarrayRBIG(n_layers=10, random_state=0)
info = xrbig.fit(da)¶
da_t = xrbig.transform(da)¶
Source code in rbig/_src/xarray_st.py
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | |
fit(X)
¶
Fit the RBIG model to xarray data and return an information summary.
Parameters¶
X : xr.DataArray or xr.Dataset
Input spatiotemporal data. Internally converted to a 2-D matrix
via :func:xr_st_to_matrix.
Returns¶
info : dict
Dictionary of RBIG information metrics (e.g. total correlation,
entropy estimates) as returned by
:func:~rbig._src.metrics.information_summary.
Source code in rbig/_src/xarray_st.py
transform(X)
¶
Gaussianise samples and return an xarray object.
Applies the fitted RBIG transform to X, then reconstructs the
original xarray structure. Original coordinates and DataArray name
are re-attached when possible.
Parameters¶
X : xr.DataArray or xr.Dataset
Data to transform. Must have the same structure as the data
passed to :meth:fit.
Returns¶
out : xr.DataArray or xr.Dataset
Gaussianised data with the same shape and dimension names as X.
Source code in rbig/_src/xarray_st.py
score_samples(X)
¶
Compute per-sample log-probability log p(x).
Parameters¶
X : xr.DataArray or xr.Dataset Input data.
Returns¶
log_prob : np.ndarray, shape (n_samples,)
Log-probability of each sample under the fitted RBIG model.
Source code in rbig/_src/xarray_st.py
mutual_information(X, Y)
¶
Estimate mutual information between two xarray variables via RBIG.
Fits independent RBIG models to X, Y, and their concatenation
[X, Y], then computes:
.. math::
\mathrm{MI}(X;\,Y)
= H(X) + H(Y) - H(X,\,Y)
where each differential entropy :math:H is estimated from the RBIG
log-determinant accumulation.
Parameters¶
X : xr.DataArray or xr.Dataset
First variable.
Y : xr.DataArray or xr.Dataset
Second variable. Must have the same number of samples as X
after flattening.
Returns¶
mi : float Estimated mutual information in nats.
Notes¶
All three RBIG models share the same n_layers, tol, and
random_state settings as the parent :class:XarrayRBIG instance.
Examples¶
import numpy as np import xarray as xr rng = np.random.default_rng(0) x = xr.DataArray(rng.standard_normal((50, 1)), dims=["time", "f"]) y = xr.DataArray(rng.standard_normal((50, 1)), dims=["time", "f"]) xrbig = XarrayRBIG(n_layers=5, random_state=0)
mi = xrbig.mutual_information(x, y)¶