src/stats/ss/regression/linear.hpp
/*
         * Computes the least-square fitting by SVD decomposition
         */
Computes the least-square fitting by SVD decomposition
Computes the least - square fitting by SVD decomposition
inline LinearResults lSVD(const Matrix &Y, const Matrix &X)
        {
            const auto n = Y.rows();
            const auto p = X.cols();
            Eigen::JacobiSVD<Eigen::MatrixXd> svd(X, Eigen::ComputeThinU | Eigen::ComputeThinV);
            const auto &U = svd.matrixU();
            const auto &V = svd.matrixV();
            Matrix D = Eigen::MatrixXd::Constant(X.cols(), X.cols(), 0.0);
            for (auto i = 0; i < svd.singularValues().size(); i++)
            {
                D(i,i) = svd.singularValues()[i];
            }
            const Matrix B = V * D.inverse() * U.transpose() * Y;
            const Matrix RSE = (Y.transpose() * Y) - (B.transpose() * X.transpose() * Y);
            const auto errorDF = (n - p);
            const auto MSE = RSE(0,0) / errorDF;
            const Matrix EV = MSE * (V * (D.inverse() * D.inverse()) * V.transpose());
            assert(B.rows() == EV.rows());
            LinearResults r;
            for (auto i = 0; i < B.rows(); i++)
            {
                Coefficient c;
                c.est = B(i, 0);
                c.se  = sqrt(EV(i, i));
                c.test = c.se ? c.est / c.se : NAN;
                c.df = errorDF;
                c.p = !isinf(c.test) && !isnan(c.test) ? Internal::pval(c.test, Internal::pt(c.test, errorDF), TwoSided) : P(NAN);
                c.upper = !isnan(c.test) ? c.est + c.test * Internal::qt(0.95, errorDF) : NAN;
                c.lower = !isnan(c.test) ? c.est - c.test * Internal::qt(0.95, errorDF) : NAN;
                r.coeffs.push_back(c);
            }
            const Matrix E = Y - X * B;
            r.error.df = errorDF;
            r.error.ss = (E.transpose() * E)(0, 0);
            r.error.ms = r.error.df ? r.error.ss / r.error.df : NAN;
            Real sum = 0.0;
            for (auto i = 0; i < Y.col(0).size(); i++)
            {
                sum += (Y.col(0))(i);
            }
            const auto mean = sum / Y.col(0).size();
            #define DEFINE_EY() Matrix EY(Y.rows(), 1); EY.setConstant(mean);
            DEFINE_EY();
            const Matrix M = (X * B) - EY;
            r.model.df = p - 1;
            r.model.ss = (M.transpose() * M)(0, 0);
            r.model.ms = r.model.ss / r.model.df;
            r.total.df = r.model.df + r.error.df;
            r.total.ss = r.model.ss + r.error.ss;
            r.total.ms = r.total.ss / r.total.df;
            r.f = r.error.ms ? r.model.ms / r.error.ms : NAN;
            r.p = (!isinf(r.f) && !isnan(r.f) && r.error.df) ? P(1.0 - Internal::pf(r.f, r.model.df, r.error.df)) : P(NAN);
            r.r2  = r.model.ss / r.total.ss;
            r.ar2 = errorDF ? (1 - (r.error.ss / errorDF) / (r.total.ss / (n - 1))) : NAN;
            if (!r.error.df)
            {
                r.error.ss = NAN;
            }
            r.AIC = n * std::log(r.error.ss/n) + 2.0 * r.coeffs.size();
            r.BIC = n * std::log(r.error.ss/n) + std::log(n) * r.coeffs.size();
            return r;
        }
