diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp index 405188a4f6..32bb94ece9 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp @@ -182,6 +182,14 @@ class DiscreteHilbertValue */ DiscreteHilbertValue& operator=(const DiscreteHilbertValue& val); + /** + * Move the local Hilbert object. + * + * @param val The DiscreteHilbertValue object from which the dataset + * will be copied. + */ + DiscreteHilbertValue& operator=(DiscreteHilbertValue&& val); + /** * Nullify the localHilbertValues pointer in order to prevent an invalid free. */ diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp index c4baa38a90..48ad8557f7 100644 --- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp +++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp @@ -450,6 +450,27 @@ operator=(const DiscreteHilbertValue& val) return *this; } +template +DiscreteHilbertValue& DiscreteHilbertValue:: +operator=(DiscreteHilbertValue&& other) +{ + if (this != &other) + { + localHilbertValues = other.localHilbertValues; + ownsLocalHilbertValues = other.ownsLocalHilbertValues; + numValues = other.numValues; + valueToInsert = other.valueToInsert; + ownsValueToInsert = other.ownsValueToInsert; + + other.localHilbertValues = nullptr; + other.ownsLocalHilbertValues = false; + other.numValues = 0; + other.valueToInsert = nullptr; + other.ownsValueToInsert = false; + } + return *this; +} + template void DiscreteHilbertValue::NullifyData() { diff --git a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp index 970b24289f..81893f4fa3 100644 --- a/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp +++ b/src/mlpack/methods/amf/termination_policies/simple_residue_termination.hpp @@ -41,7 +41,15 @@ class SimpleResidueTermination */ SimpleResidueTermination(const double minResidue = 1e-5, const size_t maxIterations = 10000) - : minResidue(minResidue), maxIterations(maxIterations) { } + : minResidue(minResidue), + maxIterations(maxIterations), + residue(0.0), + iteration(0), + nm(0), + normOld(0) + { + // Nothing to do here. + } /** * Initializes the termination policy before stating the factorization. diff --git a/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp index 4ab1c0d610..37b7ab8c0a 100644 --- a/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp +++ b/src/mlpack/methods/amf/update_rules/svd_complete_incremental_learning.hpp @@ -56,7 +56,7 @@ class SVDCompleteIncrementalLearning SVDCompleteIncrementalLearning(double u = 0.0001, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh) + : u(u), kw(kw), kh(kh), currentUserIndex(0), currentItemIndex(0) { // Nothing to do. } @@ -172,7 +172,7 @@ class SVDCompleteIncrementalLearning SVDCompleteIncrementalLearning(double u = 0.01, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh), it(NULL) + : u(u), kw(kw), kh(kh), it(NULL), m(0), n(0), isStart(false) {} ~SVDCompleteIncrementalLearning() diff --git a/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp index 0082824129..9880ea2945 100644 --- a/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp +++ b/src/mlpack/methods/amf/update_rules/svd_incomplete_incremental_learning.hpp @@ -53,7 +53,7 @@ class SVDIncompleteIncrementalLearning SVDIncompleteIncrementalLearning(double u = 0.001, double kw = 0, double kh = 0) - : u(u), kw(kw), kh(kh) + : u(u), kw(kw), kh(kh), currentUserIndex(0) { // Nothing to do. } diff --git a/src/mlpack/methods/fastmks/fastmks.hpp b/src/mlpack/methods/fastmks/fastmks.hpp index 93d234d541..ea2057b0b9 100644 --- a/src/mlpack/methods/fastmks/fastmks.hpp +++ b/src/mlpack/methods/fastmks/fastmks.hpp @@ -163,6 +163,11 @@ class FastMKS */ FastMKS& operator=(const FastMKS& other); + /** + * Move assignment operator. + */ + FastMKS& operator=(FastMKS&& other); + //! Destructor for the FastMKS object. ~FastMKS(); diff --git a/src/mlpack/methods/fastmks/fastmks_impl.hpp b/src/mlpack/methods/fastmks/fastmks_impl.hpp index 660617fdb0..3b2d12eaae 100644 --- a/src/mlpack/methods/fastmks/fastmks_impl.hpp +++ b/src/mlpack/methods/fastmks/fastmks_impl.hpp @@ -250,6 +250,35 @@ FastMKS::operator=(const FastMKS& other) naive = other.naive; } +template class TreeType> +FastMKS& +FastMKS::operator=(FastMKS&& other) +{ + if (this != &other) + { + referenceSet = other.referenceSet; + referenceTree = other.referenceTree; + treeOwner = other.treeOwner; + setOwner = other.setOwner; + singleMode = other.singleMode; + naive = other.naive; + metric = std::move(other.metric); + + // Clear information from the other. + other.referenceSet = nullptr; + other.referenceTree = nullptr; + other.treeOwner = false; + other.setOwner = false; + other.singleMode = false; + other.naive = false; + } + return *this; +} + template(*other.linear); - if (other.polynomial) - polynomial = new FastMKS(*other.polynomial); - if (other.cosine) - cosine = new FastMKS(*other.cosine); - if (other.gaussian) - gaussian = new FastMKS(*other.gaussian); - if (other.epan) - epan = new FastMKS(*other.epan); - if (other.triangular) - triangular = new FastMKS(*other.triangular); - if (other.hyptan) - hyptan = new FastMKS(*other.hyptan); + kernelType = other.kernelType; + if (other.linear) + linear = new FastMKS(*other.linear); + if (other.polynomial) + polynomial = new FastMKS(*other.polynomial); + if (other.cosine) + cosine = new FastMKS(*other.cosine); + if (other.gaussian) + gaussian = new FastMKS(*other.gaussian); + if (other.epan) + epan = new FastMKS(*other.epan); + if (other.triangular) + triangular = new FastMKS(*other.triangular); + if (other.hyptan) + hyptan = new FastMKS(*other.hyptan); + } + return *this; +} +FastMKSModel& FastMKSModel::operator=(FastMKSModel&& other) +{ + if (this != &other) + { + kernelType = other.kernelType; + linear = other.linear; + polynomial = other.polynomial; + cosine = other.cosine; + gaussian = other.gaussian; + epan = other.epan; + triangular = other.triangular; + hyptan = other.hyptan; + + // Clear other object. + other.kernelType = KernelTypes::LINEAR_KERNEL; + other.linear = nullptr; + other.polynomial = nullptr; + other.cosine = nullptr; + other.gaussian = nullptr; + other.epan = nullptr; + other.triangular = nullptr; + other.hyptan = nullptr; + } return *this; } diff --git a/src/mlpack/methods/fastmks/fastmks_model.hpp b/src/mlpack/methods/fastmks/fastmks_model.hpp index e84eee0c28..0b7568c641 100644 --- a/src/mlpack/methods/fastmks/fastmks_model.hpp +++ b/src/mlpack/methods/fastmks/fastmks_model.hpp @@ -60,6 +60,9 @@ class FastMKSModel //! Copy assignment operator. FastMKSModel& operator=(const FastMKSModel& other); + //! Move assignment operator. + FastMKSModel& operator=(FastMKSModel&& other); + /** * Clean memory. */ diff --git a/src/mlpack/methods/hmm/hmm_model.hpp b/src/mlpack/methods/hmm/hmm_model.hpp index 41a7fd406b..0a2bce384b 100644 --- a/src/mlpack/methods/hmm/hmm_model.hpp +++ b/src/mlpack/methods/hmm/hmm_model.hpp @@ -129,6 +129,20 @@ class HMMModel return *this; } + //! Move assignment operator. + HMMModel& operator=(HMMModel&& other) + { + if (this != &other) + { + type = other.type; + discreteHMM = other.discreteHMM; + gaussianHMM = other.gaussianHMM; + gmmHMM = other.gmmHMM; + diagGMMHMM = other.diagGMMHMM; + } + return *this; + } + //! Clean memory. ~HMMModel() { diff --git a/src/mlpack/methods/range_search/range_search.hpp b/src/mlpack/methods/range_search/range_search.hpp index 06575005ac..98de888a69 100644 --- a/src/mlpack/methods/range_search/range_search.hpp +++ b/src/mlpack/methods/range_search/range_search.hpp @@ -122,12 +122,18 @@ class RangeSearch RangeSearch(RangeSearch&& other); /** - * Copy the given RangeSearch model. - * Use std::move to pass in the model if the old copy is no longer needed. - * + * Deep copy the given RangeSearch model. + * * @param other RangeSearch model to copy. */ - RangeSearch& operator=(RangeSearch other); + RangeSearch& operator=(const RangeSearch& other); + + /** + * Move the given RangeSearch model. + * + * @param other RangeSearch model to move. + */ + RangeSearch& operator=(RangeSearch&& other); /** * Destroy the RangeSearch object. If trees were created, they will be diff --git a/src/mlpack/methods/range_search/range_search_impl.hpp b/src/mlpack/methods/range_search/range_search_impl.hpp index 298aae995e..2652d47c89 100644 --- a/src/mlpack/methods/range_search/range_search_impl.hpp +++ b/src/mlpack/methods/range_search/range_search_impl.hpp @@ -169,25 +169,61 @@ template class TreeType> RangeSearch& -RangeSearch::operator=(RangeSearch other) +RangeSearch::operator=(const RangeSearch& other) { - // Clean memory first. - if (treeOwner) - delete referenceTree; - if (naive) - delete referenceSet; + if (this != &other) + { + oldFromNewReferences = other.oldFromNewReferences; + referenceTree = other.referenceTree ? new Tree(*other.referenceTree) : nullptr; + referenceSet = other.referenceTree ? &referenceTree->Dataset() : + new MatType(*other.referenceSet); + treeOwner = other.referenceTree; + naive = other.naive; + singleMode = other.singleMode; + metric = other.metric; + baseCases = other.baseCases; + scores = other.scores; + } + return *this; +} - // Move the other model. - oldFromNewReferences = std::move(other.oldFromNewReferences); - referenceTree = other.referenceTree; - referenceSet = other.referenceSet; - treeOwner = other.treeOwner; - naive = other.naive; - singleMode = other.singleMode; - metric = std::move(other.metric); - baseCases = other.baseCases; - scores = other.scores; +template class TreeType> +RangeSearch& +RangeSearch::operator=(RangeSearch&& other) +{ + if (this != &other) + { + // Clean memory first. + if (treeOwner) + delete referenceTree; + if (naive) + delete referenceSet; + // Move the other model. + oldFromNewReferences = std::move(other.oldFromNewReferences); + referenceTree = other.referenceTree; + referenceSet = other.referenceSet; + treeOwner = other.treeOwner; + naive = other.naive; + singleMode = other.singleMode; + metric = std::move(other.metric); + baseCases = other.baseCases; + scores = other.scores; + + // Clear other object. + other.referenceTree = nullptr; + other.referenceSet = nullptr; + other.treeOwner = false; + other.naive = false; + other.singleMode = false; + other.baseCases = 0; + other.scores = 0; + + } return *this; } @@ -254,12 +290,15 @@ void RangeSearch::Train( throw std::invalid_argument("cannot train on given reference tree when " "naive search (without trees) is desired"); + // Can only train when passed argument `referenceTree` is not nullptr if (treeOwner && referenceTree) + { delete this->referenceTree; - this->referenceTree = referenceTree; - this->referenceSet = &referenceTree->Dataset(); - treeOwner = false; + this->referenceTree = referenceTree; + this->referenceSet = &referenceTree->Dataset(); + treeOwner = false; + } } template