Я реализую общий матричный решатель. При этом я использую оператор Not, чтобы обойти другую проблему, которую я объясню ниже. Однако, вызывая функцию в моих тестах, я получаю следующую ошибку:
error[E0271]: type mismatch resolving `<i32 as std::ops::Not>::Output == bool`
--> src/matrix.rs:223:15
|
90 | pub fn reduce<T>(mat: &mut Matrix<T>) -> Result<Matrix<T>, &'static str>
| ------
...
97 | + Not<Output = bool>
| ------------- required by this bound in `matrix::reduce`
...
223 | let res = reduce(&mut mat).unwrap();
| ^^^^^^ expected i32, found bool
error: aborting due to previous error
Это особенно сбивает с толку, потому что я не уверен, как иначе я бы реализовал черту Not
и правильно ее работал. Когда тип вывода bool, он прекрасно компилируется, но кажется, что он лает во время выполнения.
Вот мой код:
/// Performs a reduction operation on a given matrix, giving the reduced row echelon form
pub fn reduce<T>(mat: &mut Matrix<T>) -> Result<Matrix<T>, &'static str>
where
T: num_traits::Zero
+ num_traits::One
+ Mul<T, Output = T>
+ Add<T, Output = T>
+ Sub<T, Output = T>
+ Not<Output = bool>
+ Neg<Output = T>
+ Div<T, Output = T>
+ Copy,
{
let exchange = |matrix: &mut Matrix<T>, i: usize, j: usize| {
matrix.data.swap(i, j);
};
let scale = |matrix: &mut Matrix<T>, row: usize, factor: T| {
for i in 0..matrix.data[row].len() {
matrix.data[row][i] = matrix.data[row][i] * factor;
}
};
let row_replace = |matrix: &mut Matrix<T>, i: usize, j: usize, factor: T| {
for k in 0..matrix.data[j].len() {
matrix.data[j][k] = matrix.data[j][k] + (matrix.data[i][k] * factor);
}
};
// Reduction steps
let n = mat.data.len();
for i in 0..n {
// Find a pivot point
for j in i..n {
if !mat.data[j][i] { // <------- Error Here *********
if i != j {
exchange(mat, i, j);
break;
}
}
if j == n - 1 {
return Err("No pivot found")
}
}
// Put zeros below diagonal
for j in i + 1..n {
row_replace(mat, i, j, -mat.data[j][i] / mat.data[i][i]);
}
}
// Back substitution (bottom up)
for i in (0..n - 1).rev() {
for j in 0..i {
row_replace(mat, i, j, -mat.data[j][i] / mat.data[i][i]);
}
}
// Add 1's to the diagonal
for i in 0..n {
scale(mat, i, T::one() / mat.data[i][i]);
}
Ok(mat.clone())
}
#[test]
fn it_row_reduces() {
let mat = Matrix {
data: vec![vec![2, 1, 4], vec![1, 2, 5]],
nrows: 2,
ncols: 3,
};
let comp = Matrix {
data: vec![vec![1, 0, 1], vec![0, 1, 2]],
nrows: 2,
ncols: 3,
};
let res = reduce(&mut mat).unwrap();
assert_eq!(res.data, comp.data);
}
Первоначально код выглядел следующим образом:
if mat.data[j][i] != T::zero() {
if i != j {
exchange(mat, i, j);
break;
}
}
Но, похоже, что даже с чертой Not, добавленной к сигнатуре функции, эта операция никогда не будет работать, выдавая следующую ошибку:
binary operation `!=` cannot be applied to type `T`: T
Я пытаюсь выяснить, где я 'Я ошибаюсь с этим кодом, и если мое использование обобщений для этого сравнения - самый идиоматичный способ сделать это в ржавчине. Любые дополнительные отзывы приветствуются. Я также могу предоставить структуру, я просто хотел, чтобы вопрос был как можно более кратким.