I'm implementing a mathematical vector in Rust with a generic type K that should be used for f32 and Complex<f32>.
However, for some reason, the implementation seems to support only f32 type.
This is the code from the vector.rs file:
pub use core::fmt;
pub use core::ops::Neg;
pub use num::complex::Complex;
pub use num::Num;
pub use num::Zero;
impl<K> Vector<K>
where Vector<K>: std::fmt::Display, Matrix<K>: std::fmt::Display,
K: Copy + Clone + num::Num + num::Float + std::ops::AddAssign
+ std::ops::SubAssign + std::ops::MulAssign + std::fmt::Display
+ std::ops::Neg<Output = K> {
pub fn new() -> Self {
Vector {
values: Vec::new(),
rows: 0
}
}
pub fn from(arr: &[K]) -> Self {
Vector {
values: arr.to_vec(),
rows: arr.len()
}
}
pub fn from_vec(vec: Vec<K>) -> Self {
Vector {
values: vec.clone(),
rows: vec.len()
}
}
pub fn print(&self) {
println!("{}", self);
}
pub fn add(&mut self, other: Vector<K>) {
self.vectors_have_equal_length(other.clone());
for (a, b) in self.values.iter_mut().zip(other.values.iter()) {
*a += b.clone();
}
}
pub fn sub(&mut self, other: Vector<K>) {
self.vectors_have_equal_length(other.clone());
for (a, b) in self.values.iter_mut().zip(other.values.iter()) {
*a -= b.clone();
}
}
pub fn scl(&mut self, scalar: K) {
for el in self.values.iter_mut() {
*el *= scalar.clone();
}
}
}
The main.rs file:
fn main() {
let _ = panic::catch_unwind(|| {
let complex_numbers = [
Complex::new(1.0, 1.0),
Complex::new(1.0, -1.0)
];
let mut vec: Vec<Complex<f32>> = complex_numbers.to_vec();
let mut t = Vector::from_vec(vec);
println!("{}", t.norm());
});
}
The error message states that the compiler expects a vec based on the Vector::from_vec()
function I previously showed:
error[E0308]: mismatched types
--> src/main.rs:68:28
|
68 | let t = Vector::from_vec(vec);
| ---------------- ^^^ expected `Vec<f32>`, found `Vec<Complex<f32>>`
| |
| arguments to this function are incorrect
|
= note: expected struct `Vec<f32>`
found struct `Vec<Complex<f32>>`
note: associated function defined here
--> src/linear_algebra/vector.rs:79:9
|
79 | pub fn from_vec(vec: Vec<K>) -> Self {
| ^^^^^^^^ -----------
linear_algebra.rs:
pub use core::fmt;
pub use core::ops::Neg;
pub use num::complex::Complex;
pub use num::Num;
pub use num::Zero;
#[derive(Debug, PartialEq, Clone)]
pub struct Vector<K> {
values: Vec<K>,
rows: usize
}
impl<K> Vector<K>
where Vector<K>: std::fmt::Display,
K: Copy + Clone + num::Num + std::ops::AddAssign
+ std::ops::SubAssign + std::ops::MulAssign + std::fmt::Display
+ std::ops::Neg<Output = K> {
pub fn new() -> Self {
Vector {
values: Vec::new(),
rows: 0
}
}
pub fn from(arr: &[K]) -> Self {
Vector {
values: arr.to_vec(),
rows: arr.len()
}
}
pub fn from_vec(vec: Vec<K>) -> Self {
Vector {
values: vec.clone(),
rows: vec.len()
}
}
pub fn print(&self) {
println!("{}", self);
}
}
impl std::ops::Mul<Vector<f32>> for f32 {
type Output = Vector<f32>;
fn mul(self, _rhs: Vector<f32>) -> Vector<f32> {
let mut a: Vector<f32> = Vector::new();
for el in _rhs.values.iter() {
a.values.push(*el * self);
a.rows += 1;
}
a
}
}
impl fmt::Display for Vector<f32> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
for n in self.values.iter() {
write!(fmt, "[")?;
write!(fmt, "{}", (n * 100.).round() / 100.)?;
write!(fmt, "]")?;
write!(fmt, "\n")?;
}
println!("The vector has {} rows.", self.rows);
Ok(())
}
}
impl fmt::Display for Vector<Complex<f32>> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
for n in self.values.iter() {
write!(fmt, "[")?;
write!(fmt, "{}", n)?;
write!(fmt, "]")?;
write!(fmt, "\n")?;
}
println!("The vector has {} rows.", self.rows);
Ok(())
}
}
impl std::ops::Mul<Vector<Complex<f32>>> for Complex<f32> {
type Output = Vector<Complex<f32>>;
fn mul(self, _rhs: Vector<Complex<f32>>) -> Vector<Complex<f32>> {
let mut a: Vector<Complex<f32>> = Vector::new();
for el in _rhs.values.iter() {
a.values.push(*el * self);
a.rows += 1;
}
a
}
}
impl Vector<Complex<f32>> {
pub fn norm(&self) -> Complex<f32> {
let mut sum = Complex::<f32>::zero();
for el in self.values.iter() {
sum += el.powf(2.);
}
return sum.powf(0.5);
}
}
and main.rs:
use std::panic;
use crate::linear_algebra::Vector;
use crate::linear_algebra::Complex;
pub mod linear_algebra;
fn main() {
println!("\n\x1b[31;1;4mThe Norm\x1b[0m\n");
let _ = panic::catch_unwind(|| {
let complex_numbers = [
Complex::new(1.0, 1.0),
Complex::new(1.0, -1.0)
];
let vec: Vec<Complex<f32>> = complex_numbers.to_vec();
let mut t = Vector::from_vec(vec);
t.print();
});
}
The problem was the presence of num::float in linear_algebra.rs, since Complex does not implement the num::float trait.
However, the error message appeared after I cut out half of the code.
Edit: I have a file matrix.rs calling functions of the linear_algebra.rs file.
And in matrix.rs I didn't add the line:
use super::Complex;