inline LinearResults lSVD ( const Matrix & Y , const Matrix & X ) { const auto n = Y . rows ( ) ; const auto p = X . cols ( ) ; Eigen :: JacobiSVD < Eigen :: MatrixXd > svd ( X , Eigen :: ComputeThinU | Eigen :: ComputeThinV ) ; const auto & U = svd . matrixU ( ) ; const auto & V = svd . matrixV ( ) ; Matrix D = Eigen :: MatrixXd :: Constant ( X . cols ( ) , X . cols ( ) , 0.0 ) ; for ( auto i = 0 ; i < svd . singularValues ( ) . size ( ) ; i ++ ) { D ( i , i ) = svd . singularValues ( ) [ i ] ; } const Matrix B = V * D . inverse ( ) * U . transpose ( ) * Y ; const Matrix RSE = ( Y . transpose ( ) * Y ) - ( B . transpose ( ) * X . transpose ( ) * Y ) ; const auto errorDF = ( n - p ) ; const auto MSE = RSE ( 0 , 0 ) / errorDF ; const Matrix EV = MSE * ( V * ( D . inverse ( ) * D . inverse ( ) ) * V . transpose ( ) ) ; assert ( B . rows ( ) == EV . rows ( ) ) ; LinearResults r ; for ( auto i = 0 ; i < B . rows ( ) ; i ++ ) { Coefficient c ; c . est = B ( i , 0 ) ; c . se = sqrt ( EV ( i , i ) ) ; c . test = c . se ? c . est / c . se : NAN ; c . df = errorDF ; c . p = ! isinf ( c . test ) && ! isnan ( c . test ) ? Internal :: pval ( c . test , Internal :: pt ( c . test , errorDF ) , TwoSided ) : P ( NAN ) ; c . upper = ! isnan ( c . test ) ? c . est + c . test * Internal :: qt ( 0.95 , errorDF ) : NAN ; c . lower = ! isnan ( c . test ) ? c . est - c . test * Internal :: qt ( 0.95 , errorDF ) : NAN ; r . coeffs . push_back ( c ) ; } const Matrix E = Y - X * B ; r . error . df = errorDF ; r . error . ss = ( E . transpose ( ) * E ) ( 0 , 0 ) ; r . error . ms = r . error . df ? r . error . ss / r . error . df : NAN ; Real sum = 0.0 ; for ( auto i = 0 ; i < Y . col ( 0 ) . size ( ) ; i ++ ) { sum += ( Y . col ( 0 ) ) ( i ) ; } const auto mean = sum / Y . col ( 0 ) . size ( ) ; #define DEFINE_EY ( )  Matrix EY(Y.rows(), 1); EY.setConstant(mean);
 DEFINE_EY ( ) ; const Matrix M = ( X * B ) - EY ; r . model . df = p - 1 ; r . model . ss = ( M . transpose ( ) * M ) ( 0 , 0 ) ; r . model . ms = r . model . ss / r . model . df ; r . total . df = r . model . df + r . error . df ; r . total . ss = r . model . ss + r . error . ss ; r . total . ms = r . total . ss / r . total . df ; r . f = r . error . ms ? r . model . ms / r . error . ms : NAN ; r . p = ( ! isinf ( r . f ) && ! isnan ( r . f ) && r . error . df ) ? P ( 1.0 - Internal :: pf ( r . f , r . model . df , r . error . df ) ) : P ( NAN ) ; r . r2 = r . model . ss / r . total . ss ; r . ar2 = errorDF ? ( 1 - ( r . error . ss / errorDF ) / ( r . total . ss / ( n - 1 ) ) ) : NAN ; if ( ! r . error . df ) { r . error . ss = NAN ; } r . AIC = n * std :: log ( r . error . ss / n ) + 2.0 * r . coeffs . size ( ) ; r . BIC = n * std :: log ( r . error . ss / n ) + std :: log ( n ) * r . coeffs . size ( ) ; return r ; }
Computes the least-square fitting by SVD decomposition
Computes the least - square fitting by SVD decomposition
// The size of the sample
 // Number of coefficients (including the constant coefficient)
 /*
             * Construct the diagonal matrix for singular values
             */ // Calculate for the coefficients
 // Degree of freedom for MSE
 // Unbiased estimate for the variance
 // Compute for the variance of the estimators
 /*
                 * Under the null hypothesis, each coefficent has a value of zero. The coefficents
                 * are normally distributed while the population coefficient is unknown.
                 */ // Each coefficient inherits the same degree of freedom from MSE
 // Compute p-value for the coefficient
 // Residuals of the the model
 /*
             * Computes for the SSM
             */ /*
             * Computes for total sum of squares
             */ /*
             * Note that we can't set it earlier because we'd need it for computing r2
             */