Remove the Copy requirement from SimdRealField.

This commit is contained in:
Sébastien Crozet 2021-08-04 17:34:25 +02:00
parent 107b3bedb4
commit dd6c40016e
82 changed files with 1420 additions and 1295 deletions

View File

@ -76,12 +76,7 @@ pub fn mat2_to_mat3<T: Number>(m: &TMat2<T>) -> TMat3<T> {
/// Converts a 3x3 matrix to a 2x2 matrix. /// Converts a 3x3 matrix to a 2x2 matrix.
pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> { pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> {
TMat2::new( TMat2::new(m.m11.clone(), m.m12.clone(), m.m21.clone(), m.m22.clone())
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.
@ -97,15 +92,15 @@ pub fn mat3_to_mat4<T: Number>(m: &TMat3<T>) -> TMat4<T> {
/// Converts a 4x4 matrix to a 3x3 matrix. /// Converts a 4x4 matrix to a 3x3 matrix.
pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> { pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> {
TMat3::new( TMat3::new(
m.m11.inlined_clone(), m.m11.clone(),
m.m12.inlined_clone(), m.m12.clone(),
m.m13.inlined_clone(), m.m13.clone(),
m.m21.inlined_clone(), m.m21.clone(),
m.m22.inlined_clone(), m.m22.clone(),
m.m23.inlined_clone(), m.m23.clone(),
m.m31.inlined_clone(), m.m31.clone(),
m.m32.inlined_clone(), m.m32.clone(),
m.m33.inlined_clone(), m.m33.clone(),
) )
} }
@ -121,12 +116,7 @@ pub fn mat2_to_mat4<T: Number>(m: &TMat2<T>) -> TMat4<T> {
/// Converts a 4x4 matrix to a 2x2 matrix. /// Converts a 4x4 matrix to a 2x2 matrix.
pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> { pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> {
TMat2::new( TMat2::new(m.m11.clone(), m.m12.clone(), m.m21.clone(), m.m22.clone())
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]`.
@ -156,7 +146,7 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> { pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.clone())
} }
/// Creates a 1D vector from another vector. /// Creates a 1D vector from another vector.
@ -170,7 +160,7 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> { pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.clone())
} }
/// Creates a 1D vector from another vector. /// Creates a 1D vector from another vector.
@ -184,7 +174,7 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> { pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.clone())
} }
/// Creates a 2D vector from another vector. /// Creates a 2D vector from another vector.
@ -200,7 +190,7 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> { pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), T::zero()) TVec2::new(v.x.clone(), T::zero())
} }
/// Creates a 2D vector from another vector. /// Creates a 2D vector from another vector.
@ -229,7 +219,7 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> { pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
/// Creates a 2D vector from another vector. /// Creates a 2D vector from another vector.
@ -243,7 +233,7 @@ pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> { pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
/// Creates a 2D vector from a slice. /// Creates a 2D vector from a slice.
@ -269,7 +259,7 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> { pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
TVec3::new(v.x.inlined_clone(), T::zero(), T::zero()) TVec3::new(v.x.clone(), T::zero(), T::zero())
} }
/// Creates a 3D vector from another vector. /// Creates a 3D vector from another vector.
@ -285,7 +275,7 @@ pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
/// * [`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 vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> { pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), T::zero()) TVec3::new(v.x.clone(), v.y.clone(), T::zero())
} }
/// Creates a 3D vector from another vector. /// Creates a 3D vector from another vector.
@ -313,11 +303,7 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
/// * [`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<T: Scalar>(v: &TVec4<T>) -> TVec3<T> { pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
TVec3::new( TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
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.

View File

@ -30,7 +30,7 @@ where
// We use the fact that matrix iteration is guaranteed to be column-major // We use the fact that matrix iteration is guaranteed to be column-major
let i = index % dense.nrows(); let i = index % dense.nrows();
let j = index / dense.nrows(); let j = index / dense.nrows();
coo.push(i, j, v.inlined_clone()); coo.push(i, j, v.clone());
} }
} }
@ -44,7 +44,7 @@ where
{ {
let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero()); let mut output = DMatrix::repeat(coo.nrows(), coo.ncols(), T::zero());
for (i, j, v) in coo.triplet_iter() { for (i, j, v) in coo.triplet_iter() {
output[(i, j)] += v.inlined_clone(); output[(i, j)] += v.clone();
} }
output output
} }
@ -71,7 +71,7 @@ where
pub fn convert_csr_coo<T: Scalar>(csr: &CsrMatrix<T>) -> CooMatrix<T> { pub fn convert_csr_coo<T: Scalar>(csr: &CsrMatrix<T>) -> CooMatrix<T> {
let mut result = CooMatrix::new(csr.nrows(), csr.ncols()); let mut result = CooMatrix::new(csr.nrows(), csr.ncols());
for (i, j, v) in csr.triplet_iter() { for (i, j, v) in csr.triplet_iter() {
result.push(i, j, v.inlined_clone()); result.push(i, j, v.clone());
} }
result result
} }
@ -84,7 +84,7 @@ where
let mut output = DMatrix::zeros(csr.nrows(), csr.ncols()); let mut output = DMatrix::zeros(csr.nrows(), csr.ncols());
for (i, j, v) in csr.triplet_iter() { for (i, j, v) in csr.triplet_iter() {
output[(i, j)] += v.inlined_clone(); output[(i, j)] += v.clone();
} }
output output
@ -111,7 +111,7 @@ where
let v = dense.index((i, j)); let v = dense.index((i, j));
if v != &T::zero() { if v != &T::zero() {
col_idx.push(j); col_idx.push(j);
values.push(v.inlined_clone()); values.push(v.clone());
} }
} }
row_offsets.push(col_idx.len()); row_offsets.push(col_idx.len());
@ -148,7 +148,7 @@ where
{ {
let mut coo = CooMatrix::new(csc.nrows(), csc.ncols()); let mut coo = CooMatrix::new(csc.nrows(), csc.ncols());
for (i, j, v) in csc.triplet_iter() { for (i, j, v) in csc.triplet_iter() {
coo.push(i, j, v.inlined_clone()); coo.push(i, j, v.clone());
} }
coo coo
} }
@ -161,7 +161,7 @@ where
let mut output = DMatrix::zeros(csc.nrows(), csc.ncols()); let mut output = DMatrix::zeros(csc.nrows(), csc.ncols());
for (i, j, v) in csc.triplet_iter() { for (i, j, v) in csc.triplet_iter() {
output[(i, j)] += v.inlined_clone(); output[(i, j)] += v.clone();
} }
output output
@ -185,7 +185,7 @@ where
let v = dense.index((i, j)); let v = dense.index((i, j));
if v != &T::zero() { if v != &T::zero() {
row_idx.push(i); row_idx.push(i);
values.push(v.inlined_clone()); values.push(v.clone());
} }
} }
col_offsets.push(row_idx.len()); col_offsets.push(row_idx.len());

View File

@ -522,7 +522,7 @@ where
let entry_offset = target_offsets[source_minor_idx] + *target_lane_count; let entry_offset = target_offsets[source_minor_idx] + *target_lane_count;
target_indices[entry_offset] = source_major_idx; target_indices[entry_offset] = source_major_idx;
unsafe { unsafe {
target_values.set(entry_offset, val.inlined_clone()); target_values.set(entry_offset, val.clone());
} }
*target_lane_count += 1; *target_lane_count += 1;
} }

View File

@ -225,7 +225,7 @@ impl<T: RealField> CscCholesky<T> {
let col_j_entries = col_j.row_indices().iter().zip(col_j.values()); let col_j_entries = col_j.row_indices().iter().zip(col_j.values());
for (&z, val) in col_j_entries { for (&z, val) in col_j_entries {
if z >= k { if z >= k {
*self.work_x.get_unchecked_mut(z) += val.inlined_clone() * factor; *self.work_x.get_unchecked_mut(z) += val.clone() * factor;
} }
} }
} }

View File

@ -141,7 +141,7 @@ macro_rules! impl_scalar_mul {
impl_mul!(<'a, T>(a: &'a $matrix_type<T>, b: &'a T) -> $matrix_type<T> { impl_mul!(<'a, T>(a: &'a $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
let values: Vec<_> = a.values() let values: Vec<_> = a.values()
.iter() .iter()
.map(|v_i| v_i.inlined_clone() * b.inlined_clone()) .map(|v_i| v_i.clone() * b.clone())
.collect(); .collect();
$matrix_type::try_from_pattern_and_values(a.pattern().clone(), values).unwrap() $matrix_type::try_from_pattern_and_values(a.pattern().clone(), values).unwrap()
}); });
@ -151,7 +151,7 @@ macro_rules! impl_scalar_mul {
impl_mul!(<'a, T>(a: $matrix_type<T>, b: &'a T) -> $matrix_type<T> { impl_mul!(<'a, T>(a: $matrix_type<T>, b: &'a T) -> $matrix_type<T> {
let mut a = a; let mut a = a;
for value in a.values_mut() { for value in a.values_mut() {
*value = b.inlined_clone() * value.inlined_clone(); *value = b.clone() * value.clone();
} }
a a
}); });
@ -168,7 +168,7 @@ macro_rules! impl_scalar_mul {
{ {
fn mul_assign(&mut self, scalar: T) { fn mul_assign(&mut self, scalar: T) {
for val in self.values_mut() { for val in self.values_mut() {
*val *= scalar.inlined_clone(); *val *= scalar.clone();
} }
} }
} }
@ -179,7 +179,7 @@ macro_rules! impl_scalar_mul {
{ {
fn mul_assign(&mut self, scalar: &'a T) { fn mul_assign(&mut self, scalar: &'a T) {
for val in self.values_mut() { for val in self.values_mut() {
*val *= scalar.inlined_clone(); *val *= scalar.clone();
} }
} }
} }
@ -199,7 +199,7 @@ macro_rules! impl_neg {
fn neg(mut self) -> Self::Output { fn neg(mut self) -> Self::Output {
for v_i in self.values_mut() { for v_i in self.values_mut() {
*v_i = -v_i.inlined_clone(); *v_i = -v_i.clone();
} }
self self
} }
@ -233,25 +233,25 @@ macro_rules! impl_div {
matrix matrix
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: $matrix_type<T>, scalar: &T) -> $matrix_type<T> {
matrix / scalar.inlined_clone() matrix / scalar.clone()
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: T) -> $matrix_type<T> {
let new_values = matrix.values() let new_values = matrix.values()
.iter() .iter()
.map(|v_i| v_i.inlined_clone() / scalar.inlined_clone()) .map(|v_i| v_i.clone() / scalar.clone())
.collect(); .collect();
$matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values) $matrix_type::try_from_pattern_and_values(matrix.pattern().clone(), new_values)
.unwrap() .unwrap()
}); });
impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> { impl_bin_op!(Div, div, <'a, T: ClosedDiv>(matrix: &'a $matrix_type<T>, scalar: &'a T) -> $matrix_type<T> {
matrix / scalar.inlined_clone() matrix / scalar.clone()
}); });
impl<T> DivAssign<T> for $matrix_type<T> impl<T> DivAssign<T> for $matrix_type<T>
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
{ {
fn div_assign(&mut self, scalar: T) { fn div_assign(&mut self, scalar: T) {
self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.inlined_clone()); self.values_mut().iter_mut().for_each(|v_i| *v_i /= scalar.clone());
} }
} }
@ -259,7 +259,7 @@ macro_rules! impl_div {
where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One where T : Scalar + ClosedAdd + ClosedMul + ClosedDiv + Zero + One
{ {
fn div_assign(&mut self, scalar: &'a T) { fn div_assign(&mut self, scalar: &'a T) {
*self /= scalar.inlined_clone(); *self /= scalar.clone();
} }
} }
} }

View File

@ -34,13 +34,13 @@ where
let a_lane_i = a.get_lane(i).unwrap(); let a_lane_i = a.get_lane(i).unwrap();
let mut c_lane_i = c.get_lane_mut(i).unwrap(); let mut c_lane_i = c.get_lane_mut(i).unwrap();
for c_ij in c_lane_i.values_mut() { for c_ij in c_lane_i.values_mut() {
*c_ij = beta.inlined_clone() * c_ij.inlined_clone(); *c_ij = beta.clone() * c_ij.clone();
} }
for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) { for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
let b_lane_k = b.get_lane(k).unwrap(); let b_lane_k = b.get_lane(k).unwrap();
let (mut c_lane_i_cols, mut c_lane_i_values) = c_lane_i.indices_and_values_mut(); let (mut c_lane_i_cols, mut c_lane_i_values) = c_lane_i.indices_and_values_mut();
let alpha_aik = alpha.inlined_clone() * a_ik.inlined_clone(); let alpha_aik = alpha.clone() * a_ik.clone();
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) { for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
// Determine the location in C to append the value // Determine the location in C to append the value
let (c_local_idx, _) = c_lane_i_cols let (c_local_idx, _) = c_lane_i_cols
@ -49,7 +49,7 @@ where
.find(|(_, c_col)| *c_col == j) .find(|(_, c_col)| *c_col == j)
.ok_or_else(spmm_cs_unexpected_entry)?; .ok_or_else(spmm_cs_unexpected_entry)?;
c_lane_i_values[c_local_idx] += alpha_aik.inlined_clone() * b_kj.inlined_clone(); c_lane_i_values[c_local_idx] += alpha_aik.clone() * b_kj.clone();
c_lane_i_cols = &c_lane_i_cols[c_local_idx..]; c_lane_i_cols = &c_lane_i_cols[c_local_idx..];
c_lane_i_values = &mut c_lane_i_values[c_local_idx..]; c_lane_i_values = &mut c_lane_i_values[c_local_idx..];
} }
@ -81,7 +81,7 @@ where
for (mut c_lane_i, a_lane_i) in c.lane_iter_mut().zip(a.lane_iter()) { for (mut c_lane_i, a_lane_i) in c.lane_iter_mut().zip(a.lane_iter()) {
if beta != T::one() { if beta != T::one() {
for c_ij in c_lane_i.values_mut() { for c_ij in c_lane_i.values_mut() {
*c_ij *= beta.inlined_clone(); *c_ij *= beta.clone();
} }
} }
@ -97,7 +97,7 @@ where
.enumerate() .enumerate()
.find(|(_, c_col)| *c_col == a_col) .find(|(_, c_col)| *c_col == a_col)
.ok_or_else(spadd_cs_unexpected_entry)?; .ok_or_else(spadd_cs_unexpected_entry)?;
c_vals[c_idx] += alpha.inlined_clone() * a_val.inlined_clone(); c_vals[c_idx] += alpha.clone() * a_val.clone();
c_minors = &c_minors[c_idx..]; c_minors = &c_minors[c_idx..];
c_vals = &mut c_vals[c_idx..]; c_vals = &mut c_vals[c_idx..];
} }
@ -106,14 +106,14 @@ where
Op::Transpose(a) => { Op::Transpose(a) => {
if beta != T::one() { if beta != T::one() {
for c_ij in c.values_mut() { for c_ij in c.values_mut() {
*c_ij *= beta.inlined_clone(); *c_ij *= beta.clone();
} }
} }
for (i, a_lane_i) in a.lane_iter().enumerate() { for (i, a_lane_i) in a.lane_iter().enumerate() {
for (&j, a_val) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) { for (&j, a_val) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
let a_val = a_val.inlined_clone(); let a_val = a_val.clone();
let alpha = alpha.inlined_clone(); let alpha = alpha.clone();
match c.get_entry_mut(j, i).unwrap() { match c.get_entry_mut(j, i).unwrap() {
SparseEntryMut::NonZero(c_ji) => *c_ji += alpha * a_val, SparseEntryMut::NonZero(c_ji) => *c_ji += alpha * a_val,
SparseEntryMut::Zero => return Err(spadd_cs_unexpected_entry()), SparseEntryMut::Zero => return Err(spadd_cs_unexpected_entry()),
@ -149,10 +149,9 @@ pub fn spmm_cs_dense<T>(
Op::NoOp(ref b) => b.index((k, j)), Op::NoOp(ref b) => b.index((k, j)),
Op::Transpose(ref b) => b.index((j, k)), Op::Transpose(ref b) => b.index((j, k)),
}; };
dot_ij += a_ik.inlined_clone() * b_contrib.inlined_clone(); dot_ij += a_ik.clone() * b_contrib.clone();
} }
*c_ij = beta.inlined_clone() * c_ij.inlined_clone() *c_ij = beta.clone() * c_ij.clone() + alpha.clone() * dot_ij;
+ alpha.inlined_clone() * dot_ij;
} }
} }
} }
@ -163,19 +162,19 @@ pub fn spmm_cs_dense<T>(
for k in 0..a.pattern().major_dim() { for k in 0..a.pattern().major_dim() {
let a_row_k = a.get_lane(k).unwrap(); let a_row_k = a.get_lane(k).unwrap();
for (&i, a_ki) in a_row_k.minor_indices().iter().zip(a_row_k.values()) { for (&i, a_ki) in a_row_k.minor_indices().iter().zip(a_row_k.values()) {
let gamma_ki = alpha.inlined_clone() * a_ki.inlined_clone(); let gamma_ki = alpha.clone() * a_ki.clone();
let mut c_row_i = c.row_mut(i); let mut c_row_i = c.row_mut(i);
match b { match b {
Op::NoOp(ref b) => { Op::NoOp(ref b) => {
let b_row_k = b.row(k); let b_row_k = b.row(k);
for (c_ij, b_kj) in c_row_i.iter_mut().zip(b_row_k.iter()) { for (c_ij, b_kj) in c_row_i.iter_mut().zip(b_row_k.iter()) {
*c_ij += gamma_ki.inlined_clone() * b_kj.inlined_clone(); *c_ij += gamma_ki.clone() * b_kj.clone();
} }
} }
Op::Transpose(ref b) => { Op::Transpose(ref b) => {
let b_col_k = b.column(k); let b_col_k = b.column(k);
for (c_ij, b_jk) in c_row_i.iter_mut().zip(b_col_k.iter()) { for (c_ij, b_jk) in c_row_i.iter_mut().zip(b_col_k.iter()) {
*c_ij += gamma_ki.inlined_clone() * b_jk.inlined_clone(); *c_ij += gamma_ki.clone() * b_jk.clone();
} }
} }
} }

View File

@ -179,7 +179,7 @@ fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
// Note: The remaining entries are below the diagonal // Note: The remaining entries are below the diagonal
for (&i, l_ik) in row_indices.iter().zip(l_values) { for (&i, l_ik) in row_indices.iter().zip(l_values) {
let x_ij = &mut x_col_j[i]; let x_ij = &mut x_col_j[i];
*x_ij -= l_ik.inlined_clone() * x_kj; *x_ij -= l_ik.clone() * x_kj;
} }
x_col_j[k] = x_kj; x_col_j[k] = x_kj;

View File

@ -47,36 +47,36 @@ where
// because the `for` loop below won't be very efficient on those. // because the `for` loop below won't be very efficient on those.
if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) { if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) {
unsafe { unsafe {
let a = conjugate(self.get_unchecked((0, 0)).inlined_clone()) let a = conjugate(self.get_unchecked((0, 0)).clone())
* rhs.get_unchecked((0, 0)).inlined_clone(); * rhs.get_unchecked((0, 0)).clone();
let b = conjugate(self.get_unchecked((1, 0)).inlined_clone()) let b = conjugate(self.get_unchecked((1, 0)).clone())
* rhs.get_unchecked((1, 0)).inlined_clone(); * rhs.get_unchecked((1, 0)).clone();
return a + b; return a + b;
} }
} }
if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) { if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) {
unsafe { unsafe {
let a = conjugate(self.get_unchecked((0, 0)).inlined_clone()) let a = conjugate(self.get_unchecked((0, 0)).clone())
* rhs.get_unchecked((0, 0)).inlined_clone(); * rhs.get_unchecked((0, 0)).clone();
let b = conjugate(self.get_unchecked((1, 0)).inlined_clone()) let b = conjugate(self.get_unchecked((1, 0)).clone())
* rhs.get_unchecked((1, 0)).inlined_clone(); * rhs.get_unchecked((1, 0)).clone();
let c = conjugate(self.get_unchecked((2, 0)).inlined_clone()) let c = conjugate(self.get_unchecked((2, 0)).clone())
* rhs.get_unchecked((2, 0)).inlined_clone(); * rhs.get_unchecked((2, 0)).clone();
return a + b + c; return a + b + c;
} }
} }
if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) { if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) {
unsafe { unsafe {
let mut a = conjugate(self.get_unchecked((0, 0)).inlined_clone()) let mut a = conjugate(self.get_unchecked((0, 0)).clone())
* rhs.get_unchecked((0, 0)).inlined_clone(); * rhs.get_unchecked((0, 0)).clone();
let mut b = conjugate(self.get_unchecked((1, 0)).inlined_clone()) let mut b = conjugate(self.get_unchecked((1, 0)).clone())
* rhs.get_unchecked((1, 0)).inlined_clone(); * rhs.get_unchecked((1, 0)).clone();
let c = conjugate(self.get_unchecked((2, 0)).inlined_clone()) let c = conjugate(self.get_unchecked((2, 0)).clone())
* rhs.get_unchecked((2, 0)).inlined_clone(); * rhs.get_unchecked((2, 0)).clone();
let d = conjugate(self.get_unchecked((3, 0)).inlined_clone()) let d = conjugate(self.get_unchecked((3, 0)).clone())
* rhs.get_unchecked((3, 0)).inlined_clone(); * rhs.get_unchecked((3, 0)).clone();
a += c; a += c;
b += d; b += d;
@ -117,36 +117,36 @@ where
while self.nrows() - i >= 8 { while self.nrows() - i >= 8 {
acc0 += unsafe { acc0 += unsafe {
conjugate(self.get_unchecked((i, j)).inlined_clone()) conjugate(self.get_unchecked((i, j)).clone())
* rhs.get_unchecked((i, j)).inlined_clone() * rhs.get_unchecked((i, j)).clone()
}; };
acc1 += unsafe { acc1 += unsafe {
conjugate(self.get_unchecked((i + 1, j)).inlined_clone()) conjugate(self.get_unchecked((i + 1, j)).clone())
* rhs.get_unchecked((i + 1, j)).inlined_clone() * rhs.get_unchecked((i + 1, j)).clone()
}; };
acc2 += unsafe { acc2 += unsafe {
conjugate(self.get_unchecked((i + 2, j)).inlined_clone()) conjugate(self.get_unchecked((i + 2, j)).clone())
* rhs.get_unchecked((i + 2, j)).inlined_clone() * rhs.get_unchecked((i + 2, j)).clone()
}; };
acc3 += unsafe { acc3 += unsafe {
conjugate(self.get_unchecked((i + 3, j)).inlined_clone()) conjugate(self.get_unchecked((i + 3, j)).clone())
* rhs.get_unchecked((i + 3, j)).inlined_clone() * rhs.get_unchecked((i + 3, j)).clone()
}; };
acc4 += unsafe { acc4 += unsafe {
conjugate(self.get_unchecked((i + 4, j)).inlined_clone()) conjugate(self.get_unchecked((i + 4, j)).clone())
* rhs.get_unchecked((i + 4, j)).inlined_clone() * rhs.get_unchecked((i + 4, j)).clone()
}; };
acc5 += unsafe { acc5 += unsafe {
conjugate(self.get_unchecked((i + 5, j)).inlined_clone()) conjugate(self.get_unchecked((i + 5, j)).clone())
* rhs.get_unchecked((i + 5, j)).inlined_clone() * rhs.get_unchecked((i + 5, j)).clone()
}; };
acc6 += unsafe { acc6 += unsafe {
conjugate(self.get_unchecked((i + 6, j)).inlined_clone()) conjugate(self.get_unchecked((i + 6, j)).clone())
* rhs.get_unchecked((i + 6, j)).inlined_clone() * rhs.get_unchecked((i + 6, j)).clone()
}; };
acc7 += unsafe { acc7 += unsafe {
conjugate(self.get_unchecked((i + 7, j)).inlined_clone()) conjugate(self.get_unchecked((i + 7, j)).clone())
* rhs.get_unchecked((i + 7, j)).inlined_clone() * rhs.get_unchecked((i + 7, j)).clone()
}; };
i += 8; i += 8;
} }
@ -158,8 +158,8 @@ where
for k in i..self.nrows() { for k in i..self.nrows() {
res += unsafe { res += unsafe {
conjugate(self.get_unchecked((k, j)).inlined_clone()) conjugate(self.get_unchecked((k, j)).clone())
* rhs.get_unchecked((k, j)).inlined_clone() * rhs.get_unchecked((k, j)).clone()
} }
} }
} }
@ -266,8 +266,7 @@ where
for j in 0..self.nrows() { for j in 0..self.nrows() {
for i in 0..self.ncols() { for i in 0..self.ncols() {
res += unsafe { res += unsafe {
self.get_unchecked((j, i)).inlined_clone() self.get_unchecked((j, i)).clone() * rhs.get_unchecked((i, j)).clone()
* rhs.get_unchecked((i, j)).inlined_clone()
} }
} }
} }
@ -398,9 +397,9 @@ where
// TODO: avoid bound checks. // TODO: avoid bound checks.
let col2 = a.column(0); let col2 = a.column(0);
let val = unsafe { x.vget_unchecked(0).inlined_clone() }; let val = unsafe { x.vget_unchecked(0).clone() };
self.axpy(alpha.inlined_clone() * val, &col2, beta); self.axpy(alpha.clone() * val, &col2, beta);
self[0] += alpha.inlined_clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..)); self[0] += alpha.clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..));
for j in 1..dim2 { for j in 1..dim2 {
let col2 = a.column(j); let col2 = a.column(j);
@ -408,11 +407,11 @@ where
let val; let val;
unsafe { unsafe {
val = x.vget_unchecked(j).inlined_clone(); val = x.vget_unchecked(j).clone();
*self.vget_unchecked_mut(j) += alpha.inlined_clone() * dot; *self.vget_unchecked_mut(j) += alpha.clone() * dot;
} }
self.rows_range_mut(j + 1..).axpy( self.rows_range_mut(j + 1..).axpy(
alpha.inlined_clone() * val, alpha.clone() * val,
&col2.rows_range(j + 1..), &col2.rows_range(j + 1..),
T::one(), T::one(),
); );
@ -538,13 +537,12 @@ where
if beta.is_zero() { if beta.is_zero() {
for j in 0..ncols2 { for j in 0..ncols2 {
let val = unsafe { self.vget_unchecked_mut(j) }; let val = unsafe { self.vget_unchecked_mut(j) };
*val = alpha.inlined_clone() * dot(&a.column(j), x) *val = alpha.clone() * dot(&a.column(j), x)
} }
} else { } else {
for j in 0..ncols2 { for j in 0..ncols2 {
let val = unsafe { self.vget_unchecked_mut(j) }; let val = unsafe { self.vget_unchecked_mut(j) };
*val = alpha.inlined_clone() * dot(&a.column(j), x) *val = alpha.clone() * dot(&a.column(j), x) + beta.clone() * val.clone();
+ beta.inlined_clone() * val.inlined_clone();
} }
} }
} }
@ -648,9 +646,9 @@ where
for j in 0..ncols1 { for j in 0..ncols1 {
// TODO: avoid bound checks. // TODO: avoid bound checks.
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) }; let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
self.column_mut(j) self.column_mut(j)
.axpy(alpha.inlined_clone() * val, x, beta.inlined_clone()); .axpy(alpha.clone() * val, x, beta.clone());
} }
} }
@ -813,12 +811,8 @@ where
for j1 in 0..ncols1 { for j1 in 0..ncols1 {
// TODO: avoid bound checks. // TODO: avoid bound checks.
self.column_mut(j1).gemv_tr( self.column_mut(j1)
alpha.inlined_clone(), .gemv_tr(alpha.clone(), a, &b.column(j1), beta.clone());
a,
&b.column(j1),
beta.inlined_clone(),
);
} }
} }
@ -875,7 +869,8 @@ where
for j1 in 0..ncols1 { for j1 in 0..ncols1 {
// TODO: avoid bound checks. // TODO: avoid bound checks.
self.column_mut(j1).gemv_ad(alpha, a, &b.column(j1), beta); self.column_mut(j1)
.gemv_ad(alpha.clone(), a, &b.column(j1), beta.clone());
} }
} }
} }
@ -909,13 +904,13 @@ where
assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch."); assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch.");
for j in 0..dim1 { for j in 0..dim1 {
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) }; let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
let subdim = Dynamic::new(dim1 - j); let subdim = Dynamic::new(dim1 - j);
// TODO: avoid bound checks. // TODO: avoid bound checks.
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy( self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
alpha.inlined_clone() * val, alpha.clone() * val,
&x.rows_range(j..), &x.rows_range(j..),
beta.inlined_clone(), beta.clone(),
); );
} }
} }
@ -1076,11 +1071,11 @@ where
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>, ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
{ {
work.gemv(T::one(), lhs, &mid.column(0), T::zero()); work.gemv(T::one(), lhs, &mid.column(0), T::zero());
self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta); self.ger(alpha.clone(), work, &lhs.column(0), beta);
for j in 1..mid.ncols() { for j in 1..mid.ncols() {
work.gemv(T::one(), lhs, &mid.column(j), T::zero()); work.gemv(T::one(), lhs, &mid.column(j), T::zero());
self.ger(alpha.inlined_clone(), work, &lhs.column(j), T::one()); self.ger(alpha.clone(), work, &lhs.column(j), T::one());
} }
} }
@ -1170,12 +1165,12 @@ where
{ {
work.gemv(T::one(), mid, &rhs.column(0), T::zero()); work.gemv(T::one(), mid, &rhs.column(0), T::zero());
self.column_mut(0) self.column_mut(0)
.gemv_tr(alpha.inlined_clone(), rhs, work, beta.inlined_clone()); .gemv_tr(alpha.clone(), rhs, work, beta.clone());
for j in 1..rhs.ncols() { for j in 1..rhs.ncols() {
work.gemv(T::one(), mid, &rhs.column(j), T::zero()); work.gemv(T::one(), mid, &rhs.column(j), T::zero());
self.column_mut(j) self.column_mut(j)
.gemv_tr(alpha.inlined_clone(), rhs, work, beta.inlined_clone()); .gemv_tr(alpha.clone(), rhs, work, beta.clone());
} }
} }

View File

@ -44,8 +44,8 @@ unsafe fn array_axcpy<Status, T>(
{ {
for i in 0..len { for i in 0..len {
let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1)); let y = Status::assume_init_mut(y.get_unchecked_mut(i * stride1));
*y = a.inlined_clone() * x.get_unchecked(i * stride2).inlined_clone() * c.inlined_clone() *y =
+ beta.inlined_clone() * y.inlined_clone(); a.clone() * x.get_unchecked(i * stride2).clone() * c.clone() + beta.clone() * y.clone();
} }
} }
@ -66,9 +66,7 @@ fn array_axc<Status, T>(
unsafe { unsafe {
Status::init( Status::init(
y.get_unchecked_mut(i * stride1), y.get_unchecked_mut(i * stride1),
a.inlined_clone() a.clone() * x.get_unchecked(i * stride2).clone() * c.clone(),
* x.get_unchecked(i * stride2).inlined_clone()
* c.inlined_clone(),
); );
} }
} }
@ -150,24 +148,24 @@ pub unsafe fn gemv_uninit<Status, T, D1: Dim, R2: Dim, C2: Dim, D3: Dim, SA, SB,
y.apply(|e| Status::init(e, T::zero())); y.apply(|e| Status::init(e, T::zero()));
} else { } else {
// SAFETY: this is UB if y is uninitialized. // SAFETY: this is UB if y is uninitialized.
y.apply(|e| *Status::assume_init_mut(e) *= beta.inlined_clone()); y.apply(|e| *Status::assume_init_mut(e) *= beta.clone());
} }
return; return;
} }
// TODO: avoid bound checks. // TODO: avoid bound checks.
let col2 = a.column(0); let col2 = a.column(0);
let val = x.vget_unchecked(0).inlined_clone(); let val = x.vget_unchecked(0).clone();
// SAFETY: this is the call that makes this method unsafe: it is UB if Status = Uninit and beta != 0. // SAFETY: this is the call that makes this method unsafe: it is UB if Status = Uninit and beta != 0.
axcpy_uninit(status, y, alpha.inlined_clone(), &col2, val, beta); axcpy_uninit(status, y, alpha.clone(), &col2, val, beta);
for j in 1..ncols2 { for j in 1..ncols2 {
let col2 = a.column(j); let col2 = a.column(j);
let val = x.vget_unchecked(j).inlined_clone(); let val = x.vget_unchecked(j).clone();
// SAFETY: safe because y was initialized above. // SAFETY: safe because y was initialized above.
axcpy_uninit(status, y, alpha.inlined_clone(), &col2, val, T::one()); axcpy_uninit(status, y, alpha.clone(), &col2, val, T::one());
} }
} }
@ -254,7 +252,7 @@ pub unsafe fn gemm_uninit<
y.apply(|e| Status::init(e, T::zero())); y.apply(|e| Status::init(e, T::zero()));
} else { } else {
// SAFETY: this is UB if Status = Uninit // SAFETY: this is UB if Status = Uninit
y.apply(|e| *Status::assume_init_mut(e) *= beta.inlined_clone()); y.apply(|e| *Status::assume_init_mut(e) *= beta.clone());
} }
return; return;
} }
@ -314,10 +312,10 @@ pub unsafe fn gemm_uninit<
gemv_uninit( gemv_uninit(
status, status,
&mut y.column_mut(j1), &mut y.column_mut(j1),
alpha.inlined_clone(), alpha.clone(),
a, a,
&b.column(j1), &b.column(j1),
beta.inlined_clone(), beta.clone(),
); );
} }
} }

View File

@ -45,7 +45,7 @@ where
{ {
let mut res = Self::identity(); let mut res = Self::identity();
for i in 0..scaling.len() { for i in 0..scaling.len() {
res[(i, i)] = scaling[i].inlined_clone(); res[(i, i)] = scaling[i].clone();
} }
res res
@ -85,13 +85,13 @@ impl<T: RealField> Matrix3<T> {
let zero = T::zero(); let zero = T::zero();
let one = T::one(); let one = T::one();
Matrix3::new( Matrix3::new(
scaling.x, scaling.x.clone(),
zero, zero.clone(),
pt.x - pt.x * scaling.x, pt.x.clone() - pt.x.clone() * scaling.x.clone(),
zero, zero.clone(),
scaling.y, scaling.y.clone(),
pt.y - pt.y * scaling.y, pt.y.clone() - pt.y.clone() * scaling.y.clone(),
zero, zero.clone(),
zero, zero,
one, one,
) )
@ -125,20 +125,20 @@ impl<T: RealField> Matrix4<T> {
let zero = T::zero(); let zero = T::zero();
let one = T::one(); let one = T::one();
Matrix4::new( Matrix4::new(
scaling.x, scaling.x.clone(),
zero, zero.clone(),
zero, zero.clone(),
pt.x - pt.x * scaling.x, pt.x.clone() - pt.x.clone() * scaling.x.clone(),
zero, zero.clone(),
scaling.y, scaling.y.clone(),
zero, zero.clone(),
pt.y - pt.y * scaling.y, pt.y.clone() - pt.y.clone() * scaling.y.clone(),
zero, zero.clone(),
zero, zero.clone(),
scaling.z, scaling.z.clone(),
pt.z - pt.z * scaling.z, pt.z.clone() - pt.z.clone() * scaling.z.clone(),
zero, zero.clone(),
zero, zero.clone(),
zero, zero,
one, one,
) )
@ -336,7 +336,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
{ {
for i in 0..scaling.len() { for i in 0..scaling.len() {
let mut to_scale = self.fixed_rows_mut::<1>(i); let mut to_scale = self.fixed_rows_mut::<1>(i);
to_scale *= scaling[i].inlined_clone(); to_scale *= scaling[i].clone();
} }
} }
@ -352,7 +352,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
{ {
for i in 0..scaling.len() { for i in 0..scaling.len() {
let mut to_scale = self.fixed_columns_mut::<1>(i); let mut to_scale = self.fixed_columns_mut::<1>(i);
to_scale *= scaling[i].inlined_clone(); to_scale *= scaling[i].clone();
} }
} }
@ -366,7 +366,7 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
{ {
for i in 0..D::dim() { for i in 0..D::dim() {
for j in 0..D::dim() - 1 { for j in 0..D::dim() - 1 {
let add = shift[j].inlined_clone() * self[(D::dim() - 1, i)].inlined_clone(); let add = shift[j].clone() * self[(D::dim() - 1, i)].clone();
self[(j, i)] += add; self[(j, i)] += add;
} }
} }
@ -440,7 +440,7 @@ impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>,
let transform = self.fixed_slice::<2, 2>(0, 0); let transform = self.fixed_slice::<2, 2>(0, 0);
let translation = self.fixed_slice::<2, 1>(0, 2); let translation = self.fixed_slice::<2, 1>(0, 2);
let normalizer = self.fixed_slice::<1, 2>(2, 0); let normalizer = self.fixed_slice::<1, 2>(2, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) }; let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
if !n.is_zero() { if !n.is_zero() {
(transform * pt + translation) / n (transform * pt + translation) / n
@ -457,7 +457,7 @@ impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>,
let transform = self.fixed_slice::<3, 3>(0, 0); let transform = self.fixed_slice::<3, 3>(0, 0);
let translation = self.fixed_slice::<3, 1>(0, 3); let translation = self.fixed_slice::<3, 1>(0, 3);
let normalizer = self.fixed_slice::<1, 3>(3, 0); let normalizer = self.fixed_slice::<1, 3>(3, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) }; let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
if !n.is_zero() { if !n.is_zero() {
(transform * pt + translation) / n (transform * pt + translation) / n

View File

@ -64,7 +64,7 @@ macro_rules! component_binop_impl(
for j in 0 .. res.ncols() { for j in 0 .. res.ncols() {
for i in 0 .. res.nrows() { for i in 0 .. res.nrows() {
unsafe { unsafe {
res.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).inlined_clone()); res.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).clone());
} }
} }
} }
@ -91,7 +91,7 @@ macro_rules! component_binop_impl(
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
unsafe { unsafe {
let res = alpha.inlined_clone() * a.get_unchecked((i, j)).inlined_clone().$op(b.get_unchecked((i, j)).inlined_clone()); let res = alpha.clone() * a.get_unchecked((i, j)).clone().$op(b.get_unchecked((i, j)).clone());
*self.get_unchecked_mut((i, j)) = res; *self.get_unchecked_mut((i, j)) = res;
} }
} }
@ -101,8 +101,8 @@ macro_rules! component_binop_impl(
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
unsafe { unsafe {
let res = alpha.inlined_clone() * a.get_unchecked((i, j)).inlined_clone().$op(b.get_unchecked((i, j)).inlined_clone()); let res = alpha.clone() * a.get_unchecked((i, j)).clone().$op(b.get_unchecked((i, j)).clone());
*self.get_unchecked_mut((i, j)) = beta.inlined_clone() * self.get_unchecked((i, j)).inlined_clone() + res; *self.get_unchecked_mut((i, j)) = beta.clone() * self.get_unchecked((i, j)).clone() + res;
} }
} }
} }
@ -124,7 +124,7 @@ macro_rules! component_binop_impl(
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
unsafe { unsafe {
self.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).inlined_clone()); self.get_unchecked_mut((i, j)).$op_assign(rhs.get_unchecked((i, j)).clone());
} }
} }
} }
@ -347,7 +347,7 @@ impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
SA: StorageMut<T, R1, C1>, SA: StorageMut<T, R1, C1>,
{ {
for e in self.iter_mut() { for e in self.iter_mut() {
*e += rhs.inlined_clone() *e += rhs.clone()
} }
} }
} }

