diff --git a/src/mlpack/methods/lmnn/constraints_impl.hpp b/src/mlpack/methods/lmnn/constraints_impl.hpp index cce03ea9b0..ee3ecc5841 100644 --- a/src/mlpack/methods/lmnn/constraints_impl.hpp +++ b/src/mlpack/methods/lmnn/constraints_impl.hpp @@ -276,9 +276,6 @@ void Constraints::Impostors(arma::Mat& outputNeighbors, // Perform pre-calculation. If neccesary. Precalculate(labels); - arma::mat subDataset = dataset.cols(points); - arma::Row sublabels = labels.cols(points); - // KNN instance. KNN knn; @@ -291,12 +288,13 @@ void Constraints::Impostors(arma::Mat& outputNeighbors, for (size_t i = 0; i < uniqueLabels.n_cols; i++) { // Calculate impostors. - subIndexSame = arma::find(sublabels == uniqueLabels[i]); + subIndexSame = arma::find(labels.cols(points) == uniqueLabels[i]); // Perform KNN search with differently labeled points as reference // set and same class points as query set. knn.Train(dataset.cols(indexDiff[i])); - knn.Search(subDataset.cols(subIndexSame), k, neighbors, distances); + knn.Search(dataset.cols(points.elem(subIndexSame)), + k, neighbors, distances); // Re-map neighbors to their index. for (size_t j = 0; j < neighbors.n_elem; j++) diff --git a/src/mlpack/methods/lmnn/lmnn_function_impl.hpp b/src/mlpack/methods/lmnn/lmnn_function_impl.hpp index 683bc4ff9b..ee8e00a2c0 100644 --- a/src/mlpack/methods/lmnn/lmnn_function_impl.hpp +++ b/src/mlpack/methods/lmnn/lmnn_function_impl.hpp @@ -42,9 +42,9 @@ LMNNFunction::LMNNFunction(const arma::mat& dataset, transformedDataset = dataset; // Initialize target neighbors & impostors. - targetNeighbors = arma::Mat(k + 1, dataset.n_cols, arma::fill::zeros); - impostors = arma::Mat(k + 1, dataset.n_cols, arma::fill::zeros); - distance = arma::mat(k + 1, dataset.n_cols, arma::fill::zeros); + targetNeighbors.set_size(k + 1, dataset.n_cols); + impostors.set_size(k + 1, dataset.n_cols); + distance.set_size(k + 1, dataset.n_cols); constraint.TargetNeighbors(targetNeighbors, dataset, labels); constraint.Impostors(impostors, dataset, labels); @@ -83,29 +83,32 @@ double LMNNFunction::Evaluate(const arma::mat& transformation) transformedDataset = transformation * dataset; double transformationDiff = 0; - if (transformationOld.n_elem != 0 && iteration % range == 0) + if (transformationOld.n_elem != 0 && iteration++ % range == 0) { // Calculate norm of change in transformation. transformationDiff = arma::norm(transformation - transformationOld); - std::vector tempPoints; + arma::uvec points(dataset.n_cols); + + // Track number of data points to use for impostors calculatiom. + size_t numPoints = 0; for (size_t i = 0; i < dataset.n_cols; i++) { if (transformationDiff * (2 * norm(i) + norm(impostors(k - 1, i)) + norm(impostors(k, i))) > distance(k, i) - distance(k - 1, i)) { - tempPoints.push_back(i); + points(numPoints++) = i; } } - arma::uvec points = arma::conv_to::from(tempPoints); + points.resize(numPoints); // Re-calculate impostors on transformed dataset. constraint.Impostors(impostors, distance, transformedDataset, labels, points); } - else if (iteration % range == 0) + else if (iteration++ % range == 0) { // Re-calculate impostors on transformed dataset. constraint.Impostors(impostors, distance, transformedDataset, labels); @@ -346,29 +349,32 @@ double LMNNFunction::EvaluateWithGradient( transformedDataset = transformation * dataset; double transformationDiff = 0; - if (transformationOld.n_elem != 0 && iteration % range == 0) + if (transformationOld.n_elem != 0 && iteration++ % range == 0) { // Calculate norm of change in transformation. transformationDiff = arma::norm(transformation - transformationOld); - std::vector tempPoints; + arma::uvec points(dataset.n_cols); + + // Track number of data points to use for impostors calculatiom. + size_t numPoints = 0; for (size_t i = 0; i < dataset.n_cols; i++) { if (transformationDiff * (2 * norm(i) + norm(impostors(k - 1, i)) + norm(impostors(k, i))) > distance(k, i) - distance(k - 1, i)) { - tempPoints.push_back(i); + points(numPoints++) = i; } } - arma::uvec points = arma::conv_to::from(tempPoints); + points.resize(numPoints); // Re-calculate impostors on transformed dataset. constraint.Impostors(impostors, distance, transformedDataset, labels, points); } - else if (iteration % range == 0) + else if (iteration++ % range == 0) { // Re-calculate impostors on transformed dataset. constraint.Impostors(impostors, distance, transformedDataset, labels); @@ -535,7 +541,7 @@ template inline void LMNNFunction::Precalculate() { pCij.zeros(dataset.n_rows, dataset.n_rows); - norm.zeros(dataset.n_cols); + norm.set_size(dataset.n_cols); for (size_t i = 0; i < dataset.n_cols; i++) {