ó
    >:jÊ6  ã                   ó,   • S SK Jr  S SKr " S S5      rg)é    )ÚOptionalNc                   ó¶  • \ rS rSrSr        SS\\   S\\   S\\   S\\   S\S	\\   S
\S\\   4S jjr	S r
S rS rS\R                  4S jr\S\\R                  \R                  \R                  4   4S j5       r\SS\\R                  \R                  4   4S jj5       rSS jrSS jrS\R                  4S jr\SS\S\S\4S jj5       rSrg)ÚIncrementalPCAé   a%  
An implementation of Incremental Principal Components Analysis (IPCA) that leverages PyTorch for GPU acceleration.
Adapted from https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/decomposition/_incremental_pca.py

This class provides methods to fit the model on data incrementally in batches, and to transform new data based on
the principal components learned during the fitting process.

Args:
    n_components (int, optional): Number of components to keep. If `None`, it's set to the minimum of the
        number of samples and features. Defaults to None.
    copy (bool): If False, input data will be overwritten. Defaults to True.
    batch_size (int, optional): The number of samples to use for each batch. Only needed if self.fit is called.
        If `None`, it's inferred from the data and set to `5 * n_features`. Defaults to None.
    svd_driver (str, optional): name of the cuSOLVER method to be used for torch.linalg.svd. This keyword
        argument only works on CUDA inputs. Available options are: None, gesvd, gesvdj, and gesvda. Defaults to
        None.
    lowrank (bool, optional): Whether to use torch.svd_lowrank instead of torch.linalg.svd which can be faster.
        Defaults to False.
    lowrank_q (int, optional): For an adequate approximation of n_components, this parameter defaults to
        n_components * 2.
    lowrank_niter (int, optional): Number of subspace iterations to conduct for torch.svd_lowrank.
        Defaults to 4.
    lowrank_seed (int, optional): Seed for making results of torch.svd_lowrank reproducible.
