numas/array/array.rs
1use std::fmt;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use shape::Shape;
6
7
8/// Array structure
9pub struct Array<T: Copy> {
10 pub data: Rc<RefCell<Vec<T>>>,
11 pub shape: Shape,
12}
13
14impl<T: Copy> Array<T> {
15 /// Creates new bounded array
16 ///
17 /// # Arguments
18 ///
19 /// * `data` - array elements
20 /// * `shape` - vector representing array shape
21 /// * `start` - start offset of array data
22 /// * `end` - end offset of array data
23 #[inline]
24 pub fn new_bounded(data: Vec<T>, shape: Vec<i32>, start: usize, end: usize) -> Array<T> {
25 return Array {
26 data: Rc::new(RefCell::new(data)),
27 shape: Shape::new(shape, start, end)
28 };
29 }
30
31 /// Creates new array
32 ///
33 /// # Arguments
34 ///
35 /// * `data` - array elements
36 /// * `shape` - vector representing array shape
37 pub fn new(data: Vec<T>, shape: Vec<i32>) -> Array<T> {
38 let length = data.len();
39
40 return Array::new_bounded(data, shape, 0, length);
41 }
42
43 /// Returns Shape instance
44 #[inline]
45 pub fn shape(&self) -> &Shape {
46 &self.shape
47 }
48
49 /// Returns vector representing array shape
50 #[inline]
51 pub fn get_shape(&self) -> &Vec<i32> {
52 self.shape.get_shape()
53 }
54
55 /// Sets array shape
56 ///
57 /// # Arguments
58 ///
59 /// * `shape` - vector representing new array shape
60 #[inline]
61 pub fn reshape(&mut self, shape: Vec<i32>) -> &Array<T> {
62 self.shape.set_shape(shape);
63 return self;
64 }
65
66 /// Sets array shape
67 ///
68 /// # Arguments
69 ///
70 /// * `shape` - vector representing new array shape
71 #[inline]
72 pub fn set_shape(&mut self, shape: Vec<i32>) -> () {
73 self.shape.set_shape(shape);
74 }
75
76 /// Validates indices have right dimension
77 ///
78 /// # Arguments
79 ///
80 /// * `indices` - Indices
81 fn check_indices_size(&self, indices: &Vec<usize>) -> () {
82 let shape_len = self.shape.get_shape().len();
83
84 if indices.len() / 2 > shape_len {
85 panic!(
86 "Invalid indices given: shape dimensions {}, indices dimensions {}",
87 shape_len,
88 indices.len() / 2
89 );
90 }
91 }
92
93 /// Set values on given indices to given value
94 ///
95 /// # Arguments
96 ///
97 /// * `indices` - vector of indices
98 /// * `value` - value to fill it with
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// #[macro_use] extern crate numas;
104 /// use numas::array::Array;
105 ///
106 /// let f_array = Array::new(vec![1,2,3,4,5,6,7,8,9], vec![3,3]);
107 ///
108 /// // first row
109 /// f_array.set(s![0], -1);
110 /// assert_eq!(f_array.collect(), vec![-1,-1,-1,4,5,6,7,8,9]);
111 ///
112 /// let s_array = Array::new(vec![1,2,3,4,5,6,7,8,9], vec![3,3]);
113 ///
114 /// // fist two rows
115 /// s_array.set(s![0 => 2], -1);
116 /// assert_eq!(s_array.collect(), vec![-1,-1,-1,-1,-1,-1,7,8,9]);
117 ///
118 /// let t_array = Array::new(vec![1,2,3,4,5,6,7,8,9], vec![3,3]);
119 ///
120 /// // second row, second column
121 /// t_array.set(s![1; 1], -1);
122 /// assert_eq!(t_array.collect(), vec![1,2,3,4,-1,6,7,8,9]);
123 ///
124 /// let x_array = Array::new(vec![1,2,3,4,5,6,7,8,9], vec![3,3]);
125 ///
126 /// // last row, two last columns
127 /// x_array.set(s![2; 1 => 3], -1);
128 /// assert_eq!(x_array.collect(), vec![1,2,3,4,5,6,7,-1,-1]);
129 /// ```
130 pub fn set(&self, indices: Vec<usize>, value: T) -> () {
131 self.check_indices_size(&indices);
132
133 let shape = self.shape.indices_to_shape(indices);
134 let mut data = self.data.borrow_mut();
135
136 for i in shape.get_bounds() {
137 data[i] = value;
138 }
139 }
140
141 /// Fills array with given value
142 ///
143 /// # Arguments
144 ///
145 /// * `value` - fill value
146 pub fn fill(&self, value: T) -> &Array<T> {
147 let mut data = self.data.borrow_mut();
148
149 for i in self.shape.get_bounds() {
150 data[i] = value;
151 }
152
153 return self;
154 }
155
156 /// Return new Array from given indices
157 ///
158 /// # Arguments
159 ///
160 /// * `indices` - vector of indices
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// #[macro_use] extern crate numas;
166 /// use numas::array::Array;
167 ///
168 /// let array = Array::new(vec![1,2,3,4,5,6,7,8,9], vec![3,3]);
169 ///
170 /// // first row
171 /// assert_eq!(array.get(s![0]).collect(), vec![1,2,3]);
172 ///
173 /// // fist two rows
174 /// assert_eq!(array.get(s![0 => 2]).collect(), vec![1,2,3,4,5,6]);
175 ///
176 /// // second row, second column
177 /// assert_eq!(array.get(s![1; 1]).collect(), vec![5]);
178 ///
179 /// // last row, two last columns
180 /// assert_eq!(array.get(s![2; 1 => 3]).collect(), vec![8,9]);
181 /// ```
182 pub fn get(&self, indices: Vec<usize>) -> Array<T> {
183 // Handle invalid indices length
184 self.check_indices_size(&indices);
185
186 let new_shape = self.shape.indices_to_shape(indices);
187
188 return Array {
189 shape: new_shape,
190 data: self.data.clone(),
191 };
192 }
193
194 /// Returns length of array
195 pub fn len(&self) -> usize {
196 return Shape::total_len(&self.shape) as usize;
197 }
198
199 /// Returns base length of array
200 #[inline]
201 pub fn base_len(&self) -> usize {
202 return self.data.borrow().len();
203 }
204
205 /// Creates view into array
206 #[inline]
207 pub fn view(&self) -> Array<T> {
208 return Array {
209 data: self.data.clone(),
210 shape: self.shape.clone(),
211 }
212 }
213
214 /// Creates bounded view into array
215 ///
216 /// # Arguments
217 ///
218 /// * `shape` - vector representing array shape
219 /// * `start` - start offset of array data
220 /// * `end` - end offset of array data
221 #[inline]
222 pub fn bounded_view(&self, shape: &Vec<i32>, start: usize, end: usize) -> Array<T> {
223 return Array {
224 data: self.data.clone(),
225 shape: Shape::new(shape.clone(), start, end),
226 }
227 }
228
229 /// Collects elements of array into vector
230 pub fn collect(&self) -> Vec<T> {
231 let data = self.data.borrow();
232 return data[self.shape.get_bounds()].to_vec();
233 }
234}
235
236impl<T: Copy> Clone for Array<T> {
237 /// Clones array object
238 fn clone(&self) -> Array<T> {
239 let data = self.data.borrow().to_vec().clone();
240
241 return Array {
242 data: Rc::new(RefCell::new(data)),
243 shape: self.shape.clone(),
244 };
245 }
246}
247
248impl <T: fmt::Debug + Copy> fmt::Debug for Array<T> {
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 let data = self.data.borrow();
251 return write!(f, "data: \t{:?}\nshape: \t{:?}", &data[self.shape.get_bounds()], self.get_shape());
252 }
253}