<commit_before>"""
CP decomposition by classic alternating least squares (ALS).
"""

import numpy as np
import scipy as sci

from tensortools.operations import unfold, khatri_rao
from tensortools.tensors import Ktensor
from tensortools.data.random_tensor import randn_tensor
from tensortools.optimize import FitResult

from functools import reduce


def cp_als(X, rank=None, random_state=None, **options):
    """
    CP Decomposition using the Alternating Least Squares Method.
    
    Given a tensor X, the best rank-R CP model is estimated.

    
    Parameters
    ----------
    X : array_like
        Tens
    
    rank : int
        `rank` denotes the number of components to compute.     
        
    options : dict, specifying fitting options.

        tol : float, optional (default `tol=1E-5`)
            Stopping tolerance for reconstruction error.
            
        maxiter : int, optional (default `maxiter=500`)
            Maximum number of iterations to perform before exiting.

        trace : bool `{'True', 'False'}`, optional (default `trace=True`)
            Display progress.


    Returns
    -------
    P : ktensor
        Tensor stored in decomposed form as a Kruskal operator.

    
    Notes
    -----    
    
    
    References
    ----------
    <NAME>. & <NAME>.
    "Tensor Decompositions and Applications." 
    SIAM Rev. 51 (2009): 455-500
    http://epubs.siam.org/doi/pdf/10.1137/07070111X

    <NAME> & <NAME> & <NAME>. 
    "Tensor decompositions, alternating least squares and other tales."
    Journal of chemometrics 23 (2009): 393-405.
    http://onlinelibrary.wiley.com/doi/10.1002/cem.1236/abstract
    
    
    Examples
    --------    

    

    """

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Error catching
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
    if X.ndim < 3:
        raise ValueError("Array with X.ndim > 2 expected.")

    if rank is None:<commit_msg>update of docstrings<commit_after>"""
CP decomposition by classic alternating least squares (ALS).
"""

import numpy as np
import scipy as sci

from tensortools.operations import unfold, khatri_rao
from tensortools.tensors import Ktensor
from tensortools.data.random_tensor import randn_tensor
from tensortools.optimize import FitResult

from functools import reduce


def cp_als(X, rank=None, random_state=None, **options):
    """
    The CP (CANDECOMP/PARAFAC) method  is a decomposition for higher order 
    arrays (tensors). The CP decomposition can be seen as a generalziation 
    of PCA, yet there are some important conceptutal differences: (a) the CP
    decomposition allows to extract pure spectra from multi-way spectral data;
    (b) the data do not need to be unfolded. Hence, the resulting
    factors are easier to interpret and more rebust to noise. 
        

    When `X` is a N-way array, it is factorized as ``[U_1, ...., U_N]``, 
    where `U_i` are 2D arrays of rank R.

    
    Parameters
    ----------
    X : (I_1, ..., I_N) array_like
        A real array with ``X.ndim >= 3``.
    
    rank : integer
        The `rank` sets the number of components to be computed.     
        
    options : dict, specifying fitting options.

        tol : float, optional (default ``tol=1E-5``)
            Stopping tolerance for reconstruction error.
            
        maxiter : integer, optional (default ``maxiter = 500``)
            Maximum number of iterations to perform before exiting.

        trace : bool ``{'True', 'False'}``, optional (default ``trace=True``)
            Display progress.


    Returns
    -------
    P : FitResult object
        Object which returens the fited results. It provides the factor matrices
        in form of a Kruskal operator. 

    
    Notes
    -----    
    This implemenation is using the Alternating Least Squares Method.
   
    
    References
    ----------
    <NAME>. & <NAME>.
    "Tensor Decompositions and Applications." 
    SIAM Rev. 51 (2009): 455-500
    http://epubs.siam.org/doi/pdf/10.1137/07070111X

    <NAME> & <NAME> & <NAME>. 
    "Tensor decompositions, alternating least squares and other tales."
    Journal of chemometrics 23 (2009): 393-405.
    http://onlinelibrary.wiley.com/doi/10.1002/cem.1236/abstract
    
    
    Examples
    --------    

    

    """

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Error catching
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
    if X.ndim < 3:
        raise ValueError("Array with X.ndim > 2 expected.")

    if rank is None:
{'fraction_non_alphanumeric': 0.15764604810996563, 'fraction_numerical': 0.024484536082474227, 'mean_word_length': 2.414222873900293, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4015976', 'n_tokens_mistral': 1431, 'n_tokens_neox': 1256, 'n_words': 441}