tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
tensor_view.hpp
1 // -*- mode: c++; fill-column: 80; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 /*
3  Copyright (c) 2010 Juan Jose Garcia Ripoll
4 
5  Tensor is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published
7  by the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Library General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <cassert>
21 
24 namespace tensor {
25 
27  // CONVERT TENSOR VIEWS TO TENSORS
28  //
29 
30  template<typename elt_t>
31  Tensor<elt_t>::view::operator Tensor<elt_t>() const
32  {
33  Tensor<elt_t> t(dims_);
34  typename Tensor<elt_t>::iterator it = t.begin();
35  ranges_->reset();
36  for (index j; (j = ranges_->pop()) != ranges_->nomore(); it++) {
37  *it = data_[j];
38  }
39  return t;
40  }
41 
43  // CONSTRUCT CONST TENSOR VIEWS
44  //
45 
46  template<typename elt_t> const typename Tensor<elt_t>::view
47  Tensor<elt_t>::operator()(PRange r) const
48  {
49  Indices dims(1);
50  assert(this->rank() == 1);
51  r->set_limit(dimension(0));
52  dims.at(0) = r->size();
53  return view(*this, dims, r);
54  }
55 
56  template<typename elt_t> const typename Tensor<elt_t>::view
57  Tensor<elt_t>::operator()(PRange r1, PRange r2) const
58  {
59  Indices dims(2);
60  assert(this->rank() == 2);
61  r1->set_limit(dimension(0));
62  r2->set_limit(dimension(1));
63  dims.at(0) = r1->size();
64  dims.at(1) = r2->size();
65  Range *r = product(r1, r2);
66  return view(*this, dims, r);
67  }
68 
69  template<typename elt_t> const typename Tensor<elt_t>::view
70  Tensor<elt_t>::operator()(PRange r1, PRange r2, PRange r3) const
71  {
72  Indices dims(3);
73  assert(this->rank() == 3);
74  r1->set_limit(dimension(0));
75  r2->set_limit(dimension(1));
76  r3->set_limit(dimension(2));
77  dims.at(0) = r1->size();
78  dims.at(1) = r2->size();
79  dims.at(2) = r3->size();
80  Range *r = product(r1, product(r2, r3));
81  return view(*this, dims, r);
82  }
83 
84  template<typename elt_t> const typename Tensor<elt_t>::view
85  Tensor<elt_t>::operator()(PRange r1, PRange r2, PRange r3, PRange r4) const
86  {
87  Indices dims(4);
88  assert(this->rank() == 4);
89  r1->set_limit(dimension(0));
90  r2->set_limit(dimension(1));
91  r3->set_limit(dimension(2));
92  r4->set_limit(dimension(3));
93  dims.at(0) = r1->size();
94  dims.at(1) = r2->size();
95  dims.at(2) = r3->size();
96  dims.at(3) = r4->size();
97  Range *r = product(r1, product(r2, product(r3, r4)));
98  return view(*this, dims, r);
99  }
100 
101  template<typename elt_t> const typename Tensor<elt_t>::view
102  Tensor<elt_t>::operator()(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5) const
103  {
104  Indices dims(5);
105  assert(this->rank() == 5);
106  r1->set_limit(dimension(0));
107  r2->set_limit(dimension(1));
108  r3->set_limit(dimension(2));
109  r4->set_limit(dimension(3));
110  r5->set_limit(dimension(4));
111  dims.at(0) = r1->size();
112  dims.at(1) = r2->size();
113  dims.at(2) = r3->size();
114  dims.at(3) = r4->size();
115  dims.at(4) = r5->size();
116  PRange r = product(r1, product(r2, product(r3, product(r4, r5))));
117  return view(*this, dims, r);
118  }
119 
120  template<typename elt_t> const typename Tensor<elt_t>::view
121  Tensor<elt_t>::operator()(PRange r1, PRange r2, PRange r3,
122  PRange r4, PRange r5, PRange r6) const
123  {
124  Indices dims(6);
125  assert(this->rank() == 6);
126  r1->set_limit(dimension(0));
127  r2->set_limit(dimension(1));
128  r3->set_limit(dimension(2));
129  r4->set_limit(dimension(3));
130  r5->set_limit(dimension(4));
131  r6->set_limit(dimension(5));
132  dims.at(0) = r1->size();
133  dims.at(1) = r2->size();
134  dims.at(2) = r3->size();
135  dims.at(3) = r4->size();
136  dims.at(4) = r5->size();
137  dims.at(5) = r6->size();
138  Range *r = product(r1, product(r2, product(r3, product(r4, product(r5, r6)))));
139  return view(*this, dims, r);
140  }
141 
143  // CONSTRUCT MUTABLE TENSOR VIEWS
144  //
145 
146  template<typename elt_t> typename Tensor<elt_t>::mutable_view
147  Tensor<elt_t>::at(PRange r)
148  {
149  Indices dims(1);
150  assert(this->rank() == 1);
151  r->set_limit(dimension(0));
152  dims.at(0) = r->size();
153  return mutable_view(*this, dims, r);
154  }
155 
156  template<typename elt_t> typename Tensor<elt_t>::mutable_view
157  Tensor<elt_t>::at(PRange r1, PRange r2)
158  {
159  Indices dims(2);
160  assert(this->rank() == 2);
161  r1->set_limit(dimension(0));
162  r2->set_limit(dimension(1));
163  dims.at(0) = r1->size();
164  dims.at(1) = r2->size();
165  Range *r = product(r1, r2);
166  return mutable_view(*this, dims, r);
167  }
168 
169  template<typename elt_t> typename Tensor<elt_t>::mutable_view
170  Tensor<elt_t>::at(PRange r1, PRange r2, PRange r3)
171  {
172  Indices dims(3);
173  assert(this->rank() == 3);
174  r1->set_limit(dimension(0));
175  r2->set_limit(dimension(1));
176  r3->set_limit(dimension(2));
177  dims.at(0) = r1->size();
178  dims.at(1) = r2->size();
179  dims.at(2) = r3->size();
180  Range *r = product(r1, product(r2, r3));
181  return mutable_view(*this, dims, r);
182  }
183 
184  template<typename elt_t> typename Tensor<elt_t>::mutable_view
185  Tensor<elt_t>::at(PRange r1, PRange r2, PRange r3, PRange r4)
186  {
187  Indices dims(4);
188  assert(this->rank() == 4);
189  r1->set_limit(dimension(0));
190  r2->set_limit(dimension(1));
191  r3->set_limit(dimension(2));
192  r4->set_limit(dimension(3));
193  dims.at(0) = r1->size();
194  dims.at(1) = r2->size();
195  dims.at(2) = r3->size();
196  dims.at(3) = r4->size();
197  Range *r = product(r1, product(r2, product(r3, r4)));
198  return mutable_view(*this, dims, r);
199  }
200 
201  template<typename elt_t> typename Tensor<elt_t>::mutable_view
202  Tensor<elt_t>::at(PRange r1, PRange r2, PRange r3, PRange r4, PRange r5)
203  {
204  Indices dims(5);
205  assert(this->rank() == 5);
206  r1->set_limit(dimension(0));
207  r2->set_limit(dimension(1));
208  r3->set_limit(dimension(2));
209  r4->set_limit(dimension(3));
210  r5->set_limit(dimension(4));
211  dims.at(0) = r1->size();
212  dims.at(1) = r2->size();
213  dims.at(2) = r3->size();
214  dims.at(3) = r4->size();
215  dims.at(4) = r5->size();
216  Range *r = product(r1, product(r2, product(r3, product(r4, r5))));
217  return mutable_view(*this, dims, r);
218  }
219 
220  template<typename elt_t> typename Tensor<elt_t>::mutable_view
221  Tensor<elt_t>::at(PRange r1, PRange r2, PRange r3,
222  PRange r4, PRange r5, PRange r6)
223  {
224  Indices dims(6);
225  assert(this->rank() == 6);
226  r1->set_limit(dimension(0));
227  r2->set_limit(dimension(1));
228  r3->set_limit(dimension(2));
229  r4->set_limit(dimension(3));
230  r5->set_limit(dimension(4));
231  r6->set_limit(dimension(5));
232  dims.at(0) = r1->size();
233  dims.at(1) = r2->size();
234  dims.at(2) = r3->size();
235  dims.at(3) = r4->size();
236  dims.at(4) = r5->size();
237  dims.at(5) = r6->size();
238  Range *r = product(r1, product(r2, product(r3, product(r4, product(r5, r6)))));
239  return mutable_view(*this, dims, r);
240  }
241 
243  // ASSIGN TO MUTABLE MUTABLE_VIEWS
244  //
245 
246  template<typename elt_t> void
247  Tensor<elt_t>::mutable_view::operator=
248  (const typename Tensor<elt_t>::view &t)
249  {
250  //assert(verify_tensor_dimensions_match(dims_, t.dims_));
251  assert(dims_.total_size() == t.dims_.total_size());
252  Range *r1 = ranges_;
253  Range *r2 = t.ranges_;
254  r1->reset();
255  r2->reset();
256  for (index i, j;
257  (i = r1->pop(), j = r2->pop(), i != r1->nomore() && j != r2->nomore()); ) {
258  data_.at(i) = t.data_[j];
259  }
260  }
261 
262  template<typename elt_t> void
263  Tensor<elt_t>::mutable_view::operator=(const Tensor<elt_t> &t)
264  {
265  //assert(verify_tensor_dimensions_match(dims_, t.dimensions()));
266  assert(dims_.total_size() == t.dims_.total_size());
267  ranges_->reset();
268  for (index i = 0, j; (j = ranges_->pop()) != ranges_->nomore(); i++) {
269  data_.at(j) = t[i];
270  }
271  }
272 
273  template<typename elt_t> void
274  Tensor<elt_t>::mutable_view::operator=(elt_t v)
275  {
276  ranges_->reset();
277  for (index i; (i = ranges_->pop()) != ranges_->nomore(); ) {
278  data_.at(i) = v;
279  }
280  }
281 
282 } // namespace tensor
283 
const elt_t & operator()(index i) const
Return an element of a 1D Tensor.
elt_t & at(index i)
Return a mutable reference to an element of a 1D Tensor.