// Cross-correlation implementation in Eigen //' @rdname corFamily //' @export // [[Rcpp::export]] Eigen::MatrixXd xcorEigen(Eigen::Map<Eigen::MatrixXd> & X, Eigen::Map<Eigen::MatrixXd> & Y) { // Handle degenerate cases if (X.cols() == 0 || Y.cols() == 0) { return Eigen::MatrixXd::Constant(0, 0, 0); } else if (X.rows() == 0) { // && X.cols() > 0 && Y.cols() > 0 implicit return Eigen::MatrixXd::Constant(X.cols(), Y.cols(), Rcpp::NumericVector::get_na()); } // Computing degrees of freedom // n - 1 is the unbiased estimate whereas n is the MLE const int df = X.rows() - 1; // Subtract 1 by default // Centering matrices Y.rowwise() -= Y.colwise().mean(); X.rowwise() -= X.colwise().mean(); // The covariance matrix Eigen::MatrixXd cor = X.transpose() * Y / df; // Compute 1 over the standard deviations of X and Y Eigen::VectorXd inv_sds_X = (X.colwise().norm()/sqrt(df)).array().inverse(); Eigen::VectorXd inv_sds_Y = (Y.colwise().norm()/sqrt(df)).array().inverse(); // Scale the covariance matrix cor = cor.cwiseProduct(inv_sds_X * inv_sds_Y.transpose()); return cor; }
/** * Generates an artificial topographyGrid of size numRows x numCols if no * topographic data is available. Results are dumped into topographyGrid. * @param topographyGrid A pointer to a zero-initialized Grid of size * numRows x numCols. * @param numRows The desired number of non-border rows in the resulting matrix. * @param numCols The desired number of non-border cols in the resulting matrix. */ void simulatetopographyGrid(Grid* topographyGrid, int numRows, int numCols) { Eigen::VectorXd refx = refx.LinSpaced(numCols, -2*M_PI, 2*M_PI); Eigen::VectorXd refy = refx.LinSpaced(numRows, -2*M_PI, 2*M_PI); Eigen::MatrixXd X = refx.replicate(1, numRows); X.transposeInPlace(); Eigen::MatrixXd Y = refy.replicate(1, numCols); // Eigen can only deal with two matrices at a time, // so split the computation: // topographyGrid = sin(X) * sin(Y) * abs(X) * abs(Y) -pi Eigen::MatrixXd absXY = X.cwiseAbs().cwiseProduct(Y.cwiseAbs()); Eigen::MatrixXd sins = X.array().sin().cwiseProduct(Y.array().sin()); Eigen::MatrixXd temp; temp.resize(numRows, numCols); temp = absXY.cwiseProduct(sins); // All this work to create a matrix of pi... Eigen::MatrixXd pi; pi.resize(numRows, numCols); pi.setConstant(M_PI); temp = temp - pi; // And the final result. topographyGrid->data.block(border, border, numRows, numCols) = temp.block(0, 0, numRows, numCols); // Ignore positive values. topographyGrid->data = topographyGrid->data.unaryExpr(std::ptr_fun(validateDepth)); topographyGrid->clearNA(); }
void RunningStacker::Stack(Eigen::MatrixXd input) { n++; if (n == 1) { mean = input; M2 = Eigen::MatrixXd::Zero(input.rows(), input.cols()); return; } const Eigen::MatrixXd delta = input - mean; mean = mean + delta / n; M2 = M2 + delta.cwiseProduct(input - mean); }
// Correlation implementation in Eigen //' @rdname corFamily //' @export // [[Rcpp::export]] Eigen::MatrixXd corEigen(Eigen::Map<Eigen::MatrixXd> & X) { // Handle degenerate cases if (X.rows() == 0 && X.cols() > 0) { return Eigen::MatrixXd::Constant(X.cols(), X.cols(), Rcpp::NumericVector::get_na()); } // Computing degrees of freedom // n - 1 is the unbiased estimate whereas n is the MLE const int df = X.rows() - 1; // Subtract 1 by default X.rowwise() -= X.colwise().mean(); // Centering Eigen::MatrixXd cor = X.transpose() * X / df; // The covariance matrix // Get 1 over the standard deviations Eigen::VectorXd inv_sds = cor.diagonal().array().sqrt().inverse(); // Scale the covariance matrix cor = cor.cwiseProduct(inv_sds * inv_sds.transpose()); return cor; }