Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::ops::Mul;
- // definition of vector type
- #[derive(Debug, Clone, PartialEq)]
- pub struct Vector<T>
- where T: Clone + Copy {
- value: Vec<T>
- }
- // these two Mul implementations are fine
- // they take owned values
- impl<T, U, O> Mul<Vector<U>> for Vector<T>
- where T: Clone + Copy + Mul<U, Output = O>,
- U: Clone + Copy,
- O: Clone + Copy {
- type Output = Result<Vector<O>, String>;
- fn mul(self, rhs: Vector<U>) -> Self::Output {
- apply(self, rhs, |t, u| t * u)
- }
- }
- impl<T, U, O> Mul<U> for Vector<T>
- where T: Clone + Copy + Mul<U, Output = O>,
- U: Clone + Copy,
- O: Clone + Copy {
- type Output = Vector<O>;
- fn mul(self, rhs: U) -> Self::Output {
- apply_const(self, |t| t * rhs)
- }
- }
- // these two Mul implementations don't work with each other
- // they take borrow values
- // if I comment one out the other works fine
- // This is the second major iteration of this code (the first is below)
- impl<'a, 'b, T, U, O> Mul<&'b Vector<U>> for &'a Vector<T>
- where T: Clone + Copy + Mul<U, Output = O>,
- U: Clone + Copy,
- O: Clone + Copy {
- type Output = Result<Vector<O>, String>;
- fn mul(self, rhs: &'b Vector<U>) -> Self::Output {
- apply_ref(self, rhs, |t, u| *t * *u)
- }
- }
- impl<'a, T, U, O> Mul<U> for &'a Vector<T>
- where T: Clone + Copy + Mul<U, Output = O>,
- U: Clone + Copy,
- O: Clone + Copy {
- type Output = Vector<O>;
- fn mul(self, rhs: U) -> Self::Output {
- apply_const_ref(self, |t| *t * rhs)
- }
- }
- // This is what I had before I changed (I wanted to generalize the basic operations if type T could multiply with other types)
- // This led to the above code
- // This code works fine if swapped with the more general code above
- /*
- impl<'a, 'b, T> Mul<&'b Vector<T>> for &'a Vector<T>
- where T: Clone + Copy + Mul<T, Output = T> {
- type Output = Result<Vector<T>, String>;
- fn mul(self, rhs: &'b Vector<T>) -> Self::Output {
- apply_ref(self, rhs, |t, u| *t * *u)
- }
- }
- impl<'a, T> Mul<T> for &'a Vector<T>
- where T: Clone + Copy + Mul<T, Output = T> {
- type Output = Vector<T>;
- fn mul(self, rhs: T) -> Self::Output {
- apply_const_ref(self, |t| *t * rhs)
- }
- }
- */
- // These functions below are used more in the actual lib
- // so that I don't copy and paste code too much
- // ideally all of these functions would be consolidated
- // but I don't know how to generalize over both owned types
- // and borrow types at once
- // All of them take in a vector and the rhs of the operation (vector or scalar)
- // and a function, then it applies the function to the two inputs and stores into
- // a return value
- // these also perform dimension checks
- impl<T> Vector<T>
- where T: Clone + Copy {
- fn dim(&self) -> usize {
- self.value.len()
- }
- }
- impl<T> From<Vec<T>> for Vector<T>
- where T: Clone + Copy {
- fn from(value: Vec<T>) -> Self {
- Self { value }
- }
- }
- fn apply<T, U, O, F>(t: Vector<T>, u: Vector<U>, f: F) -> Result<Vector<O>, String>
- where T: Clone + Copy,
- U: Clone + Copy,
- O: Clone + Copy,
- F: Fn(T, U) -> O {
- if t.dim() != u.dim() {
- return Err(format!("incompatible sizes"))
- }
- let mut vec = Vec::with_capacity(t.dim());
- for (i, j) in t.value.iter().zip(u.value.iter()) {
- vec.push(f(*i, *j))
- }
- Ok(Vector::from(vec))
- }
- fn apply_ref<'a, 'b, T, U, O, F>(t: &'a Vector<T>, u: &'b Vector<U>, f: F) -> Result<Vector<O>, String>
- where T: Clone + Copy,
- U: Clone + Copy,
- O: Clone + Copy,
- F: Fn(&'a T, &'b U) -> O {
- if t.dim() != u.dim() {
- return Err(format!("incompatible sizes"))
- }
- let mut vec = Vec::with_capacity(t.dim());
- for (i, j) in t.value.iter().zip(u.value.iter()) {
- vec.push(f(i, j))
- }
- Ok(Vector::from(vec))
- }
- fn apply_const<T, O, F>(t: Vector<T>, f: F) -> Vector<O>
- where T: Clone + Copy,
- O: Clone + Copy,
- F: Fn(T) -> O {
- let mut vec = Vec::with_capacity(t.dim());
- for i in t.value.iter() {
- vec.push(f(*i));
- }
- Vector::from(vec)
- }
- fn apply_const_ref<'a, T, O, F>(t: &'a Vector<T>, f: F) -> Vector<O>
- where T: Clone + Copy,
- O: Clone + Copy,
- F: Fn(&'a T) -> O {
- let mut vec = Vec::with_capacity(t.dim());
- for i in t.value.iter() {
- vec.push(f(i));
- }
- Vector::from(vec)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement