diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index fd95c54d9a..75a437366b 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -83,7 +83,7 @@ Copyright: Copyright 2017, Samikshya Chand Copyright 2017, N Rajiv Vaidyanathan Copyright 2017, Kartik Nighania - Copyright 2017-2023, Dirk Eddelbuettel + Copyright 2017-2024, Dirk Eddelbuettel Copyright 2017-2018, Eugene Freyman Copyright 2017-2019, Manish Kumar Copyright 2017-2018, Haritha Sreedharan Nair @@ -151,7 +151,7 @@ Copyright: Copyright 2021, Roshan Nrusing Swain Copyright 2021, Suvarsha Chennareddy Copyright 2021, Shubham Agrawal - Copyright 2020-2022, James Joseph Balamuta + Copyright 2020-2024, James Balamuta Copyright 2022, Sri Madhan M Copyright 2022, Zhuojin Liu Copyright 2022, Richèl Bilderbeek diff --git a/doc/developer/community.md b/doc/developer/community.md index 43e3da3140..4687667645 100644 --- a/doc/developer/community.md +++ b/doc/developer/community.md @@ -12,9 +12,9 @@ information, see [this page](gsoc.md). All mlpack development is done on [GitHub](https://github.com/mlpack/mlpack). Commits and issue comments can be tracked via the -[mlpack-git](https://freelists.org/list/mlpack-git) list (graciously hosted by -[FreeLists](https://freelists.org). Communication is generally either via -issues on GitHub, or via chat: +[mlpack-git](https://www.freelists.org/list/mlpack-git) list (graciously hosted +by [FreeLists](https://www.freelists.org). Communication is generally either +via issues on GitHub, or via chat: ## Real-time chat diff --git a/doc/developer/gsoc.md b/doc/developer/gsoc.md index 88d739eca5..92583c1f85 100644 --- a/doc/developer/gsoc.md +++ b/doc/developer/gsoc.md @@ -51,7 +51,7 @@ project. A student should ideally be familiar with mlpack are SFINAE ([example in mlpack, see std::enable_if usages](https://github.com/mlpack/mlpack/blob/565cfd3aad22deec0656b86e801052593a937723/src/mlpack/methods/mean_shift/mean_shift.hpp)), [policy-based design](https://www.drdobbs.com/policy-based-design-in-the-real-world/184401861), and [compile-time class traits](https://accu.org/index.php/journals/442). - Here are some [other useful resources](https://www.codeproject.com/Articles/3743/A-gentle-introduction-to-Template-Metaprogramming) + Here are some [other useful resources](https://en.wikipedia.org/wiki/Template_metaprogramming) for learning template metaprogramming, and some useful [reference books](https://www.aristeia.com/books.html). If some of this sounds new to you, don’t feel overwhelmed; it’s not a diff --git a/src/mlpack/bindings/R/mlpack/src/Makevars b/src/mlpack/bindings/R/mlpack/src/Makevars index 90b241a3e5..c012d37814 100644 --- a/src/mlpack/bindings/R/mlpack/src/Makevars +++ b/src/mlpack/bindings/R/mlpack/src/Makevars @@ -1,2 +1,3 @@ +CXX_STD = CXX17 PKG_CXXFLAGS = -I. -I../inst/include $(SHLIB_OPENMP_CXXFLAGS) PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) diff --git a/src/mlpack/methods/adaboost/adaboost_impl.hpp b/src/mlpack/methods/adaboost/adaboost_impl.hpp index 7609ee7749..15492c6f8c 100644 --- a/src/mlpack/methods/adaboost/adaboost_impl.hpp +++ b/src/mlpack/methods/adaboost/adaboost_impl.hpp @@ -163,9 +163,8 @@ void AdaBoost::Classify( probabilities(prediction) += alpha[i]; } - arma::uword maxIndex = 0; probabilities /= accu(probabilities); - probabilities.max(maxIndex); + arma::uword maxIndex = probabilities.index_max(); prediction = (size_t) maxIndex; } @@ -204,7 +203,7 @@ void AdaBoost::Classify( for (size_t i = 0; i < predictedLabels.n_cols; ++i) { probabilities.col(i) /= accu(probabilities.col(i)); - probabilities.col(i).max(maxIndex); + maxIndex = probabilities.col(i).index_max(); predictedLabels(i) = maxIndex; } } diff --git a/src/mlpack/methods/ann/loss_functions/vr_class_reward_impl.hpp b/src/mlpack/methods/ann/loss_functions/vr_class_reward_impl.hpp index 9f67233995..ee85009819 100644 --- a/src/mlpack/methods/ann/loss_functions/vr_class_reward_impl.hpp +++ b/src/mlpack/methods/ann/loss_functions/vr_class_reward_impl.hpp @@ -49,7 +49,7 @@ typename MatType::elem_type VRClassRewardType::Forward( for (size_t i = 0; i < input.n_cols - 1; ++i) { - input.unsafe_col(i).max(index); + index = input.unsafe_col(i).index_max(); reward = (index == target(i)) * scale; } diff --git a/src/mlpack/methods/approx_kfn/drusilla_select_impl.hpp b/src/mlpack/methods/approx_kfn/drusilla_select_impl.hpp index f66d701893..89988b0a71 100644 --- a/src/mlpack/methods/approx_kfn/drusilla_select_impl.hpp +++ b/src/mlpack/methods/approx_kfn/drusilla_select_impl.hpp @@ -94,8 +94,7 @@ void DrusillaSelect::Train( for (size_t i = 0; i < l; ++i) { // Pick best index. - arma::uword maxIndex = 0; - norms.max(maxIndex); + arma::uword maxIndex = norms.index_max(); arma::vec line(refCopy.col(maxIndex) / norm(refCopy.col(maxIndex))); diff --git a/src/mlpack/methods/decision_tree/decision_tree_impl.hpp b/src/mlpack/methods/decision_tree/decision_tree_impl.hpp index c677e34c47..4bb8cfeb62 100644 --- a/src/mlpack/methods/decision_tree/decision_tree_impl.hpp +++ b/src/mlpack/methods/decision_tree/decision_tree_impl.hpp @@ -1159,8 +1159,7 @@ void DecisionTree::Predict(const arma::mat& dataSeq, for (size_t j = 0; j < logTransition.n_rows; j++) { arma::vec prob = logStateProb.col(t - 1) + logTransition.row(j).t(); - logStateProb(j, t) = prob.max(index) + logProbs(t, j); + index = prob.index_max(); + logStateProb(j, t) = prob[index] + logProbs(t, j); stateSeqBack(j, t) = index; } } // Backtrack to find the most probable state sequence. - logStateProb.unsafe_col(dataSeq.n_cols - 1).max(index); + index = logStateProb.unsafe_col(dataSeq.n_cols - 1).index_max(); stateSeq[dataSeq.n_cols - 1] = index; for (size_t t = 2; t <= dataSeq.n_cols; t++) { diff --git a/src/mlpack/methods/hoeffding_trees/binary_numeric_split_impl.hpp b/src/mlpack/methods/hoeffding_trees/binary_numeric_split_impl.hpp index bd5cbb5de2..85dd641503 100644 --- a/src/mlpack/methods/hoeffding_trees/binary_numeric_split_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/binary_numeric_split_impl.hpp @@ -141,10 +141,9 @@ void BinaryNumericSplit::Split( } // Calculate the majority classes of the children. - arma::uword maxIndex; - counts.unsafe_col(0).max(maxIndex); + arma::uword maxIndex = counts.unsafe_col(0).index_max(); childMajorities[0] = size_t(maxIndex); - counts.unsafe_col(1).max(maxIndex); + maxIndex = counts.unsafe_col(1).index_max(); childMajorities[1] = size_t(maxIndex); // Create the according SplitInfo object. @@ -155,8 +154,7 @@ template size_t BinaryNumericSplit::MajorityClass() const { - arma::uword maxIndex; - classCounts.max(maxIndex); + arma::uword maxIndex = classCounts.index_max(); return size_t(maxIndex); } diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_categorical_split_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_categorical_split_impl.hpp index 6e35b5a1c3..810d7dc638 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_categorical_split_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_categorical_split_impl.hpp @@ -64,8 +64,7 @@ void HoeffdingCategoricalSplit::Split( childMajorities.set_size(sufficientStatistics.n_cols); for (size_t i = 0; i < sufficientStatistics.n_cols; ++i) { - arma::uword maxIndex = 0; - sufficientStatistics.unsafe_col(i).max(maxIndex); + arma::uword maxIndex = sufficientStatistics.unsafe_col(i).index_max(); childMajorities[i] = size_t(maxIndex); } @@ -79,8 +78,7 @@ size_t HoeffdingCategoricalSplit::MajorityClass() const // Calculate the class that we have seen the most of. arma::Col classCounts = sum(sufficientStatistics, 1); - arma::uword maxIndex = 0; - classCounts.max(maxIndex); + arma::uword maxIndex = classCounts.index_max(); return size_t(maxIndex); } diff --git a/src/mlpack/methods/hoeffding_trees/hoeffding_numeric_split_impl.hpp b/src/mlpack/methods/hoeffding_trees/hoeffding_numeric_split_impl.hpp index 617ff288c7..e6b425a805 100644 --- a/src/mlpack/methods/hoeffding_trees/hoeffding_numeric_split_impl.hpp +++ b/src/mlpack/methods/hoeffding_trees/hoeffding_numeric_split_impl.hpp @@ -122,8 +122,7 @@ void HoeffdingNumericSplit::Split( childMajorities.set_size(sufficientStatistics.n_cols); for (size_t i = 0; i < sufficientStatistics.n_cols; ++i) { - arma::uword maxIndex = 0; - sufficientStatistics.unsafe_col(i).max(maxIndex); + arma::uword maxIndex = sufficientStatistics.unsafe_col(i).index_max(); childMajorities[i] = size_t(maxIndex); } @@ -144,8 +143,7 @@ size_t HoeffdingNumericSplit:: for (size_t i = 0; i < samplesSeen; ++i) classes[labels[i]]++; - arma::uword majorityClass; - classes.max(majorityClass); + arma::uword majorityClass = classes.index_max(); return size_t(majorityClass); } else @@ -154,8 +152,7 @@ size_t HoeffdingNumericSplit:: // statistics. arma::Col classCounts = sum(sufficientStatistics, 1); - arma::uword maxIndex = 0; - classCounts.max(maxIndex); + arma::uword maxIndex = classCounts.index_max(); return size_t(maxIndex); } } diff --git a/src/mlpack/methods/kmeans/max_variance_new_cluster_impl.hpp b/src/mlpack/methods/kmeans/max_variance_new_cluster_impl.hpp index c3a86845c5..87b4a9ca71 100644 --- a/src/mlpack/methods/kmeans/max_variance_new_cluster_impl.hpp +++ b/src/mlpack/methods/kmeans/max_variance_new_cluster_impl.hpp @@ -35,8 +35,7 @@ void MaxVarianceNewCluster::EmptyCluster(const MatType& data, this->iteration = iteration; // Now find the cluster with maximum variance. - arma::uword maxVarCluster = 0; - variances.max(maxVarCluster); + arma::uword maxVarCluster = variances.index_max(); // If the cluster with maximum variance has variance of 0, then we can't // continue. All the points are the same. diff --git a/src/mlpack/methods/naive_bayes/naive_bayes_classifier_impl.hpp b/src/mlpack/methods/naive_bayes/naive_bayes_classifier_impl.hpp index 16343bc01c..bc4c22dbaf 100644 --- a/src/mlpack/methods/naive_bayes/naive_bayes_classifier_impl.hpp +++ b/src/mlpack/methods/naive_bayes/naive_bayes_classifier_impl.hpp @@ -258,8 +258,7 @@ size_t NaiveBayesClassifier::Classify(const VecType& point) const ModelMatType logLikelihoods; LogLikelihood(point, logLikelihoods); - arma::uword maxIndex = 0; - logLikelihoods.max(maxIndex); + arma::uword maxIndex = logLikelihoods.index_max(); return maxIndex; } @@ -301,8 +300,7 @@ void NaiveBayesClassifier::Classify( maxValue; probabilities = exp(logLikelihoods - logProbX); // log(exp(value)) == value. - arma::uword maxIndex = 0; - logLikelihoods.max(maxIndex); + arma::uword maxIndex = logLikelihoods.index_max(); prediction = (size_t) maxIndex; } @@ -332,8 +330,7 @@ void NaiveBayesClassifier::Classify( for (size_t i = 0; i < data.n_cols; ++i) { - arma::uword maxIndex = 0; - logLikelihoods.unsafe_col(i).max(maxIndex); + arma::uword maxIndex = logLikelihoods.unsafe_col(i).index_max(); predictions[i] = maxIndex; } } @@ -384,8 +381,7 @@ void NaiveBayesClassifier::Classify( // Now calculate maximum probabilities for each point. for (size_t i = 0; i < data.n_cols; ++i) { - arma::uword maxIndex = 0; - logLikelihoods.unsafe_col(i).max(maxIndex); + arma::uword maxIndex = logLikelihoods.unsafe_col(i).index_max(); predictions[i] = maxIndex; } } diff --git a/src/mlpack/methods/perceptron/perceptron_impl.hpp b/src/mlpack/methods/perceptron/perceptron_impl.hpp index c03533889c..d13351fccd 100644 --- a/src/mlpack/methods/perceptron/perceptron_impl.hpp +++ b/src/mlpack/methods/perceptron/perceptron_impl.hpp @@ -225,7 +225,7 @@ void Perceptron< size_t j, i = 0; bool converged = false; size_t tempLabel; - arma::uword maxIndexRow = 0, maxIndexCol = 0; + arma::uword maxIndexRow = 0; arma::Mat tempLabelMat; LearnPolicy LP; @@ -244,7 +244,8 @@ void Perceptron< // correctly classifies this. tempLabelMat = weights.t() * data.col(j) + biases; - tempLabelMat.max(maxIndexRow, maxIndexCol); + maxIndexRow = arma::ind2sub(arma::size(tempLabelMat), + tempLabelMat.index_max())(0); // Check whether prediction is correct. if (maxIndexRow != labels(0, j)) @@ -289,7 +290,7 @@ size_t Perceptron::Classify( arma::uword maxIndex = 0; tempLabelVec = weights.t() * point + biases; - tempLabelVec.max(maxIndex); + maxIndex = tempLabelVec.index_max(); return size_t(maxIndex); } @@ -322,7 +323,7 @@ void Perceptron::Classify( for (size_t i = 0; i < test.n_cols; ++i) { tempLabelMat = weights.t() * test.col(i) + biases; - tempLabelMat.max(maxIndex); + maxIndex = tempLabelMat.index_max(); predictedLabels(i) = maxIndex; } } diff --git a/src/mlpack/methods/radical/radical_impl.hpp b/src/mlpack/methods/radical/radical_impl.hpp index 6926919c99..8327a85d14 100644 --- a/src/mlpack/methods/radical/radical_impl.hpp +++ b/src/mlpack/methods/radical/radical_impl.hpp @@ -103,8 +103,7 @@ inline typename MatType::elem_type Radical::Apply2D(const MatType& matX, values(i) = Vasicek(candidateY1, m) + Vasicek(candidateY2, m); } - arma::uword indOpt = 0; - values.min(indOpt); // we ignore the return value; we don't care about it + arma::uword indOpt = values.index_min(); return (indOpt / (ElemType) angles) * M_PI / 2.0; } diff --git a/src/mlpack/methods/random_forest/random_forest_impl.hpp b/src/mlpack/methods/random_forest/random_forest_impl.hpp index 5946d1a66c..2214111192 100644 --- a/src/mlpack/methods/random_forest/random_forest_impl.hpp +++ b/src/mlpack/methods/random_forest/random_forest_impl.hpp @@ -356,8 +356,7 @@ void RandomForest< // Find maximum element after renormalizing probabilities. probabilities /= trees.size(); - arma::uword maxIndex = 0; - probabilities.max(maxIndex); + arma::uword maxIndex = probabilities.index_max(); // Set prediction. prediction = (size_t) maxIndex; diff --git a/src/mlpack/tests/adaboost_test.cpp b/src/mlpack/tests/adaboost_test.cpp index 5d6c456731..d9fe4826a2 100644 --- a/src/mlpack/tests/adaboost_test.cpp +++ b/src/mlpack/tests/adaboost_test.cpp @@ -644,7 +644,7 @@ TEMPLATE_TEST_CASE("ClassifyTest_VERTEBRALCOL", "[AdaBoostTest]", mat, fmat) for (size_t i = 0; i < predictedLabels1.n_cols; ++i) { pRow = probabilities.unsafe_col(i); - pRow.max(maxIndex); + maxIndex = pRow.index_max(); REQUIRE(predictedLabels1(i) == maxIndex); REQUIRE(accu(probabilities.col(i)) == Approx(1)); } @@ -714,7 +714,7 @@ TEMPLATE_TEST_CASE("ClassifyTest_NONLINSEP", "[AdaBoostTest]", mat, fmat) for (size_t i = 0; i < predictedLabels1.n_cols; ++i) { pRow = probabilities.unsafe_col(i); - pRow.max(maxIndex); + maxIndex = pRow.index_max(); REQUIRE(predictedLabels1(i) == maxIndex); REQUIRE(accu(probabilities.col(i)) == Approx(1).epsilon(1e-7)); } @@ -787,7 +787,7 @@ TEMPLATE_TEST_CASE("ClassifyTest_IRIS", "[AdaBoostTest]", mat, fmat) for (size_t i = 0; i < predictedLabels1.n_cols; ++i) { pRow = probabilities.unsafe_col(i); - pRow.max(maxIndex); + maxIndex = pRow.index_max(); REQUIRE(predictedLabels1(i) == maxIndex); REQUIRE(accu(probabilities.col(i)) == Approx(1).epsilon(1e-7)); } diff --git a/src/mlpack/tests/mean_shift_test.cpp b/src/mlpack/tests/mean_shift_test.cpp index b0dee3bc6a..579d1f230a 100644 --- a/src/mlpack/tests/mean_shift_test.cpp +++ b/src/mlpack/tests/mean_shift_test.cpp @@ -163,7 +163,8 @@ TEMPLATE_TEST_CASE("GaussianClustering", "[MeanShiftTest]", float, double) centroids.col(i)); // Are we near a centroid of a Gaussian? - const ElemType minVal = centroidDistances.min(minIndices[i]); + minIndices[i] = centroidDistances.index_min(); + const ElemType minVal = centroidDistances(minIndices[i]); success = (std::abs(minVal) <= 0.65); if (!success) break; @@ -240,7 +241,8 @@ TEMPLATE_TEST_CASE("GaussianClusteringCentroidsOnly", "[MeanShiftTest]", float, centroids.col(i)); // Are we near a centroid of a Gaussian? - const ElemType minVal = centroidDistances.min(minIndices[i]); + minIndices[i] = centroidDistances.index_min(); + const ElemType minVal = centroidDistances(minIndices[i]); success = (std::abs(minVal) <= 0.65); if (!success) break;