
    M/PhU                         d dl Z d dlZd dlmZmZmZmZ d dlZ	d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZ dd	lmZmZ d
diZd Zd Z G d de          Z G d d          ZdS )    N)eighinvnormmatrix_rank)minimize)cache_readonly)Model)summary2)_import_mpl   )rotate_factorspromaxgtolgHz>c                     d}| |t          |          | |t          j        d           |dk    rt          d|z            || t          j        d           d S d S d S )N&Either endog or corr must be provided.zHBoth endog and corr are provided, corr will be used for factor analysis.r   z&n_factor must be larger than 0! %d < 0z&nobs is ignored when endog is provided)
ValueErrorwarningswarn)endogn_factorcorrnobsmsgs        _/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/multivariate/factor.py_check_args_1r      s    
2CT-oo} ? 	@ 	@ 	@ 1}}A"$ % % 	% E->????? --    c                 <   ||k    rt          d||fz            t          j        t          j        t          j        |          dz
                      dk    rt          d          |j        d         |j        d         k    rt          d|j        z            d S )Nz@n_factor cannot be greater than the number of variables! %d > %dr   绽|=z!corr must be a correlation matrixr   z=Correlation matrix corr must be a square (rows %d != cols %d))r   npmaxabsdiagshape)r   r   r   r   k_endogs        r   _check_args_2r%   $   s    ' 2"G,- . . 	. 
vbfRWT]]Q&''((500<===z!}
1%% 026*= > > 	> &%r   c                        e Zd ZdZ	 	 d fd	Zed             Zej        d	             Z	 	 ddZddZ	d Z
d Zd Zd Zd ZddZd Z xZS )FactoraD  
    Factor analysis

    Parameters
    ----------
    endog : array_like
        Variables in columns, observations in rows.  May be `None` if
        `corr` is not `None`.
    n_factor : int
        The number of factors to extract
    corr : array_like
        Directly specify the correlation matrix instead of estimating
        it from `endog`.  If provided, `endog` is not used for the
        factor analysis, it may be used in post-estimation.
    method : str
        The method to extract factors, currently must be either 'pa'
        for principal axis factor analysis or 'ml' for maximum
        likelihood estimation.
    smc : True or False
        Whether or not to apply squared multiple correlations (method='pa')
    endog_names : str
        Names of endogenous variables.  If specified, it will be used
        instead of the column names in endog
    nobs : int
        The number of observations, not used if endog is present. Needs to
        be provided for inference if endog is None.
    missing : 'none', 'drop', or 'raise'
        Missing value handling for endog, default is row-wise deletion 'drop'
        If 'none', no nan checking is done. If 'drop', any observations with
        nans are dropped. If 'raise', an error is raised.


    Notes
    -----
    **Experimental**

    Supported rotations: 'varimax', 'quartimax', 'biquartimax',
    'equamax', 'oblimin', 'parsimax', 'parsimony', 'biquartimin',
    'promax'

    If method='ml', the factors are rotated to satisfy condition IC3
    of Bai and Li (2012).  This means that the scores have covariance
    I, so the model for the covariance matrix is L * L' + diag(U),
    where L are the loadings and U are the uniquenesses.  In addition,
    L' * diag(U)^{-1} L must be diagonal.

    References
    ----------
    .. [*] Hofacker, C. (2004). Exploratory Factor Analysis, Mathematical
       Marketing. http://www.openaccesstexts.org/pdf/Quant_Chapter_11_efa.pdf
    .. [*] J Bai, K Li (2012).  Statistical analysis of factor models of high
       dimension.  Annals of Statistics. https://arxiv.org/pdf/1205.6617.pdf
    Nr   paTdropc	                    t          ||||           |ct                                          |d |           | j        }|j        d         }	|j        d         }t          j        |d          x}| _        nH|5t          j        |          x}| _        | j        j        d         }	d | _        nd}
