@@ -9086,15 +9086,14 @@ def polyfit(
90869086        numpy.polyval 
90879087        xarray.polyval 
90889088        """ 
9089-         from  xarray .core .dataarray  import  DataArray 
9090- 
9091-         variables  =  {}
9089+         variables : dict [Hashable , Variable ] =  {}
90929090        skipna_da  =  skipna 
90939091
90949092        x  =  np .asarray (_ensure_numeric (self .coords [dim ]).astype (np .float64 ))
90959093
90969094        xname  =  f"{ self [dim ].name }  
90979095        order  =  int (deg ) +  1 
9096+         degree_coord_values  =  np .arange (order )[::- 1 ]
90989097        lhs  =  np .vander (x , order )
90999098
91009099        if  rcond  is  None :
@@ -9120,46 +9119,48 @@ def polyfit(
91209119        rank  =  np .linalg .matrix_rank (lhs )
91219120
91229121        if  full :
9123-             rank  =  DataArray ( rank ,  name = xname   +   "matrix_rank" )
9124-             variables [rank . name ] =  rank 
9122+             rank  =  Variable ( dims = (),  data = rank )
9123+             variables [xname   +   "matrix_rank" ] =  rank 
91259124            _sing  =  np .linalg .svd (lhs , compute_uv = False )
9126-             sing  =  DataArray (
9127-                 _sing ,
9125+             variables [xname  +  "singular_values" ] =  Variable (
91289126                dims = (degree_dim ,),
9129-                 coords = {degree_dim : np .arange (rank  -  1 , - 1 , - 1 )},
9130-                 name = xname  +  "singular_values" ,
9127+                 data = np .concatenate ([np .full ((order  -  rank .data ,), np .nan ), _sing ]),
91319128            )
9132-             variables [sing .name ] =  sing 
91339129
91349130        # If we have a coordinate get its underlying dimension. 
9135-         true_dim  =  self .coords [dim ].dims [ 0 ] 
9131+         ( true_dim ,)  =  self .coords [dim ].dims 
91369132
9137-         for  name , da  in  self .data_vars .items ():
9138-             if  true_dim  not  in da .dims :
9133+         other_coords  =  {
9134+             dim : self ._variables [dim ]
9135+             for  dim  in  set (self .dims ) -  {true_dim }
9136+             if  dim  in  self ._variables 
9137+         }
9138+         present_dims : set [Hashable ] =  set ()
9139+         for  name , var  in  self ._variables .items ():
9140+             if  name  in  self ._coord_names  or  name  in  self .dims :
9141+                 continue 
9142+             if  true_dim  not  in var .dims :
91399143                continue 
91409144
9141-             if  is_duck_dask_array (da . data ) and  (
9145+             if  is_duck_dask_array (var . _data ) and  (
91429146                rank  !=  order  or  full  or  skipna  is  None 
91439147            ):
91449148                # Current algorithm with dask and skipna=False neither supports 
91459149                # deficient ranks nor does it output the "full" info (issue dask/dask#6516) 
91469150                skipna_da  =  True 
91479151            elif  skipna  is  None :
9148-                 skipna_da  =  bool (np .any (da .isnull ()))
9149- 
9150-             dims_to_stack  =  [dimname  for  dimname  in  da .dims  if  dimname  !=  true_dim ]
9151-             stacked_coords : dict [Hashable , DataArray ] =  {}
9152-             if  dims_to_stack :
9153-                 stacked_dim  =  utils .get_temp_dimname (dims_to_stack , "stacked" )
9154-                 rhs  =  da .transpose (true_dim , * dims_to_stack ).stack (
9155-                     {stacked_dim : dims_to_stack }
9156-                 )
9157-                 stacked_coords  =  {stacked_dim : rhs [stacked_dim ]}
9158-                 scale_da  =  scale [:, np .newaxis ]
9152+                 skipna_da  =  bool (np .any (var .isnull ()))
9153+ 
9154+             if  var .ndim  >  1 :
9155+                 rhs  =  var .transpose (true_dim , ...)
9156+                 other_dims  =  rhs .dims [1 :]
9157+                 scale_da  =  scale .reshape (- 1 , * ((1 ,) *  len (other_dims )))
91599158            else :
9160-                 rhs  =  da 
9159+                 rhs  =  var 
91619160                scale_da  =  scale 
9161+                 other_dims  =  ()
91629162
9163+             present_dims .update (other_dims )
91639164            if  w  is  not None :
91649165                rhs  =  rhs  *  w [:, np .newaxis ]
91659166
@@ -9179,42 +9180,45 @@ def polyfit(
91799180                # Thus a ReprObject => polyfit was called on a DataArray 
91809181                name  =  "" 
91819182
9182-             coeffs  =  DataArray (
9183-                 coeffs  /  scale_da ,
9184-                 dims = [degree_dim ] +  list (stacked_coords .keys ()),
9185-                 coords = {degree_dim : np .arange (order )[::- 1 ], ** stacked_coords },
9186-                 name = name  +  "polyfit_coefficients" ,
9183+             variables [name  +  "polyfit_coefficients" ] =  Variable (
9184+                 data = coeffs  /  scale_da , dims = (degree_dim ,) +  other_dims 
91879185            )
9188-             if  dims_to_stack :
9189-                 coeffs  =  coeffs .unstack (stacked_dim )
9190-             variables [coeffs .name ] =  coeffs 
91919186
91929187            if  full  or  (cov  is  True ):
9193-                 residuals  =  DataArray (
9194-                     residuals  if  dims_to_stack  else  residuals .squeeze (),
9195-                     dims = list (stacked_coords .keys ()),
9196-                     coords = stacked_coords ,
9197-                     name = name  +  "polyfit_residuals" ,
9188+                 variables [name  +  "polyfit_residuals" ] =  Variable (
9189+                     data = residuals  if  var .ndim  >  1  else  residuals .squeeze (),
9190+                     dims = other_dims ,
91989191                )
9199-                 if  dims_to_stack :
9200-                     residuals  =  residuals .unstack (stacked_dim )
9201-                 variables [residuals .name ] =  residuals 
92029192
92039193            if  cov :
92049194                Vbase  =  np .linalg .inv (np .dot (lhs .T , lhs ))
92059195                Vbase  /=  np .outer (scale , scale )
9196+                 if  TYPE_CHECKING :
9197+                     fac : int  |  Variable 
92069198                if  cov  ==  "unscaled" :
92079199                    fac  =  1 
92089200                else :
92099201                    if  x .shape [0 ] <=  order :
92109202                        raise  ValueError (
92119203                            "The number of data points must exceed order to scale the covariance matrix." 
92129204                        )
9213-                     fac  =  residuals  /  (x .shape [0 ] -  order )
9214-                 covariance  =  DataArray (Vbase , dims = ("cov_i" , "cov_j" )) *  fac 
9215-                 variables [name  +  "polyfit_covariance" ] =  covariance 
9205+                     fac  =  variables [name  +  "polyfit_residuals" ] /  (x .shape [0 ] -  order )
9206+                 variables [name  +  "polyfit_covariance" ] =  (
9207+                     Variable (data = Vbase , dims = ("cov_i" , "cov_j" )) *  fac 
9208+                 )
92169209
9217-         return  type (self )(data_vars = variables , attrs = self .attrs .copy ())
9210+         return  type (self )(
9211+             data_vars = variables ,
9212+             coords = {
9213+                 degree_dim : degree_coord_values ,
9214+                 ** {
9215+                     name : coord 
9216+                     for  name , coord  in  other_coords .items ()
9217+                     if  name  in  present_dims 
9218+                 },
9219+             },
9220+             attrs = self .attrs .copy (),
9221+         )
92189222
92199223    def  pad (
92209224        self ,
0 commit comments