From 53351b2eceff2e5f256ad7f2352ee0a9a2ef7c6f Mon Sep 17 00:00:00 2001 From: morenol Date: Fri, 11 Dec 2020 16:52:39 -0400 Subject: [PATCH] fix needless-range and clippy::ptr_arg warnings. (#36) * Fix needless for loop range * Do not ignore clippy::ptr_arg --- src/algorithm/neighbour/bbd_tree.rs | 33 ++++++------ src/algorithm/neighbour/cover_tree.rs | 2 +- src/algorithm/neighbour/mod.rs | 1 + src/decomposition/pca.rs | 22 ++++---- src/ensemble/random_forest_classifier.rs | 14 ++--- src/lib.rs | 2 - src/linalg/evd.rs | 68 ++++++++++++------------ src/linalg/lu.rs | 13 ++--- src/linalg/naive/dense_matrix.rs | 45 ++++++++-------- src/linalg/qr.rs | 8 +-- src/linalg/stats.rs | 16 +++--- src/linalg/svd.rs | 32 +++++------ src/linear/bg_solver.rs | 6 +-- src/linear/lasso.rs | 12 ++--- src/linear/logistic_regression.rs | 12 ++--- src/linear/ridge_regression.rs | 12 ++--- src/math/distance/euclidian.rs | 2 +- src/metrics/auc.rs | 4 +- src/metrics/cluster_helpers.rs | 9 ++-- src/model_selection/mod.rs | 12 ++--- src/naive_bayes/bernoulli.rs | 4 +- src/naive_bayes/gaussian.rs | 6 +-- src/naive_bayes/multinomial.rs | 4 +- src/neighbors/knn_classifier.rs | 4 +- src/optimization/line_search.rs | 2 +- src/tree/decision_tree_classifier.rs | 57 ++++++++++---------- src/tree/decision_tree_regressor.rs | 25 ++++----- 27 files changed, 208 insertions(+), 219 deletions(-) diff --git a/src/algorithm/neighbour/bbd_tree.rs b/src/algorithm/neighbour/bbd_tree.rs index 85e6628..0d11fc6 100644 --- a/src/algorithm/neighbour/bbd_tree.rs +++ b/src/algorithm/neighbour/bbd_tree.rs @@ -44,10 +44,7 @@ impl BBDTree { let (n, _) = data.shape(); - let mut index = vec![0; n]; - for i in 0..n { - index[i] = i; - } + let index = (0..n).collect::>(); let mut tree = BBDTree { nodes, @@ -64,7 +61,7 @@ impl BBDTree { pub(in crate) fn clustering( &self, - centroids: &Vec>, + centroids: &[Vec], sums: &mut Vec>, counts: &mut Vec, membership: &mut Vec, @@ -92,8 +89,8 @@ impl BBDTree { fn filter( &self, node: usize, - centroids: &Vec>, - candidates: &Vec, + centroids: &[Vec], + candidates: &[usize], k: usize, sums: &mut Vec>, counts: &mut Vec, @@ -117,15 +114,15 @@ impl BBDTree { let mut new_candidates = vec![0; k]; let mut newk = 0; - for i in 0..k { + for candidate in candidates.iter().take(k) { if !BBDTree::prune( &self.nodes[node].center, &self.nodes[node].radius, centroids, closest, - candidates[i], + *candidate, ) { - new_candidates[newk] = candidates[i]; + new_candidates[newk] = *candidate; newk += 1; } } @@ -166,9 +163,9 @@ impl BBDTree { } fn prune( - center: &Vec, - radius: &Vec, - centroids: &Vec>, + center: &[T], + radius: &[T], + centroids: &[Vec], best_index: usize, test_index: usize, ) -> bool { @@ -285,8 +282,8 @@ impl BBDTree { } let mut mean = vec![T::zero(); d]; - for i in 0..d { - mean[i] = node.sum[i] / T::from(node.count).unwrap(); + for (i, mean_i) in mean.iter_mut().enumerate().take(d) { + *mean_i = node.sum[i] / T::from(node.count).unwrap(); } node.cost = BBDTree::node_cost(&self.nodes[node.lower.unwrap()], &mean) @@ -295,11 +292,11 @@ impl BBDTree { self.add_node(node) } - fn node_cost(node: &BBDTreeNode, center: &Vec) -> T { + fn node_cost(node: &BBDTreeNode, center: &[T]) -> T { let d = center.len(); let mut scatter = T::zero(); - for i in 0..d { - let x = (node.sum[i] / T::from(node.count).unwrap()) - center[i]; + for (i, center_i) in center.iter().enumerate().take(d) { + let x = (node.sum[i] / T::from(node.count).unwrap()) - *center_i; scatter += x * x; } node.cost + T::from(node.count).unwrap() * scatter diff --git a/src/algorithm/neighbour/cover_tree.rs b/src/algorithm/neighbour/cover_tree.rs index e7dbac0..2fe7792 100644 --- a/src/algorithm/neighbour/cover_tree.rs +++ b/src/algorithm/neighbour/cover_tree.rs @@ -436,7 +436,7 @@ impl> CoverTree } } - fn max(&self, distance_set: &Vec>) -> F { + fn max(&self, distance_set: &[DistanceSet]) -> F { let mut max = F::zero(); for n in distance_set { if max < n.dist[n.dist.len() - 1] { diff --git a/src/algorithm/neighbour/mod.rs b/src/algorithm/neighbour/mod.rs index 7ef1c5c..bf9e669 100644 --- a/src/algorithm/neighbour/mod.rs +++ b/src/algorithm/neighbour/mod.rs @@ -1,3 +1,4 @@ +#![allow(clippy::ptr_arg)] //! # Nearest Neighbors Search Algorithms and Data Structures //! //! Nearest neighbor search is a basic computational tool that is particularly relevant to machine learning, diff --git a/src/decomposition/pca.rs b/src/decomposition/pca.rs index f25aaad..9f5bd39 100644 --- a/src/decomposition/pca.rs +++ b/src/decomposition/pca.rs @@ -112,9 +112,9 @@ impl> PCA { let mut x = data.clone(); - for c in 0..n { + for (c, mu_c) in mu.iter().enumerate().take(n) { for r in 0..m { - x.sub_element_mut(r, c, mu[c]); + x.sub_element_mut(r, c, *mu_c); } } @@ -124,8 +124,8 @@ impl> PCA { if m > n && !parameters.use_correlation_matrix { let svd = x.svd()?; eigenvalues = svd.s; - for i in 0..eigenvalues.len() { - eigenvalues[i] = eigenvalues[i] * eigenvalues[i]; + for eigenvalue in &mut eigenvalues { + *eigenvalue = *eigenvalue * (*eigenvalue); } eigenvectors = svd.V; @@ -149,8 +149,8 @@ impl> PCA { if parameters.use_correlation_matrix { let mut sd = vec![T::zero(); n]; - for i in 0..n { - sd[i] = cov.get(i, i).sqrt(); + for (i, sd_i) in sd.iter_mut().enumerate().take(n) { + *sd_i = cov.get(i, i).sqrt(); } for i in 0..n { @@ -166,9 +166,9 @@ impl> PCA { eigenvectors = evd.V; - for i in 0..n { + for (i, sd_i) in sd.iter().enumerate().take(n) { for j in 0..n { - eigenvectors.div_element_mut(i, j, sd[i]); + eigenvectors.div_element_mut(i, j, *sd_i); } } } else { @@ -188,9 +188,9 @@ impl> PCA { } let mut pmu = vec![T::zero(); n_components]; - for k in 0..n { - for i in 0..n_components { - pmu[i] += projection.get(i, k) * mu[k]; + for (k, mu_k) in mu.iter().enumerate().take(n) { + for (i, pmu_i) in pmu.iter_mut().enumerate().take(n_components) { + *pmu_i += projection.get(i, k) * (*mu_k); } } diff --git a/src/ensemble/random_forest_classifier.rs b/src/ensemble/random_forest_classifier.rs index 011b0ba..7229d92 100644 --- a/src/ensemble/random_forest_classifier.rs +++ b/src/ensemble/random_forest_classifier.rs @@ -132,9 +132,9 @@ impl RandomForestClassifier { let mut yi: Vec = vec![0; y_ncols]; let classes = y_m.unique(); - for i in 0..y_ncols { + for (i, yi_i) in yi.iter_mut().enumerate().take(y_ncols) { let yc = y_m.get(0, i); - yi[i] = classes.iter().position(|c| yc == *c).unwrap(); + *yi_i = classes.iter().position(|c| yc == *c).unwrap(); } let mtry = parameters.m.unwrap_or_else(|| { @@ -192,22 +192,22 @@ impl RandomForestClassifier { which_max(&result) } - fn sample_with_replacement(y: &Vec, num_classes: usize) -> Vec { + fn sample_with_replacement(y: &[usize], num_classes: usize) -> Vec { let mut rng = rand::thread_rng(); let class_weight = vec![1.; num_classes]; let nrows = y.len(); let mut samples = vec![0; nrows]; - for l in 0..num_classes { + for (l, class_weight_l) in class_weight.iter().enumerate().take(num_classes) { let mut n_samples = 0; let mut index: Vec = Vec::new(); - for i in 0..nrows { - if y[i] == l { + for (i, y_i) in y.iter().enumerate().take(nrows) { + if *y_i == l { index.push(i); n_samples += 1; } } - let size = ((n_samples as f64) / class_weight[l]) as usize; + let size = ((n_samples as f64) / *class_weight_l) as usize; for _ in 0..size { let xi: usize = rng.gen_range(0, n_samples); samples[index[xi]] += 1; diff --git a/src/lib.rs b/src/lib.rs index ada7925..9290c86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,4 @@ #![allow( - clippy::needless_range_loop, - clippy::ptr_arg, clippy::type_complexity, clippy::too_many_arguments, clippy::many_single_char_names diff --git a/src/linalg/evd.rs b/src/linalg/evd.rs index c216696..4c1b6c3 100644 --- a/src/linalg/evd.rs +++ b/src/linalg/evd.rs @@ -99,27 +99,27 @@ pub trait EVDDecomposableMatrix: BaseMatrix { fn tred2>(V: &mut M, d: &mut Vec, e: &mut Vec) { let (n, _) = V.shape(); - for i in 0..n { - d[i] = V.get(n - 1, i); + for (i, d_i) in d.iter_mut().enumerate().take(n) { + *d_i = V.get(n - 1, i); } for i in (1..n).rev() { let mut scale = T::zero(); let mut h = T::zero(); - for k in 0..i { - scale += d[k].abs(); + for d_k in d.iter().take(i) { + scale += d_k.abs(); } if scale == T::zero() { e[i] = d[i - 1]; - for j in 0..i { - d[j] = V.get(i - 1, j); + for (j, d_j) in d.iter_mut().enumerate().take(i) { + *d_j = V.get(i - 1, j); V.set(i, j, T::zero()); V.set(j, i, T::zero()); } } else { - for k in 0..i { - d[k] /= scale; - h += d[k] * d[k]; + for d_k in d.iter_mut().take(i) { + *d_k /= scale; + h += (*d_k) * (*d_k); } let mut f = d[i - 1]; let mut g = h.sqrt(); @@ -129,8 +129,8 @@ fn tred2>(V: &mut M, d: &mut Vec, e: &mut Vec e[i] = scale * g; h -= f * g; d[i - 1] = f - g; - for j in 0..i { - e[j] = T::zero(); + for e_j in e.iter_mut().take(i) { + *e_j = T::zero(); } for j in 0..i { @@ -170,16 +170,16 @@ fn tred2>(V: &mut M, d: &mut Vec, e: &mut Vec V.set(i, i, T::one()); let h = d[i + 1]; if h != T::zero() { - for k in 0..=i { - d[k] = V.get(k, i + 1) / h; + for (k, d_k) in d.iter_mut().enumerate().take(i + 1) { + *d_k = V.get(k, i + 1) / h; } for j in 0..=i { let mut g = T::zero(); for k in 0..=i { g += V.get(k, i + 1) * V.get(k, j); } - for k in 0..=i { - V.sub_element_mut(k, j, g * d[k]); + for (k, d_k) in d.iter().enumerate().take(i + 1) { + V.sub_element_mut(k, j, g * (*d_k)); } } } @@ -187,8 +187,8 @@ fn tred2>(V: &mut M, d: &mut Vec, e: &mut Vec V.set(k, i + 1, T::zero()); } } - for j in 0..n { - d[j] = V.get(n - 1, j); + for (j, d_j) in d.iter_mut().enumerate().take(n) { + *d_j = V.get(n - 1, j); V.set(n - 1, j, T::zero()); } V.set(n - 1, n - 1, T::one()); @@ -238,8 +238,8 @@ fn tql2>(V: &mut M, d: &mut Vec, e: &mut Vec< d[l + 1] = e[l] * (p + r); let dl1 = d[l + 1]; let mut h = g - d[l]; - for i in l + 2..n { - d[i] -= h; + for d_i in d.iter_mut().take(n).skip(l + 2) { + *d_i -= h; } f += h; @@ -285,10 +285,10 @@ fn tql2>(V: &mut M, d: &mut Vec, e: &mut Vec< for i in 0..n - 1 { let mut k = i; let mut p = d[i]; - for j in i + 1..n { - if d[j] > p { + for (j, d_j) in d.iter().enumerate().take(n).skip(i + 1) { + if *d_j > p { k = j; - p = d[j]; + p = *d_j; } } if k != i { @@ -316,7 +316,7 @@ fn balance>(A: &mut M) -> Vec { let mut done = false; while !done { done = true; - for i in 0..n { + for (i, scale_i) in scale.iter_mut().enumerate().take(n) { let mut r = T::zero(); let mut c = T::zero(); for j in 0..n { @@ -341,7 +341,7 @@ fn balance>(A: &mut M) -> Vec { if (c + r) / f < t * s { done = false; g = T::one() / f; - scale[i] *= f; + *scale_i *= f; for j in 0..n { A.mul_element_mut(i, j, g); } @@ -360,7 +360,7 @@ fn elmhes>(A: &mut M) -> Vec { let (n, _) = A.shape(); let mut perm = vec![0; n]; - for m in 1..n - 1 { + for (m, perm_m) in perm.iter_mut().enumerate().take(n - 1).skip(1) { let mut x = T::zero(); let mut i = m; for j in m..n { @@ -369,7 +369,7 @@ fn elmhes>(A: &mut M) -> Vec { i = j; } } - perm[m] = i; + *perm_m = i; if i != m { for j in (m - 1)..n { let swap = A.get(i, j); @@ -402,7 +402,7 @@ fn elmhes>(A: &mut M) -> Vec { perm } -fn eltran>(A: &M, V: &mut M, perm: &Vec) { +fn eltran>(A: &M, V: &mut M, perm: &[usize]) { let (n, _) = A.shape(); for mp in (1..n - 1).rev() { for k in mp + 1..n { @@ -774,11 +774,11 @@ fn hqr2>(A: &mut M, V: &mut M, d: &mut Vec, e } } -fn balbak>(V: &mut M, scale: &Vec) { +fn balbak>(V: &mut M, scale: &[T]) { let (n, _) = V.shape(); - for i in 0..n { + for (i, scale_i) in scale.iter().enumerate().take(n) { for j in 0..n { - V.mul_element_mut(i, j, scale[i]); + V.mul_element_mut(i, j, *scale_i); } } } @@ -789,8 +789,8 @@ fn sort>(d: &mut Vec, e: &mut Vec, V: &mut for j in 1..n { let real = d[j]; let img = e[j]; - for k in 0..n { - temp[k] = V.get(k, j); + for (k, temp_k) in temp.iter_mut().enumerate().take(n) { + *temp_k = V.get(k, j); } let mut i = j as i32 - 1; while i >= 0 { @@ -806,8 +806,8 @@ fn sort>(d: &mut Vec, e: &mut Vec, V: &mut } d[i as usize + 1] = real; e[i as usize + 1] = img; - for k in 0..n { - V.set(k, i as usize + 1, temp[k]); + for (k, temp_k) in temp.iter().enumerate().take(n) { + V.set(k, i as usize + 1, *temp_k); } } } diff --git a/src/linalg/lu.rs b/src/linalg/lu.rs index bfc7fff..6daed69 100644 --- a/src/linalg/lu.rs +++ b/src/linalg/lu.rs @@ -202,24 +202,21 @@ pub trait LUDecomposableMatrix: BaseMatrix { fn lu_mut(mut self) -> Result, Failed> { let (m, n) = self.shape(); - let mut piv = vec![0; m]; - for i in 0..m { - piv[i] = i; - } + let mut piv = (0..m).collect::>(); let mut pivsign = 1; let mut LUcolj = vec![T::zero(); m]; for j in 0..n { - for i in 0..m { - LUcolj[i] = self.get(i, j); + for (i, LUcolj_i) in LUcolj.iter_mut().enumerate().take(m) { + *LUcolj_i = self.get(i, j); } for i in 0..m { let kmax = usize::min(i, j); let mut s = T::zero(); - for k in 0..kmax { - s += self.get(i, k) * LUcolj[k]; + for (k, LUcolj_k) in LUcolj.iter().enumerate().take(kmax) { + s += self.get(i, k) * (*LUcolj_k); } LUcolj[i] -= s; diff --git a/src/linalg/naive/dense_matrix.rs b/src/linalg/naive/dense_matrix.rs index 14e5e62..8c822d2 100644 --- a/src/linalg/naive/dense_matrix.rs +++ b/src/linalg/naive/dense_matrix.rs @@ -1,3 +1,4 @@ +#![allow(clippy::ptr_arg)] use std::fmt; use std::fmt::Debug; use std::marker::PhantomData; @@ -164,8 +165,8 @@ impl BaseVector for Vec { fn sum(&self) -> T { let mut sum = T::zero(); - for i in 0..self.len() { - sum += self[i]; + for self_i in self.iter() { + sum += *self_i; } sum } @@ -239,9 +240,9 @@ impl DenseMatrix { nrows, values: vec![T::zero(); ncols * nrows], }; - for row in 0..nrows { - for col in 0..ncols { - m.set(row, col, values[row][col]); + for (row_index, row) in values.iter().enumerate().take(nrows) { + for (col_index, value) in row.iter().enumerate().take(ncols) { + m.set(row_index, col_index, *value); } } m @@ -259,7 +260,7 @@ impl DenseMatrix { /// * `nrows` - number of rows in new matrix. /// * `ncols` - number of columns in new matrix. /// * `values` - values to initialize the matrix. - pub fn from_vec(nrows: usize, ncols: usize, values: &Vec) -> DenseMatrix { + pub fn from_vec(nrows: usize, ncols: usize, values: &[T]) -> DenseMatrix { let mut m = DenseMatrix { ncols, nrows, @@ -543,8 +544,8 @@ impl BaseMatrix for DenseMatrix { fn get_row(&self, row: usize) -> Self::RowVector { let mut v = vec![T::zero(); self.ncols]; - for c in 0..self.ncols { - v[c] = self.get(row, c); + for (c, v_c) in v.iter_mut().enumerate().take(self.ncols) { + *v_c = self.get(row, c); } v @@ -552,29 +553,29 @@ impl BaseMatrix for DenseMatrix { fn get_row_as_vec(&self, row: usize) -> Vec { let mut result = vec![T::zero(); self.ncols]; - for c in 0..self.ncols { - result[c] = self.get(row, c); + for (c, result_c) in result.iter_mut().enumerate().take(self.ncols) { + *result_c = self.get(row, c); } result } fn copy_row_as_vec(&self, row: usize, result: &mut Vec) { - for c in 0..self.ncols { - result[c] = self.get(row, c); + for (c, result_c) in result.iter_mut().enumerate().take(self.ncols) { + *result_c = self.get(row, c); } } fn get_col_as_vec(&self, col: usize) -> Vec { let mut result = vec![T::zero(); self.nrows]; - for r in 0..self.nrows { - result[r] = self.get(r, col); + for (r, result_r) in result.iter_mut().enumerate().take(self.nrows) { + *result_r = self.get(r, col); } result } fn copy_col_as_vec(&self, col: usize, result: &mut Vec) { - for r in 0..self.nrows { - result[r] = self.get(r, col); + for (r, result_r) in result.iter_mut().enumerate().take(self.nrows) { + *result_r = self.get(r, col); } } @@ -836,13 +837,13 @@ impl BaseMatrix for DenseMatrix { let mut mean = vec![T::zero(); self.ncols]; for r in 0..self.nrows { - for c in 0..self.ncols { - mean[c] += self.get(r, c); + for (c, mean_c) in mean.iter_mut().enumerate().take(self.ncols) { + *mean_c += self.get(r, c); } } - for i in 0..mean.len() { - mean[i] /= T::from(self.nrows).unwrap(); + for mean_i in mean.iter_mut() { + *mean_i /= T::from(self.nrows).unwrap(); } mean @@ -989,7 +990,7 @@ impl BaseMatrix for DenseMatrix { fn argmax(&self) -> Vec { let mut res = vec![0usize; self.nrows]; - for r in 0..self.nrows { + for (r, res_r) in res.iter_mut().enumerate().take(self.nrows) { let mut max = T::neg_infinity(); let mut max_pos = 0usize; for c in 0..self.ncols { @@ -999,7 +1000,7 @@ impl BaseMatrix for DenseMatrix { max_pos = c; } } - res[r] = max_pos; + *res_r = max_pos; } res diff --git a/src/linalg/qr.rs b/src/linalg/qr.rs index c3a7978..a06a01f 100644 --- a/src/linalg/qr.rs +++ b/src/linalg/qr.rs @@ -44,8 +44,8 @@ pub struct QR> { impl> QR { pub(crate) fn new(QR: M, tau: Vec) -> QR { let mut singular = false; - for j in 0..tau.len() { - if tau[j] == T::zero() { + for tau_elem in tau.iter() { + if *tau_elem == T::zero() { singular = true; break; } @@ -153,7 +153,7 @@ pub trait QRDecomposableMatrix: BaseMatrix { let mut r_diagonal: Vec = vec![T::zero(); n]; - for k in 0..n { + for (k, r_diagonal_k) in r_diagonal.iter_mut().enumerate().take(n) { let mut nrm = T::zero(); for i in k..m { nrm = nrm.hypot(self.get(i, k)); @@ -179,7 +179,7 @@ pub trait QRDecomposableMatrix: BaseMatrix { } } } - r_diagonal[k] = -nrm; + *r_diagonal_k = -nrm; } Ok(QR::new(self, r_diagonal)) diff --git a/src/linalg/stats.rs b/src/linalg/stats.rs index fff87c3..45a17af 100644 --- a/src/linalg/stats.rs +++ b/src/linalg/stats.rs @@ -22,14 +22,14 @@ pub trait MatrixStats: BaseMatrix { let div = T::from_usize(m).unwrap(); - for i in 0..n { + for (i, x_i) in x.iter_mut().enumerate().take(n) { for j in 0..m { - x[i] += match axis { + *x_i += match axis { 0 => self.get(j, i), _ => self.get(i, j), }; } - x[i] /= div; + *x_i /= div; } x @@ -49,7 +49,7 @@ pub trait MatrixStats: BaseMatrix { let div = T::from_usize(m).unwrap(); - for i in 0..n { + for (i, x_i) in x.iter_mut().enumerate().take(n) { let mut mu = T::zero(); let mut sum = T::zero(); for j in 0..m { @@ -61,7 +61,7 @@ pub trait MatrixStats: BaseMatrix { sum += a * a; } mu /= div; - x[i] = sum / div - mu * mu; + *x_i = sum / div - mu * mu; } x @@ -76,15 +76,15 @@ pub trait MatrixStats: BaseMatrix { _ => self.shape().0, }; - for i in 0..n { - x[i] = x[i].sqrt(); + for x_i in x.iter_mut().take(n) { + *x_i = x_i.sqrt(); } x } /// standardize values by removing the mean and scaling to unit variance - fn scale_mut(&mut self, mean: &Vec, std: &Vec, axis: u8) { + fn scale_mut(&mut self, mean: &[T], std: &[T], axis: u8) { let (n, m) = match axis { 0 => { let (n, m) = self.shape(); diff --git a/src/linalg/svd.rs b/src/linalg/svd.rs index 9271f5b..e370453 100644 --- a/src/linalg/svd.rs +++ b/src/linalg/svd.rs @@ -156,8 +156,8 @@ pub trait SVDDecomposableMatrix: BaseMatrix { let h = f * g - s; U.set(i, l - 1, f - g); - for k in l - 1..n { - rv1[k] = U.get(i, k) / h; + for (k, rv1_k) in rv1.iter_mut().enumerate().take(n).skip(l - 1) { + *rv1_k = U.get(i, k) / h; } for j in l - 1..m { @@ -166,8 +166,8 @@ pub trait SVDDecomposableMatrix: BaseMatrix { s += U.get(j, k) * U.get(i, k); } - for k in l - 1..n { - U.add_element_mut(j, k, s * rv1[k]); + for (k, rv1_k) in rv1.iter().enumerate().take(n).skip(l - 1) { + U.add_element_mut(j, k, s * (*rv1_k)); } } @@ -365,11 +365,11 @@ pub trait SVDDecomposableMatrix: BaseMatrix { inc /= 3; for i in inc..n { let sw = w[i]; - for k in 0..m { - su[k] = U.get(k, i); + for (k, su_k) in su.iter_mut().enumerate().take(m) { + *su_k = U.get(k, i); } - for k in 0..n { - sv[k] = v.get(k, i); + for (k, sv_k) in sv.iter_mut().enumerate().take(n) { + *sv_k = v.get(k, i); } let mut j = i; while w[j - inc] < sw { @@ -386,11 +386,11 @@ pub trait SVDDecomposableMatrix: BaseMatrix { } } w[j] = sw; - for k in 0..m { - U.set(k, j, su[k]); + for (k, su_k) in su.iter().enumerate().take(m) { + U.set(k, j, *su_k); } - for k in 0..n { - v.set(k, j, sv[k]); + for (k, sv_k) in sv.iter().enumerate().take(n) { + v.set(k, j, *sv_k); } } if inc <= 1 { @@ -454,7 +454,7 @@ impl> SVD { for k in 0..p { let mut tmp = vec![T::zero(); self.n]; - for j in 0..self.n { + for (j, tmp_j) in tmp.iter_mut().enumerate().take(self.n) { let mut r = T::zero(); if self.s[j] > self.tol { for i in 0..self.m { @@ -462,13 +462,13 @@ impl> SVD { } r /= self.s[j]; } - tmp[j] = r; + *tmp_j = r; } for j in 0..self.n { let mut r = T::zero(); - for jj in 0..self.n { - r += self.V.get(j, jj) * tmp[jj]; + for (jj, tmp_jj) in tmp.iter().enumerate().take(self.n) { + r += self.V.get(j, jj) * (*tmp_jj); } b.set(j, k, r); } diff --git a/src/linear/bg_solver.rs b/src/linear/bg_solver.rs index b299623..46ef13d 100644 --- a/src/linear/bg_solver.rs +++ b/src/linear/bg_solver.rs @@ -85,9 +85,9 @@ pub trait BiconjugateGradientSolver> { let diag = Self::diag(a); let n = diag.len(); - for i in 0..n { - if diag[i] != T::zero() { - x.set(i, 0, b.get(i, 0) / diag[i]); + for (i, diag_i) in diag.iter().enumerate().take(n) { + if *diag_i != T::zero() { + x.set(i, 0, b.get(i, 0) / *diag_i); } else { x.set(i, 0, b.get(i, 0)); } diff --git a/src/linear/lasso.rs b/src/linear/lasso.rs index 965c1c4..490694c 100644 --- a/src/linear/lasso.rs +++ b/src/linear/lasso.rs @@ -120,14 +120,14 @@ impl> Lasso { let mut w = optimizer.optimize(&scaled_x, y, ¶meters)?; - for j in 0..p { - w.set(j, 0, w.get(j, 0) / col_std[j]); + for (j, col_std_j) in col_std.iter().enumerate().take(p) { + w.set(j, 0, w.get(j, 0) / *col_std_j); } let mut b = T::zero(); - for i in 0..p { - b += w.get(i, 0) * col_mean[i]; + for (i, col_mean_i) in col_mean.iter().enumerate().take(p) { + b += w.get(i, 0) * *col_mean_i; } b = y.mean() - b; @@ -169,8 +169,8 @@ impl> Lasso { let col_mean = x.mean(0); let col_std = x.std(0); - for i in 0..col_std.len() { - if (col_std[i] - T::zero()).abs() < T::epsilon() { + for (i, col_std_i) in col_std.iter().enumerate() { + if (*col_std_i - T::zero()).abs() < T::epsilon() { return Err(Failed::fit(&format!( "Cannot rescale constant column {}", i diff --git a/src/linear/logistic_regression.rs b/src/linear/logistic_regression.rs index a3674b3..7b7cab6 100644 --- a/src/linear/logistic_regression.rs +++ b/src/linear/logistic_regression.rs @@ -228,9 +228,9 @@ impl> LogisticRegression { let mut yi: Vec = vec![0; y_nrows]; - for i in 0..y_nrows { + for (i, yi_i) in yi.iter_mut().enumerate().take(y_nrows) { let yc = y_m.get(0, i); - yi[i] = classes.iter().position(|c| yc == *c).unwrap(); + *yi_i = classes.iter().position(|c| yc == *c).unwrap(); } match k.cmp(&2) { @@ -291,11 +291,11 @@ impl> LogisticRegression { if self.num_classes == 2 { let y_hat: Vec = x.ab(false, &self.coefficients, true).get_col_as_vec(0); let intercept = self.intercept.get(0, 0); - for i in 0..n { + for (i, y_hat_i) in y_hat.iter().enumerate().take(n) { result.set( 0, i, - self.classes[if (y_hat[i] + intercept).sigmoid() > T::half() { + self.classes[if (*y_hat_i + intercept).sigmoid() > T::half() { 1 } else { 0 @@ -310,8 +310,8 @@ impl> LogisticRegression { } } let class_idxs = y_hat.argmax(); - for i in 0..n { - result.set(0, i, self.classes[class_idxs[i]]); + for (i, class_i) in class_idxs.iter().enumerate().take(n) { + result.set(0, i, self.classes[*class_i]); } } Ok(result.to_row_vector()) diff --git a/src/linear/ridge_regression.rs b/src/linear/ridge_regression.rs index bb03c54..98bc639 100644 --- a/src/linear/ridge_regression.rs +++ b/src/linear/ridge_regression.rs @@ -155,14 +155,14 @@ impl> RidgeRegression { RidgeRegressionSolverName::SVD => x_t_x.svd_solve_mut(x_t_y)?, }; - for i in 0..p { - w.set(i, 0, w.get(i, 0) / col_std[i]); + for (i, col_std_i) in col_std.iter().enumerate().take(p) { + w.set(i, 0, w.get(i, 0) / *col_std_i); } let mut b = T::zero(); - for i in 0..p { - b += w.get(i, 0) * col_mean[i]; + for (i, col_mean_i) in col_mean.iter().enumerate().take(p) { + b += w.get(i, 0) * *col_mean_i; } let b = y.mean() - b; @@ -196,8 +196,8 @@ impl> RidgeRegression { let col_mean = x.mean(0); let col_std = x.std(0); - for i in 0..col_std.len() { - if (col_std[i] - T::zero()).abs() < T::epsilon() { + for (i, col_std_i) in col_std.iter().enumerate() { + if (*col_std_i - T::zero()).abs() < T::epsilon() { return Err(Failed::fit(&format!( "Cannot rescale constant column {}", i diff --git a/src/math/distance/euclidian.rs b/src/math/distance/euclidian.rs index 31503bd..e292f9c 100644 --- a/src/math/distance/euclidian.rs +++ b/src/math/distance/euclidian.rs @@ -30,7 +30,7 @@ pub struct Euclidian {} impl Euclidian { #[inline] - pub(crate) fn squared_distance(x: &Vec, y: &Vec) -> T { + pub(crate) fn squared_distance(x: &[T], y: &[T]) -> T { if x.len() != y.len() { panic!("Input vector sizes are different."); } diff --git a/src/metrics/auc.rs b/src/metrics/auc.rs index 571dd49..0f8d56a 100644 --- a/src/metrics/auc.rs +++ b/src/metrics/auc.rs @@ -68,8 +68,8 @@ impl AUC { j += 1; } let r = T::from_usize(i + 1 + j).unwrap() / T::two(); - for k in i..j { - rank[k] = r; + for rank_k in rank.iter_mut().take(j).skip(i) { + *rank_k = r; } i = j - 1; } diff --git a/src/metrics/cluster_helpers.rs b/src/metrics/cluster_helpers.rs index 8d1e17e..a8fa7e5 100644 --- a/src/metrics/cluster_helpers.rs +++ b/src/metrics/cluster_helpers.rs @@ -1,3 +1,4 @@ +#![allow(clippy::ptr_arg)] use std::collections::HashMap; use crate::math::num::RealNumber; @@ -23,7 +24,7 @@ pub fn contingency_matrix( contingency_matrix } -pub fn entropy(data: &Vec) -> Option { +pub fn entropy(data: &[T]) -> Option { let mut bincounts = HashMap::with_capacity(data.len()); for e in data.iter() { @@ -44,17 +45,17 @@ pub fn entropy(data: &Vec) -> Option { Some(entropy) } -pub fn mutual_info_score(contingency: &Vec>) -> T { +pub fn mutual_info_score(contingency: &[Vec]) -> T { let mut contingency_sum = 0; let mut pi = vec![0; contingency.len()]; let mut pj = vec![0; contingency[0].len()]; let (mut nzx, mut nzy, mut nz_val) = (Vec::new(), Vec::new(), Vec::new()); for r in 0..contingency.len() { - for c in 0..contingency[0].len() { + for (c, pj_c) in pj.iter_mut().enumerate().take(contingency[0].len()) { contingency_sum += contingency[r][c]; pi[r] += contingency[r][c]; - pj[c] += contingency[r][c]; + *pj_c += contingency[r][c]; if contingency[r][c] > 0 { nzx.push(r); nzy.push(c); diff --git a/src/model_selection/mod.rs b/src/model_selection/mod.rs index b066b30..bc0f9b8 100644 --- a/src/model_selection/mod.rs +++ b/src/model_selection/mod.rs @@ -44,10 +44,10 @@ pub fn train_test_split>( let mut n_test = 0; let mut index = vec![false; n]; - for i in 0..n { + for index_i in index.iter_mut().take(n) { let p_test: f32 = rng.gen(); if p_test <= test_size { - index[i] = true; + *index_i = true; n_test += 1; } } @@ -62,8 +62,8 @@ pub fn train_test_split>( let mut r_train = 0; let mut r_test = 0; - for r in 0..n { - if index[r] { + for (r, index_r) in index.iter().enumerate().take(n) { + if *index_r { //sample belongs to test for c in 0..m { x_test.set(r_test, c, x.get(r, c)); @@ -133,8 +133,8 @@ impl BaseKFold for KFold { let mut fold_sizes = vec![n_samples / self.n_splits; self.n_splits]; // increment by one if odd - for i in 0..(n_samples % self.n_splits) { - fold_sizes[i] += 1; + for fold_size in fold_sizes.iter_mut().take(n_samples % self.n_splits) { + *fold_size += 1; } // generate the right array of arrays for test indices diff --git a/src/naive_bayes/bernoulli.rs b/src/naive_bayes/bernoulli.rs index 535b5ee..057b447 100644 --- a/src/naive_bayes/bernoulli.rs +++ b/src/naive_bayes/bernoulli.rs @@ -134,8 +134,8 @@ impl BernoulliNBDistribution { let mut feature_in_class_counter = vec![vec![T::zero(); n_features]; class_labels.len()]; for (row, class_index) in row_iter(x).zip(indices) { - for idx in 0..n_features { - feature_in_class_counter[class_index][idx] += row[idx]; + for (idx, row_i) in row.iter().enumerate().take(n_features) { + feature_in_class_counter[class_index][idx] += *row_i; } } diff --git a/src/naive_bayes/gaussian.rs b/src/naive_bayes/gaussian.rs index 8e7e37c..af5732d 100644 --- a/src/naive_bayes/gaussian.rs +++ b/src/naive_bayes/gaussian.rs @@ -119,9 +119,9 @@ impl GaussianNBDistribution { .into_iter() .map(|v| { let mut m = M::zeros(v.len(), n_features); - for row in 0..v.len() { - for col in 0..n_features { - m.set(row, col, v[row][col]); + for (row_i, v_i) in v.iter().enumerate() { + for (col_j, v_i_j) in v_i.iter().enumerate().take(n_features) { + m.set(row_i, col_j, *v_i_j); } } m diff --git a/src/naive_bayes/multinomial.rs b/src/naive_bayes/multinomial.rs index a70fd2d..be8a7da 100644 --- a/src/naive_bayes/multinomial.rs +++ b/src/naive_bayes/multinomial.rs @@ -122,8 +122,8 @@ impl MultinomialNBDistribution { let mut feature_in_class_counter = vec![vec![T::zero(); n_features]; class_labels.len()]; for (row, class_index) in row_iter(x).zip(indices) { - for idx in 0..n_features { - feature_in_class_counter[class_index][idx] += row[idx]; + for (idx, row_i) in row.iter().enumerate().take(n_features) { + feature_in_class_counter[class_index][idx] += *row_i; } } diff --git a/src/neighbors/knn_classifier.rs b/src/neighbors/knn_classifier.rs index 135594a..f940211 100644 --- a/src/neighbors/knn_classifier.rs +++ b/src/neighbors/knn_classifier.rs @@ -119,9 +119,9 @@ impl, T>> KNNClassifier { let mut yi: Vec = vec![0; y_n]; let classes = y_m.unique(); - for i in 0..y_n { + for (i, yi_i) in yi.iter_mut().enumerate().take(y_n) { let yc = y_m.get(0, i); - yi[i] = classes.iter().position(|c| yc == *c).unwrap(); + *yi_i = classes.iter().position(|c| yc == *c).unwrap(); } if x_n != y_n { diff --git a/src/optimization/line_search.rs b/src/optimization/line_search.rs index e6a3b80..99457c9 100644 --- a/src/optimization/line_search.rs +++ b/src/optimization/line_search.rs @@ -41,7 +41,7 @@ impl Default for Backtracking { } impl LineSearchMethod for Backtracking { - fn search<'a>( + fn search( &self, f: &(dyn Fn(T) -> T), _: &(dyn Fn(T) -> T), diff --git a/src/tree/decision_tree_classifier.rs b/src/tree/decision_tree_classifier.rs index 9fe1b1a..371bc4e 100644 --- a/src/tree/decision_tree_classifier.rs +++ b/src/tree/decision_tree_classifier.rs @@ -187,42 +187,42 @@ impl Node { struct NodeVisitor<'a, T: RealNumber, M: Matrix> { x: &'a M, - y: &'a Vec, + y: &'a [usize], node: usize, samples: Vec, - order: &'a Vec>, + order: &'a [Vec], true_child_output: usize, false_child_output: usize, level: u16, phantom: PhantomData<&'a T>, } -fn impurity(criterion: &SplitCriterion, count: &Vec, n: usize) -> T { +fn impurity(criterion: &SplitCriterion, count: &[usize], n: usize) -> T { let mut impurity = T::zero(); match criterion { SplitCriterion::Gini => { impurity = T::one(); - for i in 0..count.len() { - if count[i] > 0 { - let p = T::from(count[i]).unwrap() / T::from(n).unwrap(); + for count_i in count.iter() { + if *count_i > 0 { + let p = T::from(*count_i).unwrap() / T::from(n).unwrap(); impurity -= p * p; } } } SplitCriterion::Entropy => { - for i in 0..count.len() { - if count[i] > 0 { - let p = T::from(count[i]).unwrap() / T::from(n).unwrap(); + for count_i in count.iter() { + if *count_i > 0 { + let p = T::from(*count_i).unwrap() / T::from(n).unwrap(); impurity -= p * p.log2(); } } } SplitCriterion::ClassificationError => { - for i in 0..count.len() { - if count[i] > 0 { - impurity = impurity.max(T::from(count[i]).unwrap() / T::from(n).unwrap()); + for count_i in count.iter() { + if *count_i > 0 { + impurity = impurity.max(T::from(*count_i).unwrap() / T::from(n).unwrap()); } } impurity = (T::one() - impurity).abs(); @@ -236,9 +236,9 @@ impl<'a, T: RealNumber, M: Matrix> NodeVisitor<'a, T, M> { fn new( node_id: usize, samples: Vec, - order: &'a Vec>, + order: &'a [Vec], x: &'a M, - y: &'a Vec, + y: &'a [usize], level: u16, ) -> Self { NodeVisitor { @@ -255,13 +255,13 @@ impl<'a, T: RealNumber, M: Matrix> NodeVisitor<'a, T, M> { } } -pub(in crate) fn which_max(x: &Vec) -> usize { +pub(in crate) fn which_max(x: &[usize]) -> usize { let mut m = x[0]; let mut which = 0; - for i in 1..x.len() { - if x[i] > m { - m = x[i]; + for (i, x_i) in x.iter().enumerate().skip(1) { + if *x_i > m { + m = *x_i; which = i; } } @@ -304,9 +304,9 @@ impl DecisionTreeClassifier { let mut yi: Vec = vec![0; y_ncols]; - for i in 0..y_ncols { + for (i, yi_i) in yi.iter_mut().enumerate().take(y_ncols) { let yc = y_m.get(0, i); - yi[i] = classes.iter().position(|c| yc == *c).unwrap(); + *yi_i = classes.iter().position(|c| yc == *c).unwrap(); } let mut nodes: Vec> = Vec::new(); @@ -431,23 +431,20 @@ impl DecisionTreeClassifier { let parent_impurity = impurity(&self.parameters.criterion, &count, n); - let mut variables = vec![0; n_attr]; - for i in 0..n_attr { - variables[i] = i; - } + let mut variables = (0..n_attr).collect::>(); if mtry < n_attr { variables.shuffle(&mut rand::thread_rng()); } - for j in 0..mtry { + for variable in variables.iter().take(mtry) { self.find_best_split( visitor, n, &count, &mut false_count, parent_impurity, - variables[j], + *variable, ); } @@ -458,7 +455,7 @@ impl DecisionTreeClassifier { &mut self, visitor: &mut NodeVisitor<'_, T, M>, n: usize, - count: &Vec, + count: &[usize], false_count: &mut Vec, parent_impurity: T, j: usize, @@ -527,13 +524,13 @@ impl DecisionTreeClassifier { let mut fc = 0; let mut true_samples: Vec = vec![0; n]; - for i in 0..n { + for (i, true_sample) in true_samples.iter_mut().enumerate().take(n) { if visitor.samples[i] > 0 { if visitor.x.get(i, self.nodes[visitor.node].split_feature) <= self.nodes[visitor.node].split_value.unwrap_or_else(T::nan) { - true_samples[i] = visitor.samples[i]; - tc += true_samples[i]; + *true_sample = visitor.samples[i]; + tc += *true_sample; visitor.samples[i] = 0; } else { fc += visitor.samples[i]; diff --git a/src/tree/decision_tree_regressor.rs b/src/tree/decision_tree_regressor.rs index c30c9e2..5e80b4c 100644 --- a/src/tree/decision_tree_regressor.rs +++ b/src/tree/decision_tree_regressor.rs @@ -161,7 +161,7 @@ struct NodeVisitor<'a, T: RealNumber, M: Matrix> { y: &'a M, node: usize, samples: Vec, - order: &'a Vec>, + order: &'a [Vec], true_child_output: T, false_child_output: T, level: u16, @@ -171,7 +171,7 @@ impl<'a, T: RealNumber, M: Matrix> NodeVisitor<'a, T, M> { fn new( node_id: usize, samples: Vec, - order: &'a Vec>, + order: &'a [Vec], x: &'a M, y: &'a M, level: u16, @@ -219,9 +219,9 @@ impl DecisionTreeRegressor { let mut n = 0; let mut sum = T::zero(); - for i in 0..y_ncols { - n += samples[i]; - sum += T::from(samples[i]).unwrap() * y_m.get(0, i); + for (i, sample_i) in samples.iter().enumerate().take(y_ncols) { + n += *sample_i; + sum += T::from(*sample_i).unwrap() * y_m.get(0, i); } let root = Node::new(0, sum / T::from(n).unwrap()); @@ -312,10 +312,7 @@ impl DecisionTreeRegressor { let sum = self.nodes[visitor.node].output * T::from(n).unwrap(); - let mut variables = vec![0; n_attr]; - for i in 0..n_attr { - variables[i] = i; - } + let mut variables = (0..n_attr).collect::>(); if mtry < n_attr { variables.shuffle(&mut rand::thread_rng()); @@ -324,8 +321,8 @@ impl DecisionTreeRegressor { let parent_gain = T::from(n).unwrap() * self.nodes[visitor.node].output * self.nodes[visitor.node].output; - for j in 0..mtry { - self.find_best_split(visitor, n, sum, parent_gain, variables[j]); + for variable in variables.iter().take(mtry) { + self.find_best_split(visitor, n, sum, parent_gain, *variable); } self.nodes[visitor.node].split_score != Option::None @@ -399,13 +396,13 @@ impl DecisionTreeRegressor { let mut fc = 0; let mut true_samples: Vec = vec![0; n]; - for i in 0..n { + for (i, true_sample) in true_samples.iter_mut().enumerate().take(n) { if visitor.samples[i] > 0 { if visitor.x.get(i, self.nodes[visitor.node].split_feature) <= self.nodes[visitor.node].split_value.unwrap_or_else(T::nan) { - true_samples[i] = visitor.samples[i]; - tc += true_samples[i]; + *true_sample = visitor.samples[i]; + tc += *true_sample; visitor.samples[i] = 0; } else { fc += visitor.samples[i];