t          |
          t          |||||	           || _        d | _        d | _        || _        || _        || _        || _        || _        |	| _        |.t%          |d          r|j        }t%          |d          r|j        }|| _        d S )N)exogmissingr   r   )rowvarr   indexcolumns)r   super__init__r   r#   r   corrcoefr   asarrayr   r%   r   loadingscommunalitymethodsmcr   r$   hasattrr.   r/   endog_names)selfr   r   r   r6   r7   r9   r   r,   r$   r   	__class__s              r   r1   zFactor.__init__i   sX    	eXtT222GGUw???JEk!nG;q>D!{5;;;;D499!z$///D49ioa(GDJJ:CS//!eXtT7;;; 		tW%% )"jtY'' +"l&r   c                     | j         | j         S | j        | j        j        S d| j        j        d         dz
  }|dk    rdz  |dz  }|dk    fdt          | j        j        d                   D             S )zNames of endogenous variablesNr   r   
   c                 @    g | ]}d t                    z   dz   |z  S )zvar%0d)str).0ir?   s     r   
<listcomp>z&Factor.endog_names.<locals>.<listcomp>   s>     < < < !3q66)C/14 < < <r   )_endog_namesr   dataynamesr   r#   range)r:   nr?   s     @r   r9   zFactor.endog_names   s     ($$z%y''IOA&*!eeFA"HA !ee< < < <!&tyq'9!:!:< < < <r   c                     |Mt          |          | j        j        d         k    rt          d          t	          j        |          | _        d S d | _        d S )Nr   z?The length of `endog_names` must equal the number of variables.)lenr   r#   r   r   r3   rD   )r:   values     r   r9   zFactor.endog_names   se     5zzTY_Q///  "B C C C "
5 1 1D $Dr   2   :0yE>BFGS   c                     | j                                         }|dk    r|                     ||          S |dk    r|                     ||||          S d| j         z  }t	          |          )a*  
        Estimate factor model parameters.

        Parameters
        ----------
        maxiter : int
            Maximum number of iterations for iterative estimation algorithms
        tol : float
            Stopping criteria (error tolerance) for iterative estimation
            algorithms
        start : array_like
            Starting values, currently only used for ML estimation
        opt_method : str
            Optimization method for ML estimation
        opt : dict-like
            Keyword arguments passed to optimizer, only used for ML estimation
        em_iter : int
            The number of EM iterations before starting gradient optimization,
            only used for ML estimation.

        Returns
        -------
        FactorResults
            Results class instance.
        r(   )maxitertolmlz'Unknown factor extraction approach '%s')r6   lower_fit_pa_fit_mlr   )	r:   rQ   rR   start
opt_methodoptem_iterr6   r   s	            r   fitz
Factor.fit   so    6 ""$$T>><<S<999t^^<<w
C@@@;dkICS//!r   c                    | j                                         }t          |          | _        | j        | j        k    rt          d| j        | j        fz            |dk    rt          d|z            |dk    s|dk    rt          d|z            | j        r(ddt          j        t          |                    z  z
  }n!t          j
        t          |                    }d}t          |          D ]c}t          t          |                    D ]}||         |||f<   t          |d	          \  }}	t          j        |          }
t          j        |          }|ddd
         }||         }|dk                                    }|	dd|f         }	t          j        |          }t          j        || j        g          }t          j        t          j        |d|                             }|	ddd|f         }	|	                    |          }t          j        |d                              d          }t+          |
|z
            |k     r ne|| _        || _        d|z
  | _        || _        t5          |           S )a  
        Extract factors using the iterative principal axis method

        Parameters
        ----------
        maxiter : int
            Maximum number of iterations for communality estimation
        tol : float
            If `norm(communality - last_communality)  < tolerance`,
            estimation stops

        Returns
        -------
        results : FactorResults instance
        z?n_factor must be smaller or equal to the rank of endog! %d > %dr   z(n_max_iter must be larger than 0! %d < 0g{Gz?zEtolerance must be larger than 0 and smaller than 0.01! Got %f insteadr   NU)UPLO   axis)r   copyr   n_compr   r   r7   r   r"   r   onesrJ   rG   r   arrayargsortsumminsqrtdotpowerr   	eigenvalsr5   
