Run cargo fmt.

This commit is contained in:
sebcrozet 2020-04-05 18:49:48 +02:00
parent bc1b62d06a
commit bbb3be512e
125 changed files with 2136 additions and 1276 deletions

View File

@ -50,11 +50,13 @@ fn mat_div_scalar(b: &mut criterion::Criterion) {
let a = DMatrix::from_row_slice(1000, 1000, &vec![2.0; 1000000]); let a = DMatrix::from_row_slice(1000, 1000, &vec![2.0; 1000000]);
let n = 42.0; let n = 42.0;
b.bench_function("mat_div_scalar", move |bh| bh.iter(|| { b.bench_function("mat_div_scalar", move |bh| {
let mut aa = a.clone(); bh.iter(|| {
let mut b = aa.slice_mut((0, 0), (1000, 1000)); let mut aa = a.clone();
b /= n let mut b = aa.slice_mut((0, 0), (1000, 1000));
})); b /= n
})
});
} }
fn mat100_add_mat100(bench: &mut criterion::Criterion) { fn mat100_add_mat100(bench: &mut criterion::Criterion) {
@ -138,9 +140,11 @@ fn copy_from(bench: &mut criterion::Criterion) {
let a = DMatrix::<f64>::new_random(1000, 1000); let a = DMatrix::<f64>::new_random(1000, 1000);
let mut b = DMatrix::<f64>::new_random(1000, 1000); let mut b = DMatrix::<f64>::new_random(1000, 1000);
bench.bench_function("copy_from", move |bh| bh.iter(|| { bench.bench_function("copy_from", move |bh| {
b.copy_from(&a); bh.iter(|| {
})); b.copy_from(&a);
})
});
} }
fn axpy(bench: &mut criterion::Criterion) { fn axpy(bench: &mut criterion::Criterion) {
@ -148,9 +152,11 @@ fn axpy(bench: &mut criterion::Criterion) {
let mut y = DVector::<f64>::from_element(100000, 3.0); let mut y = DVector::<f64>::from_element(100000, 3.0);
let a = 42.0; let a = 42.0;
bench.bench_function("axpy", move |bh| bh.iter(|| { bench.bench_function("axpy", move |bh| {
y.axpy(a, &x, 1.0); bh.iter(|| {
})); y.axpy(a, &x, 1.0);
})
});
} }
fn tr_mul_to(bench: &mut criterion::Criterion) { fn tr_mul_to(bench: &mut criterion::Criterion) {
@ -166,60 +172,57 @@ fn mat_mul_mat(bench: &mut criterion::Criterion) {
let b = DMatrix::<f64>::new_random(100, 100); let b = DMatrix::<f64>::new_random(100, 100);
let mut ab = DMatrix::<f64>::from_element(100, 100, 0.0); let mut ab = DMatrix::<f64>::from_element(100, 100, 0.0);
bench.bench_function("mat_mul_mat", move |bh| bh.iter(|| { bench.bench_function("mat_mul_mat", move |bh| {
test::black_box(a.mul_to(&b, &mut ab)); bh.iter(|| {
})); test::black_box(a.mul_to(&b, &mut ab));
})
});
} }
fn mat100_from_fn(bench: &mut criterion::Criterion) { fn mat100_from_fn(bench: &mut criterion::Criterion) {
bench.bench_function("mat100_from_fn", move |bh| bh.iter(|| DMatrix::from_fn(100, 100, |a, b| a + b))); bench.bench_function("mat100_from_fn", move |bh| {
bh.iter(|| DMatrix::from_fn(100, 100, |a, b| a + b))
});
} }
fn mat500_from_fn(bench: &mut criterion::Criterion) { fn mat500_from_fn(bench: &mut criterion::Criterion) {
bench.bench_function("mat500_from_fn", move |bh| bh.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b))); bench.bench_function("mat500_from_fn", move |bh| {
bh.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b))
});
} }
criterion_group!(matrix, criterion_group!(
matrix,
mat2_mul_m, mat2_mul_m,
mat3_mul_m, mat3_mul_m,
mat4_mul_m, mat4_mul_m,
mat2_tr_mul_m, mat2_tr_mul_m,
mat3_tr_mul_m, mat3_tr_mul_m,
mat4_tr_mul_m, mat4_tr_mul_m,
mat2_add_m, mat2_add_m,
mat3_add_m, mat3_add_m,
mat4_add_m, mat4_add_m,
mat2_sub_m, mat2_sub_m,
mat3_sub_m, mat3_sub_m,
mat4_sub_m, mat4_sub_m,
mat2_mul_v, mat2_mul_v,
mat3_mul_v, mat3_mul_v,
mat4_mul_v, mat4_mul_v,
mat2_tr_mul_v, mat2_tr_mul_v,
mat3_tr_mul_v, mat3_tr_mul_v,
mat4_tr_mul_v, mat4_tr_mul_v,
mat2_mul_s, mat2_mul_s,
mat3_mul_s, mat3_mul_s,
mat4_mul_s, mat4_mul_s,
mat2_div_s, mat2_div_s,
mat3_div_s, mat3_div_s,
mat4_div_s, mat4_div_s,
mat2_inv, mat2_inv,
mat3_inv, mat3_inv,
mat4_inv, mat4_inv,
mat2_transpose, mat2_transpose,
mat3_transpose, mat3_transpose,
mat4_transpose, mat4_transpose,
mat_div_scalar, mat_div_scalar,
mat100_add_mat100, mat100_add_mat100,
mat4_mul_mat4, mat4_mul_mat4,

View File

@ -55,7 +55,9 @@ fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
bh.bench_function("vec10000_axpy_f64", move |bh| bh.iter(|| a.axpy(n, &b, 1.0))); bh.bench_function("vec10000_axpy_f64", move |bh| {
bh.iter(|| a.axpy(n, &b, 1.0))
});
} }
fn vec10000_axpy_beta_f64(bh: &mut criterion::Criterion) { fn vec10000_axpy_beta_f64(bh: &mut criterion::Criterion) {
@ -66,7 +68,9 @@ fn vec10000_axpy_beta_f64(bh: &mut criterion::Criterion) {
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
let beta = rng.gen::<f64>(); let beta = rng.gen::<f64>();
bh.bench_function("vec10000_axpy_beta_f64", move |bh| bh.iter(|| a.axpy(n, &b, beta))); bh.bench_function("vec10000_axpy_beta_f64", move |bh| {
bh.iter(|| a.axpy(n, &b, beta))
});
} }
fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) { fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
@ -76,12 +80,14 @@ fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
bh.bench_function("vec10000_axpy_f64_slice", move |bh| bh.iter(|| { bh.bench_function("vec10000_axpy_f64_slice", move |bh| {
let mut a = a.fixed_rows_mut::<U10000>(0); bh.iter(|| {
let b = b.fixed_rows::<U10000>(0); let mut a = a.fixed_rows_mut::<U10000>(0);
let b = b.fixed_rows::<U10000>(0);
a.axpy(n, &b, 1.0) a.axpy(n, &b, 1.0)
})); })
});
} }
fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) { fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
@ -92,7 +98,9 @@ fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
// NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)). // NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)).
bh.bench_function("vec10000_axpy_f64_static", move |bh| bh.iter(|| a.axpy(n, &b, 1.0))); bh.bench_function("vec10000_axpy_f64_static", move |bh| {
bh.iter(|| a.axpy(n, &b, 1.0))
});
} }
fn vec10000_axpy_f32(bh: &mut criterion::Criterion) { fn vec10000_axpy_f32(bh: &mut criterion::Criterion) {
@ -102,7 +110,9 @@ fn vec10000_axpy_f32(bh: &mut criterion::Criterion) {
let b = DVector::new_random(10000); let b = DVector::new_random(10000);
let n = rng.gen::<f32>(); let n = rng.gen::<f32>();
bh.bench_function("vec10000_axpy_f32", move |bh| bh.iter(|| a.axpy(n, &b, 1.0))); bh.bench_function("vec10000_axpy_f32", move |bh| {
bh.iter(|| a.axpy(n, &b, 1.0))
});
} }
fn vec10000_axpy_beta_f32(bh: &mut criterion::Criterion) { fn vec10000_axpy_beta_f32(bh: &mut criterion::Criterion) {
@ -113,51 +123,43 @@ fn vec10000_axpy_beta_f32(bh: &mut criterion::Criterion) {
let n = rng.gen::<f32>(); let n = rng.gen::<f32>();
let beta = rng.gen::<f32>(); let beta = rng.gen::<f32>();
bh.bench_function("vec10000_axpy_beta_f32", move |bh| bh.iter(|| a.axpy(n, &b, beta))); bh.bench_function("vec10000_axpy_beta_f32", move |bh| {
bh.iter(|| a.axpy(n, &b, beta))
});
} }
criterion_group!(vector, criterion_group!(
vector,
vec2_add_v_f32, vec2_add_v_f32,
vec3_add_v_f32, vec3_add_v_f32,
vec4_add_v_f32, vec4_add_v_f32,
vec2_add_v_f64, vec2_add_v_f64,
vec3_add_v_f64, vec3_add_v_f64,
vec4_add_v_f64, vec4_add_v_f64,
vec2_sub_v, vec2_sub_v,
vec3_sub_v, vec3_sub_v,
vec4_sub_v, vec4_sub_v,
vec2_mul_s, vec2_mul_s,
vec3_mul_s, vec3_mul_s,
vec4_mul_s, vec4_mul_s,
vec2_div_s, vec2_div_s,
vec3_div_s, vec3_div_s,
vec4_div_s, vec4_div_s,
vec2_dot_f32, vec2_dot_f32,
vec3_dot_f32, vec3_dot_f32,
vec4_dot_f32, vec4_dot_f32,
vec2_dot_f64, vec2_dot_f64,
vec3_dot_f64, vec3_dot_f64,
vec4_dot_f64, vec4_dot_f64,
vec3_cross, vec3_cross,
vec2_norm, vec2_norm,
vec3_norm, vec3_norm,
vec4_norm, vec4_norm,
vec2_normalize, vec2_normalize,
vec3_normalize, vec3_normalize,
vec4_normalize, vec4_normalize,
vec10000_dot_f64, vec10000_dot_f64,
vec10000_dot_f32, vec10000_dot_f32,
vec10000_axpy_f64, vec10000_axpy_f64,
vec10000_axpy_beta_f64, vec10000_axpy_beta_f64,
vec10000_axpy_f64_slice, vec10000_axpy_f64_slice,

View File

@ -26,7 +26,8 @@ bench_unop!(unit_quaternion_inv, UnitQuaternion<f32>, inverse);
// bench_unop_self!(quaternion_conjugate, Quaternion<f32>, conjugate); // bench_unop_self!(quaternion_conjugate, Quaternion<f32>, conjugate);
// bench_unop!(quaternion_normalize, Quaternion<f32>, normalize); // bench_unop!(quaternion_normalize, Quaternion<f32>, normalize);
criterion_group!(quaternion, criterion_group!(
quaternion,
quaternion_add_q, quaternion_add_q,
quaternion_sub_q, quaternion_sub_q,
quaternion_mul_q, quaternion_mul_q,

View File

@ -6,70 +6,89 @@ mod macros;
// Without unpack. // Without unpack.
fn bidiagonalize_100x100(bh: &mut criterion::Criterion) { fn bidiagonalize_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("bidiagonalize_100x100", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))); bh.bench_function("bidiagonalize_100x100", move |bh| {
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
});
} }
fn bidiagonalize_100x500(bh: &mut criterion::Criterion) { fn bidiagonalize_100x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 500); let m = DMatrix::<f64>::new_random(100, 500);
bh.bench_function("bidiagonalize_100x500", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))); bh.bench_function("bidiagonalize_100x500", move |bh| {
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
});
} }
fn bidiagonalize_4x4(bh: &mut criterion::Criterion) { fn bidiagonalize_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("bidiagonalize_4x4", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))); bh.bench_function("bidiagonalize_4x4", move |bh| {
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
});
} }
fn bidiagonalize_500x100(bh: &mut criterion::Criterion) { fn bidiagonalize_500x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 100); let m = DMatrix::<f64>::new_random(500, 100);
bh.bench_function("bidiagonalize_500x100", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))); bh.bench_function("bidiagonalize_500x100", move |bh| {
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
});
} }
fn bidiagonalize_500x500(bh: &mut criterion::Criterion) { fn bidiagonalize_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("bidiagonalize_500x500", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))); bh.bench_function("bidiagonalize_500x500", move |bh| {
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
});
} }
// With unpack. // With unpack.
fn bidiagonalize_unpack_100x100(bh: &mut criterion::Criterion) { fn bidiagonalize_unpack_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("bidiagonalize_unpack_100x100", move |bh| bh.iter(|| { bh.bench_function("bidiagonalize_unpack_100x100", move |bh| {
let bidiag = Bidiagonal::new(m.clone()); bh.iter(|| {
let _ = bidiag.unpack(); let bidiag = Bidiagonal::new(m.clone());
})); let _ = bidiag.unpack();
})
});
} }
fn bidiagonalize_unpack_100x500(bh: &mut criterion::Criterion) { fn bidiagonalize_unpack_100x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 500); let m = DMatrix::<f64>::new_random(100, 500);
bh.bench_function("bidiagonalize_unpack_100x500", move |bh| bh.iter(|| { bh.bench_function("bidiagonalize_unpack_100x500", move |bh| {
let bidiag = Bidiagonal::new(m.clone()); bh.iter(|| {
let _ = bidiag.unpack(); let bidiag = Bidiagonal::new(m.clone());
})); let _ = bidiag.unpack();
})
});
} }
fn bidiagonalize_unpack_500x100(bh: &mut criterion::Criterion) { fn bidiagonalize_unpack_500x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 100); let m = DMatrix::<f64>::new_random(500, 100);
bh.bench_function("bidiagonalize_unpack_500x100", move |bh| bh.iter(|| { bh.bench_function("bidiagonalize_unpack_500x100", move |bh| {
let bidiag = Bidiagonal::new(m.clone()); bh.iter(|| {
let _ = bidiag.unpack(); let bidiag = Bidiagonal::new(m.clone());
})); let _ = bidiag.unpack();
})
});
} }
fn bidiagonalize_unpack_500x500(bh: &mut criterion::Criterion) { fn bidiagonalize_unpack_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("bidiagonalize_unpack_500x500", move |bh| bh.iter(|| { bh.bench_function("bidiagonalize_unpack_500x500", move |bh| {
let bidiag = Bidiagonal::new(m.clone()); bh.iter(|| {
let _ = bidiag.unpack(); let bidiag = Bidiagonal::new(m.clone());
})); let _ = bidiag.unpack();
})
});
} }
criterion_group!(bidiagonal, criterion_group!(
bidiagonal,
bidiagonalize_100x100, bidiagonalize_100x100,
bidiagonalize_100x500, bidiagonalize_100x500,
bidiagonalize_4x4, bidiagonalize_4x4,
bidiagonalize_500x100, bidiagonalize_500x100,
// bidiagonalize_500x500, // too long // bidiagonalize_500x500, // too long
bidiagonalize_unpack_100x100, bidiagonalize_unpack_100x100,
bidiagonalize_unpack_100x500, bidiagonalize_unpack_100x500,
bidiagonalize_unpack_500x100, bidiagonalize_unpack_500x100,
// bidiagonalize_unpack_500x500 // too long // bidiagonalize_unpack_500x500 // too long
); );

View File

@ -4,14 +4,18 @@ fn cholesky_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let m = &m * m.transpose(); let m = &m * m.transpose();
bh.bench_function("cholesky_100x100", move |bh| bh.iter(|| test::black_box(Cholesky::new(m.clone())))); bh.bench_function("cholesky_100x100", move |bh| {
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
});
} }
fn cholesky_500x500(bh: &mut criterion::Criterion) { fn cholesky_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let m = &m * m.transpose(); let m = &m * m.transpose();
bh.bench_function("cholesky_500x500", move |bh| bh.iter(|| test::black_box(Cholesky::new(m.clone())))); bh.bench_function("cholesky_500x500", move |bh| {
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
});
} }
// With unpack. // With unpack.
@ -19,19 +23,23 @@ fn cholesky_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let m = &m * m.transpose(); let m = &m * m.transpose();
bh.bench_function("cholesky_decompose_unpack_100x100", move |bh| bh.iter(|| { bh.bench_function("cholesky_decompose_unpack_100x100", move |bh| {
let chol = Cholesky::new(m.clone()).unwrap(); bh.iter(|| {
let _ = chol.unpack(); let chol = Cholesky::new(m.clone()).unwrap();
})); let _ = chol.unpack();
})
});
} }
fn cholesky_decompose_unpack_500x500(bh: &mut criterion::Criterion) { fn cholesky_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let m = &m * m.transpose(); let m = &m * m.transpose();
bh.bench_function("cholesky_decompose_unpack_500x500", move |bh| bh.iter(|| { bh.bench_function("cholesky_decompose_unpack_500x500", move |bh| {
let chol = Cholesky::new(m.clone()).unwrap(); bh.iter(|| {
let _ = chol.unpack(); let chol = Cholesky::new(m.clone()).unwrap();
})); let _ = chol.unpack();
})
});
} }
fn cholesky_solve_10x10(bh: &mut criterion::Criterion) { fn cholesky_solve_10x10(bh: &mut criterion::Criterion) {
@ -40,9 +48,11 @@ fn cholesky_solve_10x10(bh: &mut criterion::Criterion) {
let v = DVector::<f64>::new_random(10); let v = DVector::<f64>::new_random(10);
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_solve_10x10", move |bh| bh.iter(|| { bh.bench_function("cholesky_solve_10x10", move |bh| {
let _ = chol.solve(&v); bh.iter(|| {
})); let _ = chol.solve(&v);
})
});
} }
fn cholesky_solve_100x100(bh: &mut criterion::Criterion) { fn cholesky_solve_100x100(bh: &mut criterion::Criterion) {
@ -51,9 +61,11 @@ fn cholesky_solve_100x100(bh: &mut criterion::Criterion) {
let v = DVector::<f64>::new_random(100); let v = DVector::<f64>::new_random(100);
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_solve_100x100", move |bh| bh.iter(|| { bh.bench_function("cholesky_solve_100x100", move |bh| {
let _ = chol.solve(&v); bh.iter(|| {
})); let _ = chol.solve(&v);
})
});
} }
fn cholesky_solve_500x500(bh: &mut criterion::Criterion) { fn cholesky_solve_500x500(bh: &mut criterion::Criterion) {
@ -62,20 +74,23 @@ fn cholesky_solve_500x500(bh: &mut criterion::Criterion) {
let v = DVector::<f64>::new_random(500); let v = DVector::<f64>::new_random(500);
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_solve_500x500", move |bh| bh.iter(|| { bh.bench_function("cholesky_solve_500x500", move |bh| {
let _ = chol.solve(&v); bh.iter(|| {
})); let _ = chol.solve(&v);
})
});
} }
fn cholesky_inverse_10x10(bh: &mut criterion::Criterion) { fn cholesky_inverse_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let m = &m * m.transpose(); let m = &m * m.transpose();
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_inverse_10x10", move |bh| bh.iter(|| { bh.bench_function("cholesky_inverse_10x10", move |bh| {
let _ = chol.inverse(); bh.iter(|| {
})); let _ = chol.inverse();
})
});
} }
fn cholesky_inverse_100x100(bh: &mut criterion::Criterion) { fn cholesky_inverse_100x100(bh: &mut criterion::Criterion) {
@ -83,9 +98,11 @@ fn cholesky_inverse_100x100(bh: &mut criterion::Criterion) {
let m = &m * m.transpose(); let m = &m * m.transpose();
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_inverse_100x100", move |bh| bh.iter(|| { bh.bench_function("cholesky_inverse_100x100", move |bh| {
let _ = chol.inverse(); bh.iter(|| {
})); let _ = chol.inverse();
})
});
} }
fn cholesky_inverse_500x500(bh: &mut criterion::Criterion) { fn cholesky_inverse_500x500(bh: &mut criterion::Criterion) {
@ -93,12 +110,15 @@ fn cholesky_inverse_500x500(bh: &mut criterion::Criterion) {
let m = &m * m.transpose(); let m = &m * m.transpose();
let chol = Cholesky::new(m.clone()).unwrap(); let chol = Cholesky::new(m.clone()).unwrap();
bh.bench_function("cholesky_inverse_500x500", move |bh| bh.iter(|| { bh.bench_function("cholesky_inverse_500x500", move |bh| {
let _ = chol.inverse(); bh.iter(|| {
})); let _ = chol.inverse();
})
});
} }
criterion_group!(cholesky, criterion_group!(
cholesky,
cholesky_100x100, cholesky_100x100,
cholesky_500x500, cholesky_500x500,
cholesky_decompose_unpack_100x100, cholesky_decompose_unpack_100x100,
@ -109,4 +129,4 @@ criterion_group!(cholesky,
cholesky_inverse_10x10, cholesky_inverse_10x10,
cholesky_inverse_100x100, cholesky_inverse_100x100,
cholesky_inverse_500x500 cholesky_inverse_500x500
); );

View File

@ -3,103 +3,127 @@ use na::{DMatrix, DVector, FullPivLU};
// Without unpack. // Without unpack.
fn full_piv_lu_decompose_10x10(bh: &mut criterion::Criterion) { fn full_piv_lu_decompose_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
bh.bench_function("full_piv_lu_decompose_10x10", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone())))); bh.bench_function("full_piv_lu_decompose_10x10", move |bh| {
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
});
} }
fn full_piv_lu_decompose_100x100(bh: &mut criterion::Criterion) { fn full_piv_lu_decompose_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("full_piv_lu_decompose_100x100", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone())))); bh.bench_function("full_piv_lu_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
});
} }
fn full_piv_lu_decompose_500x500(bh: &mut criterion::Criterion) { fn full_piv_lu_decompose_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("full_piv_lu_decompose_500x500", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone())))); bh.bench_function("full_piv_lu_decompose_500x500", move |bh| {
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
});
} }
fn full_piv_lu_solve_10x10(bh: &mut criterion::Criterion) { fn full_piv_lu_solve_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_solve_10x10", move |bh| bh.iter(|| { bh.bench_function("full_piv_lu_solve_10x10", move |bh| {
let mut b = DVector::<f64>::from_element(10, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(10, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn full_piv_lu_solve_100x100(bh: &mut criterion::Criterion) { fn full_piv_lu_solve_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_solve_100x100", move |bh| bh.iter(|| { bh.bench_function("full_piv_lu_solve_100x100", move |bh| {
let mut b = DVector::<f64>::from_element(100, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(100, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn full_piv_lu_solve_500x500(bh: &mut criterion::Criterion) { fn full_piv_lu_solve_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_solve_500x500", move |bh| bh.iter(|| { bh.bench_function("full_piv_lu_solve_500x500", move |bh| {
let mut b = DVector::<f64>::from_element(500, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(500, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn full_piv_lu_inverse_10x10(bh: &mut criterion::Criterion) { fn full_piv_lu_inverse_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_inverse_10x10", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("full_piv_lu_inverse_10x10", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn full_piv_lu_inverse_100x100(bh: &mut criterion::Criterion) { fn full_piv_lu_inverse_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_inverse_100x100", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("full_piv_lu_inverse_100x100", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn full_piv_lu_inverse_500x500(bh: &mut criterion::Criterion) { fn full_piv_lu_inverse_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_inverse_500x500", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("full_piv_lu_inverse_500x500", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn full_piv_lu_determinant_10x10(bh: &mut criterion::Criterion) { fn full_piv_lu_determinant_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_determinant_10x10", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("full_piv_lu_determinant_10x10", move |bh| {
bh.iter(|| test::black_box(lu.determinant()))
});
} }
fn full_piv_lu_determinant_100x100(bh: &mut criterion::Criterion) { fn full_piv_lu_determinant_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_determinant_100x100", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("full_piv_lu_determinant_100x100", move |bh| {
bh.iter(|| test::black_box(lu.determinant()))
});
} }
fn full_piv_lu_determinant_500x500(bh: &mut criterion::Criterion) { fn full_piv_lu_determinant_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let lu = FullPivLU::new(m.clone()); let lu = FullPivLU::new(m.clone());
bh.bench_function("full_piv_lu_determinant_500x500", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("full_piv_lu_determinant_500x500", move |bh| {
bh.iter(|| test::black_box(lu.determinant()))
});
} }
criterion_group!(full_piv_lu, criterion_group!(
full_piv_lu,
full_piv_lu_decompose_10x10, full_piv_lu_decompose_10x10,
full_piv_lu_decompose_100x100, full_piv_lu_decompose_100x100,
// full_piv_lu_decompose_500x500, // full_piv_lu_decompose_500x500,
full_piv_lu_solve_10x10, full_piv_lu_solve_10x10,
full_piv_lu_solve_100x100, full_piv_lu_solve_100x100,
// full_piv_lu_solve_500x500, // full_piv_lu_solve_500x500,
full_piv_lu_inverse_10x10, full_piv_lu_inverse_10x10,
full_piv_lu_inverse_100x100, full_piv_lu_inverse_100x100,
// full_piv_lu_inverse_500x500, // full_piv_lu_inverse_500x500,
full_piv_lu_determinant_10x10, full_piv_lu_determinant_10x10,
full_piv_lu_determinant_100x100, full_piv_lu_determinant_100x100,
// full_piv_lu_determinant_500x500 // full_piv_lu_determinant_500x500
); );

View File

@ -6,55 +6,70 @@ mod macros;
// Without unpack. // Without unpack.
fn hessenberg_decompose_4x4(bh: &mut criterion::Criterion) { fn hessenberg_decompose_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("hessenberg_decompose_4x4", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone())))); bh.bench_function("hessenberg_decompose_4x4", move |bh| {
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
});
} }
fn hessenberg_decompose_100x100(bh: &mut criterion::Criterion) { fn hessenberg_decompose_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("hessenberg_decompose_100x100", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone())))); bh.bench_function("hessenberg_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
});
} }
fn hessenberg_decompose_200x200(bh: &mut criterion::Criterion) { fn hessenberg_decompose_200x200(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(200, 200); let m = DMatrix::<f64>::new_random(200, 200);
bh.bench_function("hessenberg_decompose_200x200", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone())))); bh.bench_function("hessenberg_decompose_200x200", move |bh| {
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
});
} }
fn hessenberg_decompose_500x500(bh: &mut criterion::Criterion) { fn hessenberg_decompose_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("hessenberg_decompose_500x500", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone())))); bh.bench_function("hessenberg_decompose_500x500", move |bh| {
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
});
} }
// With unpack. // With unpack.
fn hessenberg_decompose_unpack_100x100(bh: &mut criterion::Criterion) { fn hessenberg_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("hessenberg_decompose_unpack_100x100", move |bh| bh.iter(|| { bh.bench_function("hessenberg_decompose_unpack_100x100", move |bh| {
let hess = Hessenberg::new(m.clone()); bh.iter(|| {
let _ = hess.unpack(); let hess = Hessenberg::new(m.clone());
})); let _ = hess.unpack();
})
});
} }
fn hessenberg_decompose_unpack_200x200(bh: &mut criterion::Criterion) { fn hessenberg_decompose_unpack_200x200(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(200, 200); let m = DMatrix::<f64>::new_random(200, 200);
bh.bench_function("hessenberg_decompose_unpack_200x200", move |bh| bh.iter(|| { bh.bench_function("hessenberg_decompose_unpack_200x200", move |bh| {
let hess = Hessenberg::new(m.clone()); bh.iter(|| {
let _ = hess.unpack(); let hess = Hessenberg::new(m.clone());
})); let _ = hess.unpack();
})
});
} }
fn hessenberg_decompose_unpack_500x500(bh: &mut criterion::Criterion) { fn hessenberg_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("hessenberg_decompose_unpack_500x500", move |bh| bh.iter(|| { bh.bench_function("hessenberg_decompose_unpack_500x500", move |bh| {
let hess = Hessenberg::new(m.clone()); bh.iter(|| {
let _ = hess.unpack(); let hess = Hessenberg::new(m.clone());
})); let _ = hess.unpack();
})
});
} }
criterion_group!(hessenberg, criterion_group!(
hessenberg,
hessenberg_decompose_4x4, hessenberg_decompose_4x4,
hessenberg_decompose_100x100, hessenberg_decompose_100x100,
hessenberg_decompose_200x200, hessenberg_decompose_200x200,
// hessenberg_decompose_500x500, // hessenberg_decompose_500x500,
hessenberg_decompose_unpack_100x100, hessenberg_decompose_unpack_100x100,
hessenberg_decompose_unpack_200x200, hessenberg_decompose_unpack_200x200,
// hessenberg_decompose_unpack_500x500 // hessenberg_decompose_unpack_500x500
); );

View File