View File

@ -104,8 +104,7 @@ where
unsafe { unsafe {
for i in 0..nrows.value() { for i in 0..nrows.value() {
for j in 0..ncols.value() { for j in 0..ncols.value() {
*res.get_unchecked_mut((i, j)) = *res.get_unchecked_mut((i, j)) = MaybeUninit::new(iter.next().unwrap().clone())
MaybeUninit::new(iter.next().unwrap().inlined_clone())
} }
} }
@ -166,7 +165,7 @@ where
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()) {
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() } unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
} }
res res
@ -188,7 +187,7 @@ where
); );
for (i, elt) in elts.iter().enumerate() { for (i, elt) in elts.iter().enumerate() {
unsafe { *res.get_unchecked_mut((i, i)) = elt.inlined_clone() } unsafe { *res.get_unchecked_mut((i, i)) = elt.clone() }
} }
res res
@ -232,7 +231,7 @@ where
// TODO: optimize that. // TODO: optimize that.
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| { Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
rows[i][(0, j)].inlined_clone() rows[i][(0, j)].clone()
}) })
} }
@ -274,7 +273,7 @@ where
// TODO: optimize that. // TODO: optimize that.
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| { Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |i, j| {
columns[j][i].inlined_clone() columns[j][i].clone()
}) })
} }
@ -358,7 +357,7 @@ where
for i in 0..diag.len() { for i in 0..diag.len() {
unsafe { unsafe {
*res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone(); *res.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone();
} }
} }

View File

@ -509,11 +509,7 @@ where
let (nrows, ncols) = arr[0].shape_generic(); let (nrows, ncols) = arr[0].shape_generic();
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
[ [arr[0][(i, j)].clone(), arr[1][(i, j)].clone()].into()
arr[0][(i, j)].inlined_clone(),
arr[1][(i, j)].inlined_clone(),
]
.into()
}) })
} }
} }
@ -531,10 +527,10 @@ where
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
[ [
arr[0][(i, j)].inlined_clone(), arr[0][(i, j)].clone(),
arr[1][(i, j)].inlined_clone(), arr[1][(i, j)].clone(),
arr[2][(i, j)].inlined_clone(), arr[2][(i, j)].clone(),
arr[3][(i, j)].inlined_clone(), arr[3][(i, j)].clone(),
] ]
.into() .into()
}) })
@ -554,14 +550,14 @@ where
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
[ [
arr[0][(i, j)].inlined_clone(), arr[0][(i, j)].clone(),
arr[1][(i, j)].inlined_clone(), arr[1][(i, j)].clone(),
arr[2][(i, j)].inlined_clone(), arr[2][(i, j)].clone(),
arr[3][(i, j)].inlined_clone(), arr[3][(i, j)].clone(),
arr[4][(i, j)].inlined_clone(), arr[4][(i, j)].clone(),
arr[5][(i, j)].inlined_clone(), arr[5][(i, j)].clone(),
arr[6][(i, j)].inlined_clone(), arr[6][(i, j)].clone(),
arr[7][(i, j)].inlined_clone(), arr[7][(i, j)].clone(),
] ]
.into() .into()
}) })
@ -580,22 +576,22 @@ where
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
[ [
arr[0][(i, j)].inlined_clone(), arr[0][(i, j)].clone(),
arr[1][(i, j)].inlined_clone(), arr[1][(i, j)].clone(),
arr[2][(i, j)].inlined_clone(), arr[2][(i, j)].clone(),
arr[3][(i, j)].inlined_clone(), arr[3][(i, j)].clone(),
arr[4][(i, j)].inlined_clone(), arr[4][(i, j)].clone(),
arr[5][(i, j)].inlined_clone(), arr[5][(i, j)].clone(),
arr[6][(i, j)].inlined_clone(), arr[6][(i, j)].clone(),
arr[7][(i, j)].inlined_clone(), arr[7][(i, j)].clone(),
arr[8][(i, j)].inlined_clone(), arr[8][(i, j)].clone(),
arr[9][(i, j)].inlined_clone(), arr[9][(i, j)].clone(),
arr[10][(i, j)].inlined_clone(), arr[10][(i, j)].clone(),
arr[11][(i, j)].inlined_clone(), arr[11][(i, j)].clone(),
arr[12][(i, j)].inlined_clone(), arr[12][(i, j)].clone(),
arr[13][(i, j)].inlined_clone(), arr[13][(i, j)].clone(),
arr[14][(i, j)].inlined_clone(), arr[14][(i, j)].clone(),
arr[15][(i, j)].inlined_clone(), arr[15][(i, j)].clone(),
] ]
.into() .into()
}) })

View File

@ -70,7 +70,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
*res.vget_unchecked_mut(destination) = *res.vget_unchecked_mut(destination) =
MaybeUninit::new(src.vget_unchecked(*source).inlined_clone()); MaybeUninit::new(src.vget_unchecked(*source).clone());
} }
} }
} }
@ -96,7 +96,7 @@ impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
// NOTE: this is basically a copy_frow but wrapping the values insnide of MaybeUninit. // NOTE: this is basically a copy_frow but wrapping the values insnide of MaybeUninit.
res.column_mut(destination) res.column_mut(destination)
.zip_apply(&self.column(*source), |out, e| { .zip_apply(&self.column(*source), |out, e| {
*out = MaybeUninit::new(e.inlined_clone()) *out = MaybeUninit::new(e.clone())
}); });
} }
@ -120,7 +120,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions."); assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions.");
for i in 0..min_nrows_ncols { for i in 0..min_nrows_ncols {
unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).inlined_clone() } unsafe { *self.get_unchecked_mut((i, i)) = diag.vget_unchecked(i).clone() }
} }
} }
@ -177,7 +177,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
T: Scalar, T: Scalar,
{ {
for e in self.iter_mut() { for e in self.iter_mut() {
*e = val.inlined_clone() *e = val.clone()
} }
} }
@ -201,7 +201,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
let n = cmp::min(nrows, ncols); let n = cmp::min(nrows, ncols);
for i in 0..n { for i in 0..n {
unsafe { *self.get_unchecked_mut((i, i)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, i)) = val.clone() }
} }
} }
@ -213,7 +213,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
{ {
assert!(i < self.nrows(), "Row index out of bounds."); assert!(i < self.nrows(), "Row index out of bounds.");
for j in 0..self.ncols() { for j in 0..self.ncols() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
} }
} }
@ -225,7 +225,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
{ {
assert!(j < self.ncols(), "Row index out of bounds."); assert!(j < self.ncols(), "Row index out of bounds.");
for i in 0..self.nrows() { for i in 0..self.nrows() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
} }
} }
@ -243,7 +243,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
{ {
for j in 0..self.ncols() { for j in 0..self.ncols() {
for i in (j + shift)..self.nrows() { for i in (j + shift)..self.nrows() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
} }
} }
} }
@ -264,7 +264,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
// TODO: is there a more efficient way to avoid the min ? // TODO: is there a more efficient way to avoid the min ?
// (necessary for rectangular matrices) // (necessary for rectangular matrices)
for i in 0..cmp::min(j + 1 - shift, self.nrows()) { for i in 0..cmp::min(j + 1 - shift, self.nrows()) {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.clone() }
} }
} }
} }
@ -281,7 +281,7 @@ impl<T: Scalar, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
for j in 0..dim { for j in 0..dim {
for i in j + 1..dim { for i in j + 1..dim {
unsafe { unsafe {
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone(); *self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
} }
} }
} }
@ -296,7 +296,7 @@ impl<T: Scalar, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S> {
for j in 1..self.ncols() { for j in 1..self.ncols() {
for i in 0..j { for i in 0..j {
unsafe { unsafe {
*self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).inlined_clone(); *self.get_unchecked_mut((i, j)) = self.get_unchecked((j, i)).clone();
} }
} }
} }
@ -647,7 +647,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
{ {
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Const::<D>) }; let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Const::<D>) };
res.fixed_columns_mut::<D>(i) res.fixed_columns_mut::<D>(i)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
// Safety: the result is now fully initialized. The added columns have // Safety: the result is now fully initialized. The added columns have
// been initialized by the `fill_with` above, and the rest have // been initialized by the `fill_with` above, and the rest have
@ -665,7 +665,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
{ {
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) }; let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) };
res.columns_mut(i, n) res.columns_mut(i, n)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
// Safety: the result is now fully initialized. The added columns have // Safety: the result is now fully initialized. The added columns have
// been initialized by the `fill_with` above, and the rest have // been initialized by the `fill_with` above, and the rest have
@ -740,7 +740,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
{ {
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Const::<D>) }; let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Const::<D>) };
res.fixed_rows_mut::<D>(i) res.fixed_rows_mut::<D>(i)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
// Safety: the result is now fully initialized. The added rows have // Safety: the result is now fully initialized. The added rows have
// been initialized by the `fill_with` above, and the rest have // been initialized by the `fill_with` above, and the rest have
@ -758,7 +758,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
{ {
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) }; let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) };
res.rows_mut(i, n) res.rows_mut(i, n)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
// Safety: the result is now fully initialized. The added rows have // Safety: the result is now fully initialized. The added rows have
// been initialized by the `fill_with` above, and the rest have // been initialized by the `fill_with` above, and the rest have
@ -896,7 +896,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
if new_ncols.value() > ncols { if new_ncols.value() > ncols {
res.columns_range_mut(ncols..) res.columns_range_mut(ncols..)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
} }
// Safety: the result is now fully initialized by `reallocate_copy` and // Safety: the result is now fully initialized by `reallocate_copy` and
@ -933,12 +933,12 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
if new_ncols.value() > ncols { if new_ncols.value() > ncols {
res.columns_range_mut(ncols..) res.columns_range_mut(ncols..)
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
} }
if new_nrows.value() > nrows { if new_nrows.value() > nrows {
res.slice_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value())) res.slice_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value()))
.fill_with(|| MaybeUninit::new(val.inlined_clone())); .fill_with(|| MaybeUninit::new(val.clone()));
} }
// Safety: the result is now fully initialized by `reallocate_copy` and // Safety: the result is now fully initialized by `reallocate_copy` and

View File

@ -26,7 +26,7 @@ impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.axpy(t.inlined_clone(), rhs, T::one() - t); res.axpy(t.clone(), rhs, T::one() - t);
res res
} }
@ -109,14 +109,14 @@ impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
return Some(Unit::new_unchecked(self.clone_owned())); return Some(Unit::new_unchecked(self.clone_owned()));
} }
let hang = c_hang.acos(); let hang = c_hang.clone().acos();
let s_hang = (T::one() - c_hang * c_hang).sqrt(); let s_hang = (T::one() - c_hang.clone() * c_hang).sqrt();
// TODO: what if s_hang is 0.0 ? The result is not well-defined. // TODO: what if s_hang is 0.0 ? The result is not well-defined.
if relative_eq!(s_hang, T::zero(), epsilon = epsilon) { if relative_eq!(s_hang, T::zero(), epsilon = epsilon) {
None None
} else { } else {
let ta = ((T::one() - t) * hang).sin() / s_hang; let ta = ((T::one() - t.clone()) * hang.clone()).sin() / s_hang.clone();
let tb = (t * hang).sin() / s_hang; let tb = (t * hang).sin() / s_hang;
let mut res = self.scale(ta); let mut res = self.scale(ta);
res.axpy(tb, &**rhs, T::one()); res.axpy(tb, &**rhs, T::one());

View File

@ -567,13 +567,13 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
SB: Storage<T, R2, C2>, SB: Storage<T, R2, C2>,
T::Epsilon: Copy, T::Epsilon: Clone,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
assert!(self.shape() == other.shape()); assert!(self.shape() == other.shape());
self.iter() self.iter()
.zip(other.iter()) .zip(other.iter())
.all(|(a, b)| a.relative_eq(b, eps, max_relative)) .all(|(a, b)| a.relative_eq(b, eps.clone(), max_relative.clone()))
} }
/// Tests whether `self` and `rhs` are exactly equal. /// Tests whether `self` and `rhs` are exactly equal.
@ -668,7 +668,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for j in 0..res.ncols() { for j in 0..res.ncols() {
for i in 0..res.nrows() { for i in 0..res.nrows() {
*res.get_unchecked_mut((i, j)) = *res.get_unchecked_mut((i, j)) =
MaybeUninit::new(self.get_unchecked((i, j)).inlined_clone()); MaybeUninit::new(self.get_unchecked((i, j)).clone());
} }
} }
@ -704,7 +704,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
unsafe { unsafe {
Status::init( Status::init(
out.get_unchecked_mut((j, i)), out.get_unchecked_mut((j, i)),
self.get_unchecked((i, j)).inlined_clone(), self.get_unchecked((i, j)).clone(),
); );
} }
} }
@ -758,7 +758,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows.value() { for i in 0..nrows.value() {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a)); *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a));
} }
} }
@ -827,7 +827,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows.value() { for i in 0..nrows.value() {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(i, j, a)); *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(i, j, a));
} }
} }
@ -863,8 +863,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows.value() { for i in 0..nrows.value() {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
let b = rhs.data.get_unchecked(i, j).inlined_clone(); let b = rhs.data.get_unchecked(i, j).clone();
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b)) *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b))
} }
} }
@ -912,9 +912,9 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows.value() { for i in 0..nrows.value() {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
let b = b.data.get_unchecked(i, j).inlined_clone(); let b = b.data.get_unchecked(i, j).clone();
let c = c.data.get_unchecked(i, j).inlined_clone(); let c = c.data.get_unchecked(i, j).clone();
*res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b, c)) *res.data.get_unchecked_mut(i, j) = MaybeUninit::new(f(a, b, c))
} }
} }
@ -939,7 +939,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows.value() { for i in 0..nrows.value() {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
res = f(res, a) res = f(res, a)
} }
} }
@ -978,8 +978,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for j in 0..ncols.value() { for j in 0..ncols.value() {
for i in 0..nrows.value() { for i in 0..nrows.value() {
unsafe { unsafe {
let a = self.data.get_unchecked(i, j).inlined_clone(); let a = self.data.get_unchecked(i, j).clone();
let b = rhs.data.get_unchecked(i, j).inlined_clone(); let b = rhs.data.get_unchecked(i, j).clone();
res = f(res, a, b) res = f(res, a, b)
} }
} }
@ -1033,7 +1033,7 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows { for i in 0..nrows {
unsafe { unsafe {
let e = self.data.get_unchecked_mut(i, j); let e = self.data.get_unchecked_mut(i, j);
let rhs = rhs.get_unchecked((i, j)).inlined_clone(); let rhs = rhs.get_unchecked((i, j)).clone();
f(e, rhs) f(e, rhs)
} }
} }
@ -1078,8 +1078,8 @@ impl<T, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows { for i in 0..nrows {
unsafe { unsafe {
let e = self.data.get_unchecked_mut(i, j); let e = self.data.get_unchecked_mut(i, j);
let b = b.get_unchecked((i, j)).inlined_clone(); let b = b.get_unchecked((i, j)).clone();
let c = c.get_unchecked((i, j)).inlined_clone(); let c = c.get_unchecked((i, j)).clone();
f(e, b, c) f(e, b, c)
} }
} }
@ -1248,8 +1248,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
for j in 0..ncols { for j in 0..ncols {
for i in 0..nrows { for i in 0..nrows {
unsafe { unsafe {
*self.get_unchecked_mut((i, j)) = *self.get_unchecked_mut((i, j)) = slice.get_unchecked(i + j * nrows).clone();
slice.get_unchecked(i + j * nrows).inlined_clone();
} }
} }
} }
@ -1273,7 +1272,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
for j in 0..self.ncols() { for j in 0..self.ncols() {
for i in 0..self.nrows() { for i in 0..self.nrows() {
unsafe { unsafe {
*self.get_unchecked_mut((i, j)) = other.get_unchecked((i, j)).inlined_clone(); *self.get_unchecked_mut((i, j)) = other.get_unchecked((i, j)).clone();
} }
} }
} }
@ -1298,7 +1297,7 @@ impl<T, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R, C, S> {
for j in 0..ncols { for j in 0..ncols {
for i in 0..nrows { for i in 0..nrows {
unsafe { unsafe {
*self.get_unchecked_mut((i, j)) = other.get_unchecked((j, i)).inlined_clone(); *self.get_unchecked_mut((i, j)) = other.get_unchecked((j, i)).clone();
} }
} }
} }
@ -1400,7 +1399,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
unsafe { unsafe {
Status::init( Status::init(
out.get_unchecked_mut((j, i)), out.get_unchecked_mut((j, i)),
self.get_unchecked((i, j)).simd_conjugate(), self.get_unchecked((i, j)).clone().simd_conjugate(),
); );
} }
} }
@ -1475,7 +1474,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
where where
DefaultAllocator: Allocator<T, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.map(|e| e.simd_unscale(real)) self.map(|e| e.simd_unscale(real.clone()))
} }
/// Multiplies each component of the complex matrix `self` by the given real. /// Multiplies each component of the complex matrix `self` by the given real.
@ -1485,7 +1484,7 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C
where where
DefaultAllocator: Allocator<T, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.map(|e| e.simd_scale(real)) self.map(|e| e.simd_scale(real.clone()))
} }
} }
@ -1493,19 +1492,19 @@ impl<T: SimdComplexField, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> Matrix<T, R
/// The conjugate of the complex matrix `self` computed in-place. /// The conjugate of the complex matrix `self` computed in-place.
#[inline] #[inline]
pub fn conjugate_mut(&mut self) { pub fn conjugate_mut(&mut self) {
self.apply(|e| *e = e.simd_conjugate()) self.apply(|e| *e = e.clone().simd_conjugate())
} }
/// Divides each component of the complex matrix `self` by the given real. /// Divides each component of the complex matrix `self` by the given real.
#[inline] #[inline]
pub fn unscale_mut(&mut self, real: T::SimdRealField) { pub fn unscale_mut(&mut self, real: T::SimdRealField) {
self.apply(|e| *e = e.simd_unscale(real)) self.apply(|e| *e = e.clone().simd_unscale(real.clone()))
} }
/// Multiplies each component of the complex matrix `self` by the given real. /// Multiplies each component of the complex matrix `self` by the given real.
#[inline] #[inline]
pub fn scale_mut(&mut self, real: T::SimdRealField) { pub fn scale_mut(&mut self, real: T::SimdRealField) {
self.apply(|e| *e = e.simd_scale(real)) self.apply(|e| *e = e.clone().simd_scale(real.clone()))
} }
} }
@ -1528,18 +1527,18 @@ impl<T: SimdComplexField, D: Dim, S: RawStorageMut<T, D, D>> Matrix<T, D, D, S>
for i in 0..dim { for i in 0..dim {
for j in 0..i { for j in 0..i {
unsafe { unsafe {
let ref_ij = self.get_unchecked_mut((i, j)) as *mut T; let ref_ij = self.get_unchecked((i, j)).clone();
let ref_ji = self.get_unchecked_mut((j, i)) as *mut T; let ref_ji = self.get_unchecked((j, i)).clone();
let conj_ij = (*ref_ij).simd_conjugate(); let conj_ij = ref_ij.simd_conjugate();
let conj_ji = (*ref_ji).simd_conjugate(); let conj_ji = ref_ji.simd_conjugate();
*ref_ij = conj_ji; *self.get_unchecked_mut((i, j)) = conj_ji;
*ref_ji = conj_ij; *self.get_unchecked_mut((j, i)) = conj_ij;
} }
} }
{ {
let diag = unsafe { self.get_unchecked_mut((i, i)) }; let diag = unsafe { self.get_unchecked_mut((i, i)) };
*diag = diag.simd_conjugate(); *diag = diag.clone().simd_conjugate();
} }
} }
} }
@ -1577,7 +1576,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
// Safety: all indices are in range. // Safety: all indices are in range.
unsafe { unsafe {
*res.vget_unchecked_mut(i) = *res.vget_unchecked_mut(i) =
MaybeUninit::new(f(self.get_unchecked((i, i)).inlined_clone())); MaybeUninit::new(f(self.get_unchecked((i, i)).clone()));
} }
} }
@ -1601,7 +1600,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D, D>> SquareMatrix<T, D, S> {
let mut res = T::zero(); let mut res = T::zero();
for i in 0..dim.value() { for i in 0..dim.value() {
res += unsafe { self.get_unchecked((i, i)).inlined_clone() }; res += unsafe { self.get_unchecked((i, i)).clone() };
} }
res res
@ -1723,7 +1722,7 @@ impl<T, R: Dim, C: Dim, S> AbsDiffEq for Matrix<T, R, C, S>
where where
T: Scalar + AbsDiffEq, T: Scalar + AbsDiffEq,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -1736,7 +1735,7 @@ where
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.iter() self.iter()
.zip(other.iter()) .zip(other.iter())
.all(|(a, b)| a.abs_diff_eq(b, epsilon)) .all(|(a, b)| a.abs_diff_eq(b, epsilon.clone()))
} }
} }
@ -1744,7 +1743,7 @@ impl<T, R: Dim, C: Dim, S> RelativeEq for Matrix<T, R, C, S>
where where
T: Scalar + RelativeEq, T: Scalar + RelativeEq,
S: Storage<T, R, C>, S: Storage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -1766,7 +1765,7 @@ impl<T, R: Dim, C: Dim, S> UlpsEq for Matrix<T, R, C, S>
where where
T: Scalar + UlpsEq, T: Scalar + UlpsEq,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {
@ -1778,7 +1777,7 @@ where
assert!(self.shape() == other.shape()); assert!(self.shape() == other.shape());
self.iter() self.iter()
.zip(other.iter()) .zip(other.iter())
.all(|(a, b)| a.ulps_eq(b, epsilon, max_ulps)) .all(|(a, b)| a.ulps_eq(b, epsilon.clone(), max_ulps.clone()))
} }
} }
@ -2029,9 +2028,8 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
); );
unsafe { unsafe {
self.get_unchecked((0, 0)).inlined_clone() * b.get_unchecked((1, 0)).inlined_clone() self.get_unchecked((0, 0)).clone() * b.get_unchecked((1, 0)).clone()
- self.get_unchecked((1, 0)).inlined_clone() - self.get_unchecked((1, 0)).clone() * b.get_unchecked((0, 0)).clone()
* b.get_unchecked((0, 0)).inlined_clone()
} }
} }
@ -2073,18 +2071,12 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
let by = b.get_unchecked((1, 0)); let by = b.get_unchecked((1, 0));
let bz = b.get_unchecked((2, 0)); let bz = b.get_unchecked((2, 0));
*res.get_unchecked_mut((0, 0)) = MaybeUninit::new( *res.get_unchecked_mut((0, 0)) =
ay.inlined_clone() * bz.inlined_clone() MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
- az.inlined_clone() * by.inlined_clone(), *res.get_unchecked_mut((1, 0)) =
); MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
*res.get_unchecked_mut((1, 0)) = MaybeUninit::new( *res.get_unchecked_mut((2, 0)) =
az.inlined_clone() * bx.inlined_clone() MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
- ax.inlined_clone() * bz.inlined_clone(),
);
*res.get_unchecked_mut((2, 0)) = MaybeUninit::new(
ax.inlined_clone() * by.inlined_clone()
- ay.inlined_clone() * bx.inlined_clone(),
);
// Safety: res is now fully initialized. // Safety: res is now fully initialized.
res.assume_init() res.assume_init()
@ -2104,18 +2096,12 @@ impl<T: Scalar + ClosedAdd + ClosedSub + ClosedMul, R: Dim, C: Dim, S: RawStorag
let by = b.get_unchecked((0, 1)); let by = b.get_unchecked((0, 1));
let bz = b.get_unchecked((0, 2)); let bz = b.get_unchecked((0, 2));
*res.get_unchecked_mut((0, 0)) = MaybeUninit::new( *res.get_unchecked_mut((0, 0)) =
ay.inlined_clone() * bz.inlined_clone() MaybeUninit::new(ay.clone() * bz.clone() - az.clone() * by.clone());
- az.inlined_clone() * by.inlined_clone(), *res.get_unchecked_mut((0, 1)) =
); MaybeUninit::new(az.clone() * bx.clone() - ax.clone() * bz.clone());
*res.get_unchecked_mut((0, 1)) = MaybeUninit::new( *res.get_unchecked_mut((0, 2)) =
az.inlined_clone() * bx.inlined_clone() MaybeUninit::new(ax.clone() * by.clone() - ay.clone() * bx.clone());
- ax.inlined_clone() * bz.inlined_clone(),
);
*res.get_unchecked_mut((0, 2)) = MaybeUninit::new(
ax.inlined_clone() * by.inlined_clone()
- ay.inlined_clone() * bx.inlined_clone(),
);
// Safety: res is now fully initialized. // Safety: res is now fully initialized.
res.assume_init() res.assume_init()
@ -2131,13 +2117,13 @@ impl<T: Scalar + Field, S: RawStorage<T, U3>> Vector<T, U3, S> {
pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> { pub fn cross_matrix(&self) -> OMatrix<T, U3, U3> {
OMatrix::<T, U3, U3>::new( OMatrix::<T, U3, U3>::new(
T::zero(), T::zero(),
-self[2].inlined_clone(), -self[2].clone(),
self[1].inlined_clone(), self[1].clone(),
self[2].inlined_clone(), self[2].clone(),
T::zero(), T::zero(),
-self[0].inlined_clone(), -self[0].clone(),
-self[1].inlined_clone(), -self[1].clone(),
self[0].inlined_clone(), self[0].clone(),
T::zero(), T::zero(),
) )
} }
@ -2170,7 +2156,7 @@ impl<T, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<T, R, C, S>>
where where
T: Scalar + AbsDiffEq, T: Scalar + AbsDiffEq,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -2189,7 +2175,7 @@ impl<T, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<T, R, C, S>>
where where
T: Scalar + RelativeEq, T: Scalar + RelativeEq,
S: Storage<T, R, C>, S: Storage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -2212,7 +2198,7 @@ impl<T, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<T, R, C, S>>
where where
T: Scalar + UlpsEq, T: Scalar + UlpsEq,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {

View File

@ -40,8 +40,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
T: SimdComplexField, T: SimdComplexField,
{ {
self.fold_with( self.fold_with(
|e| e.unwrap_or(&T::zero()).simd_norm1(), |e| e.unwrap_or(&T::zero()).clone().simd_norm1(),
|a, b| a.simd_max(b.simd_norm1()), |a, b| a.simd_max(b.clone().simd_norm1()),
) )
} }
@ -60,8 +60,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
T: SimdPartialOrd + Zero, T: SimdPartialOrd + Zero,
{ {
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero), |e| e.map(|e| e.clone()).unwrap_or_else(T::zero),
|a, b| a.simd_max(b.inlined_clone()), |a, b| a.simd_max(b.clone()),
) )
} }
@ -101,10 +101,10 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
{ {
self.fold_with( self.fold_with(
|e| { |e| {
e.map(|e| e.simd_norm1()) e.map(|e| e.clone().simd_norm1())
.unwrap_or_else(T::SimdRealField::zero) .unwrap_or_else(T::SimdRealField::zero)
}, },
|a, b| a.simd_min(b.simd_norm1()), |a, b| a.simd_min(b.clone().simd_norm1()),
) )
} }
@ -123,8 +123,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
T: SimdPartialOrd + Zero, T: SimdPartialOrd + Zero,
{ {
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero), |e| e.map(|e| e.clone()).unwrap_or_else(T::zero),
|a, b| a.simd_min(b.inlined_clone()), |a, b| a.simd_min(b.clone()),
) )
} }
@ -149,12 +149,12 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
{ {
assert!(!self.is_empty(), "The input matrix must not be empty."); assert!(!self.is_empty(), "The input matrix must not be empty.");
let mut the_max = unsafe { self.get_unchecked((0, 0)).norm1() }; let mut the_max = unsafe { self.get_unchecked((0, 0)).clone().norm1() };
let mut the_ij = (0, 0); let mut the_ij = (0, 0);
for j in 0..self.ncols() { for j in 0..self.ncols() {
for i in 0..self.nrows() { for i in 0..self.nrows() {
let val = unsafe { self.get_unchecked((i, j)).norm1() }; let val = unsafe { self.get_unchecked((i, j)).clone().norm1() };
if val > the_max { if val > the_max {
the_max = val; the_max = val;
@ -224,11 +224,11 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
{ {
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).norm1() }; let mut the_max = unsafe { self.vget_unchecked(0).clone().norm1() };
let mut the_i = 0; let mut the_i = 0;
for i in 1..self.nrows() { for i in 1..self.nrows() {
let val = unsafe { self.vget_unchecked(i).norm1() }; let val = unsafe { self.vget_unchecked(i).clone().norm1() };
if val > the_max { if val > the_max {
the_max = val; the_max = val;
@ -268,7 +268,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
} }
} }
(the_i, the_max.inlined_clone()) (the_i, the_max.clone())
} }
/// Computes the index of the vector component with the largest value. /// Computes the index of the vector component with the largest value.
@ -350,7 +350,7 @@ impl<T: Scalar, D: Dim, S: RawStorage<T, D>> Vector<T, D, S> {
} }
} }
(the_i, the_min.inlined_clone()) (the_i, the_min.clone())
} }
/// Computes the index of the vector component with the smallest value. /// Computes the index of the vector component with the smallest value.

View File

@ -328,7 +328,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let le = n.simd_le(min_norm); let le = n.clone().simd_le(min_norm);
let val = self.unscale(n); let val = self.unscale(n);
SimdOption::new(val, le) SimdOption::new(val, le)
} }
@ -377,7 +377,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let scaled = self.scale(max / n); let scaled = self.scale(max.clone() / n.clone());
let use_scaled = n.simd_gt(max); let use_scaled = n.simd_gt(max);
scaled.select(use_scaled, self.clone_owned()) scaled.select(use_scaled, self.clone_owned())
} }
@ -413,7 +413,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
T: SimdComplexField, T: SimdComplexField,
{ {
let n = self.norm(); let n = self.norm();
self.unscale_mut(n); self.unscale_mut(n.clone());
n n
} }
@ -433,8 +433,13 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let le = n.simd_le(min_norm); let le = n.clone().simd_le(min_norm);
self.apply(|e| *e = e.simd_unscale(n).select(le, *e)); self.apply(|e| {
*e = e
.clone()
.simd_unscale(n.clone())
.select(le.clone(), e.clone())
});
SimdOption::new(n, le) SimdOption::new(n, le)
} }
@ -451,7 +456,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
if n <= min_norm { if n <= min_norm {
None None
} else { } else {
self.unscale_mut(n); self.unscale_mut(n.clone());
Some(n) Some(n)
} }
} }
@ -572,7 +577,7 @@ where
&& f(&Self::canonical_basis_element(1)); && f(&Self::canonical_basis_element(1));
} else if vs.len() == 1 { } else if vs.len() == 1 {
let v = &vs[0]; let v = &vs[0];
let res = Self::from_column_slice(&[-v[1], v[0]]); let res = Self::from_column_slice(&[-v[1].clone(), v[0].clone()]);
let _ = f(&res.normalize()); let _ = f(&res.normalize());
} }
@ -588,10 +593,10 @@ where
let v = &vs[0]; let v = &vs[0];
let mut a; let mut a;
if v[0].norm1() > v[1].norm1() { if v[0].clone().norm1() > v[1].clone().norm1() {
a = Self::from_column_slice(&[v[2], T::zero(), -v[0]]); a = Self::from_column_slice(&[v[2].clone(), T::zero(), -v[0].clone()]);
} else { } else {
a = Self::from_column_slice(&[T::zero(), -v[2], v[1]]); a = Self::from_column_slice(&[T::zero(), -v[2].clone(), v[1].clone()]);
}; };
let _ = a.normalize_mut(); let _ = a.normalize_mut();

View File

@ -116,7 +116,7 @@ where
#[inline] #[inline]
pub fn neg_mut(&mut self) { pub fn neg_mut(&mut self) {
for e in self.iter_mut() { for e in self.iter_mut() {
*e = -e.inlined_clone() *e = -e.clone()
} }
} }
} }
@ -163,12 +163,12 @@ macro_rules! componentwise_binop_impl(
let arr2 = rhs.data.as_slice_unchecked(); let arr2 = rhs.data.as_slice_unchecked();
let out = out.data.as_mut_slice_unchecked(); let out = out.data.as_mut_slice_unchecked();
for i in 0 .. arr1.len() { for i in 0 .. arr1.len() {
Status::init(out.get_unchecked_mut(i), arr1.get_unchecked(i).inlined_clone().$method(arr2.get_unchecked(i).inlined_clone())); Status::init(out.get_unchecked_mut(i), arr1.get_unchecked(i).clone().$method(arr2.get_unchecked(i).clone()));
} }
} else { } else {
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
let val = self.get_unchecked((i, j)).inlined_clone().$method(rhs.get_unchecked((i, j)).inlined_clone()); let val = self.get_unchecked((i, j)).clone().$method(rhs.get_unchecked((i, j)).clone());
Status::init(out.get_unchecked_mut((i, j)), val); Status::init(out.get_unchecked_mut((i, j)), val);
} }
} }
@ -193,12 +193,12 @@ macro_rules! componentwise_binop_impl(
let arr2 = rhs.data.as_slice_unchecked(); let arr2 = rhs.data.as_slice_unchecked();
for i in 0 .. arr2.len() { for i in 0 .. arr2.len() {
arr1.get_unchecked_mut(i).$method_assign(arr2.get_unchecked(i).inlined_clone()); arr1.get_unchecked_mut(i).$method_assign(arr2.get_unchecked(i).clone());
} }
} else { } else {
for j in 0 .. rhs.ncols() { for j in 0 .. rhs.ncols() {
for i in 0 .. rhs.nrows() { for i in 0 .. rhs.nrows() {
self.get_unchecked_mut((i, j)).$method_assign(rhs.get_unchecked((i, j)).inlined_clone()) self.get_unchecked_mut((i, j)).$method_assign(rhs.get_unchecked((i, j)).clone())
} }
} }
} }
@ -221,14 +221,14 @@ macro_rules! componentwise_binop_impl(
let arr2 = rhs.data.as_mut_slice_unchecked(); let arr2 = rhs.data.as_mut_slice_unchecked();
for i in 0 .. arr1.len() { for i in 0 .. arr1.len() {
let res = arr1.get_unchecked(i).inlined_clone().$method(arr2.get_unchecked(i).inlined_clone()); let res = arr1.get_unchecked(i).clone().$method(arr2.get_unchecked(i).clone());
*arr2.get_unchecked_mut(i) = res; *arr2.get_unchecked_mut(i) = res;
} }
} else { } else {
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
let r = rhs.get_unchecked_mut((i, j)); let r = rhs.get_unchecked_mut((i, j));
*r = self.get_unchecked((i, j)).inlined_clone().$method(r.inlined_clone()) *r = self.get_unchecked((i, j)).clone().$method(r.clone())
} }
} }
} }
@ -472,7 +472,7 @@ macro_rules! componentwise_scalarop_impl(
// for left in res.iter_mut() { // for left in res.iter_mut() {
for left in res.as_mut_slice().iter_mut() { for left in res.as_mut_slice().iter_mut() {
*left = left.inlined_clone().$method(rhs.inlined_clone()) *left = left.clone().$method(rhs.clone())
} }
res res
@ -498,7 +498,7 @@ macro_rules! componentwise_scalarop_impl(
fn $method_assign(&mut self, rhs: T) { fn $method_assign(&mut self, rhs: T) {
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.inlined_clone()) }; unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.clone()) };
} }
} }
} }
@ -815,11 +815,11 @@ where
for j1 in 0..ncols1.value() { for j1 in 0..ncols1.value() {
for j2 in 0..ncols2.value() { for j2 in 0..ncols2.value() {
for i1 in 0..nrows1.value() { for i1 in 0..nrows1.value() {
let coeff = self.get_unchecked((i1, j1)).inlined_clone(); let coeff = self.get_unchecked((i1, j1)).clone();
for i2 in 0..nrows2.value() { for i2 in 0..nrows2.value() {
*data_res = MaybeUninit::new( *data_res = MaybeUninit::new(
coeff.inlined_clone() * rhs.get_unchecked((i2, j2)).inlined_clone(), coeff.clone() * rhs.get_unchecked((i2, j2)).clone(),
); );
data_res = data_res.offset(1); data_res = data_res.offset(1);
} }

View File

@ -60,7 +60,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
pub fn is_identity(&self, eps: T::Epsilon) -> bool pub fn is_identity(&self, eps: T::Epsilon) -> bool
where where
T: Zero + One + RelativeEq, T: Zero + One + RelativeEq,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let d; let d;
@ -70,7 +70,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in d..nrows { for i in d..nrows {
for j in 0..ncols { for j in 0..ncols {
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) { if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) {
return false; return false;
} }
} }
@ -81,7 +81,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 0..nrows { for i in 0..nrows {
for j in d..ncols { for j in d..ncols {
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) { if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone()) {
return false; return false;
} }
} }
@ -92,8 +92,8 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
for i in 1..d { for i in 1..d {
for j in 0..i { for j in 0..i {
// TODO: use unsafe indexing. // TODO: use unsafe indexing.
if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps.clone())
|| !relative_eq!(self[(j, i)], T::zero(), epsilon = eps) || !relative_eq!(self[(j, i)], T::zero(), epsilon = eps.clone())
{ {
return false; return false;
} }
@ -102,7 +102,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
// Diagonal elements of the sub-square matrix. // Diagonal elements of the sub-square matrix.
for i in 0..d { for i in 0..d {
if !relative_eq!(self[(i, i)], T::one(), epsilon = eps) { if !relative_eq!(self[(i, i)], T::one(), epsilon = eps.clone()) {
return false; return false;
} }
} }
@ -122,7 +122,7 @@ impl<T: ComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
where where
T: Zero + One + ClosedAdd + ClosedMul + RelativeEq, T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
S: Storage<T, R, C>, S: Storage<T, R, C>,
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, R, C> + Allocator<T, C, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, C, C>,
{ {
(self.ad_mul(self)).is_identity(eps) (self.ad_mul(self)).is_identity(eps)

View File

@ -1,20 +1,8 @@
use std::any::Any;
use std::fmt::Debug; use std::fmt::Debug;
/// The basic scalar type for all structures of `nalgebra`. /// The basic scalar type for all structures of `nalgebra`.
/// ///
/// This does not make any assumption on the algebraic properties of `Self`. /// This does not make any assumption on the algebraic properties of `Self`.
pub trait Scalar: 'static + Clone + PartialEq + Debug { pub trait Scalar: 'static + Clone + PartialEq + Debug {}
#[inline(always)]
/// Performance hack: Clone doesn't get inlined for Copy types in debug mode, so make it inline anyway.
fn inlined_clone(&self) -> Self {
self.clone()
}
}
impl<T: Copy + PartialEq + Debug + Any> Scalar for T { impl<T: 'static + Clone + PartialEq + Debug> Scalar for T {}
#[inline(always)]
fn inlined_clone(&self) -> T {
*self
}
}

View File

@ -216,11 +216,11 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
T::zero() T::zero()
} else { } else {
let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| { let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
(a.0 + b.inlined_clone() * b.inlined_clone(), a.1 + b) (a.0 + b.clone() * b.clone(), a.1 + b)
}); });
let denom = T::one() / crate::convert::<_, T>(self.len() as f64); let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
let vd = val.1 * denom.inlined_clone(); let vd = val.1 * denom.clone();
val.0 * denom - vd.inlined_clone() * vd val.0 * denom - vd.clone() * vd
} }
} }
@ -289,15 +289,14 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let mut mean = self.column_mean(); let mut mean = self.column_mean();
mean.apply(|e| *e = -(e.inlined_clone() * e.inlined_clone())); mean.apply(|e| *e = -(e.clone() * e.clone()));
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64); let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
self.compress_columns(mean, |out, col| { self.compress_columns(mean, |out, col| {
for i in 0..nrows.value() { for i in 0..nrows.value() {
unsafe { unsafe {
let val = col.vget_unchecked(i); let val = col.vget_unchecked(i);
*out.vget_unchecked_mut(i) += *out.vget_unchecked_mut(i) += denom.clone() * val.clone() * val.clone()
denom.inlined_clone() * val.inlined_clone() * val.inlined_clone()
} }
} }
}) })
@ -397,7 +396,7 @@ impl<T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> Matrix<T, R, C, S> {
let (nrows, ncols) = self.shape_generic(); let (nrows, ncols) = self.shape_generic();
let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64); let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| { self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
out.axpy(denom.inlined_clone(), &col, T::one()) out.axpy(denom.clone(), &col, T::one())
}) })
} }
} }