uniquenessr4   FactorResults)r:   rQ   rR   Rcrm   rB   jLVc_lastindn_posrH   sLAs                   r   rU   zFactor._fit_pa   s   " INN "!nn=4;&& 2"mT[9: ; ; ; a<<G%' ( ( (!88sTzz 58;= > > > 8 	 AA''AAAA 	w 	 	A 3q66]]  A$!Q$$$$DAqXa[[F*Q--Cddd)C#AUKKMME!!!S&	AI t}-..A2A2((B!!!RaR%A b		AA"""**AFQJ#%% & #a%T"""r   c                     |d| j                  dz  t          j        || j         d          d| j         f          j        fS )Nr   r`   r_   )r$   r   reshapeT)r:   pars     r   _unpackzFactor._unpack  sE    AdlN#Q&
3t|}}-DL/ABBDF 	Fr   c                 f    t          j        t          j        |          |j        j        f          S N)r   concatenaterj   r|   flat)r:   loaduniqs      r   _packzFactor._pack   s#    ~rwt}}dfk:;;;r   c                    t          |          t          j        u r|                     |          \  }}n|d         |d         }}||dddf         z  }t          j        |j        |          }|j        dd|j        d         dz   xx         dz  cc<   t          j        	                    |          \  }}t          j
        t          j        |                    |z   }t          j
        d|z            }	t          j        |j        | j        |dddf         z            }
t          j                            ||
          }
t          j        ||
          }
|	t          j        |
          z  }	||	z    d| j        z  z  S )a  
        Evaluate the log-likelihood function.

        Parameters
        ----------
        par : ndarray or tuple of 2 ndarray's
            The model parameters, either a packed representation of
            the model parameters or a 2-tuple containing a `k_endog x
            n_factor` matrix of factor loadings and a `k_endog` vector
            of uniquenesses.

        Returns
        -------
        float
            The value of the log-likelihood evaluated at par.
        r   r   Nr`   )typer   ndarrayr~   rk   r|   r   r#   linalgslogdetrh   logr   solvetracer$   )r:   r}   r   r   loadulul_ldvwbs              r   loglikezFactor.loglike#  s\   $ 99
""c**JD$$QQ$DtAAAtG}$fTVU##
 	!!39Q<>!"""a'"""	!!#&&2F26$<<  2% F1t8F4649tAAAtG}455IOOC##F5!	RXa[[ Qx1T\>**r   c                    t          |          t          j        u r|                     |          \  }}n|d         |d         }}||dddf         z  }t          j        |j        |          }|j        dd|j        d         dz   xx         dz  cc<   t          j        	                    ||j                  }t          j        ||          }| j
        |z  |dddf         z  }t          j        ||          }	t          j        |j        |          }
t          j        ||
          }dt          j        |          z  d|z  ||j        z                      d          |dz  z  z
  z  }d|t          j        ||          z
  z  }t          j        ||          }t          j        ||j                  }|dt          j        |          z  t          j        |          dt          j        |          z  z
  t          j        |          z   z  z  }|d|	z  z  }|dt          j        ||	          z  z  }|d|z  z  }|dt          j        ||          z  z  }t          j        ||j        j        f           d| j        z  z  S )a  
        Evaluate the score function (first derivative of loglike).

        Parameters
        ----------
        par : ndarray or tuple of 2 ndarray's
            The model parameters, either a packed representation of
            the model parameters or a 2-tuple containing a `k_endog x
            n_factor` matrix of factor loadings and a `k_endog` vector
            of uniquenesses.

        Returns
        -------
        ndarray
            The score function evaluated at par.
        r   r   Nr`   )r   r   r   r~   rk   r|   r   r#   r   r   r   rj   rh   r"   r   r$   )r:   r}   r   r   r   rq   r?   ludcurr   luzdudlhfs                   r   scorezFactor.scoreO  sF   $ 99
""c**JD$$QQ$D tAAAtG}$F465!!	~~A~!#IOOAtv&& fUAi$$qqq$w-/F2tfSUD!!fRoo rwt}}_$!df*)9)9!)<)<tQw)F FGsE***+ F3OOF1ce
aoq|!;bgajj!HII
ac	
asA
ae
asC     BDI///1T\>BBr   c                     |/                      |          \  }}                     ||          }nt          |          dk    r^t          |d                   |d         j        d         k    rd}t	          |                               |d         |d                   }nt	          d           fd} fd}	|t
          }t          |||	||	          }
|
j        st          j	        d
           |
