Merge pull request #3164 from eshaanagarwal/size-checks

Added Size checks for Matrix Completion, Kmeans and Linear Regression
This commit is contained in:
Ryan Curtin
2022-04-18 15:43:03 -07:00
committed by GitHub
4 changed files with 36 additions and 27 deletions
+14 -5
View File
@@ -26,18 +26,27 @@ namespace util {
* error generation.
* @param addInfo Name to use for labels for precise error generation. Default
* is "labels"; for example, "weights" could also be used.
* @param isDataTranspose Bool parameter which can be set true to transpose data
* before size-check. Default is false.
* @param isLabelTranspose Bool parameter which can be set true to transpose label
* before size-check. Default is false.
*/
template<typename DataType, typename LabelsType>
inline void CheckSameSizes(const DataType& data,
const LabelsType& label,
const std::string& callerDescription,
const std::string& addInfo = "labels")
{
if (data.n_cols != label.n_cols)
const std::string& addInfo = "labels",
const bool& isDataTranspose = false,
const bool& isLabelTranspose = false)
{
const size_t dataPoints = (isDataTranspose == true) ? data.n_rows : data.n_cols;
const size_t labelPoints = (isLabelTranspose == true) ? label.n_rows : label.n_cols;
if (dataPoints != labelPoints)
{
std::ostringstream oss;
oss << callerDescription << ": number of points (" << data.n_cols << ") "
<< "does not match number of " << addInfo << " (" << label.n_cols
oss << callerDescription << ": number of points (" << dataPoints << ") "
<< "does not match number of " << addInfo << " (" << labelPoints
<< ")!" << std::endl;
throw std::invalid_argument(oss.str());
}
+4 -13
View File
@@ -14,6 +14,7 @@
#include <mlpack/core/metrics/lmetric.hpp>
#include <mlpack/core/util/sfinae_utility.hpp>
#include <mlpack/core/util/size_checks.hpp>
namespace mlpack {
namespace kmeans {
@@ -161,15 +162,8 @@ Cluster(const MatType& data,
// Check validity of initial guess.
if (initialGuess)
{
if (centroids.n_cols != clusters)
Log::Fatal << "KMeans::Cluster(): wrong number of initial cluster "
<< "centroids (" << centroids.n_cols << ", should be " << clusters
<< ")!" << std::endl;
if (centroids.n_rows != data.n_rows)
Log::Fatal << "KMeans::Cluster(): initial cluster centroids have wrong "
<< " dimensionality (" << centroids.n_rows << ", should be "
<< data.n_rows << ")!" << std::endl;
util::CheckSameSizes(centroids, clusters, "KMeans::Cluster()", "clusters");
util::CheckSameDimensionality(data, centroids, "KMeans::Cluster()");
}
// Use the partitioner to come up with the partition assignments and calculate
@@ -288,10 +282,7 @@ Cluster(const MatType& data,
// Now, the initial assignments. First determine if they are necessary.
if (initialAssignmentGuess)
{
if (assignments.n_elem != data.n_cols)
Log::Fatal << "KMeans::Cluster(): initial cluster assignments (length "
<< assignments.n_elem << ") not the same size as the dataset (size "
<< data.n_cols << ")!" << std::endl;
util::CheckSameSizes(data, assignments, "KMeans::Cluster()", "assignments");
// Calculate initial centroids.
arma::Row<size_t> counts;
@@ -12,6 +12,7 @@
*/
#include "linear_regression.hpp"
#include <mlpack/core/util/log.hpp>
#include <mlpack/core/util/size_checks.hpp>
using namespace mlpack;
using namespace mlpack::regression;
@@ -57,6 +58,10 @@ double LinearRegression::Train(const arma::mat& predictors,
// We store the number of rows and columns of the predictors.
// Reminder: Armadillo stores the data transposed from how we think of it,
// that is, columns are actually rows (see: column major order).
// Sanity check on data.
util::CheckSameSizes(predictors, responses, "LinearRegression::Train()");
const size_t nCols = predictors.n_cols;
arma::mat p = predictors;
@@ -95,7 +100,11 @@ void LinearRegression::Predict(const arma::mat& points,
{
// We want to be sure we have the correct number of dimensions in the
// dataset.
Log::Assert(points.n_rows == parameters.n_rows - 1);
// Prevent underflow.
const size_t labels = (parameters.n_rows == 0) ? size_t(0) :
size_t(parameters.n_rows - 1);
util::CheckSameDimensionality(points, labels, "LinearRegression::Predict()",
"points");
// Get the predictions, but this ignores the intercept value
// (parameters[0]).
predictions = arma::trans(parameters.subvec(1, parameters.n_elem - 1))
@@ -107,7 +116,8 @@ void LinearRegression::Predict(const arma::mat& points,
{
// We want to be sure we have the correct number of dimensions in
// the dataset.
Log::Assert(points.n_rows == parameters.n_rows);
util::CheckSameDimensionality(points, parameters,
"LinearRegression::Predict()", "points");
predictions = arma::trans(parameters) * points;
}
}
@@ -115,6 +125,9 @@ void LinearRegression::Predict(const arma::mat& points,
double LinearRegression::ComputeError(const arma::mat& predictors,
const arma::rowvec& responses) const
{
// Sanity check on data.
util::CheckSameSizes(predictors, responses, "LinearRegression::Train()");
// Get the number of columns and rows of the dataset.
const size_t nCols = predictors.n_cols;
const size_t nRows = predictors.n_rows;
@@ -11,6 +11,7 @@
*/
#include "matrix_completion.hpp"
#include <mlpack/core/util/size_checks.hpp>
namespace mlpack {
namespace matrix_completion {
@@ -59,13 +60,8 @@ void MatrixCompletion::CheckValues()
<< "indices does not have 2 rows!" << std::endl;
}
if (indices.n_cols != values.n_elem)
{
Log::Fatal << "MatrixCompletion::CheckValues(): the number of constraint "
<< "indices (columns of constraint indices matrix) does not match the "
<< "number of constraint values (length of constraint value vector)!"
<< std::endl;
}
util::CheckSameSizes(indices, values,
"MatrixCompletion::CheckValues()", "labels", false, true);
for (size_t i = 0; i < values.n_elem; ++i)
{