Skip to content

Commit 8276bdc

Browse files
authored
Update ndarray 0.14 (#110)
* Update ndarray 0.14 * approx = 0.4 * argmin = 0.4 * ndarray-csv = 0.5 * ndarray-linalg = 0.13 * ndarray-npy = 0.7 * ndarray-rand = 0.13 * ndarray-stats = 0.4 * num-traits = 0.2 * rand = 0.8 * rand-isaac = 0.3 * sprs = git master rev=761d4f0 * Fix spacing * Check Lapack error properly * Use sprs 0.9.4 branch * Update linfa-clustering * Update linfa-preprocessing * Use sprs 0.9.4 * Pin argmin 0.4.1 * Revert to argmin 0.4 to get argmin 0.4.3 fix
1 parent 2079957 commit 8276bdc

File tree

46 files changed

+223
-207
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+223
-207
lines changed

Cargo.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ blas = ["ndarray/blas"]
3535
[dependencies]
3636
num-traits = "0.2"
3737
thiserror = "1"
38-
rand = { version = "0.7", features = ["small_rng"] }
39-
ndarray = { version = "0.13", default-features = false, features = ["approx"] }
40-
ndarray-linalg = { version = "0.12.1", optional = true }
38+
rand = { version = "0.8", features = ["small_rng"] }
39+
ndarray = { version = "0.14", default-features = false, features = ["approx"] }
40+
ndarray-linalg = { version = "0.13", optional = true }
4141

4242
[dependencies.intel-mkl-src]
4343
version = "0.6.0"
@@ -57,8 +57,8 @@ default-features = false
5757
features = ["cblas"]
5858

5959
[dev-dependencies]
60-
ndarray-rand = "0.11"
61-
approx = { version = "0.3", default-features = false, features = ["std"] }
60+
ndarray-rand = "0.13"
61+
approx = { version = "0.4", default-features = false, features = ["std"] }
6262

6363
linfa-datasets = { path = "datasets", features = ["winequality", "iris", "diabetes"] }
6464

algorithms/linfa-bayes/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ keywords = ["factorization", "machine-learning", "linfa", "unsupervised"]
1111
categories = ["algorithms", "mathematics", "science"]
1212

1313
[dependencies]
14-
ndarray = { version = "0.13" , features = ["blas", "approx"]}
15-
ndarray-stats = "0.3"
14+
ndarray = { version = "0.14" , features = ["blas", "approx"]}
15+
ndarray-stats = "0.4"
1616
thiserror = "1"
1717

1818
linfa = { version = "0.3.1", path = "../.." }
1919

2020
[dev-dependencies]
21-
approx = "0.3"
21+
approx = "0.4"
2222
linfa-datasets = { version = "0.3.1", path = "../../datasets", features = ["winequality"] }

algorithms/linfa-clustering/Cargo.toml

+9-9
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ default-features = false
2828
features = ["std", "derive"]
2929

3030
[dependencies]
31-
ndarray = { version = "0.13", features = ["rayon", "approx"]}
32-
ndarray-linalg = "0.12"
33-
ndarray-rand = "0.11"
34-
ndarray-stats = "0.3"
35-
sprs = "0.7"
36-
num-traits = "0.1.32"
37-
rand_isaac = "0.2.0"
31+
ndarray = { version = "0.14", features = ["rayon", "approx"]}
32+
ndarray-linalg = "0.13"
33+
lax = "0.1"
34+
ndarray-rand = "0.13"
35+
ndarray-stats = "0.4"
36+
num-traits = "0.2"
37+
rand_isaac = "0.3"
3838

3939
linfa = { version = "0.3.1", path = "../.." }
4040
partitions = "0.2.4"
4141

4242
[dev-dependencies]
43-
ndarray-npy = { version = "0.5", default-features = false }
43+
ndarray-npy = { version = "0.7", default-features = false }
4444
criterion = "0.3"
4545
serde_json = "1"
46-
approx = "0.3"
46+
approx = "0.4"
4747

4848
[[bench]]
4949
name = "k_means"

algorithms/linfa-clustering/examples/appx_dbscan.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ fn main() {
5454

5555
// Save to disk our dataset (and the cluster label assigned to each observation)
5656
// We use the `npy` format for compatibility with NumPy
57-
write_npy("clustered_dataset.npy", records).expect("Failed to write .npy file");
57+
write_npy("clustered_dataset.npy", &records).expect("Failed to write .npy file");
5858
write_npy(
5959
"clustered_memberships.npy",
60-
cluster_memberships.map(|&x| x.map(|c| c as i64).unwrap_or(-1)),
60+
&cluster_memberships.map(|&x| x.map(|c| c as i64).unwrap_or(-1)),
6161
)
6262
.expect("Failed to write .npy file");
6363
}

algorithms/linfa-clustering/examples/dbscan.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ fn main() {
5151

5252
// Save to disk our dataset (and the cluster label assigned to each observation)
5353
// We use the `npy` format for compatibility with NumPy
54-
write_npy("clustered_dataset.npy", records).expect("Failed to write .npy file");
54+
write_npy("clustered_dataset.npy", &records).expect("Failed to write .npy file");
5555
write_npy(
5656
"clustered_memberships.npy",
57-
cluster_memberships.map(|&x| x.map(|c| c as i64).unwrap_or(-1)),
57+
&cluster_memberships.map(|&x| x.map(|c| c as i64).unwrap_or(-1)),
5858
)
5959
.expect("Failed to write .npy file");
6060
}

algorithms/linfa-clustering/examples/kmeans.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn main() {
3333

3434
// Save to disk our dataset (and the cluster label assigned to each observation)
3535
// We use the `npy` format for compatibility with NumPy
36-
write_npy("clustered_dataset.npy", records).expect("Failed to write .npy file");
37-
write_npy("clustered_memberships.npy", targets.map(|&x| x as u64))
36+
write_npy("clustered_dataset.npy", &records).expect("Failed to write .npy file");
37+
write_npy("clustered_memberships.npy", &targets.map(|&x| x as u64))
3838
.expect("Failed to write .npy file");
3939
}

algorithms/linfa-clustering/src/gaussian_mixture/algorithm.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<F: Float + Lapack + Scalar> GaussianMixtureModel<F> {
296296
let n_samples = observations.nrows();
297297
let (weights, means, covariances) = Self::estimate_gaussian_parameters(
298298
&observations,
299-
&log_resp.mapv(|v| v.exp()),
299+
&log_resp.mapv(|v| Scalar::exp(v)),
300300
&self.covar_type,
301301
reg_covar,
302302
)?;
@@ -325,9 +325,9 @@ impl<F: Float + Lapack + Scalar> GaussianMixtureModel<F> {
325325
) -> (Array1<F>, Array2<F>) {
326326
let weighted_log_prob = self.estimate_weighted_log_prob(&observations);
327327
let log_prob_norm = weighted_log_prob
328-
.mapv(|v| v.exp())
328+
.mapv(|v| Scalar::exp(v))
329329
.sum_axis(Axis(1))
330-
.mapv(|v| v.ln());
330+
.mapv(|v| Scalar::ln(v));
331331
let log_resp = weighted_log_prob - log_prob_norm.to_owned().insert_axis(Axis(1));
332332
(log_prob_norm, log_resp)
333333
}
@@ -384,12 +384,12 @@ impl<F: Float + Lapack + Scalar> GaussianMixtureModel<F> {
384384
.unwrap()
385385
.slice(s![.., ..; n_features+1])
386386
.to_owned()
387-
.mapv(|v| v.ln());
387+
.mapv(|v| Scalar::ln(v));
388388
log_diags.sum_axis(Axis(1))
389389
}
390390

391391
fn estimate_log_weights(&self) -> Array1<F> {
392-
self.weights().mapv(|v| v.ln())
392+
self.weights().mapv(|v| Scalar::ln(v))
393393
}
394394
}
395395

@@ -420,7 +420,7 @@ impl<'a, F: Float + Lapack + Scalar, R: Rng + SeedableRng + Clone, D: Data<Elem
420420
lower_bound =
421421
GaussianMixtureModel::<F>::compute_lower_bound(&log_resp, log_prob_norm);
422422
let change = lower_bound - prev_lower_bound;
423-
if change.abs() < self.tolerance() {
423+
if ndarray_rand::rand_distr::num_traits::Float::abs(change) < self.tolerance() {
424424
converged_iter = Some(n_iter);
425425
break;
426426
}
@@ -456,7 +456,7 @@ impl<F: Float + Lapack + Scalar, D: Data<Elem = F>> PredictRef<ArrayBase<D, Ix2>
456456
fn predict_ref<'a>(&'a self, observations: &ArrayBase<D, Ix2>) -> Array1<usize> {
457457
let (_, log_resp) = self.estimate_log_prob_resp(&observations);
458458
log_resp
459-
.mapv(|v| v.exp())
459+
.mapv(|v| Scalar::exp(v))
460460
.map_axis(Axis(1), |row| row.argmax().unwrap())
461461
}
462462
}
@@ -466,7 +466,8 @@ mod tests {
466466
use super::*;
467467
use crate::generate_blobs;
468468
use approx::{abs_diff_eq, assert_abs_diff_eq};
469-
use ndarray::{array, stack, ArrayView1, ArrayView2, Axis};
469+
use lax::error::Error;
470+
use ndarray::{array, concatenate, ArrayView1, ArrayView2, Axis};
470471
use ndarray_linalg::error::LinalgError;
471472
use ndarray_linalg::error::Result as LAResult;
472473
use ndarray_rand::rand::SeedableRng;
@@ -560,7 +561,7 @@ mod tests {
560561
let mut rng = Isaac64Rng::seed_from_u64(42);
561562
let xt = Array2::random_using((50, 1), Uniform::new(0., 1.), &mut rng);
562563
let yt = function_test_1d(&xt);
563-
let data = stack(Axis(1), &[xt.view(), yt.view()]).unwrap();
564+
let data = concatenate(Axis(1), &[xt.view(), yt.view()]).unwrap();
564565
let dataset = DatasetBase::from(data);
565566

566567
// Test that cholesky decomposition fails when reg_covariance is zero
@@ -571,7 +572,8 @@ mod tests {
571572
assert!(
572573
match gmm.expect_err("should generate an error with reg_covar being nul") {
573574
GmmError::LinalgError(e) => match e {
574-
LinalgError::Lapack { return_code: 2 } => true,
575+
LinalgError::Lapack(Error::LapackComputationalFailure { return_code: 2 }) =>
576+
true,
575577
_ => panic!("should be a lapack error 2"),
576578
},
577579
_ => panic!("should be a linear algebra error"),
@@ -588,7 +590,7 @@ mod tests {
588590
fn test_zeroed_reg_covar_const_failure() {
589591
// repeat values such that covariance is zero
590592
let xt = Array2::ones((50, 1));
591-
let data = stack(Axis(1), &[xt.view(), xt.view()]).unwrap();
593+
let data = concatenate(Axis(1), &[xt.view(), xt.view()]).unwrap();
592594
let dataset = DatasetBase::from(data);
593595

594596
// Test that cholesky decomposition fails when reg_covariance is zero
@@ -599,7 +601,8 @@ mod tests {
599601
assert!(
600602
match gmm.expect_err("should generate an error with reg_covar being nul") {
601603
GmmError::LinalgError(e) => match e {
602-
LinalgError::Lapack { return_code: 1 } => true,
604+
LinalgError::Lapack(Error::LapackComputationalFailure { return_code: 1 }) =>
605+
true,
603606
_ => panic!("should be a lapack error 1"),
604607
},
605608
_ => panic!("should be a linear algebra error"),

algorithms/linfa-clustering/src/k_means/algorithm.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ mod tests {
595595
use super::super::KMeansInit;
596596
use super::*;
597597
use approx::assert_abs_diff_eq;
598-
use ndarray::{array, stack, Array, Array1, Array2, Axis};
598+
use ndarray::{array, concatenate, Array, Array1, Array2, Axis};
599599
use ndarray_rand::rand::SeedableRng;
600600
use ndarray_rand::rand_distr::Uniform;
601601
use ndarray_rand::RandomExt;
@@ -619,7 +619,7 @@ mod tests {
619619
let mut rng = Isaac64Rng::seed_from_u64(42);
620620
let xt = Array::random_using(100, Uniform::new(0., 1.0), &mut rng).insert_axis(Axis(1));
621621
let yt = function_test_1d(&xt);
622-
let data = stack(Axis(1), &[xt.view(), yt.view()]).unwrap();
622+
let data = concatenate(Axis(1), &[xt.view(), yt.view()]).unwrap();
623623

624624
for init in &[
625625
KMeansInit::Random,
@@ -673,9 +673,10 @@ mod tests {
673673
let memberships_2 = Array1::ones(cluster_size);
674674
let expected_centroid_2 = cluster_2.sum_axis(Axis(0)) / (cluster_size + 1) as f64;
675675

676-
// `stack` combines arrays along a given axis: https://docs.rs/ndarray/0.13.0/ndarray/fn.stack.html
677-
let observations = stack(Axis(0), &[cluster_1.view(), cluster_2.view()]).unwrap();
678-
let memberships = stack(Axis(0), &[memberships_1.view(), memberships_2.view()]).unwrap();
676+
// `concatenate` combines arrays along a given axis: https://docs.rs/ndarray/0.13.0/ndarray/fn.concatenate.html
677+
let observations = concatenate(Axis(0), &[cluster_1.view(), cluster_2.view()]).unwrap();
678+
let memberships =
679+
concatenate(Axis(0), &[memberships_1.view(), memberships_2.view()]).unwrap();
679680

680681
// Does it work?
681682
let old_centroids = Array2::zeros((2, n_features));

algorithms/linfa-clustering/src/k_means/init.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn k_means_para<R: Rng + SeedableRng, F: Float>(
135135
let mut candidates = Array2::zeros((n_clusters * n_rounds, n_features));
136136

137137
// Pick 1st centroid randomly
138-
let first_idx = rng.gen_range(0, n_samples);
138+
let first_idx = rng.gen_range(0..n_samples);
139139
candidates.row_mut(0).assign(&observations.row(first_idx));
140140
let mut n_candidates = 1;
141141

@@ -149,7 +149,7 @@ fn k_means_para<R: Rng + SeedableRng, F: Float>(
149149
let next_candidates_idx = sample_subsequent_candidates::<R, _>(
150150
&dists,
151151
F::from(candidates_per_round).unwrap(),
152-
rng.gen_range(0, std::u64::MAX),
152+
rng.gen_range(0..std::u64::MAX),
153153
);
154154

155155
// Append the newly generated candidates to the current cadidates, breaking out of the loop
@@ -199,7 +199,7 @@ fn sample_subsequent_candidates<R: Rng + SeedableRng, F: Float>(
199199
|| R::seed_from_u64(seed.fetch_add(1, Relaxed)),
200200
move |rng, (i, d)| {
201201
let d = *d.into_scalar();
202-
let rand = F::from(rng.gen_range(0.0, 1.0)).unwrap();
202+
let rand = F::from(rng.gen_range(0.0..1.0)).unwrap();
203203
let prob = multiplier * d / cost;
204204
(i, rand, prob)
205205
},
@@ -227,7 +227,7 @@ mod tests {
227227
use super::super::algorithm::{compute_inertia, update_cluster_memberships};
228228
use super::*;
229229
use approx::{abs_diff_eq, assert_abs_diff_eq, assert_abs_diff_ne};
230-
use ndarray::{array, stack, Array};
230+
use ndarray::{array, concatenate, Array};
231231
use ndarray_rand::rand::SeedableRng;
232232
use ndarray_rand::rand_distr::Normal;
233233
use ndarray_rand::RandomExt;
@@ -307,7 +307,7 @@ mod tests {
307307
// Make sure we don't panic on degenerate data (n_clusters > n_samples)
308308
let degenerate_data = array![[1.0, 2.0]];
309309
let out = init.run(2, degenerate_data.view(), &mut rng);
310-
assert_abs_diff_eq!(out, stack![Axis(0), degenerate_data, degenerate_data]);
310+
assert_abs_diff_eq!(out, concatenate![Axis(0), degenerate_data, degenerate_data]);
311311

312312
// Build 3 separated clusters of points
313313
let centroids = [20.0, -1000.0, 1000.0];
@@ -316,7 +316,7 @@ mod tests {
316316
.map(|&c| Array::random_using((50, 2), Normal::new(c, 1.).unwrap(), &mut rng))
317317
.collect();
318318
let obs = clusters.iter().fold(Array2::default((0, 2)), |a, b| {
319-
stack(Axis(0), &[a.view(), b.view()]).unwrap()
319+
concatenate(Axis(0), &[a.view(), b.view()]).unwrap()
320320
});
321321

322322
// Look for the right number of centroids
@@ -353,7 +353,7 @@ mod tests {
353353
.map(|&c| Array::random_using((50, 2), Normal::new(c, 1.).unwrap(), &mut rng))
354354
.collect();
355355
let obs = clusters.iter().fold(Array2::default((0, 2)), |a, b| {
356-
stack(Axis(0), &[a.view(), b.view()]).unwrap()
356+
concatenate(Axis(0), &[a.view(), b.view()]).unwrap()
357357
});
358358

359359
let out_rand = random_init(3, obs.view(), &mut rng.clone());

algorithms/linfa-elasticnet/Cargo.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ default-features = false
2828
features = ["std", "derive"]
2929

3030
[dependencies]
31-
ndarray = {version = "0.13", features = ["blas", "approx"]}
32-
ndarray-linalg = "0.12"
31+
ndarray = { version = "0.14", features = ["blas", "approx"]}
32+
ndarray-linalg = "0.13"
3333

3434
num-traits = "0.2"
35-
approx = "0.3.2"
35+
approx = "0.4"
3636
thiserror = "1"
3737

3838
linfa = { version = "0.3.1", path = "../.." }
3939

4040
[dev-dependencies]
4141
linfa-datasets = { version = "0.3.1", path = "../../datasets", features = ["diabetes"] }
42-
ndarray-rand = "0.11"
43-
rand_isaac = "0.2"
42+
ndarray-rand = "0.13"
43+
rand_isaac = "0.3"

algorithms/linfa-hierarchical/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ keywords = ["hierachical", "agglomerative", "clustering", "machine-learning", "l
1414
categories = ["algorithms", "mathematics", "science"]
1515

1616
[dependencies]
17-
ndarray = { version = "0.13", default-features = false }
17+
ndarray = { version = "0.14", default-features = false }
1818
kodama = "0.2"
1919

2020
linfa = { version = "0.3.1", path = "../.." }
2121
linfa-kernel = { version = "0.3.1", path = "../linfa-kernel" }
2222

2323
[dev-dependencies]
24-
rand = "0.7"
25-
ndarray-rand = "0.11"
24+
rand = "0.8"
25+
ndarray-rand = "0.13"
2626
linfa-datasets = { version = "0.3.1", path = "../../datasets", features = ["iris"] }

algorithms/linfa-hierarchical/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ mod tests {
186186
// we have 10 observations per cluster
187187
let npoints = 10;
188188
// generate data
189-
let entries = ndarray::stack(
189+
let entries = ndarray::concatenate(
190190
Axis(0),
191191
&[
192192
Array::random((npoints, 2), Normal::new(-1., 0.1).unwrap()).view(),

algorithms/linfa-ica/Cargo.toml

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ default-features = false
2424
features = ["std", "derive"]
2525

2626
[dependencies]
27-
ndarray = { version = "0.13", default-features = false }
28-
ndarray-linalg = "0.12"
29-
ndarray-rand = "0.11"
30-
ndarray-stats = "0.3"
27+
ndarray = { version = "0.14", default-features = false }
28+
ndarray-linalg = "0.13"
29+
ndarray-rand = "0.13"
30+
ndarray-stats = "0.4"
3131
num-traits = "0.2"
32-
rand_isaac = "0.2.0"
32+
rand_isaac = "0.3"
3333

3434
linfa = { version = "0.3.1", path = "../.." }
3535

3636
[dev-dependencies]
37-
ndarray-npy = { version = "0.5", default-features = false }
37+
ndarray-npy = { version = "0.7", default-features = false }
3838
paste = "1.0"

0 commit comments

Comments
 (0)