j
        }                     |          \  }}|                                dk     rt          j	        d                                ||          }| _        d|z
   _        | _        |
 _        t%                     S )z7estimate Factor model using Maximum Likelihood
        Nr`   r   r   z,Starting values have incompatible dimensionszInvalid starting valuesc                 0                         |            S r   )r   r}   r:   s    r   nloglikez Factor._fit_ml.<locals>.nloglike  s    LL%%%%r   c                 0                         |            S r   )r   r   s    r   nscorezFactor._fit_ml.<locals>.nscore  s    JJsOO##r   )jacr6   optionszFitting did not converger   z!Some uniquenesses are nearly zero)
_fit_ml_emr   rJ   r#   r   _opt_defaultsr   successr   r   xr~   ri   _rotatern   r5   r4   mle_retvalsro   )r:   rW   rZ   rX   rY   r   r   r   r   r   r   r}   s   `           r   rV   zFactor._fit_ml  s   
 =11JD$JJtT**EEZZ1__58}}aq 111D oo%JJuQxq22EE6777	& 	& 	& 	& 	&	$ 	$ 	$ 	$ 	$ ;CXu& " " "y 	6M4555c\\#&&
d88::M=>>> ||D$''t8T"""r   c                    |t           j                            d          }d|                    | j        | j        f          z  }dt          j        | j                  z  }t          |          D ]}||dddf         z  }t          j        |j	        |          }|j
        dd|j        d         dz   xx         dz  cc<   t           j                            ||j	                  }t          j        |j	        |          }	t          j        ||          }
|t          j        ||
          z
  }||dddf         z  }t          j        |	|          }t          j        || j                  }t          j        |j	        | j                  |z
  }t          j        ||          }|t          j        |j	        |          z  }|j
        dd|j        d         dz   xx         dz  cc<   t          j        | j        |          }t           j                            ||j	                  j	        }t          j        | j                  ||j	        z                      d          z
  }||fS )z1estimate Factor model using EM algorithm
        Nic  g?)sizeg      ?r   r   )r   randomRandomStatestandard_normalr$   r   re   rG   rk   r|   r   r#   r   r   r   r"   rh   )r:   iterrandom_stater   r   kr   r   r   qr   rq   ger?   ar   s                    r   r   zFactor._fit_ml_em  s    90066L\11dm7T1UUURWT\***t 	< 	<A44=(Etvu%%AF>>QWQZ\>"""a'"""	57++Auw%%Aq$ArvdA&AaaagAq!Aq$)$$Auw	**Q.Aq!A"""AF>>QWQZ\>"""a'"""ty!$$A9??1ac**,D749%%(8(8(;(;;DDTzr   c                 <   t           j                            |d          \  }}}||z  }| j        d}n| j        }t          j        |j        ||dddf         z            |z  }t           j                            |          \  }}t          j        ||          }|S )z rotate loadings for MLE
        r   Nr   )r   r   svdr   rk   r|   eig)r:   r   r   sr   r   cmr   s           r   r   zFactor._rotate  s     Y]]4++
a	9DD9DVDFD44=011D8y}}R  1vdAr   )Nr   Nr(   TNNr)   )rL   rM   NrN   NrO   )rL   rM   r   )__name__
__module____qualname____doc__r1   propertyr9   setterr[   rU   r~   r   r   r   rV   r   r   __classcell__)r;   s   @r   r'   r'   3   s=       4 4j BF@F$' $' $' $' $' $'L < < X<  % % % @F"" "" "" ""HE# E# E# E#VF F F< < <*+ *+ *+X3C 3C 3Cl+# +# +#Z$ $ $ $L      r   r'   c                       e Zd ZdZd Zd Zd Zd ZddZdd
Z	d Z
	 	 	 ddZddZddZed             Zedd            Zed             ZdS )ro   a  
    Factor results class

    For result summary, scree/loading plots and factor rotations

    Parameters
    ----------
    factor : Factor
        Fitted Factor class

    Attributes
    ----------
    uniqueness : ndarray
        The uniqueness (variance of uncorrelated errors unique to
        each variable)
    communality : ndarray
        1 - uniqueness
    loadings : ndarray
        Each column is the loading vector for one factor
    loadings_no_rot : ndarray
        Unrotated loadings, not available under maximum likelihood
        analysis.
    eigenvals : ndarray
        The eigenvalues for a factor analysis obtained using
        principal components; not available under ML estimation.
    n_comp : int
        Number of components (factors)
    nbs : int
        Number of observations
    fa_method : str
        The method used to obtain the decomposition, either 'pa' for
        'principal axes' or 'ml' for maximum likelihood.
    df : int
        Degrees of freedom of the factor model.

    Notes
    -----
    Under ML estimation, the default rotation (used for `loadings`) is
    condition IC3 of Bai and Li (2012).  Under this rotation, the
    factor scores are iid and standardized.  If `G` is the canonical
    loadings and `U` is the vector of uniquenesses, then the
    covariance matrix implied by the factor analysis is `GG' +
    diag(U)`.

    Status: experimental, Some refactoring will be necessary when new
        features are added.
    c                    || _         |j        | _        |j        | _        t	          |d          r|j        | _        |j        | _        |j        | _        d | _        |j	        | _
        |j        j        d         | _        |j        | _        || _        t	          |d          r|j        | _        | j        j        \  }}||z
  dz  ||z   z
  dz  | _        |j        | _        t#          j        | j                  | _        d S )Nrm   r   r   r`   )modelr9   r4   loadings_no_rotr8   rm   r5   rn   rotation_methodr6   	fa_methodr#   rd   r   _factorr   dfr   eyerotation_matrix)r:   factorpr   s       r   r1   zFactorResults.__init__  s    
!-%6;'' 	.#-DN!- +#o+A.K	6=)) 	2%1D#)1EA:Q'A- !vdk22r   c                 N    |                                                                  S r   )summary__str__)r:   s    r   r   zFactorResults.__str__3  s    ||~~%%'''r   c                 >   || _         |dvrt          d|z            |dv rt          | j        |          \  | _        }nV|dk    rt          | j        d          \  | _        }n2|dk    rt          | j                  \  | _        }nt          d          || _        dS )	a  
        Apply rotation, inplace modification of this Results instance

        Parameters
        ----------
        method : str
            Rotation to be applied.  Allowed methods are varimax,
            quartimax, biquartimax, equamax, oblimin, parsimax,
            parsimony, biquartimin, promax.

        Returns
        -------
        None : nothing returned, modifications are inplace


        Notes
        -----
        Warning: 'varimax', 'quartimax' and 'oblimin' are verified against R or
        Stata. Some rotation methods such as promax do not produce the same
        results as the R or Stata default functions.

        See Also
        --------
        factor_rotation : subpackage that implements rotation methods
        )	varimax	quartimaxbiquartimaxequamaxobliminparsimax	parsimonybiquartiminr   zUnknown rotation method %s)r   r   r   r   r   r   r   r   	quartiminr   zrotation method not recognizedN)r   r   r   r   r4   r   r   )r:   r6   r|   s      r   rotatezFactorResults.rotate6  s    4  & 3 3 3 9VDEEE > > >-d.BFKKDM11y  -d.B.9 ;  ;DM11x%d&:;;DM11=>>> r   c                 H    | j         }|j                            |          }|S )a8  correlation of factors implied by rotation

        If the rotation is oblique, then the factors are correlated.

        currently not cached

        Returns
        -------
        corr_f : ndarray
            correlation matrix of rotated factors, assuming initial factors are
            orthogonal
        )r   r|   rk   )r:   r|   corr_fs      r   _corr_factorszFactorResults._corr_factorsc  s"      r   bartlettc           	      X   | j         }| j        j        }d| j        z
  }|dk    rft          j                            |j                            ||dddf         z                                          |j        |z            j        }n|                    d          rq| j	        j
        }|                                 }|                    |j                            t          j                            |                              j        }n|dk    rX| j	        j
        }|                                 }|                    t          j                            |                    j        }n|dk    r| j	        j
        }|                                 }t          j                            t          j                            |          |j                            ||dddf         z            z             }|                    |j        |z            j        }nt          d          |S )a8  
        Compute factor scoring coefficient matrix

        The coefficient matrix is not cached.

        Parameters
        ----------
        method : 'bartlett' or 'regression'
            Method to use for factor scoring.
            'regression' can be abbreviated to `reg`

        Returns
        -------
        coeff_matrix : ndarray
            matrix s to compute factors f from a standardized endog ys.
            ``f = ys dot s``

        Notes
        -----
        The `regression` method follows the Stata definition.
        Method bartlett and regression are verified against Stats.
        Two unofficial methods, 'ols' and 'gls', produce similar factor scores
        but are not verified.

        See Also
        --------
        statsmodels.multivariate.factor.FactorResults.factor_scoring
        r   r   Nregolsglsz3method not available, use "bartlett or "regression")r4   r   r|   r5   r   r   r   rk   
startswithr   r   r   pinvr   )r:   r6   rs   r|   unis_matr   r   s           r   factor_score_paramsz!FactorResults.factor_score_paramst  s   : M "$""ZIMM!#''!S4[/":":;;??c	JJLEEu%% 	0:?D''))FJJqswwry}}T':':;;<<>EEu__:?D''))FJJry~~a00113EEu__ :?D''))FIMM")--"7"7!#''!S4[/:R:R"RSSEIIacCi((*EE / 0 0 0r   NTc                    |du r|t          j        |          }n| j        j        d| j        j                            d          }| j        j                            dd          }|| j        j        }n$t          j        |          }nt          d          ||z
  |z  }|                     |          }|                    |          }|S )a  
        factor scoring: compute factors for endog

        If endog was not provided when creating the factor class, then
        a standarized endog needs to be provided here.

        Parameters
        ----------
        method : 'bartlett' or 'regression'
            Method to use for factor scoring.
            'regression' can be abbreviated to `reg`
        transform : bool
            If transform is true and endog is provided, then it will be
            standardized using mean and scale of original data, which has to
            be available in this case.
            If transform is False, then a provided endog will be used unchanged.
            The original endog in the Factor class will
            always be standardized if endog is None, independently of `transform`.

        Returns
        -------
        factor_score : ndarray
            estimated factors using scoring matrix s and standarized endog ys
            ``f = ys dot s``

        Notes
        -----
        Status: transform option is experimental and might change.

        See Also
        --------
        statsmodels.multivariate.factor.FactorResults.factor_score_params
        FNr   r   )ddofrb   zPIf transform is True, then `endog` needs to be available in the Factor instance.)r6   )	r   r3   r   r   meanstdr   r   rk   )r:   r   r6   	transformmr   r   factorss           r   factor_scoringzFactorResults.factor_scoring  s    F %"3Ju%%EE z+J$))!,,J$((aa(88= J,EEJu--EE  "K L L L QY!OE(((77))E""r   c                 *   t          j                    }|                    d           t          j        | j        d t          | j        j        d                   D             | j                  }t          | d          rOt          j        | j
        g| j        dg          }|                    ddi           |                    |           t          j        | j        g| j        dg          }|                    ddi           |                    ddi           |                    |           |                    ddi           |                    dd	i           |                    |           |                    ddi           | j        |t          j        | j        d t          | j        j        d                   D             | j                  }|                    dd| j        z  i           |                    |           |S )SummaryzFactor analysis resultsc                     g | ]}d |z  S z	factor %d rA   rB   s     r   rC   z)FactorResults.summary.<locals>.<listcomp>  s3     D D D !A& D D Dr   r   r/   r.   rm    EigenvaluesCommunalityzPre-rotated loadingsNc                     g | ]}d |z  S r   r   r   s     r   rC   z)FactorResults.summary.<locals>.<listcomp>  3     A A A %* A A Ar   z%s rotated loadings)r
   r   	add_titlepd	DataFramer   rG   r#   r9   r8   rm   add_dictadd_dfr5   r   r4   )r:   summr   rm   r5   r4   s         r   r   zFactorResults.summary  s6   !!0111, D D#D$8$>q$ABBD D D"	
 
 
 4%% 	# $*:2$H H HIMM2}-...KK	"""lD$4#5+/+;B4I I Ir2hr=)***K   r2hr12333O$$$r2h+|A A"'(;A(>"?"?A A A&	  H MM248LMNOOOKK!!!r   display333333?yellowc                 h   t          j        | j        d t          | j        j        d                   D             | j                  }|dvrd}t          |          |dk    r|S |du r|                                }	t          |	          }
