source: mmcs/armadillo_bits/op_reshape_meat.hpp @ 8daa049

matrices
Last change on this file since 8daa049 was 9dd61b1, checked in by rboet <rboet@…>, 9 years ago

Avance del proyecto 60%

  • Property mode set to 100644
File size: 8.4 KB
Line 
1// Copyright (C) 2008-2014 Conrad Sanderson
2// Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9
10//! \addtogroup op_reshape
11//! @{
12
13
14
15template<typename eT>
16inline
17void
18op_reshape::apply_unwrap(Mat<eT>& out, const Mat<eT>& A, const uword in_n_rows, const uword in_n_cols, const uword in_dim)
19  {
20  arma_extra_debug_sigprint();
21 
22  const bool is_alias = (&out == &A);
23 
24  const uword in_n_elem = in_n_rows * in_n_cols;
25 
26  if(A.n_elem == in_n_elem)
27    {
28    if(in_dim == 0)
29      {
30      if(is_alias == false)
31        {
32        out.set_size(in_n_rows, in_n_cols);
33        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
34        }
35      else  // &out == &A, i.e. inplace resize
36        {
37        out.set_size(in_n_rows, in_n_cols);
38        // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same
39        }
40      }
41    else
42      {
43      unwrap_check< Mat<eT> > B_tmp(A, is_alias);
44      const Mat<eT>& B      = B_tmp.M;
45     
46      out.set_size(in_n_rows, in_n_cols);
47     
48      eT* out_mem = out.memptr();
49     
50      const uword B_n_rows = B.n_rows;
51      const uword B_n_cols = B.n_cols;
52     
53      for(uword row=0; row<B_n_rows; ++row)
54        {
55        uword i,j;
56        for(i=0, j=1; j < B_n_cols; i+=2, j+=2)
57          {
58          const eT tmp_i = B.at(row,i);
59          const eT tmp_j = B.at(row,j);
60         
61          *out_mem = tmp_i;  out_mem++;
62          *out_mem = tmp_j;  out_mem++;
63          }
64       
65        if(i < B_n_cols)
66          {
67          *out_mem = B.at(row,i);  out_mem++;
68          }
69        }
70      }
71    }
72  else
73    {
74    const unwrap_check< Mat<eT> > B_tmp(A, is_alias);
75    const Mat<eT>& B            = B_tmp.M;
76   
77    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
78   
79    out.set_size(in_n_rows, in_n_cols);
80   
81    eT* out_mem = out.memptr();
82   
83    if(in_dim == 0)
84      {
85      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
86      }
87    else
88      {
89      uword row = 0;
90      uword col = 0;
91     
92      const uword B_n_cols = B.n_cols;
93     
94      for(uword i=0; i<n_elem_to_copy; ++i)
95        {
96        out_mem[i] = B.at(row,col);
97       
98        ++col;
99       
100        if(col >= B_n_cols)
101          {
102          col = 0;
103          ++row;
104          }
105        }
106      }
107   
108    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
109      {
110      out_mem[i] = eT(0);
111      }
112   
113    }
114  }
115
116
117
118template<typename T1>
119inline
120void
121op_reshape::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword in_n_rows, const uword in_n_cols)
122  {
123  arma_extra_debug_sigprint();
124 
125  typedef typename T1::elem_type eT;
126 
127  out.set_size(in_n_rows, in_n_cols);
128 
129  eT* out_mem = out.memptr();
130 
131  const uword in_n_elem = in_n_rows * in_n_cols;
132 
133  if(P.get_n_elem() == in_n_elem)
134    {
135    if(Proxy<T1>::prefer_at_accessor == false)
136      {
137      typename Proxy<T1>::ea_type Pea = P.get_ea();
138     
139      for(uword i=0; i<in_n_elem; ++i)
140        {
141        out_mem[i] = Pea[i];
142        }
143      }
144    else
145      {
146      const uword P_n_rows = P.get_n_rows();
147      const uword P_n_cols = P.get_n_cols();
148     
149      for(uword col=0; col < P_n_cols; ++col)
150        {
151        uword i,j;
152       
153        for(i=0, j=1; j < P_n_rows; i+=2, j+=2)
154          {
155          const eT tmp_i = P.at(i,col);
156          const eT tmp_j = P.at(j,col);
157         
158          *out_mem = tmp_i;  out_mem++;
159          *out_mem = tmp_j;  out_mem++;
160          }
161       
162        if(i < P_n_rows)
163          {
164          *out_mem = P.at(i,col);  out_mem++;
165          }
166        }
167      }
168    }
169  else
170    {
171    const uword n_elem_to_copy = (std::min)(P.get_n_elem(), in_n_elem);
172   
173    if(Proxy<T1>::prefer_at_accessor == false)
174      {
175      typename Proxy<T1>::ea_type Pea = P.get_ea();
176     
177      for(uword i=0; i<n_elem_to_copy; ++i)
178        {
179        out_mem[i] = Pea[i];
180        }
181      }
182    else
183      {
184      uword i = 0;
185     
186      const uword P_n_rows = P.get_n_rows();
187      const uword P_n_cols = P.get_n_cols();
188     
189      for(uword col=0; col < P_n_cols; ++col)
190      for(uword row=0; row < P_n_rows; ++row)
191        {
192        if(i >= n_elem_to_copy)  { goto nested_loop_end; }
193       
194        out_mem[i] = P.at(row,col);
195       
196        ++i;
197        }
198     
199      nested_loop_end: ;
200      }
201   
202    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
203      {
204      out_mem[i] = eT(0);
205      }
206    }
207  }
208
209
210
211template<typename T1>
212inline
213void
214op_reshape::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape>& in)
215  {
216  arma_extra_debug_sigprint();
217 
218  typedef typename T1::elem_type eT;
219 
220  const Proxy<T1> P(in.m);
221 
222  const uword in_n_rows = in.aux_uword_a;
223  const uword in_n_cols = in.aux_uword_b;
224 
225  if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) )
226    {
227    // not checking for aliasing here, as this might be an inplace reshape
228   
229    const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q);
230   
231    op_reshape::apply_unwrap(out, tmp.M, in_n_rows, in_n_cols, uword(0));
232    }
233  else
234    {
235    if(P.is_alias(out))
236      {
237      Mat<eT> tmp;
238     
239      op_reshape::apply_proxy(tmp, P, in_n_rows, in_n_cols);
240     
241      out.steal_mem(tmp);
242      }
243    else
244      {
245      op_reshape::apply_proxy(out, P, in_n_rows, in_n_cols);
246      }
247    }
248  }
249
250
251
252template<typename T1>
253inline
254void
255op_reshape_ext::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape_ext>& in)
256  {
257  arma_extra_debug_sigprint();
258 
259  const unwrap<T1> tmp(in.m);
260 
261  const uword in_n_rows = in.aux_uword_a;
262  const uword in_n_cols = in.aux_uword_b;
263  const uword in_dim    = in.aux_uword_c;
264 
265  op_reshape::apply_unwrap(out, tmp.M, in_n_rows, in_n_cols, in_dim);
266  }
267
268
269
270template<typename T1>
271inline
272void
273op_reshape_ext::apply(Cube<typename T1::elem_type>& out, const OpCube<T1,op_reshape_ext>& in)
274  {
275  arma_extra_debug_sigprint();
276 
277  typedef typename T1::elem_type eT;
278 
279  const unwrap_cube<T1> A_tmp(in.m);
280  const Cube<eT>& A   = A_tmp.M;
281 
282  const uword in_n_rows   = in.aux_uword_a;
283  const uword in_n_cols   = in.aux_uword_b;
284  const uword in_n_slices = in.aux_uword_c;
285  const uword in_dim      = in.aux_uword_d;
286 
287  const uword in_n_elem = in_n_rows * in_n_cols * in_n_slices;
288 
289  if(A.n_elem == in_n_elem)
290    {
291    if(in_dim == 0)
292      {
293      if(&out != &A)
294        {
295        out.set_size(in_n_rows, in_n_cols, in_n_slices);
296        arrayops::copy( out.memptr(), A.memptr(), out.n_elem );
297        }
298      else  // &out == &A, i.e. inplace resize
299        {
300        out.set_size(in_n_rows, in_n_cols, in_n_slices);
301        // set_size() doesn't destroy data as long as the number of elements in the cube remains the same
302        }
303      }
304    else
305      {
306      unwrap_cube_check< Cube<eT> > B_tmp(A, out);
307      const Cube<eT>& B           = B_tmp.M;
308     
309      out.set_size(in_n_rows, in_n_cols, in_n_slices);
310     
311      eT* out_mem = out.memptr();
312     
313      const uword B_n_rows   = B.n_rows;
314      const uword B_n_cols   = B.n_cols;
315      const uword B_n_slices = B.n_slices;
316     
317      for(uword slice = 0; slice < B_n_slices; ++slice)
318      for(uword row   = 0; row   < B_n_rows;   ++row  )
319      for(uword col   = 0; col   < B_n_cols;   ++col  )
320        {
321        *out_mem = B.at(row,col,slice);
322        out_mem++;
323        }
324      }
325    }
326  else
327    {
328    const unwrap_cube_check< Cube<eT> > B_tmp(A, out);
329    const Cube<eT>& B                 = B_tmp.M;
330   
331    const uword n_elem_to_copy = (std::min)(B.n_elem, in_n_elem);
332   
333    out.set_size(in_n_rows, in_n_cols, in_n_slices);
334   
335    eT* out_mem = out.memptr();
336   
337    if(in_dim == 0)
338      {
339      arrayops::copy( out_mem, B.memptr(), n_elem_to_copy );
340      }
341    else
342      {
343      uword row   = 0;
344      uword col   = 0;
345      uword slice = 0;
346     
347      const uword B_n_rows = B.n_rows;
348      const uword B_n_cols = B.n_cols;
349     
350      for(uword i=0; i<n_elem_to_copy; ++i)
351        {
352        out_mem[i] = B.at(row,col,slice);
353       
354        ++col;
355       
356        if(col >= B_n_cols)
357          {
358          col = 0;
359          ++row;
360         
361          if(row >= B_n_rows)
362            {
363            row = 0;
364            ++slice;
365            }
366          }
367        }
368      }
369   
370    for(uword i=n_elem_to_copy; i<in_n_elem; ++i)
371      {
372      out_mem[i] = eT(0);
373      }
374   
375    }
376  }
377
378
379
380//! @}
Note: See TracBrowser for help on using the repository browser.