View File

@ -11,7 +11,7 @@ macro_rules! impl_swizzle {
#[must_use] #[must_use]
pub fn $name(&self) -> $Result<T> pub fn $name(&self) -> $Result<T>
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> { where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].clone()),*)
} }
)* )*
)* )*

View File

@ -170,7 +170,7 @@ impl<T: Normed> Unit<T> {
#[inline] #[inline]
pub fn new_and_get(mut value: T) -> (Self, T::Norm) { pub fn new_and_get(mut value: T) -> (Self, T::Norm) {
let n = value.norm(); let n = value.norm();
value.unscale_mut(n); value.unscale_mut(n.clone());
(Unit { value }, n) (Unit { value }, n)
} }
@ -184,9 +184,9 @@ impl<T: Normed> Unit<T> {
{ {
let sq_norm = value.norm_squared(); let sq_norm = value.norm_squared();
if sq_norm > min_norm * min_norm { if sq_norm > min_norm.clone() * min_norm {
let n = sq_norm.simd_sqrt(); let n = sq_norm.simd_sqrt();
value.unscale_mut(n); value.unscale_mut(n.clone());
Some((Unit { value }, n)) Some((Unit { value }, n))
} else { } else {
None None
@ -201,7 +201,7 @@ impl<T: Normed> Unit<T> {
#[inline] #[inline]
pub fn renormalize(&mut self) -> T::Norm { pub fn renormalize(&mut self) -> T::Norm {
let n = self.norm(); let n = self.norm();
self.value.unscale_mut(n); self.value.unscale_mut(n.clone());
n n
} }

View File

@ -87,7 +87,10 @@ where
pub fn normalize(&self) -> Self { pub fn normalize(&self) -> Self {
let real_norm = self.real.norm(); let real_norm = self.real.norm();
Self::from_real_and_dual(self.real / real_norm, self.dual / real_norm) Self::from_real_and_dual(
self.real.clone() / real_norm.clone(),
self.dual.clone() / real_norm,
)
} }
/// Normalizes this quaternion. /// Normalizes this quaternion.
@ -107,8 +110,8 @@ where
#[inline] #[inline]
pub fn normalize_mut(&mut self) -> T { pub fn normalize_mut(&mut self) -> T {
let real_norm = self.real.norm(); let real_norm = self.real.norm();
self.real /= real_norm; self.real /= real_norm.clone();
self.dual /= real_norm; self.dual /= real_norm.clone();
real_norm real_norm
} }
@ -182,7 +185,7 @@ where
where where
T: RealField, T: RealField,
{ {
let mut res = *self; let mut res = self.clone();
if res.try_inverse_mut() { if res.try_inverse_mut() {
Some(res) Some(res)
} else { } else {
@ -216,7 +219,7 @@ where
{ {
let inverted = self.real.try_inverse_mut(); let inverted = self.real.try_inverse_mut();
if inverted { if inverted {
self.dual = -self.real * self.dual * self.real; self.dual = -self.real.clone() * self.dual.clone() * self.real.clone();
true true
} else { } else {
false false
@ -246,7 +249,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn lerp(&self, other: &Self, t: T) -> Self { pub fn lerp(&self, other: &Self, t: T) -> Self {
self * (T::one() - t) + other * t self * (T::one() - t.clone()) + other * t
} }
} }
@ -293,15 +296,15 @@ where
let dq: Dq<T> = Dq::<T>::deserialize(deserializer)?; let dq: Dq<T> = Dq::<T>::deserialize(deserializer)?;
Ok(Self { Ok(Self {
real: Quaternion::new(dq[3], dq[0], dq[1], dq[2]), real: Quaternion::new(dq[3].clone(), dq[0].clone(), dq[1].clone(), dq[2].clone()),
dual: Quaternion::new(dq[7], dq[4], dq[5], dq[6]), dual: Quaternion::new(dq[7].clone(), dq[4].clone(), dq[5].clone(), dq[6].clone()),
}) })
} }
} }
impl<T: RealField> DualQuaternion<T> { impl<T: RealField> DualQuaternion<T> {
fn to_vector(self) -> OVector<T, U8> { fn to_vector(self) -> OVector<T, U8> {
(*self.as_ref()).into() self.as_ref().clone().into()
} }
} }
@ -315,9 +318,9 @@ impl<T: RealField + AbsDiffEq<Epsilon = T>> AbsDiffEq for DualQuaternion<T> {
#[inline] #[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.to_vector().abs_diff_eq(&other.to_vector(), epsilon) || self.clone().to_vector().abs_diff_eq(&other.clone().to_vector(), epsilon.clone()) ||
// Account for the double-covering of S², i.e. q = -q // Account for the double-covering of S², i.e. q = -q
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-*b, epsilon)) self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-b.clone(), epsilon.clone()))
} }
} }
@ -334,9 +337,9 @@ impl<T: RealField + RelativeEq<Epsilon = T>> RelativeEq for DualQuaternion<T> {
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool { ) -> bool {
self.to_vector().relative_eq(&other.to_vector(), epsilon, max_relative) || self.clone().to_vector().relative_eq(&other.clone().to_vector(), epsilon.clone(), max_relative.clone()) ||
// Account for the double-covering of S², i.e. q = -q // Account for the double-covering of S², i.e. q = -q
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative)) self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.relative_eq(&-b.clone(), epsilon.clone(), max_relative.clone()))
} }
} }
@ -348,9 +351,9 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for DualQuaternion<T> {
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.to_vector().ulps_eq(&other.to_vector(), epsilon, max_ulps) || self.clone().to_vector().ulps_eq(&other.clone().to_vector(), epsilon.clone(), max_ulps.clone()) ||
// Account for the double-covering of S², i.e. q = -q. // Account for the double-covering of S², i.e. q = -q.
self.to_vector().iter().zip(other.to_vector().iter()).all(|(a, b)| a.ulps_eq(&-*b, epsilon, max_ulps)) self.clone().to_vector().iter().zip(other.clone().to_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps.clone()))
} }
} }
@ -381,13 +384,13 @@ impl<T: SimdRealField> Normed for DualQuaternion<T> {
#[inline] #[inline]
fn scale_mut(&mut self, n: Self::Norm) { fn scale_mut(&mut self, n: Self::Norm) {
self.real.scale_mut(n); self.real.scale_mut(n.clone());
self.dual.scale_mut(n); self.dual.scale_mut(n);
} }
#[inline] #[inline]
fn unscale_mut(&mut self, n: Self::Norm) { fn unscale_mut(&mut self, n: Self::Norm) {
self.real.unscale_mut(n); self.real.unscale_mut(n.clone());
self.dual.unscale_mut(n); self.dual.unscale_mut(n);
} }
} }
@ -471,10 +474,10 @@ where
#[inline] #[inline]
#[must_use = "Did you mean to use inverse_mut()?"] #[must_use = "Did you mean to use inverse_mut()?"]
pub fn inverse(&self) -> Self { pub fn inverse(&self) -> Self {
let real = Unit::new_unchecked(self.as_ref().real) let real = Unit::new_unchecked(self.as_ref().real.clone())
.inverse() .inverse()
.into_inner(); .into_inner();
let dual = -real * self.as_ref().dual * real; let dual = -real.clone() * self.as_ref().dual.clone() * real.clone();
UnitDualQuaternion::new_unchecked(DualQuaternion { real, dual }) UnitDualQuaternion::new_unchecked(DualQuaternion { real, dual })
} }
@ -495,8 +498,10 @@ where
#[inline] #[inline]
pub fn inverse_mut(&mut self) { pub fn inverse_mut(&mut self) {
let quat = self.as_mut_unchecked(); let quat = self.as_mut_unchecked();
quat.real = Unit::new_unchecked(quat.real).inverse().into_inner(); quat.real = Unit::new_unchecked(quat.real.clone())
quat.dual = -quat.real * quat.dual * quat.real; .inverse()
.into_inner();
quat.dual = -quat.real.clone() * quat.dual.clone() * quat.real.clone();
} }
/// The unit dual quaternion needed to make `self` and `other` coincide. /// The unit dual quaternion needed to make `self` and `other` coincide.
@ -639,16 +644,16 @@ where
T: RealField, T: RealField,
{ {
let two = T::one() + T::one(); let two = T::one() + T::one();
let half = T::one() / two; let half = T::one() / two.clone();
// Invert one of the quaternions if we've got a longest-path // Invert one of the quaternions if we've got a longest-path
// interpolation. // interpolation.
let other = { let other = {
let dot_product = self.as_ref().real.coords.dot(&other.as_ref().real.coords); let dot_product = self.as_ref().real.coords.dot(&other.as_ref().real.coords);
if dot_product < T::zero() { if dot_product < T::zero() {
-*other -other.clone()
} else { } else {
*other other.clone()
} }
}; };
@ -661,21 +666,21 @@ where
let inverse_norm_squared = T::one() / norm_squared; let inverse_norm_squared = T::one() / norm_squared;
let inverse_norm = inverse_norm_squared.sqrt(); let inverse_norm = inverse_norm_squared.sqrt();
let mut angle = two * difference.real.scalar().acos(); let mut angle = two.clone() * difference.real.scalar().acos();
let mut pitch = -two * difference.dual.scalar() * inverse_norm; let mut pitch = -two * difference.dual.scalar() * inverse_norm.clone();
let direction = difference.real.vector() * inverse_norm; let direction = difference.real.vector() * inverse_norm.clone();
let moment = (difference.dual.vector() let moment = (difference.dual.vector()
- direction * (pitch * difference.real.scalar() * half)) - direction.clone() * (pitch.clone() * difference.real.scalar() * half.clone()))
* inverse_norm; * inverse_norm;
angle *= t; angle *= t.clone();
pitch *= t; pitch *= t;
let sin = (half * angle).sin(); let sin = (half.clone() * angle.clone()).sin();
let cos = (half * angle).cos(); let cos = (half.clone() * angle).cos();
let real = Quaternion::from_parts(cos, direction * sin); let real = Quaternion::from_parts(cos.clone(), direction.clone() * sin.clone());
let dual = Quaternion::from_parts( let dual = Quaternion::from_parts(
-pitch * half * sin, -pitch.clone() * half.clone() * sin.clone(),
moment * sin + direction * (pitch * half * cos), moment * sin + direction * (pitch * half * cos),
); );
@ -703,7 +708,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn rotation(&self) -> UnitQuaternion<T> { pub fn rotation(&self) -> UnitQuaternion<T> {
Unit::new_unchecked(self.as_ref().real) Unit::new_unchecked(self.as_ref().real.clone())
} }
/// Return the translation part of this unit dual quaternion. /// Return the translation part of this unit dual quaternion.
@ -725,7 +730,7 @@ where
pub fn translation(&self) -> Translation3<T> { pub fn translation(&self) -> Translation3<T> {
let two = T::one() + T::one(); let two = T::one() + T::one();
Translation3::from( Translation3::from(
((self.as_ref().dual * self.as_ref().real.conjugate()) * two) ((self.as_ref().dual.clone() * self.as_ref().real.clone().conjugate()) * two)
.vector() .vector()
.into_owned(), .into_owned(),
) )

View File

@ -186,7 +186,7 @@ where
pub fn from_parts(translation: Translation3<T>, rotation: UnitQuaternion<T>) -> Self { pub fn from_parts(translation: Translation3<T>, rotation: UnitQuaternion<T>) -> Self {
let half: T = crate::convert(0.5f64); let half: T = crate::convert(0.5f64);
UnitDualQuaternion::new_unchecked(DualQuaternion { UnitDualQuaternion::new_unchecked(DualQuaternion {
real: rotation.into_inner(), real: rotation.clone().into_inner(),
dual: Quaternion::from_parts(T::zero(), translation.vector) dual: Quaternion::from_parts(T::zero(), translation.vector)
* rotation.into_inner() * rotation.into_inner()
* half, * half,
@ -210,6 +210,8 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn from_isometry(isometry: &Isometry3<T>) -> Self { pub fn from_isometry(isometry: &Isometry3<T>) -> Self {
// TODO: take the isometry by-move instead of cloning it.
let isometry = isometry.clone();
UnitDualQuaternion::from_parts(isometry.translation, isometry.rotation) UnitDualQuaternion::from_parts(isometry.translation, isometry.rotation)
} }

View File

@ -122,7 +122,7 @@ where
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<T2, C, 3> { fn to_superset(&self) -> Transform<T2, C, 3> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
} }
#[inline] #[inline]
@ -141,7 +141,7 @@ impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>>
{ {
#[inline] #[inline]
fn to_superset(&self) -> Matrix4<T2> { fn to_superset(&self) -> Matrix4<T2> {
self.to_homogeneous().to_superset() self.clone().to_homogeneous().to_superset()
} }
#[inline] #[inline]

View File

@ -417,7 +417,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>, self: &'a UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
Output = UnitDualQuaternion<T> => U1, U4; Output = UnitDualQuaternion<T> => U1, U4;
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner())); self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.clone().into_inner()));
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -433,7 +433,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>, self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U3; Output = UnitDualQuaternion<T> => U3, U3;
self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.into_inner())); self * UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(rhs.clone().into_inner()));
'b); 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -449,7 +449,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>, self: &'a UnitQuaternion<T>, rhs: &'b UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U1, U4; Output = UnitDualQuaternion<T> => U1, U4;
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs; UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.clone().into_inner())) * rhs;
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -457,7 +457,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>, self: &'a UnitQuaternion<T>, rhs: UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U3; Output = UnitDualQuaternion<T> => U3, U3;
UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.into_inner())) * rhs; UnitDualQuaternion::<T>::new_unchecked(DualQuaternion::from_real(self.clone().into_inner())) * rhs;
'a); 'a);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -520,7 +520,7 @@ dual_quaternion_op_impl!(
#[allow(clippy::suspicious_arithmetic_impl)] #[allow(clippy::suspicious_arithmetic_impl)]
{ {
UnitDualQuaternion::<T>::new_unchecked( UnitDualQuaternion::<T>::new_unchecked(
DualQuaternion::from_real(self.into_inner()) DualQuaternion::from_real(self.clone().into_inner())
) * rhs.inverse() ) * rhs.inverse()
}; 'a, 'b); }; 'a, 'b);
@ -532,7 +532,7 @@ dual_quaternion_op_impl!(
#[allow(clippy::suspicious_arithmetic_impl)] #[allow(clippy::suspicious_arithmetic_impl)]
{ {
UnitDualQuaternion::<T>::new_unchecked( UnitDualQuaternion::<T>::new_unchecked(
DualQuaternion::from_real(self.into_inner()) DualQuaternion::from_real(self.clone().into_inner())
) * rhs.inverse() ) * rhs.inverse()
}; 'a); }; 'a);
@ -566,7 +566,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U3, U1); (U4, U1), (U3, U1);
self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>, self: &'a UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity()); self * UnitDualQuaternion::<T>::from_parts(rhs.clone(), UnitQuaternion::identity());
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -582,7 +582,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U3, U3); (U4, U1), (U3, U3);
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>, self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
self * UnitDualQuaternion::<T>::from_parts(*rhs, UnitQuaternion::identity()); self * UnitDualQuaternion::<T>::from_parts(rhs.clone(), UnitQuaternion::identity());
'b); 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -634,7 +634,7 @@ dual_quaternion_op_impl!(
(U3, U1), (U4, U1); (U3, U1), (U4, U1);
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>, self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs; UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) * rhs;
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -642,7 +642,7 @@ dual_quaternion_op_impl!(
(U3, U1), (U4, U1); (U3, U1), (U4, U1);
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>, self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) * rhs; UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) * rhs;
'a); 'a);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -666,7 +666,7 @@ dual_quaternion_op_impl!(
(U3, U1), (U4, U1); (U3, U1), (U4, U1);
self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>, self: &'b Translation3<T>, rhs: &'a UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs; UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) / rhs;
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -674,7 +674,7 @@ dual_quaternion_op_impl!(
(U3, U1), (U4, U1); (U3, U1), (U4, U1);
self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>, self: &'a Translation3<T>, rhs: UnitDualQuaternion<T>,
Output = UnitDualQuaternion<T> => U3, U1; Output = UnitDualQuaternion<T> => U3, U1;
UnitDualQuaternion::<T>::from_parts(*self, UnitQuaternion::identity()) / rhs; UnitDualQuaternion::<T>::from_parts(self.clone(), UnitQuaternion::identity()) / rhs;
'a); 'a);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -828,7 +828,7 @@ dual_quaternion_op_impl!(
(U4, U1), (U3, U1) for SB: Storage<T, U3> ; (U4, U1), (U3, U1) for SB: Storage<T, U3> ;
self: &'a UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>, self: &'a UnitDualQuaternion<T>, rhs: &'b Vector<T, U3, SB>,
Output = Vector3<T> => U3, U1; Output = Vector3<T> => U3, U1;
Unit::new_unchecked(self.as_ref().real) * rhs; Unit::new_unchecked(self.as_ref().real.clone()) * rhs;
'a, 'b); 'a, 'b);
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -862,9 +862,9 @@ dual_quaternion_op_impl!(
Output = Point3<T> => U3, U1; Output = Point3<T> => U3, U1;
{ {
let two: T = crate::convert(2.0f64); let two: T = crate::convert(2.0f64);
let q_point = Quaternion::from_parts(T::zero(), rhs.coords); let q_point = Quaternion::from_parts(T::zero(), rhs.coords.clone());
Point::from( Point::from(
((self.as_ref().real * q_point + self.as_ref().dual * two) * self.as_ref().real.conjugate()) ((self.as_ref().real.clone() * q_point + self.as_ref().dual.clone() * two) * self.as_ref().real.clone().conjugate())
.vector() .vector()
.into_owned(), .into_owned(),
) )
@ -1117,7 +1117,7 @@ dual_quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>; self: UnitDualQuaternion<T>, rhs: &'b UnitQuaternion<T>;
*self *= *rhs; 'b); *self *= rhs.clone(); 'b);
// UnitDualQuaternion ÷= UnitQuaternion // UnitDualQuaternion ÷= UnitQuaternion
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -1153,7 +1153,7 @@ dual_quaternion_op_impl!(
MulAssign, mul_assign; MulAssign, mul_assign;
(U4, U1), (U4, U1); (U4, U1), (U4, U1);
self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>; self: UnitDualQuaternion<T>, rhs: &'b Translation3<T>;
*self *= *rhs; 'b); *self *= rhs.clone(); 'b);
// UnitDualQuaternion ÷= Translation3 // UnitDualQuaternion ÷= Translation3
dual_quaternion_op_impl!( dual_quaternion_op_impl!(
@ -1219,8 +1219,8 @@ macro_rules! scalar_op_impl(
#[inline] #[inline]
fn $op(self, n: T) -> Self::Output { fn $op(self, n: T) -> Self::Output {
DualQuaternion::from_real_and_dual( DualQuaternion::from_real_and_dual(
self.real.$op(n), self.real.clone().$op(n.clone()),
self.dual.$op(n) self.dual.clone().$op(n)
) )
} }
} }
@ -1232,8 +1232,8 @@ macro_rules! scalar_op_impl(
#[inline] #[inline]
fn $op(self, n: T) -> Self::Output { fn $op(self, n: T) -> Self::Output {
DualQuaternion::from_real_and_dual( DualQuaternion::from_real_and_dual(
self.real.$op(n), self.real.clone().$op(n.clone()),
self.dual.$op(n) self.dual.clone().$op(n)
) )
} }
} }
@ -1243,7 +1243,7 @@ macro_rules! scalar_op_impl(
#[inline] #[inline]
fn $op_assign(&mut self, n: T) { fn $op_assign(&mut self, n: T) {
self.real.$op_assign(n); self.real.$op_assign(n.clone());
self.dual.$op_assign(n); self.dual.$op_assign(n);
} }
} }

View File

@ -272,7 +272,7 @@ where
#[must_use] #[must_use]
pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self { pub fn inv_mul(&self, rhs: &Isometry<T, R, D>) -> Self {
let inv_rot1 = self.rotation.inverse(); let inv_rot1 = self.rotation.inverse();
let tr_12 = rhs.translation.vector - self.translation.vector; let tr_12 = &rhs.translation.vector - &self.translation.vector;
Isometry::from_parts( Isometry::from_parts(
inv_rot1.transform_vector(&tr_12).into(), inv_rot1.transform_vector(&tr_12).into(),
inv_rot1 * rhs.rotation.clone(), inv_rot1 * rhs.rotation.clone(),
@ -437,7 +437,7 @@ where
#[must_use] #[must_use]
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> { pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
self.rotation self.rotation
.inverse_transform_point(&(pt - self.translation.vector)) .inverse_transform_point(&(pt - &self.translation.vector))
} }
/// Transform the given vector by the inverse of this isometry, ignoring the /// Transform the given vector by the inverse of this isometry, ignoring the
@ -574,7 +574,7 @@ where
impl<T: RealField, R, const D: usize> AbsDiffEq for Isometry<T, R, D> impl<T: RealField, R, const D: usize> AbsDiffEq for Isometry<T, R, D>
where where
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -585,7 +585,8 @@ where
#[inline] #[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.translation.abs_diff_eq(&other.translation, epsilon) self.translation
.abs_diff_eq(&other.translation, epsilon.clone())
&& self.rotation.abs_diff_eq(&other.rotation, epsilon) && self.rotation.abs_diff_eq(&other.rotation, epsilon)
} }
} }
@ -593,7 +594,7 @@ where
impl<T: RealField, R, const D: usize> RelativeEq for Isometry<T, R, D> impl<T: RealField, R, const D: usize> RelativeEq for Isometry<T, R, D>
where where
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -608,7 +609,7 @@ where
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool { ) -> bool {
self.translation self.translation
.relative_eq(&other.translation, epsilon, max_relative) .relative_eq(&other.translation, epsilon.clone(), max_relative.clone())
&& self && self
.rotation .rotation
.relative_eq(&other.rotation, epsilon, max_relative) .relative_eq(&other.rotation, epsilon, max_relative)
@ -618,7 +619,7 @@ where
impl<T: RealField, R, const D: usize> UlpsEq for Isometry<T, R, D> impl<T: RealField, R, const D: usize> UlpsEq for Isometry<T, R, D>
where where
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {
@ -628,7 +629,7 @@ where
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.translation self.translation
.ulps_eq(&other.translation, epsilon, max_ulps) .ulps_eq(&other.translation, epsilon.clone(), max_ulps.clone())
&& self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps) && self.rotation.ulps_eq(&other.rotation, epsilon, max_ulps)
} }
} }

View File

@ -31,7 +31,10 @@ impl<T: SimdRealField> Isometry3<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.slerp(&other.rotation, t); let rot = self.rotation.slerp(&other.rotation, t);
Self::from_parts(tr.into(), rot) Self::from_parts(tr.into(), rot)
} }
@ -65,7 +68,10 @@ impl<T: SimdRealField> Isometry3<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?; let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
Some(Self::from_parts(tr.into(), rot)) Some(Self::from_parts(tr.into(), rot))
} }
@ -101,7 +107,10 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.slerp(&other.rotation, t); let rot = self.rotation.slerp(&other.rotation, t);
Self::from_parts(tr.into(), rot) Self::from_parts(tr.into(), rot)
} }
@ -135,7 +144,10 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?; let rot = self.rotation.try_slerp(&other.rotation, t, epsilon)?;
Some(Self::from_parts(tr.into(), rot)) Some(Self::from_parts(tr.into(), rot))
} }
@ -172,7 +184,10 @@ impl<T: SimdRealField> Isometry2<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.slerp(&other.rotation, t); let rot = self.rotation.slerp(&other.rotation, t);
Self::from_parts(tr.into(), rot) Self::from_parts(tr.into(), rot)
} }
@ -209,7 +224,10 @@ impl<T: SimdRealField> IsometryMatrix2<T> {
where where
T: RealField, T: RealField,
{ {
let tr = self.translation.vector.lerp(&other.translation.vector, t); let tr = self
.translation
.vector
.lerp(&other.translation.vector, t.clone());
let rot = self.rotation.slerp(&other.rotation, t); let rot = self.rotation.slerp(&other.rotation, t);
Self::from_parts(tr.into(), rot) Self::from_parts(tr.into(), rot)
} }

View File

@ -201,7 +201,7 @@ md_assign_impl_all!(
const D; for; where; const D; for; where;
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>; self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= *rhs; [ref] => self.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(
@ -220,7 +220,7 @@ md_assign_impl_all!(
const; for; where; const; for; where;
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>; self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= *rhs; [ref] => self.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(
@ -239,7 +239,7 @@ md_assign_impl_all!(
const; for; where; const; for; where;
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>; self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
[val] => self.rotation *= rhs; [val] => self.rotation *= rhs;
[ref] => self.rotation *= *rhs; [ref] => self.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(
@ -368,9 +368,9 @@ isometry_from_composition_impl_all!(
D; D;
self: Rotation<T, D>, right: Translation<T, D>, Output = Isometry<T, Rotation<T, D>, D>; self: Rotation<T, D>, right: Translation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
[ref val] => Isometry::from_parts(Translation::from(self * right.vector), *self); [ref val] => Isometry::from_parts(Translation::from(self * right.vector), self.clone());
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
[ref ref] => Isometry::from_parts(Translation::from(self * &right.vector), *self); [ref ref] => Isometry::from_parts(Translation::from(self * &right.vector), self.clone());
); );
// UnitQuaternion × Translation // UnitQuaternion × Translation
@ -380,9 +380,9 @@ isometry_from_composition_impl_all!(
self: UnitQuaternion<T>, right: Translation<T, 3>, self: UnitQuaternion<T>, right: Translation<T, 3>,
Output = Isometry<T, UnitQuaternion<T>, 3>; Output = Isometry<T, UnitQuaternion<T>, 3>;
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self); [ref val] => Isometry::from_parts(Translation::from( self * right.vector), self.clone());
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), *self); [ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), self.clone());
); );
// Isometry × Rotation // Isometry × Rotation
@ -392,9 +392,9 @@ isometry_from_composition_impl_all!(
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>, self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
Output = Isometry<T, Rotation<T, D>, D>; Output = Isometry<T, Rotation<T, D>, D>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
); );
// Rotation × Isometry // Rotation × Isometry
@ -419,9 +419,9 @@ isometry_from_composition_impl_all!(
self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>, self: Isometry<T, Rotation<T, D>, D>, rhs: Rotation<T, D>,
Output = Isometry<T, Rotation<T, D>, D>; Output = Isometry<T, Rotation<T, D>, D>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
); );
// Rotation ÷ Isometry // Rotation ÷ Isometry
@ -444,9 +444,9 @@ isometry_from_composition_impl_all!(
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>, self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
Output = Isometry<T, UnitQuaternion<T>, 3>; Output = Isometry<T, UnitQuaternion<T>, 3>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
); );
// UnitQuaternion × Isometry // UnitQuaternion × Isometry
@ -471,9 +471,9 @@ isometry_from_composition_impl_all!(
self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>, self: Isometry<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>,
Output = Isometry<T, UnitQuaternion<T>, 3>; Output = Isometry<T, UnitQuaternion<T>, 3>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
); );
// UnitQuaternion ÷ Isometry // UnitQuaternion ÷ Isometry
@ -495,9 +495,9 @@ isometry_from_composition_impl_all!(
D; D;
self: Translation<T, D>, right: Rotation<T, D>, Output = Isometry<T, Rotation<T, D>, D>; self: Translation<T, D>, right: Rotation<T, D>, Output = Isometry<T, Rotation<T, D>, D>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(*self, right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, *right); [val ref] => Isometry::from_parts(self, right.clone());
[ref ref] => Isometry::from_parts(*self, *right); [ref ref] => Isometry::from_parts(self.clone(), right.clone());
); );
// Translation × UnitQuaternion // Translation × UnitQuaternion
@ -506,9 +506,9 @@ isometry_from_composition_impl_all!(
; ;
self: Translation<T, 3>, right: UnitQuaternion<T>, Output = Isometry<T, UnitQuaternion<T>, 3>; self: Translation<T, 3>, right: UnitQuaternion<T>, Output = Isometry<T, UnitQuaternion<T>, 3>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(*self, right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, *right); [val ref] => Isometry::from_parts(self, right.clone());
[ref ref] => Isometry::from_parts(*self, *right); [ref ref] => Isometry::from_parts(self.clone(), right.clone());
); );
// Isometry × UnitComplex // Isometry × UnitComplex
@ -518,9 +518,9 @@ isometry_from_composition_impl_all!(
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>, self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
Output = Isometry<T, UnitComplex<T>, 2>; Output = Isometry<T, UnitComplex<T>, 2>;
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs); [val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation * rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation * *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
); );
// Isometry ÷ UnitComplex // Isometry ÷ UnitComplex
@ -530,7 +530,7 @@ isometry_from_composition_impl_all!(
self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>, self: Isometry<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>,
Output = Isometry<T, UnitComplex<T>, 2>; Output = Isometry<T, UnitComplex<T>, 2>;
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs); [val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
[ref val] => Isometry::from_parts(self.translation, self.rotation / rhs); [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs);
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
[ref ref] => Isometry::from_parts(self.translation, self.rotation / *rhs); [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
); );

View File

