diff --git a/src/mlpack/methods/lmnn/constraints_impl.hpp b/src/mlpack/methods/lmnn/constraints_impl.hpp index 5eaec385ae..faff89a445 100644 --- a/src/mlpack/methods/lmnn/constraints_impl.hpp +++ b/src/mlpack/methods/lmnn/constraints_impl.hpp @@ -238,6 +238,8 @@ void Constraints::Impostors(arma::Mat& outputNeighbors, arma::Mat neighbors; arma::mat distances; + outputDistance = arma::mat(k, dataset.n_cols, arma::fill::zeros); + // Vectors to store indices. arma::uvec subIndexSame; diff --git a/src/mlpack/methods/lmnn/lmnn_function_impl.hpp b/src/mlpack/methods/lmnn/lmnn_function_impl.hpp index 171cda43c9..390ddbcd2f 100644 --- a/src/mlpack/methods/lmnn/lmnn_function_impl.hpp +++ b/src/mlpack/methods/lmnn/lmnn_function_impl.hpp @@ -76,8 +76,8 @@ double LMNNFunction::Evaluate(const arma::mat& coordinates) // Apply metric over dataset. transformedDataset = coordinates * dataset; - arma::mat distance = arma::mat(k, dataset.n_cols, arma::fill::zeros); - if (iteration++ % range == 0) + arma::mat distance; + if (iteration % range == 0) { // Re-calculate impostors on transformed dataset. Constraints constraint(transformedDataset, labels, k); @@ -100,17 +100,22 @@ double LMNNFunction::Evaluate(const arma::mat& coordinates) // breaking point. for (size_t l = 0, bp = k; l < bp ; l++) { - // Check if we already have distance between impostor & data point - // stored. - double distImp = distance(l, i) > 0 ? distance(l, i) : - metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(impostors(l, i))); - // Calculate cost due to {data point, target neighbors, impostors} // triplets. - double eval = metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(targetNeighbors(j, i))) - - distImp; + double eval = 0; + if (iteration++ % range == 0) + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + std::pow(distance(l, i), 2); + } + else + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(impostors(l, i))); + } // Check bounding condition. if (eval < -1) @@ -139,8 +144,8 @@ double LMNNFunction::Evaluate(const arma::mat& coordinates, // Apply metric over dataset. transformedDataset = coordinates * dataset; - arma::mat distance = arma::mat(k, dataset.n_cols, arma::fill::zeros); - if (iteration++ % range == 0) + arma::mat distance; + if (iteration % range == 0) { // Re-calculate impostors on transformed dataset. Constraints constraint(transformedDataset, labels, k); @@ -162,17 +167,22 @@ double LMNNFunction::Evaluate(const arma::mat& coordinates, // Bound constraints to avoid uneccesary computation. for (size_t l = 0, bp = k; l < bp ; l++) { - // Check if we already have distance between impostor & data point - // stored. - double distImp = distance(l, i) > 0 ? distance(l, i) : - metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(impostors(l, i))); - // Calculate cost due to {data point, target neighbors, impostors} // triplets. - double eval = metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(targetNeighbors(j, i))) - - distImp; + double eval = 0; + if (iteration++ % range == 0) + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + std::pow(distance(l, i), 2); + } + else + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(impostors(l, i))); + } // Check bounding condition. if (eval < -1) @@ -307,8 +317,8 @@ double LMNNFunction::EvaluateWithGradient( // Apply metric over dataset. transformedDataset = coordinates * dataset; - arma::mat distance = arma::mat(k, dataset.n_cols, arma::fill::zeros); - if (iteration++ % range == 0) + arma::mat distance; + if (iteration % range == 0) { // Re-calculate impostors on transformed dataset. Constraints constraint(transformedDataset, labels, k); @@ -339,17 +349,22 @@ double LMNNFunction::EvaluateWithGradient( // Bound constraints to avoid uneccesary computation. for (size_t l = 0, bp = k; l < bp ; l++) { - // Check if we already have distance between impostor & data point - // stored. - double distImp = distance(l, i) > 0 ? distance(l, i) : - metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(impostors(l, i))); - // Calculate cost due to {data point, target neighbors, impostors} // triplets. - double eval = metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(targetNeighbors(j, i))) - - distImp; + double eval = 0; + if (iteration++ % range == 0) + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + std::pow(distance(l, i), 2); + } + else + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(impostors(l, i))); + } // Check bounding condition. if (eval < -1) @@ -391,8 +406,8 @@ double LMNNFunction::EvaluateWithGradient( // Apply metric over dataset. transformedDataset = coordinates * dataset; - arma::mat distance = arma::mat(k, dataset.n_cols, arma::fill::zeros); - if (iteration++ % range == 0) + arma::mat distance; + if (iteration % range == 0) { // Re-calculate impostors on transformed dataset. Constraints constraint(transformedDataset, labels, k); @@ -423,17 +438,22 @@ double LMNNFunction::EvaluateWithGradient( // Bound constraints to avoid uneccesary computation. for (size_t l = 0, bp = k; l < bp ; l++) { - // Check if we already have distance between impostor & data point - // stored. - double distImp = distance(l, i) > 0 ? distance(l, i) : - metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(impostors(l, i))); - // Calculate cost due to {data point, target neighbors, impostors} // triplets. - double eval = metric.Evaluate(transformedDataset.col(i), - transformedDataset.col(targetNeighbors(j, i))) - - distImp; + double eval = 0; + if (iteration++ % range == 0) + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + std::pow(distance(l, i), 2); + } + else + { + eval = metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(targetNeighbors(j, i))) - + metric.Evaluate(transformedDataset.col(i), + transformedDataset.col(impostors(l, i))); + } // Check bounding condition. if (eval < -1)