@ -3,82 +3,104 @@ use na::{DMatrix, DVector, LU};
// Without unpack. // Without unpack.
fn lu_decompose_10x10(bh: &mut criterion::Criterion) { fn lu_decompose_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
bh.bench_function("lu_decompose_10x10", move |bh| bh.iter(|| test::black_box(LU::new(m.clone())))); bh.bench_function("lu_decompose_10x10", move |bh| {
bh.iter(|| test::black_box(LU::new(m.clone())))
});
} }
fn lu_decompose_100x100(bh: &mut criterion::Criterion) { fn lu_decompose_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("lu_decompose_100x100", move |bh| bh.iter(|| test::black_box(LU::new(m.clone())))); bh.bench_function("lu_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(LU::new(m.clone())))
});
} }
fn lu_decompose_500x500(bh: &mut criterion::Criterion) { fn lu_decompose_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("lu_decompose_500x500", move |bh| bh.iter(|| test::black_box(LU::new(m.clone())))); bh.bench_function("lu_decompose_500x500", move |bh| {
bh.iter(|| test::black_box(LU::new(m.clone())))
});
} }
fn lu_solve_10x10(bh: &mut criterion::Criterion) { fn lu_solve_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_solve_10x10", move |bh| bh.iter(|| { bh.bench_function("lu_solve_10x10", move |bh| {
let mut b = DVector::<f64>::from_element(10, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(10, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn lu_solve_100x100(bh: &mut criterion::Criterion) { fn lu_solve_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_solve_100x100", move |bh| bh.iter(|| { bh.bench_function("lu_solve_100x100", move |bh| {
let mut b = DVector::<f64>::from_element(100, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(100, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn lu_solve_500x500(bh: &mut criterion::Criterion) { fn lu_solve_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("", move |bh| bh.iter(|| { bh.bench_function("", move |bh| {
let mut b = DVector::<f64>::from_element(500, 1.0); bh.iter(|| {
lu.solve(&mut b); let mut b = DVector::<f64>::from_element(500, 1.0);
})); lu.solve(&mut b);
})
});
} }
fn lu_inverse_10x10(bh: &mut criterion::Criterion) { fn lu_inverse_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_inverse_10x10", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("lu_inverse_10x10", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn lu_inverse_100x100(bh: &mut criterion::Criterion) { fn lu_inverse_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_inverse_100x100", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("lu_inverse_100x100", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn lu_inverse_500x500(bh: &mut criterion::Criterion) { fn lu_inverse_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_inverse_500x500", move |bh| bh.iter(|| test::black_box(lu.try_inverse()))); bh.bench_function("lu_inverse_500x500", move |bh| {
bh.iter(|| test::black_box(lu.try_inverse()))
});
} }
fn lu_determinant_10x10(bh: &mut criterion::Criterion) { fn lu_determinant_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_determinant_10x10", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("lu_determinant_10x10", move |bh| {
bh.iter(|| test::black_box(lu.determinant()))
});
} }
fn lu_determinant_100x100(bh: &mut criterion::Criterion) { fn lu_determinant_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let lu = LU::new(m.clone()); let lu = LU::new(m.clone());
bh.bench_function("lu_determinant_100x100", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("lu_determinant_100x100", move |bh| {
bh.iter(|| test::black_box(lu.determinant()))
});
} }
fn lu_determinant_500x500(bh: &mut criterion::Criterion) { fn lu_determinant_500x500(bh: &mut criterion::Criterion) {
@ -88,15 +110,16 @@ fn lu_determinant_500x500(bh: &mut criterion::Criterion) {
bh.bench_function("", move |bh| bh.iter(|| test::black_box(lu.determinant()))); bh.bench_function("", move |bh| bh.iter(|| test::black_box(lu.determinant())));
} }
criterion_group!(lu, criterion_group!(
lu,
lu_decompose_10x10, lu_decompose_10x10,
lu_decompose_100x100, lu_decompose_100x100,
// lu_decompose_500x500, // lu_decompose_500x500,
lu_solve_10x10, lu_solve_10x10,
lu_solve_100x100, lu_solve_100x100,
lu_inverse_10x10, lu_inverse_10x10,
lu_inverse_100x100, lu_inverse_100x100,
// lu_inverse_500x500, // lu_inverse_500x500,
lu_determinant_10x10, lu_determinant_10x10,
lu_determinant_100x100 lu_determinant_100x100
); );

View File

@ -19,4 +19,4 @@ mod schur;
mod solve; mod solve;
mod svd; mod svd;
mod symmetric_eigen; mod symmetric_eigen;
// mod eigen; // mod eigen;

View File

@ -6,128 +6,158 @@ mod macros;
// Without unpack. // Without unpack.
fn qr_decompose_100x100(bh: &mut criterion::Criterion) { fn qr_decompose_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("qr_decompose_100x100", move |bh| bh.iter(|| test::black_box(QR::new(m.clone())))); bh.bench_function("qr_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(QR::new(m.clone())))
});
} }
fn qr_decompose_100x500(bh: &mut criterion::Criterion) { fn qr_decompose_100x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 500); let m = DMatrix::<f64>::new_random(100, 500);
bh.bench_function("qr_decompose_100x500", move |bh| bh.iter(|| test::black_box(QR::new(m.clone())))); bh.bench_function("qr_decompose_100x500", move |bh| {
bh.iter(|| test::black_box(QR::new(m.clone())))
});
} }
fn qr_decompose_4x4(bh: &mut criterion::Criterion) { fn qr_decompose_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("qr_decompose_4x4", move |bh| bh.iter(|| test::black_box(QR::new(m.clone())))); bh.bench_function("qr_decompose_4x4", move |bh| {
bh.iter(|| test::black_box(QR::new(m.clone())))
});
} }
fn qr_decompose_500x100(bh: &mut criterion::Criterion) { fn qr_decompose_500x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 100); let m = DMatrix::<f64>::new_random(500, 100);
bh.bench_function("qr_decompose_500x100", move |bh| bh.iter(|| test::black_box(QR::new(m.clone())))); bh.bench_function("qr_decompose_500x100", move |bh| {
bh.iter(|| test::black_box(QR::new(m.clone())))
});
} }
fn qr_decompose_500x500(bh: &mut criterion::Criterion) { fn qr_decompose_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("qr_decompose_500x500", move |bh| bh.iter(|| test::black_box(QR::new(m.clone())))); bh.bench_function("qr_decompose_500x500", move |bh| {
bh.iter(|| test::black_box(QR::new(m.clone())))
});
} }
// With unpack. // With unpack.
fn qr_decompose_unpack_100x100(bh: &mut criterion::Criterion) { fn qr_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
bh.bench_function("qr_decompose_unpack_100x100", move |bh| bh.iter(|| { bh.bench_function("qr_decompose_unpack_100x100", move |bh| {
let qr = QR::new(m.clone()); bh.iter(|| {
let _ = qr.unpack(); let qr = QR::new(m.clone());
})); let _ = qr.unpack();
})
});
} }
fn qr_decompose_unpack_100x500(bh: &mut criterion::Criterion) { fn qr_decompose_unpack_100x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 500); let m = DMatrix::<f64>::new_random(100, 500);
bh.bench_function("qr_decompose_unpack_100x500", move |bh| bh.iter(|| { bh.bench_function("qr_decompose_unpack_100x500", move |bh| {
let qr = QR::new(m.clone()); bh.iter(|| {
let _ = qr.unpack(); let qr = QR::new(m.clone());
})); let _ = qr.unpack();
})
});
} }
fn qr_decompose_unpack_500x100(bh: &mut criterion::Criterion) { fn qr_decompose_unpack_500x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 100); let m = DMatrix::<f64>::new_random(500, 100);
bh.bench_function("qr_decompose_unpack_500x100", move |bh| bh.iter(|| { bh.bench_function("qr_decompose_unpack_500x100", move |bh| {
let qr = QR::new(m.clone()); bh.iter(|| {
let _ = qr.unpack(); let qr = QR::new(m.clone());
})); let _ = qr.unpack();
})
});
} }
fn qr_decompose_unpack_500x500(bh: &mut criterion::Criterion) { fn qr_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
bh.bench_function("qr_decompose_unpack_500x500", move |bh| bh.iter(|| { bh.bench_function("qr_decompose_unpack_500x500", move |bh| {
let qr = QR::new(m.clone()); bh.iter(|| {
let _ = qr.unpack(); let qr = QR::new(m.clone());
})); let _ = qr.unpack();
})
});
} }
fn qr_solve_10x10(bh: &mut criterion::Criterion) { fn qr_solve_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_solve_10x10", move |bh| bh.iter(|| { bh.bench_function("qr_solve_10x10", move |bh| {
let mut b = DVector::<f64>::from_element(10, 1.0); bh.iter(|| {
qr.solve(&mut b); let mut b = DVector::<f64>::from_element(10, 1.0);
})); qr.solve(&mut b);
})
});
} }
fn qr_solve_100x100(bh: &mut criterion::Criterion) { fn qr_solve_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_solve_100x100", move |bh| bh.iter(|| { bh.bench_function("qr_solve_100x100", move |bh| {
let mut b = DVector::<f64>::from_element(100, 1.0); bh.iter(|| {
qr.solve(&mut b); let mut b = DVector::<f64>::from_element(100, 1.0);
})); qr.solve(&mut b);
})
});
} }
fn qr_solve_500x500(bh: &mut criterion::Criterion) { fn qr_solve_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_solve_500x500", move |bh| bh.iter(|| { bh.bench_function("qr_solve_500x500", move |bh| {
let mut b = DVector::<f64>::from_element(500, 1.0); bh.iter(|| {
qr.solve(&mut b); let mut b = DVector::<f64>::from_element(500, 1.0);
})); qr.solve(&mut b);
})
});
} }
fn qr_inverse_10x10(bh: &mut criterion::Criterion) { fn qr_inverse_10x10(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(10, 10); let m = DMatrix::<f64>::new_random(10, 10);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_inverse_10x10", move |bh| bh.iter(|| test::black_box(qr.try_inverse()))); bh.bench_function("qr_inverse_10x10", move |bh| {
bh.iter(|| test::black_box(qr.try_inverse()))
});
} }
fn qr_inverse_100x100(bh: &mut criterion::Criterion) { fn qr_inverse_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_inverse_100x100", move |bh| bh.iter(|| test::black_box(qr.try_inverse()))); bh.bench_function("qr_inverse_100x100", move |bh| {
bh.iter(|| test::black_box(qr.try_inverse()))
});
} }
fn qr_inverse_500x500(bh: &mut criterion::Criterion) { fn qr_inverse_500x500(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(500, 500); let m = DMatrix::<f64>::new_random(500, 500);
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
bh.bench_function("qr_inverse_500x500", move |bh| bh.iter(|| test::black_box(qr.try_inverse()))); bh.bench_function("qr_inverse_500x500", move |bh| {
bh.iter(|| test::black_box(qr.try_inverse()))
});
} }
criterion_group!(
criterion_group!(qr, qr,
qr_decompose_100x100, qr_decompose_100x100,
qr_decompose_100x500, qr_decompose_100x500,
qr_decompose_4x4, qr_decompose_4x4,
qr_decompose_500x100, qr_decompose_500x100,
// qr_decompose_500x500, // qr_decompose_500x500,
qr_decompose_unpack_100x100, qr_decompose_unpack_100x100,
qr_decompose_unpack_100x500, qr_decompose_unpack_100x500,
qr_decompose_unpack_500x100, qr_decompose_unpack_500x100,
// qr_decompose_unpack_500x500, // qr_decompose_unpack_500x500,
qr_solve_10x10, qr_solve_10x10,
qr_solve_100x100, qr_solve_100x100,
// qr_solve_500x500, // qr_solve_500x500,
qr_inverse_10x10, qr_inverse_10x10,
qr_inverse_100x100, qr_inverse_100x100,
// qr_inverse_500x500 // qr_inverse_500x500
); );

View File

@ -2,45 +2,62 @@ use na::{Matrix4, Schur};
fn schur_decompose_4x4(bh: &mut criterion::Criterion) { fn schur_decompose_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("schur_decompose_4x4", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone())))); bh.bench_function("schur_decompose_4x4", move |bh| {
bh.iter(|| test::black_box(Schur::new(m.clone())))
});
} }
fn schur_decompose_10x10(bh: &mut criterion::Criterion) { fn schur_decompose_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("schur_decompose_10x10", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone())))); bh.bench_function("schur_decompose_10x10", move |bh| {
bh.iter(|| test::black_box(Schur::new(m.clone())))
});
} }
fn schur_decompose_100x100(bh: &mut criterion::Criterion) { fn schur_decompose_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("schur_decompose_100x100", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone())))); bh.bench_function("schur_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(Schur::new(m.clone())))
});
} }
fn schur_decompose_200x200(bh: &mut criterion::Criterion) { fn schur_decompose_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("schur_decompose_200x200", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone())))); bh.bench_function("schur_decompose_200x200", move |bh| {
bh.iter(|| test::black_box(Schur::new(m.clone())))
});
} }
fn eigenvalues_4x4(bh: &mut criterion::Criterion) { fn eigenvalues_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("eigenvalues_4x4", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues()))); bh.bench_function("eigenvalues_4x4", move |bh| {
bh.iter(|| test::black_box(m.complex_eigenvalues()))
});
} }
fn eigenvalues_10x10(bh: &mut criterion::Criterion) { fn eigenvalues_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("eigenvalues_10x10", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues()))); bh.bench_function("eigenvalues_10x10", move |bh| {
bh.iter(|| test::black_box(m.complex_eigenvalues()))
});
} }
fn eigenvalues_100x100(bh: &mut criterion::Criterion) { fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("eigenvalues_100x100", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues()))); bh.bench_function("eigenvalues_100x100", move |bh| {
bh.iter(|| test::black_box(m.complex_eigenvalues()))
});
} }
fn eigenvalues_200x200(bh: &mut criterion::Criterion) { fn eigenvalues_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("eigenvalues_200x200", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues()))); bh.bench_function("eigenvalues_200x200", move |bh| {
bh.iter(|| test::black_box(m.complex_eigenvalues()))
});
} }
criterion_group!(schur, criterion_group!(
schur,
schur_decompose_4x4, schur_decompose_4x4,
schur_decompose_10x10, schur_decompose_10x10,
schur_decompose_100x100, schur_decompose_100x100,
@ -49,4 +66,4 @@ criterion_group!(schur,
eigenvalues_10x10, eigenvalues_10x10,
eigenvalues_100x100, eigenvalues_100x100,
eigenvalues_200x200 eigenvalues_200x200
); );

View File

@ -4,76 +4,92 @@ fn solve_l_triangular_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let v = DVector::<f64>::new_random(100); let v = DVector::<f64>::new_random(100);
bh.bench_function("solve_l_triangular_100x100", move |bh| bh.iter(|| { bh.bench_function("solve_l_triangular_100x100", move |bh| {
let _ = m.solve_lower_triangular(&v); bh.iter(|| {
})); let _ = m.solve_lower_triangular(&v);
})
});
} }
fn solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) { fn solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(1000, 1000); let m = DMatrix::<f64>::new_random(1000, 1000);
let v = DVector::<f64>::new_random(1000); let v = DVector::<f64>::new_random(1000);
bh.bench_function("solve_l_triangular_1000x1000", move |bh| bh.iter(|| { bh.bench_function("solve_l_triangular_1000x1000", move |bh| {
let _ = m.solve_lower_triangular(&v); bh.iter(|| {
})); let _ = m.solve_lower_triangular(&v);
})
});
} }
fn tr_solve_l_triangular_100x100(bh: &mut criterion::Criterion) { fn tr_solve_l_triangular_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let v = DVector::<f64>::new_random(100); let v = DVector::<f64>::new_random(100);
bh.bench_function("tr_solve_l_triangular_100x100", move |bh| bh.iter(|| { bh.bench_function("tr_solve_l_triangular_100x100", move |bh| {
let _ = m.tr_solve_lower_triangular(&v); bh.iter(|| {
})); let _ = m.tr_solve_lower_triangular(&v);
})
});
} }
fn tr_solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) { fn tr_solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(1000, 1000); let m = DMatrix::<f64>::new_random(1000, 1000);
let v = DVector::<f64>::new_random(1000); let v = DVector::<f64>::new_random(1000);
bh.bench_function("tr_solve_l_triangular_1000x1000", move |bh| bh.iter(|| { bh.bench_function("tr_solve_l_triangular_1000x1000", move |bh| {
let _ = m.tr_solve_lower_triangular(&v); bh.iter(|| {
})); let _ = m.tr_solve_lower_triangular(&v);
})
});
} }
fn solve_u_triangular_100x100(bh: &mut criterion::Criterion) { fn solve_u_triangular_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let v = DVector::<f64>::new_random(100); let v = DVector::<f64>::new_random(100);
bh.bench_function("solve_u_triangular_100x100", move |bh| bh.iter(|| { bh.bench_function("solve_u_triangular_100x100", move |bh| {
let _ = m.solve_upper_triangular(&v); bh.iter(|| {
})); let _ = m.solve_upper_triangular(&v);
})
});
} }
fn solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) { fn solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(1000, 1000); let m = DMatrix::<f64>::new_random(1000, 1000);
let v = DVector::<f64>::new_random(1000); let v = DVector::<f64>::new_random(1000);
bh.bench_function("solve_u_triangular_1000x1000", move |bh| bh.iter(|| { bh.bench_function("solve_u_triangular_1000x1000", move |bh| {
let _ = m.solve_upper_triangular(&v); bh.iter(|| {
})); let _ = m.solve_upper_triangular(&v);
})
});
} }
fn tr_solve_u_triangular_100x100(bh: &mut criterion::Criterion) { fn tr_solve_u_triangular_100x100(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(100, 100); let m = DMatrix::<f64>::new_random(100, 100);
let v = DVector::<f64>::new_random(100); let v = DVector::<f64>::new_random(100);
bh.bench_function("tr_solve_u_triangular_100x100", move |bh| bh.iter(|| { bh.bench_function("tr_solve_u_triangular_100x100", move |bh| {
let _ = m.tr_solve_upper_triangular(&v); bh.iter(|| {
})); let _ = m.tr_solve_upper_triangular(&v);
})
});
} }
fn tr_solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) { fn tr_solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) {
let m = DMatrix::<f64>::new_random(1000, 1000); let m = DMatrix::<f64>::new_random(1000, 1000);
let v = DVector::<f64>::new_random(1000); let v = DVector::<f64>::new_random(1000);
bh.bench_function("tr_solve_u_triangular_1000x1000", move |bh| bh.iter(|| { bh.bench_function("tr_solve_u_triangular_1000x1000", move |bh| {
let _ = m.tr_solve_upper_triangular(&v); bh.iter(|| {
})); let _ = m.tr_solve_upper_triangular(&v);
})
});
} }
criterion_group!(
criterion_group!(solve, solve,
solve_l_triangular_100x100, solve_l_triangular_100x100,
solve_l_triangular_1000x1000, solve_l_triangular_1000x1000,
tr_solve_l_triangular_100x100, tr_solve_l_triangular_100x100,
@ -82,4 +98,4 @@ criterion_group!(solve,
solve_u_triangular_1000x1000, solve_u_triangular_1000x1000,
tr_solve_u_triangular_100x100, tr_solve_u_triangular_100x100,
tr_solve_u_triangular_1000x1000 tr_solve_u_triangular_1000x1000
); );

View File

@ -2,86 +2,118 @@ use na::{Matrix4, SVD};
fn svd_decompose_4x4(bh: &mut criterion::Criterion) { fn svd_decompose_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("svd_decompose_4x4", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))); bh.bench_function("svd_decompose_4x4", move |bh| {
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
});
} }
fn svd_decompose_10x10(bh: &mut criterion::Criterion) { fn svd_decompose_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("svd_decompose_10x10", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))); bh.bench_function("svd_decompose_10x10", move |bh| {
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
});
} }
fn svd_decompose_100x100(bh: &mut criterion::Criterion) { fn svd_decompose_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("svd_decompose_100x100", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))); bh.bench_function("svd_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
});
} }
fn svd_decompose_200x200(bh: &mut criterion::Criterion) { fn svd_decompose_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("svd_decompose_200x200", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))); bh.bench_function("svd_decompose_200x200", move |bh| {
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
});
} }
fn rank_4x4(bh: &mut criterion::Criterion) { fn rank_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("rank_4x4", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10)))); bh.bench_function("rank_4x4", move |bh| {
bh.iter(|| test::black_box(m.rank(1.0e-10)))
});
} }
fn rank_10x10(bh: &mut criterion::Criterion) { fn rank_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("rank_10x10", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10)))); bh.bench_function("rank_10x10", move |bh| {
bh.iter(|| test::black_box(m.rank(1.0e-10)))
});
} }
fn rank_100x100(bh: &mut criterion::Criterion) { fn rank_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("rank_100x100", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10)))); bh.bench_function("rank_100x100", move |bh| {
bh.iter(|| test::black_box(m.rank(1.0e-10)))
});
} }
fn rank_200x200(bh: &mut criterion::Criterion) { fn rank_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("rank_200x200", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10)))); bh.bench_function("rank_200x200", move |bh| {
bh.iter(|| test::black_box(m.rank(1.0e-10)))
});
} }
fn singular_values_4x4(bh: &mut criterion::Criterion) { fn singular_values_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("singular_values_4x4", move |bh| bh.iter(|| test::black_box(m.singular_values()))); bh.bench_function("singular_values_4x4", move |bh| {
bh.iter(|| test::black_box(m.singular_values()))
});
} }
fn singular_values_10x10(bh: &mut criterion::Criterion) { fn singular_values_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("singular_values_10x10", move |bh| bh.iter(|| test::black_box(m.singular_values()))); bh.bench_function("singular_values_10x10", move |bh| {
bh.iter(|| test::black_box(m.singular_values()))
});
} }
fn singular_values_100x100(bh: &mut criterion::Criterion) { fn singular_values_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("singular_values_100x100", move |bh| bh.iter(|| test::black_box(m.singular_values()))); bh.bench_function("singular_values_100x100", move |bh| {
bh.iter(|| test::black_box(m.singular_values()))
});
} }
fn singular_values_200x200(bh: &mut criterion::Criterion) { fn singular_values_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("singular_values_200x200", move |bh| bh.iter(|| test::black_box(m.singular_values()))); bh.bench_function("singular_values_200x200", move |bh| {
bh.iter(|| test::black_box(m.singular_values()))
});
} }
fn pseudo_inverse_4x4(bh: &mut criterion::Criterion) { fn pseudo_inverse_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("pseudo_inverse_4x4", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))); bh.bench_function("pseudo_inverse_4x4", move |bh| {
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
});
} }
fn pseudo_inverse_10x10(bh: &mut criterion::Criterion) { fn pseudo_inverse_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("pseudo_inverse_10x10", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))); bh.bench_function("pseudo_inverse_10x10", move |bh| {
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
});
} }
fn pseudo_inverse_100x100(bh: &mut criterion::Criterion) { fn pseudo_inverse_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("pseudo_inverse_100x100", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))); bh.bench_function("pseudo_inverse_100x100", move |bh| {
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
});
} }
fn pseudo_inverse_200x200(bh: &mut criterion::Criterion) { fn pseudo_inverse_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("pseudo_inverse_200x200", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))); bh.bench_function("pseudo_inverse_200x200", move |bh| {
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
});
} }
criterion_group!(
criterion_group!(svd, svd,
svd_decompose_4x4, svd_decompose_4x4,
svd_decompose_10x10, svd_decompose_10x10,
svd_decompose_100x100, svd_decompose_100x100,
@ -98,4 +130,4 @@ criterion_group!(svd,
pseudo_inverse_10x10, pseudo_inverse_10x10,
pseudo_inverse_100x100, pseudo_inverse_100x100,
pseudo_inverse_200x200 pseudo_inverse_200x200
); );

View File

@ -2,25 +2,34 @@ use na::{Matrix4, SymmetricEigen};
fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) { fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) {
let m = Matrix4::<f64>::new_random(); let m = Matrix4::<f64>::new_random();
bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))); bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| {
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
});
} }
fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) { fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(10, 10); let m = crate::reproductible_dmatrix(10, 10);
bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))); bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| {
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
});
} }
fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) { fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(100, 100); let m = crate::reproductible_dmatrix(100, 100);
bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))); bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| {
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
});
} }
fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) { fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) {
let m = crate::reproductible_dmatrix(200, 200); let m = crate::reproductible_dmatrix(200, 200);
bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))); bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| {
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
});
} }
criterion_group!(symmetric_eigen, criterion_group!(
symmetric_eigen,
symmetric_eigen_decompose_4x4, symmetric_eigen_decompose_4x4,
symmetric_eigen_decompose_10x10, symmetric_eigen_decompose_10x10,
symmetric_eigen_decompose_100x100, symmetric_eigen_decompose_100x100,

View File

@ -20,7 +20,9 @@ where
/// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`. /// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
fn reflect_wrt_hyperplane2<N>(plane_normal: &Unit<Vector2<N>>, vector: &Vector2<N>) -> Vector2<N> fn reflect_wrt_hyperplane2<N>(plane_normal: &Unit<Vector2<N>>, vector: &Vector2<N>) -> Vector2<N>
where N: RealField { where
N: RealField,
{
let n = plane_normal.as_ref(); // Get the underlying Vector2 let n = plane_normal.as_ref(); // Get the underlying Vector2
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))
} }
@ -28,7 +30,9 @@ where N: RealField {
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`. /// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D. /// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
fn reflect_wrt_hyperplane3<N>(plane_normal: &Unit<Vector3<N>>, vector: &Vector3<N>) -> Vector3<N> fn reflect_wrt_hyperplane3<N>(plane_normal: &Unit<Vector3<N>>, vector: &Vector3<N>) -> Vector3<N>
where N: RealField { where
N: RealField,
{
let n = plane_normal.as_ref(); // Get the underlying Vector3 let n = plane_normal.as_ref(); // Get the underlying Vector3
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))
} }

View File

@ -1,6 +1,6 @@
use core::mem;
use na::{self, DefaultAllocator, RealField}; use na::{self, DefaultAllocator, RealField};
use num::FromPrimitive; use num::FromPrimitive;
use core::mem;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::{Alloc, Dimension, Number};
@ -22,7 +22,9 @@ use crate::traits::{Alloc, Dimension, Number};
/// ///
/// * [`sign`](fn.sign.html) /// * [`sign`](fn.sign.html)
pub fn abs<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, R, C> pub fn abs<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, R, C>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.abs() x.abs()
} }
@ -44,7 +46,9 @@ where DefaultAllocator: Alloc<N, R, C> {
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn ceil<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn ceil<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.ceil()) x.map(|x| x.ceil())
} }
@ -94,7 +98,9 @@ pub fn clamp_scalar<N: Number>(x: N, min_val: N, max_val: N) -> N {
/// * [`clamp_scalar`](fn.clamp_scalar.html) /// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp_vec`](fn.clamp_vec.html) /// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp<N: Number, D: Dimension>(x: &TVec<N, D>, min_val: N, max_val: N) -> TVec<N, D> pub fn clamp<N: Number, D: Dimension>(x: &TVec<N, D>, min_val: N, max_val: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| na::clamp(x, min_val, max_val)) x.map(|x| na::clamp(x, min_val, max_val))
} }
@ -167,7 +173,9 @@ pub fn float_bits_to_int(v: f32) -> i32 {
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_int_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<i32, D> pub fn float_bits_to_int_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<i32, D>
where DefaultAllocator: Alloc<f32, D> { where
DefaultAllocator: Alloc<f32, D>,
{
v.map(float_bits_to_int) v.map(float_bits_to_int)
} }
@ -202,7 +210,9 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_uint_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<u32, D> pub fn float_bits_to_uint_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<u32, D>
where DefaultAllocator: Alloc<f32, D> { where
DefaultAllocator: Alloc<f32, D>,
{
v.map(float_bits_to_uint) v.map(float_bits_to_uint)
} }
@ -223,7 +233,9 @@ where DefaultAllocator: Alloc<f32, D> {
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn floor<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn floor<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.floor()) x.map(|x| x.floor())
} }
@ -250,7 +262,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn fract<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn fract<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.fract()) x.map(|x| x.fract())
} }
@ -293,7 +307,9 @@ pub fn int_bits_to_float(v: i32) -> f32 {
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn int_bits_to_float_vec<D: Dimension>(v: &TVec<i32, D>) -> TVec<f32, D> pub fn int_bits_to_float_vec<D: Dimension>(v: &TVec<i32, D>) -> TVec<f32, D>
where DefaultAllocator: Alloc<f32, D> { where
DefaultAllocator: Alloc<f32, D>,
{
v.map(int_bits_to_float) v.map(int_bits_to_float)
} }
@ -352,7 +368,9 @@ pub fn mix_scalar<N: Number>(x: N, y: N, a: N) -> N {
/// * [`mix_scalar`](fn.mix_scalar.html) /// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix_vec`](fn.mix_vec.html) /// * [`mix_vec`](fn.mix_vec.html)
pub fn mix<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D> pub fn mix<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x * (N::one() - a) + y * a x * (N::one() - a) + y * a
} }
@ -425,7 +443,9 @@ pub fn lerp_scalar<N: Number>(x: N, y: N, a: N) -> N {
/// * [`lerp_scalar`](fn.lerp_scalar.html) /// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp_vec`](fn.lerp_vec.html) /// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D> pub fn lerp<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
mix(x, y, a) mix(x, y, a)
} }
@ -468,7 +488,9 @@ where
/// ///
/// * [`modf`](fn.modf.html) /// * [`modf`](fn.modf.html)
pub fn modf_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D> pub fn modf_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x % y) x.zip_map(y, |x, y| x % y)
} }
@ -500,7 +522,9 @@ pub fn modf<N: Number>(x: N, i: N) -> N {
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn round<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn round<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.round()) x.map(|x| x.round())
} }
@ -524,7 +548,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`abs`](fn.abs.html) /// * [`abs`](fn.abs.html)
/// ///
pub fn sign<N: Number, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn sign<N: Number, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| if x.is_zero() { N::zero() } else { x.signum() }) x.map(|x| if x.is_zero() { N::zero() } else { x.signum() })
} }
@ -550,13 +576,17 @@ pub fn step_scalar<N: Number>(edge: N, x: N) -> N {
/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0. /// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
pub fn step<N: Number, D: Dimension>(edge: N, x: &TVec<N, D>) -> TVec<N, D> pub fn step<N: Number, D: Dimension>(edge: N, x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| step_scalar(edge, x)) x.map(|x| step_scalar(edge, x))
} }
/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0. /// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
pub fn step_vec<N: Number, D: Dimension>(edge: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D> pub fn step_vec<N: Number, D: Dimension>(edge: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
edge.zip_map(x, step_scalar) edge.zip_map(x, step_scalar)
} }
@ -577,7 +607,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
pub fn trunc<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn trunc<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.trunc()) x.map(|x| x.trunc())
} }
@ -612,6 +644,8 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn uint_bits_to_float<D: Dimension>(v: &TVec<u32, D>) -> TVec<f32, D> pub fn uint_bits_to_float<D: Dimension>(v: &TVec<u32, D>) -> TVec<f32, D>
where DefaultAllocator: Alloc<f32, D> { where
DefaultAllocator: Alloc<f32, D>,
{
v.map(uint_bits_to_float_scalar) v.map(uint_bits_to_float_scalar)
} }

View File

@ -1,6 +1,6 @@
use crate::aliases::TVec; use crate::aliases::TVec;
use na::{DefaultAllocator, RealField};
use crate::traits::{Alloc, Dimension}; use crate::traits::{Alloc, Dimension};
use na::{DefaultAllocator, RealField};
/// Component-wise exponential. /// Component-wise exponential.
/// ///
@ -8,7 +8,9 @@ use crate::traits::{Alloc, Dimension};
/// ///
/// * [`exp2`](fn.exp2.html) /// * [`exp2`](fn.exp2.html)
pub fn exp<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp()) v.map(|x| x.exp())
} }
@ -18,7 +20,9 @@ where DefaultAllocator: Alloc<N, D> {
/// ///
/// * [`exp`](fn.exp.html) /// * [`exp`](fn.exp.html)
pub fn exp2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp2()) v.map(|x| x.exp2())
} }
@ -28,7 +32,9 @@ where DefaultAllocator: Alloc<N, D> {
/// ///
/// * [`sqrt`](fn.sqrt.html) /// * [`sqrt`](fn.sqrt.html)
pub fn inversesqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn inversesqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| N::one() / x.sqrt()) v.map(|x| N::one() / x.sqrt())
} }
@ -38,7 +44,9 @@ where DefaultAllocator: Alloc<N, D> {
/// ///
/// * [`log2`](fn.log2.html) /// * [`log2`](fn.log2.html)
pub fn log<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.ln()) v.map(|x| x.ln())
} }
@ -48,13 +56,17 @@ where DefaultAllocator: Alloc<N, D> {
/// ///
/// * [`log`](fn.log.html) /// * [`log`](fn.log.html)
pub fn log2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.log2()) v.map(|x| x.log2())
} }
/// Component-wise power. /// Component-wise power.
pub fn pow<N: RealField, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D> pub fn pow<N: RealField, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
base.zip_map(exponent, |b, e| b.powf(e)) base.zip_map(exponent, |b, e| b.powf(e))
} }
@ -67,6 +79,8 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`inversesqrt`](fn.inversesqrt.html) /// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`](fn.pow.html) /// * [`pow`](fn.pow.html)
pub fn sqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn sqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.sqrt()) v.map(|x| x.sqrt())
} }

View File