@ -23,12 +23,12 @@ pub struct Orthographic3<T> {
matrix: Matrix4<T>, matrix: Matrix4<T>,
} }
impl<T: RealField> Copy for Orthographic3<T> {} impl<T: RealField + Copy> Copy for Orthographic3<T> {}
impl<T: RealField> Clone for Orthographic3<T> { impl<T: RealField> Clone for Orthographic3<T> {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self::from_matrix_unchecked(self.matrix) Self::from_matrix_unchecked(self.matrix.clone())
} }
} }
@ -175,13 +175,13 @@ impl<T: RealField> Orthographic3<T> {
); );
let half: T = crate::convert(0.5); let half: T = crate::convert(0.5);
let width = zfar * (vfov * half).tan(); let width = zfar.clone() * (vfov.clone() * half.clone()).tan();
let height = width / aspect; let height = width.clone() / aspect;
Self::new( Self::new(
-width * half, -width.clone() * half.clone(),
width * half, width * half.clone(),
-height * half, -height.clone() * half.clone(),
height * half, height * half,
znear, znear,
zfar, zfar,
@ -208,19 +208,19 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse(&self) -> Matrix4<T> { pub fn inverse(&self) -> Matrix4<T> {
let mut res = self.to_homogeneous(); let mut res = self.clone().to_homogeneous();
let inv_m11 = T::one() / self.matrix[(0, 0)]; let inv_m11 = T::one() / self.matrix[(0, 0)].clone();
let inv_m22 = T::one() / self.matrix[(1, 1)]; let inv_m22 = T::one() / self.matrix[(1, 1)].clone();
let inv_m33 = T::one() / self.matrix[(2, 2)]; let inv_m33 = T::one() / self.matrix[(2, 2)].clone();
res[(0, 0)] = inv_m11; res[(0, 0)] = inv_m11.clone();
res[(1, 1)] = inv_m22; res[(1, 1)] = inv_m22.clone();
res[(2, 2)] = inv_m33; res[(2, 2)] = inv_m33.clone();
res[(0, 3)] = -self.matrix[(0, 3)] * inv_m11; res[(0, 3)] = -self.matrix[(0, 3)].clone() * inv_m11;
res[(1, 3)] = -self.matrix[(1, 3)] * inv_m22; res[(1, 3)] = -self.matrix[(1, 3)].clone() * inv_m22;
res[(2, 3)] = -self.matrix[(2, 3)] * inv_m33; res[(2, 3)] = -self.matrix[(2, 3)].clone() * inv_m33;
res res
} }
@ -335,7 +335,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn left(&self) -> T { pub fn left(&self) -> T {
(-T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)] (-T::one() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone()
} }
/// The right offset of the view cuboid. /// The right offset of the view cuboid.
@ -352,7 +352,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn right(&self) -> T { pub fn right(&self) -> T {
(T::one() - self.matrix[(0, 3)]) / self.matrix[(0, 0)] (T::one() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone()
} }
/// The bottom offset of the view cuboid. /// The bottom offset of the view cuboid.
@ -369,7 +369,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn bottom(&self) -> T { pub fn bottom(&self) -> T {
(-T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)] (-T::one() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone()
} }
/// The top offset of the view cuboid. /// The top offset of the view cuboid.
@ -386,7 +386,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn top(&self) -> T { pub fn top(&self) -> T {
(T::one() - self.matrix[(1, 3)]) / self.matrix[(1, 1)] (T::one() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone()
} }
/// The near plane offset of the view cuboid. /// The near plane offset of the view cuboid.
@ -403,7 +403,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn znear(&self) -> T { pub fn znear(&self) -> T {
(T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)] (T::one() + self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone()
} }
/// The far plane offset of the view cuboid. /// The far plane offset of the view cuboid.
@ -420,7 +420,7 @@ impl<T: RealField> Orthographic3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn zfar(&self) -> T { pub fn zfar(&self) -> T {
(-T::one() + self.matrix[(2, 3)]) / self.matrix[(2, 2)] (-T::one() + self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone()
} }
// TODO: when we get specialization, specialize the Mul impl instead. // TODO: when we get specialization, specialize the Mul impl instead.
@ -454,9 +454,9 @@ impl<T: RealField> Orthographic3<T> {
#[must_use] #[must_use]
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> { pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
Point3::new( Point3::new(
self.matrix[(0, 0)] * p[0] + self.matrix[(0, 3)], self.matrix[(0, 0)].clone() * p[0].clone() + self.matrix[(0, 3)].clone(),
self.matrix[(1, 1)] * p[1] + self.matrix[(1, 3)], self.matrix[(1, 1)].clone() * p[1].clone() + self.matrix[(1, 3)].clone(),
self.matrix[(2, 2)] * p[2] + self.matrix[(2, 3)], self.matrix[(2, 2)].clone() * p[2].clone() + self.matrix[(2, 3)].clone(),
) )
} }
@ -490,9 +490,9 @@ impl<T: RealField> Orthographic3<T> {
#[must_use] #[must_use]
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> { pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
Point3::new( Point3::new(
(p[0] - self.matrix[(0, 3)]) / self.matrix[(0, 0)], (p[0].clone() - self.matrix[(0, 3)].clone()) / self.matrix[(0, 0)].clone(),
(p[1] - self.matrix[(1, 3)]) / self.matrix[(1, 1)], (p[1].clone() - self.matrix[(1, 3)].clone()) / self.matrix[(1, 1)].clone(),
(p[2] - self.matrix[(2, 3)]) / self.matrix[(2, 2)], (p[2].clone() - self.matrix[(2, 3)].clone()) / self.matrix[(2, 2)].clone(),
) )
} }
@ -522,9 +522,9 @@ impl<T: RealField> Orthographic3<T> {
SB: Storage<T, U3>, SB: Storage<T, U3>,
{ {
Vector3::new( Vector3::new(
self.matrix[(0, 0)] * p[0], self.matrix[(0, 0)].clone() * p[0].clone(),
self.matrix[(1, 1)] * p[1], self.matrix[(1, 1)].clone() * p[1].clone(),
self.matrix[(2, 2)] * p[2], self.matrix[(2, 2)].clone() * p[2].clone(),
) )
} }
@ -663,8 +663,8 @@ impl<T: RealField> Orthographic3<T> {
left != right, left != right,
"The left corner must not be equal to the right corner." "The left corner must not be equal to the right corner."
); );
self.matrix[(0, 0)] = crate::convert::<_, T>(2.0) / (right - left); self.matrix[(0, 0)] = crate::convert::<_, T>(2.0) / (right.clone() - left.clone());
self.matrix[(0, 3)] = -(right + left) / (right - left); self.matrix[(0, 3)] = -(right.clone() + left.clone()) / (right - left);
} }
/// Sets the view cuboid offsets along the `y` axis. /// Sets the view cuboid offsets along the `y` axis.
@ -684,12 +684,12 @@ impl<T: RealField> Orthographic3<T> {
/// ``` /// ```
#[inline] #[inline]
pub fn set_bottom_and_top(&mut self, bottom: T, top: T) { pub fn set_bottom_and_top(&mut self, bottom: T, top: T) {
assert!( assert_ne!(
bottom != top, bottom, top,
"The top corner must not be equal to the bottom corner." "The top corner must not be equal to the bottom corner."
); );
self.matrix[(1, 1)] = crate::convert::<_, T>(2.0) / (top - bottom); self.matrix[(1, 1)] = crate::convert::<_, T>(2.0) / (top.clone() - bottom.clone());
self.matrix[(1, 3)] = -(top + bottom) / (top - bottom); self.matrix[(1, 3)] = -(top.clone() + bottom.clone()) / (top - bottom);
} }
/// Sets the near and far plane offsets of the view cuboid. /// Sets the near and far plane offsets of the view cuboid.
@ -713,8 +713,8 @@ impl<T: RealField> Orthographic3<T> {
zfar != znear, zfar != znear,
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
self.matrix[(2, 2)] = -crate::convert::<_, T>(2.0) / (zfar - znear); self.matrix[(2, 2)] = -crate::convert::<_, T>(2.0) / (zfar.clone() - znear.clone());
self.matrix[(2, 3)] = -(zfar + znear) / (zfar - znear); self.matrix[(2, 3)] = -(zfar.clone() + znear.clone()) / (zfar - znear);
} }
} }

View File

@ -24,12 +24,12 @@ pub struct Perspective3<T> {
matrix: Matrix4<T>, matrix: Matrix4<T>,
} }
impl<T: RealField> Copy for Perspective3<T> {} impl<T: RealField + Copy> Copy for Perspective3<T> {}
impl<T: RealField> Clone for Perspective3<T> { impl<T: RealField> Clone for Perspective3<T> {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self::from_matrix_unchecked(self.matrix) Self::from_matrix_unchecked(self.matrix.clone())
} }
} }
@ -99,7 +99,7 @@ impl<T: RealField> Perspective3<T> {
/// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes. /// Creates a new perspective matrix from the aspect ratio, y field of view, and near/far planes.
pub fn new(aspect: T, fovy: T, znear: T, zfar: T) -> Self { pub fn new(aspect: T, fovy: T, znear: T, zfar: T) -> Self {
assert!( assert!(
!relative_eq!(zfar - znear, T::zero()), relative_ne!(zfar, znear),
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
assert!( assert!(
@ -124,18 +124,18 @@ impl<T: RealField> Perspective3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse(&self) -> Matrix4<T> { pub fn inverse(&self) -> Matrix4<T> {
let mut res = self.to_homogeneous(); let mut res = self.clone().to_homogeneous();
res[(0, 0)] = T::one() / self.matrix[(0, 0)]; res[(0, 0)] = T::one() / self.matrix[(0, 0)].clone();
res[(1, 1)] = T::one() / self.matrix[(1, 1)]; res[(1, 1)] = T::one() / self.matrix[(1, 1)].clone();
res[(2, 2)] = T::zero(); res[(2, 2)] = T::zero();
let m23 = self.matrix[(2, 3)]; let m23 = self.matrix[(2, 3)].clone();
let m32 = self.matrix[(3, 2)]; let m32 = self.matrix[(3, 2)].clone();
res[(2, 3)] = T::one() / m32; res[(2, 3)] = T::one() / m32.clone();
res[(3, 2)] = T::one() / m23; res[(3, 2)] = T::one() / m23.clone();
res[(3, 3)] = -self.matrix[(2, 2)] / (m23 * m32); res[(3, 3)] = -self.matrix[(2, 2)].clone() / (m23 * m32);
res res
} }
@ -186,33 +186,35 @@ impl<T: RealField> Perspective3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn aspect(&self) -> T { pub fn aspect(&self) -> T {
self.matrix[(1, 1)] / self.matrix[(0, 0)] self.matrix[(1, 1)].clone() / self.matrix[(0, 0)].clone()
} }
/// Gets the y field of view of the view frustum. /// Gets the y field of view of the view frustum.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn fovy(&self) -> T { pub fn fovy(&self) -> T {
(T::one() / self.matrix[(1, 1)]).atan() * crate::convert(2.0) (T::one() / self.matrix[(1, 1)].clone()).atan() * crate::convert(2.0)
} }
/// Gets the near plane offset of the view frustum. /// Gets the near plane offset of the view frustum.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn znear(&self) -> T { pub fn znear(&self) -> T {
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one()); let ratio =
(-self.matrix[(2, 2)].clone() + T::one()) / (-self.matrix[(2, 2)].clone() - T::one());
self.matrix[(2, 3)] / (ratio * crate::convert(2.0)) self.matrix[(2, 3)].clone() / (ratio * crate::convert(2.0))
- self.matrix[(2, 3)] / crate::convert(2.0) - self.matrix[(2, 3)].clone() / crate::convert(2.0)
} }
/// Gets the far plane offset of the view frustum. /// Gets the far plane offset of the view frustum.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn zfar(&self) -> T { pub fn zfar(&self) -> T {
let ratio = (-self.matrix[(2, 2)] + T::one()) / (-self.matrix[(2, 2)] - T::one()); let ratio =
(-self.matrix[(2, 2)].clone() + T::one()) / (-self.matrix[(2, 2)].clone() - T::one());
(self.matrix[(2, 3)] - ratio * self.matrix[(2, 3)]) / crate::convert(2.0) (self.matrix[(2, 3)].clone() - ratio * self.matrix[(2, 3)].clone()) / crate::convert(2.0)
} }
// TODO: add a method to retrieve znear and zfar simultaneously? // TODO: add a method to retrieve znear and zfar simultaneously?
@ -222,11 +224,12 @@ impl<T: RealField> Perspective3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn project_point(&self, p: &Point3<T>) -> Point3<T> { pub fn project_point(&self, p: &Point3<T>) -> Point3<T> {
let inverse_denom = -T::one() / p[2]; let inverse_denom = -T::one() / p[2].clone();
Point3::new( Point3::new(
self.matrix[(0, 0)] * p[0] * inverse_denom, self.matrix[(0, 0)].clone() * p[0].clone() * inverse_denom.clone(),
self.matrix[(1, 1)] * p[1] * inverse_denom, self.matrix[(1, 1)].clone() * p[1].clone() * inverse_denom.clone(),
(self.matrix[(2, 2)] * p[2] + self.matrix[(2, 3)]) * inverse_denom, (self.matrix[(2, 2)].clone() * p[2].clone() + self.matrix[(2, 3)].clone())
* inverse_denom,
) )
} }
@ -234,11 +237,12 @@ impl<T: RealField> Perspective3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> { pub fn unproject_point(&self, p: &Point3<T>) -> Point3<T> {
let inverse_denom = self.matrix[(2, 3)] / (p[2] + self.matrix[(2, 2)]); let inverse_denom =
self.matrix[(2, 3)].clone() / (p[2].clone() + self.matrix[(2, 2)].clone());
Point3::new( Point3::new(
p[0] * inverse_denom / self.matrix[(0, 0)], p[0].clone() * inverse_denom.clone() / self.matrix[(0, 0)].clone(),
p[1] * inverse_denom / self.matrix[(1, 1)], p[1].clone() * inverse_denom.clone() / self.matrix[(1, 1)].clone(),
-inverse_denom, -inverse_denom,
) )
} }
@ -251,11 +255,11 @@ impl<T: RealField> Perspective3<T> {
where where
SB: Storage<T, U3>, SB: Storage<T, U3>,
{ {
let inverse_denom = -T::one() / p[2]; let inverse_denom = -T::one() / p[2].clone();
Vector3::new( Vector3::new(
self.matrix[(0, 0)] * p[0] * inverse_denom, self.matrix[(0, 0)].clone() * p[0].clone() * inverse_denom.clone(),
self.matrix[(1, 1)] * p[1] * inverse_denom, self.matrix[(1, 1)].clone() * p[1].clone() * inverse_denom,
self.matrix[(2, 2)], self.matrix[(2, 2)].clone(),
) )
} }
@ -267,15 +271,15 @@ impl<T: RealField> Perspective3<T> {
!relative_eq!(aspect, T::zero()), !relative_eq!(aspect, T::zero()),
"The aspect ratio must not be zero." "The aspect ratio must not be zero."
); );
self.matrix[(0, 0)] = self.matrix[(1, 1)] / aspect; self.matrix[(0, 0)] = self.matrix[(1, 1)].clone() / aspect;
} }
/// Updates this perspective with a new y field of view of the view frustum. /// Updates this perspective with a new y field of view of the view frustum.
#[inline] #[inline]
pub fn set_fovy(&mut self, fovy: T) { pub fn set_fovy(&mut self, fovy: T) {
let old_m22 = self.matrix[(1, 1)]; let old_m22 = self.matrix[(1, 1)].clone();
let new_m22 = T::one() / (fovy / crate::convert(2.0)).tan(); let new_m22 = T::one() / (fovy / crate::convert(2.0)).tan();
self.matrix[(1, 1)] = new_m22; self.matrix[(1, 1)] = new_m22.clone();
self.matrix[(0, 0)] *= new_m22 / old_m22; self.matrix[(0, 0)] *= new_m22 / old_m22;
} }
@ -296,8 +300,8 @@ impl<T: RealField> Perspective3<T> {
/// Updates this perspective matrix with new near and far plane offsets of the view frustum. /// Updates this perspective matrix with new near and far plane offsets of the view frustum.
#[inline] #[inline]
pub fn set_znear_and_zfar(&mut self, znear: T, zfar: T) { pub fn set_znear_and_zfar(&mut self, znear: T, zfar: T) {
self.matrix[(2, 2)] = (zfar + znear) / (znear - zfar); self.matrix[(2, 2)] = (zfar.clone() + znear.clone()) / (znear.clone() - zfar.clone());
self.matrix[(2, 3)] = zfar * znear * crate::convert(2.0) / (znear - zfar); self.matrix[(2, 3)] = zfar.clone() * znear.clone() * crate::convert(2.0) / (znear - zfar);
} }
} }
@ -310,8 +314,8 @@ where
fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Perspective3<T> { fn sample<R: Rng + ?Sized>(&self, r: &mut R) -> Perspective3<T> {
use crate::base::helper; use crate::base::helper;
let znear = r.gen(); let znear = r.gen();
let zfar = helper::reject_rand(r, |&x: &T| !(x - znear).is_zero()); let zfar = helper::reject_rand(r, |x: &T| !(x.clone() - znear.clone()).is_zero());
let aspect = helper::reject_rand(r, |&x: &T| !x.is_zero()); let aspect = helper::reject_rand(r, |x: &T| !x.is_zero());
Perspective3::new(aspect, r.gen(), znear, zfar) Perspective3::new(aspect, r.gen(), znear, zfar)
} }
@ -321,9 +325,9 @@ where
impl<T: RealField + Arbitrary> Arbitrary for Perspective3<T> { impl<T: RealField + Arbitrary> Arbitrary for Perspective3<T> {
fn arbitrary(g: &mut Gen) -> Self { fn arbitrary(g: &mut Gen) -> Self {
use crate::base::helper; use crate::base::helper;
let znear = Arbitrary::arbitrary(g); let znear: T = Arbitrary::arbitrary(g);
let zfar = helper::reject(g, |&x: &T| !(x - znear).is_zero()); let zfar = helper::reject(g, |x: &T| !(x.clone() - znear.clone()).is_zero());
let aspect = helper::reject(g, |&x: &T| !x.is_zero()); let aspect = helper::reject(g, |x: &T| !x.is_zero());
Self::new(aspect, Arbitrary::arbitrary(g), znear, zfar) Self::new(aspect, Arbitrary::arbitrary(g), znear, zfar)
} }

View File

@ -323,7 +323,7 @@ where
impl<T: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for OPoint<T, D> impl<T: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for OPoint<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -341,7 +341,7 @@ where
impl<T: Scalar + RelativeEq, D: DimName> RelativeEq for OPoint<T, D> impl<T: Scalar + RelativeEq, D: DimName> RelativeEq for OPoint<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
{ {
#[inline] #[inline]
@ -363,7 +363,7 @@ where
impl<T: Scalar + UlpsEq, D: DimName> UlpsEq for OPoint<T, D> impl<T: Scalar + UlpsEq, D: DimName> UlpsEq for OPoint<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D>, DefaultAllocator: Allocator<T, D>,
{ {
#[inline] #[inline]

View File

@ -104,8 +104,7 @@ where
DefaultAllocator: Allocator<T, DimNameSum<D, U1>>, DefaultAllocator: Allocator<T, DimNameSum<D, U1>>,
{ {
if !v[D::dim()].is_zero() { if !v[D::dim()].is_zero() {
let coords = let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone();
Some(Self::from(coords)) Some(Self::from(coords))
} else { } else {
None None

View File

@ -66,7 +66,7 @@ where
#[inline] #[inline]
fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self { fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone(); let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
Self { Self {
coords: crate::convert_unchecked(coords), coords: crate::convert_unchecked(coords),
} }

View File

@ -208,7 +208,7 @@ where
#[inline] #[inline]
#[must_use = "Did you mean to use conjugate_mut()?"] #[must_use = "Did you mean to use conjugate_mut()?"]
pub fn conjugate(&self) -> Self { pub fn conjugate(&self) -> Self {
Self::from_parts(self.w, -self.imag()) Self::from_parts(self.w.clone(), -self.imag())
} }
/// Linear interpolation between two quaternion. /// Linear interpolation between two quaternion.
@ -226,7 +226,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn lerp(&self, other: &Self, t: T) -> Self { pub fn lerp(&self, other: &Self, t: T) -> Self {
self * (T::one() - t) + other * t self * (T::one() - t.clone()) + other * t
} }
/// The vector part `(i, j, k)` of this quaternion. /// The vector part `(i, j, k)` of this quaternion.
@ -256,7 +256,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn scalar(&self) -> T { pub fn scalar(&self) -> T {
self.coords[3] self.coords[3].clone()
} }
/// Reinterprets this quaternion as a 4D vector. /// Reinterprets this quaternion as a 4D vector.
@ -385,7 +385,7 @@ where
where where
T: RealField, T: RealField,
{ {
let mut res = *self; let mut res = self.clone();
if res.try_inverse_mut() { if res.try_inverse_mut() {
Some(res) Some(res)
@ -401,7 +401,7 @@ where
#[must_use = "Did you mean to use try_inverse_mut()?"] #[must_use = "Did you mean to use try_inverse_mut()?"]
pub fn simd_try_inverse(&self) -> SimdOption<Self> { pub fn simd_try_inverse(&self) -> SimdOption<Self> {
let norm_squared = self.norm_squared(); let norm_squared = self.norm_squared();
let ge = norm_squared.simd_ge(T::simd_default_epsilon()); let ge = norm_squared.clone().simd_ge(T::simd_default_epsilon());
SimdOption::new(self.conjugate() / norm_squared, ge) SimdOption::new(self.conjugate() / norm_squared, ge)
} }
@ -511,7 +511,7 @@ where
where where
T: RealField, T: RealField,
{ {
if let Some((q, n)) = Unit::try_new_and_get(*self, T::zero()) { if let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) {
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) { if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) {
let angle = q.angle() / crate::convert(2.0f64); let angle = q.angle() / crate::convert(2.0f64);
@ -540,7 +540,7 @@ where
let v = self.vector(); let v = self.vector();
let s = self.scalar(); let s = self.scalar();
Self::from_parts(n.simd_ln(), v.normalize() * (s / n).simd_acos()) Self::from_parts(n.clone().simd_ln(), v.normalize() * (s / n).simd_acos())
} }
/// Compute the exponential of a quaternion. /// Compute the exponential of a quaternion.
@ -577,11 +577,11 @@ where
pub fn exp_eps(&self, eps: T) -> Self { pub fn exp_eps(&self, eps: T) -> Self {
let v = self.vector(); let v = self.vector();
let nn = v.norm_squared(); let nn = v.norm_squared();
let le = nn.simd_le(eps * eps); let le = nn.clone().simd_le(eps.clone() * eps);
le.if_else(Self::identity, || { le.if_else(Self::identity, || {
let w_exp = self.scalar().simd_exp(); let w_exp = self.scalar().simd_exp();
let n = nn.simd_sqrt(); let n = nn.simd_sqrt();
let nv = v * (w_exp * n.simd_sin() / n); let nv = v * (w_exp.clone() * n.clone().simd_sin() / n.clone());
Self::from_parts(w_exp * n.simd_cos(), nv) Self::from_parts(w_exp * n.simd_cos(), nv)
}) })
@ -648,9 +648,9 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn conjugate_mut(&mut self) { pub fn conjugate_mut(&mut self) {
self.coords[0] = -self.coords[0]; self.coords[0] = -self.coords[0].clone();
self.coords[1] = -self.coords[1]; self.coords[1] = -self.coords[1].clone();
self.coords[2] = -self.coords[2]; self.coords[2] = -self.coords[2].clone();
} }
/// Inverts this quaternion in-place if it is not zero. /// Inverts this quaternion in-place if it is not zero.
@ -671,8 +671,8 @@ where
#[inline] #[inline]
pub fn try_inverse_mut(&mut self) -> T::SimdBool { pub fn try_inverse_mut(&mut self) -> T::SimdBool {
let norm_squared = self.norm_squared(); let norm_squared = self.norm_squared();
let ge = norm_squared.simd_ge(T::simd_default_epsilon()); let ge = norm_squared.clone().simd_ge(T::simd_default_epsilon());
*self = ge.if_else(|| self.conjugate() / norm_squared, || *self); *self = ge.if_else(|| self.conjugate() / norm_squared, || self.clone());
ge ge
} }
@ -778,8 +778,8 @@ where
#[must_use] #[must_use]
pub fn cos(&self) -> Self { pub fn cos(&self) -> Self {
let z = self.imag().magnitude(); let z = self.imag().magnitude();
let w = -self.w.simd_sin() * z.simd_sinhc(); let w = -self.w.clone().simd_sin() * z.clone().simd_sinhc();
Self::from_parts(self.w.simd_cos() * z.simd_cosh(), self.imag() * w) Self::from_parts(self.w.clone().simd_cos() * z.simd_cosh(), self.imag() * w)
} }
/// Calculates the quaternionic arccosinus. /// Calculates the quaternionic arccosinus.
@ -818,8 +818,8 @@ where
#[must_use] #[must_use]
pub fn sin(&self) -> Self { pub fn sin(&self) -> Self {
let z = self.imag().magnitude(); let z = self.imag().magnitude();
let w = self.w.simd_cos() * z.simd_sinhc(); let w = self.w.clone().simd_cos() * z.clone().simd_sinhc();
Self::from_parts(self.w.simd_sin() * z.simd_cosh(), self.imag() * w) Self::from_parts(self.w.clone().simd_sin() * z.simd_cosh(), self.imag() * w)
} }
/// Calculates the quaternionic arcsinus. /// Calculates the quaternionic arcsinus.
@ -838,7 +838,7 @@ where
let u = Self::from_imag(self.imag().normalize()); let u = Self::from_imag(self.imag().normalize());
let identity = Self::identity(); let identity = Self::identity();
let z = ((u * self) + (identity - self.squared()).sqrt()).ln(); let z = ((u.clone() * self) + (identity - self.squared()).sqrt()).ln();
-(u * z) -(u * z)
} }
@ -880,8 +880,8 @@ where
T: RealField, T: RealField,
{ {
let u = Self::from_imag(self.imag().normalize()); let u = Self::from_imag(self.imag().normalize());
let num = u + self; let num = u.clone() + self;
let den = u - self; let den = u.clone() - self;
let fr = num.right_div(&den).unwrap(); let fr = num.right_div(&den).unwrap();
let ln = fr.ln(); let ln = fr.ln();
(u.half()) * ln (u.half()) * ln
@ -954,7 +954,7 @@ where
#[must_use] #[must_use]
pub fn acosh(&self) -> Self { pub fn acosh(&self) -> Self {
let identity = Self::identity(); let identity = Self::identity();
(self + (self + identity).sqrt() * (self - identity).sqrt()).ln() (self + (self + identity.clone()).sqrt() * (self - identity).sqrt()).ln()
} }
/// Calculates the hyperbolic quaternionic tangent. /// Calculates the hyperbolic quaternionic tangent.
@ -992,7 +992,7 @@ where
#[must_use] #[must_use]
pub fn atanh(&self) -> Self { pub fn atanh(&self) -> Self {
let identity = Self::identity(); let identity = Self::identity();
((identity + self).ln() - (identity - self).ln()).half() ((identity.clone() + self).ln() - (identity - self).ln()).half()
} }
} }
@ -1006,9 +1006,9 @@ impl<T: RealField + AbsDiffEq<Epsilon = T>> AbsDiffEq for Quaternion<T> {
#[inline] #[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.as_vector().abs_diff_eq(other.as_vector(), epsilon) || self.as_vector().abs_diff_eq(other.as_vector(), epsilon.clone()) ||
// Account for the double-covering of S², i.e. q = -q // Account for the double-covering of S², i.e. q = -q
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-*b, epsilon)) self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-b.clone(), epsilon.clone()))
} }
} }
@ -1025,9 +1025,9 @@ impl<T: RealField + RelativeEq<Epsilon = T>> RelativeEq for Quaternion<T> {
epsilon: Self::Epsilon, epsilon: Self::Epsilon,
max_relative: Self::Epsilon, max_relative: Self::Epsilon,
) -> bool { ) -> bool {
self.as_vector().relative_eq(other.as_vector(), epsilon, max_relative) || self.as_vector().relative_eq(other.as_vector(), epsilon.clone(), max_relative.clone()) ||
// Account for the double-covering of S², i.e. q = -q // Account for the double-covering of S², i.e. q = -q
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative)) self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-b.clone(), epsilon.clone(), max_relative.clone()))
} }
} }
@ -1039,9 +1039,9 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for Quaternion<T> {
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.as_vector().ulps_eq(other.as_vector(), epsilon, max_ulps) || self.as_vector().ulps_eq(other.as_vector(), epsilon.clone(), max_ulps.clone()) ||
// Account for the double-covering of S², i.e. q = -q. // Account for the double-covering of S², i.e. q = -q.
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.ulps_eq(&-*b, epsilon, max_ulps)) self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.ulps_eq(&-b.clone(), epsilon.clone(), max_ulps.clone()))
} }
} }
@ -1063,7 +1063,7 @@ impl<T: Scalar + ClosedNeg + PartialEq> PartialEq for UnitQuaternion<T> {
fn eq(&self, rhs: &Self) -> bool { fn eq(&self, rhs: &Self) -> bool {
self.coords == rhs.coords || self.coords == rhs.coords ||
// Account for the double-covering of S², i.e. q = -q // Account for the double-covering of S², i.e. q = -q
self.coords.iter().zip(rhs.coords.iter()).all(|(a, b)| *a == -b.inlined_clone()) self.coords.iter().zip(rhs.coords.iter()).all(|(a, b)| *a == -b.clone())
} }
} }
@ -1279,14 +1279,14 @@ where
T: RealField, T: RealField,
{ {
let coords = if self.coords.dot(&other.coords) < T::zero() { let coords = if self.coords.dot(&other.coords) < T::zero() {
Unit::new_unchecked(self.coords).try_slerp( Unit::new_unchecked(self.coords.clone()).try_slerp(
&Unit::new_unchecked(-other.coords), &Unit::new_unchecked(-other.coords.clone()),
t, t,
epsilon, epsilon,
) )
} else { } else {
Unit::new_unchecked(self.coords).try_slerp( Unit::new_unchecked(self.coords.clone()).try_slerp(
&Unit::new_unchecked(other.coords), &Unit::new_unchecked(other.coords.clone()),
t, t,
epsilon, epsilon,
) )
@ -1479,31 +1479,31 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn to_rotation_matrix(self) -> Rotation<T, 3> { pub fn to_rotation_matrix(self) -> Rotation<T, 3> {
let i = self.as_ref()[0]; let i = self.as_ref()[0].clone();
let j = self.as_ref()[1]; let j = self.as_ref()[1].clone();
let k = self.as_ref()[2]; let k = self.as_ref()[2].clone();
let w = self.as_ref()[3]; let w = self.as_ref()[3].clone();
let ww = w * w; let ww = w.clone() * w.clone();
let ii = i * i; let ii = i.clone() * i.clone();
let jj = j * j; let jj = j.clone() * j.clone();
let kk = k * k; let kk = k.clone() * k.clone();
let ij = i * j * crate::convert(2.0f64); let ij = i.clone() * j.clone() * crate::convert(2.0f64);
let wk = w * k * crate::convert(2.0f64); let wk = w.clone() * k.clone() * crate::convert(2.0f64);
let wj = w * j * crate::convert(2.0f64); let wj = w.clone() * j.clone() * crate::convert(2.0f64);
let ik = i * k * crate::convert(2.0f64); let ik = i.clone() * k.clone() * crate::convert(2.0f64);
let jk = j * k * crate::convert(2.0f64); let jk = j.clone() * k.clone() * crate::convert(2.0f64);
let wi = w * i * crate::convert(2.0f64); let wi = w.clone() * i.clone() * crate::convert(2.0f64);
Rotation::from_matrix_unchecked(Matrix3::new( Rotation::from_matrix_unchecked(Matrix3::new(
ww + ii - jj - kk, ww.clone() + ii.clone() - jj.clone() - kk.clone(),
ij - wk, ij.clone() - wk.clone(),
wj + ik, wj.clone() + ik.clone(),
wk + ij, wk.clone() + ij.clone(),
ww - ii + jj - kk, ww.clone() - ii.clone() + jj.clone() - kk.clone(),
jk - wi, jk.clone() - wi.clone(),
ik - wj, ik.clone() - wj.clone(),
wi + jk, wi.clone() + jk.clone(),
ww - ii - jj + kk, ww - ii - jj + kk,
)) ))
} }
@ -1540,7 +1540,7 @@ where
where where
T: RealField, T: RealField,
{ {
self.to_rotation_matrix().euler_angles() self.clone().to_rotation_matrix().euler_angles()
} }
/// Converts this unit quaternion into its equivalent homogeneous transformation matrix. /// Converts this unit quaternion into its equivalent homogeneous transformation matrix.
@ -1679,9 +1679,9 @@ where
#[must_use] #[must_use]
pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self { pub fn append_axisangle_linearized(&self, axisangle: &Vector3<T>) -> Self {
let half: T = crate::convert(0.5); let half: T = crate::convert(0.5);
let q1 = self.into_inner(); let q1 = self.clone().into_inner();
let q2 = Quaternion::from_imag(axisangle * half); let q2 = Quaternion::from_imag(axisangle * half);
Unit::new_normalize(q1 + q2 * q1) Unit::new_normalize(&q1 + q2 * &q1)
} }
} }

View File

@ -95,7 +95,12 @@ impl<T: SimdRealField> Quaternion<T> {
where where
SB: Storage<T, U3>, SB: Storage<T, U3>,
{ {
Self::new(scalar, vector[0], vector[1], vector[2]) Self::new(
scalar,
vector[0].clone(),
vector[1].clone(),
vector[2].clone(),
)
} }
/// Constructs a real quaternion. /// Constructs a real quaternion.
@ -296,9 +301,9 @@ where
let (sy, cy) = (yaw * crate::convert(0.5f64)).simd_sin_cos(); let (sy, cy) = (yaw * crate::convert(0.5f64)).simd_sin_cos();
let q = Quaternion::new( let q = Quaternion::new(
cr * cp * cy + sr * sp * sy, cr.clone() * cp.clone() * cy.clone() + sr.clone() * sp.clone() * sy.clone(),
sr * cp * cy - cr * sp * sy, sr.clone() * cp.clone() * cy.clone() - cr.clone() * sp.clone() * sy.clone(),
cr * sp * cy + sr * cp * sy, cr.clone() * sp.clone() * cy.clone() + sr.clone() * cp.clone() * sy.clone(),
cr * cp * sy - sr * sp * cy, cr * cp * sy - sr * sp * cy,
); );
@ -334,56 +339,65 @@ where
pub fn from_rotation_matrix(rotmat: &Rotation3<T>) -> Self { pub fn from_rotation_matrix(rotmat: &Rotation3<T>) -> Self {
// Robust matrix to quaternion transformation. // Robust matrix to quaternion transformation.
// See https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion // See https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion
let tr = rotmat[(0, 0)] + rotmat[(1, 1)] + rotmat[(2, 2)]; let tr = rotmat[(0, 0)].clone() + rotmat[(1, 1)].clone() + rotmat[(2, 2)].clone();
let quarter: T = crate::convert(0.25); let quarter: T = crate::convert(0.25);
let res = tr.simd_gt(T::zero()).if_else3( let res = tr.clone().simd_gt(T::zero()).if_else3(
|| { || {
let denom = (tr + T::one()).simd_sqrt() * crate::convert(2.0); let denom = (tr.clone() + T::one()).simd_sqrt() * crate::convert(2.0);
Quaternion::new( Quaternion::new(
quarter * denom, quarter.clone() * denom.clone(),
(rotmat[(2, 1)] - rotmat[(1, 2)]) / denom, (rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone()) / denom.clone(),
(rotmat[(0, 2)] - rotmat[(2, 0)]) / denom, (rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone()) / denom.clone(),
(rotmat[(1, 0)] - rotmat[(0, 1)]) / denom, (rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone()) / denom,
) )
}, },
( (
|| rotmat[(0, 0)].simd_gt(rotmat[(1, 1)]) & rotmat[(0, 0)].simd_gt(rotmat[(2, 2)]),
|| { || {
let denom = (T::one() + rotmat[(0, 0)] - rotmat[(1, 1)] - rotmat[(2, 2)]) rotmat[(0, 0)].clone().simd_gt(rotmat[(1, 1)].clone())
& rotmat[(0, 0)].clone().simd_gt(rotmat[(2, 2)].clone())
},
|| {
let denom = (T::one() + rotmat[(0, 0)].clone()
- rotmat[(1, 1)].clone()
- rotmat[(2, 2)].clone())
.simd_sqrt() .simd_sqrt()
* crate::convert(2.0); * crate::convert(2.0);
Quaternion::new( Quaternion::new(
(rotmat[(2, 1)] - rotmat[(1, 2)]) / denom, (rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone()) / denom.clone(),
quarter * denom, quarter.clone() * denom.clone(),
(rotmat[(0, 1)] + rotmat[(1, 0)]) / denom, (rotmat[(0, 1)].clone() + rotmat[(1, 0)].clone()) / denom.clone(),
(rotmat[(0, 2)] + rotmat[(2, 0)]) / denom, (rotmat[(0, 2)].clone() + rotmat[(2, 0)].clone()) / denom,
) )
}, },
), ),
( (
|| rotmat[(1, 1)].simd_gt(rotmat[(2, 2)]), || rotmat[(1, 1)].clone().simd_gt(rotmat[(2, 2)].clone()),
|| { || {
let denom = (T::one() + rotmat[(1, 1)] - rotmat[(0, 0)] - rotmat[(2, 2)]) let denom = (T::one() + rotmat[(1, 1)].clone()
- rotmat[(0, 0)].clone()
- rotmat[(2, 2)].clone())
.simd_sqrt() .simd_sqrt()
* crate::convert(2.0); * crate::convert(2.0);
Quaternion::new( Quaternion::new(
(rotmat[(0, 2)] - rotmat[(2, 0)]) / denom, (rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone()) / denom.clone(),
(rotmat[(0, 1)] + rotmat[(1, 0)]) / denom, (rotmat[(0, 1)].clone() + rotmat[(1, 0)].clone()) / denom.clone(),
quarter * denom, quarter.clone() * denom.clone(),
(rotmat[(1, 2)] + rotmat[(2, 1)]) / denom, (rotmat[(1, 2)].clone() + rotmat[(2, 1)].clone()) / denom,
) )
}, },
), ),
|| { || {
let denom = (T::one() + rotmat[(2, 2)] - rotmat[(0, 0)] - rotmat[(1, 1)]) let denom = (T::one() + rotmat[(2, 2)].clone()
- rotmat[(0, 0)].clone()
- rotmat[(1, 1)].clone())
.simd_sqrt() .simd_sqrt()
* crate::convert(2.0); * crate::convert(2.0);
Quaternion::new( Quaternion::new(
(rotmat[(1, 0)] - rotmat[(0, 1)]) / denom, (rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone()) / denom.clone(),
(rotmat[(0, 2)] + rotmat[(2, 0)]) / denom, (rotmat[(0, 2)].clone() + rotmat[(2, 0)].clone()) / denom.clone(),
(rotmat[(1, 2)] + rotmat[(2, 1)]) / denom, (rotmat[(1, 2)].clone() + rotmat[(2, 1)].clone()) / denom.clone(),
quarter * denom, quarter.clone() * denom,
) )
}, },
); );
@ -833,10 +847,10 @@ where
let max_eigenvector = eigen_matrix.eigenvectors.column(max_eigenvalue_index); let max_eigenvector = eigen_matrix.eigenvectors.column(max_eigenvalue_index);
UnitQuaternion::from_quaternion(Quaternion::new( UnitQuaternion::from_quaternion(Quaternion::new(
max_eigenvector[0], max_eigenvector[0].clone(),
max_eigenvector[1], max_eigenvector[1].clone(),
max_eigenvector[2], max_eigenvector[2].clone(),
max_eigenvector[3], max_eigenvector[3].clone(),
)) ))
} }
} }
@ -868,13 +882,18 @@ where
let twopi = Uniform::new(T::zero(), T::simd_two_pi()); let twopi = Uniform::new(T::zero(), T::simd_two_pi());
let theta1 = rng.sample(&twopi); let theta1 = rng.sample(&twopi);
let theta2 = rng.sample(&twopi); let theta2 = rng.sample(&twopi);
let s1 = theta1.simd_sin(); let s1 = theta1.clone().simd_sin();
let c1 = theta1.simd_cos(); let c1 = theta1.simd_cos();
let s2 = theta2.simd_sin(); let s2 = theta2.clone().simd_sin();
let c2 = theta2.simd_cos(); let c2 = theta2.simd_cos();
let r1 = (T::one() - x0).simd_sqrt(); let r1 = (T::one() - x0.clone()).simd_sqrt();
let r2 = x0.simd_sqrt(); let r2 = x0.simd_sqrt();
Unit::new_unchecked(Quaternion::new(s1 * r1, c1 * r1, s2 * r2, c2 * r2)) Unit::new_unchecked(Quaternion::new(
s1 * r1.clone(),
c1 * r1,
s2 * r2.clone(),
c2 * r2,
))
} }
} }

View File