NÚn_componentsÚcopyÚ
batch_sizeÚ
svd_driverÚlowrankÚ	lowrank_qÚlowrank_niterÚlowrank_seedc	                 ó¶   • Xl         X l        X0l        X@l        XPl        X`l        Xpl        X€l        S U l        U R                  (       a  U R                  5         g g )N)
r   r   r	   r
   r   r   r   r   Ún_features_Ú_validate_lowrank_params)	Úselfr   r   r	   r
   r   r   r   r   s	            ÚW/home/mande/repo/quber/.venv/lib/python3.13/site-packages/peft/utils/incremental_pca.pyÚ__init__ÚIncrementalPCA.__init__.   sO   € ð )ÔØŒ	Ø$ŒØ$ŒØŒØ"ŒØ*ÔØ(ÔàˆÔà�<�<Ø×)Ñ)Õ+ð ó    c                 óÂ   • U R                   c-  U R                  c  [        S5      eU R                  S-  U l         g U R                   U R                  :  a  [        S5      eg )NzKn_components must be specified when using lowrank mode with lowrank_q=None.é   z8lowrank_q must be greater than or equal to n_components.)r   r   Ú
ValueError)r   s    r   r   Ú'IncrementalPCA._validate_lowrank_paramsG   sY   € Ø�>‰>Ñ!Ø× Ñ Ñ(Ü Ð!nÓoÐoØ!×.Ñ.°Ñ2ˆD�NØ�^‰^˜d×/Ñ/Ó/ÜÐWÓXÐXð 0r   c                 óT   • [         R                  R                  USU R                  S9$ )NF)Úfull_matricesÚdriver)ÚtorchÚlinalgÚsvdr
   ©r   ÚXs     r   Ú_svd_fn_fullÚIncrementalPCA._svd_fn_fullO   s"   € Ü�|‰|×Ñ °¸t¿¹ÐÐOÐOr   c                 óP  • U R                   S Ln[        R                  R                  US9   U(       a   [        R                  " U R                   5        [        R
                  " XR                  U R                  S9u  p4nX4UR                  4sS S S 5        $ ! , (       d  f       g = f)N)Úenabled)ÚqÚniter)	r   r   ÚrandomÚfork_rngÚmanual_seedÚsvd_lowrankr   r   ÚmH)r   r"   Úseed_enabledÚUÚSÚVs         r   Ú_svd_fn_lowrankÚIncrementalPCA._svd_fn_lowrankR   su   € Ø×(Ñ(°Ð4ˆÜ�\‰\×"Ñ"¨<Ð"Ò8ÞÜ×!Ò! $×"3Ñ"3Ô4Ü×'Ò'¨¯^©^À4×CUÑCUÑV‰GˆA�!Ø˜Ÿ™�:÷	 9×8×8ús   ¬A!BÂ
B%Úreturnc                 óR  • [         R                  [         R                  /n[        U[         R                  5      (       d$  [         R
                  " U[         R                  S9nO!U R                  (       a  UR                  5       nUR                  u  p4U R                  c  OWU R                  U:”  a  [        SU R                   SU S35      eU R                  U:”  a  [        SU R                   SU 35      eUR                  U;  a  UR                  [         R                  5      nU$ )z³
Validates and converts the input data `X` to the appropriate tensor format.

Args:
    X (torch.Tensor): Input data.

Returns:
    torch.Tensor: Converted to appropriate format.
)Údtypezn_components=z invalid for n_features=z<, need more rows than columns for IncrementalPCA processing.z6 must be less or equal to the batch number of samples )r   Úfloat32Úfloat64Ú
isinstanceÚTensorÚtensorr   ÚcloneÚshaper   r   r6   Úto)r   r"   Úvalid_dtypesÚ	n_samplesÚ
n_featuress        r   Ú_validate_dataÚIncrementalPCA._validate_dataZ   s  € ô Ÿ™¤u§}¡}Ð5ˆä˜!œUŸ\™\×*Ñ*Ü—’˜Q¤e§m¡mÑ4‰AØ�Y�YØ—‘“	ˆAà !§¡Ñˆ	Ø×ÑÑ$ØØ×Ñ Ó+ÜØ × 1Ñ 1Ð2Ð2JÈ:È,ð WMð Móð ð ×Ñ Ó*ÜØ × 1Ñ 1Ð2Ð2hÐirÐhsÐtóð ð �7‰7˜,Ó&Ø—‘”U—]‘]Ó#ˆAàˆr   c                 ó  • U R                   S   S:X  a  XU4$ US:”  a  Uc  [        S5      eUc  [        S5      e[        R                  " U R                   S   /U R                  S9nX4-   nUc<  [        R
                  " U R                   S   [        R                  U R                  S9nOX-  nU R                  S[        R                  S9nXg-   U-  nXt-  n	X	-
  n
U
R                  S[        R                  S9R                  5       nU
R                  5         U
R                  S[        R                  S9nXËU-  -  nUc  XÅ-  nO<X#-  nUR                  5       U-  nUU-   Xõ-  Xo-  U-
  R                  5       -  -   nUU-  nX�U4$ )a"  
Computes the incremental mean and variance for the data `X`.

Args:
    X (torch.Tensor): The batch input data tensor with shape (n_samples, n_features).
    last_mean (torch.Tensor): The previous mean tensor with shape (n_features,).
    last_variance (torch.Tensor): The previous variance tensor with shape (n_features,).
    last_sample_count (torch.Tensor): The count tensor of samples processed before the current batch.

Returns:
    Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: Updated mean, variance tensors, and total sample count.
r   z6last_mean should not be None if last_sample_count > 0.z:last_variance should not be None if last_sample_count > 0.©Údeviceé   )r6   rF   )Údimr6   )r=   r   r   r;   rF   Úzerosr8   ÚsumÚsquareÚsquare_Údouble)r"   Ú	last_meanÚlast_varianceÚlast_sample_countÚnew_sample_countÚupdated_sample_countÚlast_sumÚnew_sumÚupdated_meanÚTÚtempÚ
correctionÚnew_unnormalized_varianceÚupdated_varianceÚlast_unnormalized_varianceÚlast_over_new_countÚupdated_unnormalized_variances                    r   Ú_incremental_mean_and_varÚ(IncrementalPCA._incremental_mean_and_var}   sž  € ð  �7‰7�1‰:˜‹?ØÐ->Ð>Ð>à˜qÓ ØÑ Ü Ð!YÓZÐZØÑ$Ü Ð!]Ó^Ð^ä Ÿ<š<¨¯©°©¨¸Q¿X¹XÑFÐØ0ÑCÐàÑÜ—{’{ 1§7¡7¨1¡:´U·]±]È1Ï8É8ÑT‰Hà Ñ4ˆHà—%‘%˜A¤U§]¡]�%Ð3ˆà Ñ*Ð.BÑBˆàÑ&ˆØ‰uˆØ—X‘X !¬5¯=©=�XÐ9×@Ñ@ÓBˆ
Ø�‰ŒØ$(§H¡H°¼%¿-¹- HÐ$HÐ!Ø!Ð2BÑ%BÑBÐ!ØÑ Ø8ÑOÑà)6Ñ)JÐ&Ø"3×":Ñ":Ó"<Ð?OÑ"OÐà*Ø+ñ,à%Ñ<ÀÑ@^ÐahÑ@h×?pÑ?pÓ?rÑrñsð *ð
  =Ð?SÑSÐàÐ/CÐCÐCr   c                 óî  • U(       aZ  [         R                  " [         R                  " U 5      SS9n[         R                  " X[	        U R
                  S   5      4   5      nOZ[         R                  " [         R                  " U5      SS9n[         R                  " U[	        UR
                  S   5      U4   5      nXSU R
                  S    R                  SS5      -  n XR                  SS5      -  nX4$ )a  
Adjusts the signs of the singular vectors from the SVD decomposition for deterministic output.

This method ensures that the output remains consistent across different runs.

Args:
    u (torch.Tensor): Left singular vectors tensor.
    v (torch.Tensor): Right singular vectors tensor.
    u_based_decision (bool, optional): If True, uses the left singular vectors to determine the sign flipping.
        Defaults to True.

Returns:
    Tuple[torch.Tensor, torch.Tensor]: Adjusted left and right singular vectors tensors.
r   ©rH   rG   Néÿÿÿÿ)r   ÚargmaxÚabsÚsignÚranger=   Úview)ÚuÚvÚu_based_decisionÚmax_abs_colsÚsignsÚmax_abs_rowss         r   Ú	_svd_flipÚIncrementalPCA._svd_flip¶   s½   € ö  Ü Ÿ<š<¬¯	ª	°!«¸!Ñ<ˆLÜ—J’J˜q¬u°Q·W±W¸Q±ZÓ/@Ð!@ÑAÓB‰Eä Ÿ<š<¬¯	ª	°!«¸!Ñ<ˆLÜ—J’J˜q¤ q§w¡w¨q¡zÓ!2°LÐ!@ÑAÓBˆEØ	�<�Q—W‘W˜Q‘ZÐ ×%Ñ% a¨Ó,Ñ,ˆØ	�Z‰Z˜˜AÓÑˆØˆtˆr   c                 ó  • U(       a  U R                  U5      nUR                  u  p4U R                  c
  SU-  U l        U R                  X0R                  U R                  =(       d    SS9 H  nU R                  X   SS9  M     U $ )a$  
Fits the model with data `X` using minibatches of size `batch_size`.

Args:
    X (torch.Tensor): The input data tensor with shape (n_samples, n_features).
    check_input (bool, optional): If True, validates the input. Defaults to True.

Returns:
    IncrementalPCA: The fitted IPCA model.
é   r   )Úmin_batch_sizeF)Úcheck_input)rB   r=   r	   Úgen_batchesr   Úpartial_fit)r   r"   rs   r@   rA   Úbatchs         r   ÚfitÚIncrementalPCA.fitÐ   s€   € ö Ø×#Ñ# AÓ&ˆAØ !§¡Ñˆ	Ø�?‰?Ñ"Ø *™nˆDŒOà×%Ñ% i·±ÐQU×QbÑQb×QgÐfgÐ%ÓhˆEØ×Ñ˜Q™X°5ÐÓ9ñ ið ˆr   c                 ó‚  • [        U S5      (       + nU(       a  U R                  U5      nUR                  u  pEU(       aZ  SU l        SU l        [
        R                  " S/UR                  S9U l        XPl	        U R                  (       d  [        XE5      U l
        XPR                  :w  a  [        S5      eU R                  XR                  U R                  U R                  5      u  pgnU(       a  X-  nO�[
        R                  " USS9n	X-  n[
        R                  " U R                  R!                  5       U-  U-  5      n
X R                  U	-
  -  n[
        R"                  " U R$                  R'                  S5      U R(                  -  UU45      nU R*                  (       a  U R-                  U5      u  pÍnOU R/                  U5      u  pÍnU R1                  XÎSS	9u  pÎUS
-  US-
  -  nUS
-  [
        R2                  " Xx-  5      -  nX€l        USU R                   U l        USU R                   U l        X`l        Xpl        USU R                   U l        USU R                   U l        U R                  XE4;  a#  XðR                  S R                  5       U l        U $ [
        R                  " SUR                  S9U l        U $ )a3  