@ -1,5 +1,5 @@
use crate::aliases::TMat4; use crate::aliases::TMat4;
use na::{RealField}; use na::RealField;
//pub fn frustum<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
// unimplemented!() // unimplemented!()
@ -90,13 +90,20 @@ pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_lh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_lh_no<N: RealField>(
let two : N = crate::convert(2.0); left: N,
let mut mat : TMat4<N> = TMat4::<N>::identity(); right: N,
bottom: N,
top: N,
znear: N,
zfar: N,
) -> TMat4<N> {
let two: N = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = -(right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
mat[(1, 1)] = two / (top-bottom); mat[(1, 1)] = two / (top - bottom);
mat[(1, 3)] = -(top + bottom) / (top - bottom); mat[(1, 3)] = -(top + bottom) / (top - bottom);
mat[(2, 2)] = two / (zfar - znear); mat[(2, 2)] = two / (zfar - znear);
mat[(2, 3)] = -(zfar + znear) / (zfar - znear); mat[(2, 3)] = -(zfar + znear) / (zfar - znear);
@ -115,17 +122,24 @@ pub fn ortho_lh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N,
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_lh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_lh_zo<N: RealField>(
let one : N = N::one(); left: N,
let two : N = crate::convert(2.0); right: N,
let mut mat : TMat4<N> = TMat4::<N>::identity(); bottom: N,
top: N,
znear: N,
zfar: N,
) -> TMat4<N> {
let one: N = N::one();
let two: N = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = - (right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
mat[(1, 1)] = two / (top - bottom); mat[(1, 1)] = two / (top - bottom);
mat[(1, 3)] = - (top + bottom) / (top - bottom); mat[(1, 3)] = -(top + bottom) / (top - bottom);
mat[(2, 2)] = one / (zfar - znear); mat[(2, 2)] = one / (zfar - znear);
mat[(2, 3)] = - znear / (zfar - znear); mat[(2, 3)] = -znear / (zfar - znear);
mat mat
} }
@ -171,16 +185,23 @@ pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_rh_no<N: RealField>(
let two : N = crate::convert(2.0); left: N,
let mut mat : TMat4<N> = TMat4::<N>::identity(); right: N,
bottom: N,
top: N,
znear: N,
zfar: N,
) -> TMat4<N> {
let two: N = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = - (right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
mat[(1, 1)] = two/(top-bottom); mat[(1, 1)] = two / (top - bottom);
mat[(1, 3)] = - (top + bottom) / (top - bottom); mat[(1, 3)] = -(top + bottom) / (top - bottom);
mat[(2, 2)] = - two / (zfar - znear); mat[(2, 2)] = -two / (zfar - znear);
mat[(2, 3)] = - (zfar + znear) / (zfar - znear); mat[(2, 3)] = -(zfar + znear) / (zfar - znear);
mat mat
} }
@ -196,17 +217,24 @@ pub fn ortho_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N,
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_rh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_rh_zo<N: RealField>(
let one : N = N::one(); left: N,
let two : N = crate::convert(2.0); right: N,
let mut mat : TMat4<N> = TMat4::<N>::identity(); bottom: N,
top: N,
znear: N,
zfar: N,
) -> TMat4<N> {
let one: N = N::one();
let two: N = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = - (right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
mat[(1, 1)] = two/(top-bottom); mat[(1, 1)] = two / (top - bottom);
mat[(1, 3)] = - (top + bottom) / (top - bottom); mat[(1, 3)] = -(top + bottom) / (top - bottom);
mat[(2, 2)] = - one / (zfar - znear); mat[(2, 2)] = -one / (zfar - znear);
mat[(2, 3)] = - znear / (zfar - znear); mat[(2, 3)] = -znear / (zfar - znear);
mat mat
} }
@ -264,19 +292,16 @@ pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_lh_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_lh_no<N: RealField>(
assert!( fov: N,
width > N::zero(), width: N,
"The width must be greater than zero" height: N,
); near: N,
assert!( far: N,
height > N::zero(), ) -> TMat4<N> {
"The height must be greater than zero." assert!(width > N::zero(), "The width must be greater than zero");
); assert!(height > N::zero(), "The height must be greater than zero.");
assert!( assert!(fov > N::zero(), "The fov must be greater than zero");
fov > N::zero(),
"The fov must be greater than zero"
);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -287,7 +312,7 @@ pub fn perspective_fov_lh_no<N: RealField>(fov: N, width: N, height: N, near: N,
mat[(0, 0)] = w; mat[(0, 0)] = w;
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = (far + near) / (far - near); mat[(2, 2)] = (far + near) / (far - near);
mat[(2, 3)] = - (far * near * crate::convert(2.0)) / (far - near); mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
mat[(3, 2)] = N::one(); mat[(3, 2)] = N::one();
mat mat
@ -303,19 +328,16 @@ pub fn perspective_fov_lh_no<N: RealField>(fov: N, width: N, height: N, near: N,
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_lh_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_lh_zo<N: RealField>(
assert!( fov: N,
width > N::zero(), width: N,
"The width must be greater than zero" height: N,
); near: N,
assert!( far: N,
height > N::zero(), ) -> TMat4<N> {
"The height must be greater than zero." assert!(width > N::zero(), "The width must be greater than zero");
); assert!(height > N::zero(), "The height must be greater than zero.");
assert!( assert!(fov > N::zero(), "The fov must be greater than zero");
fov > N::zero(),
"The fov must be greater than zero"
);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -370,19 +392,16 @@ pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_rh_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_rh_no<N: RealField>(
assert!( fov: N,
width > N::zero(), width: N,
"The width must be greater than zero" height: N,
); near: N,
assert!( far: N,
height > N::zero(), ) -> TMat4<N> {
"The height must be greater than zero." assert!(width > N::zero(), "The width must be greater than zero");
); assert!(height > N::zero(), "The height must be greater than zero.");
assert!( assert!(fov > N::zero(), "The fov must be greater than zero");
fov > N::zero(),
"The fov must be greater than zero"
);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -392,8 +411,8 @@ pub fn perspective_fov_rh_no<N: RealField>(fov: N, width: N, height: N, near: N,
mat[(0, 0)] = w; mat[(0, 0)] = w;
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = - (far + near) / (far - near); mat[(2, 2)] = -(far + near) / (far - near);
mat[(2, 3)] = - (far * near * crate::convert(2.0)) / (far - near); mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -N::one();
mat mat
@ -409,19 +428,16 @@ pub fn perspective_fov_rh_no<N: RealField>(fov: N, width: N, height: N, near: N,
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_rh_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_rh_zo<N: RealField>(
assert!( fov: N,
width > N::zero(), width: N,
"The width must be greater than zero" height: N,
); near: N,
assert!( far: N,
height > N::zero(), ) -> TMat4<N> {
"The height must be greater than zero." assert!(width > N::zero(), "The width must be greater than zero");
); assert!(height > N::zero(), "The height must be greater than zero.");
assert!( assert!(fov > N::zero(), "The fov must be greater than zero");
fov > N::zero(),
"The fov must be greater than zero"
);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -518,8 +534,8 @@ pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
); );
let one = N::one(); let one = N::one();
let two: N = crate::convert( 2.0); let two: N = crate::convert(2.0);
let mut mat : TMat4<N> = TMat4::zeros(); let mut mat: TMat4<N> = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -554,7 +570,7 @@ pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
); );
let one = N::one(); let one = N::one();
let two: N = crate::convert( 2.0); let two: N = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::zeros(); let mut mat: TMat4<N> = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -620,15 +636,15 @@ pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
); );
let negone = -N::one(); let negone = -N::one();
let one = N::one(); let one = N::one();
let two: N = crate::convert( 2.0); let two: N = crate::convert(2.0);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
mat[(0, 0)] = one / (aspect * tan_half_fovy); mat[(0, 0)] = one / (aspect * tan_half_fovy);
mat[(1, 1)] = one / tan_half_fovy; mat[(1, 1)] = one / tan_half_fovy;
mat[(2, 2)] = - (far + near) / (far - near); mat[(2, 2)] = -(far + near) / (far - near);
mat[(2, 3)] = -(two * far * near) / (far - near); mat[(2, 3)] = -(two * far * near) / (far - near);
mat[(3, 2)] = negone; mat[(3, 2)] = negone;
@ -657,8 +673,8 @@ pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
); );
let negone = -N::one(); let negone = -N::one();
let one = N::one(); let one = N::one();
let two = crate::convert( 2.0); let two = crate::convert(2.0);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -793,4 +809,4 @@ pub fn reversed_infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, nea
// //
//pub fn tweaked_infinite_perspective_ep<N: RealField>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> { //pub fn tweaked_infinite_perspective_ep<N: RealField>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -9,7 +9,11 @@ use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
/// * `center` - Specify the center of a picking region in window coordinates. /// * `center` - Specify the center of a picking region in window coordinates.
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates. /// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
/// * `viewport` - Rendering viewport. /// * `viewport` - Rendering viewport.
pub fn pick_matrix<N: RealField>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec4<N>) -> TMat4<N> { pub fn pick_matrix<N: RealField>(
center: &TVec2<N>,
delta: &TVec2<N>,
viewport: &TVec4<N>,
) -> TMat4<N> {
let shift = TVec3::new( let shift = TVec3::new(
(viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x, (viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x,
(viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y, (viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y,
@ -46,8 +50,7 @@ pub fn project<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
project_no(obj, model, proj, viewport) project_no(obj, model, proj, viewport)
} }
@ -74,8 +77,7 @@ pub fn project_no<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
let proj = project_zo(obj, model, proj, viewport); let proj = project_zo(obj, model, proj, viewport);
TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5)) TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5))
} }
@ -103,8 +105,7 @@ pub fn project_zo<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one()); let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one());
let scale = N::one() / normalized.w; let scale = N::one() / normalized.w;
@ -137,8 +138,7 @@ pub fn unproject<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
unproject_no(win, model, proj, viewport) unproject_no(win, model, proj, viewport)
} }
@ -165,8 +165,7 @@ pub fn unproject_no<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
let _2: N = na::convert(2.0); let _2: N = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(
@ -203,8 +202,7 @@ pub fn unproject_zo<N: RealField>(
model: &TMat4<N>, model: &TMat4<N>,
proj: &TMat4<N>, proj: &TMat4<N>,
viewport: TVec4<N>, viewport: TVec4<N>,
) -> TVec3<N> ) -> TVec3<N> {
{
let _2: N = na::convert(2.0); let _2: N = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(

View File

@ -5,7 +5,9 @@ use crate::traits::{Alloc, Dimension, Number};
/// The identity matrix. /// The identity matrix.
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D> pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
TMat::<N, D, D>::identity() TMat::<N, D, D>::identity()
} }

View File

@ -14,13 +14,17 @@ pub fn cross<N: Number>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
/// ///
/// * [`distance2`](fn.distance2.html) /// * [`distance2`](fn.distance2.html)
pub fn distance<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm() (p1 - p0).norm()
} }
/// The dot product of two vectors. /// The dot product of two vectors.
pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.dot(y) x.dot(y)
} }
@ -50,7 +54,9 @@ where
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn length<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -64,26 +70,34 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
/// Normalizes a vector. /// Normalizes a vector.
pub fn normalize<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn normalize<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.normalize() x.normalize()
} }
/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. /// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`.
pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D> pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
let _2 = N::one() + N::one(); let _2 = N::one() + N::one();
i - n * (n.dot(i) * _2) i - n * (n.dot(i) * _2)
} }
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. /// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
pub fn refract_vec<N: RealField, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D> pub fn refract_vec<N: RealField, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
let ni = n.dot(i); let ni = n.dot(i);
let k = N::one() - eta * eta * (N::one() - ni * ni); let k = N::one() - eta * eta * (N::one() - ni * ni);

View File

@ -10,10 +10,7 @@ use crate::traits::{Alloc, Dimension};
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn column<N: Scalar, R: Dimension, C: Dimension>( pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, R>
m: &TMat<N, R, C>,
index: usize,
) -> TVec<N, R>
where where
DefaultAllocator: Alloc<N, R, C>, DefaultAllocator: Alloc<N, R, C>,
{ {
@ -48,7 +45,9 @@ where
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C> pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
m.row(index).into_owned().transpose() m.row(index).into_owned().transpose()
} }

View File

@ -5,14 +5,18 @@ use crate::traits::{Alloc, Dimension};
/// Fast matrix inverse for affine matrix. /// Fast matrix inverse for affine matrix.
pub fn affine_inverse<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn affine_inverse<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
// FIXME: this should be optimized. // FIXME: this should be optimized.
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros) m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
} }
/// Compute the transpose of the inverse of a matrix. /// Compute the transpose of the inverse of a matrix.
pub fn inverse_transpose<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse_transpose<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
m.try_inverse() m.try_inverse()
.unwrap_or_else(TMat::<_, D, D>::zeros) .unwrap_or_else(TMat::<_, D, D>::zeros)
.transpose() .transpose()

View File

@ -76,7 +76,12 @@ pub fn mat2_to_mat3<N: Number>(m: &TMat2<N>) -> TMat3<N> {
/// Converts a 3x3 matrix to a 2x2 matrix. /// Converts a 3x3 matrix to a 2x2 matrix.
pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> { pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> {
TMat2::new(m.m11.inlined_clone(), m.m12.inlined_clone(), m.m21.inlined_clone(), m.m22.inlined_clone()) TMat2::new(
m.m11.inlined_clone(),
m.m12.inlined_clone(),
m.m21.inlined_clone(),
m.m22.inlined_clone(),
)
} }
/// Converts a 3x3 matrix to a 4x4 matrix. /// Converts a 3x3 matrix to a 4x4 matrix.
@ -92,9 +97,15 @@ pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> {
/// Converts a 4x4 matrix to a 3x3 matrix. /// Converts a 4x4 matrix to a 3x3 matrix.
pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> { pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> {
TMat3::new( TMat3::new(
m.m11.inlined_clone(), m.m12.inlined_clone(), m.m13.inlined_clone(), m.m11.inlined_clone(),
m.m21.inlined_clone(), m.m22.inlined_clone(), m.m23.inlined_clone(), m.m12.inlined_clone(),
m.m31.inlined_clone(), m.m32.inlined_clone(), m.m33.inlined_clone(), m.m13.inlined_clone(),
m.m21.inlined_clone(),
m.m22.inlined_clone(),
m.m23.inlined_clone(),
m.m31.inlined_clone(),
m.m32.inlined_clone(),
m.m33.inlined_clone(),
) )
} }
@ -110,7 +121,12 @@ pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> {
/// Converts a 4x4 matrix to a 2x2 matrix. /// Converts a 4x4 matrix to a 2x2 matrix.
pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> { pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> {
TMat2::new(m.m11.inlined_clone(), m.m12.inlined_clone(), m.m21.inlined_clone(), m.m22.inlined_clone()) TMat2::new(
m.m11.inlined_clone(),
m.m12.inlined_clone(),
m.m21.inlined_clone(),
m.m22.inlined_clone(),
)
} }
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`. /// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
@ -297,7 +313,11 @@ pub fn vec3_to_vec3<N: Scalar>(v: &TVec3<N>) -> TVec3<N> {
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> { pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> {
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), v.z.inlined_clone()) TVec3::new(
v.x.inlined_clone(),
v.y.inlined_clone(),
v.z.inlined_clone(),
)
} }
/// Creates a 3D vector from another vector. /// Creates a 3D vector from another vector.
@ -386,12 +406,16 @@ pub fn make_vec4<N: Scalar>(ptr: &[N]) -> TVec4<N> {
/// Converts a matrix or vector to a slice arranged in column-major order. /// Converts a matrix or vector to a slice arranged in column-major order.
pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N] pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N]
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_slice() x.as_slice()
} }
/// Converts a matrix or vector to a mutable slice arranged in column-major order. /// Converts a matrix or vector to a mutable slice arranged in column-major order.
pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N] pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N]
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_mut_slice() x.as_mut_slice()
} }

View File

@ -9,7 +9,9 @@ use crate::traits::{Alloc, Dimension};
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance`](fn.distance.html)
pub fn distance2<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance2<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm_squared() (p1 - p0).norm_squared()
} }
@ -21,7 +23,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l1_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
l1_norm(&(y - x)) l1_norm(&(y - x))
} }
@ -36,7 +40,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_norm<N: RealField, D: Dimension>(v: &TVec<N, D>) -> N pub fn l1_norm<N: RealField, D: Dimension>(v: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
crate::comp_add(&v.abs()) crate::comp_add(&v.abs())
} }
@ -55,7 +61,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l2_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
l2_norm(&(y - x)) l2_norm(&(y - x))
} }
@ -76,7 +84,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_norm<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn l2_norm<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -92,7 +102,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn length2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }
@ -108,7 +120,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html) /// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
pub fn magnitude2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }

View File

@ -11,7 +11,9 @@ use crate::traits::{Alloc, Dimension};
/// ///
/// * [`normalize_dot`](fn.normalize_dot.html`) /// * [`normalize_dot`](fn.normalize_dot.html`)
pub fn fast_normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn fast_normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }
@ -22,7 +24,9 @@ where DefaultAllocator: Alloc<N, D> {
/// ///
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`) /// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
pub fn normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }

View File

@ -5,7 +5,9 @@ use crate::traits::{Alloc, Dimension};
/// The angle between two vectors. /// The angle between two vectors.
pub fn angle<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn angle<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.angle(y) x.angle(y)
} }

View File

@ -22,11 +22,7 @@ pub fn are_collinear2d<N: Number>(v0: &TVec2<N>, v1: &TVec2<N>, epsilon: N) -> b
} }
/// Returns `true` if two vectors are orthogonal (up to an epsilon). /// Returns `true` if two vectors are orthogonal (up to an epsilon).
pub fn are_orthogonal<N: Number, D: Dimension>( pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool
v0: &TVec<N, D>,
v1: &TVec<N, D>,
epsilon: N,
) -> bool
where where
DefaultAllocator: Alloc<N, D>, DefaultAllocator: Alloc<N, D>,
{ {
@ -40,18 +36,24 @@ where
/// Returns `true` if all the components of `v` are zero (up to an epsilon). /// Returns `true` if all the components of `v` are zero (up to an epsilon).
pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D> pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon)) v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon))
} }
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). /// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
pub fn is_normalized<N: RealField, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_normalized<N: RealField, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon) abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
} }
/// Returns `true` if `v` is zero (up to an epsilon). /// Returns `true` if `v` is zero (up to an epsilon).
pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon) abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon)
} }

View File

@ -5,13 +5,17 @@ use crate::traits::{Alloc, Dimension, Number};
/// The determinant of the matrix `m`. /// The determinant of the matrix `m`.
pub fn determinant<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> N pub fn determinant<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> N
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
m.determinant() m.determinant()
} }
/// The inverse of the matrix `m`. /// The inverse of the matrix `m`.
pub fn inverse<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D>
where DefaultAllocator: Alloc<N, D, D> { where
DefaultAllocator: Alloc<N, D, D>,
{
m.clone() m.clone()
.try_inverse() .try_inverse()
.unwrap_or_else(TMat::<N, D, D>::zeros) .unwrap_or_else(TMat::<N, D, D>::zeros)
@ -41,6 +45,8 @@ where
/// The transpose of the matrix `m`. /// The transpose of the matrix `m`.
pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R> pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R>
where DefaultAllocator: Alloc<N, R, C> { where
DefaultAllocator: Alloc<N, R, C>,
{
x.transpose() x.transpose()
} }

View File

@ -71,7 +71,8 @@ pub trait Alloc<N: Scalar, R: Dimension, C: Dimension = U1>:
{ {
} }
impl<N: Scalar, R: Dimension, C: Dimension, T> Alloc<N, R, C> for T where T: Allocator<N, R> impl<N: Scalar, R: Dimension, C: Dimension, T> Alloc<N, R, C> for T where
T: Allocator<N, R>
+ Allocator<N, C> + Allocator<N, C>
+ Allocator<N, U1, R> + Allocator<N, U1, R>
+ Allocator<N, U1, C> + Allocator<N, U1, C>

View File

@ -5,90 +5,120 @@ use crate::traits::{Alloc, Dimension};
/// Component-wise arc-cosinus. /// Component-wise arc-cosinus.
pub fn acos<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acos<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acos()) x.map(|e| e.acos())
} }
/// Component-wise hyperbolic arc-cosinus. /// Component-wise hyperbolic arc-cosinus.
pub fn acosh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acosh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acosh()) x.map(|e| e.acosh())
} }
/// Component-wise arc-sinus. /// Component-wise arc-sinus.
pub fn asin<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asin<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asin()) x.map(|e| e.asin())
} }
/// Component-wise hyperbolic arc-sinus. /// Component-wise hyperbolic arc-sinus.
pub fn asinh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asinh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asinh()) x.map(|e| e.asinh())
} }
/// Component-wise arc-tangent of `y / x`. /// Component-wise arc-tangent of `y / x`.
pub fn atan2<N: RealField, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D> pub fn atan2<N: RealField, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
y.zip_map(x, |y, x| y.atan2(x)) y.zip_map(x, |y, x| y.atan2(x))
} }
/// Component-wise arc-tangent. /// Component-wise arc-tangent.
pub fn atan<N: RealField, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D> pub fn atan<N: RealField, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
y_over_x.map(|e| e.atan()) y_over_x.map(|e| e.atan())
} }
/// Component-wise hyperbolic arc-tangent. /// Component-wise hyperbolic arc-tangent.
pub fn atanh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn atanh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.atanh()) x.map(|e| e.atanh())
} }
/// Component-wise cosinus. /// Component-wise cosinus.
pub fn cos<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cos<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cos()) angle.map(|e| e.cos())
} }
/// Component-wise hyperbolic cosinus. /// Component-wise hyperbolic cosinus.
pub fn cosh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cosh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cosh()) angle.map(|e| e.cosh())
} }
/// Component-wise conversion from radians to degrees. /// Component-wise conversion from radians to degrees.
pub fn degrees<N: RealField, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D> pub fn degrees<N: RealField, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
radians.map(|e| e * na::convert(180.0) / N::pi()) radians.map(|e| e * na::convert(180.0) / N::pi())
} }
/// Component-wise conversion fro degrees to radians. /// Component-wise conversion fro degrees to radians.
pub fn radians<N: RealField, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D> pub fn radians<N: RealField, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
degrees.map(|e| e * N::pi() / na::convert(180.0)) degrees.map(|e| e * N::pi() / na::convert(180.0))
} }
/// Component-wise sinus. /// Component-wise sinus.
pub fn sin<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sin<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sin()) angle.map(|e| e.sin())
} }
/// Component-wise hyperbolic sinus. /// Component-wise hyperbolic sinus.
pub fn sinh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sinh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sinh()) angle.map(|e| e.sinh())
} }
/// Component-wise tangent. /// Component-wise tangent.
pub fn tan<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tan<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tan()) angle.map(|e| e.tan())
} }
/// Component-wise hyperbolic tangent. /// Component-wise hyperbolic tangent.
pub fn tanh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tanh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tanh()) angle.map(|e| e.tanh())
} }

View File

@ -21,7 +21,9 @@ use crate::traits::{Alloc, Dimension, Number};
/// * [`any`](fn.any.html) /// * [`any`](fn.any.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().all(|x| *x) v.iter().all(|x| *x)
} }
@ -46,7 +48,9 @@ where DefaultAllocator: Alloc<bool, D> {
/// * [`all`](fn.all.html) /// * [`all`](fn.all.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().any(|x| *x) v.iter().any(|x| *x)
} }
@ -70,7 +74,9 @@ where DefaultAllocator: Alloc<bool, D> {
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x == y) x.zip_map(y, |x, y| x == y)
} }
@ -94,7 +100,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x > y) x.zip_map(y, |x, y| x > y)
} }
@ -117,10 +125,7 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<N: Number, D: Dimension>( pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
x: &TVec<N, D>,
y: &TVec<N, D>,
) -> TVec<bool, D>
where where
DefaultAllocator: Alloc<N, D>, DefaultAllocator: Alloc<N, D>,
{ {
@ -147,7 +152,9 @@ where
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x < y) x.zip_map(y, |x, y| x < y)
} }
@ -171,7 +178,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x <= y) x.zip_map(y, |x, y| x <= y)
} }
@ -196,7 +205,9 @@ where DefaultAllocator: Alloc<N, D> {
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D> pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<bool, D> { where
DefaultAllocator: Alloc<bool, D>,
{
v.map(|x| !x) v.map(|x| !x)
} }
@ -220,6 +231,8 @@ where DefaultAllocator: Alloc<bool, D> {
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x != y) x.zip_map(y, |x, y| x != y)
} }

View File

@ -1,36 +1,36 @@
extern crate nalgebra as na; extern crate nalgebra as na;
extern crate nalgebra_glm as glm; extern crate nalgebra_glm as glm;
use na::Perspective3;
use na::Orthographic3;
use glm::Mat4; use glm::Mat4;
use glm::Vec4; use glm::Vec4;
use na::Orthographic3;
use na::Perspective3;
#[test] #[test]
pub fn orthographic_glm_nalgebra_same() pub fn orthographic_glm_nalgebra_same() {
{ let na_mat: Mat4 =
let na_mat : Mat4 = Orthographic3::new(-100.0f32,100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32).into_inner(); Orthographic3::new(-100.0f32, 100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32).into_inner();
let gl_mat : Mat4 = glm::ortho(-100.0f32,100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32); let gl_mat: Mat4 = glm::ortho(-100.0f32, 100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32);
assert_eq!(na_mat, gl_mat); assert_eq!(na_mat, gl_mat);
} }
#[test] #[test]
pub fn perspective_glm_nalgebra_same() pub fn perspective_glm_nalgebra_same() {
{ let na_mat: Mat4 =
let na_mat : Mat4 = Perspective3::new(16.0f32/9.0f32, 3.14f32/2.0f32, 0.1f32, 100.0f32).into_inner(); Perspective3::new(16.0f32 / 9.0f32, 3.14f32 / 2.0f32, 0.1f32, 100.0f32).into_inner();
let gl_mat : Mat4 = glm::perspective(16.0f32/9.0f32, 3.14f32/2.0f32, 0.1f32, 100.0f32); let gl_mat: Mat4 = glm::perspective(16.0f32 / 9.0f32, 3.14f32 / 2.0f32, 0.1f32, 100.0f32);
assert_eq!(na_mat, gl_mat); assert_eq!(na_mat, gl_mat);
} }
#[test] #[test]
pub fn orthographic_glm_nalgebra_project_same() pub fn orthographic_glm_nalgebra_project_same() {
{ let point = Vec4::new(1.0, 0.0, -20.0, 1.0);
let point = Vec4::new(1.0,0.0,-20.0,1.0);
let na_mat : Mat4 = Orthographic3::new(-100.0f32,100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32).into_inner(); let na_mat: Mat4 =
let gl_mat : Mat4 = glm::ortho(-100.0f32,100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32); Orthographic3::new(-100.0f32, 100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32).into_inner();
let gl_mat: Mat4 = glm::ortho(-100.0f32, 100.0f32, -50.0f32, 50.0f32, 0.1f32, 100.0f32);
let na_pt = na_mat * point; let na_pt = na_mat * point;
let gl_pt = gl_mat * point; let gl_pt = gl_mat * point;
@ -40,12 +40,12 @@ pub fn orthographic_glm_nalgebra_project_same()
} }
#[test] #[test]
pub fn perspective_glm_nalgebra_project_same() pub fn perspective_glm_nalgebra_project_same() {
{ let point = Vec4::new(1.0, 0.0, -20.0, 1.0);
let point = Vec4::new(1.0,0.0,-20.0,1.0);
let na_mat : Mat4 = Perspective3::new(16.0f32/9.0f32, 3.14f32/2.0f32, 0.1f32, 100.0f32).into_inner(); let na_mat: Mat4 =
let gl_mat : Mat4 = glm::perspective(16.0f32/9.0f32, 3.14f32/2.0f32, 0.1f32, 100.0f32); Perspective3::new(16.0f32 / 9.0f32, 3.14f32 / 2.0f32, 0.1f32, 100.0f32).into_inner();
let gl_mat: Mat4 = glm::perspective(16.0f32 / 9.0f32, 3.14f32 / 2.0f32, 0.1f32, 100.0f32);
let na_pt = na_mat * point; let na_pt = na_mat * point;
let gl_pt = gl_mat * point; let gl_pt = gl_mat * point;

View File

@ -15,21 +15,18 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, D>,
serialize = "DefaultAllocator: Allocator<N, D>, MatrixN<N, D>: Serialize"))
MatrixN<N, D>: Serialize"
))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(deserialize = "DefaultAllocator: Allocator<N, D>,
deserialize = "DefaultAllocator: Allocator<N, D>, MatrixN<N, D>: Deserialize<'de>"))
MatrixN<N, D>: Deserialize<'de>"
))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Cholesky<N: Scalar, D: Dim> pub struct Cholesky<N: Scalar, D: Dim>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
l: MatrixN<N, D>, l: MatrixN<N, D>,
} }
@ -38,10 +35,12 @@ impl<N: Scalar + Copy, D: Dim> Copy for Cholesky<N, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<N, D, D>,
MatrixN<N, D>: Copy, MatrixN<N, D>: Copy,
{} {
}
impl<N: CholeskyScalar + Zero, D: Dim> Cholesky<N, D> impl<N: CholeskyScalar + Zero, D: Dim> Cholesky<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Computes the cholesky decomposition of the given symmetric-definite-positive square /// Computes the cholesky decomposition of the given symmetric-definite-positive square
/// matrix. /// matrix.
@ -117,7 +116,9 @@ where DefaultAllocator: Allocator<N, D, D>
/// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is /// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is
/// the unknown to be determined. /// the unknown to be determined.
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
where DefaultAllocator: Allocator<N, R2, C2> { where
DefaultAllocator: Allocator<N, R2, C2>,
{
let dim = self.l.nrows(); let dim = self.l.nrows();
assert!( assert!(

View File

@ -34,7 +34,8 @@ use lapack;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Eigen<N: Scalar, D: Dim> pub struct Eigen<N: Scalar, D: Dim>
where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
{ {
/// The eigenvalues of the decomposed matrix. /// The eigenvalues of the decomposed matrix.
pub eigenvalues: VectorN<N, D>, pub eigenvalues: VectorN<N, D>,
@ -53,7 +54,8 @@ where
} }
impl<N: EigenScalar + RealField, D: Dim> Eigen<N, D> impl<N: EigenScalar + RealField, D: Dim> Eigen<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the square matrix `m`. /// Computes the eigenvalues and eigenvectors of the square matrix `m`.
/// ///
@ -62,8 +64,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
mut m: MatrixN<N, D>, mut m: MatrixN<N, D>,
left_eigenvectors: bool, left_eigenvectors: bool,
eigenvectors: bool, eigenvectors: bool,
) -> Option<Eigen<N, D>> ) -> Option<Eigen<N, D>> {
{
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."
@ -229,7 +230,9 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
/// ///
/// Panics if the eigenvalue computation does not converge. /// Panics if the eigenvalue computation does not converge.
pub fn complex_eigenvalues(mut m: MatrixN<N, D>) -> VectorN<Complex<N>, D> pub fn complex_eigenvalues(mut m: MatrixN<N, D>) -> VectorN<Complex<N>, D>
where DefaultAllocator: Allocator<Complex<N>, D> { where
DefaultAllocator: Allocator<Complex<N>, D>,
{
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."

View File

@ -1,11 +1,11 @@
use num::Zero; use num::Zero;
use num_complex::Complex; use num_complex::Complex;
use crate::ComplexHelper;
use na::allocator::Allocator; use na::allocator::Allocator;
use na::dimension::{DimDiff, DimSub, U1}; use na::dimension::{DimDiff, DimSub, U1};
use na::storage::Storage; use na::storage::Storage;
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN}; use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
use crate::ComplexHelper;
use lapack; use lapack;
@ -13,25 +13,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, D, D> +
serialize = "DefaultAllocator: Allocator<N, D, D> +
Allocator<N, DimDiff<D, U1>>, Allocator<N, DimDiff<D, U1>>,
MatrixN<N, D>: Serialize, MatrixN<N, D>: Serialize,
VectorN<N, DimDiff<D, U1>>: Serialize" VectorN<N, DimDiff<D, U1>>: Serialize"))
))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(deserialize = "DefaultAllocator: Allocator<N, D, D> +
deserialize = "DefaultAllocator: Allocator<N, D, D> +
Allocator<N, DimDiff<D, U1>>, Allocator<N, DimDiff<D, U1>>,
MatrixN<N, D>: Deserialize<'de>, MatrixN<N, D>: Deserialize<'de>,
VectorN<N, DimDiff<D, U1>>: Deserialize<'de>" VectorN<N, DimDiff<D, U1>>: Deserialize<'de>"))
))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hessenberg<N: Scalar, D: DimSub<U1>> pub struct Hessenberg<N: Scalar, D: DimSub<U1>>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
{ {
h: MatrixN<N, D>, h: MatrixN<N, D>,
tau: VectorN<N, DimDiff<D, U1>>, tau: VectorN<N, DimDiff<D, U1>>,
@ -42,10 +39,12 @@ where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>, DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
MatrixN<N, D>: Copy, MatrixN<N, D>: Copy,
VectorN<N, DimDiff<D, U1>>: Copy, VectorN<N, DimDiff<D, U1>>: Copy,
{} {
}
impl<N: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<N, D> impl<N: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
{ {
/// Computes the hessenberg decomposition of the matrix `m`. /// Computes the hessenberg decomposition of the matrix `m`.
pub fn new(mut m: MatrixN<N, D>) -> Self { pub fn new(mut m: MatrixN<N, D>) -> Self {
@ -97,7 +96,8 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>
} }
impl<N: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<N, D> impl<N: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
{ {
/// Computes the matrices `(Q, H)` of this decomposition. /// Computes the matrices `(Q, H)` of this decomposition.
#[inline] #[inline]

View File

@ -1,11 +1,11 @@
use num::{One, Zero}; use num::{One, Zero};
use num_complex::Complex; use num_complex::Complex;
use crate::ComplexHelper;
use na::allocator::Allocator; use na::allocator::Allocator;
use na::dimension::{Dim, DimMin, DimMinimum, U1}; use na::dimension::{Dim, DimMin, DimMinimum, U1};
use na::storage::Storage; use na::storage::Storage;
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN}; use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN};
use crate::ComplexHelper;
use lapack; use lapack;
@ -20,25 +20,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> +
serialize = "DefaultAllocator: Allocator<N, R, C> +
Allocator<i32, DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Serialize, MatrixMN<N, R, C>: Serialize,
PermutationSequence<DimMinimum<R, C>>: Serialize" PermutationSequence<DimMinimum<R, C>>: Serialize"))
))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> +
deserialize = "DefaultAllocator: Allocator<N, R, C> +
Allocator<i32, DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Deserialize<'de>, MatrixMN<N, R, C>: Deserialize<'de>,
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>" PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LU<N: Scalar, R: DimMin<C>, C: Dim> pub struct LU<N: Scalar, R: DimMin<C>, C: Dim>
where DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<N, R, C> where
DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<N, R, C>,
{ {
lu: MatrixMN<N, R, C>, lu: MatrixMN<N, R, C>,
p: VectorN<i32, DimMinimum<R, C>>, p: VectorN<i32, DimMinimum<R, C>>,
@ -49,7 +46,8 @@ where
DefaultAllocator: Allocator<N, R, C> + Allocator<i32, DimMinimum<R, C>>, DefaultAllocator: Allocator<N, R, C> + Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Copy, MatrixMN<N, R, C>: Copy,
VectorN<i32, DimMinimum<R, C>>: Copy, VectorN<i32, DimMinimum<R, C>>: Copy,
{} {
}
impl<N: LUScalar, R: Dim, C: Dim> LU<N, R, C> impl<N: LUScalar, R: Dim, C: Dim> LU<N, R, C>
where where
@ -133,7 +131,9 @@ where
/// Applies the permutation matrix to a given matrix or vector in-place. /// Applies the permutation matrix to a given matrix or vector in-place.
#[inline] #[inline]
pub fn permute<C2: Dim>(&self, rhs: &mut MatrixMN<N, R, C2>) pub fn permute<C2: Dim>(&self, rhs: &mut MatrixMN<N, R, C2>)
where DefaultAllocator: Allocator<N, R, C2> { where
DefaultAllocator: Allocator<N, R, C2>,
{
let (nrows, ncols) = rhs.shape(); let (nrows, ncols) = rhs.shape();
N::xlaswp( N::xlaswp(
@ -148,7 +148,9 @@ where
} }
fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut MatrixMN<N, R2, C2>) -> bool fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut MatrixMN<N, R2, C2>) -> bool
where DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2> { where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
{
let dim = self.lu.nrows(); let dim = self.lu.nrows();
assert!( assert!(
@ -236,7 +238,9 @@ where
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
where DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2> { where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
{
self.generic_solve_mut(b'N', b) self.generic_solve_mut(b'N', b)
} }
@ -245,7 +249,9 @@ where
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
where DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2> { where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
{
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
@ -253,10 +259,7 @@ where
/// be determined. /// be determined.
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>( pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
&self,
b: &mut MatrixMN<N, R2, C2>,
) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
{ {

View File

@ -4,11 +4,11 @@ use serde::{Deserialize, Serialize};
use num::Zero; use num::Zero;
use num_complex::Complex; use num_complex::Complex;
use crate::ComplexHelper;
use na::allocator::Allocator; use na::allocator::Allocator;
use na::dimension::{Dim, DimMin, DimMinimum, U1}; use na::dimension::{Dim, DimMin, DimMinimum, U1};
use na::storage::Storage; use na::storage::Storage;
use na::{DefaultAllocator, Matrix, MatrixMN, Scalar, VectorN}; use na::{DefaultAllocator, Matrix, MatrixMN, Scalar, VectorN};
use crate::ComplexHelper;
use lapack; use lapack;
@ -16,25 +16,22 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> +
serialize = "DefaultAllocator: Allocator<N, R, C> +
Allocator<N, DimMinimum<R, C>>, Allocator<N, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Serialize, MatrixMN<N, R, C>: Serialize,
VectorN<N, DimMinimum<R, C>>: Serialize" VectorN<N, DimMinimum<R, C>>: Serialize"))
))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> +
deserialize = "DefaultAllocator: Allocator<N, R, C> +
Allocator<N, DimMinimum<R, C>>, Allocator<N, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Deserialize<'de>, MatrixMN<N, R, C>: Deserialize<'de>,
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>" VectorN<N, DimMinimum<R, C>>: Deserialize<'de>"))
))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct QR<N: Scalar, R: DimMin<C>, C: Dim> pub struct QR<N: Scalar, R: DimMin<C>, C: Dim>
where DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>,
{ {
qr: MatrixMN<N, R, C>, qr: MatrixMN<N, R, C>,
tau: VectorN<N, DimMinimum<R, C>>, tau: VectorN<N, DimMinimum<R, C>>,
@ -45,13 +42,15 @@ where
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>, DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Copy, MatrixMN<N, R, C>: Copy,
VectorN<N, DimMinimum<R, C>>: Copy, VectorN<N, DimMinimum<R, C>>: Copy,
{} {
}
impl<N: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<N, R, C> impl<N: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<N, R, C>
where DefaultAllocator: Allocator<N, R, C> where
DefaultAllocator: Allocator<N, R, C>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<N, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<N, DimMinimum<R, C>, C>
+ Allocator<N, DimMinimum<R, C>> + Allocator<N, DimMinimum<R, C>>,
{ {
/// Computes the QR decomposition of the matrix `m`. /// Computes the QR decomposition of the matrix `m`.
pub fn new(mut m: MatrixMN<N, R, C>) -> Self { pub fn new(mut m: MatrixMN<N, R, C>) -> Self {
@ -98,10 +97,11 @@ where DefaultAllocator: Allocator<N, R, C>
} }
impl<N: QRReal + Zero, R: DimMin<C>, C: Dim> QR<N, R, C> impl<N: QRReal + Zero, R: DimMin<C>, C: Dim> QR<N, R, C>
where DefaultAllocator: Allocator<N, R, C> where
DefaultAllocator: Allocator<N, R, C>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<N, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<N, DimMinimum<R, C>, C>
+ Allocator<N, DimMinimum<R, C>> + Allocator<N, DimMinimum<R, C>>,
{ {
/// Retrieves the matrices `(Q, R)` of this decompositions. /// Retrieves the matrices `(Q, R)` of this decompositions.
pub fn unpack( pub fn unpack(

View File

@ -34,7 +34,8 @@ use lapack;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Schur<N: Scalar, D: Dim> pub struct Schur<N: Scalar, D: Dim>
where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
{ {
re: VectorN<N, D>, re: VectorN<N, D>,
im: VectorN<N, D>, im: VectorN<N, D>,
@ -51,7 +52,8 @@ where
} }
impl<N: SchurScalar + RealField, D: Dim> Schur<N, D> impl<N: SchurScalar + RealField, D: Dim> Schur<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
/// Computes the eigenvalues and real Schur form of the matrix `m`. /// Computes the eigenvalues and real Schur form of the matrix `m`.
/// ///
@ -146,7 +148,9 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
/// Computes the complex eigenvalues of the decomposed matrix. /// Computes the complex eigenvalues of the decomposed matrix.
pub fn complex_eigenvalues(&self) -> VectorN<Complex<N>, D> pub fn complex_eigenvalues(&self) -> VectorN<Complex<N>, D>
where DefaultAllocator: Allocator<Complex<N>, D> { where
DefaultAllocator: Allocator<Complex<N>, D>,
{
let mut out = unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1) }; let mut out = unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1) };
for i in 0..out.len() { for i in 0..out.len() {

View File

@ -15,29 +15,26 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
Allocator<N, R, R> + Allocator<N, R, R> +
Allocator<N, C, C>, Allocator<N, C, C>,
MatrixN<N, R>: Serialize, MatrixN<N, R>: Serialize,
MatrixN<N, C>: Serialize, MatrixN<N, C>: Serialize,
VectorN<N, DimMinimum<R, C>>: Serialize" VectorN<N, DimMinimum<R, C>>: Serialize"))
))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound( serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
Allocator<N, R, R> + Allocator<N, R, R> +
Allocator<N, C, C>, Allocator<N, C, C>,
MatrixN<N, R>: Deserialize<'de>, MatrixN<N, R>: Deserialize<'de>,
MatrixN<N, C>: Deserialize<'de>, MatrixN<N, C>: Deserialize<'de>,
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>" VectorN<N, DimMinimum<R, C>>: Deserialize<'de>"))
))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SVD<N: Scalar, R: DimMin<C>, C: Dim> pub struct SVD<N: Scalar, R: DimMin<C>, C: Dim>
where DefaultAllocator: Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>> + Allocator<N, C, C> where
DefaultAllocator: Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>> + Allocator<N, C, C>,
{ {
/// The left-singular vectors `U` of this SVD. /// The left-singular vectors `U` of this SVD.
pub u: MatrixN<N, R>, // FIXME: should be MatrixMN<N, R, DimMinimum<R, C>> pub u: MatrixN<N, R>, // FIXME: should be MatrixMN<N, R, DimMinimum<R, C>>
@ -53,25 +50,28 @@ where
MatrixMN<N, R, R>: Copy, MatrixMN<N, R, R>: Copy,
MatrixMN<N, C, C>: Copy, MatrixMN<N, C, C>: Copy,
VectorN<N, DimMinimum<R, C>>: Copy, VectorN<N, DimMinimum<R, C>>: Copy,
{} {
}
/// Trait implemented by floats (`f32`, `f64`) and complex floats (`Complex<f32>`, `Complex<f64>`) /// Trait implemented by floats (`f32`, `f64`) and complex floats (`Complex<f32>`, `Complex<f64>`)
/// supported by the Singular Value Decompotition. /// supported by the Singular Value Decompotition.
pub trait SVDScalar<R: DimMin<C>, C: Dim>: Scalar pub trait SVDScalar<R: DimMin<C>, C: Dim>: Scalar
where DefaultAllocator: Allocator<Self, R, R> where
DefaultAllocator: Allocator<Self, R, R>
+ Allocator<Self, R, C> + Allocator<Self, R, C>
+ Allocator<Self, DimMinimum<R, C>> + Allocator<Self, DimMinimum<R, C>>
+ Allocator<Self, C, C> + Allocator<Self, C, C>,
{ {
/// Computes the SVD decomposition of `m`. /// Computes the SVD decomposition of `m`.
fn compute(m: MatrixMN<Self, R, C>) -> Option<SVD<Self, R, C>>; fn compute(m: MatrixMN<Self, R, C>) -> Option<SVD<Self, R, C>>;
} }
impl<N: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<N, R, C> impl<N: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<N, R, C>
where DefaultAllocator: Allocator<N, R, R> where
DefaultAllocator: Allocator<N, R, R>
+ Allocator<N, R, C> + Allocator<N, R, C>
+ Allocator<N, DimMinimum<R, C>> + Allocator<N, DimMinimum<R, C>>
+ Allocator<N, C, C> + Allocator<N, C, C>,
{ {
/// Computes the Singular Value Decomposition of `matrix`. /// Computes the Singular Value Decomposition of `matrix`.
pub fn new(m: MatrixMN<N, R, C>) -> Option<Self> { pub fn new(m: MatrixMN<N, R, C>) -> Option<Self> {

View File

@ -32,7 +32,8 @@ use lapack;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SymmetricEigen<N: Scalar, D: Dim> pub struct SymmetricEigen<N: Scalar, D: Dim>
where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
{ {
/// The eigenvectors of the decomposed matrix. /// The eigenvectors of the decomposed matrix.
pub eigenvectors: MatrixN<N, D>, pub eigenvectors: MatrixN<N, D>,
@ -50,7 +51,8 @@ where
} }
impl<N: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<N, D> impl<N: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`. /// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
/// ///
@ -79,8 +81,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
fn do_decompose( fn do_decompose(
mut m: MatrixN<N, D>, mut m: MatrixN<N, D>,
eigenvectors: bool, eigenvectors: bool,
) -> Option<(VectorN<N, D>, Option<MatrixN<N, D>>)> ) -> Option<(VectorN<N, D>, Option<MatrixN<N, D>>)> {
{
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."

View File

@ -3,7 +3,7 @@ use std::cmp;
use na::{DMatrix, DVector, Matrix3, Matrix4, Matrix4x3, Vector4}; use na::{DMatrix, DVector, Matrix3, Matrix4, Matrix4x3, Vector4};
use nl::Cholesky; use nl::Cholesky;
quickcheck!{ quickcheck! {
fn cholesky(m: DMatrix<f64>) -> bool { fn cholesky(m: DMatrix<f64>) -> bool {
if m.len() != 0 { if m.len() != 0 {
let m = &m * m.transpose(); let m = &m * m.transpose();

View File

@ -3,7 +3,7 @@ use std::cmp;
use na::{DMatrix, DVector, Matrix3x4, Matrix4, Matrix4x3, Vector4}; use na::{DMatrix, DVector, Matrix3x4, Matrix4, Matrix4x3, Vector4};
use nl::LU; use nl::LU;
quickcheck!{ quickcheck! {
fn lup(m: DMatrix<f64>) -> bool { fn lup(m: DMatrix<f64>) -> bool {
if m.len() != 0 { if m.len() != 0 {
let lup = LU::new(m.clone()); let lup = LU::new(m.clone());

View File

@ -1,7 +1,7 @@
use na::{DMatrix, Matrix4x3}; use na::{DMatrix, Matrix4x3};
use nl::QR; use nl::QR;
quickcheck!{ quickcheck! {
fn qr(m: DMatrix<f64>) -> bool { fn qr(m: DMatrix<f64>) -> bool {
let qr = QR::new(m.clone()); let qr = QR::new(m.clone());
let q = qr.q(); let q = qr.q();

View File

@ -3,7 +3,7 @@ use std::cmp;
use na::{DMatrix, Matrix4}; use na::{DMatrix, Matrix4};
use nl::Eigen; use nl::Eigen;
quickcheck!{ quickcheck! {
fn eigensystem(n: usize) -> bool { fn eigensystem(n: usize) -> bool {
if n != 0 { if n != 0 {
let n = cmp::min(n, 25); let n = cmp::min(n, 25);

View File

@ -1,7 +1,7 @@
use na::{DMatrix, Matrix3x4}; use na::{DMatrix, Matrix3x4};
use nl::SVD; use nl::SVD;
quickcheck!{ quickcheck! {
fn svd(m: DMatrix<f64>) -> bool { fn svd(m: DMatrix<f64>) -> bool {
if m.nrows() != 0 && m.ncols() != 0 { if m.nrows() != 0 && m.ncols() != 0 {
let svd = SVD::new(m.clone()).unwrap(); let svd = SVD::new(m.clone()).unwrap();

View File

@ -3,7 +3,7 @@ use std::cmp;
use na::{DMatrix, Matrix4}; use na::{DMatrix, Matrix4};
use nl::SymmetricEigen; use nl::SymmetricEigen;
quickcheck!{ quickcheck! {
fn symmetric_eigen(n: usize) -> bool { fn symmetric_eigen(n: usize) -> bool {
let n = cmp::max(1, cmp::min(n, 10)); let n = cmp::max(1, cmp::min(n, 10));
let m = DMatrix::<f64>::new_random(n, n); let m = DMatrix::<f64>::new_random(n, n);

View File

@ -1,9 +1,9 @@
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::Dynamic;
use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::base::storage::Owned;
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage; use crate::base::vec_storage::VecStorage;
use crate::base::storage::Owned;
use crate::base::Matrix; use crate::base::Matrix;
/* /*

View File

@ -179,20 +179,27 @@ pub type VectorSliceN<'a, N, D, RStride = U1, CStride = D> =
Matrix<N, D, U1, SliceStorage<'a, N, D, U1, RStride, CStride>>; Matrix<N, D, U1, SliceStorage<'a, N, D, U1, RStride, CStride>>;
/// A column vector slice dynamic numbers of rows and columns. /// A column vector slice dynamic numbers of rows and columns.
pub type DVectorSlice<'a, N, RStride = U1, CStride = Dynamic> = VectorSliceN<'a, N, Dynamic, RStride, CStride>; pub type DVectorSlice<'a, N, RStride = U1, CStride = Dynamic> =
VectorSliceN<'a, N, Dynamic, RStride, CStride>;
/// A 1D column vector slice. /// A 1D column vector slice.
pub type VectorSlice1<'a, N, RStride = U1, CStride = U1> = VectorSliceN<'a, N, U1, RStride, CStride>; pub type VectorSlice1<'a, N, RStride = U1, CStride = U1> =
VectorSliceN<'a, N, U1, RStride, CStride>;
/// A 2D column vector slice. /// A 2D column vector slice.
pub type VectorSlice2<'a, N, RStride = U1, CStride = U2> = VectorSliceN<'a, N, U2, RStride, CStride>; pub type VectorSlice2<'a, N, RStride = U1, CStride = U2> =
VectorSliceN<'a, N, U2, RStride, CStride>;
/// A 3D column vector slice. /// A 3D column vector slice.
pub type VectorSlice3<'a, N, RStride = U1, CStride = U3> = VectorSliceN<'a, N, U3, RStride, CStride>; pub type VectorSlice3<'a, N, RStride = U1, CStride = U3> =
VectorSliceN<'a, N, U3, RStride, CStride>;
/// A 4D column vector slice. /// A 4D column vector slice.
pub type VectorSlice4<'a, N, RStride = U1, CStride = U4> = VectorSliceN<'a, N, U4, RStride, CStride>; pub type VectorSlice4<'a, N, RStride = U1, CStride = U4> =
VectorSliceN<'a, N, U4, RStride, CStride>;
/// A 5D column vector slice. /// A 5D column vector slice.
pub type VectorSlice5<'a, N, RStride = U1, CStride = U5> = VectorSliceN<'a, N, U5, RStride, CStride>; pub type VectorSlice5<'a, N, RStride = U1, CStride = U5> =
VectorSliceN<'a, N, U5, RStride, CStride>;
/// A 6D column vector slice. /// A 6D column vector slice.
pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> = VectorSliceN<'a, N, U6, RStride, CStride>; pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> =
VectorSliceN<'a, N, U6, RStride, CStride>;
/* /*
* *
@ -371,17 +378,24 @@ pub type VectorSliceMutN<'a, N, D, RStride = U1, CStride = D> =
Matrix<N, D, U1, SliceStorageMut<'a, N, D, U1, RStride, CStride>>; Matrix<N, D, U1, SliceStorageMut<'a, N, D, U1, RStride, CStride>>;
/// A mutable column vector slice dynamic numbers of rows and columns. /// A mutable column vector slice dynamic numbers of rows and columns.
pub type DVectorSliceMut<'a, N, RStride = U1, CStride = Dynamic> = VectorSliceMutN<'a, N, Dynamic, RStride, CStride>; pub type DVectorSliceMut<'a, N, RStride = U1, CStride = Dynamic> =
VectorSliceMutN<'a, N, Dynamic, RStride, CStride>;
/// A 1D mutable column vector slice. /// A 1D mutable column vector slice.
pub type VectorSliceMut1<'a, N, RStride = U1, CStride = U1> = VectorSliceMutN<'a, N, U1, RStride, CStride>; pub type VectorSliceMut1<'a, N, RStride = U1, CStride = U1> =
VectorSliceMutN<'a, N, U1, RStride, CStride>;
/// A 2D mutable column vector slice. /// A 2D mutable column vector slice.
pub type VectorSliceMut2<'a, N, RStride = U1, CStride = U2> = VectorSliceMutN<'a, N, U2, RStride, CStride>; pub type VectorSliceMut2<'a, N, RStride = U1, CStride = U2> =
VectorSliceMutN<'a, N, U2, RStride, CStride>;
/// A 3D mutable column vector slice. /// A 3D mutable column vector slice.
pub type VectorSliceMut3<'a, N, RStride = U1, CStride = U3> = VectorSliceMutN<'a, N, U3, RStride, CStride>; pub type VectorSliceMut3<'a, N, RStride = U1, CStride = U3> =
VectorSliceMutN<'a, N, U3, RStride, CStride>;
/// A 4D mutable column vector slice. /// A 4D mutable column vector slice.
pub type VectorSliceMut4<'a, N, RStride = U1, CStride = U4> = VectorSliceMutN<'a, N, U4, RStride, CStride>; pub type VectorSliceMut4<'a, N, RStride = U1, CStride = U4> =
VectorSliceMutN<'a, N, U4, RStride, CStride>;
/// A 5D mutable column vector slice. /// A 5D mutable column vector slice.
pub type VectorSliceMut5<'a, N, RStride = U1, CStride = U5> = VectorSliceMutN<'a, N, U5, RStride, CStride>; pub type VectorSliceMut5<'a, N, RStride = U1, CStride = U5> =
VectorSliceMutN<'a, N, U5, RStride, CStride>;
/// A 6D mutable column vector slice. /// A 6D mutable column vector slice.
pub type VectorSliceMut6<'a, N, RStride = U1, CStride = U6> = VectorSliceMutN<'a, N, U6, RStride, CStride>; pub type VectorSliceMut6<'a, N, RStride = U1, CStride = U6> =
VectorSliceMutN<'a, N, U6, RStride, CStride>;

View File

@ -79,7 +79,8 @@ where
N: Scalar, N: Scalar,
DefaultAllocator: Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>, DefaultAllocator: Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{} {
}
// XXX: Bad name. // XXX: Bad name.
/// Restricts the given number of rows to be equal. /// Restricts the given number of rows to be equal.
@ -100,4 +101,5 @@ where
N: Scalar, N: Scalar,
DefaultAllocator: Allocator<N, R1, U1> + Allocator<N, SameShapeR<R1, R2>>, DefaultAllocator: Allocator<N, R1, U1> + Allocator<N, SameShapeR<R1, R2>>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{} {
}

View File

@ -44,7 +44,7 @@ where
data: GenericArray<N, Prod<R::Value, C::Value>>, data: GenericArray<N, Prod<R::Value, C::Value>>,
} }
#[deprecated(note="renamed to `ArrayStorage`")] #[deprecated(note = "renamed to `ArrayStorage`")]
/// Renamed to [ArrayStorage]. /// Renamed to [ArrayStorage].
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>; pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;
@ -111,7 +111,8 @@ where
R::Value: Mul<C::Value>, R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
GenericArray<N, Prod<R::Value, C::Value>>: Copy, GenericArray<N, Prod<R::Value, C::Value>>: Copy,
{} {
}
impl<N, R, C> Clone for ArrayStorage<N, R, C> impl<N, R, C> Clone for ArrayStorage<N, R, C>
where where
@ -136,7 +137,8 @@ where
C: DimName, C: DimName,
R::Value: Mul<C::Value>, R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
{} {
}
impl<N, R, C> PartialEq for ArrayStorage<N, R, C> impl<N, R, C> PartialEq for ArrayStorage<N, R, C>
where where
@ -186,13 +188,17 @@ where
#[inline] #[inline]
fn into_owned(self) -> Owned<N, R, C> fn into_owned(self) -> Owned<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, R, C> fn clone_owned(&self) -> Owned<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
let it = self.iter().cloned(); let it = self.iter().cloned();
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it) DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
@ -232,7 +238,8 @@ where
R::Value: Mul<C::Value>, R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>, DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{} {
}
unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for ArrayStorage<N, R, C> unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for ArrayStorage<N, R, C>
where where
@ -242,7 +249,8 @@ where
R::Value: Mul<C::Value>, R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
DefaultAllocator: Allocator<N, R, C, Buffer = Self>, DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
{} {
}
/* /*
* *
@ -260,7 +268,9 @@ where
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?; let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?;
for e in self.iter() { for e in self.iter() {
@ -281,7 +291,9 @@ where
Prod<R::Value, C::Value>: ArrayLength<N>, Prod<R::Value, C::Value>: ArrayLength<N>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'a> { where
D: Deserializer<'a>,
{
deserializer.deserialize_seq(ArrayStorageVisitor::new()) deserializer.deserialize_seq(ArrayStorageVisitor::new())
} }
} }
@ -326,12 +338,15 @@ where
#[inline] #[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<N, R, C>, V::Error> fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<N, R, C>, V::Error>
where V: SeqAccess<'a> { where
V: SeqAccess<'a>,
{
let mut out: Self::Value = unsafe { mem::uninitialized() }; let mut out: Self::Value = unsafe { mem::uninitialized() };
let mut curr = 0; let mut curr = 0;
while let Some(value) = visitor.next_element()? { while let Some(value) = visitor.next_element()? {
*out.get_mut(curr).ok_or_else(|| V::Error::invalid_length(curr, &self))? = value; *out.get_mut(curr)
.ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
curr += 1; curr += 1;
} }

View File

@ -104,7 +104,9 @@ impl<N: Scalar + PartialOrd, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn iamax(&self) -> usize pub fn iamax(&self) -> usize
where N: Signed { where
N: Signed,
{
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_max = unsafe { self.vget_unchecked(0).abs() }; let mut the_max = unsafe { self.vget_unchecked(0).abs() };
@ -175,7 +177,9 @@ impl<N: Scalar + PartialOrd, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn iamin(&self) -> usize pub fn iamin(&self) -> usize
where N: Signed { where
N: Signed,
{
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
let mut the_min = unsafe { self.vget_unchecked(0).abs() }; let mut the_min = unsafe { self.vget_unchecked(0).abs() };
@ -265,7 +269,8 @@ impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matri
} }
impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
where N: Scalar + Zero + ClosedAdd + ClosedMul where
N: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn dotx<R2: Dim, C2: Dim, SB>( fn dotx<R2: Dim, C2: Dim, SB>(
@ -535,7 +540,9 @@ fn array_axcpy<N>(
} }
fn array_axc<N>(y: &mut [N], a: N, x: &[N], c: N, stride1: usize, stride2: usize, len: usize) fn array_axc<N>(y: &mut [N], a: N, x: &[N], c: N, stride1: usize, stride2: usize, len: usize)
where N: Scalar + Zero + ClosedAdd + ClosedMul { where
N: Scalar + Zero + ClosedAdd + ClosedMul,
{
for i in 0..len { for i in 0..len {
unsafe { unsafe {
*y.get_unchecked_mut(i * stride1) = a.inlined_clone() *y.get_unchecked_mut(i * stride1) = a.inlined_clone()
@ -948,7 +955,8 @@ where
} }
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S> impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
where N: Scalar + Zero + ClosedAdd + ClosedMul where
N: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn gerx<D2: Dim, D3: Dim, SB, SC>( fn gerx<D2: Dim, D3: Dim, SB, SC>(
@ -1321,7 +1329,8 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
} }
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S> impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
where N: Scalar + Zero + ClosedAdd + ClosedMul where
N: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn xxgerx<D2: Dim, D3: Dim, SB, SC>( fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
@ -1468,7 +1477,8 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
} }
impl<N, D1: Dim, S: StorageMut<N, D1, D1>> SquareMatrix<N, D1, S> impl<N, D1: Dim, S: StorageMut<N, D1, D1>> SquareMatrix<N, D1, S>
where N: Scalar + Zero + One + ClosedAdd + ClosedMul where
N: Scalar + Zero + One + ClosedAdd + ClosedMul,
{ {
/// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`. /// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`.
/// ///

View File

@ -253,7 +253,9 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: StorageMut<N
/// Computes in-place the transformation equal to `self` followed by an uniform scaling factor. /// Computes in-place the transformation equal to `self` followed by an uniform scaling factor.
#[inline] #[inline]
pub fn append_scaling_mut(&mut self, scaling: N) pub fn append_scaling_mut(&mut self, scaling: N)
where D: DimNameSub<U1> { where
D: DimNameSub<U1>,
{
let mut to_scale = self.fixed_rows_mut::<DimNameDiff<D, U1>>(0); let mut to_scale = self.fixed_rows_mut::<DimNameDiff<D, U1>>(0);
to_scale *= scaling; to_scale *= scaling;
} }
@ -261,7 +263,9 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: StorageMut<N
/// Computes in-place the transformation equal to an uniform scaling factor followed by `self`. /// Computes in-place the transformation equal to an uniform scaling factor followed by `self`.
#[inline] #[inline]
pub fn prepend_scaling_mut(&mut self, scaling: N) pub fn prepend_scaling_mut(&mut self, scaling: N)
where D: DimNameSub<U1> { where
D: DimNameSub<U1>,
{
let mut to_scale = self.fixed_columns_mut::<DimNameDiff<D, U1>>(0); let mut to_scale = self.fixed_columns_mut::<DimNameDiff<D, U1>>(0);
to_scale *= scaling; to_scale *= scaling;
} }
@ -331,17 +335,17 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: StorageMut<N
} }
impl<N: RealField, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<N: RealField, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>
+ Allocator<N, DimNameDiff<D, U1>> + Allocator<N, DimNameDiff<D, U1>>
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>> + Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>,
{ {
/// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_vector( pub fn transform_vector(
&self, &self,
v: &VectorN<N, DimNameDiff<D, U1>>, v: &VectorN<N, DimNameDiff<D, U1>>,
) -> VectorN<N, DimNameDiff<D, U1>> ) -> VectorN<N, DimNameDiff<D, U1>> {
{
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0); let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0); let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);
let n = normalizer.tr_dot(&v); let n = normalizer.tr_dot(&v);
@ -358,8 +362,7 @@ where DefaultAllocator: Allocator<N, D, D>
pub fn transform_point( pub fn transform_point(
&self, &self,
pt: &Point<N, DimNameDiff<D, U1>>, pt: &Point<N, DimNameDiff<D, U1>>,
) -> Point<N, DimNameDiff<D, U1>> ) -> Point<N, DimNameDiff<D, U1>> {
{
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0); let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1); let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0); let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);

View File

@ -8,8 +8,10 @@ pub struct ShapeConstraint;
/// Constraints `C1` and `R2` to be equivalent. /// Constraints `C1` and `R2` to be equivalent.
pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {} pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {}
impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where ShapeConstraint: DimEq<C1, R2> impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where
{} ShapeConstraint: DimEq<C1, R2>
{
}
/// Constraints `D1` and `D2` to be equivalent. /// Constraints `D1` and `D2` to be equivalent.
pub trait DimEq<D1: Dim, D2: Dim> { pub trait DimEq<D1: Dim, D2: Dim> {

View File

@ -28,7 +28,8 @@ use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vec
* *
*/ */
impl<N: Scalar, R: Dim, C: Dim> MatrixMN<N, R, C> impl<N: Scalar, R: Dim, C: Dim> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> where
DefaultAllocator: Allocator<N, R, C>,
{ {
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics /// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`. /// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
@ -56,14 +57,18 @@ where DefaultAllocator: Allocator<N, R, C>
/// Creates a matrix with all its elements set to 0. /// Creates a matrix with all its elements set to 0.
#[inline] #[inline]
pub fn zeros_generic(nrows: R, ncols: C) -> Self pub fn zeros_generic(nrows: R, ncols: C) -> Self
where N: Zero { where
N: Zero,
{
Self::from_element_generic(nrows, ncols, N::zero()) Self::from_element_generic(nrows, ncols, N::zero())
} }
/// Creates a matrix with all its elements filled by an iterator. /// Creates a matrix with all its elements filled by an iterator.
#[inline] #[inline]
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
where I: IntoIterator<Item = N> { where
I: IntoIterator<Item = N>,
{
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter)) Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
} }
@ -102,7 +107,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// coordinates. /// coordinates.
#[inline] #[inline]
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
where F: FnMut(usize, usize) -> N { where
F: FnMut(usize, usize) -> N,
{
let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) }; let mut res = unsafe { Self::new_uninitialized_generic(nrows, ncols) };
for j in 0..ncols.value() { for j in 0..ncols.value() {
@ -120,7 +127,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// to the identity matrix. All other entries are set to zero. /// to the identity matrix. All other entries are set to zero.
#[inline] #[inline]
pub fn identity_generic(nrows: R, ncols: C) -> Self pub fn identity_generic(nrows: R, ncols: C) -> Self
where N: Zero + One { where
N: Zero + One,
{
Self::from_diagonal_element_generic(nrows, ncols, N::one()) Self::from_diagonal_element_generic(nrows, ncols, N::one())
} }
@ -130,7 +139,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// to the identity matrix. All other entries are set to zero. /// to the identity matrix. All other entries are set to zero.
#[inline] #[inline]
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Self pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Self
where N: Zero + One { where
N: Zero + One,
{
let mut res = Self::zeros_generic(nrows, ncols); let mut res = Self::zeros_generic(nrows, ncols);
for i in 0..crate::min(nrows.value(), ncols.value()) { for i in 0..crate::min(nrows.value(), ncols.value()) {
@ -146,7 +157,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`. /// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
#[inline] #[inline]
pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[N]) -> Self pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[N]) -> Self
where N: Zero { where
N: Zero,
{
let mut res = Self::zeros_generic(nrows, ncols); let mut res = Self::zeros_generic(nrows, ncols);
assert!( assert!(
elts.len() <= crate::min(nrows.value(), ncols.value()), elts.len() <= crate::min(nrows.value(), ncols.value()),
@ -178,7 +191,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// ``` /// ```
#[inline] #[inline]
pub fn from_rows<SB>(rows: &[Matrix<N, U1, C, SB>]) -> Self pub fn from_rows<SB>(rows: &[Matrix<N, U1, C, SB>]) -> Self
where SB: Storage<N, U1, C> { where
SB: Storage<N, U1, C>,
{
assert!(rows.len() > 0, "At least one row must be given."); assert!(rows.len() > 0, "At least one row must be given.");
let nrows = R::try_to_usize().unwrap_or(rows.len()); let nrows = R::try_to_usize().unwrap_or(rows.len());
let ncols = rows[0].len(); let ncols = rows[0].len();
@ -218,7 +233,9 @@ where DefaultAllocator: Allocator<N, R, C>
/// ``` /// ```
#[inline] #[inline]
pub fn from_columns<SB>(columns: &[Vector<N, R, SB>]) -> Self pub fn from_columns<SB>(columns: &[Vector<N, R, SB>]) -> Self
where SB: Storage<N, R> { where
SB: Storage<N, R>,
{
assert!(columns.len() > 0, "At least one column must be given."); assert!(columns.len() > 0, "At least one column must be given.");
let ncols = C::try_to_usize().unwrap_or(columns.len()); let ncols = C::try_to_usize().unwrap_or(columns.len());
let nrows = columns[0].len(); let nrows = columns[0].len();
@ -244,7 +261,9 @@ where DefaultAllocator: Allocator<N, R, C>
#[inline] #[inline]
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn new_random_generic(nrows: R, ncols: C) -> Self pub fn new_random_generic(nrows: R, ncols: C) -> Self
where Standard: Distribution<N> { where
Standard: Distribution<N>,
{
Self::from_fn_generic(nrows, ncols, |_, _| rand::random()) Self::from_fn_generic(nrows, ncols, |_, _| rand::random())
} }
@ -255,8 +274,7 @@ where DefaultAllocator: Allocator<N, R, C>
ncols: C, ncols: C,
distribution: &Distr, distribution: &Distr,
rng: &mut G, rng: &mut G,
) -> Self ) -> Self {
{
Self::from_fn_generic(nrows, ncols, |_, _| distribution.sample(rng)) Self::from_fn_generic(nrows, ncols, |_, _| distribution.sample(rng))
} }
@ -309,7 +327,9 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn from_diagonal<SB: Storage<N, D>>(diag: &Vector<N, D, SB>) -> Self pub fn from_diagonal<SB: Storage<N, D>>(diag: &Vector<N, D, SB>) -> Self
where N: Zero { where
N: Zero,
{
let (dim, _) = diag.data.shape(); let (dim, _) = diag.data.shape();
let mut res = Self::zeros_generic(dim, dim); let mut res = Self::zeros_generic(dim, dim);
@ -994,7 +1014,9 @@ where
/// The column vector with a 1 as its first component, and zero elsewhere. /// The column vector with a 1 as its first component, and zero elsewhere.
#[inline] #[inline]
pub fn x() -> Self pub fn x() -> Self
where R::Value: Cmp<typenum::U0, Output = Greater> { where
R::Value: Cmp<typenum::U0, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(0) = N::one(); *res.vget_unchecked_mut(0) = N::one();
@ -1006,7 +1028,9 @@ where
/// The column vector with a 1 as its second component, and zero elsewhere. /// The column vector with a 1 as its second component, and zero elsewhere.
#[inline] #[inline]
pub fn y() -> Self pub fn y() -> Self
where R::Value: Cmp<typenum::U1, Output = Greater> { where
R::Value: Cmp<typenum::U1, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(1) = N::one(); *res.vget_unchecked_mut(1) = N::one();
@ -1018,7 +1042,9 @@ where
/// The column vector with a 1 as its third component, and zero elsewhere. /// The column vector with a 1 as its third component, and zero elsewhere.
#[inline] #[inline]
pub fn z() -> Self pub fn z() -> Self
where R::Value: Cmp<typenum::U2, Output = Greater> { where
R::Value: Cmp<typenum::U2, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(2) = N::one(); *res.vget_unchecked_mut(2) = N::one();
@ -1030,7 +1056,9 @@ where
/// The column vector with a 1 as its fourth component, and zero elsewhere. /// The column vector with a 1 as its fourth component, and zero elsewhere.
#[inline] #[inline]
pub fn w() -> Self pub fn w() -> Self
where R::Value: Cmp<typenum::U3, Output = Greater> { where
R::Value: Cmp<typenum::U3, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(3) = N::one(); *res.vget_unchecked_mut(3) = N::one();
@ -1042,7 +1070,9 @@ where
/// The column vector with a 1 as its fifth component, and zero elsewhere. /// The column vector with a 1 as its fifth component, and zero elsewhere.
#[inline] #[inline]
pub fn a() -> Self pub fn a() -> Self
where R::Value: Cmp<typenum::U4, Output = Greater> { where
R::Value: Cmp<typenum::U4, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(4) = N::one(); *res.vget_unchecked_mut(4) = N::one();
@ -1054,7 +1084,9 @@ where
/// The column vector with a 1 as its sixth component, and zero elsewhere. /// The column vector with a 1 as its sixth component, and zero elsewhere.
#[inline] #[inline]
pub fn b() -> Self pub fn b() -> Self
where R::Value: Cmp<typenum::U5, Output = Greater> { where
R::Value: Cmp<typenum::U5, Output = Greater>,
{
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(5) = N::one(); *res.vget_unchecked_mut(5) = N::one();
@ -1066,42 +1098,54 @@ where
/// The unit column vector with a 1 as its first component, and zero elsewhere. /// The unit column vector with a 1 as its first component, and zero elsewhere.
#[inline] #[inline]
pub fn x_axis() -> Unit<Self> pub fn x_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U0, Output = Greater> { where
R::Value: Cmp<typenum::U0, Output = Greater>,
{
Unit::new_unchecked(Self::x()) Unit::new_unchecked(Self::x())
} }
/// The unit column vector with a 1 as its second component, and zero elsewhere. /// The unit column vector with a 1 as its second component, and zero elsewhere.
#[inline] #[inline]
pub fn y_axis() -> Unit<Self> pub fn y_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U1, Output = Greater> { where
R::Value: Cmp<typenum::U1, Output = Greater>,
{
Unit::new_unchecked(Self::y()) Unit::new_unchecked(Self::y())
} }
/// The unit column vector with a 1 as its third component, and zero elsewhere. /// The unit column vector with a 1 as its third component, and zero elsewhere.
#[inline] #[inline]
pub fn z_axis() -> Unit<Self> pub fn z_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U2, Output = Greater> { where
R::Value: Cmp<typenum::U2, Output = Greater>,
{
Unit::new_unchecked(Self::z()) Unit::new_unchecked(Self::z())
} }
/// The unit column vector with a 1 as its fourth component, and zero elsewhere. /// The unit column vector with a 1 as its fourth component, and zero elsewhere.
#[inline] #[inline]
pub fn w_axis() -> Unit<Self> pub fn w_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U3, Output = Greater> { where
R::Value: Cmp<typenum::U3, Output = Greater>,
{
Unit::new_unchecked(Self::w()) Unit::new_unchecked(Self::w())
} }
/// The unit column vector with a 1 as its fifth component, and zero elsewhere. /// The unit column vector with a 1 as its fifth component, and zero elsewhere.
#[inline] #[inline]
pub fn a_axis() -> Unit<Self> pub fn a_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U4, Output = Greater> { where
R::Value: Cmp<typenum::U4, Output = Greater>,
{
Unit::new_unchecked(Self::a()) Unit::new_unchecked(Self::a())
} }
/// The unit column vector with a 1 as its sixth component, and zero elsewhere. /// The unit column vector with a 1 as its sixth component, and zero elsewhere.
#[inline] #[inline]
pub fn b_axis() -> Unit<Self> pub fn b_axis() -> Unit<Self>
where R::Value: Cmp<typenum::U5, Output = Greater> { where
R::Value: Cmp<typenum::U5, Output = Greater>,
{
Unit::new_unchecked(Self::b()) Unit::new_unchecked(Self::b())
} }
} }

View File

@ -23,8 +23,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self ) -> Self {
{
let data = SliceStorage::from_raw_parts( let data = SliceStorage::from_raw_parts(
data.as_ptr().offset(start as isize), data.as_ptr().offset(start as isize),
(nrows, ncols), (nrows, ncols),
@ -44,8 +43,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self ) -> Self {
{
// NOTE: The assertion implements the following formula, but without subtractions to avoid // NOTE: The assertion implements the following formula, but without subtractions to avoid
// underflow panics: // underflow panics:
// len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1 // len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
@ -76,8 +74,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self ) -> Self {
{
let data = SliceStorageMut::from_raw_parts( let data = SliceStorageMut::from_raw_parts(
data.as_mut_ptr().offset(start as isize), data.as_mut_ptr().offset(start as isize),
(nrows, ncols), (nrows, ncols),
@ -97,8 +94,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self ) -> Self {
{
// NOTE: The assertion implements the following formula, but without subtractions to avoid // NOTE: The assertion implements the following formula, but without subtractions to avoid
// underflow panics: // underflow panics:
// len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1 // len >= (ncols - 1) * cstride + (nrows - 1) * rstride + 1
@ -108,24 +104,27 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
"Matrix slice: input data buffer to small." "Matrix slice: input data buffer to small."
); );
assert!({ assert!(
let nrows = nrows.value(); {
let ncols = ncols.value(); let nrows = nrows.value();
let rstride = rstride.value(); let ncols = ncols.value();
let cstride = cstride.value(); let rstride = rstride.value();
let cstride = cstride.value();
nrows * ncols <= 1 || nrows * ncols <= 1
match (rstride, cstride) { || match (rstride, cstride) {
(0, 0) => false, // otherwise: matrix[(0, 0)] == index[(nrows - 1, ncols - 1)], (0, 0) => false, // otherwise: matrix[(0, 0)] == index[(nrows - 1, ncols - 1)],
(0, _) => nrows <= 1, // otherwise: matrix[(0, 0)] == index[(nrows - 1, 0)], (0, _) => nrows <= 1, // otherwise: matrix[(0, 0)] == index[(nrows - 1, 0)],
(_, 0) => ncols <= 1, // otherwise: matrix[(0, 0)] == index[(0, ncols - 1)], (_, 0) => ncols <= 1, // otherwise: matrix[(0, 0)] == index[(0, ncols - 1)],
(_, _) => { // otherwise: matrix[(0, numer)] == index[(denom, 0)] (_, _) => {
let ratio = Ratio::new(rstride, cstride); // otherwise: matrix[(0, numer)] == index[(denom, 0)]
nrows <= *ratio.denom() || ncols <= *ratio.numer() let ratio = Ratio::new(rstride, cstride);
nrows <= *ratio.denom() || ncols <= *ratio.numer()
}
} }
}
}, },
"Matrix slice: dimensions and strides result in aliased indices."); "Matrix slice: dimensions and strides result in aliased indices."
);
unsafe { unsafe {
Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride) Self::from_slice_with_strides_generic_unchecked(data, 0, nrows, ncols, rstride, cstride)
@ -144,8 +143,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
) -> Self ) -> Self {
{
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
} }
@ -170,8 +168,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
) -> Self ) -> Self {
{
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows) Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
} }

View File

@ -15,13 +15,13 @@ use generic_array::ArrayLength;
use typenum::Prod; use typenum::Prod;
use crate::base::allocator::{Allocator, Reallocator}; use crate::base::allocator::{Allocator, Reallocator};
use crate::base::array_storage::ArrayStorage;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::Dynamic;
use crate::base::dimension::{Dim, DimName}; use crate::base::dimension::{Dim, DimName};
use crate::base::array_storage::ArrayStorage; use crate::base::storage::{Storage, StorageMut};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage; use crate::base::vec_storage::VecStorage;
use crate::base::storage::{Storage, StorageMut};
use crate::base::Scalar; use crate::base::Scalar;
/* /*
@ -54,8 +54,7 @@ where
nrows: R, nrows: R,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer ) -> Self::Buffer {
{
let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols) }; let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols) };
let mut count = 0; let mut count = 0;
@ -94,8 +93,7 @@ impl<N: Scalar, C: Dim> Allocator<N, Dynamic, C> for DefaultAllocator {
nrows: Dynamic, nrows: Dynamic,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer ) -> Self::Buffer {
{
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<N> = it.collect(); let res: Vec<N> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
@ -125,8 +123,7 @@ impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator {
nrows: R, nrows: R,
ncols: Dynamic, ncols: Dynamic,
iter: I, iter: I,
) -> Self::Buffer ) -> Self::Buffer {
{
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<N> = it.collect(); let res: Vec<N> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
@ -157,8 +154,7 @@ where
rto: RTo, rto: RTo,
cto: CTo, cto: CTo,
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer, buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer,
) -> ArrayStorage<N, RTo, CTo> ) -> ArrayStorage<N, RTo, CTo> {
{
let mut res = <Self as Allocator<N, RTo, CTo>>::allocate_uninitialized(rto, cto); let mut res = <Self as Allocator<N, RTo, CTo>>::allocate_uninitialized(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -186,8 +182,7 @@ where
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFrom, CFrom>,
) -> VecStorage<N, Dynamic, CTo> ) -> VecStorage<N, Dynamic, CTo> {
{
let mut res = <Self as Allocator<N, Dynamic, CTo>>::allocate_uninitialized(rto, cto); let mut res = <Self as Allocator<N, Dynamic, CTo>>::allocate_uninitialized(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -215,8 +210,7 @@ where
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: ArrayStorage<N, RFrom, CFrom>, buf: ArrayStorage<N, RFrom, CFrom>,
) -> VecStorage<N, RTo, Dynamic> ) -> VecStorage<N, RTo, Dynamic> {
{
let mut res = <Self as Allocator<N, RTo, Dynamic>>::allocate_uninitialized(rto, cto); let mut res = <Self as Allocator<N, RTo, Dynamic>>::allocate_uninitialized(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -239,8 +233,7 @@ impl<N: Scalar, CFrom: Dim, CTo: Dim> Reallocator<N, Dynamic, CFrom, Dynamic, CT
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: VecStorage<N, Dynamic, CFrom>, buf: VecStorage<N, Dynamic, CFrom>,
) -> VecStorage<N, Dynamic, CTo> ) -> VecStorage<N, Dynamic, CTo> {
{
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
@ -255,8 +248,7 @@ impl<N: Scalar, CFrom: Dim, RTo: DimName> Reallocator<N, Dynamic, CFrom, RTo, Dy
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: VecStorage<N, Dynamic, CFrom>, buf: VecStorage<N, Dynamic, CFrom>,
) -> VecStorage<N, RTo, Dynamic> ) -> VecStorage<N, RTo, Dynamic> {
{
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
@ -271,8 +263,7 @@ impl<N: Scalar, RFrom: DimName, CTo: Dim> Reallocator<N, RFrom, Dynamic, Dynamic
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: VecStorage<N, RFrom, Dynamic>, buf: VecStorage<N, RFrom, Dynamic>,
) -> VecStorage<N, Dynamic, CTo> ) -> VecStorage<N, Dynamic, CTo> {
{
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
@ -287,8 +278,7 @@ impl<N: Scalar, RFrom: DimName, RTo: DimName> Reallocator<N, RFrom, Dynamic, RTo
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: VecStorage<N, RFrom, Dynamic>, buf: VecStorage<N, RFrom, Dynamic>,
) -> VecStorage<N, RTo, Dynamic> ) -> VecStorage<N, RTo, Dynamic> {
{
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }

View File

@ -30,7 +30,9 @@ impl Dynamic {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl Serialize for Dynamic { impl Serialize for Dynamic {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.value.serialize(serializer) self.value.serialize(serializer)
} }
} }
@ -38,7 +40,9 @@ impl Serialize for Dynamic {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'de> Deserialize<'de> for Dynamic { impl<'de> Deserialize<'de> for Dynamic {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> { where
D: Deserializer<'de>,
{
usize::deserialize(deserializer).map(|x| Dynamic { value: x }) usize::deserialize(deserializer).map(|x| Dynamic { value: x })
} }
} }

View File

@ -22,7 +22,9 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Extracts the upper triangular part of this matrix (including the diagonal). /// Extracts the upper triangular part of this matrix (including the diagonal).
#[inline] #[inline]
pub fn upper_triangle(&self) -> MatrixMN<N, R, C> pub fn upper_triangle(&self) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_lower_triangle(N::zero(), 1); res.fill_lower_triangle(N::zero(), 1);
@ -32,7 +34,9 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Extracts the lower triangular part of this matrix (including the diagonal). /// Extracts the lower triangular part of this matrix (including the diagonal).
#[inline] #[inline]
pub fn lower_triangle(&self) -> MatrixMN<N, R, C> pub fn lower_triangle(&self) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_upper_triangle(N::zero(), 1); res.fill_upper_triangle(N::zero(), 1);
@ -64,7 +68,10 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
let src = self.column(j); let src = self.column(j);
for (destination, source) in irows.clone().enumerate() { for (destination, source) in irows.clone().enumerate() {
unsafe { *res.vget_unchecked_mut(destination) = src.vget_unchecked(*source).inlined_clone() } unsafe {
*res.vget_unchecked_mut(destination) =
src.vget_unchecked(*source).inlined_clone()
}
} }
} }
@ -104,7 +111,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// Fills `self` with the identity matrix. /// Fills `self` with the identity matrix.
#[inline] #[inline]
pub fn fill_with_identity(&mut self) pub fn fill_with_identity(&mut self)
where N: Zero + One { where
N: Zero + One,
{
self.fill(N::zero()); self.fill(N::zero());
self.fill_diagonal(N::one()); self.fill_diagonal(N::one());
} }
@ -350,7 +359,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
where where
R: DimSub<Dynamic, Output = Dynamic>, R: DimSub<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>, DefaultAllocator: Reallocator<N, R, C, Dynamic, C>,
{ {
let mut m = self.into_owned(); let mut m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let mut offset: usize = 0; let mut offset: usize = 0;
@ -371,7 +380,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
unsafe { unsafe {
Matrix::from_data(DefaultAllocator::reallocate_copy( Matrix::from_data(DefaultAllocator::reallocate_copy(
nrows.sub(Dynamic::from_usize(offset / ncols.value ())), nrows.sub(Dynamic::from_usize(offset / ncols.value())),
ncols, ncols,
m.data, m.data,
)) ))
@ -693,7 +702,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize(self, new_nrows: usize, new_ncols: usize, val: N) -> DMatrix<N> pub fn resize(self, new_nrows: usize, new_ncols: usize, val: N) -> DMatrix<N>
where DefaultAllocator: Reallocator<N, R, C, Dynamic, Dynamic> { where
DefaultAllocator: Reallocator<N, R, C, Dynamic, Dynamic>,
{
self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val) self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val)
} }
@ -703,7 +714,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// rows than `self`, then the extra rows are filled with `val`. /// rows than `self`, then the extra rows are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically(self, new_nrows: usize, val: N) -> MatrixMN<N, Dynamic, C> pub fn resize_vertically(self, new_nrows: usize, val: N) -> MatrixMN<N, Dynamic, C>
where DefaultAllocator: Reallocator<N, R, C, Dynamic, C> { where
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>,
{
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
self.resize_generic(Dynamic::new(new_nrows), ncols, val) self.resize_generic(Dynamic::new(new_nrows), ncols, val)
} }
@ -714,7 +727,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// columns than `self`, then the extra columns are filled with `val`. /// columns than `self`, then the extra columns are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally(self, new_ncols: usize, val: N) -> MatrixMN<N, R, Dynamic> pub fn resize_horizontally(self, new_ncols: usize, val: N) -> MatrixMN<N, R, Dynamic>
where DefaultAllocator: Reallocator<N, R, C, R, Dynamic> { where
DefaultAllocator: Reallocator<N, R, C, R, Dynamic>,
{
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
self.resize_generic(nrows, Dynamic::new(new_ncols), val) self.resize_generic(nrows, Dynamic::new(new_ncols), val)
} }
@ -724,7 +739,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
pub fn fixed_resize<R2: DimName, C2: DimName>(self, val: N) -> MatrixMN<N, R2, C2> pub fn fixed_resize<R2: DimName, C2: DimName>(self, val: N) -> MatrixMN<N, R2, C2>
where DefaultAllocator: Reallocator<N, R, C, R2, C2> { where
DefaultAllocator: Reallocator<N, R, C, R2, C2>,
{
self.resize_generic(R2::name(), C2::name(), val) self.resize_generic(R2::name(), C2::name(), val)
} }
@ -805,7 +822,9 @@ impl<N: Scalar> DMatrix<N> {
/// ///
/// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`. /// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`.
pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: N) pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: N)
where DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic> { where
DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic>,
{
let placeholder = unsafe { Self::new_uninitialized(0, 0) }; let placeholder = unsafe { Self::new_uninitialized(0, 0) };
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
let new = old.resize(new_nrows, new_ncols, val); let new = old.resize(new_nrows, new_ncols, val);
@ -815,7 +834,8 @@ impl<N: Scalar> DMatrix<N> {
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, C: Dim> MatrixMN<N, Dynamic, C> impl<N: Scalar, C: Dim> MatrixMN<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C> where
DefaultAllocator: Allocator<N, Dynamic, C>,
{ {
/// Changes the number of rows of this matrix in-place. /// Changes the number of rows of this matrix in-place.
/// ///
@ -825,7 +845,9 @@ where DefaultAllocator: Allocator<N, Dynamic, C>
/// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`). /// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: N) pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: N)
where DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C> { where
DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C>,
{
let placeholder = let placeholder =
unsafe { Self::new_uninitialized_generic(Dynamic::new(0), self.data.shape().1) }; unsafe { Self::new_uninitialized_generic(Dynamic::new(0), self.data.shape().1) };
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
@ -836,7 +858,8 @@ where DefaultAllocator: Allocator<N, Dynamic, C>
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, R: Dim> MatrixMN<N, R, Dynamic> impl<N: Scalar, R: Dim> MatrixMN<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic> where
DefaultAllocator: Allocator<N, R, Dynamic>,
{ {
/// Changes the number of column of this matrix in-place. /// Changes the number of column of this matrix in-place.
/// ///
@ -846,7 +869,9 @@ where DefaultAllocator: Allocator<N, R, Dynamic>
/// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`). /// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: N) pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: N)
where DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic> { where
DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic>,
{
let placeholder = let placeholder =
unsafe { Self::new_uninitialized_generic(self.data.shape().0, Dynamic::new(0)) }; unsafe { Self::new_uninitialized_generic(self.data.shape().0, Dynamic::new(0)) };
let old = mem::replace(self, placeholder); let old = mem::replace(self, placeholder);
@ -861,8 +886,7 @@ unsafe fn compress_rows<N: Scalar>(
ncols: usize, ncols: usize,
i: usize, i: usize,
nremove: usize, nremove: usize,
) ) {
{
let new_nrows = nrows - nremove; let new_nrows = nrows - nremove;
if new_nrows == 0 || ncols == 0 { if new_nrows == 0 || ncols == 0 {
@ -901,8 +925,7 @@ unsafe fn extend_rows<N: Scalar>(
ncols: usize, ncols: usize,
i: usize, i: usize,
ninsert: usize, ninsert: usize,
) ) {
{
let new_nrows = nrows + ninsert; let new_nrows = nrows + ninsert;
if new_nrows == 0 || ncols == 0 { if new_nrows == 0 || ncols == 0 {

View File

@ -18,7 +18,9 @@ pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
pub fn reject_rand<G: Rng + ?Sized, F: FnMut(&T) -> bool, T>(g: &mut G, f: F) -> T pub fn reject_rand<G: Rng + ?Sized, F: FnMut(&T) -> bool, T>(g: &mut G, f: F) -> T
where Standard: Distribution<T> { where
Standard: Distribution<T>,
{
use std::iter; use std::iter;
iter::repeat(()).map(|_| g.gen()).find(f).unwrap() iter::repeat(()).map(|_| g.gen()).find(f).unwrap()
} }

View File

@ -1,13 +1,14 @@
//! Indexing //! Indexing
use crate::base::{Dim, DimName, DimDiff, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{
Dim, DimDiff, DimName, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1,
};
use std::ops; use std::ops;
// N.B.: Not a public trait! // N.B.: Not a public trait!
trait DimRange<D: Dim> trait DimRange<D: Dim> {
{
/// The number of elements indexed by this range. /// The number of elements indexed by this range.
type Length: Dim; type Length: Dim;
@ -68,15 +69,27 @@ impl<D: Dim> DimRange<D> for ops::Range<usize> {
#[test] #[test]
fn dimrange_range_usize() { fn dimrange_range_usize() {
use std::usize::MAX;
use crate::base::dimension::U0; use crate::base::dimension::U0;
use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..0), U0), false); assert_eq!(DimRange::contained_by(&(0..0), U0), false);
assert_eq!(DimRange::contained_by(&(0..1), U0), false); assert_eq!(DimRange::contained_by(&(0..1), U0), false);
assert_eq!(DimRange::contained_by(&(0..1), U1), true); assert_eq!(DimRange::contained_by(&(0..1), U1), true);
assert_eq!(DimRange::contained_by(&((MAX - 1)..MAX), Dynamic::new(MAX)), true); assert_eq!(
assert_eq!(DimRange::length(&((MAX - 1)..MAX), Dynamic::new(MAX)), Dynamic::new(1)); DimRange::contained_by(&((MAX - 1)..MAX), Dynamic::new(MAX)),
assert_eq!(DimRange::length(&(MAX..(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(0)); true
assert_eq!(DimRange::length(&(MAX..MAX), Dynamic::new(MAX)), Dynamic::new(0)); );
assert_eq!(
DimRange::length(&((MAX - 1)..MAX), Dynamic::new(MAX)),
Dynamic::new(1)
);
assert_eq!(
DimRange::length(&(MAX..(MAX - 1)), Dynamic::new(MAX)),
Dynamic::new(0)
);
assert_eq!(
DimRange::length(&(MAX..MAX), Dynamic::new(MAX)),
Dynamic::new(0)
);
} }
impl<D: Dim> DimRange<D> for ops::RangeFrom<usize> { impl<D: Dim> DimRange<D> for ops::RangeFrom<usize> {
@ -100,18 +113,28 @@ impl<D: Dim> DimRange<D> for ops::RangeFrom<usize> {
#[test] #[test]
fn dimrange_rangefrom_usize() { fn dimrange_rangefrom_usize() {
use std::usize::MAX;
use crate::base::dimension::U0; use crate::base::dimension::U0;
use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..), U0), false); assert_eq!(DimRange::contained_by(&(0..), U0), false);
assert_eq!(DimRange::contained_by(&(0..), U0), false); assert_eq!(DimRange::contained_by(&(0..), U0), false);
assert_eq!(DimRange::contained_by(&(0..), U1), true); assert_eq!(DimRange::contained_by(&(0..), U1), true);
assert_eq!(DimRange::contained_by(&((MAX - 1)..), Dynamic::new(MAX)), true); assert_eq!(
assert_eq!(DimRange::length(&((MAX - 1)..), Dynamic::new(MAX)), Dynamic::new(1)); DimRange::contained_by(&((MAX - 1)..), Dynamic::new(MAX)),
assert_eq!(DimRange::length(&(MAX..), Dynamic::new(MAX)), Dynamic::new(0)); true
);
assert_eq!(
DimRange::length(&((MAX - 1)..), Dynamic::new(MAX)),
Dynamic::new(1)
);
assert_eq!(
DimRange::length(&(MAX..), Dynamic::new(MAX)),
Dynamic::new(0)
);
} }
impl<D: Dim, T: Dim> DimRange<D> for ops::RangeFrom<T> impl<D: Dim, T: Dim> DimRange<D> for ops::RangeFrom<T>
where D: DimSub<T> where
D: DimSub<T>,
{ {
type Length = DimDiff<D, T>; type Length = DimDiff<D, T>;
@ -133,7 +156,7 @@ where D: DimSub<T>
#[test] #[test]
fn dimrange_rangefrom_dimname() { fn dimrange_rangefrom_dimname() {
use crate::base::dimension::{U5, U4}; use crate::base::dimension::{U4, U5};
assert_eq!(DimRange::length(&(U1..), U5), U4); assert_eq!(DimRange::length(&(U1..), U5), U4);
} }
@ -173,12 +196,11 @@ impl<D: Dim> DimRange<D> for ops::RangeInclusive<usize> {
#[inline(always)] #[inline(always)]
fn length(&self, _: D) -> Self::Length { fn length(&self, _: D) -> Self::Length {
Dynamic::new( Dynamic::new(if self.end() < self.start() {
if self.end() < self.start() { 0
0 } else {
} else { self.end().wrapping_sub(self.start().wrapping_sub(1))
self.end().wrapping_sub(self.start().wrapping_sub(1)) })
})
} }
#[inline(always)] #[inline(always)]
@ -189,21 +211,38 @@ impl<D: Dim> DimRange<D> for ops::RangeInclusive<usize> {
#[test] #[test]
fn dimrange_rangeinclusive_usize() { fn dimrange_rangeinclusive_usize() {
use std::usize::MAX;
use crate::base::dimension::U0; use crate::base::dimension::U0;
use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(0..=0), U0), false); assert_eq!(DimRange::contained_by(&(0..=0), U0), false);
assert_eq!(DimRange::contained_by(&(0..=0), U1), true); assert_eq!(DimRange::contained_by(&(0..=0), U1), true);
assert_eq!(DimRange::contained_by(&(MAX..=MAX), Dynamic::new(MAX)), false); assert_eq!(
assert_eq!(DimRange::contained_by(&((MAX-1)..=MAX), Dynamic::new(MAX)), false); DimRange::contained_by(&(MAX..=MAX), Dynamic::new(MAX)),
assert_eq!(DimRange::contained_by(&((MAX-1)..=(MAX-1)), Dynamic::new(MAX)), true); false
);
assert_eq!(
DimRange::contained_by(&((MAX - 1)..=MAX), Dynamic::new(MAX)),
false
);
assert_eq!(
DimRange::contained_by(&((MAX - 1)..=(MAX - 1)), Dynamic::new(MAX)),
true
);
assert_eq!(DimRange::length(&(0..=0), U1), Dynamic::new(1)); assert_eq!(DimRange::length(&(0..=0), U1), Dynamic::new(1));
assert_eq!(DimRange::length(&((MAX - 1)..=MAX), Dynamic::new(MAX)), Dynamic::new(2)); assert_eq!(
assert_eq!(DimRange::length(&(MAX..=(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(0)); DimRange::length(&((MAX - 1)..=MAX), Dynamic::new(MAX)),
assert_eq!(DimRange::length(&(MAX..=MAX), Dynamic::new(MAX)), Dynamic::new(1)); Dynamic::new(2)
);
assert_eq!(
DimRange::length(&(MAX..=(MAX - 1)), Dynamic::new(MAX)),
Dynamic::new(0)
);
assert_eq!(
DimRange::length(&(MAX..=MAX), Dynamic::new(MAX)),
Dynamic::new(1)
);
} }
impl<D: Dim> DimRange<D> for ops::RangeTo<usize> impl<D: Dim> DimRange<D> for ops::RangeTo<usize> {
{
type Length = Dynamic; type Length = Dynamic;
#[inline(always)] #[inline(always)]
@ -224,18 +263,26 @@ impl<D: Dim> DimRange<D> for ops::RangeTo<usize>
#[test] #[test]
fn dimrange_rangeto_usize() { fn dimrange_rangeto_usize() {
use std::usize::MAX;
use crate::base::dimension::U0; use crate::base::dimension::U0;
use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(..0), U0), true); assert_eq!(DimRange::contained_by(&(..0), U0), true);
assert_eq!(DimRange::contained_by(&(..1), U0), false); assert_eq!(DimRange::contained_by(&(..1), U0), false);
assert_eq!(DimRange::contained_by(&(..0), U1), true); assert_eq!(DimRange::contained_by(&(..0), U1), true);
assert_eq!(DimRange::contained_by(&(..(MAX - 1)), Dynamic::new(MAX)), true); assert_eq!(
assert_eq!(DimRange::length(&(..(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(MAX - 1)); DimRange::contained_by(&(..(MAX - 1)), Dynamic::new(MAX)),
assert_eq!(DimRange::length(&(..MAX), Dynamic::new(MAX)), Dynamic::new(MAX)); true
);
assert_eq!(
DimRange::length(&(..(MAX - 1)), Dynamic::new(MAX)),
Dynamic::new(MAX - 1)
);
assert_eq!(
DimRange::length(&(..MAX), Dynamic::new(MAX)),
Dynamic::new(MAX)
);
} }
impl<D: Dim> DimRange<D> for ops::RangeToInclusive<usize> impl<D: Dim> DimRange<D> for ops::RangeToInclusive<usize> {
{
type Length = Dynamic; type Length = Dynamic;
#[inline(always)] #[inline(always)]
@ -256,21 +303,29 @@ impl<D: Dim> DimRange<D> for ops::RangeToInclusive<usize>
#[test] #[test]
fn dimrange_rangetoinclusive_usize() { fn dimrange_rangetoinclusive_usize() {
use std::usize::MAX;
use crate::base::dimension::U0; use crate::base::dimension::U0;
use std::usize::MAX;
assert_eq!(DimRange::contained_by(&(..=0), U0), false); assert_eq!(DimRange::contained_by(&(..=0), U0), false);
assert_eq!(DimRange::contained_by(&(..=1), U0), false); assert_eq!(DimRange::contained_by(&(..=1), U0), false);
assert_eq!(DimRange::contained_by(&(..=0), U1), true); assert_eq!(DimRange::contained_by(&(..=0), U1), true);
assert_eq!(DimRange::contained_by(&(..=(MAX)), Dynamic::new(MAX)), false); assert_eq!(
assert_eq!(DimRange::contained_by(&(..=(MAX - 1)), Dynamic::new(MAX)), true); DimRange::contained_by(&(..=(MAX)), Dynamic::new(MAX)),
assert_eq!(DimRange::length(&(..=(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(MAX)); false
);
assert_eq!(
DimRange::contained_by(&(..=(MAX - 1)), Dynamic::new(MAX)),
true
);
assert_eq!(
DimRange::length(&(..=(MAX - 1)), Dynamic::new(MAX)),
Dynamic::new(MAX)
);
} }
/// A helper trait used for indexing operations. /// A helper trait used for indexing operations.
pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized { pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized {
/// The output type returned by methods. /// The output type returned by methods.
type Output : 'a; type Output: 'a;
/// Produces true if the given matrix is contained by this index. /// Produces true if the given matrix is contained by this index.
#[doc(hidden)] #[doc(hidden)]
@ -282,7 +337,7 @@ pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized
#[inline(always)] #[inline(always)]
fn get(self, matrix: &'a Matrix<N, R, C, S>) -> Option<Self::Output> { fn get(self, matrix: &'a Matrix<N, R, C, S>) -> Option<Self::Output> {
if self.contained_by(matrix) { if self.contained_by(matrix) {
Some(unsafe{self.get_unchecked(matrix)}) Some(unsafe { self.get_unchecked(matrix) })
} else { } else {
None None
} }
@ -303,9 +358,11 @@ pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized
} }
/// A helper trait used for indexing operations. /// A helper trait used for indexing operations.
pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>: MatrixIndex<'a, N, R, C, S> { pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
MatrixIndex<'a, N, R, C, S>
{
/// The output type returned by methods. /// The output type returned by methods.
type OutputMut : 'a; type OutputMut: 'a;
/// Produces a mutable view of the data at this location, without /// Produces a mutable view of the data at this location, without
/// performing any bounds checking. /// performing any bounds checking.
@ -318,7 +375,7 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
#[inline(always)] #[inline(always)]
fn get_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Option<Self::OutputMut> { fn get_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Option<Self::OutputMut> {
if self.contained_by(matrix) { if self.contained_by(matrix) {
Some(unsafe{self.get_unchecked_mut(matrix)}) Some(unsafe { self.get_unchecked_mut(matrix) })
} else { } else {
None None
} }
@ -432,14 +489,13 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// 4, 7, /// 4, 7,
/// 5, 8))); /// 5, 8)));
/// ``` /// ```
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
{
/// Produces a view of the data at the given index, or /// Produces a view of the data at the given index, or
/// `None` if the index is out of bounds. /// `None` if the index is out of bounds.
#[inline] #[inline]
pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output> pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output>
where where
I: MatrixIndex<'a, N, R, C, S> I: MatrixIndex<'a, N, R, C, S>,
{ {
index.get(self) index.get(self)
} }
@ -450,7 +506,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut> pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut>
where where
S: StorageMut<N, R, C>, S: StorageMut<N, R, C>,
I: MatrixIndexMut<'a, N, R, C, S> I: MatrixIndexMut<'a, N, R, C, S>,
{ {
index.get_mut(self) index.get_mut(self)
} }
@ -460,7 +516,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
#[inline] #[inline]
pub fn index<'a, I>(&'a self, index: I) -> I::Output pub fn index<'a, I>(&'a self, index: I) -> I::Output
where where
I: MatrixIndex<'a, N, R, C, S> I: MatrixIndex<'a, N, R, C, S>,
{ {
index.index(self) index.index(self)
} }
@ -471,7 +527,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
pub fn index_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut pub fn index_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<N, R, C>,
I: MatrixIndexMut<'a, N, R, C, S> I: MatrixIndexMut<'a, N, R, C, S>,
{ {
index.index_mut(self) index.index_mut(self)
} }
@ -481,7 +537,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
#[inline] #[inline]
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
where where
I: MatrixIndex<'a, N, R, C, S> I: MatrixIndex<'a, N, R, C, S>,
{ {
index.get_unchecked(self) index.get_unchecked(self)
} }
@ -492,7 +548,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<N, R, C>,
I: MatrixIndexMut<'a, N, R, C, S> I: MatrixIndexMut<'a, N, R, C, S>,
{ {
index.get_unchecked_mut(self) index.get_unchecked_mut(self)
} }
@ -505,7 +561,7 @@ where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C> S: Storage<N, R, C>,
{ {
type Output = &'a N; type Output = &'a N;
@ -527,14 +583,15 @@ where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: StorageMut<N, R, C> S: StorageMut<N, R, C>,
{ {
type OutputMut = &'a mut N; type OutputMut = &'a mut N;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut
where S: StorageMut<N, R, C>, where
S: StorageMut<N, R, C>,
{ {
matrix.data.get_unchecked_linear_mut(self) matrix.data.get_unchecked_linear_mut(self)
} }
@ -547,7 +604,7 @@ where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C> S: Storage<N, R, C>,
{ {
type Output = &'a N; type Output = &'a N;
@ -572,14 +629,15 @@ where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: StorageMut<N, R, C> S: StorageMut<N, R, C>,
{ {
type OutputMut = &'a mut N; type OutputMut = &'a mut N;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut
where S: StorageMut<N, R, C>, where
S: StorageMut<N, R, C>,
{ {
let (row, col) = self; let (row, col) = self;
matrix.data.get_unchecked_mut(row, col) matrix.data.get_unchecked_mut(row, col)
@ -684,7 +742,7 @@ macro_rules! impl_index_pairs {
} }
} }
impl_index_pairs!{ impl_index_pairs! {
index R with { index R with {
[<> usize => U1], [<> usize => U1],
[<> ops::Range<usize> => Dynamic], [<> ops::Range<usize> => Dynamic],

View File

@ -5,7 +5,7 @@ use std::mem;
use crate::base::dimension::{Dim, U1}; use crate::base::dimension::{Dim, U1};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{Scalar, Matrix, MatrixSlice, MatrixSliceMut}; use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar};
macro_rules! iterator { macro_rules! iterator {
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
@ -125,7 +125,6 @@ macro_rules! iterator {
iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S); iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S);
iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a mut S); iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a mut S);
/* /*
* *
* Row iterators. * Row iterators.
@ -135,18 +134,15 @@ iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a
/// An iterator through the rows of a matrix. /// An iterator through the rows of a matrix.
pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> { pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
mat: &'a Matrix<N, R, C, S>, mat: &'a Matrix<N, R, C, S>,
curr: usize curr: usize,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> {
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
RowIter { RowIter { mat, curr: 0 }
mat, curr: 0
}
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIter<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIter<'a, N, R, C, S> {
type Item = MatrixSlice<'a, N, U1, C, S::RStride, S::CStride>; type Item = MatrixSlice<'a, N, U1, C, S::RStride, S::CStride>;
@ -163,7 +159,10 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIt
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
(self.mat.nrows() - self.curr, Some(self.mat.nrows() - self.curr)) (
self.mat.nrows() - self.curr,
Some(self.mat.nrows() - self.curr),
)
} }
#[inline] #[inline]
@ -172,19 +171,20 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIt
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for RowIter<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
for RowIter<'a, N, R, C, S>
{
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
self.mat.nrows() - self.curr self.mat.nrows() - self.curr
} }
} }
/// An iterator through the mutable rows of a matrix. /// An iterator through the mutable rows of a matrix.
pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> { pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
mat: *mut Matrix<N, R, C, S>, mat: *mut Matrix<N, R, C, S>,
curr: usize, curr: usize,
phantom: PhantomData<&'a mut Matrix<N, R, C, S>> phantom: PhantomData<&'a mut Matrix<N, R, C, S>>,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> {
@ -192,19 +192,18 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a,
RowIterMut { RowIterMut {
mat, mat,
curr: 0, curr: 0,
phantom: PhantomData phantom: PhantomData,
} }
} }
fn nrows(&self) -> usize { fn nrows(&self) -> usize {
unsafe { unsafe { (*self.mat).nrows() }
(*self.mat).nrows()
}
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for RowIterMut<'a, N, R, C, S> { for RowIterMut<'a, N, R, C, S>
{
type Item = MatrixSliceMut<'a, N, U1, C, S::RStride, S::CStride>; type Item = MatrixSliceMut<'a, N, U1, C, S::RStride, S::CStride>;
#[inline] #[inline]
@ -229,14 +228,15 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for Ro
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for RowIterMut<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator
for RowIterMut<'a, N, R, C, S>
{
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
self.nrows() - self.curr self.nrows() - self.curr
} }
} }
/* /*
* *
* Column iterators. * Column iterators.
@ -246,19 +246,18 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
/// An iterator through the columns of a matrix. /// An iterator through the columns of a matrix.
pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> { pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> {
mat: &'a Matrix<N, R, C, S>, mat: &'a Matrix<N, R, C, S>,
curr: usize curr: usize,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> {
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self {
ColumnIter { ColumnIter { mat, curr: 0 }
mat, curr: 0
}
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for ColumnIter<'a, N, R, C, S> { for ColumnIter<'a, N, R, C, S>
{
type Item = MatrixSlice<'a, N, R, U1, S::RStride, S::CStride>; type Item = MatrixSlice<'a, N, R, U1, S::RStride, S::CStride>;
#[inline] #[inline]
@ -274,7 +273,10 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for Colum
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
(self.mat.ncols() - self.curr, Some(self.mat.ncols() - self.curr)) (
self.mat.ncols() - self.curr,
Some(self.mat.ncols() - self.curr),
)
} }
#[inline] #[inline]
@ -283,19 +285,20 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for Colum
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator for ColumnIter<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
for ColumnIter<'a, N, R, C, S>
{
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
self.mat.ncols() - self.curr self.mat.ncols() - self.curr
} }
} }
/// An iterator through the mutable columns of a matrix. /// An iterator through the mutable columns of a matrix.
pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> { pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> {
mat: *mut Matrix<N, R, C, S>, mat: *mut Matrix<N, R, C, S>,
curr: usize, curr: usize,
phantom: PhantomData<&'a mut Matrix<N, R, C, S>> phantom: PhantomData<&'a mut Matrix<N, R, C, S>>,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> {
@ -303,19 +306,18 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'
ColumnIterMut { ColumnIterMut {
mat, mat,
curr: 0, curr: 0,
phantom: PhantomData phantom: PhantomData,
} }
} }
fn ncols(&self) -> usize { fn ncols(&self) -> usize {
unsafe { unsafe { (*self.mat).ncols() }
(*self.mat).ncols()
}
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for ColumnIterMut<'a, N, R, C, S> { for ColumnIterMut<'a, N, R, C, S>
{
type Item = MatrixSliceMut<'a, N, R, U1, S::RStride, S::CStride>; type Item = MatrixSliceMut<'a, N, R, U1, S::RStride, S::CStride>;
#[inline] #[inline]
@ -340,10 +342,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator for Co
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator for ColumnIterMut<'a, N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator
for ColumnIterMut<'a, N, R, C, S>
{
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
self.ncols() - self.curr self.ncols() - self.curr
} }
} }

View File

@ -103,7 +103,9 @@ where
S: Serialize, S: Serialize,
{ {
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error> fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
where T: Serializer { where
T: Serializer,
{
self.data.serialize(serializer) self.data.serialize(serializer)
} }
} }
@ -117,7 +119,9 @@ where
S: Deserialize<'de>, S: Deserialize<'de>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de> { where
D: Deserializer<'de>,
{
S::deserialize(deserializer).map(|x| Matrix { S::deserialize(deserializer).map(|x| Matrix {
data: x, data: x,
_phantoms: PhantomData, _phantoms: PhantomData,
@ -348,7 +352,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Moves this matrix into one that owns its data. /// Moves this matrix into one that owns its data.
#[inline] #[inline]
pub fn into_owned(self) -> MatrixMN<N, R, C> pub fn into_owned(self) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
Matrix::from_data(self.data.into_owned()) Matrix::from_data(self.data.into_owned())
} }
@ -382,7 +388,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Clones this matrix to one that owns its data. /// Clones this matrix to one that owns its data.
#[inline] #[inline]
pub fn clone_owned(&self) -> MatrixMN<N, R, C> pub fn clone_owned(&self) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
Matrix::from_data(self.data.clone_owned()) Matrix::from_data(self.data.clone_owned())
} }
@ -418,7 +426,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Returns a matrix containing the result of `f` applied to each of its entries. /// Returns a matrix containing the result of `f` applied to each of its entries.
#[inline] #[inline]
pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, mut f: F) -> MatrixMN<N2, R, C> pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, mut f: F) -> MatrixMN<N2, R, C>
where DefaultAllocator: Allocator<N2, R, C> { where
DefaultAllocator: Allocator<N2, R, C>,
{
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) }; let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) };
@ -447,8 +457,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
&self, &self,
init_f: impl FnOnce(Option<&N>) -> N2, init_f: impl FnOnce(Option<&N>) -> N2,
f: impl FnMut(N2, &N) -> N2, f: impl FnMut(N2, &N) -> N2,
) -> N2 ) -> N2 {
{
let mut it = self.iter(); let mut it = self.iter();
let init = init_f(it.next()); let init = init_f(it.next());
it.fold(init, f) it.fold(init, f)
@ -640,7 +649,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
#[must_use = "Did you mean to use transpose_mut()?"] #[must_use = "Did you mean to use transpose_mut()?"]
pub fn transpose(&self) -> MatrixMN<N, C, R> pub fn transpose(&self) -> MatrixMN<N, C, R>
where DefaultAllocator: Allocator<N, C, R> { where
DefaultAllocator: Allocator<N, C, R>,
{
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
unsafe { unsafe {
@ -983,7 +994,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
#[inline] #[inline]
#[must_use = "Did you mean to use adjoint_mut()?"] #[must_use = "Did you mean to use adjoint_mut()?"]
pub fn adjoint(&self) -> MatrixMN<N, C, R> pub fn adjoint(&self) -> MatrixMN<N, C, R>
where DefaultAllocator: Allocator<N, C, R> { where
DefaultAllocator: Allocator<N, C, R>,
{
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
unsafe { unsafe {
@ -1011,7 +1024,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
#[deprecated(note = "Renamed `self.adjoint()`.")] #[deprecated(note = "Renamed `self.adjoint()`.")]
#[inline] #[inline]
pub fn conjugate_transpose(&self) -> MatrixMN<N, C, R> pub fn conjugate_transpose(&self) -> MatrixMN<N, C, R>
where DefaultAllocator: Allocator<N, C, R> { where
DefaultAllocator: Allocator<N, C, R>,
{
self.adjoint() self.adjoint()
} }
@ -1019,7 +1034,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
#[inline] #[inline]
#[must_use = "Did you mean to use conjugate_mut()?"] #[must_use = "Did you mean to use conjugate_mut()?"]
pub fn conjugate(&self) -> MatrixMN<N, R, C> pub fn conjugate(&self) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
self.map(|e| e.simd_conjugate()) self.map(|e| e.simd_conjugate())
} }
@ -1027,7 +1044,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
#[inline] #[inline]
#[must_use = "Did you mean to use unscale_mut()?"] #[must_use = "Did you mean to use unscale_mut()?"]
pub fn unscale(&self, real: N::SimdRealField) -> MatrixMN<N, R, C> pub fn unscale(&self, real: N::SimdRealField) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
self.map(|e| e.simd_unscale(real)) self.map(|e| e.simd_unscale(real))
} }
@ -1035,7 +1054,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
#[inline] #[inline]
#[must_use = "Did you mean to use scale_mut()?"] #[must_use = "Did you mean to use scale_mut()?"]
pub fn scale(&self, real: N::SimdRealField) -> MatrixMN<N, R, C> pub fn scale(&self, real: N::SimdRealField) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
self.map(|e| e.simd_scale(real)) self.map(|e| e.simd_scale(real))
} }
} }
@ -1100,7 +1121,9 @@ impl<N: Scalar, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
/// The diagonal of this matrix. /// The diagonal of this matrix.
#[inline] #[inline]
pub fn diagonal(&self) -> VectorN<N, D> pub fn diagonal(&self) -> VectorN<N, D>
where DefaultAllocator: Allocator<N, D> { where
DefaultAllocator: Allocator<N, D>,
{
self.map_diagonal(|e| e) self.map_diagonal(|e| e)
} }
@ -1109,7 +1132,9 @@ impl<N: Scalar, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
/// This is a more efficient version of `self.diagonal().map(f)` since this /// This is a more efficient version of `self.diagonal().map(f)` since this
/// allocates only once. /// allocates only once.
pub fn map_diagonal<N2: Scalar>(&self, mut f: impl FnMut(N) -> N2) -> VectorN<N2, D> pub fn map_diagonal<N2: Scalar>(&self, mut f: impl FnMut(N) -> N2) -> VectorN<N2, D>
where DefaultAllocator: Allocator<N2, D> { where
DefaultAllocator: Allocator<N2, D>,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Unable to get the diagonal of a non-square matrix." "Unable to get the diagonal of a non-square matrix."
@ -1130,7 +1155,9 @@ impl<N: Scalar, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
/// Computes a trace of a square matrix, i.e., the sum of its diagonal elements. /// Computes a trace of a square matrix, i.e., the sum of its diagonal elements.
#[inline] #[inline]
pub fn trace(&self) -> N pub fn trace(&self) -> N
where N: Scalar + Zero + ClosedAdd { where
N: Scalar + Zero + ClosedAdd,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Cannot compute the trace of non-square matrix." "Cannot compute the trace of non-square matrix."
@ -1151,7 +1178,9 @@ impl<N: SimdComplexField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
/// The symmetric part of `self`, i.e., `0.5 * (self + self.transpose())`. /// The symmetric part of `self`, i.e., `0.5 * (self + self.transpose())`.
#[inline] #[inline]
pub fn symmetric_part(&self) -> MatrixMN<N, D, D> pub fn symmetric_part(&self) -> MatrixMN<N, D, D>
where DefaultAllocator: Allocator<N, D, D> { where
DefaultAllocator: Allocator<N, D, D>,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Cannot compute the symmetric part of a non-square matrix." "Cannot compute the symmetric part of a non-square matrix."
@ -1165,7 +1194,9 @@ impl<N: SimdComplexField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
/// The hermitian part of `self`, i.e., `0.5 * (self + self.adjoint())`. /// The hermitian part of `self`, i.e., `0.5 * (self + self.adjoint())`.
#[inline] #[inline]
pub fn hermitian_part(&self) -> MatrixMN<N, D, D> pub fn hermitian_part(&self) -> MatrixMN<N, D, D>
where DefaultAllocator: Allocator<N, D, D> { where
DefaultAllocator: Allocator<N, D, D>,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Cannot compute the hermitian part of a non-square matrix." "Cannot compute the hermitian part of a non-square matrix."
@ -1185,7 +1216,9 @@ impl<N: Scalar + Zero + One, D: DimAdd<U1> + IsNotStaticOne, S: Storage<N, D, D>
/// and setting the diagonal element to `1`. /// and setting the diagonal element to `1`.
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimSum<D, U1>>
where DefaultAllocator: Allocator<N, DimSum<D, U1>, DimSum<D, U1>> { where
DefaultAllocator: Allocator<N, DimSum<D, U1>, DimSum<D, U1>>,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Only square matrices can currently be transformed to homogeneous coordinates." "Only square matrices can currently be transformed to homogeneous coordinates."
@ -1203,7 +1236,9 @@ impl<N: Scalar + Zero, D: DimAdd<U1>, S: Storage<N, D>> Vector<N, D, S> {
/// coordinates. /// coordinates.
#[inline] #[inline]
pub fn to_homogeneous(&self) -> VectorN<N, DimSum<D, U1>> pub fn to_homogeneous(&self) -> VectorN<N, DimSum<D, U1>>
where DefaultAllocator: Allocator<N, DimSum<D, U1>> { where
DefaultAllocator: Allocator<N, DimSum<D, U1>>,
{
self.push(N::zero()) self.push(N::zero())
} }
@ -1228,7 +1263,9 @@ impl<N: Scalar + Zero, D: DimAdd<U1>, S: Storage<N, D>> Vector<N, D, S> {
/// Constructs a new vector of higher dimension by appending `element` to the end of `self`. /// Constructs a new vector of higher dimension by appending `element` to the end of `self`.
#[inline] #[inline]
pub fn push(&self, element: N) -> VectorN<N, DimSum<D, U1>> pub fn push(&self, element: N) -> VectorN<N, DimSum<D, U1>>
where DefaultAllocator: Allocator<N, DimSum<D, U1>> { where
DefaultAllocator: Allocator<N, DimSum<D, U1>>,
{
let len = self.len(); let len = self.len();
let hnrows = DimSum::<D, U1>::from_usize(len + 1); let hnrows = DimSum::<D, U1>::from_usize(len + 1);
let mut res = unsafe { VectorN::<N, _>::new_uninitialized_generic(hnrows, U1) }; let mut res = unsafe { VectorN::<N, _>::new_uninitialized_generic(hnrows, U1) };
@ -1278,8 +1315,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.relative_eq(other, epsilon, max_relative) self.relative_eq(other, epsilon, max_relative)
} }
} }
@ -1618,7 +1654,8 @@ impl<N: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: Storage<N
} }
impl<N: Scalar + Field, S: Storage<N, U3>> Vector<N, U3, S> impl<N: Scalar + Field, S: Storage<N, U3>> Vector<N, U3, S>
where DefaultAllocator: Allocator<N, U3> where
DefaultAllocator: Allocator<N, U3>,
{ {
/// Computes the matrix `M` such that for all vector `v` we have `M * v == self.cross(&v)`. /// Computes the matrix `M` such that for all vector `v` we have `M * v == self.cross(&v)`.
#[inline] #[inline]
@ -1675,7 +1712,9 @@ impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
/// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7)); /// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7));
/// ``` /// ```
pub fn lerp<S2: Storage<N, D>>(&self, rhs: &Vector<N, D, S2>, t: N) -> VectorN<N, D> pub fn lerp<S2: Storage<N, D>>(&self, rhs: &Vector<N, D, S2>, t: N) -> VectorN<N, D>
where DefaultAllocator: Allocator<N, D> { where
DefaultAllocator: Allocator<N, D>,
{
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.axpy(t.inlined_clone(), rhs, N::one() - t); res.axpy(t.inlined_clone(), rhs, N::one() - t);
res res
@ -1783,8 +1822,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.as_ref() self.as_ref()
.relative_eq(other.as_ref(), epsilon, max_relative) .relative_eq(other.as_ref(), epsilon, max_relative)
} }

View File

@ -4,9 +4,9 @@ use std::slice;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Dim, DimName, Dynamic, U1, IsNotStaticOne}; use crate::base::dimension::{Dim, DimName, Dynamic, IsNotStaticOne, U1};
use crate::base::iter::MatrixIter; use crate::base::iter::MatrixIter;
use crate::base::storage::{Owned, Storage, StorageMut, ContiguousStorage, ContiguousStorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
use crate::base::{Matrix, Scalar}; use crate::base::{Matrix, Scalar};
macro_rules! slice_storage_impl( macro_rules! slice_storage_impl(
@ -198,13 +198,31 @@ unsafe impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> StorageMu
} }
} }
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1> for SliceStorage<'a, N, R, U1, U1, CStride> { } unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1>
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1> for SliceStorageMut<'a, N, R, U1, U1, CStride> { } for SliceStorage<'a, N, R, U1, U1, CStride>
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorageMut<N, R, U1> for SliceStorageMut<'a, N, R, U1, U1, CStride> { } {
}
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1>
for SliceStorageMut<'a, N, R, U1, U1, CStride>
{
}
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorageMut<N, R, U1>
for SliceStorageMut<'a, N, R, U1, U1, CStride>
{
}
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C> for SliceStorage<'a, N, R, C, U1, R> { } unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C>
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C> for SliceStorageMut<'a, N, R, C, U1, R> { } for SliceStorage<'a, N, R, C, U1, R>
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorageMut<N, R, C> for SliceStorageMut<'a, N, R, C, U1, R> { } {
}
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C>
for SliceStorageMut<'a, N, R, C, U1, R>
{
}
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorageMut<N, R, C>
for SliceStorageMut<'a, N, R, C, U1, R>
{
}
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
@ -213,8 +231,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
start: (usize, usize), start: (usize, usize),
shape: (usize, usize), shape: (usize, usize),
steps: (usize, usize), steps: (usize, usize),
) ) {
{
let my_shape = self.shape(); let my_shape = self.shape();
// NOTE: we don't do any subtraction to avoid underflow for zero-sized matrices. // NOTE: we don't do any subtraction to avoid underflow for zero-sized matrices.
// //
@ -811,8 +828,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
pub fn rows_range<RowRange: SliceRange<R>>( pub fn rows_range<RowRange: SliceRange<R>>(
&self, &self,
rows: RowRange, rows: RowRange,
) -> MatrixSlice<N, RowRange::Size, C, S::RStride, S::CStride> ) -> MatrixSlice<N, RowRange::Size, C, S::RStride, S::CStride> {
{
self.slice_range(rows, ..) self.slice_range(rows, ..)
} }
@ -821,8 +837,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
pub fn columns_range<ColRange: SliceRange<C>>( pub fn columns_range<ColRange: SliceRange<C>>(
&self, &self,
cols: ColRange, cols: ColRange,
) -> MatrixSlice<N, R, ColRange::Size, S::RStride, S::CStride> ) -> MatrixSlice<N, R, ColRange::Size, S::RStride, S::CStride> {
{
self.slice_range(.., cols) self.slice_range(.., cols)
} }
} }
@ -851,8 +866,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
pub fn rows_range_mut<RowRange: SliceRange<R>>( pub fn rows_range_mut<RowRange: SliceRange<R>>(
&mut self, &mut self,
rows: RowRange, rows: RowRange,
) -> MatrixSliceMut<N, RowRange::Size, C, S::RStride, S::CStride> ) -> MatrixSliceMut<N, RowRange::Size, C, S::RStride, S::CStride> {
{
self.slice_range_mut(rows, ..) self.slice_range_mut(rows, ..)
} }
@ -861,30 +875,28 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
pub fn columns_range_mut<ColRange: SliceRange<C>>( pub fn columns_range_mut<ColRange: SliceRange<C>>(
&mut self, &mut self,
cols: ColRange, cols: ColRange,
) -> MatrixSliceMut<N, R, ColRange::Size, S::RStride, S::CStride> ) -> MatrixSliceMut<N, R, ColRange::Size, S::RStride, S::CStride> {
{
self.slice_range_mut(.., cols) self.slice_range_mut(.., cols)
} }
} }
impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'a, N, R, C, RStride, CStride>> impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'a, N, R, C, RStride, CStride>>
for MatrixSlice<'a, N, R, C, RStride, CStride> for MatrixSlice<'a, N, R, C, RStride, CStride>
where where
N: Scalar, N: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(slice_mut: MatrixSliceMut<'a, N, R, C, RStride, CStride>) -> Self { fn from(slice_mut: MatrixSliceMut<'a, N, R, C, RStride, CStride>) -> Self {
let data = SliceStorage { let data = SliceStorage {
ptr: slice_mut.data.ptr, ptr: slice_mut.data.ptr,
shape: slice_mut.data.shape, shape: slice_mut.data.shape,
strides: slice_mut.data.strides, strides: slice_mut.data.strides,
_phantoms: PhantomData, _phantoms: PhantomData,
}; };
unsafe { Matrix::from_data_statically_unchecked(data) } unsafe { Matrix::from_data_statically_unchecked(data) }
} }
} }

View File

@ -838,7 +838,9 @@ impl<N: Scalar + ClosedAdd, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C,
#[inline] #[inline]
#[must_use = "Did you mean to use add_scalar_mut()?"] #[must_use = "Did you mean to use add_scalar_mut()?"]
pub fn add_scalar(&self, rhs: N) -> MatrixMN<N, R, C> pub fn add_scalar(&self, rhs: N) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> { where
DefaultAllocator: Allocator<N, R, C>,
{
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.add_scalar_mut(rhs); res.add_scalar_mut(rhs);
res res
@ -847,7 +849,9 @@ impl<N: Scalar + ClosedAdd, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C,
/// Adds a scalar to `self` in-place. /// Adds a scalar to `self` in-place.
#[inline] #[inline]
pub fn add_scalar_mut(&mut self, rhs: N) pub fn add_scalar_mut(&mut self, rhs: N)
where S: StorageMut<N, R, C> { where
S: StorageMut<N, R, C>,
{
for e in self.iter_mut() { for e in self.iter_mut() {
*e += rhs.inlined_clone() *e += rhs.inlined_clone()
} }
@ -884,7 +888,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn amax(&self) -> N pub fn amax(&self) -> N
where N: Zero + SimdSigned + SimdPartialOrd { where
N: Zero + SimdSigned + SimdPartialOrd,
{
self.fold_with( self.fold_with(
|e| e.unwrap_or(&N::zero()).simd_abs(), |e| e.unwrap_or(&N::zero()).simd_abs(),
|a, b| a.simd_max(b.simd_abs()), |a, b| a.simd_max(b.simd_abs()),
@ -902,7 +908,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn camax(&self) -> N::SimdRealField pub fn camax(&self) -> N::SimdRealField
where N: SimdComplexField { where
N: SimdComplexField,
{
self.fold_with( self.fold_with(
|e| e.unwrap_or(&N::zero()).simd_norm1(), |e| e.unwrap_or(&N::zero()).simd_norm1(),
|a, b| a.simd_max(b.simd_norm1()), |a, b| a.simd_max(b.simd_norm1()),
@ -919,7 +927,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn max(&self) -> N pub fn max(&self) -> N
where N: SimdPartialOrd + Zero { where
N: SimdPartialOrd + Zero,
{
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()), |e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()),
|a, b| a.simd_max(b.inlined_clone()), |a, b| a.simd_max(b.inlined_clone()),
@ -935,7 +945,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn amin(&self) -> N pub fn amin(&self) -> N
where N: Zero + SimdPartialOrd + SimdSigned { where
N: Zero + SimdPartialOrd + SimdSigned,
{
self.fold_with( self.fold_with(
|e| e.map(|e| e.simd_abs()).unwrap_or(N::zero()), |e| e.map(|e| e.simd_abs()).unwrap_or(N::zero()),
|a, b| a.simd_min(b.simd_abs()), |a, b| a.simd_min(b.simd_abs()),
@ -953,7 +965,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn camin(&self) -> N::SimdRealField pub fn camin(&self) -> N::SimdRealField
where N: SimdComplexField { where
N: SimdComplexField,
{
self.fold_with( self.fold_with(
|e| { |e| {
e.map(|e| e.simd_norm1()) e.map(|e| e.simd_norm1())
@ -973,7 +987,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ``` /// ```
#[inline] #[inline]
pub fn min(&self) -> N pub fn min(&self) -> N
where N: SimdPartialOrd + Zero { where
N: SimdPartialOrd + Zero,
{
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()), |e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()),
|a, b| a.simd_min(b.inlined_clone()), |a, b| a.simd_min(b.inlined_clone()),

View File

@ -102,7 +102,8 @@ impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
impl<N: RealField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<N: RealField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Checks that this matrix is orthogonal and has a determinant equal to 1. /// Checks that this matrix is orthogonal and has a determinant equal to 1.
#[inline] #[inline]

View File

@ -114,7 +114,9 @@ impl<N: Scalar + ClosedAdd + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N
/// ``` /// ```
#[inline] #[inline]
pub fn row_sum(&self) -> RowVectorN<N, C> pub fn row_sum(&self) -> RowVectorN<N, C>
where DefaultAllocator: Allocator<N, U1, C> { where
DefaultAllocator: Allocator<N, U1, C>,
{
self.compress_rows(|col| col.sum()) self.compress_rows(|col| col.sum())
} }
@ -135,7 +137,9 @@ impl<N: Scalar + ClosedAdd + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N
/// ``` /// ```
#[inline] #[inline]
pub fn row_sum_tr(&self) -> VectorN<N, C> pub fn row_sum_tr(&self) -> VectorN<N, C>
where DefaultAllocator: Allocator<N, C> { where
DefaultAllocator: Allocator<N, C>,
{
self.compress_rows_tr(|col| col.sum()) self.compress_rows_tr(|col| col.sum())
} }
@ -156,7 +160,9 @@ impl<N: Scalar + ClosedAdd + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N
/// ``` /// ```
#[inline] #[inline]
pub fn column_sum(&self) -> VectorN<N, R> pub fn column_sum(&self) -> VectorN<N, R>
where DefaultAllocator: Allocator<N, R> { where
DefaultAllocator: Allocator<N, R>,
{
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| { self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| {
*out += col; *out += col;
@ -210,7 +216,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn row_variance(&self) -> RowVectorN<N, C> pub fn row_variance(&self) -> RowVectorN<N, C>
where DefaultAllocator: Allocator<N, U1, C> { where
DefaultAllocator: Allocator<N, U1, C>,
{
self.compress_rows(|col| col.variance()) self.compress_rows(|col| col.variance())
} }
@ -227,7 +235,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn row_variance_tr(&self) -> VectorN<N, C> pub fn row_variance_tr(&self) -> VectorN<N, C>
where DefaultAllocator: Allocator<N, C> { where
DefaultAllocator: Allocator<N, C>,
{
self.compress_rows_tr(|col| col.variance()) self.compress_rows_tr(|col| col.variance())
} }
@ -245,7 +255,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn column_variance(&self) -> VectorN<N, R> pub fn column_variance(&self) -> VectorN<N, R>
where DefaultAllocator: Allocator<N, R> { where
DefaultAllocator: Allocator<N, R>,
{
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut mean = self.column_mean(); let mut mean = self.column_mean();
@ -303,7 +315,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn row_mean(&self) -> RowVectorN<N, C> pub fn row_mean(&self) -> RowVectorN<N, C>
where DefaultAllocator: Allocator<N, U1, C> { where
DefaultAllocator: Allocator<N, U1, C>,
{
self.compress_rows(|col| col.mean()) self.compress_rows(|col| col.mean())
} }
@ -320,7 +334,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn row_mean_tr(&self) -> VectorN<N, C> pub fn row_mean_tr(&self) -> VectorN<N, C>
where DefaultAllocator: Allocator<N, C> { where
DefaultAllocator: Allocator<N, C>,
{
self.compress_rows_tr(|col| col.mean()) self.compress_rows_tr(|col| col.mean())
} }
@ -337,7 +353,9 @@ impl<N: Scalar + Field + SupersetOf<f64>, R: Dim, C: Dim, S: Storage<N, R, C>> M
/// ``` /// ```
#[inline] #[inline]
pub fn column_mean(&self) -> VectorN<N, R> pub fn column_mean(&self) -> VectorN<N, R>
where DefaultAllocator: Allocator<N, R> { where
DefaultAllocator: Allocator<N, R>,
{
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64); let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64);
self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| { self.compress_columns(VectorN::zeros_generic(nrows, U1), |out, col| {

View File

@ -103,11 +103,13 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
/// Builds a matrix data storage that does not contain any reference. /// Builds a matrix data storage that does not contain any reference.
fn into_owned(self) -> Owned<N, R, C> fn into_owned(self) -> Owned<N, R, C>
where DefaultAllocator: Allocator<N, R, C>; where
DefaultAllocator: Allocator<N, R, C>;
/// Clones this data storage to one that does not contain any reference. /// Clones this data storage to one that does not contain any reference.
fn clone_owned(&self) -> Owned<N, R, C> fn clone_owned(&self) -> Owned<N, R, C>
where DefaultAllocator: Allocator<N, R, C>; where
DefaultAllocator: Allocator<N, R, C>;
} }
/// Trait implemented by matrix data storage that can provide a mutable access to its elements. /// Trait implemented by matrix data storage that can provide a mutable access to its elements.

View File

@ -5,11 +5,11 @@ use std::io::{Result as IOResult, Write};
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Dim, DimName, Dynamic, U1}; use crate::base::dimension::{Dim, DimName, Dynamic, U1};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
use crate::base::{Scalar, Vector}; use crate::base::{Scalar, Vector};
use crate::base::constraint::{SameNumberOfRows, ShapeConstraint};
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation; use abomonation::Abomonation;
@ -29,7 +29,7 @@ pub struct VecStorage<N, R: Dim, C: Dim> {
ncols: C, ncols: C,
} }
#[deprecated(note="renamed to `VecStorage`")] #[deprecated(note = "renamed to `VecStorage`")]
/// Renamed to [VecStorage]. /// Renamed to [VecStorage].
pub type MatrixVec<N, R, C> = VecStorage<N, R, C>; pub type MatrixVec<N, R, C> = VecStorage<N, R, C>;
@ -89,8 +89,7 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
} }
} }
impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C> impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C> {
{
fn into(self) -> Vec<N> { fn into(self) -> Vec<N> {
self.data self.data
} }
@ -103,7 +102,8 @@ impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C>
* *
*/ */
unsafe impl<N: Scalar, C: Dim> Storage<N, Dynamic, C> for VecStorage<N, Dynamic, C> unsafe impl<N: Scalar, C: Dim> Storage<N, Dynamic, C> for VecStorage<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>,
{ {
type RStride = U1; type RStride = U1;
type CStride = Dynamic; type CStride = Dynamic;
@ -130,13 +130,17 @@ where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>
#[inline] #[inline]
fn into_owned(self) -> Owned<N, Dynamic, C> fn into_owned(self) -> Owned<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C> { where
DefaultAllocator: Allocator<N, Dynamic, C>,
{
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, Dynamic, C> fn clone_owned(&self) -> Owned<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C> { where
DefaultAllocator: Allocator<N, Dynamic, C>,
{
self.clone() self.clone()
} }
@ -147,7 +151,8 @@ where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>
} }
unsafe impl<N: Scalar, R: DimName> Storage<N, R, Dynamic> for VecStorage<N, R, Dynamic> unsafe impl<N: Scalar, R: DimName> Storage<N, R, Dynamic> for VecStorage<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self> where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>,
{ {
type RStride = U1; type RStride = U1;
type CStride = R; type CStride = R;
@ -174,13 +179,17 @@ where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>
#[inline] #[inline]
fn into_owned(self) -> Owned<N, R, Dynamic> fn into_owned(self) -> Owned<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic> { where
DefaultAllocator: Allocator<N, R, Dynamic>,
{
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, R, Dynamic> fn clone_owned(&self) -> Owned<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic> { where
DefaultAllocator: Allocator<N, R, Dynamic>,
{
self.clone() self.clone()
} }
@ -196,7 +205,8 @@ where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>
* *
*/ */
unsafe impl<N: Scalar, C: Dim> StorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C> unsafe impl<N: Scalar, C: Dim> StorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut N {
@ -209,14 +219,19 @@ where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>
} }
} }
unsafe impl<N: Scalar, C: Dim> ContiguousStorage<N, Dynamic, C> for VecStorage<N, Dynamic, C> where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> unsafe impl<N: Scalar, C: Dim> ContiguousStorage<N, Dynamic, C> for VecStorage<N, Dynamic, C> where
{} DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>
{
}
unsafe impl<N: Scalar, C: Dim> ContiguousStorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C> where DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> unsafe impl<N: Scalar, C: Dim> ContiguousStorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C> where
{} DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>
{
}
unsafe impl<N: Scalar, R: DimName> StorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic> unsafe impl<N: Scalar, R: DimName> StorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self> where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut N {
@ -244,14 +259,17 @@ impl<N: Abomonation, R: Dim, C: Dim> Abomonation for VecStorage<N, R, C> {
} }
} }
unsafe impl<N: Scalar, R: DimName> ContiguousStorage<N, R, Dynamic> for VecStorage<N, R, Dynamic> where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self> unsafe impl<N: Scalar, R: DimName> ContiguousStorage<N, R, Dynamic> for VecStorage<N, R, Dynamic> where
{} DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>
unsafe impl<N: Scalar, R: DimName> ContiguousStorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic> where DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>
{}
impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic>
{ {
}
unsafe impl<N: Scalar, R: DimName> ContiguousStorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic> where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>
{
}
impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic> {
/// Extends the number of columns of the `VecStorage` with elements /// Extends the number of columns of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
/// ///
@ -259,8 +277,7 @@ impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic>
/// This function panics if the number of elements yielded by the /// This function panics if the number of elements yielded by the
/// given iterator is not a multiple of the number of rows of the /// given iterator is not a multiple of the number of rows of the
/// `VecStorage`. /// `VecStorage`.
fn extend<I: IntoIterator<Item=N>>(&mut self, iter: I) fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) {
{
self.data.extend(iter); self.data.extend(iter);
self.ncols = Dynamic::new(self.data.len() / self.nrows.value()); self.ncols = Dynamic::new(self.data.len() / self.nrows.value());
assert!(self.data.len() % self.nrows.value() == 0, assert!(self.data.len() % self.nrows.value() == 0,
@ -268,8 +285,7 @@ impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic>
} }
} }
impl<'a, N: 'a + Copy, R: Dim> Extend<&'a N> for VecStorage<N, R, Dynamic> impl<'a, N: 'a + Copy, R: Dim> Extend<&'a N> for VecStorage<N, R, Dynamic> {
{
/// Extends the number of columns of the `VecStorage` with elements /// Extends the number of columns of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
/// ///
@ -277,8 +293,7 @@ impl<'a, N: 'a + Copy, R: Dim> Extend<&'a N> for VecStorage<N, R, Dynamic>
/// This function panics if the number of elements yielded by the /// This function panics if the number of elements yielded by the
/// given iterator is not a multiple of the number of rows of the /// given iterator is not a multiple of the number of rows of the
/// `VecStorage`. /// `VecStorage`.
fn extend<I: IntoIterator<Item=&'a N>>(&mut self, iter: I) fn extend<I: IntoIterator<Item = &'a N>>(&mut self, iter: I) {
{
self.extend(iter.into_iter().copied()) self.extend(iter.into_iter().copied())
} }
} }
@ -298,8 +313,7 @@ where
/// This function panics if the number of rows of each `Vector` /// This function panics if the number of rows of each `Vector`
/// yielded by the iterator is not equal to the number of rows /// yielded by the iterator is not equal to the number of rows
/// of this `VecStorage`. /// of this `VecStorage`.
fn extend<I: IntoIterator<Item=Vector<N, RV, SV>>>(&mut self, iter: I) fn extend<I: IntoIterator<Item = Vector<N, RV, SV>>>(&mut self, iter: I) {
{
let nrows = self.nrows.value(); let nrows = self.nrows.value();
let iter = iter.into_iter(); let iter = iter.into_iter();
let (lower, _upper) = iter.size_hint(); let (lower, _upper) = iter.size_hint();
@ -312,12 +326,10 @@ where
} }
} }
impl<N> Extend<N> for VecStorage<N, Dynamic, U1> impl<N> Extend<N> for VecStorage<N, Dynamic, U1> {
{
/// Extends the number of rows of the `VecStorage` with elements /// Extends the number of rows of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
fn extend<I: IntoIterator<Item=N>>(&mut self, iter: I) fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) {
{
self.data.extend(iter); self.data.extend(iter);
self.nrows = Dynamic::new(self.data.len()); self.nrows = Dynamic::new(self.data.len());
} }

View File

@ -13,13 +13,15 @@ use simba::scalar::ComplexField;
/// A random orthogonal matrix. /// A random orthogonal matrix.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RandomOrthogonal<N: Scalar, D: Dim = Dynamic> pub struct RandomOrthogonal<N: Scalar, D: Dim = Dynamic>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
m: MatrixN<N, D>, m: MatrixN<N, D>,
} }
impl<N: ComplexField, D: Dim> RandomOrthogonal<N, D> impl<N: ComplexField, D: Dim> RandomOrthogonal<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Retrieve the generated matrix. /// Retrieve the generated matrix.
pub fn unwrap(self) -> MatrixN<N, D> { pub fn unwrap(self) -> MatrixN<N, D> {

View File

@ -14,13 +14,15 @@ use crate::debug::RandomOrthogonal;
/// A random, well-conditioned, symmetric definite-positive matrix. /// A random, well-conditioned, symmetric definite-positive matrix.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RandomSDP<N: Scalar, D: Dim = Dynamic> pub struct RandomSDP<N: Scalar, D: Dim = Dynamic>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
m: MatrixN<N, D>, m: MatrixN<N, D>,
} }
impl<N: ComplexField, D: Dim> RandomSDP<N, D> impl<N: ComplexField, D: Dim> RandomSDP<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Retrieve the generated matrix. /// Retrieve the generated matrix.
pub fn unwrap(self) -> MatrixN<N, D> { pub fn unwrap(self) -> MatrixN<N, D> {

View File

@ -114,7 +114,8 @@ where
// 2D rotation. // 2D rotation.
impl<N: SimdRealField> Isometry<N, U2, Rotation2<N>> impl<N: SimdRealField> Isometry<N, U2, Rotation2<N>>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
/// Creates a new 2D isometry from a translation and a rotation angle. /// Creates a new 2D isometry from a translation and a rotation angle.
/// ///
@ -151,7 +152,8 @@ where N::Element: SimdRealField
} }
impl<N: SimdRealField> Isometry<N, U2, UnitComplex<N>> impl<N: SimdRealField> Isometry<N, U2, UnitComplex<N>>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
/// Creates a new 2D isometry from a translation and a rotation angle. /// Creates a new 2D isometry from a translation and a rotation angle.
/// ///

View File

@ -46,7 +46,9 @@ impl<N: RealField> PartialEq for Orthographic3<N> {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: RealField + Serialize> Serialize for Orthographic3<N> { impl<N: RealField + Serialize> Serialize for Orthographic3<N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.matrix.serialize(serializer) self.matrix.serialize(serializer)
} }
} }
@ -54,7 +56,9 @@ impl<N: RealField + Serialize> Serialize for Orthographic3<N> {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: RealField + Deserialize<'a>> Deserialize<'a> for Orthographic3<N> { impl<'a, N: RealField + Deserialize<'a>> Deserialize<'a> for Orthographic3<N> {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where Des: Deserializer<'a> { where
Des: Deserializer<'a>,
{
let matrix = Matrix4::<N>::deserialize(deserializer)?; let matrix = Matrix4::<N>::deserialize(deserializer)?;
Ok(Self::from_matrix_unchecked(matrix)) Ok(Self::from_matrix_unchecked(matrix))
@ -480,7 +484,9 @@ impl<N: RealField> Orthographic3<N> {
/// ``` /// ```
#[inline] #[inline]
pub fn project_vector<SB>(&self, p: &Vector<N, U3, SB>) -> Vector3<N> pub fn project_vector<SB>(&self, p: &Vector<N, U3, SB>) -> Vector3<N>
where SB: Storage<N, U3> { where
SB: Storage<N, U3>,
{
Vector3::new( Vector3::new(
self.matrix[(0, 0)] * p[0], self.matrix[(0, 0)] * p[0],
self.matrix[(1, 1)] * p[1], self.matrix[(1, 1)] * p[1],
@ -679,7 +685,8 @@ impl<N: RealField> Orthographic3<N> {
} }
impl<N: RealField> Distribution<Orthographic3<N>> for Standard impl<N: RealField> Distribution<Orthographic3<N>> for Standard
where Standard: Distribution<N> where
Standard: Distribution<N>,
{ {
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Orthographic3<N> { fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Orthographic3<N> {
let left = r.gen(); let left = r.gen();
@ -695,7 +702,8 @@ where Standard: Distribution<N>
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: RealField + Arbitrary> Arbitrary for Orthographic3<N> impl<N: RealField + Arbitrary> Arbitrary for Orthographic3<N>
where Matrix4<N>: Send where
Matrix4<N>: Send,
{ {
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {
let left = Arbitrary::arbitrary(g); let left = Arbitrary::arbitrary(g);

View File

@ -47,7 +47,9 @@ impl<N: RealField> PartialEq for Perspective3<N> {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N: RealField + Serialize> Serialize for Perspective3<N> { impl<N: RealField + Serialize> Serialize for Perspective3<N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.matrix.serialize(serializer) self.matrix.serialize(serializer)
} }
} }
@ -55,7 +57,9 @@ impl<N: RealField + Serialize> Serialize for Perspective3<N> {
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N: RealField + Deserialize<'a>> Deserialize<'a> for Perspective3<N> { impl<'a, N: RealField + Deserialize<'a>> Deserialize<'a> for Perspective3<N> {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where Des: Deserializer<'a> { where
Des: Deserializer<'a>,
{
let matrix = Matrix4::<N>::deserialize(deserializer)?; let matrix = Matrix4::<N>::deserialize(deserializer)?;
Ok(Self::from_matrix_unchecked(matrix)) Ok(Self::from_matrix_unchecked(matrix))
@ -212,7 +216,9 @@ impl<N: RealField> Perspective3<N> {
/// Projects a vector. Faster than matrix multiplication. /// Projects a vector. Faster than matrix multiplication.
#[inline] #[inline]
pub fn project_vector<SB>(&self, p: &Vector<N, U3, SB>) -> Vector3<N> pub fn project_vector<SB>(&self, p: &Vector<N, U3, SB>) -> Vector3<N>
where SB: Storage<N, U3> { where
SB: Storage<N, U3>,
{
let inverse_denom = -N::one() / p[2]; let inverse_denom = -N::one() / p[2];
Vector3::new( Vector3::new(
self.matrix[(0, 0)] * p[0] * inverse_denom, self.matrix[(0, 0)] * p[0] * inverse_denom,
@ -263,7 +269,8 @@ impl<N: RealField> Perspective3<N> {
} }
impl<N: RealField> Distribution<Perspective3<N>> for Standard impl<N: RealField> Distribution<Perspective3<N>> for Standard
where Standard: Distribution<N> where
Standard: Distribution<N>,
{ {
fn sample<'a, R: Rng + ?Sized>(&self, r: &'a mut R) -> Perspective3<N> { fn sample<'a, R: Rng + ?Sized>(&self, r: &'a mut R) -> Perspective3<N> {
let znear = r.gen(); let znear = r.gen();

View File

@ -23,7 +23,8 @@ use crate::base::{DefaultAllocator, Scalar, VectorN};
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Point<N: Scalar, D: DimName> pub struct Point<N: Scalar, D: DimName>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// The coordinates of this point, i.e., the shift from the origin. /// The coordinates of this point, i.e., the shift from the origin.
pub coords: VectorN<N, D>, pub coords: VectorN<N, D>,
@ -53,7 +54,9 @@ where
<DefaultAllocator as Allocator<N, D>>::Buffer: Serialize, <DefaultAllocator as Allocator<N, D>>::Buffer: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.coords.serialize(serializer) self.coords.serialize(serializer)
} }
} }
@ -65,7 +68,9 @@ where
<DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>, <DefaultAllocator as Allocator<N, D>>::Buffer: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where Des: Deserializer<'a> { where
Des: Deserializer<'a>,
{
let coords = VectorN::<N, D>::deserialize(deserializer)?; let coords = VectorN::<N, D>::deserialize(deserializer)?;
Ok(Self::from(coords)) Ok(Self::from(coords))
@ -94,7 +99,8 @@ where
} }
impl<N: Scalar, D: DimName> Point<N, D> impl<N: Scalar, D: DimName> Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// Converts this point into a vector in homogeneous coordinates, i.e., appends a `1` at the /// Converts this point into a vector in homogeneous coordinates, i.e., appends a `1` at the
/// end of it. /// end of it.
@ -246,8 +252,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.coords self.coords
.relative_eq(&other.coords, epsilon, max_relative) .relative_eq(&other.coords, epsilon, max_relative)
} }
@ -272,7 +277,8 @@ where
impl<N: Scalar + Eq, D: DimName> Eq for Point<N, D> where DefaultAllocator: Allocator<N, D> {} impl<N: Scalar + Eq, D: DimName> Eq for Point<N, D> where DefaultAllocator: Allocator<N, D> {}
impl<N: Scalar, D: DimName> PartialEq for Point<N, D> impl<N: Scalar, D: DimName> PartialEq for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -281,7 +287,8 @@ where DefaultAllocator: Allocator<N, D>
} }
impl<N: Scalar + PartialOrd, D: DimName> PartialOrd for Point<N, D> impl<N: Scalar + PartialOrd, D: DimName> PartialOrd for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@ -313,7 +320,8 @@ where DefaultAllocator: Allocator<N, D>
* inf/sup * inf/sup
*/ */
impl<N: Scalar + SimdPartialOrd, D: DimName> Point<N, D> impl<N: Scalar + SimdPartialOrd, D: DimName> Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// Computes the infimum (aka. componentwise min) of two points. /// Computes the infimum (aka. componentwise min) of two points.
#[inline] #[inline]
@ -341,7 +349,8 @@ where DefaultAllocator: Allocator<N, D>
* *
*/ */
impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Point<N, D> impl<N: Scalar + fmt::Display, D: DimName> fmt::Display for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{")?; write!(f, "{{")?;

View File

@ -13,7 +13,8 @@ use simba::scalar::ClosedDiv;
use crate::geometry::Point; use crate::geometry::Point;
impl<N: Scalar, D: DimName> Point<N, D> impl<N: Scalar, D: DimName> Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new point with uninitialized coordinates. /// Creates a new point with uninitialized coordinates.
#[inline] #[inline]
@ -38,7 +39,9 @@ where DefaultAllocator: Allocator<N, D>
/// ``` /// ```
#[inline] #[inline]
pub fn origin() -> Self pub fn origin() -> Self
where N: Zero { where
N: Zero,
{
Self::from(VectorN::from_element(N::zero())) Self::from(VectorN::from_element(N::zero()))
} }
@ -113,7 +116,8 @@ where DefaultAllocator: Allocator<N, D>
* *
*/ */
impl<N: Scalar + Bounded, D: DimName> Bounded for Point<N, D> impl<N: Scalar + Bounded, D: DimName> Bounded for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn max_value() -> Self { fn max_value() -> Self {

View File

@ -21,7 +21,8 @@ use crate::geometry::Point;
* *
*/ */
impl<N: Scalar, D: DimName> Index<usize> for Point<N, D> impl<N: Scalar, D: DimName> Index<usize> for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
type Output = N; type Output = N;
@ -32,7 +33,8 @@ where DefaultAllocator: Allocator<N, D>
} }
impl<N: Scalar, D: DimName> IndexMut<usize> for Point<N, D> impl<N: Scalar, D: DimName> IndexMut<usize> for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn index_mut(&mut self, i: usize) -> &mut Self::Output { fn index_mut(&mut self, i: usize) -> &mut Self::Output {
@ -46,7 +48,8 @@ where DefaultAllocator: Allocator<N, D>
* *
*/ */
impl<N: Scalar + ClosedNeg, D: DimName> Neg for Point<N, D> impl<N: Scalar + ClosedNeg, D: DimName> Neg for Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
type Output = Self; type Output = Self;
@ -57,7 +60,8 @@ where DefaultAllocator: Allocator<N, D>
} }
impl<'a, N: Scalar + ClosedNeg, D: DimName> Neg for &'a Point<N, D> impl<'a, N: Scalar + ClosedNeg, D: DimName> Neg for &'a Point<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
type Output = Point<N, D>; type Output = Point<N, D>;

View File

@ -219,7 +219,8 @@ impl<N: SimdRealField> Into<mint::Quaternion<N>> for UnitQuaternion<N> {
} }
impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix4<N> impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix4<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn from(q: UnitQuaternion<N>) -> Self { fn from(q: UnitQuaternion<N>) -> Self {
@ -228,7 +229,8 @@ where N::Element: SimdRealField
} }
impl<N: SimdRealField> From<UnitQuaternion<N>> for Rotation3<N> impl<N: SimdRealField> From<UnitQuaternion<N>> for Rotation3<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn from(q: UnitQuaternion<N>) -> Self { fn from(q: UnitQuaternion<N>) -> Self {
@ -237,7 +239,8 @@ where N::Element: SimdRealField
} }
impl<N: SimdRealField> From<Rotation3<N>> for UnitQuaternion<N> impl<N: SimdRealField> From<Rotation3<N>> for UnitQuaternion<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn from(q: Rotation3<N>) -> Self { fn from(q: Rotation3<N>) -> Self {
@ -246,7 +249,8 @@ where N::Element: SimdRealField
} }
impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix3<N> impl<N: SimdRealField> From<UnitQuaternion<N>> for Matrix3<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn from(q: UnitQuaternion<N>) -> Self { fn from(q: UnitQuaternion<N>) -> Self {

View File

@ -551,7 +551,8 @@ macro_rules! left_scalar_mul_impl(
left_scalar_mul_impl!(f32, f64); left_scalar_mul_impl!(f32, f64);
impl<N: SimdRealField> Neg for Quaternion<N> impl<N: SimdRealField> Neg for Quaternion<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
type Output = Quaternion<N>; type Output = Quaternion<N>;
@ -562,7 +563,8 @@ where N::Element: SimdRealField
} }
impl<'a, N: SimdRealField> Neg for &'a Quaternion<N> impl<'a, N: SimdRealField> Neg for &'a Quaternion<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
type Output = Quaternion<N>; type Output = Quaternion<N>;

View File

@ -26,7 +26,8 @@ use crate::geometry::Point;
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct Rotation<N: Scalar, D: DimName> pub struct Rotation<N: Scalar, D: DimName>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
matrix: MatrixN<N, D>, matrix: MatrixN<N, D>,
} }
@ -87,7 +88,9 @@ where
Owned<N, D, D>: Serialize, Owned<N, D, D>: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.matrix.serialize(serializer) self.matrix.serialize(serializer)
} }
} }
@ -99,7 +102,9 @@ where
Owned<N, D, D>: Deserialize<'a>, Owned<N, D, D>: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where Des: Deserializer<'a> { where
Des: Deserializer<'a>,
{
let matrix = MatrixN::<N, D>::deserialize(deserializer)?; let matrix = MatrixN::<N, D>::deserialize(deserializer)?;
Ok(Self::from_matrix_unchecked(matrix)) Ok(Self::from_matrix_unchecked(matrix))
@ -107,7 +112,8 @@ where
} }
impl<N: Scalar, D: DimName> Rotation<N, D> impl<N: Scalar, D: DimName> Rotation<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// A reference to the underlying matrix representation of this rotation. /// A reference to the underlying matrix representation of this rotation.
/// ///
@ -440,7 +446,8 @@ where
impl<N: Scalar + Eq, D: DimName> Eq for Rotation<N, D> where DefaultAllocator: Allocator<N, D, D> {} impl<N: Scalar + Eq, D: DimName> Eq for Rotation<N, D> where DefaultAllocator: Allocator<N, D, D> {}
impl<N: Scalar + PartialEq, D: DimName> PartialEq for Rotation<N, D> impl<N: Scalar + PartialEq, D: DimName> PartialEq for Rotation<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -484,8 +491,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.matrix self.matrix
.relative_eq(&other.matrix, epsilon, max_relative) .relative_eq(&other.matrix, epsilon, max_relative)
} }

View File

@ -31,7 +31,8 @@ use crate::base::{DefaultAllocator, Matrix, MatrixMN, Scalar, Unit, Vector, Vect
use crate::geometry::{Point, Rotation}; use crate::geometry::{Point, Rotation};
impl<N: Scalar, D: DimName> Index<(usize, usize)> for Rotation<N, D> impl<N: Scalar, D: DimName> Index<(usize, usize)> for Rotation<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
type Output = N; type Output = N;

View File

@ -55,7 +55,9 @@ impl<N: SimdRealField> Rotation2<N> {
/// convergence parameters and starting solution. /// convergence parameters and starting solution.
/// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al. /// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al.
pub fn from_matrix(m: &Matrix2<N>) -> Self pub fn from_matrix(m: &Matrix2<N>) -> Self
where N: RealField { where
N: RealField,
{
Self::from_matrix_eps(m, N::default_epsilon(), 0, Self::identity()) Self::from_matrix_eps(m, N::default_epsilon(), 0, Self::identity())
} }
@ -72,7 +74,9 @@ impl<N: SimdRealField> Rotation2<N> {
/// to the actual solution is provided. Can be set to `Rotation2::identity()` if no other /// to the actual solution is provided. Can be set to `Rotation2::identity()` if no other
/// guesses come to mind. /// guesses come to mind.
pub fn from_matrix_eps(m: &Matrix2<N>, eps: N, mut max_iter: usize, guess: Self) -> Self pub fn from_matrix_eps(m: &Matrix2<N>, eps: N, mut max_iter: usize, guess: Self) -> Self
where N: RealField { where
N: RealField,
{
if max_iter == 0 { if max_iter == 0 {
max_iter = usize::max_value(); max_iter = usize::max_value();
} }
@ -199,7 +203,9 @@ impl<N: SimdRealField> Rotation2<N> {
/// computations might cause the matrix from progressively not being orthonormal anymore. /// computations might cause the matrix from progressively not being orthonormal anymore.
#[inline] #[inline]
pub fn renormalize(&mut self) pub fn renormalize(&mut self)
where N: RealField { where
N: RealField,
{
let mut c = UnitComplex::from(*self); let mut c = UnitComplex::from(*self);
let _ = c.renormalize(); let _ = c.renormalize();
@ -262,7 +268,8 @@ where
* *
*/ */
impl<N: SimdRealField> Rotation3<N> impl<N: SimdRealField> Rotation3<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
/// Builds a 3 dimensional rotation matrix from an axis and an angle. /// Builds a 3 dimensional rotation matrix from an axis and an angle.
/// ///
@ -299,7 +306,9 @@ where N::Element: SimdRealField
/// convergence parameters and starting solution. /// convergence parameters and starting solution.
/// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al. /// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al.
pub fn from_matrix(m: &Matrix3<N>) -> Self pub fn from_matrix(m: &Matrix3<N>) -> Self
where N: RealField { where
N: RealField,
{
Self::from_matrix_eps(m, N::default_epsilon(), 0, Self::identity()) Self::from_matrix_eps(m, N::default_epsilon(), 0, Self::identity())
} }
@ -316,7 +325,9 @@ where N::Element: SimdRealField
/// to the actual solution is provided. Can be set to `Rotation3::identity()` if no other /// to the actual solution is provided. Can be set to `Rotation3::identity()` if no other
/// guesses come to mind. /// guesses come to mind.
pub fn from_matrix_eps(m: &Matrix3<N>, eps: N, mut max_iter: usize, guess: Self) -> Self pub fn from_matrix_eps(m: &Matrix3<N>, eps: N, mut max_iter: usize, guess: Self) -> Self
where N: RealField { where
N: RealField,
{
if max_iter == 0 { if max_iter == 0 {
max_iter = usize::max_value(); max_iter = usize::max_value();
} }
@ -391,7 +402,9 @@ where N::Element: SimdRealField
/// assert_eq!(Rotation3::from_scaled_axis(Vector3::<f32>::zeros()), Rotation3::identity()); /// assert_eq!(Rotation3::from_scaled_axis(Vector3::<f32>::zeros()), Rotation3::identity());
/// ``` /// ```
pub fn from_axis_angle<SB>(axis: &Unit<Vector<N, U3, SB>>, angle: N) -> Self pub fn from_axis_angle<SB>(axis: &Unit<Vector<N, U3, SB>>, angle: N) -> Self
where SB: Storage<N, U3> { where
SB: Storage<N, U3>,
{
angle.simd_ne(N::zero()).if_else( angle.simd_ne(N::zero()).if_else(
|| { || {
let ux = axis.as_ref()[0]; let ux = axis.as_ref()[0];
@ -456,7 +469,9 @@ where N::Element: SimdRealField
/// The angles are produced in the form (roll, pitch, yaw). /// The angles are produced in the form (roll, pitch, yaw).
#[deprecated(note = "This is renamed to use `.euler_angles()`.")] #[deprecated(note = "This is renamed to use `.euler_angles()`.")]
pub fn to_euler_angles(&self) -> (N, N, N) pub fn to_euler_angles(&self) -> (N, N, N)
where N: RealField { where
N: RealField,
{
self.euler_angles() self.euler_angles()
} }
@ -475,7 +490,9 @@ where N::Element: SimdRealField
/// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6); /// assert_relative_eq!(euler.2, 0.3, epsilon = 1.0e-6);
/// ``` /// ```
pub fn euler_angles(&self) -> (N, N, N) pub fn euler_angles(&self) -> (N, N, N)
where N: RealField { where
N: RealField,
{
// Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh // Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh
// https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578 // https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578
if self[(2, 0)].abs() < N::one() { if self[(2, 0)].abs() < N::one() {
@ -498,7 +515,9 @@ where N::Element: SimdRealField
/// computations might cause the matrix from progressively not being orthonormal anymore. /// computations might cause the matrix from progressively not being orthonormal anymore.
#[inline] #[inline]
pub fn renormalize(&mut self) pub fn renormalize(&mut self)
where N: RealField { where
N: RealField,
{
let mut c = UnitQuaternion::from(*self); let mut c = UnitQuaternion::from(*self);
let _ = c.renormalize(); let _ = c.renormalize();
@ -717,7 +736,9 @@ where N::Element: SimdRealField
/// ``` /// ```
#[inline] #[inline]
pub fn axis(&self) -> Option<Unit<Vector3<N>>> pub fn axis(&self) -> Option<Unit<Vector3<N>>>
where N: RealField { where
N: RealField,
{
let axis = VectorN::<N, U3>::new( let axis = VectorN::<N, U3>::new(
self.matrix()[(2, 1)] - self.matrix()[(1, 2)], self.matrix()[(2, 1)] - self.matrix()[(1, 2)],
self.matrix()[(0, 2)] - self.matrix()[(2, 0)], self.matrix()[(0, 2)] - self.matrix()[(2, 0)],
@ -739,7 +760,9 @@ where N::Element: SimdRealField
/// ``` /// ```
#[inline] #[inline]
pub fn scaled_axis(&self) -> Vector3<N> pub fn scaled_axis(&self) -> Vector3<N>
where N: RealField { where
N: RealField,
{
if let Some(axis) = self.axis() { if let Some(axis) = self.axis() {
axis.into_inner() * self.angle() axis.into_inner() * self.angle()
} else { } else {
@ -768,7 +791,9 @@ where N::Element: SimdRealField
/// ``` /// ```
#[inline] #[inline]
pub fn axis_angle(&self) -> Option<(Unit<Vector3<N>>, N)> pub fn axis_angle(&self) -> Option<(Unit<Vector3<N>>, N)>
where N: RealField { where
N: RealField,
{
if let Some(axis) = self.axis() { if let Some(axis) = self.axis() {
Some((axis, self.angle())) Some((axis, self.angle()))
} else { } else {
@ -825,7 +850,9 @@ where N::Element: SimdRealField
/// ``` /// ```
#[inline] #[inline]
pub fn powf(&self, n: N) -> Self pub fn powf(&self, n: N) -> Self
where N: RealField { where
N: RealField,
{
if let Some(axis) = self.axis() { if let Some(axis) = self.axis() {
Self::from_axis_angle(&axis, self.angle() * n) Self::from_axis_angle(&axis, self.angle() * n)
} else if self.matrix()[(0, 0)] < N::zero() { } else if self.matrix()[(0, 0)] < N::zero() {

View File

@ -40,7 +40,8 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
Owned<N, D>: Deserialize<'de>")) Owned<N, D>: Deserialize<'de>"))
)] )]
pub struct Similarity<N: Scalar, D: DimName, R> pub struct Similarity<N: Scalar, D: DimName, R>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// The part of this similarity that does not include the scaling factor. /// The part of this similarity that does not include the scaling factor.
pub isometry: Isometry<N, D, R>, pub isometry: Isometry<N, D, R>,
@ -87,7 +88,8 @@ where
} }
impl<N: Scalar + Zero, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R> impl<N: Scalar + Zero, D: DimName, R: AbstractRotation<N, D> + Clone> Clone for Similarity<N, D, R>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -127,7 +129,8 @@ where
} }
impl<N: Scalar, D: DimName, R> Similarity<N, D, R> impl<N: Scalar, D: DimName, R> Similarity<N, D, R>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// The scaling factor of this similarity transformation. /// The scaling factor of this similarity transformation.
#[inline] #[inline]
@ -329,7 +332,8 @@ where
// This is OK since all constructors of the isometry enforce the Rotation bound already (and // This is OK since all constructors of the isometry enforce the Rotation bound already (and
// explicit struct construction is prevented by the private scaling factor). // explicit struct construction is prevented by the private scaling factor).
impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R> impl<N: SimdRealField, D: DimName, R> Similarity<N, D, R>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// Converts this similarity into its equivalent homogeneous transformation matrix. /// Converts this similarity into its equivalent homogeneous transformation matrix.
#[inline] #[inline]
@ -404,8 +408,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.isometry self.isometry
.relative_eq(&other.isometry, epsilon, max_relative) .relative_eq(&other.isometry, epsilon, max_relative)
&& self && self

View File

@ -158,7 +158,8 @@ super_tcategory_impl!(
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct Transform<N: RealField, D: DimNameAdd<U1>, C: TCategory> pub struct Transform<N: RealField, D: DimNameAdd<U1>, C: TCategory>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
matrix: MatrixN<N, DimNameSum<D, U1>>, matrix: MatrixN<N, DimNameSum<D, U1>>,
_phantom: PhantomData<C>, _phantom: PhantomData<C>,
@ -181,7 +182,8 @@ where
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Clone for Transform<N, D, C> impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Clone for Transform<N, D, C>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -196,7 +198,9 @@ where
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Serialize, Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer { where
S: Serializer,
{
self.matrix.serialize(serializer) self.matrix.serialize(serializer)
} }
} }
@ -208,18 +212,23 @@ where
Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Deserialize<'a>, Owned<N, DimNameSum<D, U1>, DimNameSum<D, U1>>: Deserialize<'a>,
{ {
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error> fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where Des: Deserializer<'a> { where
Des: Deserializer<'a>,
{
let matrix = MatrixN::<N, DimNameSum<D, U1>>::deserialize(deserializer)?; let matrix = MatrixN::<N, DimNameSum<D, U1>>::deserialize(deserializer)?;
Ok(Transform::from_matrix_unchecked(matrix)) Ok(Transform::from_matrix_unchecked(matrix))
} }
} }
impl<N: RealField + Eq, D: DimNameAdd<U1>, C: TCategory> Eq for Transform<N, D, C> where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> impl<N: RealField + Eq, D: DimNameAdd<U1>, C: TCategory> Eq for Transform<N, D, C> where
{} DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
{
}
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> PartialEq for Transform<N, D, C> impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> PartialEq for Transform<N, D, C>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
#[inline] #[inline]
fn eq(&self, right: &Self) -> bool { fn eq(&self, right: &Self) -> bool {
@ -228,7 +237,8 @@ where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C> impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
/// Creates a new transformation from the given homogeneous matrix. The transformation category /// Creates a new transformation from the given homogeneous matrix. The transformation category
/// of `Self` is not checked to be verified by the given matrix. /// of `Self` is not checked to be verified by the given matrix.
@ -398,7 +408,9 @@ where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
#[inline] #[inline]
#[must_use = "Did you mean to use inverse_mut()?"] #[must_use = "Did you mean to use inverse_mut()?"]
pub fn inverse(self) -> Transform<N, D, C> pub fn inverse(self) -> Transform<N, D, C>
where C: SubTCategoryOf<TProjective> { where
C: SubTCategoryOf<TProjective>,
{
// FIXME: specialize for TAffine? // FIXME: specialize for TAffine?
Transform::from_matrix_unchecked(self.matrix.try_inverse().unwrap()) Transform::from_matrix_unchecked(self.matrix.try_inverse().unwrap())
} }
@ -451,7 +463,9 @@ where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_mut(&mut self) pub fn inverse_mut(&mut self)
where C: SubTCategoryOf<TProjective> { where
C: SubTCategoryOf<TProjective>,
{
let _ = self.matrix.try_inverse_mut(); let _ = self.matrix.try_inverse_mut();
} }
} }
@ -509,7 +523,8 @@ where
} }
impl<N: RealField, D: DimNameAdd<U1>> Transform<N, D, TGeneral> impl<N: RealField, D: DimNameAdd<U1>> Transform<N, D, TGeneral>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
/// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this /// A mutable reference to underlying matrix. Use `.matrix_mut_unchecked` instead if this
/// transformation category is not `TGeneral`. /// transformation category is not `TGeneral`.
@ -553,8 +568,7 @@ where
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.matrix self.matrix
.relative_eq(&other.matrix, epsilon, max_relative) .relative_eq(&other.matrix, epsilon, max_relative)
} }

View File

@ -9,7 +9,8 @@ use crate::base::{DefaultAllocator, MatrixN};
use crate::geometry::{TCategory, Transform}; use crate::geometry::{TCategory, Transform};
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C> impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> Transform<N, D, C>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
/// Creates a new identity transform. /// Creates a new identity transform.
/// ///
@ -46,7 +47,8 @@ where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>
} }
impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> One for Transform<N, D, C> impl<N: RealField, D: DimNameAdd<U1>, C: TCategory> One for Transform<N, D, C>
where DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>> where
DefaultAllocator: Allocator<N, DimNameSum<D, U1>, DimNameSum<D, U1>>,
{ {
/// Creates a new identity transform. /// Creates a new identity transform.
#[inline] #[inline]

View File

@ -16,7 +16,8 @@ use crate::base::{DefaultAllocator, Scalar, VectorN};
use crate::geometry::Translation; use crate::geometry::Translation;
impl<N: Scalar + Zero, D: DimName> Translation<N, D> impl<N: Scalar + Zero, D: DimName> Translation<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
/// Creates a new identity translation. /// Creates a new identity translation.
/// ///
@ -39,7 +40,8 @@ where DefaultAllocator: Allocator<N, D>
} }
impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D> impl<N: Scalar + Zero + ClosedAdd, D: DimName> One for Translation<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {

View File

@ -167,7 +167,8 @@ where
} }
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D> impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D>
where DefaultAllocator: Allocator<N, D> where
DefaultAllocator: Allocator<N, D>,
{ {
#[inline] #[inline]
fn from(vector: VectorN<N, D>) -> Self { fn from(vector: VectorN<N, D>) -> Self {

View File

@ -41,7 +41,8 @@ impl<N: SimdRealField> Normed for Complex<N> {
} }
impl<N: SimdRealField> UnitComplex<N> impl<N: SimdRealField> UnitComplex<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
/// The rotation angle in `]-pi; pi]` of this unit complex number. /// The rotation angle in `]-pi; pi]` of this unit complex number.
/// ///
@ -100,7 +101,9 @@ where N::Element: SimdRealField
/// Returns `None` if the angle is zero. /// Returns `None` if the angle is zero.
#[inline] #[inline]
pub fn axis_angle(&self) -> Option<(Unit<Vector1<N>>, N)> pub fn axis_angle(&self) -> Option<(Unit<Vector1<N>>, N)>
where N: RealField { where
N: RealField,
{
let ang = self.angle(); let ang = self.angle();
if ang.is_zero() { if ang.is_zero() {
@ -391,8 +394,7 @@ impl<N: RealField> RelativeEq for UnitComplex<N> {
other: &Self, other: &Self,
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool ) -> bool {
{
self.re.relative_eq(&other.re, epsilon, max_relative) self.re.relative_eq(&other.re, epsilon, max_relative)
&& self.im.relative_eq(&other.im, epsilon, max_relative) && self.im.relative_eq(&other.im, epsilon, max_relative)
} }

View File

@ -14,7 +14,8 @@ use simba::scalar::RealField;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
impl<N: SimdRealField> UnitComplex<N> impl<N: SimdRealField> UnitComplex<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
/// The unit complex number multiplicative identity. /// The unit complex number multiplicative identity.
/// ///
@ -138,7 +139,9 @@ where N::Element: SimdRealField
/// convergence parameters and starting solution. /// convergence parameters and starting solution.
/// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al. /// This implements "A Robust Method to Extract the Rotational Part of Deformations" by Müller et al.
pub fn from_matrix(m: &Matrix2<N>) -> Self pub fn from_matrix(m: &Matrix2<N>) -> Self
where N: RealField { where
N: RealField,
{
Rotation2::from_matrix(m).into() Rotation2::from_matrix(m).into()
} }
@ -155,7 +158,9 @@ where N::Element: SimdRealField
/// to the actual solution is provided. Can be set to `UnitQuaternion::identity()` if no other /// to the actual solution is provided. Can be set to `UnitQuaternion::identity()` if no other
/// guesses come to mind. /// guesses come to mind.
pub fn from_matrix_eps(m: &Matrix2<N>, eps: N, max_iter: usize, guess: Self) -> Self pub fn from_matrix_eps(m: &Matrix2<N>, eps: N, max_iter: usize, guess: Self) -> Self
where N: RealField { where
N: RealField,
{
let guess = Rotation2::from(guess); let guess = Rotation2::from(guess);
Rotation2::from_matrix_eps(m, eps, max_iter, guess).into() Rotation2::from_matrix_eps(m, eps, max_iter, guess).into()
} }
@ -276,7 +281,8 @@ where N::Element: SimdRealField
} }
impl<N: SimdRealField> One for UnitComplex<N> impl<N: SimdRealField> One for UnitComplex<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {
@ -298,7 +304,8 @@ where
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: SimdRealField + Arbitrary> Arbitrary for UnitComplex<N> impl<N: SimdRealField + Arbitrary> Arbitrary for UnitComplex<N>
where N::Element: SimdRealField where
N::Element: SimdRealField,
{ {
#[inline] #[inline]
fn arbitrary<G: Gen>(g: &mut G) -> Self { fn arbitrary<G: Gen>(g: &mut G) -> Self {

View File

@ -1,9 +1,9 @@
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use pest::Parser;
use crate::sparse::CsMatrix; use crate::sparse::CsMatrix;
use crate::RealField; use crate::RealField;
use pest::Parser;
#[derive(Parser)] #[derive(Parser)]
#[grammar = "io/matrix_market.pest"] #[grammar = "io/matrix_market.pest"]

View File

@ -13,7 +13,9 @@ use crate::base::{DefaultAllocator, MatrixN, VectorN};
/// ///
/// See https://arxiv.org/pdf/1401.5766.pdf /// See https://arxiv.org/pdf/1401.5766.pdf
pub fn balance_parlett_reinsch<N: RealField, D: Dim>(m: &mut MatrixN<N, D>) -> VectorN<N, D> pub fn balance_parlett_reinsch<N: RealField, D: Dim>(m: &mut MatrixN<N, D>) -> VectorN<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> { where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{
assert!(m.is_square(), "Unable to balance a non-square matrix."); assert!(m.is_square(), "Unable to balance a non-square matrix.");
let dim = m.data.shape().0; let dim = m.data.shape().0;
@ -65,7 +67,9 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> {
/// Computes in-place `D * m * D.inverse()`, where `D` is the matrix with diagonal `d`. /// Computes in-place `D * m * D.inverse()`, where `D` is the matrix with diagonal `d`.
pub fn unbalance<N: RealField, D: Dim>(m: &mut MatrixN<N, D>, d: &VectorN<N, D>) pub fn unbalance<N: RealField, D: Dim>(m: &mut MatrixN<N, D>, d: &VectorN<N, D>)
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> { where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
{
assert!(m.is_square(), "Unable to unbalance a non-square matrix."); assert!(m.is_square(), "Unable to unbalance a non-square matrix.");
assert_eq!(m.nrows(), d.len(), "Unbalancing: mismatched dimensions."); assert_eq!(m.nrows(), d.len(), "Unbalancing: mismatched dimensions.");

View File

@ -171,9 +171,11 @@ where
MatrixN<N, DimMinimum<R, C>>, MatrixN<N, DimMinimum<R, C>>,
MatrixMN<N, DimMinimum<R, C>, C>, MatrixMN<N, DimMinimum<R, C>, C>,
) )
where DefaultAllocator: Allocator<N, DimMinimum<R, C>, DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, DimMinimum<R, C>, DimMinimum<R, C>>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<N, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> { + Allocator<N, DimMinimum<R, C>, C>,
{
// FIXME: optimize by calling a reallocator. // FIXME: optimize by calling a reallocator.
(self.u(), self.d(), self.v_t()) (self.u(), self.d(), self.v_t())
} }
@ -181,7 +183,9 @@ where
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition. /// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
#[inline] #[inline]
pub fn d(&self) -> MatrixN<N, DimMinimum<R, C>> pub fn d(&self) -> MatrixN<N, DimMinimum<R, C>>
where DefaultAllocator: Allocator<N, DimMinimum<R, C>, DimMinimum<R, C>> { where
DefaultAllocator: Allocator<N, DimMinimum<R, C>, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.uv.data.shape(); let (nrows, ncols) = self.uv.data.shape();
let d = nrows.min(ncols); let d = nrows.min(ncols);
@ -198,7 +202,9 @@ where
// FIXME: code duplication with householder::assemble_q. // FIXME: code duplication with householder::assemble_q.
// Except that we are returning a rectangular matrix here. // Except that we are returning a rectangular matrix here.
pub fn u(&self) -> MatrixMN<N, R, DimMinimum<R, C>> pub fn u(&self) -> MatrixMN<N, R, DimMinimum<R, C>>
where DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> { where
DefaultAllocator: Allocator<N, R, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.uv.data.shape(); let (nrows, ncols) = self.uv.data.shape();
let mut res = Matrix::identity_generic(nrows, nrows.min(ncols)); let mut res = Matrix::identity_generic(nrows, nrows.min(ncols));
@ -226,7 +232,9 @@ where
/// Computes the orthogonal matrix `V_t` of this `U * D * V_t` decomposition. /// Computes the orthogonal matrix `V_t` of this `U * D * V_t` decomposition.
pub fn v_t(&self) -> MatrixMN<N, DimMinimum<R, C>, C> pub fn v_t(&self) -> MatrixMN<N, DimMinimum<R, C>, C>
where DefaultAllocator: Allocator<N, DimMinimum<R, C>, C> { where
DefaultAllocator: Allocator<N, DimMinimum<R, C>, C>,
{
let (nrows, ncols) = self.uv.data.shape(); let (nrows, ncols) = self.uv.data.shape();
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
@ -259,13 +267,17 @@ where
/// The diagonal part of this decomposed matrix. /// The diagonal part of this decomposed matrix.
pub fn diagonal(&self) -> VectorN<N::RealField, DimMinimum<R, C>> pub fn diagonal(&self) -> VectorN<N::RealField, DimMinimum<R, C>>
where DefaultAllocator: Allocator<N::RealField, DimMinimum<R, C>> { where
DefaultAllocator: Allocator<N::RealField, DimMinimum<R, C>>,
{
self.diagonal.map(|e| e.modulus()) self.diagonal.map(|e| e.modulus())
} }
/// The off-diagonal part of this decomposed matrix. /// The off-diagonal part of this decomposed matrix.
pub fn off_diagonal(&self) -> VectorN<N::RealField, DimDiff<DimMinimum<R, C>, U1>> pub fn off_diagonal(&self) -> VectorN<N::RealField, DimDiff<DimMinimum<R, C>, U1>>
where DefaultAllocator: Allocator<N::RealField, DimDiff<DimMinimum<R, C>, U1>> { where
DefaultAllocator: Allocator<N::RealField, DimDiff<DimMinimum<R, C>, U1>>,
{
self.off_diagonal.map(|e| e.modulus()) self.off_diagonal.map(|e| e.modulus())
} }

View File

@ -24,7 +24,8 @@ use crate::storage::{Storage, StorageMut};
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Cholesky<N: ComplexField, D: Dim> pub struct Cholesky<N: ComplexField, D: Dim>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
chol: MatrixN<N, D>, chol: MatrixN<N, D>,
} }
@ -37,7 +38,8 @@ where
} }
impl<N: ComplexField, D: DimSub<Dynamic>> Cholesky<N, D> impl<N: ComplexField, D: DimSub<Dynamic>> Cholesky<N, D>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Attempts to compute the Cholesky decomposition of `matrix`. /// Attempts to compute the Cholesky decomposition of `matrix`.
/// ///
@ -325,7 +327,8 @@ where DefaultAllocator: Allocator<N, D, D>
} }
impl<N: ComplexField, D: DimSub<Dynamic>, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<N: ComplexField, D: DimSub<Dynamic>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where DefaultAllocator: Allocator<N, D, D> where
DefaultAllocator: Allocator<N, D, D>,
{ {
/// Attempts to compute the Cholesky decomposition of this matrix. /// Attempts to compute the Cholesky decomposition of this matrix.
/// ///

View File

@ -64,7 +64,10 @@ impl<N: RealField, D1: Dim, S1: Storage<N, D1>> Vector<N, D1, S1> {
/// # Errors /// # Errors
/// Inputs must satisfy `self.len() >= kernel.len() > 0`. /// Inputs must satisfy `self.len() >= kernel.len() > 0`.
/// ///
pub fn convolve_valid<D2, S2>(&self, kernel: Vector<N, D2, S2>) -> VectorN<N, DimDiff<DimSum<D1, U1>, D2>> pub fn convolve_valid<D2, S2>(
&self,
kernel: Vector<N, D2, S2>,
) -> VectorN<N, DimDiff<DimSum<D1, U1>, D2>>
where where
D1: DimAdd<U1>, D1: DimAdd<U1>,
D2: Dim, D2: Dim,

View File

@ -13,7 +13,9 @@ impl<N: ComplexField, D: DimMin<D, Output = D>, S: Storage<N, D, D>> SquareMatri
/// If the matrix has a dimension larger than 3, an LU decomposition is used. /// If the matrix has a dimension larger than 3, an LU decomposition is used.
#[inline] #[inline]
pub fn determinant(&self) -> N pub fn determinant(&self) -> N
where DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D> { where
DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D>,
{
assert!( assert!(
self.is_square(), self.is_square(),
"Unable to compute the determinant of a non-square matrix." "Unable to compute the determinant of a non-square matrix."

View File

@ -29,7 +29,8 @@ use crate::linalg::PermutationSequence;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FullPivLU<N: ComplexField, R: DimMin<C>, C: Dim> pub struct FullPivLU<N: ComplexField, R: DimMin<C>, C: Dim>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
lu: MatrixMN<N, R, C>, lu: MatrixMN<N, R, C>,
p: PermutationSequence<DimMinimum<R, C>>, p: PermutationSequence<DimMinimum<R, C>>,
@ -45,7 +46,8 @@ where
} }
impl<N: ComplexField, R: DimMin<C>, C: Dim> FullPivLU<N, R, C> impl<N: ComplexField, R: DimMin<C>, C: Dim> FullPivLU<N, R, C>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with full pivoting of `matrix`. /// Computes the LU decomposition with full pivoting of `matrix`.
/// ///
@ -103,7 +105,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
/// The lower triangular matrix of this decomposition. /// The lower triangular matrix of this decomposition.
#[inline] #[inline]
pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>> pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>>
where DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> { where
DefaultAllocator: Allocator<N, R, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut m = self.lu.columns_generic(0, nrows.min(ncols)).into_owned(); let mut m = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
m.fill_upper_triangle(N::zero(), 1); m.fill_upper_triangle(N::zero(), 1);
@ -114,7 +118,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
/// The upper triangular matrix of this decomposition. /// The upper triangular matrix of this decomposition.
#[inline] #[inline]
pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C> pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C>
where DefaultAllocator: Allocator<N, DimMinimum<R, C>, C> { where
DefaultAllocator: Allocator<N, DimMinimum<R, C>, C>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
self.lu.rows_generic(0, nrows.min(ncols)).upper_triangle() self.lu.rows_generic(0, nrows.min(ncols)).upper_triangle()
} }
@ -141,7 +147,8 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
MatrixMN<N, DimMinimum<R, C>, C>, MatrixMN<N, DimMinimum<R, C>, C>,
PermutationSequence<DimMinimum<R, C>>, PermutationSequence<DimMinimum<R, C>>,
) )
where DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> + Allocator<N, DimMinimum<R, C>, C> where
DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> + Allocator<N, DimMinimum<R, C>, C>,
{ {
// Use reallocation for either l or u. // Use reallocation for either l or u.
let l = self.l(); let l = self.l();
@ -154,7 +161,8 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
} }
impl<N: ComplexField, D: DimMin<D, Output = D>> FullPivLU<N, D, D> impl<N: ComplexField, D: DimMin<D, Output = D>> FullPivLU<N, D, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D> where
DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D>,
{ {
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined. /// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
/// ///
@ -259,7 +267,8 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D>
} }
impl<N: ComplexField, R: DimMin<C>, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> impl<N: ComplexField, R: DimMin<C>, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with full pivoting of `matrix`. /// Computes the LU decomposition with full pivoting of `matrix`.
/// ///

View File

@ -27,7 +27,8 @@ use crate::linalg::householder;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hessenberg<N: ComplexField, D: DimSub<U1>> pub struct Hessenberg<N: ComplexField, D: DimSub<U1>>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
{ {
hess: MatrixN<N, D>, hess: MatrixN<N, D>,
subdiag: VectorN<N, DimDiff<D, U1>>, subdiag: VectorN<N, DimDiff<D, U1>>,
@ -42,7 +43,8 @@ where
} }
impl<N: ComplexField, D: DimSub<U1>> Hessenberg<N, D> impl<N: ComplexField, D: DimSub<U1>> Hessenberg<N, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> + Allocator<N, DimDiff<D, U1>>,
{ {
/// Computes the Hessenberg decomposition using householder reflections. /// Computes the Hessenberg decomposition using householder reflections.
pub fn new(hess: MatrixN<N, D>) -> Self { pub fn new(hess: MatrixN<N, D>) -> Self {
@ -131,7 +133,8 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> + Allocator<N, DimD
} }
impl<N: ComplexField, D: DimSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<N: ComplexField, D: DimSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> + Allocator<N, DimDiff<D, U1>> where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D> + Allocator<N, DimDiff<D, U1>>,
{ {
/// Computes the Hessenberg decomposition of this matrix using householder reflections. /// Computes the Hessenberg decomposition of this matrix using householder reflections.
pub fn hessenberg(self) -> Hessenberg<N, D> { pub fn hessenberg(self) -> Hessenberg<N, D> {

View File

@ -109,7 +109,9 @@ pub fn clear_row_unchecked<N: ComplexField, R: Dim, C: Dim>(
/// matrices. /// matrices.
#[doc(hidden)] #[doc(hidden)]
pub fn assemble_q<N: ComplexField, D: Dim>(m: &MatrixN<N, D>, signs: &[N]) -> MatrixN<N, D> pub fn assemble_q<N: ComplexField, D: Dim>(m: &MatrixN<N, D>, signs: &[N]) -> MatrixN<N, D>
where DefaultAllocator: Allocator<N, D, D> { where
DefaultAllocator: Allocator<N, D, D>,
{
assert!(m.is_square()); assert!(m.is_square());
let dim = m.data.shape().0; let dim = m.data.shape().0;

View File

@ -12,7 +12,9 @@ impl<N: ComplexField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> {
#[inline] #[inline]
#[must_use = "Did you mean to use try_inverse_mut()?"] #[must_use = "Did you mean to use try_inverse_mut()?"]
pub fn try_inverse(self) -> Option<MatrixN<N, D>> pub fn try_inverse(self) -> Option<MatrixN<N, D>>
where DefaultAllocator: Allocator<N, D, D> { where
DefaultAllocator: Allocator<N, D, D>,
{
let mut me = self.into_owned(); let mut me = self.into_owned();
if me.try_inverse_mut() { if me.try_inverse_mut() {
Some(me) Some(me)
@ -27,7 +29,9 @@ impl<N: ComplexField, D: Dim, S: StorageMut<N, D, D>> SquareMatrix<N, D, S> {
/// inversion fails. /// inversion fails.
#[inline] #[inline]
pub fn try_inverse_mut(&mut self) -> bool pub fn try_inverse_mut(&mut self) -> bool
where DefaultAllocator: Allocator<N, D, D> { where
DefaultAllocator: Allocator<N, D, D>,
{
assert!(self.is_square(), "Unable to invert a non-square matrix."); assert!(self.is_square(), "Unable to invert a non-square matrix.");
let dim = self.shape().0; let dim = self.shape().0;

View File

@ -29,7 +29,8 @@ use crate::linalg::PermutationSequence;
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LU<N: ComplexField, R: DimMin<C>, C: Dim> pub struct LU<N: ComplexField, R: DimMin<C>, C: Dim>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
lu: MatrixMN<N, R, C>, lu: MatrixMN<N, R, C>,
p: PermutationSequence<DimMinimum<R, C>>, p: PermutationSequence<DimMinimum<R, C>>,
@ -84,7 +85,8 @@ where
} }
impl<N: ComplexField, R: DimMin<C>, C: Dim> LU<N, R, C> impl<N: ComplexField, R: DimMin<C>, C: Dim> LU<N, R, C>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with partial (row) pivoting of `matrix`. /// Computes the LU decomposition with partial (row) pivoting of `matrix`.
pub fn new(mut matrix: MatrixMN<N, R, C>) -> Self { pub fn new(mut matrix: MatrixMN<N, R, C>) -> Self {
@ -126,7 +128,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
/// The lower triangular matrix of this decomposition. /// The lower triangular matrix of this decomposition.
#[inline] #[inline]
pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>> pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>>
where DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> { where
DefaultAllocator: Allocator<N, R, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut m = self.lu.columns_generic(0, nrows.min(ncols)).into_owned(); let mut m = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
m.fill_upper_triangle(N::zero(), 1); m.fill_upper_triangle(N::zero(), 1);
@ -141,7 +145,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
MatrixMN<N, R, DimMinimum<R, C>>, MatrixMN<N, R, DimMinimum<R, C>>,
PermutationSequence<DimMinimum<R, C>>, PermutationSequence<DimMinimum<R, C>>,
) )
where DefaultAllocator: Reallocator<N, R, C, R, DimMinimum<R, C>> { where
DefaultAllocator: Reallocator<N, R, C, R, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut m = self.lu.resize_generic(nrows, nrows.min(ncols), N::zero()); let mut m = self.lu.resize_generic(nrows, nrows.min(ncols), N::zero());
m.fill_upper_triangle(N::zero(), 1); m.fill_upper_triangle(N::zero(), 1);
@ -152,7 +158,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
/// The lower triangular matrix of this decomposition. /// The lower triangular matrix of this decomposition.
#[inline] #[inline]
pub fn l_unpack(self) -> MatrixMN<N, R, DimMinimum<R, C>> pub fn l_unpack(self) -> MatrixMN<N, R, DimMinimum<R, C>>
where DefaultAllocator: Reallocator<N, R, C, R, DimMinimum<R, C>> { where
DefaultAllocator: Reallocator<N, R, C, R, DimMinimum<R, C>>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut m = self.lu.resize_generic(nrows, nrows.min(ncols), N::zero()); let mut m = self.lu.resize_generic(nrows, nrows.min(ncols), N::zero());
m.fill_upper_triangle(N::zero(), 1); m.fill_upper_triangle(N::zero(), 1);
@ -163,7 +171,9 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
/// The upper triangular matrix of this decomposition. /// The upper triangular matrix of this decomposition.
#[inline] #[inline]
pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C> pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C>
where DefaultAllocator: Allocator<N, DimMinimum<R, C>, C> { where
DefaultAllocator: Allocator<N, DimMinimum<R, C>, C>,
{
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
self.lu.rows_generic(0, nrows.min(ncols)).upper_triangle() self.lu.rows_generic(0, nrows.min(ncols)).upper_triangle()
} }
@ -183,9 +193,11 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
MatrixMN<N, R, DimMinimum<R, C>>, MatrixMN<N, R, DimMinimum<R, C>>,
MatrixMN<N, DimMinimum<R, C>, C>, MatrixMN<N, DimMinimum<R, C>, C>,
) )
where DefaultAllocator: Allocator<N, R, DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<N, DimMinimum<R, C>, C>
+ Reallocator<N, R, C, R, DimMinimum<R, C>> { + Reallocator<N, R, C, R, DimMinimum<R, C>>,
{
// Use reallocation for either l or u. // Use reallocation for either l or u.
let u = self.u(); let u = self.u();
let (l, p) = self.l_unpack_with_p(); let (l, p) = self.l_unpack_with_p();
@ -195,7 +207,8 @@ where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimu
} }
impl<N: ComplexField, D: DimMin<D, Output = D>> LU<N, D, D> impl<N: ComplexField, D: DimMin<D, Output = D>> LU<N, D, D>
where DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D> where
DefaultAllocator: Allocator<N, D, D> + Allocator<(usize, usize), D>,
{ {
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined. /// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
/// ///
@ -368,7 +381,8 @@ pub fn gauss_step_swap<N, R: Dim, C: Dim, S>(
} }
impl<N: ComplexField, R: DimMin<C>, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> impl<N: ComplexField, R: DimMin<C>, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
where DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>> where
DefaultAllocator: Allocator<N, R, C> + Allocator<(usize, usize), DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with partial (row) pivoting of `matrix`. /// Computes the LU decomposition with partial (row) pivoting of `matrix`.
pub fn lu(self) -> LU<N, R, C> { pub fn lu(self) -> LU<N, R, C> {

Some files were not shown because too many files have changed in this diff Show More