block_graph/
ops.rs

1impl Abs for f32{// TODO implement operations for result types
2	fn abs(self)->Self::Output{f32::abs(self)}
3	type Output=f32;
4}
5impl Rank for f32{
6	fn dynamic_rank(&self)->usize{0}
7	fn type_rank()->usize{0}
8}
9impl Squeeze for Vec<f32>{
10	fn squeeze(self,dim:i32)->Self::Output{
11		if dim!=-1&&dim!=0{panic!("squeeze dim out of bounds")}
12		if self.len()!=1{panic!("cannot squeeze a dim whose size is not 1")}
13		self[0]
14	}
15	type Output=f32;
16}
17impl SquaredError for f32{
18	fn squared_error(self,rhs:f32)->Self::Output{
19		let d=self-rhs;
20		d*d
21	}
22	type Output=f32;
23}
24impl Unsqueeze for f32{
25	fn unsqueeze(self,dim:i32)->UnsqueezeScalar<f32>{
26		if dim==-1||dim==0{UnsqueezeScalar(self)}else{panic!("unsqueeze dim out of bounds")}
27	}
28	type Output=UnsqueezeScalar<f32>;
29}
30impl<T:Rank> Rank for Vec<T>{
31	fn dynamic_rank(&self)->usize{self.first().map(T::dynamic_rank).unwrap_or_else(T::type_rank)+1}
32	fn type_rank()->usize{T::type_rank()+1}
33}
34impl<T:Squeeze> Squeeze for Vec<Vec<T>> where Vec<T>:Squeeze<Output=T>+Rank{
35	fn squeeze(self,mut dim:i32)->Self::Output{
36		let rank=self.rank() as i32;
37
38		if !(-rank..rank).contains(&dim){panic!("squeeze dim out of bounds")}
39		if dim==0||dim==-rank{
40			if self.len()!=1{panic!("cannot squeeze a dim whose size is not 1")}
41			self.into_iter().next().unwrap()
42		}else{
43			if dim>0{dim-=1}
44			self.into_iter().map(|x|x.squeeze(dim)).collect()
45		}
46	}
47	type Output=Vec<T>;
48}
49impl<T:Unsqueeze<Output=U>,U> Stack for Vec<T> where Vec<U>:Cat<Output=Vec<T>>{
50	fn stack(self,dim:i32)->Self::Output{
51		let unsqueezed:Vec<U>=self.into_iter().map(|x|x.unsqueeze(dim)).collect();
52		unsqueezed.cat(dim)
53	}
54	type Output=Self;
55}
56impl<T:Unsqueeze> Unsqueeze for Vec<T> where T::Output:Into<Vec<T>>,Vec<T>:Rank{
57	fn unsqueeze(self,mut dim:i32)->Self::Output{
58		let rank=self.rank() as i32;
59
60		if !(-rank..rank+1).contains(&dim){panic!("unsqueeze dim out of bounds")}
61		if dim==0||dim==-rank{return vec![self]}else if dim>0{dim-=1}
62		self.into_iter().map(|x|x.unsqueeze(dim).into()).collect()
63	}
64	type Output=Vec<Vec<T>>;
65}
66impl<T> From<UnsqueezeScalar<T>> for Vec<T>{
67	fn from(value:UnsqueezeScalar<T>)->Vec<T>{vec![value.0]}
68}
69#[derive(Clone,Copy,Debug,Default,Eq,Hash,Ord,PartialEq,PartialOrd)]
70/// unsqueezed scalar that can be converted to vector type
71pub struct UnsqueezeScalar<T>(pub T);
72/// trait to represent the operation
73pub trait Abs{
74	/// macro convenience version of the primary method
75	fn _apply(self)->Self::Output where Self:Sized{self.abs()}
76	/// computes the operation
77	fn abs(self)->Self::Output;
78	/// the output type
79	type Output;
80}
81/// trait to represent the operation
82pub trait Cat{
83	/// macro convenience version of the primary method
84	fn _apply(self,dim:i32)->Self::Output where Self:Sized{self.cat(dim)}
85	/// concatenates the data along the given axis
86	fn cat(self,dim:i32)->Self::Output;
87	/// the output type
88	type Output;
89}
90/// get tensor rank
91pub trait Rank{
92	/// gets the rank
93	fn dynamic_rank(&self)->usize;
94	/// gets the rank
95	fn rank(&self)->usize{self.dynamic_rank()}
96	/// gets the rank at a type level. this may be some kind of default if there isn't a clear rank associated with the type
97	fn type_rank()->usize where Self:Sized;
98}
99/// trait to represent the operation
100pub trait Squeeze{
101	/// macro convenience version of the primary method
102	fn _apply(self,dim:i32)->Self::Output where Self:Sized{self.squeeze(dim)}
103	/// computes the operation
104	fn squeeze(self,dim:i32)->Self::Output;
105	/// the output type
106	type Output;
107}
108/// trait to represent the operation
109pub trait SwapDims{
110	/// macro convenience version of the primary method
111	fn _apply(self,a:i32,b:i32)->Self::Output where Self:Sized{self.swap_dims(a,b)}
112	/// computes the operation
113	fn swap_dims(self,a:i32,b:i32)->Self::Output;
114	/// the output type
115	type Output;
116}
117/// trait to represent the operation
118pub trait SquaredError<R=Self>{
119	/// macro convenience version of the primary method
120	fn _apply(self,rhs:R)->Self::Output where Self:Sized{self.squared_error(rhs)}
121	/// computes the operation
122	fn squared_error(self,rhs:R)->Self::Output;
123	/// the output type
124	type Output;
125}
126/// trait to represent the operation
127pub trait Stack{
128	/// macro convenience version of the primary method
129	fn _apply(self,dim:i32)->Self::Output where Self:Sized{self.stack(dim)}
130	/// stacks the data along the given axis
131	fn stack(self,dim:i32)->Self::Output;
132	/// the output type
133	type Output;
134}
135/// trait to represent the operation
136pub trait Unsqueeze{
137	/// macro convenience version of the primary method
138	fn _apply(self,dim:i32)->Self::Output where Self:Sized{self.unsqueeze(dim)}
139	/// computes the operation
140	fn unsqueeze(self,dim:i32)->Self::Output;
141	/// the output type
142	type Output;
143}