Incrementally fits the model with batch data `X`.

Args:
    X (torch.Tensor): The batch input data tensor with shape (n_samples, n_features).
    check_input (bool, optional): If True, validates the input. Defaults to True.

Returns:
    IncrementalPCA: The updated IPCA model after processing the batch.
Úcomponents_Nr   rE   z]Number of features of the new batch does not match the number of features of the first batch.ra   )rb   rG   F)rj   r   rG   g        )ÚhasattrrB   r=   Úmean_Úvar_r   r;   rF   Ún_samples_seen_r   r   Úminr   r^   ÚmeanÚsqrtrM   ÚvstackÚsingular_values_rg   rz   r   r2   r#   rn   rJ   Úexplained_variance_Úexplained_variance_ratio_Únoise_variance_)r   r"   rs   Ú
first_passr@   rA   Úcol_meanÚcol_varÚn_total_samplesÚcol_batch_meanÚmean_correction_factorÚmean_correctionr/   r0   ÚVtÚexplained_varianceÚexplained_variance_ratios                    r   ru   ÚIncrementalPCA.partial_fitæ   sˆ  € ô !  }Ó5Ô5ˆ
æØ×#Ñ# AÓ&ˆAØ !§¡Ñˆ	ö ØˆDŒJØˆDŒIÜ#(§<¢<°°¸A¿H¹HÑ#EˆDÔ Ø)ÔØ×$×$Ü$'¨	Ó$>�Ô!à×)Ñ)Ó)ÜØoóð ð .2×-KÑ-KØ�z‰z˜4Ÿ9™9 d×&:Ñ&:ó.
Ñ*ˆ˜?ö Ø‰M‰Aä"ŸZšZ¨¨qÑ1ˆNØÑˆAÜ%*§Z¢Z°×1EÑ1E×1LÑ1LÓ1NÐQ`Ñ1`ÐdmÑ0mÓ%nÐ"Ø4¿
¹
À^Ñ8SÑTˆOÜ—’à×)Ñ)×.Ñ.¨wÓ7¸$×:JÑ:JÑJØØ#ðóˆAð �<�<Ø×+Ñ+¨AÓ.‰HˆA‘"à×(Ñ(¨Ó+‰HˆA�"Ø—‘˜q°u�Ð=‰ˆØ ™T _°qÑ%8Ñ9ÐØ#$ a¡4¬%¯)ª)°GÑ4MÓ*NÑ#NÐ à.ÔØÐ1 × 1Ñ 1Ð2ˆÔØ !Ð"5 D×$5Ñ$5Ð 6ˆÔØŒ
ØŒ	Ø#5Ð6I¸×8IÑ8IÐ#JˆÔ Ø)AÐBUÀD×DUÑDUÐ)VˆÔ&Ø×Ñ YÐ$;Ó;Ø#5×6GÑ6GÐ6IÐ#J×#OÑ#OÓ#QˆDÔ ð ˆô $)§<¢<°¸A¿H¹HÑ#EˆDÔ Øˆr   c                 óÂ   • XR                   -
  n[        R                  " UR                  5       U R                  R
                  5      R                  UR                  5      $ )aT  
