1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup op_flip
20 //! @{
21 
22 
23 
24 template<typename T1>
25 inline
26 void
apply(Mat<typename T1::elem_type> & out,const Op<T1,op_flipud> & in)27 op_flipud::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in)
28   {
29   arma_extra_debug_sigprint();
30 
31   const Proxy<T1> P(in.m);
32 
33   if(is_Mat<typename Proxy<T1>::stored_type>::value || P.is_alias(out))
34     {
35     const unwrap<typename Proxy<T1>::stored_type> U(P.Q);
36 
37     op_flipud::apply_direct(out, U.M);
38     }
39   else
40     {
41     op_flipud::apply_proxy_noalias(out, P);
42     }
43   }
44 
45 
46 
47 template<typename eT>
48 inline
49 void
apply_direct(Mat<eT> & out,const Mat<eT> & X)50 op_flipud::apply_direct(Mat<eT>& out, const Mat<eT>& X)
51   {
52   arma_extra_debug_sigprint();
53 
54   const uword X_n_rows = X.n_rows;
55   const uword X_n_cols = X.n_cols;
56 
57   const uword X_n_rows_m1 = X_n_rows - 1;
58 
59   if(&out != &X)
60     {
61     out.set_size(X_n_rows, X_n_cols);
62 
63     if(X_n_cols == 1)
64       {
65       const eT*   X_mem =   X.memptr();
66             eT* out_mem = out.memptr();
67 
68       for(uword row=0; row < X_n_rows; ++row)
69         {
70         out_mem[X_n_rows_m1 - row] = X_mem[row];
71         }
72       }
73     else
74       {
75       for(uword col=0; col < X_n_cols; ++col)
76         {
77         const eT*   X_colmem =   X.colptr(col);
78               eT* out_colmem = out.colptr(col);
79 
80         for(uword row=0; row < X_n_rows; ++row)
81           {
82           out_colmem[X_n_rows_m1 - row] = X_colmem[row];
83           }
84         }
85       }
86     }
87   else  // in-place operation
88     {
89     const uword N = X_n_rows / 2;
90 
91     if(X_n_cols == 1)
92       {
93       eT* out_mem = out.memptr();
94 
95       for(uword row=0; row < N; ++row)
96         {
97         std::swap(out_mem[X_n_rows_m1 - row], out_mem[row]);
98         }
99       }
100     else
101       {
102       for(uword col=0; col < X_n_cols; ++col)
103         {
104         eT* out_colmem = out.colptr(col);
105 
106         for(uword row=0; row < N; ++row)
107           {
108           std::swap(out_colmem[X_n_rows_m1 - row], out_colmem[row]);
109           }
110         }
111       }
112     }
113   }
114 
115 
116 
117 template<typename T1>
118 inline
119 void
apply_proxy_noalias(Mat<typename T1::elem_type> & out,const Proxy<T1> & P)120 op_flipud::apply_proxy_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
121   {
122   arma_extra_debug_sigprint();
123 
124   typedef typename T1::elem_type eT;
125 
126   const uword P_n_rows = P.get_n_rows();
127   const uword P_n_cols = P.get_n_cols();
128 
129   const uword P_n_rows_m1 = P_n_rows - 1;
130 
131   out.set_size(P_n_rows, P_n_cols);
132 
133   if( ((T1::is_col) || (P_n_cols == 1)) && (Proxy<T1>::use_at == false) )
134     {
135     eT* out_mem = out.memptr();
136 
137     const typename Proxy<T1>::ea_type P_ea = P.get_ea();
138 
139     for(uword row=0; row < P_n_rows; ++row)
140       {
141       out_mem[P_n_rows_m1 - row] = P_ea[row];
142       }
143     }
144   else
145     {
146     for(uword col=0; col < P_n_cols; ++col)
147       {
148       eT* out_colmem = out.colptr(col);
149 
150       for(uword row=0; row < P_n_rows; ++row)
151         {
152         out_colmem[P_n_rows_m1 - row] = P.at(row, col);
153         }
154       }
155     }
156   }
157 
158 
159 
160 //
161 
162 
163 
164 template<typename T1>
165 inline
166 void
apply(Mat<typename T1::elem_type> & out,const Op<T1,op_fliplr> & in)167 op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
168   {
169   arma_extra_debug_sigprint();
170 
171   const Proxy<T1> P(in.m);
172 
173   if(is_Mat<typename Proxy<T1>::stored_type>::value || P.is_alias(out))
174     {
175     const unwrap<typename Proxy<T1>::stored_type> U(P.Q);
176 
177     op_fliplr::apply_direct(out, U.M);
178     }
179   else
180     {
181     op_fliplr::apply_proxy_noalias(out, P);
182     }
183   }
184 
185 
186 
187 template<typename eT>
188 inline
189 void
apply_direct(Mat<eT> & out,const Mat<eT> & X)190 op_fliplr::apply_direct(Mat<eT>& out, const Mat<eT>& X)
191   {
192   arma_extra_debug_sigprint();
193 
194   const uword X_n_rows = X.n_rows;
195   const uword X_n_cols = X.n_cols;
196 
197   const uword X_n_cols_m1 = X_n_cols - 1;
198 
199   if(&out != &X)
200     {
201     out.set_size(X_n_rows, X_n_cols);
202 
203     if(X_n_rows == 1)
204       {
205       const eT*   X_mem =   X.memptr();
206             eT* out_mem = out.memptr();
207 
208       for(uword col=0; col < X_n_cols; ++col)
209         {
210         out_mem[X_n_cols_m1 - col] = X_mem[col];
211         }
212       }
213     else
214       {
215       for(uword col=0; col < X_n_cols; ++col)
216         {
217         out.col(X_n_cols_m1 - col) = X.col(col);
218         }
219       }
220     }
221   else  // in-place operation
222     {
223     const uword N = X_n_cols / 2;
224 
225     if(X_n_rows == 1)
226       {
227       eT* out_mem = out.memptr();
228 
229       for(uword col=0; col < N; ++col)
230         {
231         std::swap(out_mem[X_n_cols_m1 - col], out_mem[col]);
232         }
233       }
234     else
235       {
236       for(uword col=0; col < N; ++col)
237         {
238         out.swap_cols(X_n_cols_m1 - col, col);
239         }
240       }
241     }
242   }
243 
244 
245 
246 template<typename T1>
247 inline
248 void
apply_proxy_noalias(Mat<typename T1::elem_type> & out,const Proxy<T1> & P)249 op_fliplr::apply_proxy_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
250   {
251   arma_extra_debug_sigprint();
252 
253   typedef typename T1::elem_type eT;
254 
255   const uword P_n_rows = P.get_n_rows();
256   const uword P_n_cols = P.get_n_cols();
257 
258   const uword P_n_cols_m1 = P_n_cols - 1;
259 
260   out.set_size(P_n_rows, P_n_cols);
261 
262   if( ((T1::is_row) || (P_n_rows == 1)) && (Proxy<T1>::use_at == false) )
263     {
264     eT* out_mem = out.memptr();
265 
266     const typename Proxy<T1>::ea_type P_ea = P.get_ea();
267 
268     for(uword col=0; col < P_n_cols; ++col)
269       {
270       out_mem[P_n_cols_m1 - col] = P_ea[col];
271       }
272     }
273   else
274     {
275     for(uword col=0; col < P_n_cols; ++col)
276       {
277       eT* out_colmem = out.colptr(P_n_cols_m1 - col);
278 
279       for(uword row=0; row < P_n_rows; ++row)
280         {
281         out_colmem[row] = P.at(row,col);
282         }
283       }
284     }
285   }
286 
287 
288 
289 //! @}
290