Matrix Rust traits:边界可能没有实现,traits I';您所实现的功能不存在
所以我一直在尝试实现一个向量和矩阵数学库,我创建了一些函数,这些函数可以正常工作,但希望对所有数字原语进行推广,并将这些函数添加到普通运算符中 我的想法是为Matrix Rust traits:边界可能没有实现,traits I';您所实现的功能不存在,matrix,vector,rust,traits,bounds,Matrix,Vector,Rust,Traits,Bounds,所以我一直在尝试实现一个向量和矩阵数学库,我创建了一些函数,这些函数可以正常工作,但希望对所有数字原语进行推广,并将这些函数添加到普通运算符中 我的想法是为Vec创建一个容器,它可以包含数字类型(如i32)或另一个Vec容器,以便在可能的情况下使用矩阵。因此: #[derive(Clone, Debug)] struct Mat<T>(Vec<T>); 但是矩阵让我头疼。对于他们来说,add函数看起来非常相似,除了let Some(x)语句: impl<'a, T
Vec
创建一个容器,它可以包含数字类型(如i32
)或另一个Vec
容器,以便在可能的情况下使用矩阵。因此:
#[derive(Clone, Debug)]
struct Mat<T>(Vec<T>);
但是矩阵让我头疼。对于他们来说,add函数看起来非常相似,除了let Some(x)
语句:
impl<'a, T> Add for &'a Mat<Mat<T>>
where T: Add<&'a Mat<T>>{
type Output = Option<Mat<T>>;
fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
let a: &Vec<Mat<T>> = self.pop();
let b: &Vec<Mat<T>> = other.pop();
match a.len() == b.len() {
true => {
let mut retvec: Vec<T> = Vec::new();
for i in 0..a.len() {
if let Some(x) = &a[i] + &b[i] {
retvec.push(x);
}
}
Some(Mat(retvec))
},
false => None
}
}
}
impl有两个问题:错误关联的Output
类型和retvec
类似的方法应该会奏效:
impl<'a, T> Add for &'a Mat<Mat<T>>
where
T: PartialEq + PartialOrd + Add<T> + Clone,
{
type Output = Option<Mat<Mat<<T as std::ops::Add>::Output>>>;
fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
let a: &Vec<Mat<T>> = self.pop();
let b: &Vec<Mat<T>> = other.pop();
match a.len() == b.len() {
true => {
let mut retvec: Vec<Mat<<T as std::ops::Add>::Output>> = Vec::new();
for i in 0..a.len() {
if let Some(x) = &a[i] + &b[i] {
retvec.push(x);
}
}
Some(Mat(retvec))
}
false => None,
}
}
}
对于Mat
值的附加impl:
impl<T> Add for Mat<T>
where
T: PartialEq + PartialOrd + Add<T> + Clone
PS:YourMat
类型不是经典意义上的矩阵,也许另一个名称更合适,以避免混淆。可能重复的Hmm,我想我误读了。您的意思是要将T
添加到实现内部的Mat
中吗?这就是T:for
的含义。我怀疑你真的想要,因为我不确定我是否得到了你想要的,如果你的意思是我忘了为T
和Mat
实现一个Add函数,那么我想我不需要,因为forloop在两个函数中都通过两个向量循环,它只需要添加T+T
或Mat+Mat
,对吗?否则,如果您的意思是如果我尝试执行T+Mat
,那么不,我发布的测试是到目前为止唯一的测试。您的where
子句适用于T+&Mat
,但您在函数内部实际执行的是&Mat+&Mat
(我认为)。但这并不是全部,因为修复绑定会导致其他问题。我认为,您需要的不是&a[I]+&b[I]
,而是a[I].clone()+b[I].clone()
编辑:不,愚蠢的我。忘记推导PartialEq和PartialOrd。正如我所说,非常感谢!顺便说一句,这怎么不好?我把它们描述成向量的向量。谢谢,伙计,解释得好!是的,我同意Mat
在概念上很弱,但我只是在与编译器抗争。即使现在我已经复制了你的代码,如果我把Mat
测试留在里面,它也不会编译。仍然是同样的错误:“对于Mat
,可能缺少std::ops::Add
的实现”,而你说它对你有效,这让我怀疑存在的逻辑和原因。通常,矩阵被定义为多维数组,每个维度的基数相同。使用Mat
类型,您可以有不同大小的行。对,但它实际上无法计算那些格式错误的矩阵。您建议如何解决这个问题,一个宏或者一个使其符合正确向量维度的Mat::new()
成员函数?
impl<'a, T> Add for &'a Mat<Mat<T>>
where
T: PartialEq + PartialOrd + Add<T> + Clone,
{
type Output = Option<Mat<Mat<<T as std::ops::Add>::Output>>>;
fn add(self, other: &Mat<Mat<T>>) -> Self::Output {
let a: &Vec<Mat<T>> = self.pop();
let b: &Vec<Mat<T>> = other.pop();
match a.len() == b.len() {
true => {
let mut retvec: Vec<Mat<<T as std::ops::Add>::Output>> = Vec::new();
for i in 0..a.len() {
if let Some(x) = &a[i] + &b[i] {
retvec.push(x);
}
}
Some(Mat(retvec))
}
false => None,
}
}
}
impl<'a, T> Add for &'a Mat<T>
where
T: PartialEq + PartialOrd + Add<T> + Clone
impl<T> Add for Mat<T>
where
T: PartialEq + PartialOrd + Add<T> + Clone
use std::ops::*;
use std::vec::Vec;
#[derive(Clone, Debug, PartialEq, PartialOrd)]
struct Mat<T>(Vec<T>);
impl<T> Mat<T> {
fn pop(&self) -> &Vec<T> {
&self.0
}
}
impl<T> Add for Mat<T>
where
T: PartialEq + PartialOrd + Add<T> + Clone,
{
type Output = Mat<<T as std::ops::Add>::Output>;
fn add(self, other: Mat<T>) -> Self::Output {
let a: &Vec<T> = self.pop();
let b: &Vec<T> = other.pop();
match a.len() == b.len() {
true => {
let mut retvec: Vec<<T as std::ops::Add>::Output> = Vec::new();
for i in 0..a.len() {
retvec.push(a[i].clone() + b[i].clone());
}
Mat(retvec)
}
false => Mat(Vec::new()),
}
}
}
impl<'a, T> Add for &'a Mat<T>
where
T: PartialEq + PartialOrd + Add<T> + Clone,
{
type Output = Mat<<T as std::ops::Add>::Output>;
fn add(self, other: &Mat<T>) -> Self::Output {
let a: &Vec<T> = self.pop();
let b: &Vec<T> = other.pop();
match a.len() == b.len() {
true => {
let mut retvec: Vec<<T as std::ops::Add>::Output> = Vec::new();
for i in 0..a.len() {
retvec.push(a[i].clone() + b[i].clone());
}
Mat(retvec)
}
false => Mat(Vec::new()),
}
}
}
#[test]
fn add_override_vectors() {
let vec: Mat<Mat<i32>> = Mat(vec![Mat(vec![2, 2, 2]), Mat(vec![3, 3, 3])]);
let newvec = &vec + &vec;
assert_eq!(*newvec.pop(), vec![Mat(vec![4, 4, 4]), Mat(vec![6, 6, 6])]);
}
#[test]
fn add_wrong_vectors() {
let vec1: Mat<Mat<i32>> = Mat(vec![Mat(vec![2, 2, 2]), Mat(vec![4, 4, 4])]);
let vec2: Mat<Mat<i32>> = Mat(vec![Mat(vec![3, 3, 3]), Mat(vec![3, 3])]);
let newvec = &vec1 + &vec2;
assert_eq!(*newvec.pop(), vec![Mat(vec![5, 5, 5]), Mat(vec![])]);
}
fn main() {
let vec: Mat<Mat<i32>> = Mat(vec![Mat(vec![1, 2, 2]), Mat(vec![3, 3, 3])]);
let newvec = &vec + &vec;
println!("Hello, world!: {:?}", newvec);
}