Applies dimensionality reduction to `X`.

The input data `X` is projected on the first principal components previously extracted from a training set.

Args:
    X (torch.Tensor): New data tensor with shape (n_samples, n_features) to be transformed.

Returns:
    torch.Tensor: Transformed data tensor with shape (n_samples, n_components).
)r|   r   ÚmmrM   rz   rV   r>   r6   r!   s     r   Ú	transformÚIncrementalPCA.transform-  sA   € ð —
‘
‰NˆÜ�xŠx˜Ÿ™›
 D×$4Ñ$4×$6Ñ$6Ó7×:Ñ:¸1¿7¹7ÓCÐCr   Únrr   c              #   óª   #   • Sn[        [        X-  5      5       H   nX1-   nXR-   U :”  a  M  [        X55      v •  UnM"     X0:  a  [        X05      v •  gg7f)a¤  Generator to create slices containing `batch_size` elements from 0 to `n`.

The last slice may contain less than `batch_size` elements, when `batch_size` does not divide `n`.

Args:
    n (int): Size of the sequence.
    batch_size (int): Number of elements in each batch.
    min_batch_size (int, optional): Minimum number of elements in each batch. Defaults to 0.

Yields:
    slice: A slice of `batch_size` elements.
r   N)rf   ÚintÚslice)r–   r	   rr   ÚstartÚ_Úends         r   rt   ÚIncrementalPCA.gen_batches<  s^   é € ð ˆÜ”s˜1™?Ó+Ö,ˆAØÑ$ˆCØÑ# aÓ'ÙÜ˜Ó#Ò#ØŠEñ -ð ‹9Ü˜“/Ó!ð ùs   ‚AA)r	   rz   r   r„   r…   r   r   r   r   r|   r   r   r~   r†   rƒ   r
   r}   )NTNNFNé   N)T)r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r˜   ÚboolÚstrr   r   r#   r2   r   r:   rB   ÚstaticmethodÚtupler^   rn   rw   ru   r”   rt   Ú__static_attributes__© r   r   r   r      sZ  † ñð6 '+Ø#Ø$(Ø$(ØØ#'ØØ&*ñ,à˜s‘mð,ð �t‰nð,ð ˜S‘Mð	,ð
 ˜S‘Mð,ð ð,ð ˜C‘=ð,ð ð,ð ˜s‘mõ,ò2YòPòð! 5§<¡<ô !ðF ð6Dà	ˆu�|‰|˜UŸ\™\¨5¯<©<Ð7Ñ	8ó6Dó ð6Dðp ñ°%¸¿¹ÀeÇlÁlÐ8RÑ2Sô ó ðô2ô,EðND˜eŸl™lô Dð ñ"�sð "¨ð "¸Sô "ó ó"r   r   )Útypingr   r   r   r©   r   r   Ú<module>r«      s   ðõ ã ÷~"ò ~"r   