`L idZddlZddlZddlZddlmZddlZddlZddlm Z ddl m Z ddl mZddlmZddlmZddlmZd d lmZd gZd d hZd>dZd>dZdZdZdZdefddZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(defddZ)defdd d!Z*defdd d"Z+d?d#Z,d@d$Z-d%Z.d&Z/d'Z0dAd(Z1d?d)Z2dBd*Z3dBd+Z4dBd,Z5 dCddd-d.Z6d?d/Z7d0Z8d1Z9d2Z:d3Z;d4ddd5d6ZdEd9Z?dd:d;Z@dCd<ZAd?d=ZBy)FzTools to support array_api.Nwraps) get_config)array_api_compat)array_api_extra)numpy) parse_versionxpxr z(sklearn.externals.array_api_compat.numpyTc#8KdD]}|s |tvr|yw)a7Yield supported namespace. This is meant to be used for testing purposes only. Parameters ---------- include_numpy_namespaces : bool, default=True If True, also yield numpy namespaces. Returns ------- array_namespace : str The name of the Array API namespace. )r array_api_strictcupytorchN)_NUMPY_NAMESPACE_NAMES)include_numpy_namespacesarray_namespaces ^/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sklearn/utils/_array_api.pyyield_namespacesrs-  (O?U,U  sc#HKt|D]r}|dk(r-tjddD] \}}|||f|ddf5|dk(r2 dd l}||j d d f||j d dfl|d d fty #t $r|d d f|d dfYwxYww) aYield supported namespace, device, dtype tuples for testing. Use this to test that an estimator works with all combinations. Use in conjunction with `ids=_get_namespace_device_dtype_ids` to give clearer pytest parametrization ID names. Parameters ---------- include_numpy_namespaces : bool, default=True If True, also yield numpy namespaces. Returns ------- array_namespace : str The name of the Array API namespace. device : str The name of the device on which to allocate the arrays. Can be None to indicate that the default value should be used. dtype_name : str The name of the data type to use for arrays. Can be None to indicate that the default value should be used. )rr)cpucuda)float64float32mpsrrrN CPU_DEVICErdevice1)r itertoolsproductrDevice ImportError)rrdevicedtypers r)yield_namespace_device_dtype_combinationsr$;s2,!9. g %!*!2!2!7" 5 &vu44 5"5)3 3  2 2 <'%'7'>'>|'LiWW%'7'>'>y'I9TT"4- -/.  <&|Y>>%y);;  Nrr z$Input arrays use different devices: z, )_remove_non_arraysr= ValueError)r?r@ array_listdevice_r< device_others rr"r"sx*$ <J ":a=1G AB+E2 l "6wir,P  Nr6c@tj|jS)zReturn the total number of elements of x. Parameters ---------- x : array Array instance from NumPy or an array API compatible library. Returns ------- out : int Total number of elements. )mathprodshape)xs rsizerLs 99QWW r6c&|jtvS)z%Return True if xp is backed by NumPy.)__name__rxps r_is_numpy_namespacerQs ;;0 00r6cRt|r9ddlm}||||\}}|jt j ||S|j |j cxk(rdk(sJJ|j|j|j||j|gS)Nr ) cached_uniquerO) rQ_uniquerSasarrayr union1dndim unique_valuesconcat)abrPrSa_uniqueb_uniques r_union1dr^s2**1aB7(zz%--(;<< 66QVV q    BIIr'7'7':Bzisdtype..sB?5!33BrO)r8tupleanyrc)r#kindrPs` `risdtyperls/ $BTBBBudr22r6ct|tr3|dk(rjk(S|dk(r0jjj j hvS|dk(r0jjjjhvS|dk(rtfddDS|dk(r tvS|dk(r\t}td r|jj td r|jj"|vS|d k(rtfd d DSt%d||k(S)Nboolsigned integerunsigned integerintegralc3:K|]}t|ywrarbrds rrgz"_isdtype_single.. % qR00rh)rorp real floatingcomplex floating complex64 complex128numericc3:K|]}t|ywrarbrds rrgz"_isdtype_single..rsrh)rqrtruzUnrecognized data type kind: )r8strrnint8int16int32int64uint8uint16uint32uint64rjsupported_float_dtypessetr;addrvrwrC)r#rkrPcomplex_dtypess` ` rrcrcsN$ 6>BGG# # % %RWWbhh"((CC C ' 'RXXryy"))RYYGG G Z ? _ $2266 6 ' ' UNr;'""2<<0r<(""2==1N* * Y J  ! 1W ->> ?s?c(|dvrtd|y)N>NrzUnsupported device for NumPy: )rCrs r_check_device_cpurQs" ]"9&DEE#r6c.tfd}|S)NcJt|jdd|i|S)Nr")rpop)argskwargsfuncs r wrapped_funcz(_accept_device_cpu..wrapped_funcWs&&**Xt45T$V$$r6r)rrs` r_accept_device_cpurVs! 4[%% r6cg}t|}|D];}|r|t||rtj|r+|j |=|S)aFilter arrays to exclude None and/or specific types. Sparse arrays are always filtered out. Parameters ---------- *arrays : array objects Array objects. remove_none : bool, default=True Whether to ignore None objects passed in arrays. remove_types : tuple or list, default=(str,) Types to ignore in the arrays. Returns ------- filtered_arrays : list List of arrays filtered as requested. An empty list is returned if no input passes the filters. )rir8spissparseappend)r?r@rfiltered_arraysr<s rrBrB_s^,O&L& 5=  e\ *  ;;u  u%& r6)r?r@rPctd}|s||dfStdfS||dfSt|||d}|stdfSt|t j |d}}|j dk(rt|dr|jd||fS) aGet namespace of arrays. Introspect `arrays` arguments and return their common Array API compatible namespace object, if any. Note that sparse arrays are filtered by default. See: https://numpy.org/neps/nep-0047-array-api-standard.html If `arrays` are regular numpy arrays, `array_api_compat.numpy` is returned instead. Namespace support is not enabled by default. To enabled it call: sklearn.set_config(array_api_dispatch=True) or: with sklearn.config_context(array_api_dispatch=True): # your code here Otherwise `array_api_compat.numpy` is always returned irrespective of the fact that arrays implement the `__array_namespace__` protocol or not. Note that if no arrays pass the set filters, ``_NUMPY_API_WRAPPER_INSTANCE, False`` is returned. Parameters ---------- *arrays : array objects Array objects. remove_none : bool, default=True Whether to ignore None objects passed in arrays. remove_types : tuple or list, default=(str,) Types to ignore in the arrays. xp : module, default=None Precomputed array namespace module. When passed, typically from a caller that has already performed inspection of its own inputs, skips array namespace inspection. Returns ------- namespace : module Namespace shared by array objects. If any of the `arrays` are not arrays, the namespace defaults to the NumPy namespace. is_array_api_compliant : bool True if the arrays are containers that implement the array API spec (see https://data-apis.org/array-api/latest/index.html). Always False when array_api_dispatch=False. r2FTr>rset_array_api_strict_flagsz2024.12) api_version) r np_compatrBr5rrrNr;r)r?r@rPrr2 namespaceis_array_api_compliants rrrsn$&:;  >u9 e# # ~4x  !F %01(8(F(F(OQU%I//G/5 ,,,C , ,,r6ctdg}t|||d}t|i|}|t|i|\}}n|d}}|r|||fS|d|fS)aCombination into one single function of `get_namespace` and `device`. Parameters ---------- *array_list : array objects Array objects. remove_none : bool, default=True Whether to ignore None objects passed in arrays. remove_types : tuple or list, default=(str,) Types to ignore in the arrays. xp : module, default=None Precomputed array namespace module. When passed, typically from a caller that has already performed inspection of its own inputs, skips array namespace inspection. Returns ------- namespace : module Namespace shared by array objects. If any of the `arrays` are not arrays, the namespace defaults to NumPy. is_array_api_compliant : bool True if the arrays are containers that implement the Array API spec. Always False when array_api_dispatch=False. device : device `device` object (see the "Device Support" section of the array API spec). Fr>T)dictrBr"r)r?r@rPrDskip_remove_kwargs arrays_devicers rget_namespace_and_devicersv:%bA# !J J=*<=M z(*K8JKLtL<..5-''r6ct||\}}t|r7|jtjt j|Sdd|j | zz S)NrOg?)rrQrUspecialexpitr exp)XrP_s r_expitr sU ! #EB2zz'-- a(89:: #r " ##r6cv|jdk7r!tdt|j|j ||j t |}d}|jddz}|s|jd|jdz}|j|d}|r|d||xx|z cc<y||d||<y)a Implementation to facilitate adding or assigning specified values to the diagonal of a 2-d array. If ``add_value`` is `True` then the values will be added to the diagonal elements otherwise the values will be assigned to the diagonal elements. By default, ``add_value`` is set to `True. This is currently only supported for 2-d arrays. The implementation is taken from the `numpy.fill_diagonal` function: https://github.com/numpy/numpy/blob/v2.0.0/numpy/lib/_index_tricks_impl.py#L799-L929 rz*array should be 2-d. Got array with shape r#r"Nr )rWrCrirJrUr#r"reshape)r<valuerP add_valuewrapendstep array_flats r_fill_or_add_to_diagonalrs zzQ8u{{9K8L M   JJuEKKu J FE C ;;q>A D kk!nu{{1~-E5)J9C9& % 9C9r6c0|j|d|d|fvS)Nzarray_api_compat.z#sklearn.externals.array_api_compat.)rN)rPnames r_is_xp_namespacer2s/ ;; D6" -dV4 r6c~t|dr&t|jdr |jS|jS)zJReturn the float dtype with the highest precision supported by the device.rr)rrz startswithrrrPr"s r_max_precision_float_dtyper:s8G$V)?)? *zz ::r6c0|Dcgc] }t|ds|j|"}}|Dcgc]+}|j|jds |j-}}|r|j|S|jdjScc}wcc}w)aFind a suitable floating point dtype when computing with arrays. If any of the arrays are floating point, return the dtype with the highest precision by following official type promotion rules: https://data-apis.org/array-api/latest/API_specification/type_promotion.html If there are no floating point input arrays (all integral inputs for instance), return the default floating point dtype for the namespace. r#rt)r;rUrlr# result_type)rPrrZ dtyped_arraysfloating_dtypess r_find_matching_floating_dtyperEs-3Jqga6IRZZ]JMJ&"**QWWo*NOr~~// ::c?  KsBB!BBc t||\}}}t|rR|r'|jtj|||S|'|%|jtj ||S|j||}||j||}||j |j k7r|8tdt|j dt|j dt|j |j |fk7r;tdt|j dt|j d|d d g|jz}|j |||<|j|t|}|j|jd r td |'|j|jd r td t||| }|j!||}|"|r |j"n |j$||S|j!||}|j%|j'|||} |s| S|j%||} |j)| dk(r t+d| | z S)aPartial port of np.average to support the Array API. It does a best effort at mimicking the return dtype rule described at https://numpy.org/doc/stable/reference/generated/numpy.average.html but only for the common cases needed in scikit-learn. )axisweightsrz+Axis must be specified when the shape of a z and weights z differ.zShape of weights weights.shape=z! must be consistent with a.shape=z and axis=.r ruz;Complex floating point values are not supported by average.rOrrz(Weights sum to zero, can't be normalized)rrQrUr averagedotrJ TypeErrorrirCrWrrlr#NotImplementedErrorrastypemeansummultiplyrjZeroDivisionError) rZrr normalizerPrrErJ output_dtypesum_scales r_averager^sl.a9NB72 ::emmAD'JK K \g1::eii734 4 1W %A**WW*5qww'--7 <=eAGGn=MN /0:   AGGDM#3 31% 2F1GH++0>*:+waI  aff ggdmd **WeEl3 zz!''-.! I  rzz'--9KL! I  1GCL !\"A09"&&!$??ii.G 66"++a)6 5D  FF7F &E vvesl JKK %<r6c t|||\}}}tjdd5||j|z}ddd|j |dk(|j dj ||S#1swY;xYw)NrOignore)divideinvalidrr)rr errstatelogwhererUr#)rKyrPrrEtemps r_xlogyrsu-ar:NB7 x :266!9} 88AHbjjDJJwjOQU VVs A99Bc t||\}}}t|r&|jtj||S|j |}|j |j||j|j|j|||}|j||}|j|r9|j||j|j|j||}|SNrOrr) rrQrUr nanminisnanminrinfr#allrjnanrrrPrrEmasks r_nanminr.aB7NB72zz%,,qt455xx{ FF HHT2::rvvgQWWW:Mq Q   vvdv& 66$<rzz"&&zPRSTAr6c t||\}}}t|r&|jtj||S|j |}|j |j||j|j |j|||}|j||}|j|r9|j||j|j|j||}|Sr) rrQrUr nanmaxrmaxrrr#rrjrrs r_nanmaxrrr6c t||\}}}t|r&|jtj||S|j |}|j |j||jd|j|||}|j |j|j||j|}||z S)NrOrrr) rrQrUr nanmeanrrrr#r logical_not)rrrPrrErtotalcounts r_nanmeanrs.aB7NB72zz%--566xx{ HHT2::c:I1 MTX ryy!5qww?dKu}r6rct||\}}t|rF|durtj|||}ntj|||}|j |S|j ||||S)aHelper to support the order kwarg only for NumPy-backed arrays Memory layout parameter `order` is not exposed in the Array API standard, however some input validation code in scikit-learn needs to work both for classes and functions that will leverage Array API only operations and for code that inherently relies on NumPy backed data containers with specific memory layout constraints (e.g. our own Cython code). The purpose of this helper is to make it possible to share code for data container validation without memory copies for both downstream use cases: the `order` parameter is only enforced if the input array implementation is NumPy based, otherwise `order` is just silently ignored. rOT)orderr#)r#copyr")rrQr r<rU)r<r#rrrPr"rs r_asarray_with_orderrso %B 'EB2 4<KKU%@EMM%uEBEzz%  zz%u4zGGr6ct||\}}t|r;tj|}|jtj|dS|j |dS)zArray API compliant version of np.ravel. For non numpy namespaces, it just returns a flattened array, that might be or not be a copy. rOC)rr)rJ)rrQr rUravelr)r<rPrs r_ravelrsW %B 'EB2 e$zz%++e3788 ::e5: ))r6c:t|dr|jjSt|dr|jSt|dr5tj|j ||j dStj|S)z*Convert X into a NumPy ndarray on the CPU.rrrrr)rrr r0rUr )r<rPs r_convert_to_numpyr svG$yy{  "" "f %yy{ "0 1}}RZZbii 6MZNOO == r6cddlm}||}t|jD]@\}}t |dst |t jr||}t|||B|S)aCreate new estimator which converting all attributes that are arrays. The converter is called on all NumPy arrays and arrays that support the `DLPack interface `__. Parameters ---------- estimator : Estimator Estimator to convert converter : callable Callable that takes an array attribute and returns the converted array. Returns ------- new_estimator : Estimator Convert estimator r)clone __dlpack__) sklearn.baservarsitemsr;r8r r9setattr) estimator converterr new_estimatorkey attributes r _estimator_with_converted_arraysrsf&#)$My///1/Y 9l +z)U]]/S!),I sI./ r6cj|tj}tj|jdzS)z6Return the absolute tolerance for a given numpy dtype.d)r rfinfoeps)dtype_or_dtype_names r_atol_for_typer5s/"$mm ;;* + / /# 55r6c8|jdjS)aMReturn a platform-specific integer dtype suitable for indexing. On 32-bit platforms, this will typically return int32 and int64 otherwise. Note: using dtype is recommended for indexing transient array datastructures. For long-lived arrays, such as the fitted attributes of estimators, it is instead recommended to use platform-independent int32 if we do not expect to index more 2B elements. Using fixed dtypes simplifies the handling of serialized models, e.g. to deploy a model fit on a 64-bit platform to a target 32-bit platform such as WASM/pyodide. r)rUr#rOs rindexing_dtyper?s* ::a=  r6left)sidesorterrPct|||\}}t|dr|j||||St||}t||}t j||||}|j |t |S)NrO searchsorted)rrr)rr;r rr rUr") rZvrrrPra_npv_npindicess r _searchsortedr%Ws| !Q2 &EBr>"q!$v>> Q2 &D Q2 &D  t$vFG ::gfQi: 00r6c t|r(|jtj||||S|j}|j |d}|j |d}|j t ||||||S)zCalculates ``element in test_elements``, broadcasting over `element` only. Returns a boolean array of the same shape as `element` that is True where an element of `element` is in `test_elements` and False otherwise. )element test_elements assume_uniqueinvertr)ar1ar2rPr)r*)rQrUr isinrJr_in1d)r'r(rPr)r*original_element_shapes r_isinr0fs2zz JJ++    %]]jj%(GJJ}e4M :: '     r6ct|||\}}|jdd|jddzzkr|rE|j|jd|jt |}|D] }|||k7z} |S|j |jd|jt |}|D] }|||k(z} |S|s%|j |\}}|j|}|j||f} t | } |j| d} |j| d} |j| | d} t| d k\r|r | d d | d d k7n | d d | d d k(}n&|r|jd gn|jdg}|j||j|g| f}|j|| d}|r|d |jdS|j|dS)aChecks whether each element of an array is also present in a second array. Returns a boolean array the same length as `ar1` that is True where an element of `ar1` is in `ar2` and False otherwise. This function has been adapted using the original implementation present in numpy: https://github.com/numpy/numpy/blob/v1.26.0/numpy/lib/arraysetops.py#L524-L758 rOr g(\?rT)stablerr NrFr) rrJonesrnr"zerosunique_inverserXrYargsorttakerLrU)r+r,rPr)r*rrrZrev_idxarrEr reverse_ordersarbool_arflagrets rr.r.s #sr *EB yy|b399Q<5000 77399QSYYq\""wwsG!w,,r6cddlm}t|||\}}t|r t j |r ||||S|j dk(sJ|j||}|S|j||}|j||jddf}|j||j|z}|jd||j}|j|j|dk7||| S) zA variant of `sklearn.utils.sparsefuncs.count_nonzero` for the Array API. If the array `X` is sparse, and we are using the numpy namespace then we simply call the original function. This function only supports 2D arrays. r ) count_nonzerorO)r sample_weightrrr)r"r#r) sparsefuncsrArrQrrrW ones_likerUrrJrr#rr) rrrBrPr"rArr zero_scalars r_count_nonzerorFs + !]r 2EB22;;q>QTGG 66Q;;ll1Vl,G  = @  ==3F3Fq3I12MN ))G]%8%89MI**QvW]]*CK 66"((167K8t6 DDr6)outcDt|r ||d|i||S||i|}|S)NrG)rQ)rPrrGrrs r_modify_in_place_if_numpyrIs92 d&&v& JD#F# Jr6ct||\}}t|dr|j|||St||}|t||}nd}t j|||}|j |t |S)NrObincount)r minlengthr)rr;rKrr rUr")r<rrLrPrarray_np weights_npbin_outs r _bincountrPs %B 'EBr:{{5'Y{GG 2.H&w26  nnXzYOG ::gfUm: 44r6ct||\}}t|r|jSt||}|Dcgc]}|j c}Scc}w)NrO)rrQtolistritem)r<rPrrMr's r_tolistrTsL %B 'EB2||~ 2.H*2 3wGLLN 33 3sA)T)N)TF)NNTN)NN)NNN)FF)NNNN)C__doc__rrHr. functoolsrr r, scipy.sparsesparser scipy.specialr_configr externalsrrr externals.array_api_compatrfixesr __all__rrr$r(r5r=rzr"rLrQr^rlrcrrrrrBrrrrrrrrrrrrrrrrrrr%r0r.rFrIrPrTr6rr`si!    (.;  '!#MN>0.f" 6"%)v)X  1 S 3D (:F -1v!H(,3&TS-n"4.(b$&@!2?DW((  )-H48H< *  :60!'t 1D.-bE048 5 4r6