@ -167,7 +167,7 @@ where
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<T2, C, 3> { fn to_superset(&self) -> Transform<T2, C, 3> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
} }
#[inline] #[inline]
@ -184,7 +184,7 @@ where
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>> for UnitQuaternion<T1> { impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix4<T2>> for UnitQuaternion<T1> {
#[inline] #[inline]
fn to_superset(&self) -> Matrix4<T2> { fn to_superset(&self) -> Matrix4<T2> {
self.to_homogeneous().to_superset() self.clone().to_homogeneous().to_superset()
} }
#[inline] #[inline]

View File

@ -159,10 +159,10 @@ quaternion_op_impl!(
; ;
self: &'a Quaternion<T>, rhs: &'b Quaternion<T>, Output = Quaternion<T>; self: &'a Quaternion<T>, rhs: &'b Quaternion<T>, Output = Quaternion<T>;
Quaternion::new( Quaternion::new(
self[3] * rhs[3] - self[0] * rhs[0] - self[1] * rhs[1] - self[2] * rhs[2], self[3].clone() * rhs[3].clone() - self[0].clone() * rhs[0].clone() - self[1].clone() * rhs[1].clone() - self[2].clone() * rhs[2].clone(),
self[3] * rhs[0] + self[0] * rhs[3] + self[1] * rhs[2] - self[2] * rhs[1], self[3].clone() * rhs[0].clone() + self[0].clone() * rhs[3].clone() + self[1].clone() * rhs[2].clone() - self[2].clone() * rhs[1].clone(),
self[3] * rhs[1] - self[0] * rhs[2] + self[1] * rhs[3] + self[2] * rhs[0], self[3].clone() * rhs[1].clone() - self[0].clone() * rhs[2].clone() + self[1].clone() * rhs[3].clone() + self[2].clone() * rhs[0].clone(),
self[3] * rhs[2] + self[0] * rhs[1] - self[1] * rhs[0] + self[2] * rhs[3]); self[3].clone() * rhs[2].clone() + self[0].clone() * rhs[1].clone() - self[1].clone() * rhs[0].clone() + self[2].clone() * rhs[3].clone());
'a, 'b); 'a, 'b);
quaternion_op_impl!( quaternion_op_impl!(

View File

@ -45,7 +45,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
/// represents a plane that passes through the origin. /// represents a plane that passes through the origin.
#[must_use] #[must_use]
pub fn bias(&self) -> T { pub fn bias(&self) -> T {
self.bias self.bias.clone()
} }
// TODO: naming convention: reflect_to, reflect_assign ? // TODO: naming convention: reflect_to, reflect_assign ?
@ -60,7 +60,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
// dot product, and then mutably. Somehow, this allows significantly // dot product, and then mutably. Somehow, this allows significantly
// better optimizations of the dot product from the compiler. // better optimizations of the dot product from the compiler.
let m_two: T = crate::convert(-2.0f64); let m_two: T = crate::convert(-2.0f64);
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias) * m_two; let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
rhs.column_mut(i).axpy(factor, &self.axis, T::one()); rhs.column_mut(i).axpy(factor, &self.axis, T::one());
} }
} }
@ -76,9 +76,9 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
// NOTE: we borrow the column twice here. First it is borrowed immutably for the // NOTE: we borrow the column twice here. First it is borrowed immutably for the
// dot product, and then mutably. Somehow, this allows significantly // dot product, and then mutably. Somehow, this allows significantly
// better optimizations of the dot product from the compiler. // better optimizations of the dot product from the compiler.
let m_two = sign.scale(crate::convert(-2.0f64)); let m_two = sign.clone().scale(crate::convert(-2.0f64));
let factor = (self.axis.dotc(&rhs.column(i)) - self.bias) * m_two; let factor = (self.axis.dotc(&rhs.column(i)) - self.bias.clone()) * m_two;
rhs.column_mut(i).axpy(factor, &self.axis, sign); rhs.column_mut(i).axpy(factor, &self.axis, sign.clone());
} }
} }
@ -95,7 +95,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
lhs.mul_to(&self.axis, work); lhs.mul_to(&self.axis, work);
if !self.bias.is_zero() { if !self.bias.is_zero() {
work.add_scalar_mut(-self.bias); work.add_scalar_mut(-self.bias.clone());
} }
let m_two: T = crate::convert(-2.0f64); let m_two: T = crate::convert(-2.0f64);
@ -116,10 +116,10 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D>> Reflection<T, D, S> {
lhs.mul_to(&self.axis, work); lhs.mul_to(&self.axis, work);
if !self.bias.is_zero() { if !self.bias.is_zero() {
work.add_scalar_mut(-self.bias); work.add_scalar_mut(-self.bias.clone());
} }
let m_two = sign.scale(crate::convert(-2.0f64)); let m_two = sign.clone().scale(crate::convert(-2.0f64));
lhs.gerc(m_two, work, &self.axis, sign); lhs.gerc(m_two, work, &self.axis, sign);
} }
} }

View File

@ -514,7 +514,7 @@ impl<T: Scalar + PartialEq, const D: usize> PartialEq for Rotation<T, D> {
impl<T, const D: usize> AbsDiffEq for Rotation<T, D> impl<T, const D: usize> AbsDiffEq for Rotation<T, D>
where where
T: Scalar + AbsDiffEq, T: Scalar + AbsDiffEq,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -532,7 +532,7 @@ where
impl<T, const D: usize> RelativeEq for Rotation<T, D> impl<T, const D: usize> RelativeEq for Rotation<T, D>
where where
T: Scalar + RelativeEq, T: Scalar + RelativeEq,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -554,7 +554,7 @@ where
impl<T, const D: usize> UlpsEq for Rotation<T, D> impl<T, const D: usize> UlpsEq for Rotation<T, D>
where where
T: Scalar + UlpsEq, T: Scalar + UlpsEq,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {

View File

@ -23,8 +23,8 @@ impl<T: SimdRealField> Rotation2<T> {
where where
T::Element: SimdRealField, T::Element: SimdRealField,
{ {
let c1 = UnitComplex::from(*self); let c1 = UnitComplex::from(self.clone());
let c2 = UnitComplex::from(*other); let c2 = UnitComplex::from(other.clone());
c1.slerp(&c2, t).into() c1.slerp(&c2, t).into()
} }
} }
@ -53,8 +53,8 @@ impl<T: SimdRealField> Rotation3<T> {
where where
T: RealField, T: RealField,
{ {
let q1 = UnitQuaternion::from(*self); let q1 = UnitQuaternion::from(self.clone());
let q2 = UnitQuaternion::from(*other); let q2 = UnitQuaternion::from(other.clone());
q1.slerp(&q2, t).into() q1.slerp(&q2, t).into()
} }
@ -74,8 +74,8 @@ impl<T: SimdRealField> Rotation3<T> {
where where
T: RealField, T: RealField,
{ {
let q1 = UnitQuaternion::from(*self); let q1 = UnitQuaternion::from(self.clone());
let q2 = UnitQuaternion::from(*other); let q2 = UnitQuaternion::from(other.clone());
q1.try_slerp(&q2, t, epsilon).map(|q| q.into()) q1.try_slerp(&q2, t, epsilon).map(|q| q.into())
} }
} }

View File

@ -42,7 +42,7 @@ impl<T: SimdRealField> Rotation2<T> {
/// ``` /// ```
pub fn new(angle: T) -> Self { pub fn new(angle: T) -> Self {
let (sia, coa) = angle.simd_sin_cos(); let (sia, coa) = angle.simd_sin_cos();
Self::from_matrix_unchecked(Matrix2::new(coa, -sia, sia, coa)) Self::from_matrix_unchecked(Matrix2::new(coa.clone(), -sia.clone(), sia, coa))
} }
/// Builds a 2 dimensional rotation matrix from an angle in radian wrapped in a 1-dimensional vector. /// Builds a 2 dimensional rotation matrix from an angle in radian wrapped in a 1-dimensional vector.
@ -52,7 +52,7 @@ impl<T: SimdRealField> Rotation2<T> {
/// the `::new(angle)` method instead is more common. /// the `::new(angle)` method instead is more common.
#[inline] #[inline]
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self { pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
Self::new(axisangle[0]) Self::new(axisangle[0].clone())
} }
} }
@ -108,7 +108,7 @@ impl<T: SimdRealField> Rotation2<T> {
let denom = rot.column(0).dot(&m.column(0)) + rot.column(1).dot(&m.column(1)); let denom = rot.column(0).dot(&m.column(0)) + rot.column(1).dot(&m.column(1));
let angle = axis / (denom.abs() + T::default_epsilon()); let angle = axis / (denom.abs() + T::default_epsilon());
if angle.abs() > eps { if angle.clone().abs() > eps {
rot = Self::new(angle) * rot; rot = Self::new(angle) * rot;
} else { } else {
break; break;
@ -198,7 +198,7 @@ impl<T: SimdRealField> Rotation2<T> {
where where
T: RealField, T: RealField,
{ {
let mut c = UnitComplex::from(*self); let mut c = UnitComplex::from(self.clone());
let _ = c.renormalize(); let _ = c.renormalize();
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into()) *self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
@ -236,7 +236,9 @@ impl<T: SimdRealField> Rotation2<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn angle(&self) -> T { pub fn angle(&self) -> T {
self.matrix()[(1, 0)].simd_atan2(self.matrix()[(0, 0)]) self.matrix()[(1, 0)]
.clone()
.simd_atan2(self.matrix()[(0, 0)].clone())
} }
/// The rotation angle needed to make `self` and `other` coincide. /// The rotation angle needed to make `self` and `other` coincide.
@ -382,27 +384,27 @@ where
where where
SB: Storage<T, U3>, SB: Storage<T, U3>,
{ {
angle.simd_ne(T::zero()).if_else( angle.clone().simd_ne(T::zero()).if_else(
|| { || {
let ux = axis.as_ref()[0]; let ux = axis.as_ref()[0].clone();
let uy = axis.as_ref()[1]; let uy = axis.as_ref()[1].clone();
let uz = axis.as_ref()[2]; let uz = axis.as_ref()[2].clone();
let sqx = ux * ux; let sqx = ux.clone() * ux.clone();
let sqy = uy * uy; let sqy = uy.clone() * uy.clone();
let sqz = uz * uz; let sqz = uz.clone() * uz.clone();
let (sin, cos) = angle.simd_sin_cos(); let (sin, cos) = angle.simd_sin_cos();
let one_m_cos = T::one() - cos; let one_m_cos = T::one() - cos.clone();
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new( Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
sqx + (T::one() - sqx) * cos, sqx.clone() + (T::one() - sqx) * cos.clone(),
ux * uy * one_m_cos - uz * sin, ux.clone() * uy.clone() * one_m_cos.clone() - uz.clone() * sin.clone(),
ux * uz * one_m_cos + uy * sin, ux.clone() * uz.clone() * one_m_cos.clone() + uy.clone() * sin.clone(),
ux * uy * one_m_cos + uz * sin, ux.clone() * uy.clone() * one_m_cos.clone() + uz.clone() * sin.clone(),
sqy + (T::one() - sqy) * cos, sqy.clone() + (T::one() - sqy) * cos.clone(),
uy * uz * one_m_cos - ux * sin, uy.clone() * uz.clone() * one_m_cos.clone() - ux.clone() * sin.clone(),
ux * uz * one_m_cos - uy * sin, ux.clone() * uz.clone() * one_m_cos.clone() - uy.clone() * sin.clone(),
uy * uz * one_m_cos + ux * sin, uy * uz * one_m_cos + ux * sin,
sqz + (T::one() - sqz) * cos, sqz.clone() + (T::one() - sqz) * cos,
)) ))
}, },
Self::identity, Self::identity,
@ -429,14 +431,14 @@ where
let (sy, cy) = yaw.simd_sin_cos(); let (sy, cy) = yaw.simd_sin_cos();
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new( Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
cy * cp, cy.clone() * cp.clone(),
cy * sp * sr - sy * cr, cy.clone() * sp.clone() * sr.clone() - sy.clone() * cr.clone(),
cy * sp * cr + sy * sr, cy.clone() * sp.clone() * cr.clone() + sy.clone() * sr.clone(),
sy * cp, sy.clone() * cp.clone(),
sy * sp * sr + cy * cr, sy.clone() * sp.clone() * sr.clone() + cy.clone() * cr.clone(),
sy * sp * cr - cy * sr, sy * sp.clone() * cr.clone() - cy * sr.clone(),
-sp, -sp,
cp * sr, cp.clone() * sr,
cp * cr, cp * cr,
)) ))
} }
@ -479,7 +481,15 @@ where
let yaxis = zaxis.cross(&xaxis).normalize(); let yaxis = zaxis.cross(&xaxis).normalize();
Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new( Self::from_matrix_unchecked(SMatrix::<T, 3, 3>::new(
xaxis.x, yaxis.x, zaxis.x, xaxis.y, yaxis.y, zaxis.y, xaxis.z, yaxis.z, zaxis.z, xaxis.x.clone(),
yaxis.x.clone(),
zaxis.x.clone(),
xaxis.y.clone(),
yaxis.y.clone(),
zaxis.y.clone(),
xaxis.z.clone(),
yaxis.z.clone(),
zaxis.z.clone(),
)) ))
} }
@ -735,7 +745,7 @@ where
let axisangle = axis / (denom.abs() + T::default_epsilon()); let axisangle = axis / (denom.abs() + T::default_epsilon());
if let Some((axis, angle)) = Unit::try_new_and_get(axisangle, eps) { if let Some((axis, angle)) = Unit::try_new_and_get(axisangle, eps.clone()) {
rot = Rotation3::from_axis_angle(&axis, angle) * rot; rot = Rotation3::from_axis_angle(&axis, angle) * rot;
} else { } else {
break; break;
@ -752,7 +762,7 @@ where
where where
T: RealField, T: RealField,
{ {
let mut c = UnitQuaternion::from(*self); let mut c = UnitQuaternion::from(self.clone());
let _ = c.renormalize(); let _ = c.renormalize();
*self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into()) *self = Self::from_matrix_eps(self.matrix(), T::default_epsilon(), 0, c.into())
@ -774,7 +784,10 @@ impl<T: SimdRealField> Rotation3<T> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn angle(&self) -> T { pub fn angle(&self) -> T {
((self.matrix()[(0, 0)] + self.matrix()[(1, 1)] + self.matrix()[(2, 2)] - T::one()) ((self.matrix()[(0, 0)].clone()
+ self.matrix()[(1, 1)].clone()
+ self.matrix()[(2, 2)].clone()
- T::one())
/ crate::convert(2.0)) / crate::convert(2.0))
.simd_acos() .simd_acos()
} }
@ -800,10 +813,11 @@ impl<T: SimdRealField> Rotation3<T> {
where where
T: RealField, T: RealField,
{ {
let rotmat = self.matrix();
let axis = SVector::<T, 3>::new( let axis = SVector::<T, 3>::new(
self.matrix()[(2, 1)] - self.matrix()[(1, 2)], rotmat[(2, 1)].clone() - rotmat[(1, 2)].clone(),
self.matrix()[(0, 2)] - self.matrix()[(2, 0)], rotmat[(0, 2)].clone() - rotmat[(2, 0)].clone(),
self.matrix()[(1, 0)] - self.matrix()[(0, 1)], rotmat[(1, 0)].clone() - rotmat[(0, 1)].clone(),
); );
Unit::try_new(axis, T::default_epsilon()) Unit::try_new(axis, T::default_epsilon())
@ -911,16 +925,22 @@ impl<T: SimdRealField> Rotation3<T> {
{ {
// 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() < T::one() { if self[(2, 0)].clone().abs() < T::one() {
let yaw = -self[(2, 0)].asin(); let yaw = -self[(2, 0)].clone().asin();
let roll = (self[(2, 1)] / yaw.cos()).atan2(self[(2, 2)] / yaw.cos()); let roll = (self[(2, 1)].clone() / yaw.clone().cos())
let pitch = (self[(1, 0)] / yaw.cos()).atan2(self[(0, 0)] / yaw.cos()); .atan2(self[(2, 2)].clone() / yaw.clone().cos());
let pitch = (self[(1, 0)].clone() / yaw.clone().cos())
.atan2(self[(0, 0)].clone() / yaw.clone().cos());
(roll, yaw, pitch) (roll, yaw, pitch)
} else if self[(2, 0)] <= -T::one() { } else if self[(2, 0)].clone() <= -T::one() {
(self[(0, 1)].atan2(self[(0, 2)]), T::frac_pi_2(), T::zero()) (
self[(0, 1)].clone().atan2(self[(0, 2)].clone()),
T::frac_pi_2(),
T::zero(),
)
} else { } else {
( (
-self[(0, 1)].atan2(-self[(0, 2)]), -self[(0, 1)].clone().atan2(-self[(0, 2)].clone()),
-T::frac_pi_2(), -T::frac_pi_2(),
T::zero(), T::zero(),
) )
@ -947,8 +967,8 @@ where
let theta = rng.sample(&twopi); let theta = rng.sample(&twopi);
let (ts, tc) = theta.simd_sin_cos(); let (ts, tc) = theta.simd_sin_cos();
let a = SMatrix::<T, 3, 3>::new( let a = SMatrix::<T, 3, 3>::new(
tc, tc.clone(),
ts, ts.clone(),
T::zero(), T::zero(),
-ts, -ts,
tc, tc,
@ -962,10 +982,10 @@ where
let phi = rng.sample(&twopi); let phi = rng.sample(&twopi);
let z = rng.sample(OpenClosed01); let z = rng.sample(OpenClosed01);
let (ps, pc) = phi.simd_sin_cos(); let (ps, pc) = phi.simd_sin_cos();
let sqrt_z = z.simd_sqrt(); let sqrt_z = z.clone().simd_sqrt();
let v = Vector3::new(pc * sqrt_z, ps * sqrt_z, (T::one() - z).simd_sqrt()); let v = Vector3::new(pc * sqrt_z.clone(), ps * sqrt_z, (T::one() - z).simd_sqrt());
let mut b = v * v.transpose(); let mut b = v.clone() * v.transpose();
b += b; b += b.clone();
b -= SMatrix::<T, 3, 3>::identity(); b -= SMatrix::<T, 3, 3>::identity();
Rotation3::from_matrix_unchecked(b * a) Rotation3::from_matrix_unchecked(b * a)

View File

@ -124,7 +124,7 @@ impl<T: Scalar, R, const D: usize> Similarity<T, R, D> {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn scaling(&self) -> T { pub fn scaling(&self) -> T {
self.scaling.inlined_clone() self.scaling.clone()
} }
} }
@ -151,9 +151,9 @@ where
/// Inverts `self` in-place. /// Inverts `self` in-place.
#[inline] #[inline]
pub fn inverse_mut(&mut self) { pub fn inverse_mut(&mut self) {
self.scaling = T::one() / self.scaling; self.scaling = T::one() / self.scaling.clone();
self.isometry.inverse_mut(); self.isometry.inverse_mut();
self.isometry.translation.vector *= self.scaling; self.isometry.translation.vector *= self.scaling.clone();
} }
/// The similarity transformation that applies a scaling factor `scaling` before `self`. /// The similarity transformation that applies a scaling factor `scaling` before `self`.
@ -165,7 +165,7 @@ where
"The similarity scaling factor must not be zero." "The similarity scaling factor must not be zero."
); );
Self::from_isometry(self.isometry.clone(), self.scaling * scaling) Self::from_isometry(self.isometry.clone(), self.scaling.clone() * scaling)
} }
/// The similarity transformation that applies a scaling factor `scaling` after `self`. /// The similarity transformation that applies a scaling factor `scaling` after `self`.
@ -178,9 +178,9 @@ where
); );
Self::from_parts( Self::from_parts(
Translation::from(self.isometry.translation.vector * scaling), Translation::from(&self.isometry.translation.vector * scaling.clone()),
self.isometry.rotation.clone(), self.isometry.rotation.clone(),
self.scaling * scaling, self.scaling.clone() * scaling,
) )
} }
@ -203,7 +203,7 @@ where
"The similarity scaling factor must not be zero." "The similarity scaling factor must not be zero."
); );
self.isometry.translation.vector *= scaling; self.isometry.translation.vector *= scaling.clone();
self.scaling *= scaling; self.scaling *= scaling;
} }
@ -336,7 +336,7 @@ impl<T: SimdRealField, R, const D: usize> Similarity<T, R, D> {
let mut res = self.isometry.to_homogeneous(); let mut res = self.isometry.to_homogeneous();
for e in res.fixed_slice_mut::<D, D>(0, 0).iter_mut() { for e in res.fixed_slice_mut::<D, D>(0, 0).iter_mut() {
*e *= self.scaling *e *= self.scaling.clone()
} }
res res
@ -361,7 +361,7 @@ where
impl<T: RealField, R, const D: usize> AbsDiffEq for Similarity<T, R, D> impl<T: RealField, R, const D: usize> AbsDiffEq for Similarity<T, R, D>
where where
R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + AbsDiffEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -372,7 +372,7 @@ where
#[inline] #[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.isometry.abs_diff_eq(&other.isometry, epsilon) self.isometry.abs_diff_eq(&other.isometry, epsilon.clone())
&& self.scaling.abs_diff_eq(&other.scaling, epsilon) && self.scaling.abs_diff_eq(&other.scaling, epsilon)
} }
} }
@ -380,7 +380,7 @@ where
impl<T: RealField, R, const D: usize> RelativeEq for Similarity<T, R, D> impl<T: RealField, R, const D: usize> RelativeEq for Similarity<T, R, D>
where where
R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + RelativeEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -395,7 +395,7 @@ where
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.clone(), max_relative.clone())
&& self && self
.scaling .scaling
.relative_eq(&other.scaling, epsilon, max_relative) .relative_eq(&other.scaling, epsilon, max_relative)
@ -405,7 +405,7 @@ where
impl<T: RealField, R, const D: usize> UlpsEq for Similarity<T, R, D> impl<T: RealField, R, const D: usize> UlpsEq for Similarity<T, R, D>
where where
R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>, R: AbstractRotation<T, D> + UlpsEq<Epsilon = T::Epsilon>,
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {
@ -414,7 +414,8 @@ where
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.isometry.ulps_eq(&other.isometry, epsilon, max_ulps) self.isometry
.ulps_eq(&other.isometry, epsilon.clone(), max_ulps.clone())
&& self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps) && self.scaling.ulps_eq(&other.scaling, epsilon, max_ulps)
} }
} }

View File

@ -222,7 +222,7 @@ md_assign_impl_all!(
const D; for; where; const D; for; where;
self: Similarity<T, Rotation<T, D>, D>, rhs: Rotation<T, D>; self: Similarity<T, Rotation<T, D>, D>, rhs: Rotation<T, D>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= *rhs; [ref] => self.isometry.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(
@ -241,7 +241,7 @@ md_assign_impl_all!(
const; for; where; const; for; where;
self: Similarity<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>; self: Similarity<T, UnitQuaternion<T>, 3>, rhs: UnitQuaternion<T>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= *rhs; [ref] => self.isometry.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(
@ -260,7 +260,7 @@ md_assign_impl_all!(
const; for; where; const; for; where;
self: Similarity<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>; self: Similarity<T, UnitComplex<T>, 2>, rhs: UnitComplex<T>;
[val] => self.isometry.rotation *= rhs; [val] => self.isometry.rotation *= rhs;
[ref] => self.isometry.rotation *= *rhs; [ref] => self.isometry.rotation *= rhs.clone();
); );
md_assign_impl_all!( md_assign_impl_all!(

View File

@ -11,7 +11,7 @@ macro_rules! impl_swizzle {
#[must_use] #[must_use]
pub fn $name(&self) -> $Result<T> pub fn $name(&self) -> $Result<T>
where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> { where <Const<D> as ToTypenum>::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].clone()),*)
} }
)* )*
)* )*

View File

@ -31,7 +31,7 @@ pub trait TCategory: Any + Debug + Copy + PartialEq + Send {
/// category `Self`. /// category `Self`.
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D, D>; DefaultAllocator: Allocator<T, D, D>;
} }
@ -74,7 +74,7 @@ impl TCategory for TGeneral {
#[inline] #[inline]
fn check_homogeneous_invariants<T: RealField, D: DimName>(_: &OMatrix<T, D, D>) -> bool fn check_homogeneous_invariants<T: RealField, D: DimName>(_: &OMatrix<T, D, D>) -> bool
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
true true
@ -85,7 +85,7 @@ impl TCategory for TProjective {
#[inline] #[inline]
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
mat.is_invertible() mat.is_invertible()
@ -101,7 +101,7 @@ impl TCategory for TAffine {
#[inline] #[inline]
fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool fn check_homogeneous_invariants<T: RealField, D: DimName>(mat: &OMatrix<T, D, D>) -> bool
where where
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let last = D::dim() - 1; let last = D::dim() - 1;
@ -178,7 +178,7 @@ where
} }
} }
impl<T: RealField, C: TCategory, const D: usize> Copy for Transform<T, C, D> impl<T: RealField + Copy, C: TCategory, const D: usize> Copy for Transform<T, C, D>
where where
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
@ -583,7 +583,7 @@ where
impl<T: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<T, C, D> impl<T: RealField, C: TCategory, const D: usize> AbsDiffEq for Transform<T, C, D>
where where
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -602,7 +602,7 @@ where
impl<T: RealField, C: TCategory, const D: usize> RelativeEq for Transform<T, C, D> impl<T: RealField, C: TCategory, const D: usize> RelativeEq for Transform<T, C, D>
where where
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]
@ -625,7 +625,7 @@ where
impl<T: RealField, C: TCategory, const D: usize> UlpsEq for Transform<T, C, D> impl<T: RealField, C: TCategory, const D: usize> UlpsEq for Transform<T, C, D>
where where
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
T::Epsilon: Copy, T::Epsilon: Clone,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
#[inline] #[inline]

View File

@ -154,7 +154,7 @@ md_impl_all!(
if C::has_normalizer() { if C::has_normalizer() {
let normalizer = self.matrix().fixed_slice::<1, D>(D, 0); let normalizer = self.matrix().fixed_slice::<1, D>(D, 0);
#[allow(clippy::suspicious_arithmetic_impl)] #[allow(clippy::suspicious_arithmetic_impl)]
let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked((D, D)) }; let n = normalizer.tr_dot(&rhs.coords) + unsafe { self.matrix().get_unchecked((D, D)).clone() };
if !n.is_zero() { if !n.is_zero() {
return (transform * rhs + translation) / n; return (transform * rhs + translation) / n;
@ -221,8 +221,8 @@ md_impl_all!(
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>, Output = Transform<T, C::Representative, 3>; self: Transform<T, C, 3>, rhs: UnitQuaternion<T>, Output = Transform<T, C::Representative, 3>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.clone().to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.clone().to_homogeneous());
); );
// Transform × UnitComplex // Transform × UnitComplex
@ -235,8 +235,8 @@ md_impl_all!(
self: Transform<T, C, 2>, rhs: UnitComplex<T>, Output = Transform<T, C::Representative, 2>; self: Transform<T, C, 2>, rhs: UnitComplex<T>, Output = Transform<T, C::Representative, 2>;
[val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val val] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous());
[ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref val] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous());
[val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.to_homogeneous()); [val ref] => Self::Output::from_matrix_unchecked(self.into_inner() * rhs.clone().to_homogeneous());
[ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.to_homogeneous()); [ref ref] => Self::Output::from_matrix_unchecked(self.matrix() * rhs.clone().to_homogeneous());
); );
// UnitQuaternion × Transform // UnitQuaternion × Transform
@ -248,9 +248,9 @@ md_impl_all!(
where C: TCategoryMul<TAffine>; where C: TCategoryMul<TAffine>;
self: UnitQuaternion<T>, rhs: Transform<T, C, 3>, Output = Transform<T, C::Representative, 3>; self: UnitQuaternion<T>, rhs: Transform<T, C, 3>, Output = Transform<T, C::Representative, 3>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [ref ref] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.matrix());
); );
// UnitComplex × Transform // UnitComplex × Transform
@ -262,9 +262,9 @@ md_impl_all!(
where C: TCategoryMul<TAffine>; where C: TCategoryMul<TAffine>;
self: UnitComplex<T>, rhs: Transform<T, C, 2>, Output = Transform<T, C::Representative, 2>; self: UnitComplex<T>, rhs: Transform<T, C, 2>, Output = Transform<T, C::Representative, 2>;
[val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [val val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner());
[ref val] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.into_inner()); [ref val] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.into_inner());
[val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [val ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix());
[ref ref] => Self::Output::from_matrix_unchecked(self.to_homogeneous() * rhs.matrix()); [ref ref] => Self::Output::from_matrix_unchecked(self.clone().to_homogeneous() * rhs.matrix());
); );
// Transform × Isometry // Transform × Isometry
@ -604,7 +604,7 @@ md_assign_impl_all!(
where C: TCategory; where C: TCategory;
self: Transform<T, C, 3>, rhs: UnitQuaternion<T>; self: Transform<T, C, 3>, rhs: UnitQuaternion<T>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.clone().to_homogeneous();
); );
// Transform ×= UnitComplex // Transform ×= UnitComplex
@ -616,7 +616,7 @@ md_assign_impl_all!(
where C: TCategory; where C: TCategory;
self: Transform<T, C, 2>, rhs: UnitComplex<T>; self: Transform<T, C, 2>, rhs: UnitComplex<T>;
[val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [val] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous();
[ref] => *self.matrix_mut_unchecked() *= rhs.to_homogeneous(); [ref] => *self.matrix_mut_unchecked() *= rhs.clone().to_homogeneous();
); );
// Transform ÷= Transform // Transform ÷= Transform

View File

@ -291,7 +291,7 @@ impl<T: Scalar + PartialEq, const D: usize> PartialEq for Translation<T, D> {
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D> impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
type Epsilon = T::Epsilon; type Epsilon = T::Epsilon;
@ -308,7 +308,7 @@ where
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D> impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_relative() -> Self::Epsilon { fn default_max_relative() -> Self::Epsilon {
@ -329,7 +329,7 @@ where
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D> impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D>
where where
T::Epsilon: Copy, T::Epsilon: Clone,
{ {
#[inline] #[inline]
fn default_max_ulps() -> u32 { fn default_max_ulps() -> u32 {

View File

@ -77,7 +77,7 @@ where
{ {
#[inline] #[inline]
fn to_superset(&self) -> UnitDualQuaternion<T2> { fn to_superset(&self) -> UnitDualQuaternion<T2> {
let dq = UnitDualQuaternion::<T1>::from_parts(*self, UnitQuaternion::identity()); let dq = UnitDualQuaternion::<T1>::from_parts(self.clone(), UnitQuaternion::identity());
dq.to_superset() dq.to_superset()
} }

View File

@ -47,25 +47,25 @@ impl<T: SimdRealField> Normed for Complex<T> {
fn norm(&self) -> T::SimdRealField { fn norm(&self) -> T::SimdRealField {
// We don't use `.norm_sqr()` because it requires // We don't use `.norm_sqr()` because it requires
// some very strong Num trait requirements. // some very strong Num trait requirements.
(self.re * self.re + self.im * self.im).simd_sqrt() (self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()).simd_sqrt()
} }
#[inline] #[inline]
fn norm_squared(&self) -> T::SimdRealField { fn norm_squared(&self) -> T::SimdRealField {
// We don't use `.norm_sqr()` because it requires // We don't use `.norm_sqr()` because it requires
// some very strong Num trait requirements. // some very strong Num trait requirements.
self.re * self.re + self.im * self.im self.re.clone() * self.re.clone() + self.im.clone() * self.im.clone()
} }
#[inline] #[inline]
fn scale_mut(&mut self, n: Self::Norm) { fn scale_mut(&mut self, n: Self::Norm) {
self.re *= n; self.re *= n.clone();
self.im *= n; self.im *= n;
} }
#[inline] #[inline]
fn unscale_mut(&mut self, n: Self::Norm) { fn unscale_mut(&mut self, n: Self::Norm) {
self.re /= n; self.re /= n.clone();
self.im /= n; self.im /= n;
} }
} }
@ -86,7 +86,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn angle(&self) -> T { pub fn angle(&self) -> T {
self.im.simd_atan2(self.re) self.im.clone().simd_atan2(self.re.clone())
} }
/// The sine of the rotation angle. /// The sine of the rotation angle.
@ -101,7 +101,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn sin_angle(&self) -> T { pub fn sin_angle(&self) -> T {
self.im self.im.clone()
} }
/// The cosine of the rotation angle. /// The cosine of the rotation angle.
@ -116,7 +116,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn cos_angle(&self) -> T { pub fn cos_angle(&self) -> T {
self.re self.re.clone()
} }
/// The rotation angle returned as a 1-dimensional vector. /// The rotation angle returned as a 1-dimensional vector.
@ -145,7 +145,7 @@ where
if ang.is_zero() { if ang.is_zero() {
None None
} else if ang.is_sign_negative() { } else if ang.is_sign_negative() {
Some((Unit::new_unchecked(Vector1::x()), -ang)) Some((Unit::new_unchecked(Vector1::x()), -ang.clone()))
} else { } else {
Some((Unit::new_unchecked(-Vector1::<T>::x()), ang)) Some((Unit::new_unchecked(-Vector1::<T>::x()), ang))
} }
@ -223,7 +223,7 @@ where
#[inline] #[inline]
pub fn conjugate_mut(&mut self) { pub fn conjugate_mut(&mut self) {
let me = self.as_mut_unchecked(); let me = self.as_mut_unchecked();
me.im = -me.im; me.im = -me.im.clone();
} }
/// Inverts in-place this unit complex number. /// Inverts in-place this unit complex number.
@ -262,10 +262,10 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn to_rotation_matrix(self) -> Rotation2<T> { pub fn to_rotation_matrix(self) -> Rotation2<T> {
let r = self.re; let r = self.re.clone();
let i = self.im; let i = self.im.clone();
Rotation2::from_matrix_unchecked(Matrix2::new(r, -i, i, r)) Rotation2::from_matrix_unchecked(Matrix2::new(r.clone(), -i.clone(), i, r))
} }
/// Converts this unit complex number into its equivalent homogeneous transformation matrix. /// Converts this unit complex number into its equivalent homogeneous transformation matrix.
@ -407,7 +407,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn slerp(&self, other: &Self, t: T) -> Self { pub fn slerp(&self, other: &Self, t: T) -> Self {
Self::new(self.angle() * (T::one() - t) + other.angle() * t) Self::new(self.angle() * (T::one() - t.clone()) + other.angle() * t)
} }
} }
@ -427,7 +427,7 @@ impl<T: RealField> AbsDiffEq for UnitComplex<T> {
#[inline] #[inline]
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
self.re.abs_diff_eq(&other.re, epsilon) && self.im.abs_diff_eq(&other.im, epsilon) self.re.abs_diff_eq(&other.re, epsilon.clone()) && self.im.abs_diff_eq(&other.im, epsilon)
} }
} }
@ -444,7 +444,8 @@ impl<T: RealField> RelativeEq for UnitComplex<T> {
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.clone(), max_relative.clone())
&& self.im.relative_eq(&other.im, epsilon, max_relative) && self.im.relative_eq(&other.im, epsilon, max_relative)
} }
} }
@ -457,7 +458,8 @@ impl<T: RealField> UlpsEq for UnitComplex<T> {
#[inline] #[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
self.re.ulps_eq(&other.re, epsilon, max_ulps) self.re
.ulps_eq(&other.re, epsilon.clone(), max_ulps.clone())
&& self.im.ulps_eq(&other.im, epsilon, max_ulps) && self.im.ulps_eq(&other.im, epsilon, max_ulps)
} }
} }

View File

@ -109,7 +109,7 @@ where
/// the `::new(angle)` method instead is more common. /// the `::new(angle)` method instead is more common.
#[inline] #[inline]
pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self { pub fn from_scaled_axis<SB: Storage<T, U1>>(axisangle: Vector<T, U1, SB>) -> Self {
Self::from_angle(axisangle[0]) Self::from_angle(axisangle[0].clone())
} }
} }
@ -166,8 +166,8 @@ where
/// The input complex number will be normalized. Returns the norm of the complex number as well. /// The input complex number will be normalized. Returns the norm of the complex number as well.
#[inline] #[inline]
pub fn from_complex_and_get(q: Complex<T>) -> (Self, T) { pub fn from_complex_and_get(q: Complex<T>) -> (Self, T) {
let norm = (q.im * q.im + q.re * q.re).simd_sqrt(); let norm = (q.im.clone() * q.im.clone() + q.re.clone() * q.re.clone()).simd_sqrt();
(Self::new_unchecked(q / norm), norm) (Self::new_unchecked(q / norm.clone()), norm)
} }
/// Builds the unit complex number from the corresponding 2D rotation matrix. /// Builds the unit complex number from the corresponding 2D rotation matrix.
@ -182,7 +182,7 @@ where
// TODO: add UnitComplex::from(...) instead? // TODO: add UnitComplex::from(...) instead?
#[inline] #[inline]
pub fn from_rotation_matrix(rotmat: &Rotation2<T>) -> Self { pub fn from_rotation_matrix(rotmat: &Rotation2<T>) -> Self {
Self::new_unchecked(Complex::new(rotmat[(0, 0)], rotmat[(1, 0)])) Self::new_unchecked(Complex::new(rotmat[(0, 0)].clone(), rotmat[(1, 0)].clone()))
} }
/// Builds a rotation from a basis assumed to be orthonormal. /// Builds a rotation from a basis assumed to be orthonormal.
@ -410,7 +410,7 @@ where
#[inline] #[inline]
fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<T> { fn sample<'a, R: Rng + ?Sized>(&self, rng: &mut R) -> UnitComplex<T> {
let x = rng.sample(rand_distr::UnitCircle); let x = rng.sample(rand_distr::UnitCircle);
UnitComplex::new_unchecked(Complex::new(x[0], x[1])) UnitComplex::new_unchecked(Complex::new(x[0].clone(), x[1].clone()))
} }
} }

View File

