extern crate rand; #[cfg(feature="generic_sizes")] extern crate typenum; extern crate nalgebra as na; use rand::random; use na::{Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, Matrix3, Rotation2, Rotation3, Iterable, IterableMut}; #[cfg(feature="generic_sizes")] use typenum::U10; #[cfg(feature="generic_sizes")] use na::VectorN; macro_rules! test_iterator_impl( ($t: ty, $n: ty) => ( for _ in 0usize .. 10000 { let v: $t = random(); let mut mv: $t = v.clone(); let n: $n = random(); let nv: $t = v.iter().map(|e| *e * n).collect(); for e in mv.iter_mut() { *e = *e * n } assert!(nv == mv && nv == v * n); } ) ); macro_rules! test_commut_dot_impl( ($t: ty) => ( for _ in 0usize .. 10000 { let v1 : $t = random(); let v2 : $t = random(); assert!(na::approx_eq(&na::dot(&v1, &v2), &na::dot(&v2, &v1))); } ); ); macro_rules! test_scalar_op_impl( ($t: ty, $n: ty) => ( for _ in 0usize .. 10000 { let v1 : $t = random(); let n : $n = random(); assert!(na::approx_eq(&((v1 * n) / n), &v1)); assert!(na::approx_eq(&((v1 / n) * n), &v1)); assert!(na::approx_eq(&((v1 - n) + n), &v1)); assert!(na::approx_eq(&((v1 + n) - n), &v1)); let mut v1 : $t = random(); let v0 : $t = v1.clone(); let n : $n = random(); v1 = v1 * n; v1 = v1 / n; assert!(na::approx_eq(&v1, &v0)); } ); ); macro_rules! test_basis_impl( ($t: ty) => ( for _ in 0usize .. 10000 { na::canonical_basis(|e1: $t| { na::canonical_basis(|e2: $t| { assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero())); true }); assert!(na::approx_eq(&na::norm(&e1), &na::one())); true }) } ); ); macro_rules! test_subspace_basis_impl( ($t: ty) => ( for _ in 0usize .. 10000 { let v : $t = random(); let v1 = na::normalize(&v); na::orthonormal_subspace_basis(&v1, |e1| { // check vectors are orthogonal to v1 assert!(na::approx_eq(&na::dot(&v1, &e1), &na::zero())); // check vectors form an orthonormal basis assert!(na::approx_eq(&na::norm(&e1), &na::one())); // check vectors form an ortogonal basis na::orthonormal_subspace_basis(&v1, |e2| { assert!(e1 == e2 || na::approx_eq(&na::dot(&e1, &e2), &na::zero())); true }); true }) } ); ); #[test] fn test_cross_vec3() { for _ in 0usize .. 10000 { let v1 : Vector3 = random(); let v2 : Vector3 = random(); let v3 : Vector3 = na::cross(&v1, &v2); assert!(na::approx_eq(&na::dot(&v3, &v2), &na::zero())); assert!(na::approx_eq(&na::dot(&v3, &v1), &na::zero())); } } #[test] fn test_commut_dot_vec1() { test_commut_dot_impl!(Vector1); } #[test] fn test_commut_dot_vec2() { test_commut_dot_impl!(Vector2); } #[test] fn test_commut_dot_vec3() { test_commut_dot_impl!(Vector3); } #[test] fn test_commut_dot_vec4() { test_commut_dot_impl!(Vector4); } #[test] fn test_commut_dot_vec5() { test_commut_dot_impl!(Vector5); } #[test] fn test_commut_dot_vec6() { test_commut_dot_impl!(Vector6); } #[test] fn test_basis_vec1() { test_basis_impl!(Vector1); } #[test] fn test_basis_vec2() { test_basis_impl!(Vector2); } #[test] fn test_basis_vec3() { test_basis_impl!(Vector3); } #[test] fn test_basis_vec4() { test_basis_impl!(Vector4); } #[test] fn test_basis_vec5() { test_basis_impl!(Vector5); } #[test] fn test_basis_vec6() { test_basis_impl!(Vector6); } #[test] fn test_subspace_basis_vec1() { test_subspace_basis_impl!(Vector1); } #[test] fn test_subspace_basis_vec2() { test_subspace_basis_impl!(Vector2); } #[test] fn test_subspace_basis_vec3() { test_subspace_basis_impl!(Vector3); } #[test] fn test_subspace_basis_vec4() { test_subspace_basis_impl!(Vector4); } #[test] fn test_subspace_basis_vec5() { test_subspace_basis_impl!(Vector5); } #[test] fn test_subspace_basis_vec6() { test_subspace_basis_impl!(Vector6); } #[test] fn test_scalar_op_vec1() { test_scalar_op_impl!(Vector1, f64); } #[test] fn test_scalar_op_vec2() { test_scalar_op_impl!(Vector2, f64); } #[test] fn test_scalar_op_vec3() { test_scalar_op_impl!(Vector3, f64); } #[test] fn test_scalar_op_vec4() { test_scalar_op_impl!(Vector4, f64); } #[test] fn test_scalar_op_vec5() { test_scalar_op_impl!(Vector5, f64); } #[test] fn test_scalar_op_vec6() { test_scalar_op_impl!(Vector6, f64); } #[test] fn test_iterator_vec1() { test_iterator_impl!(Vector1, f64); } #[test] fn test_iterator_vec2() { test_iterator_impl!(Vector2, f64); } #[test] fn test_iterator_vec3() { test_iterator_impl!(Vector3, f64); } #[test] fn test_iterator_vec4() { test_iterator_impl!(Vector4, f64); } #[test] fn test_iterator_vec5() { test_iterator_impl!(Vector5, f64); } #[test] fn test_iterator_vec6() { test_iterator_impl!(Vector6, f64); } #[test] fn test_ord_vec3() { // equality assert!(Vector3::new(0.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5)); assert!(!(Vector3::new(1.5f64, 0.5, 0.5) == Vector3::new(0.5, 0.5, 0.5))); assert!(Vector3::new(1.5f64, 0.5, 0.5) != Vector3::new(0.5, 0.5, 0.5)); // comparable assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_le()); assert!(na::partial_cmp(&Vector3::new(0.5f64, 0.3, 0.3), &Vector3::new(1.0, 2.0, 1.0)).is_lt()); assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_ge()); assert!(na::partial_cmp(&Vector3::new(2.0f64, 4.0, 2.0), &Vector3::new(1.0, 2.0, 1.0)).is_gt()); // not comparable assert!(na::partial_cmp(&Vector3::new(0.0f64, 3.0, 0.0), &Vector3::new(1.0, 2.0, 1.0)).is_not_comparable()); } #[test] fn test_min_max_vec3() { assert_eq!(na::sup(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(3.0, 2.0, 3.0)); assert_eq!(na::inf(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(3.0, 2.0, 1.0)), Vector3::new(1.0, 2.0, 1.0)); } #[test] fn test_outer_vec3() { assert_eq!( na::outer(&Vector3::new(1.0f64, 2.0, 3.0), &Vector3::new(4.0, 5.0, 6.0)), Matrix3::new( 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 12.0, 15.0, 18.0)); } #[cfg(feature="generic_sizes")] #[test] fn test_vecn10_add_mul() { for _ in 0usize .. 10000 { let v1: VectorN = random(); assert!(na::approx_eq(&(v1 + v1), &(v1 * 2.0))) } } #[test] fn test_vec3_rotation_between() { for _ in 0usize .. 10000 { let v1: Vector3 = random(); let mut v2: Vector3 = random(); v2 = na::normalize(&v2) * na::norm(&v1); let rotation = na::rotation_between(&v1, &v2); assert!(na::approx_eq(&(rotation * v1), &v2)) } } #[test] fn test_vec3_angle_between() { for _ in 0usize .. 10000 { let vector: Vector3 = random(); let other: Vector3 = random(); // Ensure the axis we are using is orthogonal to `vector`. let axis_ang = na::cross(&vector, &other); let ang = na::norm(&axis_ang); let rotation = Rotation3::new(axis_ang); let delta = na::angle_between(&vector, &(rotation * vector)); assert!(na::approx_eq(&ang, &delta)) } } #[test] fn test_vec2_rotation_between() { for _ in 0usize .. 10000 { let v1: Vector2 = random(); let mut v2: Vector2 = random(); v2 = na::normalize(&v2) * na::norm(&v1); let rotation = na::rotation_between(&v1, &v2); assert!(na::approx_eq(&(rotation * v1), &v2)) } } #[test] fn test_vec2_angle_between() { for _ in 0usize .. 10000 { let axis_ang: Vector1 = random(); let ang = na::norm(&axis_ang); let rotation: Rotation2 = Rotation2::new(axis_ang); let vector: Vector2 = random(); let delta = na::angle_between(&vector, &(rotation * vector)); assert!(na::approx_eq(&ang, &delta)) } }