127template <
typename IteratorX,
typename IteratorY>
129 IteratorY y_first, IteratorY y_last)
135 throw std::invalid_argument(
"statcpp::simple_linear_regression: x and y must have same length");
138 throw std::invalid_argument(
"statcpp::simple_linear_regression: need at least 3 observations");
142 double n_d =
static_cast<double>(n);
149 double sxx = 0.0, syy = 0.0, sxy = 0.0;
152 for (; it_x != x_last; ++it_x, ++it_y) {
153 double dx =
static_cast<double>(*it_x) - mean_x;
154 double dy =
static_cast<double>(*it_y) - mean_y;
161 throw std::invalid_argument(
"statcpp::simple_linear_regression: zero variance in x");
165 double slope = sxy / sxx;
166 double intercept = mean_y - slope * mean_x;
169 double ss_total = syy;
170 double ss_regression = slope * sxy;
171 double ss_residual = std::max(0.0, ss_total - ss_regression);
173 if (ss_total == 0.0) {
174 throw std::invalid_argument(
"statcpp::simple_linear_regression: zero variance in y (constant response)");
179 double df_res = n_d - 2.0;
180 double mse = ss_residual / df_res;
181 double residual_se = std::sqrt(
mse);
184 double slope_se = residual_se / std::sqrt(sxx);
185 double intercept_se = residual_se * std::sqrt(1.0 / n_d + mean_x * mean_x / sxx);
188 double slope_t = slope / slope_se;
189 double intercept_t = intercept / intercept_se;
190 double slope_p = 2.0 * (1.0 -
t_cdf(std::abs(slope_t), df_res));
191 double intercept_p = 2.0 * (1.0 -
t_cdf(std::abs(intercept_t), df_res));
194 double r_squared = ss_regression / ss_total;
195 double adj_r_squared = 1.0 - (1.0 -
r_squared) * (n_d - 1.0) / df_res;
198 double f_statistic = (ss_regression / df_reg) /
mse;
199 double f_p_value = 1.0 -
f_cdf(f_statistic, df_reg, df_res);
203 intercept_se, slope_se,
204 intercept_t, slope_t,
205 intercept_p, slope_p,
208 f_statistic, f_p_value,
210 ss_total, ss_regression, ss_residual
232 const char* func_name)
235 std::string msg =
"statcpp::";
237 msg +=
": empty data";
238 throw std::invalid_argument(msg);
241 std::size_t p = data[0].size();
243 std::string msg =
"statcpp::";
245 msg +=
": first row is empty (0 columns)";
246 throw std::invalid_argument(msg);
250 for (std::size_t i = 1; i < data.size(); ++i) {
251 if (data[i].size() != p) {
252 std::string msg =
"statcpp::";
254 msg +=
": inconsistent row dimensions (row 0 has ";
255 msg += std::to_string(p);
256 msg +=
" columns, but row ";
257 msg += std::to_string(i);
259 msg += std::to_string(data[i].size());
261 throw std::invalid_argument(msg);
282 std::size_t n = X.size();
283 std::size_t p = X[0].size();
287 bool all_ones =
true;
288 for (std::size_t i = 0; i < n; ++i) {
289 if (X[i].size() == 0 || std::abs(X[i][0] - 1.0) > 1e-10) {
296 std::string msg =
"statcpp::";
298 msg +=
": X should not contain intercept column (all 1s in first column detected). ";
299 msg +=
"The intercept is added automatically.";
300 throw std::invalid_argument(msg);
314inline std::vector<std::vector<double>>
transpose(
const std::vector<std::vector<double>>& A)
316 if (A.empty())
return {};
319 std::size_t rows = A.size();
320 std::size_t cols = A[0].size();
321 for (std::size_t i = 1; i < rows; ++i) {
322 if (A[i].size() != cols) {
323 throw std::invalid_argument(
"statcpp::detail::transpose: inconsistent row dimensions");
327 std::vector<std::vector<double>> result(cols, std::vector<double>(rows));
328 for (std::size_t i = 0; i < rows; ++i) {
329 for (std::size_t j = 0; j < cols; ++j) {
330 result[j][i] = A[i][j];
346 const std::vector<std::vector<double>>& A,
347 const std::vector<std::vector<double>>& B)
349 if (A.empty() || B.empty())
return {};
350 std::size_t m = A.size();
351 std::size_t n = A[0].size();
352 std::size_t p = B[0].size();
355 throw std::invalid_argument(
"statcpp::detail::matrix_multiply: incompatible dimensions");
359 for (std::size_t i = 0; i < m; ++i) {
360 if (A[i].size() != n) {
361 throw std::invalid_argument(
"statcpp::detail::matrix_multiply: matrix A has inconsistent row dimensions");
364 for (std::size_t k = 0; k < n; ++k) {
365 if (B[k].size() != p) {
366 throw std::invalid_argument(
"statcpp::detail::matrix_multiply: matrix B has inconsistent row dimensions");
370 std::vector<std::vector<double>> result(m, std::vector<double>(p, 0.0));
371 for (std::size_t i = 0; i < m; ++i) {
372 for (std::size_t j = 0; j < p; ++j) {
373 for (std::size_t k = 0; k < n; ++k) {
374 result[i][j] += A[i][k] * B[k][j];
390 const std::vector<std::vector<double>>& A,
391 const std::vector<double>& v)
393 if (A.empty())
return {};
394 std::size_t m = A.size();
395 std::size_t n = A[0].size();
398 throw std::invalid_argument(
"statcpp::detail::matrix_vector_multiply: incompatible dimensions");
401 std::vector<double> result(m, 0.0);
402 for (std::size_t i = 0; i < m; ++i) {
403 for (std::size_t j = 0; j < n; ++j) {
404 result[i] += A[i][j] * v[j];
419inline std::vector<std::vector<double>>
cholesky(
const std::vector<std::vector<double>>& A)
421 std::size_t n = A.size();
422 std::vector<std::vector<double>> L(n, std::vector<double>(n, 0.0));
424 for (std::size_t i = 0; i < n; ++i) {
425 for (std::size_t j = 0; j <= i; ++j) {
427 for (std::size_t k = 0; k < j; ++k) {
428 sum += L[i][k] * L[j][k];
431 double val = A[i][i] -
sum;
433 throw std::runtime_error(
"statcpp::detail::cholesky: matrix is not positive definite");
435 L[i][j] = std::sqrt(val);
437 L[i][j] = (A[i][j] -
sum) / L[j][j];
455 const std::vector<std::vector<double>>& L,
456 const std::vector<double>& b)
458 std::size_t n = L.size();
461 std::vector<double> y(n);
462 for (std::size_t i = 0; i < n; ++i) {
464 for (std::size_t j = 0; j < i; ++j) {
465 sum += L[i][j] * y[j];
467 y[i] = (b[i] -
sum) / L[i][i];
471 std::vector<double> x(n);
472 for (std::size_t i = n; i > 0; --i) {
473 std::size_t idx = i - 1;
475 for (std::size_t j = idx + 1; j < n; ++j) {
476 sum += L[j][idx] * x[j];
478 x[idx] = (y[idx] -
sum) / L[idx][idx];
490 const std::vector<std::vector<double>>& L)
492 std::size_t n = L.size();
493 std::vector<std::vector<double>> inv(n, std::vector<double>(n, 0.0));
496 for (std::size_t j = 0; j < n; ++j) {
497 std::vector<double> e(n, 0.0);
500 for (std::size_t i = 0; i < n; ++i) {
524 const std::vector<std::vector<double>>& X,
525 const std::vector<double>& y)
530 std::size_t n = X.size();
532 throw std::invalid_argument(
"statcpp::multiple_linear_regression: empty data");
535 throw std::invalid_argument(
"statcpp::multiple_linear_regression: X and y must have same number of observations");
538 std::size_t p = X[0].size();
539 for (
const auto& row : X) {
540 if (row.size() != p) {
541 throw std::invalid_argument(
"statcpp::multiple_linear_regression: inconsistent number of predictors");
545 std::size_t p_full = p + 1;
547 throw std::invalid_argument(
"statcpp::multiple_linear_regression: need more observations than predictors");
550 double n_d =
static_cast<double>(n);
553 std::vector<std::vector<double>> X_design(n, std::vector<double>(p_full));
554 for (std::size_t i = 0; i < n; ++i) {
555 X_design[i][0] = 1.0;
556 for (std::size_t j = 0; j < p; ++j) {
557 X_design[i][j + 1] = X[i][j];
576 std::vector<double> y_hat(n);
577 std::vector<double> residuals(n);
580 double ss_total = 0.0;
581 double ss_residual = 0.0;
583 for (std::size_t i = 0; i < n; ++i) {
585 for (std::size_t j = 0; j < p_full; ++j) {
586 pred += X_design[i][j] * coefficients[j];
589 residuals[i] = y[i] - pred;
591 ss_total += (y[i] - mean_y) * (y[i] - mean_y);
592 ss_residual += residuals[i] * residuals[i];
595 double ss_regression = ss_total - ss_residual;
597 if (ss_total == 0.0) {
598 throw std::invalid_argument(
"statcpp::multiple_linear_regression: zero variance in y (constant response)");
602 double df_reg =
static_cast<double>(p);
603 double df_res = n_d -
static_cast<double>(p_full);
606 double mse = ss_residual / df_res;
607 double residual_se = std::sqrt(
mse);
610 std::vector<double> coefficient_se(p_full);
611 std::vector<double> t_statistics(p_full);
612 std::vector<double> p_values(p_full);
614 for (std::size_t j = 0; j < p_full; ++j) {
615 coefficient_se[j] = std::sqrt(
mse * XtX_inv[j][j]);
616 t_statistics[j] = coefficients[j] / coefficient_se[j];
617 p_values[j] = 2.0 * (1.0 -
t_cdf(std::abs(t_statistics[j]), df_res));
621 double r_squared = ss_regression / ss_total;
622 double adj_r_squared = 1.0 - (1.0 -
r_squared) * (n_d - 1.0) / df_res;
625 double f_statistic = (ss_regression / df_reg) /
mse;
626 double f_p_value = 1.0 -
f_cdf(f_statistic, df_reg, df_res);
629 coefficients, coefficient_se, t_statistics, p_values,
632 f_statistic, f_p_value,
634 ss_total, ss_regression, ss_residual
665 throw std::invalid_argument(
"statcpp::predict: x dimension mismatch");
669 for (std::size_t i = 0; i < x.size(); ++i) {
694template <
typename IteratorX>
697 IteratorX x_first, IteratorX x_last,
699 double confidence = 0.95)
701 if (confidence <= 0.0 || confidence >= 1.0) {
702 throw std::invalid_argument(
"statcpp::prediction_interval_simple: confidence must be in (0, 1)");
706 double n_d =
static_cast<double>(n);
711 for (
auto it = x_first; it != x_last; ++it) {
712 double dx =
static_cast<double>(*it) - mean_x;
716 double y_hat =
predict(model, x_new);
719 double dx_new = x_new - mean_x;
720 double se_pred = model.
residual_se * std::sqrt(1.0 + 1.0 / n_d + dx_new * dx_new / sxx);
723 double margin = t_crit * se_pred;
725 return {y_hat, y_hat - margin, y_hat + margin, se_pred};
743template <
typename IteratorX>
746 IteratorX x_first, IteratorX x_last,
748 double confidence = 0.95)
750 if (confidence <= 0.0 || confidence >= 1.0) {
751 throw std::invalid_argument(
"statcpp::confidence_interval_mean: confidence must be in (0, 1)");
755 double n_d =
static_cast<double>(n);
760 for (
auto it = x_first; it != x_last; ++it) {
761 double dx =
static_cast<double>(*it) - mean_x;
765 double y_hat =
predict(model, x_new);
768 double dx_new = x_new - mean_x;
769 double se_mean = model.
residual_se * std::sqrt(1.0 / n_d + dx_new * dx_new / sxx);
772 double margin = t_crit * se_mean;
774 return {y_hat, y_hat - margin, y_hat + margin, se_mean};
797template <
typename IteratorX,
typename IteratorY>
800 IteratorX x_first, IteratorX x_last,
801 IteratorY y_first, IteratorY y_last)
805 throw std::invalid_argument(
"statcpp::compute_residual_diagnostics: x and y must have same length");
808 double n_d =
static_cast<double>(n);
813 for (
auto it = x_first; it != x_last; ++it) {
814 double dx =
static_cast<double>(*it) - mean_x;
818 std::vector<double> residuals(n);
819 std::vector<double> hat_values(n);
820 std::vector<double> standardized_residuals(n);
824 for (std::size_t i = 0; it_x != x_last; ++it_x, ++it_y, ++i) {
825 double x_i =
static_cast<double>(*it_x);
826 double y_i =
static_cast<double>(*it_y);
827 double y_hat =
predict(model, x_i);
828 residuals[i] = y_i - y_hat;
831 double dx = x_i - mean_x;
832 hat_values[i] = 1.0 / n_d + dx * dx / sxx;
835 standardized_residuals[i] = residuals[i] / model.
residual_se;
839 std::vector<double> studentized_residuals(n);
843 for (std::size_t i = 0; i < n; ++i) {
844 double h_i = hat_values[i];
845 double se_i = model.
residual_se * std::sqrt(1.0 - h_i);
846 studentized_residuals[i] = (se_i > 0.0) ? residuals[i] / se_i : 0.0;
847 cooks_distance[i] = (standardized_residuals[i] * standardized_residuals[i] / p)
848 * (h_i / ((1.0 - h_i) * (1.0 - h_i)));
854 for (std::size_t i = 0; i < n; ++i) {
855 dw_den += residuals[i] * residuals[i];
857 double diff = residuals[i] - residuals[i - 1];
861 double durbin_watson = (dw_den > 0.0) ? dw_num / dw_den : 0.0;
863 return {residuals, standardized_residuals, studentized_residuals,
881 const std::vector<std::vector<double>>& X,
882 const std::vector<double>& y)
884 std::size_t n = X.size();
886 throw std::invalid_argument(
"statcpp::compute_residual_diagnostics: X and y must have same length");
889 std::size_t p = X[0].size();
890 std::size_t p_full = p + 1;
893 std::vector<std::vector<double>> X_design(n, std::vector<double>(p_full));
894 for (std::size_t i = 0; i < n; ++i) {
895 X_design[i][0] = 1.0;
896 for (std::size_t j = 0; j < p; ++j) {
897 X_design[i][j + 1] = X[i][j];
908 std::vector<double> hat_values(n);
909 for (std::size_t i = 0; i < n; ++i) {
911 for (std::size_t j = 0; j < p_full; ++j) {
912 for (std::size_t k = 0; k < p_full; ++k) {
913 h_ii += X_design[i][j] * XtX_inv[j][k] * X_design[i][k];
916 hat_values[i] = h_ii;
920 std::vector<double> residuals(n);
921 for (std::size_t i = 0; i < n; ++i) {
922 double pred =
predict(model, X[i]);
923 residuals[i] = y[i] - pred;
927 std::vector<double> standardized_residuals(n);
928 std::vector<double> studentized_residuals(n);
931 double p_d =
static_cast<double>(p_full);
933 for (std::size_t i = 0; i < n; ++i) {
934 standardized_residuals[i] = residuals[i] / model.
residual_se;
936 double h_i = hat_values[i];
937 double se_i = model.
residual_se * std::sqrt(1.0 - h_i);
938 studentized_residuals[i] = (se_i > 0.0) ? residuals[i] / se_i : 0.0;
940 cooks_distance[i] = (standardized_residuals[i] * standardized_residuals[i] / p_d)
941 * (h_i / ((1.0 - h_i) * (1.0 - h_i)));
947 for (std::size_t i = 0; i < n; ++i) {
948 dw_den += residuals[i] * residuals[i];
950 double diff = residuals[i] - residuals[i - 1];
954 double durbin_watson = (dw_den > 0.0) ? dw_num / dw_den : 0.0;
956 return {residuals, standardized_residuals, studentized_residuals,
976inline std::vector<double>
compute_vif(
const std::vector<std::vector<double>>& X)
978 std::size_t n = X.size();
980 throw std::invalid_argument(
"statcpp::compute_vif: need at least 3 observations");
983 std::size_t p = X[0].size();
985 throw std::invalid_argument(
"statcpp::compute_vif: need at least 2 predictors");
988 std::vector<double> vif(p);
990 for (std::size_t j = 0; j < p; ++j) {
992 std::vector<double> y_j(n);
993 std::vector<std::vector<double>> X_others(n, std::vector<double>(p - 1));
995 for (std::size_t i = 0; i < n; ++i) {
998 for (std::size_t k = 0; k < p; ++k) {
1000 X_others[i][col++] = X[i][k];
1006 double r_sq = result.r_squared;
1010 vif[j] = std::numeric_limits<double>::infinity();
1012 vif[j] = 1.0 / (1.0 - r_sq);
1037 std::size_t n = X.size();
1039 throw std::invalid_argument(
"statcpp::correlation_matrix_determinant: need at least 2 observations");
1042 std::size_t p = X[0].size();
1044 throw std::invalid_argument(
"statcpp::correlation_matrix_determinant: need at least 2 predictors");
1048 std::vector<std::vector<double>> corr_matrix(p, std::vector<double>(p));
1049 for (std::size_t i = 0; i < p; ++i) {
1050 for (std::size_t j = 0; j < p; ++j) {
1052 corr_matrix[i][j] = 1.0;
1055 std::vector<double> col_i(n), col_j(n);
1056 for (std::size_t k = 0; k < n; ++k) {
1061 col_j.begin(), col_j.end());
1062 corr_matrix[i][j] = corr;
1063 corr_matrix[j][i] = corr;
1071 return corr_matrix[0][0] * corr_matrix[1][1] - corr_matrix[0][1] * corr_matrix[1][0];
1072 }
else if (p == 3) {
1074 double a = corr_matrix[0][0] * corr_matrix[1][1] * corr_matrix[2][2];
1075 double b = corr_matrix[0][1] * corr_matrix[1][2] * corr_matrix[2][0];
1076 double c = corr_matrix[0][2] * corr_matrix[1][0] * corr_matrix[2][1];
1077 double d = corr_matrix[0][2] * corr_matrix[1][1] * corr_matrix[2][0];
1078 double e = corr_matrix[0][0] * corr_matrix[1][2] * corr_matrix[2][1];
1079 double f = corr_matrix[0][1] * corr_matrix[1][0] * corr_matrix[2][2];
1080 return a + b + c - d - e - f;
1083 throw std::invalid_argument(
"statcpp::correlation_matrix_determinant: only 2 or 3 predictors supported");
1102 return 1.0 - std::abs(det);
1124template <
typename IteratorY,
typename IteratorPred>
1126 IteratorPred pred_first, IteratorPred pred_last)
1131 if (n_y != n_pred) {
1132 throw std::invalid_argument(
"statcpp::r_squared: y and predictions must have same length");
1135 throw std::invalid_argument(
"statcpp::r_squared: need at least 2 observations");
1140 double ss_total = 0.0;
1141 double ss_residual = 0.0;
1143 auto it_y = y_first;
1144 auto it_pred = pred_first;
1145 for (; it_y != y_last; ++it_y, ++it_pred) {
1146 double y_i =
static_cast<double>(*it_y);
1147 double pred_i =
static_cast<double>(*it_pred);
1148 ss_total += (y_i - mean_y) * (y_i - mean_y);
1149 ss_residual += (y_i - pred_i) * (y_i - pred_i);
1152 if (ss_total == 0.0) {
1156 return 1.0 - ss_residual / ss_total;
1176template <
typename IteratorY,
typename IteratorPred>
1178 IteratorPred pred_first, IteratorPred pred_last,
1179 std::size_t num_predictors)
1182 double n_d =
static_cast<double>(n);
1183 double p =
static_cast<double>(num_predictors);
1185 if (n_d <= p + 1.0) {
1186 throw std::invalid_argument(
"statcpp::adjusted_r_squared: need more observations than predictors");
1189 double r_sq =
r_squared(y_first, y_last, pred_first, pred_last);
1190 return 1.0 - (1.0 - r_sq) * (n_d - 1.0) / (n_d - p - 1.0);
Basic statistical computation functions.
Continuous distribution functions.
Correlation and covariance computation functions.
std::vector< std::vector< double > > matrix_multiply(const std::vector< std::vector< double > > &A, const std::vector< std::vector< double > > &B)
Calculate matrix product.
std::vector< std::vector< double > > inverse_cholesky(const std::vector< std::vector< double > > &L)
Calculate inverse matrix using Cholesky decomposition.
std::vector< std::vector< double > > transpose(const std::vector< std::vector< double > > &A)
Calculate transpose matrix.
std::vector< double > matrix_vector_multiply(const std::vector< std::vector< double > > &A, const std::vector< double > &v)
Calculate matrix-vector product.
std::vector< double > solve_cholesky(const std::vector< std::vector< double > > &L, const std::vector< double > &b)
Solve system of equations using Cholesky decomposition.
std::vector< std::vector< double > > cholesky(const std::vector< std::vector< double > > &A)
Perform Cholesky decomposition.
void validate_no_intercept_column(const std::vector< std::vector< double > > &X, const char *func_name)
Check that X data does not contain an intercept column.
void validate_matrix_structure(const std::vector< std::vector< double > > &data, const char *func_name)
Validate 2D matrix structure.
double multicollinearity_score(const std::vector< std::vector< double > > &X)
Calculate multicollinearity score.
prediction_interval prediction_interval_simple(const simple_regression_result &model, IteratorX x_first, IteratorX x_last, double x_new, double confidence=0.95)
Calculate prediction interval for simple regression model.
residual_diagnostics compute_residual_diagnostics(const simple_regression_result &model, IteratorX x_first, IteratorX x_last, IteratorY y_first, IteratorY y_last)
Perform residual diagnostics for simple regression model.
auto sum(Iterator first, Iterator last)
Sum.
double t_cdf(double x, double df)
t-distribution cumulative distribution function (CDF)
simple_regression_result simple_linear_regression(IteratorX x_first, IteratorX x_last, IteratorY y_first, IteratorY y_last)
Perform simple linear regression.
std::vector< double > cooks_distance(const std::vector< double > &residuals, const std::vector< double > &hat_values, double mse, std::size_t p)
Calculate Cook's Distance.
multiple_regression_result multiple_linear_regression(const std::vector< std::vector< double > > &X, const std::vector< double > &y)
Perform multiple linear regression.
double predict(const simple_regression_result &model, double x)
Make prediction using simple regression model.
double mean(Iterator first, Iterator last)
Arithmetic mean.
double t_quantile(double p, double df)
t-distribution quantile function (Newton-Raphson method)
std::vector< double > diff(Iterator first, Iterator last, std::size_t order=1)
Difference series (first-order or d-th order differencing)
prediction_interval confidence_interval_mean(const simple_regression_result &model, IteratorX x_first, IteratorX x_last, double x_new, double confidence=0.95)
Calculate confidence interval for mean of simple regression model.
double r_squared(IteratorY y_first, IteratorY y_last, IteratorPred pred_first, IteratorPred pred_last)
Calculate coefficient of determination from observed and predicted values.
std::vector< double > compute_vif(const std::vector< std::vector< double > > &X)
Calculate VIF (Variance Inflation Factor) for each predictor.
double mse(Iterator1 first1, Iterator1 last1, Iterator2 first2)
Mean Squared Error (MSE)
double adjusted_r_squared(IteratorY y_first, IteratorY y_last, IteratorPred pred_first, IteratorPred pred_last, std::size_t num_predictors)
Calculate adjusted coefficient of determination.
double pearson_correlation(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
Pearson correlation coefficient.
double correlation_matrix_determinant(const std::vector< std::vector< double > > &X)
Calculate determinant of correlation matrix.
std::size_t count(Iterator first, Iterator last)
Data count.
double f_cdf(double x, double df1, double df2)
F-distribution cumulative distribution function (CDF)
Structure to store multiple regression analysis results.
double ss_total
Total sum of squares.
std::vector< double > coefficients
Regression coefficients (b0, b1, ..., bp)
double adj_r_squared
Adjusted R^2.
double f_p_value
p-value for F-test
std::vector< double > coefficient_se
Standard errors of coefficients.
double ss_residual
Residual sum of squares.
std::vector< double > p_values
p-values
double df_regression
Regression degrees of freedom.
double residual_se
Residual standard error.
double f_statistic
F-statistic.
double ss_regression
Regression sum of squares.
double r_squared
Coefficient of determination R^2.
std::vector< double > t_statistics
t-statistics
double df_residual
Residual degrees of freedom.
Structure to store prediction interval results.
double prediction
Predicted value.
double se_prediction
Standard error of prediction.
Structure to store residual diagnostics results.
std::vector< double > cooks_distance
Cook's distance.
double durbin_watson
Durbin-Watson statistic.
std::vector< double > studentized_residuals
Studentized residuals.
std::vector< double > standardized_residuals
Standardized residuals.
std::vector< double > residuals
Residuals.
std::vector< double > hat_values
Leverage values.
Structure to store simple regression analysis results.
double r_squared
Coefficient of determination R^2.
double slope_se
Standard error of slope.
double df_residual
Residual degrees of freedom.
double intercept_se
Standard error of intercept.
double f_statistic
F-statistic.
double residual_se
Residual standard error.
double intercept
Intercept (b0)
double slope_t
t-statistic for slope
double ss_regression
Regression sum of squares.
double intercept_t
t-statistic for intercept
double ss_total
Total sum of squares.
double df_regression
Regression degrees of freedom.
double f_p_value
p-value for F-test
double slope_p
p-value for slope
double intercept_p
p-value for intercept
double ss_residual
Residual sum of squares.
double adj_r_squared
Adjusted R^2.