@ -121,7 +121,7 @@ where
{ {
#[inline] #[inline]
fn to_superset(&self) -> Transform<T2, C, 2> { fn to_superset(&self) -> Transform<T2, C, 2> {
Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
} }
#[inline] #[inline]
@ -138,7 +138,7 @@ where
impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix3<T2>> for UnitComplex<T1> { impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix3<T2>> for UnitComplex<T1> {
#[inline] #[inline]
fn to_superset(&self) -> Matrix3<T2> { fn to_superset(&self) -> Matrix3<T2> {
self.to_homogeneous().to_superset() self.clone().to_homogeneous().to_superset()
} }
#[inline] #[inline]

View File

@ -255,9 +255,9 @@ complex_op_impl_all!(
[ref val] => self * &rhs; [ref val] => self * &rhs;
[val ref] => &self * rhs; [val ref] => &self * rhs;
[ref ref] => { [ref ref] => {
let i = self.as_ref().im; let i = self.as_ref().im.clone();
let r = self.as_ref().re; let r = self.as_ref().re.clone();
Vector2::new(r * rhs[0] - i * rhs[1], i * rhs[0] + r * rhs[1]) Vector2::new(r.clone() * rhs[0].clone() - i.clone() * rhs[1].clone(), i * rhs[0].clone() + r * rhs[1].clone())
}; };
); );
@ -306,9 +306,9 @@ complex_op_impl_all!(
self: UnitComplex<T>, rhs: Translation<T, 2>, self: UnitComplex<T>, rhs: Translation<T, 2>,
Output = Isometry<T, UnitComplex<T>, 2>; Output = Isometry<T, UnitComplex<T>, 2>;
[val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self); [val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self); [ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), self.clone());
[val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self); [val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
[ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), *self); [ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), self.clone());
); );
// Translation × UnitComplex // Translation × UnitComplex
@ -318,9 +318,9 @@ complex_op_impl_all!(
self: Translation<T, 2>, right: UnitComplex<T>, self: Translation<T, 2>, right: UnitComplex<T>,
Output = Isometry<T, UnitComplex<T>, 2>; Output = Isometry<T, UnitComplex<T>, 2>;
[val val] => Isometry::from_parts(self, right); [val val] => Isometry::from_parts(self, right);
[ref val] => Isometry::from_parts(*self, right); [ref val] => Isometry::from_parts(self.clone(), right);
[val ref] => Isometry::from_parts(self, *right); [val ref] => Isometry::from_parts(self, right.clone());
[ref ref] => Isometry::from_parts(*self, *right); [ref ref] => Isometry::from_parts(self.clone(), right.clone());
); );
// UnitComplex ×= UnitComplex // UnitComplex ×= UnitComplex
@ -330,7 +330,7 @@ where
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: UnitComplex<T>) { fn mul_assign(&mut self, rhs: UnitComplex<T>) {
*self = *self * rhs *self = self.clone() * rhs
} }
} }
@ -340,7 +340,7 @@ where
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) { fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
*self = *self * rhs *self = self.clone() * rhs
} }
} }
@ -351,7 +351,7 @@ where
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: UnitComplex<T>) { fn div_assign(&mut self, rhs: UnitComplex<T>) {
*self = *self / rhs *self = self.clone() / rhs
} }
} }
@ -361,7 +361,7 @@ where
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) { fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
*self = *self / rhs *self = self.clone() / rhs
} }
} }
@ -372,7 +372,7 @@ where
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: Rotation<T, 2>) { fn mul_assign(&mut self, rhs: Rotation<T, 2>) {
*self = *self * rhs *self = self.clone() * rhs
} }
} }
@ -382,7 +382,7 @@ where
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b Rotation<T, 2>) { fn mul_assign(&mut self, rhs: &'b Rotation<T, 2>) {
*self = *self * rhs *self = self.clone() * rhs
} }
} }
@ -393,7 +393,7 @@ where
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: Rotation<T, 2>) { fn div_assign(&mut self, rhs: Rotation<T, 2>) {
*self = *self / rhs *self = self.clone() / rhs
} }
} }
@ -403,7 +403,7 @@ where
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: &'b Rotation<T, 2>) { fn div_assign(&mut self, rhs: &'b Rotation<T, 2>) {
*self = *self / rhs *self = self.clone() / rhs
} }
} }
@ -424,7 +424,7 @@ where
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) { fn mul_assign(&mut self, rhs: &'b UnitComplex<T>) {
self.mul_assign(rhs.to_rotation_matrix()) self.mul_assign(rhs.clone().to_rotation_matrix())
} }
} }
@ -445,6 +445,6 @@ where
{ {
#[inline] #[inline]
fn div_assign(&mut self, rhs: &'b UnitComplex<T>) { fn div_assign(&mut self, rhs: &'b UnitComplex<T>) {
self.div_assign(rhs.to_rotation_matrix()) self.div_assign(rhs.clone().to_rotation_matrix())
} }
} }

View File

