1use traits;
2use std::ops::Mul;
3
4pub struct Rank1Tensor<T: traits::TensorTrait<T>> {
5 dim: i32,
6 components: Vec<T>,
7}
8
9pub struct Rank2Tensor<T: traits::TensorTrait<T>> {
10 dim: i32,
11 components: Vec<Vec<T>>,
12}
13
14pub struct Rank3Tensor<T: traits::TensorTrait<T>> {
15 dim: i32,
16 components: Vec<Vec<Vec<T>>>,
17}
18
19pub struct Tensor<T: traits::TensorTrait<T>> {
21 dim: i32,
22 rank: i32,
23 components: Vec<T>,
24}
25
26impl<T: traits::TensorTrait<T>> Tensor<T> {
28 pub fn build(d: i32, r: i32, v: Vec<T>) -> Self {
29 Tensor {
30 dim: d,
32 rank: r,
33 components: v,
34 }
35 }
36 pub fn clone(&self) -> Self {
37 Tensor::build(self.dim.clone(), self.rank.clone(), self.components.clone())
38 }
39 pub fn get(&self, indices: &[i32]) -> T {
41 let mut i: i32 = 0;
42 for x in 0..self.rank {
44 i = i + scalar_power(self.dim, x as i32) * indices[x as usize];
45 }
46 self.components[i as usize].clone()
47 }
48 pub fn set(&mut self, indices: &[i32], value: T) {
49 let mut i: i32 = 0;
50 for x in 0..self.rank {
52 i = i + scalar_power(self.dim, x as i32) * indices[x as usize];
53 }
54 self.components[i as usize] = value;
55 }
56 pub fn inner_product(&self, other: &Tensor<T>) -> Self {
57 assert_eq!(self.rank, (*other).rank);
59 assert_eq!(self.dim, (*other).dim);
60
61 let mut args: Vec<i32> = Vec::new();
62 for _ in 0..(self.rank + other.rank - 2) {
63 args.push(self.dim);
64 }
65 let new_rank: i32 = self.rank + other.rank - 2;
66 let len = scalar_power(self.dim, new_rank) as usize;
67 let mut new_tensor = &mut Tensor::build(self.dim, new_rank, vec![T::zero(); len]);
68
69 inner_product_loop(args, Tensor::print_inner_product, &self, &other, new_tensor);
70
71 (*new_tensor).clone()
73 }
74 fn print_inner_product(&mut self, t1: &Tensor<T>, t2: &Tensor<T>, indices: &[i32]) {
75 let i: usize = (t1.rank - 1) as usize;
76 let j: usize = (t1.rank - 1) as usize;
77 let mut v1 = indices[0..i].to_vec();
78 let mut v2 = indices[j..].to_vec();
79
80 v1.push(0);
82 v2.insert(0, 0);
83
84 let mut total: T = T::zero();
85 for x in 0..t1.dim {
86 v1[(t1.rank - 1) as usize] = x;
87 v2[0] = x;
88 total = total + t1.get(&v1) * t2.get(&v2);
89 }
90
91 self.set(indices, total);
93 }
94 pub fn print(&self) {
95 let mut v: Vec<i32> = Vec::new();
96 for _ in 0..self.rank {
97 v.push(self.dim.clone());
98 }
99 print_loop(v, Tensor::print_element, &self);
100 }
101 fn print_element(&self, v: Vec<i32>) {
102 println!( "T{:?} : {:?}", v, self.get(&v) );
103 }
104}
105
106pub fn scalar_power(n: i32, p: i32) -> i32 {
108 let mut a: i32 = 1;
109 for _ in 0..p { a = a*n; }
110 a
111}
112
113pub fn inner_product_loop<T: traits::TensorTrait<T>>(max_indices: Vec<i32>, f: fn(&mut Tensor<T>, &Tensor<T>, &Tensor<T>, &[i32]),
115t1: &Tensor<T>, t2: &Tensor<T>, t3: &mut Tensor<T>) {
116 inner_product_loop_many(max_indices.clone(), f, t1, t2, t3, Vec::new(), 0);
117}
118
119pub fn inner_product_loop_many<T: traits::TensorTrait<T>>(max_indices: Vec<i32>, f: fn(&mut Tensor<T>, &Tensor<T>, &Tensor<T>, &[i32]),
121t1: &Tensor<T>, t2: &Tensor<T>, t3: &mut Tensor<T>, pargs: Vec<i32>, index: i32) {
122 if max_indices.len() == 0 {
123 f(t3, t1, t2, &pargs);
124 } else {
125 let mut args = pargs.clone();
126 let rest: Vec<i32> = max_indices[1..].to_vec();
127 for _ in 0..max_indices[0] {
128 if args.len() == index as usize { args.push(0); }
129 if args[index as usize] < max_indices[0] {
130 inner_product_loop_many(rest.clone(), f, t1, t2, t3, args.clone(), index + 1);
131 args[index as usize] = args[index as usize] + 1;
132 }
133 }
134 }
135}
136
137pub fn print_loop<T: traits::TensorTrait<T>>(max_indices: Vec<i32>, f: fn(&Tensor<T>, Vec<i32>), t: &Tensor<T>) {
139 print_loop_many(max_indices.clone(), f, t, Vec::new(), 0);
140}
141
142pub fn print_loop_many<T: traits::TensorTrait<T>>(max_indices: Vec<i32>, f: fn(&Tensor<T>, Vec<i32>),
144t: &Tensor<T>, pargs: Vec<i32>, index: i32) {
145 if max_indices.len() == 0 {
146 f(t, pargs);
147 } else {
148 let mut args = pargs.clone();
149 let rest: Vec<i32> = max_indices[1..].to_vec();
150 for _ in 0..max_indices[0] {
151 if args.len() == index as usize { args.push(0); }
152 if args[index as usize] < max_indices[0] {
153 print_loop_many(rest.clone(), f, t, args.clone(), index + 1);
154 args[index as usize] = args[index as usize] + 1;
155 }
156 }
157 }
158}
159
160impl<T: traits::TensorTrait<T>> Rank1Tensor<T> {
161 pub fn new(d: i32) -> Self {
162 Rank1Tensor {
163 dim: d,
164 components: Vec::new(),
165 }
166 }
167 pub fn build(d: i32, c: Vec<T>) -> Self {
168 Rank1Tensor {
169 dim: d,
170 components: c,
171 }
172 }
173 pub fn get(&self, i: i32) -> T {
174 self.components[i as usize].clone()
175 }
176 pub fn dim(&self) -> i32 {
177 self.dim.clone()
178 }
179}
180
181impl<T: traits::TensorTrait<T>> Rank2Tensor<T> {
182 pub fn new(d: i32) -> Self {
183 let mut temp_vec = Vec::new();
184 for _ in 0..d {
185 temp_vec.push(Vec::new());
186 }
187 Rank2Tensor {
188 dim: d,
189 components: temp_vec,
190 }
191 }
192 pub fn build(d: i32, c: Vec<Vec<T>>) -> Self {
193 Rank2Tensor {
194 dim: d,
195 components: c,
196 }
197 }
198 pub fn get(&self, i: i32, j: i32) -> T {
199 self.components[i as usize][j as usize].clone()
200 }
201 pub fn dim(&self) -> i32 {
202 self.dim.clone()
203 }
204 pub fn print(&self) {
205 for i in 0..self.dim() {
206 for j in 0..self.dim() {
207 print!{ "T[{},{}]: {}\n", i, j, self.get(i, j) };
208 }
209 }
210 }
211}
212
213impl<T: traits::TensorTrait<T>> Rank3Tensor<T> {
214 pub fn new(d: i32) -> Self {
215 let mut temp_vec = Vec::new();
216 for _ in 0..d {
217 let mut temp_vec_2 = Vec::new();
218 for _ in 0..d {
219 temp_vec_2.push(Vec::new());
220 }
221 temp_vec.push(temp_vec_2);
222 }
223 Rank3Tensor {
224 dim: d,
225 components: temp_vec,
226 }
227 }
228 pub fn build(d: i32, c: Vec<Vec<Vec<T>>>) -> Self {
229 Rank3Tensor {
230 dim: d,
231 components: c,
232 }
233 }
234 pub fn get(&self, i: i32, j: i32, k: i32) -> T {
235 self.components[i as usize][j as usize][k as usize].clone()
236 }
237 pub fn dim(&self) -> i32 {
238 self.dim.clone()
239 }
240}
241
242impl<T: traits::TensorTrait<T>> Mul<Rank1Tensor<T>> for Rank1Tensor<T> {
243 type Output = Rank2Tensor<T>;
244 fn mul(self, other: Rank1Tensor<T>) -> Rank2Tensor<T> {
245 let mut vec = Vec::new();
246 for i in 0..self.dim() {
247 let mut temp_vec = Vec::new();
248 for j in 0..other.dim() {
249 temp_vec.push(self.get(i) * other.get(j))
250 }
251 vec.push(temp_vec)
252 }
253 Rank2Tensor::build(self.dim(), vec)
254 }
255}