t          j
        |	j                                      d          }||	d<   t          j
        |j        t          j        |
          |f                   |	d	<   |	                    dd	gdd
gd           |	                    dd	gd          }|dk    rd}dk    rKfd}	 |j                            |          }n*# t$          $ r |j                            |          }Y nw xY w|du r%fd}||j        }|                    |d          }|!||j        }|                    d|z             ||S |S |dk    rV|}||                    |          }|                    t0                    }dk    rd||
                                k     <   |S dS )a|	  get loadings matrix as DataFrame or pandas Styler

        Parameters
        ----------
        style : 'display' (default), 'raw' or 'strings'
            Style to use for display

            * 'raw' returns just a DataFrame of the loadings matrix, no options are
               applied
            * 'display' add sorting and styling as defined by other keywords
            * 'strings' returns a DataFrame with string elements with optional sorting
               and suppressing small loading coefficients.

        sort_ : bool
            If True, then the rows of the DataFrame is sorted by contribution of each
            factor. applies if style is either 'display' or 'strings'
        threshold : float
            If the threshold is larger than zero, then loading coefficients are
            either colored white (if style is 'display') or replace by empty
            string (if style is 'strings').
        highlight_max : bool
            This add a background color to the largest coefficient in each row.
        color_max : html color
            default is 'yellow'. color for background of row maximum
        decimals : None or int
            If None, then pandas default precision applies. Otherwise values are
            rounded to the specified decimals. If style is 'display', then the
            underlying dataframe is not changed. If style is 'strings', then
            values are rounded before conversion to strings.

        Returns
        -------
        loadings : DataFrame or pandas Styler instance
            The return is a pandas Styler instance, if style is 'display' and
            at least one of highlight_max, threshold or decimals is applied.
            Otherwise, the returned loadings is a DataFrame.

        Examples
        --------
        >>> mod = Factor(df, 3, smc=True)
        >>> res = mod.fit()
        >>> res.get_loadings_frame(style='display', decimals=3, threshold=0.2)

        To get a sorted DataFrame, all styling options need to be turned off:

        >>> df_sorted = res.get_loadings_frame(style='display',
        ...             highlight_max=False, decimals=None, threshold=0)

        Options except for highlighting are available for plain test or Latex
        usage:

        >>> lds = res_u.get_loadings_frame(style='strings', decimals=3,
        ...                                threshold=0.3)
        >>> print(lds.to_latex())
        c                     g | ]}d |z  S r   r   r   s     r   rC   z4FactorResults.get_loadings_frame.<locals>.<listcomp>H  r   r   r   r   )rawr  stringsz2style has to be one of 'raw', 'display', 'strings'r  ThighlargestF)by	ascendinginplacera   r  Nr   c                 F    t          j        |           k     rdnd}d|z  S )z
                    Takes a scalar and returns a string with
                    the css property `'color: white'` for small values, black otherwise.

                    takes threshold from outer scope
                    whiteblackz	color: %s)r   r!   )valcolor	thresholds     r   color_white_smallz;FactorResults.get_loadings_frame.<locals>.color_white_smalla  s+     (*vc{{Y'>'>GGGE&..r   c                 x    t          j        |           } | |                                 k    }fd|D             S )zS
                    highlight the maximum in a Series yellow.
                    c                 "    g | ]}|rd z   ndS )zbackground-color: r   r   )rA   r   	color_maxs     r   rC   zKFactorResults.get_loadings_frame.<locals>.highlight_max.<locals>.<listcomp>w  s)    YYYQqH0);;bYYYr   )r   r!   r    )r   is_maxr  s     r   highlight_maxz7FactorResults.get_loadings_frame.<locals>.highlight_maxq  s>     q		A!%%''\FYYYYRXYYYYr   z{:.%sf}r  r   )r  r  r4   rG   r#   r9   r   rc   rJ   r   r!   valuesargmaxarangesort_valuesr)   stylemapAttributeErrorapplymapapplyformatroundastyper@   )r:   r#  sort_r  r  r  decimalsloadings_dfr   loadings_df2n_fr  styr  r   s      ` `         r   get_loadings_framez FactorResults.get_loadings_frame  s   v lA A"'(;A(>"?"?A A A&	   555FCS//!E>> D==&++--Ll##C6,-..55a88D#'L &(f[-?	#PT@T-U&V&VL#$$(;e}^b$ccc&++VY,?a+HHKIC1}}/ / / / /H%+//0ABBCC% H H H%+445FGGCCCH $$Z Z Z Z Z ;%+CiiAi66#;%+C

9x/000{""
IB#XXh''3B1}}46;??$$y01I s   ?E $F Fc                 X    t                       ddlm}  || j        | j        |          S )a  
        Plot of the ordered eigenvalues and variance explained for the loadings

        Parameters
        ----------
        ncomp : int, optional
            Number of loadings to include in the plot.  If None, will
            included the same as the number of maximum possible loadings

        Returns
        -------
        Figure
            Handle to the figure.
        r   )
plot_scree)r   plotsr3  rm   rd   )r:   ncompr3  s      r   r3  zFactorResults.plot_scree  s7     	%%%%%%z$.$+u===r   Fc                     t                       ddlm} | j        d}|r| j        n| j        }|rd}n
d| j        z  }| j        | j        z  dz  } ||||| j        |          S )	aZ  
        Plot factor loadings in 2-d plots

        Parameters
        ----------
        loading_pairs : None or a list of tuples
            Specify plots. Each tuple (i, j) represent one figure, i and j is
            the loading number for x-axis and y-axis, respectively. If `None`,
            all combinations of the loadings will be plotted.
        plot_prerotated : True or False
            If True, the loadings before rotation applied will be plotted. If
            False, rotated loadings will be plotted.

        Returns
        -------
        figs : a list of figure handles
        r   )plot_loadingsNTzPrerotated Factor Patternz%s Rotated Factor Patternd   )loading_pairstitle	row_namespercent_variance)	r   r4  r7  r   r   r4   rm   rd   r9   )r:   r9  plot_prerotatedr7  r4   r:  var_explaineds          r   r7  zFactorResults.plot_loadings  s    $ 	(((((('"O+:M4'' 	I/EE/43GHE4s:}X]#(D4D.;= = = 	=r   c                     t          j        | j        | j        j                  }|j        dd|j        d         dz   xx         | j        z  cc<   |S )z7
        Returns the fitted covariance matrix.
        Nr   r   )r   rk   r4   r|   r   r#   rn   )r:   rq   s     r   
fitted_covzFactorResults.fitted_cov  sP     F4=$-/22	~~A~$/1r   r   c                     | j                                         dk    rd}t          |          | j        d}t          |          | j        dz  d|z   z  }t          j        || j        z            S )a  
        The standard errors of the uniquenesses.

        Parameters
        ----------
        kurt : float
            Excess kurtosis

        Notes
        -----
        If excess kurtosis is known, provide as `kurt`.  Standard
        errors are only available if the model was fit using maximum
        likelihood.  If `endog` is not provided, `nobs` must be
        provided to obtain standard errors.

        These are asymptotic standard errors.  See Bai and Li (2012)
        for conditions under which the standard errors are valid.

        The standard errors are only applicable to the original,
        unrotated maximum likelihood solution.
        rS   2Standard errors only available under ML estimationN+nobs is required to obtain standard errors.r`   )r   rT   r   r   rn   r   rj   )r:   kurtr   r   s       r   uniq_stderrzFactorResults.uniq_stderr  sr    0 >!!T))FCS//!9?CS//!OQ!d(+wq49}%%%r   c                 >   | j                                         dk    rd}t          |          | j        d}t          |          t	          j        | j        t	          j        | j        j	        d                             }t	          j
        || j        z            S )a  
        The standard errors of the loadings.

        Standard errors are only available if the model was fit using
        maximum likelihood.  If `endog` is not provided, `nobs` must be
        provided to obtain standard errors.

        These are asymptotic standard errors.  See Bai and Li (2012)
        for conditions under which the standard errors are valid.

        The standard errors are only applicable to the original,
        unrotated maximum likelihood solution.
        rS   rB  NrC  r   )r   rT   r   r   r   outerrn   re   r4   r#   rj   )r:   r   r   s      r   load_stderrzFactorResults.load_stderr  s      >!!T))FCS//!9?CS//!HT_bgdm.A!.D&E&EFFwq49}%%%r   )r   )Nr   T)r  Tr  Tr	  Nr   )NF)r   )r   r   r   r   r1   r   r   r   r   r   r   r1  r3  r7  r   r@  rE  rH  r   r   r   ro   ro     s<       . .^3 3 32( ( (+! +! +!Z  "8 8 8 8t7 7 7 7r" " "H IL9A$(E E E EN> > > >& =  =  =  =D   ^  &  &  & ^ &D & & ^& & &r   ro   )r   numpyr   numpy.linalgr   r   r   r   pandasr  scipy.optimizer   statsmodels.tools.decoratorsr   statsmodels.base.modelr	   statsmodels.iolibr
   statsmodels.graphics.utilsr   factor_rotationr   r   r   r   r%   r'   ro   r   r   r   <module>rR     sW        5 5 5 5 5 5 5 5 5 5 5 5     # # # # # # 7 7 7 7 7 7 ( ( ( ( ( ( & & & & & & 2 2 2 2 2 2 3 3 3 3 3 3 3 3 @ @ @"> > >t t t t tU t t tnc& c& c& c& c& c& c& c& c& c&r   