@ -390,7 +390,7 @@ pub fn center<T: SimdComplexField, const D: usize>(
p1: &Point<T, D>, p1: &Point<T, D>,
p2: &Point<T, D>, p2: &Point<T, D>,
) -> Point<T, D> { ) -> Point<T, D> {
((p1.coords + p2.coords) * convert::<_, T>(0.5)).into() ((&p1.coords + &p2.coords) * convert::<_, T>(0.5)).into()
} }
/// The distance between two points. /// The distance between two points.
@ -404,7 +404,7 @@ pub fn distance<T: SimdComplexField, const D: usize>(
p1: &Point<T, D>, p1: &Point<T, D>,
p2: &Point<T, D>, p2: &Point<T, D>,
) -> T::SimdRealField { ) -> T::SimdRealField {
(p2.coords - p1.coords).norm() (&p2.coords - &p1.coords).norm()
} }
/// The squared distance between two points. /// The squared distance between two points.
@ -418,7 +418,7 @@ pub fn distance_squared<T: SimdComplexField, const D: usize>(
p1: &Point<T, D>, p1: &Point<T, D>,
p2: &Point<T, D>, p2: &Point<T, D>,
) -> T::SimdRealField { ) -> T::SimdRealField {
(p2.coords - p1.coords).norm_squared() (&p2.coords - &p1.coords).norm_squared()
} }
/* /*

View File

@ -31,33 +31,33 @@ where
let mut n_row = matrix.row(i).norm_squared(); let mut n_row = matrix.row(i).norm_squared();
let mut f = T::one(); let mut f = T::one();
let s = n_col + n_row; let s = n_col.clone() + n_row.clone();
n_col = n_col.sqrt(); n_col = n_col.sqrt();
n_row = n_row.sqrt(); n_row = n_row.sqrt();
if n_col.is_zero() || n_row.is_zero() { if n_col.clone().is_zero() || n_row.clone().is_zero() {
continue; continue;
} }
while n_col < n_row / radix { while n_col.clone() < n_row.clone() / radix.clone() {
n_col *= radix; n_col *= radix.clone();
n_row /= radix; n_row /= radix.clone();
f *= radix; f *= radix.clone();
} }
while n_col >= n_row * radix { while n_col.clone() >= n_row.clone() * radix.clone() {
n_col /= radix; n_col /= radix.clone();
n_row *= radix; n_row *= radix.clone();
f /= radix; f /= radix.clone();
} }
let eps: T = crate::convert(0.95); let eps: T = crate::convert(0.95);
#[allow(clippy::suspicious_operation_groupings)] #[allow(clippy::suspicious_operation_groupings)]
if n_col * n_col + n_row * n_row < eps * s { if n_col.clone() * n_col + n_row.clone() * n_row < eps * s {
converged = false; converged = false;
d[i] *= f; d[i] *= f.clone();
matrix.column_mut(i).mul_assign(f); matrix.column_mut(i).mul_assign(f.clone());
matrix.row_mut(i).div_assign(f); matrix.row_mut(i).div_assign(f.clone());
} }
} }
} }
@ -75,10 +75,10 @@ where
for j in 0..d.len() { for j in 0..d.len() {
let mut col = m.column_mut(j); let mut col = m.column_mut(j);
let denom = T::one() / d[j]; let denom = T::one() / d[j].clone();
for i in 0..d.len() { for i in 0..d.len() {
col[i] *= d[i] * denom; col[i] *= d[i].clone() * denom.clone();
} }
} }
} }

View File

@ -195,11 +195,19 @@ where
let d = nrows.min(ncols); let d = nrows.min(ncols);
let mut res = OMatrix::identity_generic(d, d); let mut res = OMatrix::identity_generic(d, d);
res.set_partial_diagonal(self.diagonal.iter().map(|e| T::from_real(e.modulus()))); res.set_partial_diagonal(
self.diagonal
.iter()
.map(|e| T::from_real(e.clone().modulus())),
);
let start = self.axis_shift(); let start = self.axis_shift();
res.slice_mut(start, (d.value() - 1, d.value() - 1)) res.slice_mut(start, (d.value() - 1, d.value() - 1))
.set_partial_diagonal(self.off_diagonal.iter().map(|e| T::from_real(e.modulus()))); .set_partial_diagonal(
self.off_diagonal
.iter()
.map(|e| T::from_real(e.clone().modulus())),
);
res res
} }
@ -225,9 +233,9 @@ where
let mut res_rows = res.slice_range_mut(i + shift.., i..); let mut res_rows = res.slice_range_mut(i + shift.., i..);
let sign = if self.upper_diagonal { let sign = if self.upper_diagonal {
self.diagonal[i].signum() self.diagonal[i].clone().signum()
} else { } else {
self.off_diagonal[i].signum() self.off_diagonal[i].clone().signum()
}; };
refl.reflect_with_sign(&mut res_rows, sign); refl.reflect_with_sign(&mut res_rows, sign);
@ -261,9 +269,9 @@ where
let mut res_rows = res.slice_range_mut(i.., i + shift..); let mut res_rows = res.slice_range_mut(i.., i + shift..);
let sign = if self.upper_diagonal { let sign = if self.upper_diagonal {
self.off_diagonal[i].signum() self.off_diagonal[i].clone().signum()
} else { } else {
self.diagonal[i].signum() self.diagonal[i].clone().signum()
}; };
refl.reflect_rows_with_sign(&mut res_rows, &mut work.rows_range_mut(i..), sign); refl.reflect_rows_with_sign(&mut res_rows, &mut work.rows_range_mut(i..), sign);

View File

@ -52,7 +52,7 @@ where
for j in 0..n { for j in 0..n {
for k in 0..j { for k in 0..j {
let factor = unsafe { -*matrix.get_unchecked((j, k)) }; let factor = unsafe { -matrix.get_unchecked((j, k)).clone() };
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k); let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
let mut col_j = col_j.rows_range_mut(j..); let mut col_j = col_j.rows_range_mut(j..);
@ -60,11 +60,11 @@ where
col_j.axpy(factor.simd_conjugate(), &col_k, T::one()); col_j.axpy(factor.simd_conjugate(), &col_k, T::one());
} }
let diag = unsafe { *matrix.get_unchecked((j, j)) }; let diag = unsafe { matrix.get_unchecked((j, j)).clone() };
let denom = diag.simd_sqrt(); let denom = diag.simd_sqrt();
unsafe { unsafe {
*matrix.get_unchecked_mut((j, j)) = denom; *matrix.get_unchecked_mut((j, j)) = denom.clone();
} }
let mut col = matrix.slice_range_mut(j + 1.., j); let mut col = matrix.slice_range_mut(j + 1.., j);
@ -149,7 +149,7 @@ where
let dim = self.chol.nrows(); let dim = self.chol.nrows();
let mut prod_diag = T::one(); let mut prod_diag = T::one();
for i in 0..dim { for i in 0..dim {
prod_diag *= unsafe { *self.chol.get_unchecked((i, i)) }; prod_diag *= unsafe { self.chol.get_unchecked((i, i)).clone() };
} }
prod_diag.simd_modulus_squared() prod_diag.simd_modulus_squared()
} }
@ -170,7 +170,7 @@ where
for j in 0..n { for j in 0..n {
for k in 0..j { for k in 0..j {
let factor = unsafe { -*matrix.get_unchecked((j, k)) }; let factor = unsafe { -matrix.get_unchecked((j, k)).clone() };
let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k); let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
let mut col_j = col_j.rows_range_mut(j..); let mut col_j = col_j.rows_range_mut(j..);
@ -179,11 +179,11 @@ where
col_j.axpy(factor.conjugate(), &col_k, T::one()); col_j.axpy(factor.conjugate(), &col_k, T::one());
} }
let diag = unsafe { *matrix.get_unchecked((j, j)) }; let diag = unsafe { matrix.get_unchecked((j, j)).clone() };
if !diag.is_zero() { if !diag.is_zero() {
if let Some(denom) = diag.try_sqrt() { if let Some(denom) = diag.try_sqrt() {
unsafe { unsafe {
*matrix.get_unchecked_mut((j, j)) = denom; *matrix.get_unchecked_mut((j, j)) = denom.clone();
} }
let mut col = matrix.slice_range_mut(j + 1.., j); let mut col = matrix.slice_range_mut(j + 1.., j);
@ -254,7 +254,7 @@ where
// update the jth row // update the jth row
let top_left_corner = self.chol.slice_range(..j, ..j); let top_left_corner = self.chol.slice_range(..j, ..j);
let col_j = col[j]; let col_j = col[j].clone();
let (mut new_rowj_adjoint, mut new_colj) = col.rows_range_pair_mut(..j, j + 1..); let (mut new_rowj_adjoint, mut new_colj) = col.rows_range_pair_mut(..j, j + 1..);
assert!( assert!(
top_left_corner.solve_lower_triangular_mut(&mut new_rowj_adjoint), top_left_corner.solve_lower_triangular_mut(&mut new_rowj_adjoint),
@ -265,13 +265,13 @@ where
// update the center element // update the center element
let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared())); let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared()));
chol[(j, j)] = center_element; chol[(j, j)] = center_element.clone();
// update the jth column // update the jth column
let bottom_left_corner = self.chol.slice_range(j.., ..j); let bottom_left_corner = self.chol.slice_range(j.., ..j);
// new_colj = (col_jplus - bottom_left_corner * new_rowj.adjoint()) / center_element; // new_colj = (col_jplus - bottom_left_corner * new_rowj.adjoint()) / center_element;
new_colj.gemm( new_colj.gemm(
-T::one() / center_element, -T::one() / center_element.clone(),
&bottom_left_corner, &bottom_left_corner,
&new_rowj_adjoint, &new_rowj_adjoint,
T::one() / center_element, T::one() / center_element,
@ -353,23 +353,23 @@ where
for j in 0..n { for j in 0..n {
// updates the diagonal // updates the diagonal
let diag = T::real(unsafe { *chol.get_unchecked((j, j)) }); let diag = T::real(unsafe { chol.get_unchecked((j, j)).clone() });
let diag2 = diag * diag; let diag2 = diag.clone() * diag.clone();
let xj = unsafe { *x.get_unchecked(j) }; let xj = unsafe { x.get_unchecked(j).clone() };
let sigma_xj2 = sigma * T::modulus_squared(xj); let sigma_xj2 = sigma.clone() * T::modulus_squared(xj.clone());
let gamma = diag2 * beta + sigma_xj2; let gamma = diag2.clone() * beta.clone() + sigma_xj2.clone();
let new_diag = (diag2 + sigma_xj2 / beta).sqrt(); let new_diag = (diag2.clone() + sigma_xj2.clone() / beta.clone()).sqrt();
unsafe { *chol.get_unchecked_mut((j, j)) = T::from_real(new_diag) }; unsafe { *chol.get_unchecked_mut((j, j)) = T::from_real(new_diag.clone()) };
beta += sigma_xj2 / diag2; beta += sigma_xj2 / diag2;
// updates the terms of L // updates the terms of L
let mut xjplus = x.rows_range_mut(j + 1..); let mut xjplus = x.rows_range_mut(j + 1..);
let mut col_j = chol.slice_range_mut(j + 1.., j); let mut col_j = chol.slice_range_mut(j + 1.., j);
// temp_jplus -= (wj / T::from_real(diag)) * col_j; // temp_jplus -= (wj / T::from_real(diag)) * col_j;
xjplus.axpy(-xj / T::from_real(diag), &col_j, T::one()); xjplus.axpy(-xj.clone() / T::from_real(diag.clone()), &col_j, T::one());
if gamma != crate::zero::<T::RealField>() { if gamma != crate::zero::<T::RealField>() {
// col_j = T::from_real(nljj / diag) * col_j + (T::from_real(nljj * sigma / gamma) * T::conjugate(wj)) * temp_jplus; // col_j = T::from_real(nljj / diag) * col_j + (T::from_real(nljj * sigma / gamma) * T::conjugate(wj)) * temp_jplus;
col_j.axpy( col_j.axpy(
T::from_real(new_diag * sigma / gamma) * T::conjugate(xj), T::from_real(new_diag.clone() * sigma.clone() / gamma) * T::conjugate(xj),
&xjplus, &xjplus,
T::from_real(new_diag / diag), T::from_real(new_diag / diag),
); );

View File

@ -109,7 +109,7 @@ where
.col_piv_qr .col_piv_qr
.rows_generic(0, nrows.min(ncols)) .rows_generic(0, nrows.min(ncols))
.upper_triangle(); .upper_triangle();
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus()))); res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
res res
} }
@ -126,7 +126,7 @@ where
.col_piv_qr .col_piv_qr
.resize_generic(nrows.min(ncols), ncols, T::zero()); .resize_generic(nrows.min(ncols), ncols, T::zero());
res.fill_lower_triangle(T::zero(), 1); res.fill_lower_triangle(T::zero(), 1);
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus()))); res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
res res
} }
@ -149,7 +149,7 @@ where
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let mut res_rows = res.slice_range_mut(i.., i..); let mut res_rows = res.slice_range_mut(i.., i..);
refl.reflect_with_sign(&mut res_rows, self.diag[i].signum()); refl.reflect_with_sign(&mut res_rows, self.diag[i].clone().signum());
} }
res res
@ -195,7 +195,7 @@ where
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let mut rhs_rows = rhs.rows_range_mut(i..); let mut rhs_rows = rhs.rows_range_mut(i..);
refl.reflect_with_sign(&mut rhs_rows, self.diag[i].signum().conjugate()); refl.reflect_with_sign(&mut rhs_rows, self.diag[i].clone().signum().conjugate());
} }
} }
} }
@ -270,14 +270,14 @@ where
let coeff; let coeff;
unsafe { unsafe {
let diag = self.diag.vget_unchecked(i).modulus(); let diag = self.diag.vget_unchecked(i).clone().modulus();
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
coeff = b.vget_unchecked(i).unscale(diag); coeff = b.vget_unchecked(i).clone().unscale(diag);
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(..i) b.rows_range_mut(..i)
@ -337,7 +337,7 @@ where
let mut res = T::one(); let mut res = T::one();
for i in 0..dim { for i in 0..dim {
res *= unsafe { *self.diag.vget_unchecked(i) }; res *= unsafe { self.diag.vget_unchecked(i).clone() };
} }
res * self.p.determinant() res * self.p.determinant()

View File

@ -47,11 +47,11 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
let u_f = cmp::min(i, vec - 1); let u_f = cmp::min(i, vec - 1);
if u_i == u_f { if u_i == u_f {
conv[i] += self[u_i] * kernel[(i - u_i)]; conv[i] += self[u_i].clone() * kernel[(i - u_i)].clone();
} else { } else {
for u in u_i..(u_f + 1) { for u in u_i..(u_f + 1) {
if i - u < ker { if i - u < ker {
conv[i] += self[u] * kernel[(i - u)]; conv[i] += self[u].clone() * kernel[(i - u)].clone();
} }
} }
} }
@ -97,7 +97,7 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
for i in 0..(vec - ker + 1) { for i in 0..(vec - ker + 1) {
for j in 0..ker { for j in 0..ker {
conv[i] += self[i + j] * kernel[ker - j - 1]; conv[i] += self[i + j].clone() * kernel[ker - j - 1].clone();
} }
} }
conv conv
@ -133,9 +133,9 @@ impl<T: RealField, D1: Dim, S1: Storage<T, D1>> Vector<T, D1, S1> {
let val = if i + j < 1 || i + j >= vec + 1 { let val = if i + j < 1 || i + j >= vec + 1 {
zero::<T>() zero::<T>()
} else { } else {
self[i + j - 1] self[i + j - 1].clone()
}; };
conv[i] += val * kernel[ker - j - 1]; conv[i] += val * kernel[ker - j - 1].clone();
} }
} }

View File

@ -26,30 +26,30 @@ impl<T: ComplexField, D: DimMin<D, Output = D>, S: Storage<T, D, D>> SquareMatri
unsafe { unsafe {
match dim { match dim {
0 => T::one(), 0 => T::one(),
1 => *self.get_unchecked((0, 0)), 1 => self.get_unchecked((0, 0)).clone(),
2 => { 2 => {
let m11 = *self.get_unchecked((0, 0)); let m11 = self.get_unchecked((0, 0)).clone();
let m12 = *self.get_unchecked((0, 1)); let m12 = self.get_unchecked((0, 1)).clone();
let m21 = *self.get_unchecked((1, 0)); let m21 = self.get_unchecked((1, 0)).clone();
let m22 = *self.get_unchecked((1, 1)); let m22 = self.get_unchecked((1, 1)).clone();
m11 * m22 - m21 * m12 m11 * m22 - m21 * m12
} }
3 => { 3 => {
let m11 = *self.get_unchecked((0, 0)); let m11 = self.get_unchecked((0, 0)).clone();
let m12 = *self.get_unchecked((0, 1)); let m12 = self.get_unchecked((0, 1)).clone();
let m13 = *self.get_unchecked((0, 2)); let m13 = self.get_unchecked((0, 2)).clone();
let m21 = *self.get_unchecked((1, 0)); let m21 = self.get_unchecked((1, 0)).clone();
let m22 = *self.get_unchecked((1, 1)); let m22 = self.get_unchecked((1, 1)).clone();
let m23 = *self.get_unchecked((1, 2)); let m23 = self.get_unchecked((1, 2)).clone();
let m31 = *self.get_unchecked((2, 0)); let m31 = self.get_unchecked((2, 0)).clone();
let m32 = *self.get_unchecked((2, 1)); let m32 = self.get_unchecked((2, 1)).clone();
let m33 = *self.get_unchecked((2, 2)); let m33 = self.get_unchecked((2, 2)).clone();
let minor_m12_m23 = m22 * m33 - m32 * m23; let minor_m12_m23 = m22.clone() * m33.clone() - m32.clone() * m23.clone();
let minor_m11_m23 = m21 * m33 - m31 * m23; let minor_m11_m23 = m21.clone() * m33.clone() - m31.clone() * m23.clone();
let minor_m11_m22 = m21 * m32 - m31 * m22; let minor_m11_m22 = m21 * m32 - m31 * m22;
m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22 m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22

View File

@ -116,7 +116,7 @@ where
self.calc_a4(); self.calc_a4();
self.d4_exact = Some(one_norm(self.a4.as_ref().unwrap()).powf(convert(0.25))); self.d4_exact = Some(one_norm(self.a4.as_ref().unwrap()).powf(convert(0.25)));
} }
self.d4_exact.unwrap() self.d4_exact.clone().unwrap()
} }
fn d6_tight(&mut self) -> T::RealField { fn d6_tight(&mut self) -> T::RealField {
@ -124,7 +124,7 @@ where
self.calc_a6(); self.calc_a6();
self.d6_exact = Some(one_norm(self.a6.as_ref().unwrap()).powf(convert(1.0 / 6.0))); self.d6_exact = Some(one_norm(self.a6.as_ref().unwrap()).powf(convert(1.0 / 6.0)));
} }
self.d6_exact.unwrap() self.d6_exact.clone().unwrap()
} }
fn d8_tight(&mut self) -> T::RealField { fn d8_tight(&mut self) -> T::RealField {
@ -132,7 +132,7 @@ where
self.calc_a8(); self.calc_a8();
self.d8_exact = Some(one_norm(self.a8.as_ref().unwrap()).powf(convert(1.0 / 8.0))); self.d8_exact = Some(one_norm(self.a8.as_ref().unwrap()).powf(convert(1.0 / 8.0)));
} }
self.d8_exact.unwrap() self.d8_exact.clone().unwrap()
} }
fn d10_tight(&mut self) -> T::RealField { fn d10_tight(&mut self) -> T::RealField {
@ -140,7 +140,7 @@ where
self.calc_a10(); self.calc_a10();
self.d10_exact = Some(one_norm(self.a10.as_ref().unwrap()).powf(convert(1.0 / 10.0))); self.d10_exact = Some(one_norm(self.a10.as_ref().unwrap()).powf(convert(1.0 / 10.0)));
} }
self.d10_exact.unwrap() self.d10_exact.clone().unwrap()
} }
fn d4_loose(&mut self) -> T::RealField { fn d4_loose(&mut self) -> T::RealField {
@ -149,7 +149,7 @@ where
} }
if self.d4_exact.is_some() { if self.d4_exact.is_some() {
return self.d4_exact.unwrap(); return self.d4_exact.clone().unwrap();
} }
if self.d4_approx.is_none() { if self.d4_approx.is_none() {
@ -157,7 +157,7 @@ where
self.d4_approx = Some(one_norm(self.a4.as_ref().unwrap()).powf(convert(0.25))); self.d4_approx = Some(one_norm(self.a4.as_ref().unwrap()).powf(convert(0.25)));
} }
self.d4_approx.unwrap() self.d4_approx.clone().unwrap()
} }
fn d6_loose(&mut self) -> T::RealField { fn d6_loose(&mut self) -> T::RealField {
@ -166,7 +166,7 @@ where
} }
if self.d6_exact.is_some() { if self.d6_exact.is_some() {
return self.d6_exact.unwrap(); return self.d6_exact.clone().unwrap();
} }
if self.d6_approx.is_none() { if self.d6_approx.is_none() {
@ -174,7 +174,7 @@ where
self.d6_approx = Some(one_norm(self.a6.as_ref().unwrap()).powf(convert(1.0 / 6.0))); self.d6_approx = Some(one_norm(self.a6.as_ref().unwrap()).powf(convert(1.0 / 6.0)));
} }
self.d6_approx.unwrap() self.d6_approx.clone().unwrap()
} }
fn d8_loose(&mut self) -> T::RealField { fn d8_loose(&mut self) -> T::RealField {
@ -183,7 +183,7 @@ where
} }
if self.d8_exact.is_some() { if self.d8_exact.is_some() {
return self.d8_exact.unwrap(); return self.d8_exact.clone().unwrap();
} }
if self.d8_approx.is_none() { if self.d8_approx.is_none() {
@ -191,7 +191,7 @@ where
self.d8_approx = Some(one_norm(self.a8.as_ref().unwrap()).powf(convert(1.0 / 8.0))); self.d8_approx = Some(one_norm(self.a8.as_ref().unwrap()).powf(convert(1.0 / 8.0)));
} }
self.d8_approx.unwrap() self.d8_approx.clone().unwrap()
} }
fn d10_loose(&mut self) -> T::RealField { fn d10_loose(&mut self) -> T::RealField {
@ -200,7 +200,7 @@ where
} }
if self.d10_exact.is_some() { if self.d10_exact.is_some() {
return self.d10_exact.unwrap(); return self.d10_exact.clone().unwrap();
} }
if self.d10_approx.is_none() { if self.d10_approx.is_none() {
@ -208,15 +208,15 @@ where
self.d10_approx = Some(one_norm(self.a10.as_ref().unwrap()).powf(convert(1.0 / 10.0))); self.d10_approx = Some(one_norm(self.a10.as_ref().unwrap()).powf(convert(1.0 / 10.0)));
} }
self.d10_approx.unwrap() self.d10_approx.clone().unwrap()
} }
fn pade3(&mut self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) { fn pade3(&mut self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) {
let b: [T; 4] = [convert(120.0), convert(60.0), convert(12.0), convert(1.0)]; let b: [T; 4] = [convert(120.0), convert(60.0), convert(12.0), convert(1.0)];
self.calc_a2(); self.calc_a2();
let a2 = self.a2.as_ref().unwrap(); let a2 = self.a2.as_ref().unwrap();
let u = &self.a * (a2 * b[3] + &self.ident * b[1]); let u = &self.a * (a2 * b[3].clone() + &self.ident * b[1].clone());
let v = a2 * b[2] + &self.ident * b[0]; let v = a2 * b[2].clone() + &self.ident * b[0].clone();
(u, v) (u, v)
} }
@ -232,12 +232,12 @@ where
self.calc_a2(); self.calc_a2();
self.calc_a6(); self.calc_a6();
let u = &self.a let u = &self.a
* (self.a4.as_ref().unwrap() * b[5] * (self.a4.as_ref().unwrap() * b[5].clone()
+ self.a2.as_ref().unwrap() * b[3] + self.a2.as_ref().unwrap() * b[3].clone()
+ &self.ident * b[1]); + &self.ident * b[1].clone());
let v = self.a4.as_ref().unwrap() * b[4] let v = self.a4.as_ref().unwrap() * b[4].clone()
+ self.a2.as_ref().unwrap() * b[2] + self.a2.as_ref().unwrap() * b[2].clone()
+ &self.ident * b[0]; + &self.ident * b[0].clone();
(u, v) (u, v)
} }
@ -256,14 +256,14 @@ where
self.calc_a4(); self.calc_a4();
self.calc_a6(); self.calc_a6();
let u = &self.a let u = &self.a
* (self.a6.as_ref().unwrap() * b[7] * (self.a6.as_ref().unwrap() * b[7].clone()
+ self.a4.as_ref().unwrap() * b[5] + self.a4.as_ref().unwrap() * b[5].clone()
+ self.a2.as_ref().unwrap() * b[3] + self.a2.as_ref().unwrap() * b[3].clone()
+ &self.ident * b[1]); + &self.ident * b[1].clone());
let v = self.a6.as_ref().unwrap() * b[6] let v = self.a6.as_ref().unwrap() * b[6].clone()
+ self.a4.as_ref().unwrap() * b[4] + self.a4.as_ref().unwrap() * b[4].clone()
+ self.a2.as_ref().unwrap() * b[2] + self.a2.as_ref().unwrap() * b[2].clone()
+ &self.ident * b[0]; + &self.ident * b[0].clone();
(u, v) (u, v)
} }
@ -285,16 +285,16 @@ where
self.calc_a6(); self.calc_a6();
self.calc_a8(); self.calc_a8();
let u = &self.a let u = &self.a
* (self.a8.as_ref().unwrap() * b[9] * (self.a8.as_ref().unwrap() * b[9].clone()
+ self.a6.as_ref().unwrap() * b[7] + self.a6.as_ref().unwrap() * b[7].clone()
+ self.a4.as_ref().unwrap() * b[5] + self.a4.as_ref().unwrap() * b[5].clone()
+ self.a2.as_ref().unwrap() * b[3] + self.a2.as_ref().unwrap() * b[3].clone()
+ &self.ident * b[1]); + &self.ident * b[1].clone());
let v = self.a8.as_ref().unwrap() * b[8] let v = self.a8.as_ref().unwrap() * b[8].clone()
+ self.a6.as_ref().unwrap() * b[6] + self.a6.as_ref().unwrap() * b[6].clone()
+ self.a4.as_ref().unwrap() * b[4] + self.a4.as_ref().unwrap() * b[4].clone()
+ self.a2.as_ref().unwrap() * b[2] + self.a2.as_ref().unwrap() * b[2].clone()
+ &self.ident * b[0]; + &self.ident * b[0].clone();
(u, v) (u, v)
} }
@ -321,14 +321,23 @@ where
self.calc_a2(); self.calc_a2();
self.calc_a4(); self.calc_a4();
self.calc_a6(); self.calc_a6();
let mb2 = self.a2.as_ref().unwrap() * convert::<f64, T>(2.0_f64.powf(-2.0 * s)); let mb2 = self.a2.as_ref().unwrap() * convert::<f64, T>(2.0_f64.powf(-2.0 * s.clone()));
let mb4 = self.a4.as_ref().unwrap() * convert::<f64, T>(2.0.powf(-4.0 * s)); let mb4 = self.a4.as_ref().unwrap() * convert::<f64, T>(2.0.powf(-4.0 * s.clone()));
let mb6 = self.a6.as_ref().unwrap() * convert::<f64, T>(2.0.powf(-6.0 * s)); let mb6 = self.a6.as_ref().unwrap() * convert::<f64, T>(2.0.powf(-6.0 * s));
let u2 = &mb6 * (&mb6 * b[13] + &mb4 * b[11] + &mb2 * b[9]); let u2 = &mb6 * (&mb6 * b[13].clone() + &mb4 * b[11].clone() + &mb2 * b[9].clone());
let u = &mb * (&u2 + &mb6 * b[7] + &mb4 * b[5] + &mb2 * b[3] + &self.ident * b[1]); let u = &mb
let v2 = &mb6 * (&mb6 * b[12] + &mb4 * b[10] + &mb2 * b[8]); * (&u2
let v = v2 + &mb6 * b[6] + &mb4 * b[4] + &mb2 * b[2] + &self.ident * b[0]; + &mb6 * b[7].clone()
+ &mb4 * b[5].clone()
+ &mb2 * b[3].clone()
+ &self.ident * b[1].clone());
let v2 = &mb6 * (&mb6 * b[12].clone() + &mb4 * b[10].clone() + &mb2 * b[8].clone());
let v = v2
+ &mb6 * b[6].clone()
+ &mb4 * b[4].clone()
+ &mb2 * b[2].clone()
+ &self.ident * b[0].clone();
(u, v) (u, v)
} }
} }
@ -417,7 +426,9 @@ where
let col = m.column(i); let col = m.column(i);
max = max.max( max = max.max(
col.iter() col.iter()
.fold(<T as ComplexField>::RealField::zero(), |a, b| a + b.abs()), .fold(<T as ComplexField>::RealField::zero(), |a, b| {
a + b.clone().abs()
}),
); );
} }

View File

@ -67,7 +67,7 @@ where
let piv = matrix.slice_range(i.., i..).icamax_full(); let piv = matrix.slice_range(i.., i..).icamax_full();
let row_piv = piv.0 + i; let row_piv = piv.0 + i;
let col_piv = piv.1 + i; let col_piv = piv.1 + i;
let diag = matrix[(row_piv, col_piv)]; let diag = matrix[(row_piv, col_piv)].clone();
if diag.is_zero() { if diag.is_zero() {
// The remaining of the matrix is zero. // The remaining of the matrix is zero.
@ -253,10 +253,10 @@ where
); );
let dim = self.lu.nrows(); let dim = self.lu.nrows();
let mut res = self.lu[(dim - 1, dim - 1)]; let mut res = self.lu[(dim - 1, dim - 1)].clone();
if !res.is_zero() { if !res.is_zero() {
for i in 0..dim - 1 { for i in 0..dim - 1 {
res *= unsafe { *self.lu.get_unchecked((i, i)) }; res *= unsafe { self.lu.get_unchecked((i, i)).clone() };
} }
res * self.p.determinant() * self.q.determinant() res * self.p.determinant() * self.q.determinant()

View File

@ -42,12 +42,12 @@ impl<T: ComplexField> GivensRotation<T> {
/// Initializes a Givens rotation form its non-normalized cosine an sine components. /// Initializes a Givens rotation form its non-normalized cosine an sine components.
pub fn try_new(c: T, s: T, eps: T::RealField) -> Option<(Self, T)> { pub fn try_new(c: T, s: T, eps: T::RealField) -> Option<(Self, T)> {
let (mod0, sign0) = c.to_exp(); let (mod0, sign0) = c.to_exp();
let denom = (mod0 * mod0 + s.modulus_squared()).sqrt(); let denom = (mod0.clone() * mod0.clone() + s.clone().modulus_squared()).sqrt();
if denom > eps { if denom > eps {
let norm = sign0.scale(denom); let norm = sign0.scale(denom.clone());
let c = mod0 / denom; let c = mod0 / denom;
let s = s / norm; let s = s.clone() / norm.clone();
Some((Self { c, s }, norm)) Some((Self { c, s }, norm))
} else { } else {
None None
@ -60,10 +60,10 @@ impl<T: ComplexField> GivensRotation<T> {
/// of `v` and the rotation `r` such that `R * v = [ |v|, 0.0 ]^t` where `|v|` is the norm of `v`. /// of `v` and the rotation `r` such that `R * v = [ |v|, 0.0 ]^t` where `|v|` is the norm of `v`.
pub fn cancel_y<S: Storage<T, U2>>(v: &Vector<T, U2, S>) -> Option<(Self, T)> { pub fn cancel_y<S: Storage<T, U2>>(v: &Vector<T, U2, S>) -> Option<(Self, T)> {
if !v[1].is_zero() { if !v[1].is_zero() {
let (mod0, sign0) = v[0].to_exp(); let (mod0, sign0) = v[0].clone().to_exp();
let denom = (mod0 * mod0 + v[1].modulus_squared()).sqrt(); let denom = (mod0.clone() * mod0.clone() + v[1].clone().modulus_squared()).sqrt();
let c = mod0 / denom; let c = mod0 / denom.clone();
let s = -v[1] / sign0.scale(denom); let s = -v[1].clone() / sign0.clone().scale(denom.clone());
let r = sign0.scale(denom); let r = sign0.scale(denom);
Some((Self { c, s }, r)) Some((Self { c, s }, r))
} else { } else {
@ -77,10 +77,10 @@ impl<T: ComplexField> GivensRotation<T> {
/// of `v` and the rotation `r` such that `R * v = [ 0.0, |v| ]^t` where `|v|` is the norm of `v`. /// of `v` and the rotation `r` such that `R * v = [ 0.0, |v| ]^t` where `|v|` is the norm of `v`.
pub fn cancel_x<S: Storage<T, U2>>(v: &Vector<T, U2, S>) -> Option<(Self, T)> { pub fn cancel_x<S: Storage<T, U2>>(v: &Vector<T, U2, S>) -> Option<(Self, T)> {
if !v[0].is_zero() { if !v[0].is_zero() {
let (mod1, sign1) = v[1].to_exp(); let (mod1, sign1) = v[1].clone().to_exp();
let denom = (mod1 * mod1 + v[0].modulus_squared()).sqrt(); let denom = (mod1.clone() * mod1.clone() + v[0].clone().modulus_squared()).sqrt();
let c = mod1 / denom; let c = mod1 / denom.clone();
let s = (v[0].conjugate() * sign1).unscale(denom); let s = (v[0].clone().conjugate() * sign1.clone()).unscale(denom.clone());
let r = sign1.scale(denom); let r = sign1.scale(denom);
Some((Self { c, s }, r)) Some((Self { c, s }, r))
} else { } else {
@ -91,21 +91,21 @@ impl<T: ComplexField> GivensRotation<T> {
/// The cos part of this roration. /// The cos part of this roration.
#[must_use] #[must_use]
pub fn c(&self) -> T::RealField { pub fn c(&self) -> T::RealField {
self.c self.c.clone()
} }
/// The sin part of this roration. /// The sin part of this roration.
#[must_use] #[must_use]
pub fn s(&self) -> T { pub fn s(&self) -> T {
self.s self.s.clone()
} }
/// The inverse of this givens rotation. /// The inverse of this givens rotation.
#[must_use = "This function does not mutate self."] #[must_use = "This function does not mutate self."]
pub fn inverse(&self) -> Self { pub fn inverse(&self) -> Self {
Self { Self {
c: self.c, c: self.c.clone(),
s: -self.s, s: -self.s.clone(),
} }
} }
@ -121,16 +121,17 @@ impl<T: ComplexField> GivensRotation<T> {
2, 2,
"Unit complex rotation: the input matrix must have exactly two rows." "Unit complex rotation: the input matrix must have exactly two rows."
); );
let s = self.s; let s = self.s.clone();
let c = self.c; let c = self.c.clone();
for j in 0..rhs.ncols() { for j in 0..rhs.ncols() {
unsafe { unsafe {
let a = *rhs.get_unchecked((0, j)); let a = rhs.get_unchecked((0, j)).clone();
let b = *rhs.get_unchecked((1, j)); let b = rhs.get_unchecked((1, j)).clone();
*rhs.get_unchecked_mut((0, j)) = a.scale(c) - s.conjugate() * b; *rhs.get_unchecked_mut((0, j)) =
*rhs.get_unchecked_mut((1, j)) = s * a + b.scale(c); a.clone().scale(c.clone()) - s.clone().conjugate() * b.clone();
*rhs.get_unchecked_mut((1, j)) = s.clone() * a + b.scale(c.clone());
} }
} }
} }
@ -147,17 +148,17 @@ impl<T: ComplexField> GivensRotation<T> {
2, 2,
"Unit complex rotation: the input matrix must have exactly two columns." "Unit complex rotation: the input matrix must have exactly two columns."
); );
let s = self.s; let s = self.s.clone();
let c = self.c; let c = self.c.clone();
// TODO: can we optimize that to iterate on one column at a time ? // TODO: can we optimize that to iterate on one column at a time ?
for j in 0..lhs.nrows() { for j in 0..lhs.nrows() {
unsafe { unsafe {
let a = *lhs.get_unchecked((j, 0)); let a = lhs.get_unchecked((j, 0)).clone();
let b = *lhs.get_unchecked((j, 1)); let b = lhs.get_unchecked((j, 1)).clone();
*lhs.get_unchecked_mut((j, 0)) = a.scale(c) + s * b; *lhs.get_unchecked_mut((j, 0)) = a.clone().scale(c.clone()) + s.clone() * b.clone();
*lhs.get_unchecked_mut((j, 1)) = -s.conjugate() * a + b.scale(c); *lhs.get_unchecked_mut((j, 1)) = -s.clone().conjugate() * a + b.scale(c.clone());
} }
} }
} }

View File

@ -114,7 +114,11 @@ where
self.hess.fill_lower_triangle(T::zero(), 2); self.hess.fill_lower_triangle(T::zero(), 2);
self.hess self.hess
.slice_mut((1, 0), (dim - 1, dim - 1)) .slice_mut((1, 0), (dim - 1, dim - 1))
.set_partial_diagonal(self.subdiag.iter().map(|e| T::from_real(e.modulus()))); .set_partial_diagonal(
self.subdiag
.iter()
.map(|e| T::from_real(e.clone().modulus())),
);
self.hess self.hess
} }
@ -129,7 +133,11 @@ where
let mut res = self.hess.clone(); let mut res = self.hess.clone();
res.fill_lower_triangle(T::zero(), 2); res.fill_lower_triangle(T::zero(), 2);
res.slice_mut((1, 0), (dim - 1, dim - 1)) res.slice_mut((1, 0), (dim - 1, dim - 1))
.set_partial_diagonal(self.subdiag.iter().map(|e| T::from_real(e.modulus()))); .set_partial_diagonal(
self.subdiag
.iter()
.map(|e| T::from_real(e.clone().modulus())),
);
res res
} }

View File

@ -20,16 +20,16 @@ pub fn reflection_axis_mut<T: ComplexField, D: Dim, S: StorageMut<T, D>>(
column: &mut Vector<T, D, S>, column: &mut Vector<T, D, S>,
) -> (T, bool) { ) -> (T, bool) {
let reflection_sq_norm = column.norm_squared(); let reflection_sq_norm = column.norm_squared();
let reflection_norm = reflection_sq_norm.sqrt(); let reflection_norm = reflection_sq_norm.clone().sqrt();
let factor; let factor;
let signed_norm; let signed_norm;
unsafe { unsafe {
let (modulus, sign) = column.vget_unchecked(0).to_exp(); let (modulus, sign) = column.vget_unchecked(0).clone().to_exp();
signed_norm = sign.scale(reflection_norm); signed_norm = sign.scale(reflection_norm.clone());
factor = (reflection_sq_norm + modulus * reflection_norm) * crate::convert(2.0); factor = (reflection_sq_norm + modulus * reflection_norm) * crate::convert(2.0);
*column.vget_unchecked_mut(0) += signed_norm; *column.vget_unchecked_mut(0) += signed_norm.clone();
}; };
if !factor.is_zero() { if !factor.is_zero() {
@ -63,9 +63,9 @@ where
if not_zero { if not_zero {
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let sign = reflection_norm.signum(); let sign = reflection_norm.clone().signum();
if let Some(mut work) = bilateral { if let Some(mut work) = bilateral {
refl.reflect_rows_with_sign(&mut right, &mut work, sign); refl.reflect_rows_with_sign(&mut right, &mut work, sign.clone());
} }
refl.reflect_with_sign(&mut right.rows_range_mut(icol + shift..), sign.conjugate()); refl.reflect_with_sign(&mut right.rows_range_mut(icol + shift..), sign.conjugate());
} }
@ -101,7 +101,7 @@ where
refl.reflect_rows_with_sign( refl.reflect_rows_with_sign(
&mut bottom.columns_range_mut(irow + shift..), &mut bottom.columns_range_mut(irow + shift..),
&mut work.rows_range_mut(irow + 1..), &mut work.rows_range_mut(irow + 1..),
reflection_norm.signum().conjugate(), reflection_norm.clone().signum().conjugate(),
); );
top.columns_range_mut(irow + shift..) top.columns_range_mut(irow + shift..)
.tr_copy_from(refl.axis()); .tr_copy_from(refl.axis());
@ -132,7 +132,7 @@ where
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let mut res_rows = res.slice_range_mut(i + 1.., i..); let mut res_rows = res.slice_range_mut(i + 1.., i..);
refl.reflect_with_sign(&mut res_rows, signs[i].signum()); refl.reflect_with_sign(&mut res_rows, signs[i].clone().signum());
} }
res res

View File

@ -40,7 +40,7 @@ impl<T: ComplexField, D: Dim, S: StorageMut<T, D, D>> SquareMatrix<T, D, S> {
match dim { match dim {
0 => true, 0 => true,
1 => { 1 => {
let determinant = *self.get_unchecked((0, 0)); let determinant = self.get_unchecked((0, 0)).clone();
if determinant.is_zero() { if determinant.is_zero() {
false false
} else { } else {
@ -49,58 +49,66 @@ impl<T: ComplexField, D: Dim, S: StorageMut<T, D, D>> SquareMatrix<T, D, S> {
} }
} }
2 => { 2 => {
let m11 = *self.get_unchecked((0, 0)); let m11 = self.get_unchecked((0, 0)).clone();
let m12 = *self.get_unchecked((0, 1)); let m12 = self.get_unchecked((0, 1)).clone();
let m21 = *self.get_unchecked((1, 0)); let m21 = self.get_unchecked((1, 0)).clone();
let m22 = *self.get_unchecked((1, 1)); let m22 = self.get_unchecked((1, 1)).clone();
let determinant = m11 * m22 - m21 * m12; let determinant = m11.clone() * m22.clone() - m21.clone() * m12.clone();
if determinant.is_zero() { if determinant.is_zero() {
false false
} else { } else {
*self.get_unchecked_mut((0, 0)) = m22 / determinant; *self.get_unchecked_mut((0, 0)) = m22 / determinant.clone();
*self.get_unchecked_mut((0, 1)) = -m12 / determinant; *self.get_unchecked_mut((0, 1)) = -m12 / determinant.clone();
*self.get_unchecked_mut((1, 0)) = -m21 / determinant; *self.get_unchecked_mut((1, 0)) = -m21 / determinant.clone();
*self.get_unchecked_mut((1, 1)) = m11 / determinant; *self.get_unchecked_mut((1, 1)) = m11 / determinant;
true true
} }
} }
3 => { 3 => {
let m11 = *self.get_unchecked((0, 0)); let m11 = self.get_unchecked((0, 0)).clone();
let m12 = *self.get_unchecked((0, 1)); let m12 = self.get_unchecked((0, 1)).clone();
let m13 = *self.get_unchecked((0, 2)); let m13 = self.get_unchecked((0, 2)).clone();
let m21 = *self.get_unchecked((1, 0)); let m21 = self.get_unchecked((1, 0)).clone();
let m22 = *self.get_unchecked((1, 1)); let m22 = self.get_unchecked((1, 1)).clone();
let m23 = *self.get_unchecked((1, 2)); let m23 = self.get_unchecked((1, 2)).clone();
let m31 = *self.get_unchecked((2, 0)); let m31 = self.get_unchecked((2, 0)).clone();
let m32 = *self.get_unchecked((2, 1)); let m32 = self.get_unchecked((2, 1)).clone();
let m33 = *self.get_unchecked((2, 2)); let m33 = self.get_unchecked((2, 2)).clone();
let minor_m12_m23 = m22 * m33 - m32 * m23; let minor_m12_m23 = m22.clone() * m33.clone() - m32.clone() * m23.clone();
let minor_m11_m23 = m21 * m33 - m31 * m23; let minor_m11_m23 = m21.clone() * m33.clone() - m31.clone() * m23.clone();
let minor_m11_m22 = m21 * m32 - m31 * m22; let minor_m11_m22 = m21.clone() * m32.clone() - m31.clone() * m22.clone();
let determinant = let determinant = m11.clone() * minor_m12_m23.clone()
m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22; - m12.clone() * minor_m11_m23.clone()
+ m13.clone() * minor_m11_m22.clone();
if determinant.is_zero() { if determinant.is_zero() {
false false
} else { } else {
*self.get_unchecked_mut((0, 0)) = minor_m12_m23 / determinant; *self.get_unchecked_mut((0, 0)) = minor_m12_m23 / determinant.clone();
*self.get_unchecked_mut((0, 1)) = (m13 * m32 - m33 * m12) / determinant; *self.get_unchecked_mut((0, 1)) = (m13.clone() * m32.clone()
*self.get_unchecked_mut((0, 2)) = (m12 * m23 - m22 * m13) / determinant; - m33.clone() * m12.clone())
/ determinant.clone();
*self.get_unchecked_mut((0, 2)) = (m12.clone() * m23.clone()
- m22.clone() * m13.clone())
/ determinant.clone();
*self.get_unchecked_mut((1, 0)) = -minor_m11_m23 / determinant; *self.get_unchecked_mut((1, 0)) = -minor_m11_m23 / determinant.clone();
*self.get_unchecked_mut((1, 1)) = (m11 * m33 - m31 * m13) / determinant; *self.get_unchecked_mut((1, 1)) =
*self.get_unchecked_mut((1, 2)) = (m13 * m21 - m23 * m11) / determinant; (m11.clone() * m33 - m31.clone() * m13.clone()) / determinant.clone();
*self.get_unchecked_mut((1, 2)) =
(m13 * m21.clone() - m23 * m11.clone()) / determinant.clone();
*self.get_unchecked_mut((2, 0)) = minor_m11_m22 / determinant; *self.get_unchecked_mut((2, 0)) = minor_m11_m22 / determinant.clone();
*self.get_unchecked_mut((2, 1)) = (m12 * m31 - m32 * m11) / determinant; *self.get_unchecked_mut((2, 1)) =
(m12.clone() * m31 - m32 * m11.clone()) / determinant.clone();
*self.get_unchecked_mut((2, 2)) = (m11 * m22 - m21 * m12) / determinant; *self.get_unchecked_mut((2, 2)) = (m11 * m22 - m21 * m12) / determinant;
true true
@ -129,94 +137,129 @@ where
{ {
let m = m.as_slice(); let m = m.as_slice();
out[(0, 0)] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] out[(0, 0)] = m[5].clone() * m[10].clone() * m[15].clone()
+ m[9] * m[7] * m[14] - m[5].clone() * m[11].clone() * m[14].clone()
+ m[13] * m[6] * m[11] - m[9].clone() * m[6].clone() * m[15].clone()
- m[13] * m[7] * m[10]; + m[9].clone() * m[7].clone() * m[14].clone()
+ m[13].clone() * m[6].clone() * m[11].clone()
- m[13].clone() * m[7].clone() * m[10].clone();
out[(1, 0)] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] out[(1, 0)] = -m[1].clone() * m[10].clone() * m[15].clone()
- m[9] * m[3] * m[14] + m[1].clone() * m[11].clone() * m[14].clone()
- m[13] * m[2] * m[11] + m[9].clone() * m[2].clone() * m[15].clone()
+ m[13] * m[3] * m[10]; - m[9].clone() * m[3].clone() * m[14].clone()
- m[13].clone() * m[2].clone() * m[11].clone()
+ m[13].clone() * m[3].clone() * m[10].clone();
out[(2, 0)] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] out[(2, 0)] = m[1].clone() * m[6].clone() * m[15].clone()
+ m[5] * m[3] * m[14] - m[1].clone() * m[7].clone() * m[14].clone()
+ m[13] * m[2] * m[7] - m[5].clone() * m[2].clone() * m[15].clone()
- m[13] * m[3] * m[6]; + m[5].clone() * m[3].clone() * m[14].clone()
+ m[13].clone() * m[2].clone() * m[7].clone()
- m[13].clone() * m[3].clone() * m[6].clone();
out[(3, 0)] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] out[(3, 0)] = -m[1].clone() * m[6].clone() * m[11].clone()
- m[5] * m[3] * m[10] + m[1].clone() * m[7].clone() * m[10].clone()
- m[9] * m[2] * m[7] + m[5].clone() * m[2].clone() * m[11].clone()
+ m[9] * m[3] * m[6]; - m[5].clone() * m[3].clone() * m[10].clone()
- m[9].clone() * m[2].clone() * m[7].clone()
+ m[9].clone() * m[3].clone() * m[6].clone();
out[(0, 1)] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] out[(0, 1)] = -m[4].clone() * m[10].clone() * m[15].clone()
- m[8] * m[7] * m[14] + m[4].clone() * m[11].clone() * m[14].clone()
- m[12] * m[6] * m[11] + m[8].clone() * m[6].clone() * m[15].clone()
+ m[12] * m[7] * m[10]; - m[8].clone() * m[7].clone() * m[14].clone()
- m[12].clone() * m[6].clone() * m[11].clone()
+ m[12].clone() * m[7].clone() * m[10].clone();
out[(1, 1)] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] out[(1, 1)] = m[0].clone() * m[10].clone() * m[15].clone()
+ m[8] * m[3] * m[14] - m[0].clone() * m[11].clone() * m[14].clone()
+ m[12] * m[2] * m[11] - m[8].clone() * m[2].clone() * m[15].clone()
- m[12] * m[3] * m[10]; + m[8].clone() * m[3].clone() * m[14].clone()
+ m[12].clone() * m[2].clone() * m[11].clone()
- m[12].clone() * m[3].clone() * m[10].clone();
out[(2, 1)] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] out[(2, 1)] = -m[0].clone() * m[6].clone() * m[15].clone()
- m[4] * m[3] * m[14] + m[0].clone() * m[7].clone() * m[14].clone()
- m[12] * m[2] * m[7] + m[4].clone() * m[2].clone() * m[15].clone()
+ m[12] * m[3] * m[6]; - m[4].clone() * m[3].clone() * m[14].clone()
- m[12].clone() * m[2].clone() * m[7].clone()
+ m[12].clone() * m[3].clone() * m[6].clone();
out[(3, 1)] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] out[(3, 1)] = m[0].clone() * m[6].clone() * m[11].clone()
+ m[4] * m[3] * m[10] - m[0].clone() * m[7].clone() * m[10].clone()
+ m[8] * m[2] * m[7] - m[4].clone() * m[2].clone() * m[11].clone()
- m[8] * m[3] * m[6]; + m[4].clone() * m[3].clone() * m[10].clone()
+ m[8].clone() * m[2].clone() * m[7].clone()
- m[8].clone() * m[3].clone() * m[6].clone();
out[(0, 2)] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] out[(0, 2)] = m[4].clone() * m[9].clone() * m[15].clone()
+ m[8] * m[7] * m[13] - m[4].clone() * m[11].clone() * m[13].clone()
+ m[12] * m[5] * m[11] - m[8].clone() * m[5].clone() * m[15].clone()
- m[12] * m[7] * m[9]; + m[8].clone() * m[7].clone() * m[13].clone()
+ m[12].clone() * m[5].clone() * m[11].clone()
- m[12].clone() * m[7].clone() * m[9].clone();
out[(1, 2)] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] out[(1, 2)] = -m[0].clone() * m[9].clone() * m[15].clone()
- m[8] * m[3] * m[13] + m[0].clone() * m[11].clone() * m[13].clone()
- m[12] * m[1] * m[11] + m[8].clone() * m[1].clone() * m[15].clone()
+ m[12] * m[3] * m[9]; - m[8].clone() * m[3].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[11].clone()
+ m[12].clone() * m[3].clone() * m[9].clone();
out[(2, 2)] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] out[(2, 2)] = m[0].clone() * m[5].clone() * m[15].clone()
+ m[4] * m[3] * m[13] - m[0].clone() * m[7].clone() * m[13].clone()
+ m[12] * m[1] * m[7] - m[4].clone() * m[1].clone() * m[15].clone()
- m[12] * m[3] * m[5]; + m[4].clone() * m[3].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[7].clone()
- m[12].clone() * m[3].clone() * m[5].clone();
out[(0, 3)] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] out[(0, 3)] = -m[4].clone() * m[9].clone() * m[14].clone()
- m[8] * m[6] * m[13] + m[4].clone() * m[10].clone() * m[13].clone()
- m[12] * m[5] * m[10] + m[8].clone() * m[5].clone() * m[14].clone()
+ m[12] * m[6] * m[9]; - m[8].clone() * m[6].clone() * m[13].clone()
- m[12].clone() * m[5].clone() * m[10].clone()
+ m[12].clone() * m[6].clone() * m[9].clone();
out[(3, 2)] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] out[(3, 2)] = -m[0].clone() * m[5].clone() * m[11].clone()
- m[4] * m[3] * m[9] + m[0].clone() * m[7].clone() * m[9].clone()
- m[8] * m[1] * m[7] + m[4].clone() * m[1].clone() * m[11].clone()
+ m[8] * m[3] * m[5]; - m[4].clone() * m[3].clone() * m[9].clone()
- m[8].clone() * m[1].clone() * m[7].clone()
+ m[8].clone() * m[3].clone() * m[5].clone();
out[(1, 3)] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] out[(1, 3)] = m[0].clone() * m[9].clone() * m[14].clone()
+ m[8] * m[2] * m[13] - m[0].clone() * m[10].clone() * m[13].clone()
+ m[12] * m[1] * m[10] - m[8].clone() * m[1].clone() * m[14].clone()
- m[12] * m[2] * m[9]; + m[8].clone() * m[2].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[10].clone()
- m[12].clone() * m[2].clone() * m[9].clone();
out[(2, 3)] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] out[(2, 3)] = -m[0].clone() * m[5].clone() * m[14].clone()
- m[4] * m[2] * m[13] + m[0].clone() * m[6].clone() * m[13].clone()
- m[12] * m[1] * m[6] + m[4].clone() * m[1].clone() * m[14].clone()
+ m[12] * m[2] * m[5]; - m[4].clone() * m[2].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[6].clone()
+ m[12].clone() * m[2].clone() * m[5].clone();
out[(3, 3)] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] out[(3, 3)] = m[0].clone() * m[5].clone() * m[10].clone()
+ m[4] * m[2] * m[9] - m[0].clone() * m[6].clone() * m[9].clone()
+ m[8] * m[1] * m[6] - m[4].clone() * m[1].clone() * m[10].clone()
- m[8] * m[2] * m[5]; + m[4].clone() * m[2].clone() * m[9].clone()
+ m[8].clone() * m[1].clone() * m[6].clone()
- m[8].clone() * m[2].clone() * m[5].clone();
let det = m[0] * out[(0, 0)] + m[1] * out[(0, 1)] + m[2] * out[(0, 2)] + m[3] * out[(0, 3)]; let det = m[0].clone() * out[(0, 0)].clone()
+ m[1].clone() * out[(0, 1)].clone()
+ m[2].clone() * out[(0, 2)].clone()
+ m[3].clone() * out[(0, 3)].clone();
if !det.is_zero() { if !det.is_zero() {
let inv_det = T::one() / det; let inv_det = T::one() / det;
for j in 0..4 { for j in 0..4 {
for i in 0..4 { for i in 0..4 {
out[(i, j)] *= inv_det; out[(i, j)] *= inv_det.clone();
} }
} }
true true

View File

@ -65,7 +65,7 @@ where
for i in 0..dim { for i in 0..dim {
let piv = matrix.slice_range(i.., i).icamax() + i; let piv = matrix.slice_range(i.., i).icamax() + i;
let diag = matrix[(piv, i)]; let diag = matrix[(piv, i)].clone();
if diag.is_zero() { if diag.is_zero() {
return false; return false;
@ -101,7 +101,7 @@ where
for i in 0..min_nrows_ncols.value() { for i in 0..min_nrows_ncols.value() {
let piv = matrix.slice_range(i.., i).icamax() + i; let piv = matrix.slice_range(i.., i).icamax() + i;
let diag = matrix[(piv, i)]; let diag = matrix[(piv, i)].clone();
if diag.is_zero() { if diag.is_zero() {
// No non-zero entries on this column. // No non-zero entries on this column.
@ -306,7 +306,7 @@ where
let mut res = T::one(); let mut res = T::one();
for i in 0..dim { for i in 0..dim {
res *= unsafe { *self.lu.get_unchecked((i, i)) }; res *= unsafe { self.lu.get_unchecked((i, i)).clone() };
} }
res * self.p.determinant() res * self.p.determinant()
@ -351,7 +351,7 @@ where
for k in 0..pivot_row.ncols() { for k in 0..pivot_row.ncols() {
down.column_mut(k) down.column_mut(k)
.axpy(-pivot_row[k].inlined_clone(), &coeffs, T::one()); .axpy(-pivot_row[k].clone(), &coeffs, T::one());
} }
} }
@ -383,6 +383,6 @@ pub fn gauss_step_swap<T, R: Dim, C: Dim, S>(
for k in 0..pivot_row.ncols() { for k in 0..pivot_row.ncols() {
mem::swap(&mut pivot_row[k], &mut down[(piv - 1, k)]); mem::swap(&mut pivot_row[k], &mut down[(piv - 1, k)]);
down.column_mut(k) down.column_mut(k)
.axpy(-pivot_row[k].inlined_clone(), &coeffs, T::one()); .axpy(-pivot_row[k].clone(), &coeffs, T::one());
} }
} }

View File

@ -83,7 +83,7 @@ where
{ {
let (nrows, ncols) = self.qr.shape_generic(); let (nrows, ncols) = self.qr.shape_generic();
let mut res = self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle(); let mut res = self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle();
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus()))); res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
res res
} }
@ -98,7 +98,7 @@ where
let (nrows, ncols) = self.qr.shape_generic(); let (nrows, ncols) = self.qr.shape_generic();
let mut res = self.qr.resize_generic(nrows.min(ncols), ncols, T::zero()); let mut res = self.qr.resize_generic(nrows.min(ncols), ncols, T::zero());
res.fill_lower_triangle(T::zero(), 1); res.fill_lower_triangle(T::zero(), 1);
res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.modulus()))); res.set_partial_diagonal(self.diag.iter().map(|e| T::from_real(e.clone().modulus())));
res res
} }
@ -121,7 +121,7 @@ where
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let mut res_rows = res.slice_range_mut(i.., i..); let mut res_rows = res.slice_range_mut(i.., i..);
refl.reflect_with_sign(&mut res_rows, self.diag[i].signum()); refl.reflect_with_sign(&mut res_rows, self.diag[i].clone().signum());
} }
res res
@ -160,7 +160,7 @@ where
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero());
let mut rhs_rows = rhs.rows_range_mut(i..); let mut rhs_rows = rhs.rows_range_mut(i..);
refl.reflect_with_sign(&mut rhs_rows, self.diag[i].signum().conjugate()); refl.reflect_with_sign(&mut rhs_rows, self.diag[i].clone().signum().conjugate());
} }
} }
} }
@ -231,14 +231,14 @@ where
let coeff; let coeff;
unsafe { unsafe {
let diag = self.diag.vget_unchecked(i).modulus(); let diag = self.diag.vget_unchecked(i).clone().modulus();
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
coeff = b.vget_unchecked(i).unscale(diag); coeff = b.vget_unchecked(i).clone().unscale(diag);
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(..i) b.rows_range_mut(..i)

View File

@ -111,7 +111,7 @@ where
} }
let amax_m = m.camax(); let amax_m = m.camax();
m.unscale_mut(amax_m); m.unscale_mut(amax_m.clone());
let hess = Hessenberg::new_with_workspace(m, work); let hess = Hessenberg::new_with_workspace(m, work);
let mut q; let mut q;
@ -130,7 +130,7 @@ where
// Implicit double-shift QR method. // Implicit double-shift QR method.
let mut niter = 0; let mut niter = 0;
let (mut start, mut end) = Self::delimit_subproblem(&mut t, eps, dim.value() - 1); let (mut start, mut end) = Self::delimit_subproblem(&mut t, eps.clone(), dim.value() - 1);
while end != start { while end != start {
let subdim = end - start + 1; let subdim = end - start + 1;
@ -139,23 +139,23 @@ where
let m = end - 1; let m = end - 1;
let n = end; let n = end;
let h11 = t[(start, start)]; let h11 = t[(start, start)].clone();
let h12 = t[(start, start + 1)]; let h12 = t[(start, start + 1)].clone();
let h21 = t[(start + 1, start)]; let h21 = t[(start + 1, start)].clone();
let h22 = t[(start + 1, start + 1)]; let h22 = t[(start + 1, start + 1)].clone();
let h32 = t[(start + 2, start + 1)]; let h32 = t[(start + 2, start + 1)].clone();
let hnn = t[(n, n)]; let hnn = t[(n, n)].clone();
let hmm = t[(m, m)]; let hmm = t[(m, m)].clone();
let hnm = t[(n, m)]; let hnm = t[(n, m)].clone();
let hmn = t[(m, n)]; let hmn = t[(m, n)].clone();
let tra = hnn + hmm; let tra = hnn.clone() + hmm.clone();
let det = hnn * hmm - hnm * hmn; let det = hnn * hmm - hnm * hmn;
let mut axis = Vector3::new( let mut axis = Vector3::new(
h11 * h11 + h12 * h21 - tra * h11 + det, h11.clone() * h11.clone() + h12 * h21.clone() - tra.clone() * h11.clone() + det,
h21 * (h11 + h22 - tra), h21.clone() * (h11 + h22 - tra),
h21 * h32, h21 * h32,
); );
@ -169,7 +169,7 @@ where
t[(k + 2, k - 1)] = T::zero(); t[(k + 2, k - 1)] = T::zero();
} }
let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let refl = Reflection::new(Unit::new_unchecked(axis.clone()), T::zero());
{ {
let krows = cmp::min(k + 4, end + 1); let krows = cmp::min(k + 4, end + 1);
@ -192,15 +192,15 @@ where
} }
} }
axis.x = t[(k + 1, k)]; axis.x = t[(k + 1, k)].clone();
axis.y = t[(k + 2, k)]; axis.y = t[(k + 2, k)].clone();
if k < n - 2 { if k < n - 2 {
axis.z = t[(k + 3, k)]; axis.z = t[(k + 3, k)].clone();
} }
} }
let mut axis = Vector2::new(axis.x, axis.y); let mut axis = Vector2::new(axis.x.clone(), axis.y.clone());
let (norm, not_zero) = householder::reflection_axis_mut(&mut axis); let (norm, not_zero) = householder::reflection_axis_mut(&mut axis);
if not_zero { if not_zero {
@ -254,7 +254,7 @@ where
} }
} }
let sub = Self::delimit_subproblem(&mut t, eps, end); let sub = Self::delimit_subproblem(&mut t, eps.clone(), end);
start = sub.0; start = sub.0;
end = sub.1; end = sub.1;
@ -279,7 +279,7 @@ where
let n = m + 1; let n = m + 1;
if t[(n, m)].is_zero() { if t[(n, m)].is_zero() {
out[m] = t[(m, m)]; out[m] = t[(m, m)].clone();
m += 1; m += 1;
} else { } else {
// Complex eigenvalue. // Complex eigenvalue.
@ -288,7 +288,7 @@ where
} }
if m == dim - 1 { if m == dim - 1 {
out[m] = t[(m, m)]; out[m] = t[(m, m)].clone();
} }
true true
@ -307,33 +307,36 @@ where
let n = m + 1; let n = m + 1;
if t[(n, m)].is_zero() { if t[(n, m)].is_zero() {
out[m] = MaybeUninit::new(NumComplex::new(t[(m, m)], T::zero())); out[m] = MaybeUninit::new(NumComplex::new(t[(m, m)].clone(), T::zero()));
m += 1; m += 1;
} else { } else {
// Solve the 2x2 eigenvalue subproblem. // Solve the 2x2 eigenvalue subproblem.
let hmm = t[(m, m)]; let hmm = t[(m, m)].clone();
let hnm = t[(n, m)]; let hnm = t[(n, m)].clone();
let hmn = t[(m, n)]; let hmn = t[(m, n)].clone();
let hnn = t[(n, n)]; let hnn = t[(n, n)].clone();
// NOTE: use the same algorithm as in compute_2x2_eigvals. // NOTE: use the same algorithm as in compute_2x2_eigvals.
let val = (hmm - hnn) * crate::convert(0.5); let val = (hmm.clone() - hnn.clone()) * crate::convert(0.5);
let discr = hnm * hmn + val * val; let discr = hnm * hmn + val.clone() * val;
// All 2x2 blocks have negative discriminant because we already decoupled those // All 2x2 blocks have negative discriminant because we already decoupled those
// with positive eigenvalues. // with positive eigenvalues.
let sqrt_discr = NumComplex::new(T::zero(), (-discr).sqrt()); let sqrt_discr = NumComplex::new(T::zero(), (-discr).sqrt());
let half_tra = (hnn + hmm) * crate::convert(0.5); let half_tra = (hnn + hmm) * crate::convert(0.5);
out[m] = MaybeUninit::new(NumComplex::new(half_tra, T::zero()) + sqrt_discr); out[m] = MaybeUninit::new(
out[m + 1] = MaybeUninit::new(NumComplex::new(half_tra, T::zero()) - sqrt_discr); NumComplex::new(half_tra.clone(), T::zero()) + sqrt_discr.clone(),
);
out[m + 1] =
MaybeUninit::new(NumComplex::new(half_tra, T::zero()) - sqrt_discr.clone());
m += 2; m += 2;
} }
} }
if m == dim - 1 { if m == dim - 1 {
out[m] = MaybeUninit::new(NumComplex::new(t[(m, m)], T::zero())); out[m] = MaybeUninit::new(NumComplex::new(t[(m, m)].clone(), T::zero()));
} }
} }
@ -347,7 +350,9 @@ where
while n > 0 { while n > 0 {
let m = n - 1; let m = n - 1;
if t[(n, m)].norm1() <= eps * (t[(n, n)].norm1() + t[(m, m)].norm1()) { if t[(n, m)].clone().norm1()
<= eps.clone() * (t[(n, n)].clone().norm1() + t[(m, m)].clone().norm1())
{
t[(n, m)] = T::zero(); t[(n, m)] = T::zero();
} else { } else {
break; break;
@ -364,9 +369,11 @@ where
while new_start > 0 { while new_start > 0 {
let m = new_start - 1; let m = new_start - 1;
let off_diag = t[(new_start, m)]; let off_diag = t[(new_start, m)].clone();
if off_diag.is_zero() if off_diag.is_zero()
|| off_diag.norm1() <= eps * (t[(new_start, new_start)].norm1() + t[(m, m)].norm1()) || off_diag.norm1()
<= eps.clone()
* (t[(new_start, new_start)].clone().norm1() + t[(m, m)].clone().norm1())
{ {
t[(new_start, m)] = T::zero(); t[(new_start, m)] = T::zero();
break; break;
@ -435,7 +442,7 @@ where
q = Some(OMatrix::from_column_slice_generic( q = Some(OMatrix::from_column_slice_generic(
dim, dim,
dim, dim,
&[c, rot.s(), -rot.s().conjugate(), c], &[c.clone(), rot.s(), -rot.s().conjugate(), c],
)); ));
} }
} }
@ -453,20 +460,20 @@ fn compute_2x2_eigvals<T: ComplexField, S: Storage<T, U2, U2>>(
m: &SquareMatrix<T, U2, S>, m: &SquareMatrix<T, U2, S>,
) -> Option<(T, T)> { ) -> Option<(T, T)> {
// Solve the 2x2 eigenvalue subproblem. // Solve the 2x2 eigenvalue subproblem.
let h00 = m[(0, 0)]; let h00 = m[(0, 0)].clone();
let h10 = m[(1, 0)]; let h10 = m[(1, 0)].clone();
let h01 = m[(0, 1)]; let h01 = m[(0, 1)].clone();
let h11 = m[(1, 1)]; let h11 = m[(1, 1)].clone();
// NOTE: this discriminant computation is more stable than the // NOTE: this discriminant computation is more stable than the
// one based on the trace and determinant: 0.25 * tra * tra - det // one based on the trace and determinant: 0.25 * tra * tra - det
// because it ensures positiveness for symmetric matrices. // because it ensures positiveness for symmetric matrices.
let val = (h00 - h11) * crate::convert(0.5); let val = (h00.clone() - h11.clone()) * crate::convert(0.5);
let discr = h10 * h01 + val * val; let discr = h10 * h01 + val.clone() * val;
discr.try_sqrt().map(|sqrt_discr| { discr.try_sqrt().map(|sqrt_discr| {
let half_tra = (h00 + h11) * crate::convert(0.5); let half_tra = (h00 + h11) * crate::convert(0.5);
(half_tra + sqrt_discr, half_tra - sqrt_discr) (half_tra.clone() + sqrt_discr.clone(), half_tra - sqrt_discr)
}) })
} }
@ -478,20 +485,20 @@ fn compute_2x2_eigvals<T: ComplexField, S: Storage<T, U2, U2>>(
fn compute_2x2_basis<T: ComplexField, S: Storage<T, U2, U2>>( fn compute_2x2_basis<T: ComplexField, S: Storage<T, U2, U2>>(
m: &SquareMatrix<T, U2, S>, m: &SquareMatrix<T, U2, S>,
) -> Option<GivensRotation<T>> { ) -> Option<GivensRotation<T>> {
let h10 = m[(1, 0)]; let h10 = m[(1, 0)].clone();
if h10.is_zero() { if h10.is_zero() {
return None; return None;
} }
if let Some((eigval1, eigval2)) = compute_2x2_eigvals(m) { if let Some((eigval1, eigval2)) = compute_2x2_eigvals(m) {
let x1 = eigval1 - m[(1, 1)]; let x1 = eigval1 - m[(1, 1)].clone();
let x2 = eigval2 - m[(1, 1)]; let x2 = eigval2 - m[(1, 1)].clone();
// NOTE: Choose the one that yields a larger x component. // NOTE: Choose the one that yields a larger x component.
// This is necessary for numerical stability of the normalization of the complex // This is necessary for numerical stability of the normalization of the complex
// number. // number.
if x1.norm1() > x2.norm1() { if x1.clone().norm1() > x2.clone().norm1() {
Some(GivensRotation::new(x1, h10).0) Some(GivensRotation::new(x1, h10).0)
} else { } else {
Some(GivensRotation::new(x2, h10).0) Some(GivensRotation::new(x2, h10).0)

View File

@ -82,14 +82,14 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let coeff; let coeff;
unsafe { unsafe {
let diag = *self.get_unchecked((i, i)); let diag = self.get_unchecked((i, i)).clone();
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
coeff = *b.vget_unchecked(i) / diag; coeff = b.vget_unchecked(i).clone() / diag;
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(i + 1..) b.rows_range_mut(i + 1..)
@ -123,7 +123,7 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let mut bcol = b.column_mut(k); let mut bcol = b.column_mut(k);
for i in 0..dim - 1 { for i in 0..dim - 1 {
let coeff = unsafe { *bcol.vget_unchecked(i) } / diag; let coeff = unsafe { bcol.vget_unchecked(i).clone() } / diag.clone();
bcol.rows_range_mut(i + 1..) bcol.rows_range_mut(i + 1..)
.axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); .axpy(-coeff, &self.slice_range(i + 1.., i), T::one());
} }
@ -164,14 +164,14 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let coeff; let coeff;
unsafe { unsafe {
let diag = *self.get_unchecked((i, i)); let diag = self.get_unchecked((i, i)).clone();
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
coeff = *b.vget_unchecked(i) / diag; coeff = b.vget_unchecked(i).clone() / diag;
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(..i) b.rows_range_mut(..i)
@ -392,13 +392,13 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
unsafe { unsafe {
let b_i = b.vget_unchecked_mut(i); let b_i = b.vget_unchecked_mut(i);
let diag = conjugate(*self.get_unchecked((i, i))); let diag = conjugate(self.get_unchecked((i, i)).clone());
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
*b_i = (*b_i - dot) / diag; *b_i = (b_i.clone() - dot) / diag;
} }
} }
@ -426,13 +426,13 @@ impl<T: ComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
unsafe { unsafe {
let b_i = b.vget_unchecked_mut(i); let b_i = b.vget_unchecked_mut(i);
let diag = conjugate(*self.get_unchecked((i, i))); let diag = conjugate(self.get_unchecked((i, i)).clone());
if diag.is_zero() { if diag.is_zero() {
return false; return false;
} }
*b_i = (*b_i - dot) / diag; *b_i = (b_i.clone() - dot) / diag;
} }
} }
@ -508,13 +508,13 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let coeff; let coeff;
unsafe { unsafe {
let diag = *self.get_unchecked((i, i)); let diag = self.get_unchecked((i, i)).clone();
coeff = *b.vget_unchecked(i) / diag; coeff = b.vget_unchecked(i).clone() / diag;
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(i + 1..) b.rows_range_mut(i + 1..)
.axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); .axpy(-coeff.clone(), &self.slice_range(i + 1.., i), T::one());
} }
} }
@ -537,7 +537,7 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let mut bcol = b.column_mut(k); let mut bcol = b.column_mut(k);
for i in 0..dim - 1 { for i in 0..dim - 1 {
let coeff = unsafe { *bcol.vget_unchecked(i) } / diag; let coeff = unsafe { bcol.vget_unchecked(i).clone() } / diag.clone();
bcol.rows_range_mut(i + 1..) bcol.rows_range_mut(i + 1..)
.axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); .axpy(-coeff, &self.slice_range(i + 1.., i), T::one());
} }
@ -569,9 +569,9 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
let coeff; let coeff;
unsafe { unsafe {
let diag = *self.get_unchecked((i, i)); let diag = self.get_unchecked((i, i)).clone();
coeff = *b.vget_unchecked(i) / diag; coeff = b.vget_unchecked(i).clone() / diag;
*b.vget_unchecked_mut(i) = coeff; *b.vget_unchecked_mut(i) = coeff.clone();
} }
b.rows_range_mut(..i) b.rows_range_mut(..i)
@ -748,8 +748,8 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
unsafe { unsafe {
let b_i = b.vget_unchecked_mut(i); let b_i = b.vget_unchecked_mut(i);
let diag = conjugate(*self.get_unchecked((i, i))); let diag = conjugate(self.get_unchecked((i, i)).clone());
*b_i = (*b_i - dot) / diag; *b_i = (b_i.clone() - dot) / diag;
} }
} }
} }
@ -772,8 +772,8 @@ impl<T: SimdComplexField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
unsafe { unsafe {
let b_i = b.vget_unchecked_mut(i); let b_i = b.vget_unchecked_mut(i);
let diag = conjugate(*self.get_unchecked((i, i))); let diag = conjugate(self.get_unchecked((i, i)).clone());
*b_i = (*b_i - dot) / diag; *b_i = (b_i.clone() - dot) / diag;
} }
} }
} }

View File

@ -118,7 +118,7 @@ where
let m_amax = matrix.camax(); let m_amax = matrix.camax();
if !m_amax.is_zero() { if !m_amax.is_zero() {
matrix.unscale_mut(m_amax); matrix.unscale_mut(m_amax.clone());
} }
let bi_matrix = Bidiagonal::new(matrix); let bi_matrix = Bidiagonal::new(matrix);
@ -139,7 +139,7 @@ where
&mut v_t, &mut v_t,
bi_matrix.is_upper_diagonal(), bi_matrix.is_upper_diagonal(),
dim - 1, dim - 1,
eps, eps.clone(),
); );
while end != start { while end != start {
@ -153,19 +153,20 @@ where
let mut vec; let mut vec;
{ {
let dm = diagonal[m]; let dm = diagonal[m].clone();
let dn = diagonal[n]; let dn = diagonal[n].clone();
let fm = off_diagonal[m]; let fm = off_diagonal[m].clone();
let tmm = dm * dm + off_diagonal[m - 1] * off_diagonal[m - 1]; let tmm = dm.clone() * dm.clone()
let tmn = dm * fm; + off_diagonal[m - 1].clone() * off_diagonal[m - 1].clone();
let tnn = dn * dn + fm * fm; let tmn = dm * fm.clone();
let tnn = dn.clone() * dn + fm.clone() * fm;
let shift = symmetric_eigen::wilkinson_shift(tmm, tnn, tmn); let shift = symmetric_eigen::wilkinson_shift(tmm, tnn, tmn);
vec = Vector2::new( vec = Vector2::new(
diagonal[start] * diagonal[start] - shift, diagonal[start].clone() * diagonal[start].clone() - shift,
diagonal[start] * off_diagonal[start], diagonal[start].clone() * off_diagonal[start].clone(),
); );
} }
@ -173,15 +174,15 @@ where
let m12 = if k == n - 1 { let m12 = if k == n - 1 {
T::RealField::zero() T::RealField::zero()
} else { } else {
off_diagonal[k + 1] off_diagonal[k + 1].clone()
}; };
let mut subm = Matrix2x3::new( let mut subm = Matrix2x3::new(
diagonal[k], diagonal[k].clone(),
off_diagonal[k], off_diagonal[k].clone(),
T::RealField::zero(), T::RealField::zero(),
T::RealField::zero(), T::RealField::zero(),
diagonal[k + 1], diagonal[k + 1].clone(),
m12, m12,
); );
@ -195,10 +196,10 @@ where
off_diagonal[k - 1] = norm1; off_diagonal[k - 1] = norm1;
} }
let v = Vector2::new(subm[(0, 0)], subm[(1, 0)]); let v = Vector2::new(subm[(0, 0)].clone(), subm[(1, 0)].clone());
// TODO: does the case `v.y == 0` ever happen? // TODO: does the case `v.y == 0` ever happen?
let (rot2, norm2) = GivensRotation::cancel_y(&v) let (rot2, norm2) = GivensRotation::cancel_y(&v)
.unwrap_or((GivensRotation::identity(), subm[(0, 0)])); .unwrap_or((GivensRotation::identity(), subm[(0, 0)].clone()));
rot2.rotate(&mut subm.fixed_columns_mut::<2>(1)); rot2.rotate(&mut subm.fixed_columns_mut::<2>(1));
let rot2 = GivensRotation::new_unchecked(rot2.c(), T::from_real(rot2.s())); let rot2 = GivensRotation::new_unchecked(rot2.c(), T::from_real(rot2.s()));
@ -221,16 +222,16 @@ where
} }
} }
diagonal[k] = subm[(0, 0)]; diagonal[k] = subm[(0, 0)].clone();
diagonal[k + 1] = subm[(1, 1)]; diagonal[k + 1] = subm[(1, 1)].clone();
off_diagonal[k] = subm[(0, 1)]; off_diagonal[k] = subm[(0, 1)].clone();
if k != n - 1 { if k != n - 1 {
off_diagonal[k + 1] = subm[(1, 2)]; off_diagonal[k + 1] = subm[(1, 2)].clone();
} }
vec.x = subm[(0, 1)]; vec.x = subm[(0, 1)].clone();
vec.y = subm[(0, 2)]; vec.y = subm[(0, 2)].clone();
} else { } else {
break; break;
} }
@ -238,9 +239,9 @@ where
} else if subdim == 2 { } else if subdim == 2 {
// Solve the remaining 2x2 subproblem. // Solve the remaining 2x2 subproblem.
let (u2, s, v2) = compute_2x2_uptrig_svd( let (u2, s, v2) = compute_2x2_uptrig_svd(
diagonal[start], diagonal[start].clone(),
off_diagonal[start], off_diagonal[start].clone(),
diagonal[start + 1], diagonal[start + 1].clone(),
compute_u && bi_matrix.is_upper_diagonal() compute_u && bi_matrix.is_upper_diagonal()
|| compute_v && !bi_matrix.is_upper_diagonal(), || compute_v && !bi_matrix.is_upper_diagonal(),
compute_v && bi_matrix.is_upper_diagonal() compute_v && bi_matrix.is_upper_diagonal()
@ -249,15 +250,15 @@ where
let u2 = u2.map(|u2| GivensRotation::new_unchecked(u2.c(), T::from_real(u2.s()))); let u2 = u2.map(|u2| GivensRotation::new_unchecked(u2.c(), T::from_real(u2.s())));
let v2 = v2.map(|v2| GivensRotation::new_unchecked(v2.c(), T::from_real(v2.s()))); let v2 = v2.map(|v2| GivensRotation::new_unchecked(v2.c(), T::from_real(v2.s())));
diagonal[start] = s[0]; diagonal[start] = s[0].clone();
diagonal[start + 1] = s[1]; diagonal[start + 1] = s[1].clone();
off_diagonal[start] = T::RealField::zero(); off_diagonal[start] = T::RealField::zero();
if let Some(ref mut u) = u { if let Some(ref mut u) = u {
let rot = if bi_matrix.is_upper_diagonal() { let rot = if bi_matrix.is_upper_diagonal() {
u2.unwrap() u2.clone().unwrap()
} else { } else {
v2.unwrap() v2.clone().unwrap()
}; };
rot.rotate_rows(&mut u.fixed_columns_mut::<2>(start)); rot.rotate_rows(&mut u.fixed_columns_mut::<2>(start));
} }
@ -282,7 +283,7 @@ where
&mut v_t, &mut v_t,
bi_matrix.is_upper_diagonal(), bi_matrix.is_upper_diagonal(),
end, end,
eps, eps.clone(),
); );
start = sub.0; start = sub.0;
end = sub.1; end = sub.1;
@ -297,7 +298,7 @@ where
// Ensure all singular value are non-negative. // Ensure all singular value are non-negative.
for i in 0..dim { for i in 0..dim {
let sval = diagonal[i]; let sval = diagonal[i].clone();
if sval < T::RealField::zero() { if sval < T::RealField::zero() {
diagonal[i] = -sval; diagonal[i] = -sval;
@ -345,10 +346,11 @@ where
let m = n - 1; let m = n - 1;
if off_diagonal[m].is_zero() if off_diagonal[m].is_zero()
|| off_diagonal[m].norm1() <= eps * (diagonal[n].norm1() + diagonal[m].norm1()) || off_diagonal[m].clone().norm1()
<= eps.clone() * (diagonal[n].clone().norm1() + diagonal[m].clone().norm1())
{ {
off_diagonal[m] = T::RealField::zero(); off_diagonal[m] = T::RealField::zero();
} else if diagonal[m].norm1() <= eps { } else if diagonal[m].clone().norm1() <= eps {
diagonal[m] = T::RealField::zero(); diagonal[m] = T::RealField::zero();
Self::cancel_horizontal_off_diagonal_elt( Self::cancel_horizontal_off_diagonal_elt(
diagonal, diagonal,
@ -370,7 +372,7 @@ where
m - 1, m - 1,
); );
} }
} else if diagonal[n].norm1() <= eps { } else if diagonal[n].clone().norm1() <= eps {
diagonal[n] = T::RealField::zero(); diagonal[n] = T::RealField::zero();
Self::cancel_vertical_off_diagonal_elt( Self::cancel_vertical_off_diagonal_elt(
diagonal, diagonal,
@ -395,13 +397,14 @@ where
while new_start > 0 { while new_start > 0 {
let m = new_start - 1; let m = new_start - 1;
if off_diagonal[m].norm1() <= eps * (diagonal[new_start].norm1() + diagonal[m].norm1()) if off_diagonal[m].clone().norm1()
<= eps.clone() * (diagonal[new_start].clone().norm1() + diagonal[m].clone().norm1())
{ {
off_diagonal[m] = T::RealField::zero(); off_diagonal[m] = T::RealField::zero();
break; break;
} }
// TODO: write a test that enters this case. // TODO: write a test that enters this case.
else if diagonal[m].norm1() <= eps { else if diagonal[m].clone().norm1() <= eps {
diagonal[m] = T::RealField::zero(); diagonal[m] = T::RealField::zero();
Self::cancel_horizontal_off_diagonal_elt( Self::cancel_horizontal_off_diagonal_elt(
diagonal, diagonal,
@ -442,7 +445,7 @@ where
i: usize, i: usize,
end: usize, end: usize,
) { ) {
let mut v = Vector2::new(off_diagonal[i], diagonal[i + 1]); let mut v = Vector2::new(off_diagonal[i].clone(), diagonal[i + 1].clone());
off_diagonal[i] = T::RealField::zero(); off_diagonal[i] = T::RealField::zero();
for k in i..end { for k in i..end {
@ -460,8 +463,8 @@ where
} }
if k + 1 != end { if k + 1 != end {
v.x = -rot.s().real() * off_diagonal[k + 1]; v.x = -rot.s().real() * off_diagonal[k + 1].clone();
v.y = diagonal[k + 2]; v.y = diagonal[k + 2].clone();
off_diagonal[k + 1] *= rot.c(); off_diagonal[k + 1] *= rot.c();
} }
} else { } else {
@ -479,7 +482,7 @@ where
is_upper_diagonal: bool, is_upper_diagonal: bool,
i: usize, i: usize,
) { ) {
let mut v = Vector2::new(diagonal[i], off_diagonal[i]); let mut v = Vector2::new(diagonal[i].clone(), off_diagonal[i].clone());
off_diagonal[i] = T::RealField::zero(); off_diagonal[i] = T::RealField::zero();
for k in (0..i + 1).rev() { for k in (0..i + 1).rev() {
@ -497,8 +500,8 @@ where
} }
if k > 0 { if k > 0 {
v.x = diagonal[k - 1]; v.x = diagonal[k - 1].clone();
v.y = rot.s().real() * off_diagonal[k - 1]; v.y = rot.s().real() * off_diagonal[k - 1].clone();
off_diagonal[k - 1] *= rot.c(); off_diagonal[k - 1] *= rot.c();
} }
} else { } else {
@ -527,7 +530,7 @@ where
match (self.u, self.v_t) { match (self.u, self.v_t) {
(Some(mut u), Some(v_t)) => { (Some(mut u), Some(v_t)) => {
for i in 0..self.singular_values.len() { for i in 0..self.singular_values.len() {
let val = self.singular_values[i]; let val = self.singular_values[i].clone();
u.column_mut(i).scale_mut(val); u.column_mut(i).scale_mut(val);
} }
Ok(u * v_t) Ok(u * v_t)
@ -551,7 +554,7 @@ where
Err("SVD pseudo inverse: the epsilon must be non-negative.") Err("SVD pseudo inverse: the epsilon must be non-negative.")
} else { } else {
for i in 0..self.singular_values.len() { for i in 0..self.singular_values.len() {
let val = self.singular_values[i]; let val = self.singular_values[i].clone();
if val > eps { if val > eps {
self.singular_values[i] = T::RealField::one() / val; self.singular_values[i] = T::RealField::one() / val;
@ -590,9 +593,9 @@ where
let mut col = ut_b.column_mut(j); let mut col = ut_b.column_mut(j);
for i in 0..self.singular_values.len() { for i in 0..self.singular_values.len() {
let val = self.singular_values[i]; let val = self.singular_values[i].clone();
if val > eps { if val > eps {
col[i] = col[i].unscale(val); col[i] = col[i].clone().unscale(val);
} else { } else {
col[i] = T::zero(); col[i] = T::zero();
} }
@ -665,33 +668,37 @@ fn compute_2x2_uptrig_svd<T: RealField>(
let two: T::RealField = crate::convert(2.0f64); let two: T::RealField = crate::convert(2.0f64);
let half: T::RealField = crate::convert(0.5f64); let half: T::RealField = crate::convert(0.5f64);
let denom = (m11 + m22).hypot(m12) + (m11 - m22).hypot(m12); let denom = (m11.clone() + m22.clone()).hypot(m12.clone())
+ (m11.clone() - m22.clone()).hypot(m12.clone());
// NOTE: v1 is the singular value that is the closest to m22. // NOTE: v1 is the singular value that is the closest to m22.
// This prevents cancellation issues when constructing the vector `csv` below. If we chose // This prevents cancellation issues when constructing the vector `csv` below. If we chose
// otherwise, we would have v1 ~= m11 when m12 is small. This would cause catastrophic // otherwise, we would have v1 ~= m11 when m12 is small. This would cause catastrophic
// cancellation on `v1 * v1 - m11 * m11` below. // cancellation on `v1 * v1 - m11 * m11` below.
let mut v1 = m11 * m22 * two / denom; let mut v1 = m11.clone() * m22.clone() * two / denom.clone();
let mut v2 = half * denom; let mut v2 = half * denom;
let mut u = None; let mut u = None;
let mut v_t = None; let mut v_t = None;
if compute_u || compute_v { if compute_u || compute_v {
let (csv, sgn_v) = GivensRotation::new(m11 * m12, v1 * v1 - m11 * m11); let (csv, sgn_v) = GivensRotation::new(
v1 *= sgn_v; m11.clone() * m12.clone(),
v1.clone() * v1.clone() - m11.clone() * m11.clone(),
);
v1 *= sgn_v.clone();
v2 *= sgn_v; v2 *= sgn_v;
if compute_v { if compute_v {
v_t = Some(csv); v_t = Some(csv.clone());
} }
if compute_u { if compute_u {
let cu = (m11.scale(csv.c()) + m12 * csv.s()) / v1; let cu = (m11.scale(csv.c()) + m12 * csv.s()) / v1.clone();
let su = (m22 * csv.s()) / v1; let su = (m22 * csv.s()) / v1.clone();
let (csu, sgn_u) = GivensRotation::new(cu, su); let (csu, sgn_u) = GivensRotation::new(cu, su);
v1 *= sgn_u; v1 *= sgn_u.clone();
v2 *= sgn_u; v2 *= sgn_u;
u = Some(csu); u = Some(csu);
} }

View File

@ -104,7 +104,7 @@ where
let m_amax = matrix.camax(); let m_amax = matrix.camax();
if !m_amax.is_zero() { if !m_amax.is_zero() {
matrix.unscale_mut(m_amax); matrix.unscale_mut(m_amax.clone());
} }
let (mut q_mat, mut diag, mut off_diag); let (mut q_mat, mut diag, mut off_diag);
@ -127,7 +127,8 @@ where
} }
let mut niter = 0; let mut niter = 0;
let (mut start, mut end) = Self::delimit_subproblem(&diag, &mut off_diag, dim - 1, eps); let (mut start, mut end) =
Self::delimit_subproblem(&diag, &mut off_diag, dim - 1, eps.clone());
while end != start { while end != start {
let subdim = end - start + 1; let subdim = end - start + 1;
@ -138,8 +139,13 @@ where
let n = end; let n = end;
let mut vec = Vector2::new( let mut vec = Vector2::new(
diag[start] - wilkinson_shift(diag[m], diag[n], off_diag[m]), diag[start].clone()
off_diag[start], - wilkinson_shift(
diag[m].clone().clone(),
diag[n].clone(),
off_diag[m].clone().clone(),
),
off_diag[start].clone(),
); );
for i in start..n { for i in start..n {
@ -151,23 +157,23 @@ where
off_diag[i - 1] = norm; off_diag[i - 1] = norm;
} }
let mii = diag[i]; let mii = diag[i].clone();
let mjj = diag[j]; let mjj = diag[j].clone();
let mij = off_diag[i]; let mij = off_diag[i].clone();
let cc = rot.c() * rot.c(); let cc = rot.c() * rot.c();
let ss = rot.s() * rot.s(); let ss = rot.s() * rot.s();
let cs = rot.c() * rot.s(); let cs = rot.c() * rot.s();
let b = cs * crate::convert(2.0) * mij; let b = cs.clone() * crate::convert(2.0) * mij.clone();
diag[i] = (cc * mii + ss * mjj) - b; diag[i] = (cc.clone() * mii.clone() + ss.clone() * mjj.clone()) - b.clone();
diag[j] = (ss * mii + cc * mjj) + b; diag[j] = (ss.clone() * mii.clone() + cc.clone() * mjj.clone()) + b;
off_diag[i] = cs * (mii - mjj) + mij * (cc - ss); off_diag[i] = cs * (mii - mjj) + mij * (cc - ss);
if i != n - 1 { if i != n - 1 {
vec.x = off_diag[i]; vec.x = off_diag[i].clone();
vec.y = -rot.s() * off_diag[i + 1]; vec.y = -rot.s() * off_diag[i + 1].clone();
off_diag[i + 1] *= rot.c(); off_diag[i + 1] *= rot.c();
} }
@ -180,24 +186,31 @@ where
} }
} }
if off_diag[m].norm1() <= eps * (diag[m].norm1() + diag[n].norm1()) { if off_diag[m].clone().norm1()
<= eps.clone() * (diag[m].clone().norm1() + diag[n].clone().norm1())
{
end -= 1; end -= 1;
} }
} else if subdim == 2 { } else if subdim == 2 {
let m = Matrix2::new( let m = Matrix2::new(
diag[start], diag[start].clone(),
off_diag[start].conjugate(), off_diag[start].clone().conjugate(),
off_diag[start], off_diag[start].clone(),
diag[start + 1], diag[start + 1].clone(),
); );
let eigvals = m.eigenvalues().unwrap(); let eigvals = m.eigenvalues().unwrap();
let basis = Vector2::new(eigvals.x - diag[start + 1], off_diag[start]); let basis = Vector2::new(
eigvals.x.clone() - diag[start + 1].clone(),
off_diag[start].clone(),
);
diag[start] = eigvals[0]; diag[start] = eigvals[0].clone();
diag[start + 1] = eigvals[1]; diag[start + 1] = eigvals[1].clone();
if let Some(ref mut q) = q_mat { if let Some(ref mut q) = q_mat {
if let Some((rot, _)) = GivensRotation::try_new(basis.x, basis.y, eps) { if let Some((rot, _)) =
GivensRotation::try_new(basis.x.clone(), basis.y.clone(), eps.clone())
{
let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s())); let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s()));
rot.rotate_rows(&mut q.fixed_columns_mut::<2>(start)); rot.rotate_rows(&mut q.fixed_columns_mut::<2>(start));
} }
@ -207,7 +220,7 @@ where
} }
// Re-delimit the subproblem in case some decoupling occurred. // Re-delimit the subproblem in case some decoupling occurred.
let sub = Self::delimit_subproblem(&diag, &mut off_diag, end, eps); let sub = Self::delimit_subproblem(&diag, &mut off_diag, end, eps.clone());
start = sub.0; start = sub.0;
end = sub.1; end = sub.1;
@ -238,7 +251,9 @@ where
while n > 0 { while n > 0 {
let m = n - 1; let m = n - 1;
if off_diag[m].norm1() > eps * (diag[n].norm1() + diag[m].norm1()) { if off_diag[m].clone().norm1()
> eps.clone() * (diag[n].clone().norm1() + diag[m].clone().norm1())
{
break; break;
} }
@ -253,8 +268,9 @@ where
while new_start > 0 { while new_start > 0 {
let m = new_start - 1; let m = new_start - 1;
if off_diag[m].is_zero() if off_diag[m].clone().is_zero()
|| off_diag[m].norm1() <= eps * (diag[new_start].norm1() + diag[m].norm1()) || off_diag[m].clone().norm1()
<= eps.clone() * (diag[new_start].clone().norm1() + diag[m].clone().norm1())
{ {
off_diag[m] = T::RealField::zero(); off_diag[m] = T::RealField::zero();
break; break;
@ -273,7 +289,7 @@ where
pub fn recompose(&self) -> OMatrix<T, D, D> { pub fn recompose(&self) -> OMatrix<T, D, D> {
let mut u_t = self.eigenvectors.clone(); let mut u_t = self.eigenvectors.clone();
for i in 0..self.eigenvalues.len() { for i in 0..self.eigenvalues.len() {
let val = self.eigenvalues[i]; let val = self.eigenvalues[i].clone();
u_t.column_mut(i).scale_mut(val); u_t.column_mut(i).scale_mut(val);
} }
u_t.adjoint_mut(); u_t.adjoint_mut();
@ -288,11 +304,11 @@ where
/// tmm tmn /// tmm tmn
/// tmn tnn /// tmn tnn
pub fn wilkinson_shift<T: ComplexField>(tmm: T, tnn: T, tmn: T) -> T { pub fn wilkinson_shift<T: ComplexField>(tmm: T, tnn: T, tmn: T) -> T {
let sq_tmn = tmn * tmn; let sq_tmn = tmn.clone() * tmn;
if !sq_tmn.is_zero() { if !sq_tmn.is_zero() {
// We have the guarantee that the denominator won't be zero. // We have the guarantee that the denominator won't be zero.
let d = (tmm - tnn) * crate::convert(0.5); let d = (tmm - tnn.clone()) * crate::convert(0.5);
tnn - sq_tmn / (d + d.signum() * (d * d + sq_tmn).sqrt()) tnn - sq_tmn.clone() / (d.clone() + d.clone().signum() * (d.clone() * d + sq_tmn).sqrt())
} else { } else {
tnn tnn
} }

View File

@ -160,8 +160,8 @@ where
self.tri.fill_upper_triangle(T::zero(), 2); self.tri.fill_upper_triangle(T::zero(), 2);
for i in 0..self.off_diagonal.len() { for i in 0..self.off_diagonal.len() {
let val = T::from_real(self.off_diagonal[i].modulus()); let val = T::from_real(self.off_diagonal[i].clone().modulus());
self.tri[(i + 1, i)] = val; self.tri[(i + 1, i)] = val.clone();
self.tri[(i, i + 1)] = val; self.tri[(i, i + 1)] = val;
} }

View File

@ -54,34 +54,34 @@ where
let mut d = OVector::zeros_generic(n_dim, Const::<1>); let mut d = OVector::zeros_generic(n_dim, Const::<1>);
let mut u = OMatrix::zeros_generic(n_dim, n_dim); let mut u = OMatrix::zeros_generic(n_dim, n_dim);
d[n - 1] = p[(n - 1, n - 1)]; d[n - 1] = p[(n - 1, n - 1)].clone();
if d[n - 1].is_zero() { if d[n - 1].is_zero() {
return None; return None;
} }
u.column_mut(n - 1) u.column_mut(n - 1)
.axpy(T::one() / d[n - 1], &p.column(n - 1), T::zero()); .axpy(T::one() / d[n - 1].clone(), &p.column(n - 1), T::zero());
for j in (0..n - 1).rev() { for j in (0..n - 1).rev() {
let mut d_j = d[j]; let mut d_j = d[j].clone();
for k in j + 1..n { for k in j + 1..n {
d_j += d[k] * u[(j, k)].powi(2); d_j += d[k].clone() * u[(j, k)].clone().powi(2);
} }
d[j] = p[(j, j)] - d_j; d[j] = p[(j, j)].clone() - d_j;
if d[j].is_zero() { if d[j].is_zero() {
return None; return None;
} }
for i in (0..=j).rev() { for i in (0..=j).rev() {
let mut u_ij = u[(i, j)]; let mut u_ij = u[(i, j)].clone();
for k in j + 1..n { for k in j + 1..n {
u_ij += d[k] * u[(j, k)] * u[(i, k)]; u_ij += d[k].clone() * u[(j, k)].clone() * u[(i, k)].clone();
} }
u[(i, j)] = (p[(i, j)] - u_ij) / d[j]; u[(i, j)] = (p[(i, j)].clone() - u_ij) / d[j].clone();
} }
u[(j, j)] = T::one(); u[(j, j)] = T::one();

View File

@ -493,7 +493,7 @@ where
// Permute the values too. // Permute the values too.
for (i, irow) in range.clone().zip(self.data.i[range].iter().cloned()) { for (i, irow) in range.clone().zip(self.data.i[range].iter().cloned()) {
self.data.vals[i] = workspace[irow].inlined_clone(); self.data.vals[i] = workspace[irow].clone();
} }
} }
} }
@ -517,11 +517,11 @@ where
let curr_irow = self.data.i[idx]; let curr_irow = self.data.i[idx];
if curr_irow == irow { if curr_irow == irow {
value += self.data.vals[idx].inlined_clone(); value += self.data.vals[idx].clone();
} else { } else {
self.data.i[curr_i] = irow; self.data.i[curr_i] = irow;
self.data.vals[curr_i] = value; self.data.vals[curr_i] = value;
value = self.data.vals[idx].inlined_clone(); value = self.data.vals[idx].clone();
irow = curr_irow; irow = curr_irow;
curr_i += 1; curr_i += 1;
} }

View File

@ -107,28 +107,29 @@ where
let irow = *self.original_i.get_unchecked(p); let irow = *self.original_i.get_unchecked(p);
if irow >= k { if irow >= k {
*self.work_x.vget_unchecked_mut(irow) = *values.get_unchecked(p); *self.work_x.vget_unchecked_mut(irow) = values.get_unchecked(p).clone();
} }
} }
for j in self.u.data.column_row_indices(k) { for j in self.u.data.column_row_indices(k) {
let factor = -*self let factor = -self
.l .l
.data .data
.vals .vals
.get_unchecked(*self.work_c.vget_unchecked(j)); .get_unchecked(*self.work_c.vget_unchecked(j))
.clone();
*self.work_c.vget_unchecked_mut(j) += 1; *self.work_c.vget_unchecked_mut(j) += 1;
if j < k { if j < k {
for (z, val) in self.l.data.column_entries(j) { for (z, val) in self.l.data.column_entries(j) {
if z >= k { if z >= k {
*self.work_x.vget_unchecked_mut(z) += val * factor; *self.work_x.vget_unchecked_mut(z) += val * factor.clone();
} }
} }
} }
} }
let diag = *self.work_x.vget_unchecked(k); let diag = self.work_x.vget_unchecked(k).clone();
if diag > T::zero() { if diag > T::zero() {
let denom = diag.sqrt(); let denom = diag.sqrt();
@ -136,10 +137,10 @@ where
.l .l
.data .data
.vals .vals
.get_unchecked_mut(*self.l.data.p.vget_unchecked(k)) = denom; .get_unchecked_mut(*self.l.data.p.vget_unchecked(k)) = denom.clone();
for (p, val) in self.l.data.column_entries_mut(k) { for (p, val) in self.l.data.column_entries_mut(k) {
*val = *self.work_x.vget_unchecked(p) / denom; *val = self.work_x.vget_unchecked(p).clone() / denom.clone();
*self.work_x.vget_unchecked_mut(p) = T::zero(); *self.work_x.vget_unchecked_mut(p) = T::zero();
} }
} else { } else {
@ -176,11 +177,11 @@ where
let irow = *self.original_i.get_unchecked(p); let irow = *self.original_i.get_unchecked(p);
if irow <= k { if irow <= k {
*self.work_x.vget_unchecked_mut(irow) = *values.get_unchecked(p); *self.work_x.vget_unchecked_mut(irow) = values.get_unchecked(p).clone();
} }
} }
let mut diag = *self.work_x.vget_unchecked(k); let mut diag = self.work_x.vget_unchecked(k).clone();
*self.work_x.vget_unchecked_mut(k) = T::zero(); *self.work_x.vget_unchecked_mut(k) = T::zero();
// Triangular solve. // Triangular solve.
@ -189,12 +190,13 @@ where
continue; continue;
} }
let lki = *self.work_x.vget_unchecked(irow) let lki = self.work_x.vget_unchecked(irow).clone()
/ *self / self
.l .l
.data .data
.vals .vals
.get_unchecked(*self.l.data.p.vget_unchecked(irow)); .get_unchecked(*self.l.data.p.vget_unchecked(irow))
.clone();
*self.work_x.vget_unchecked_mut(irow) = T::zero(); *self.work_x.vget_unchecked_mut(irow) = T::zero();
for p in for p in
@ -203,10 +205,10 @@ where
*self *self
.work_x .work_x
.vget_unchecked_mut(*self.l.data.i.get_unchecked(p)) -= .vget_unchecked_mut(*self.l.data.i.get_unchecked(p)) -=
*self.l.data.vals.get_unchecked(p) * lki; self.l.data.vals.get_unchecked(p).clone() * lki.clone();
} }
diag -= lki * lki; diag -= lki.clone() * lki.clone();
let p = *self.work_c.vget_unchecked(irow); let p = *self.work_c.vget_unchecked(irow);
*self.work_c.vget_unchecked_mut(irow) += 1; *self.work_c.vget_unchecked_mut(irow) += 1;
*self.l.data.i.get_unchecked_mut(p) = k; *self.l.data.i.get_unchecked_mut(p) = k;

View File

@ -102,7 +102,7 @@ where
for i in 0..nrows.value() { for i in 0..nrows.value() {
if !column[i].is_zero() { if !column[i].is_zero() {
res.data.i[nz] = i; res.data.i[nz] = i;
res.data.vals[nz] = column[i].inlined_clone(); res.data.vals[nz] = column[i].clone();
nz += 1; nz += 1;
} }
} }

View File

@ -28,9 +28,9 @@ impl<T: Scalar, R: Dim, C: Dim, S: CsStorage<T, R, C>> CsMatrix<T, R, C, S> {
timestamps[i] = timestamp; timestamps[i] = timestamp;
res.data.i[nz] = i; res.data.i[nz] = i;
nz += 1; nz += 1;
workspace[i] = val * beta.inlined_clone(); workspace[i] = val * beta.clone();
} else { } else {
workspace[i] += val * beta.inlined_clone(); workspace[i] += val * beta.clone();
} }
} }
@ -88,18 +88,18 @@ impl<T: Scalar + Zero + ClosedAdd + ClosedMul, D: Dim, S: StorageMut<T, D>> Vect
unsafe { unsafe {
let k = x.data.row_index_unchecked(i); let k = x.data.row_index_unchecked(i);
let y = self.vget_unchecked_mut(k); let y = self.vget_unchecked_mut(k);
*y = alpha.inlined_clone() * x.data.get_value_unchecked(i).inlined_clone(); *y = alpha.clone() * x.data.get_value_unchecked(i).clone();
} }
} }
} else { } else {
// Needed to be sure even components not present on `x` are multiplied. // Needed to be sure even components not present on `x` are multiplied.
*self *= beta.inlined_clone(); *self *= beta.clone();
for i in 0..x.len() { for i in 0..x.len() {
unsafe { unsafe {
let k = x.data.row_index_unchecked(i); let k = x.data.row_index_unchecked(i);
let y = self.vget_unchecked_mut(k); let y = self.vget_unchecked_mut(k);
*y += alpha.inlined_clone() * x.data.get_value_unchecked(i).inlined_clone(); *y += alpha.clone() * x.data.get_value_unchecked(i).clone();
} }
} }
} }
@ -159,14 +159,14 @@ where
for (i, beta) in rhs.data.column_entries(j) { for (i, beta) in rhs.data.column_entries(j) {
for (k, val) in self.data.column_entries(i) { for (k, val) in self.data.column_entries(i) {
workspace[k] += val.inlined_clone() * beta.inlined_clone(); workspace[k] += val.clone() * beta.clone();
} }
} }
for (i, val) in workspace.as_mut_slice().iter_mut().enumerate() { for (i, val) in workspace.as_mut_slice().iter_mut().enumerate() {
if !val.is_zero() { if !val.is_zero() {
res.data.i[nz] = i; res.data.i[nz] = i;
res.data.vals[nz] = val.inlined_clone(); res.data.vals[nz] = val.clone();
*val = T::zero(); *val = T::zero();
nz += 1; nz += 1;
} }
@ -273,7 +273,7 @@ where
res.data.i[range.clone()].sort_unstable(); res.data.i[range.clone()].sort_unstable();
for p in range { for p in range {
res.data.vals[p] = workspace[res.data.i[p]].inlined_clone() res.data.vals[p] = workspace[res.data.i[p]].clone()
} }
} }
@ -296,7 +296,7 @@ where
fn mul(mut self, rhs: T) -> Self::Output { fn mul(mut self, rhs: T) -> Self::Output {
for e in self.values_mut() { for e in self.values_mut() {
*e *= rhs.inlined_clone() *e *= rhs.clone()
} }
self self

View File

@ -80,7 +80,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
} }
for (i, val) in column { for (i, val) in column {
let bj = b[j]; let bj = b[j].clone();
b[i] -= bj * val; b[i] -= bj * val;
} }
} }
@ -122,7 +122,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
if let Some(diag) = diag { if let Some(diag) = diag {
for (i, val) in column { for (i, val) in column {
let bi = b[i]; let bi = b[i].clone();
b[j] -= val * bi; b[j] -= val * bi;
} }
@ -183,7 +183,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
} }
for (i, val) in column { for (i, val) in column {
let wj = workspace[j]; let wj = workspace[j].clone();
workspace[i] -= wj * val; workspace[i] -= wj * val;
} }
} }
@ -193,7 +193,7 @@ impl<T: RealField, D: Dim, S: CsStorage<T, D, D>> CsMatrix<T, D, D, S> {
CsVector::new_uninitialized_generic(b.data.shape().0, Const::<1>, reach.len()); CsVector::new_uninitialized_generic(b.data.shape().0, Const::<1>, reach.len());
for (i, val) in reach.iter().zip(result.data.vals.iter_mut()) { for (i, val) in reach.iter().zip(result.data.vals.iter_mut()) {
*val = workspace[*i]; *val = workspace[*i].clone();
} }
result.data.i = reach; result.data.i = reach;

View File

@ -10,11 +10,11 @@ impl<T: Scalar> Into<mint::Quaternion<T>> for Quaternion<T> {
fn into(self) -> mint::Quaternion<T> { fn into(self) -> mint::Quaternion<T> {
mint::Quaternion { mint::Quaternion {
v: mint::Vector3 { v: mint::Vector3 {
x: self[0].inlined_clone(), x: self[0].clone(),
y: self[1].inlined_clone(), y: self[1].clone(),
z: self[2].inlined_clone(), z: self[2].clone(),
}, },
s: self[3].inlined_clone(), s: self[3].clone(),
} }
} }
} }
@ -23,11 +23,11 @@ impl<T: Scalar + SimdValue> Into<mint::Quaternion<T>> for UnitQuaternion<T> {
fn into(self) -> mint::Quaternion<T> { fn into(self) -> mint::Quaternion<T> {
mint::Quaternion { mint::Quaternion {
v: mint::Vector3 { v: mint::Vector3 {
x: self[0].inlined_clone(), x: self[0].clone(),
y: self[1].inlined_clone(), y: self[1].clone(),
z: self[2].inlined_clone(), z: self[2].clone(),
}, },
s: self[3].inlined_clone(), s: self[3].clone(),
} }
} }
} }