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 spop_reverse
20 //! @{
21
22
23
24 template<typename eT>
25 inline
26 void
apply_spmat(SpMat<eT> & out,const SpMat<eT> & X,const uword dim)27 spop_reverse::apply_spmat(SpMat<eT>& out, const SpMat<eT>& X, const uword dim)
28 {
29 arma_extra_debug_sigprint();
30
31 const uword X_n_rows = X.n_rows;
32 const uword X_n_cols = X.n_cols;
33
34 const uword X_n_rows_m1 = X_n_rows - 1;
35 const uword X_n_cols_m1 = X_n_cols - 1;
36
37 const uword N = X.n_nonzero;
38
39 if(N == uword(0))
40 {
41 out.zeros(X_n_rows, X_n_cols);
42 return;
43 }
44
45 umat locs(2, N, arma_nozeros_indicator());
46
47 uword* locs_mem = locs.memptr();
48
49 typename SpMat<eT>::const_iterator it = X.begin();
50
51 if(dim == 0)
52 {
53 for(uword i=0; i < N; ++i)
54 {
55 const uword row = it.row();
56 const uword col = it.col();
57
58 (*locs_mem) = X_n_rows_m1 - row; locs_mem++;
59 (*locs_mem) = col; locs_mem++;
60
61 ++it;
62 }
63 }
64 else
65 if(dim == 1)
66 {
67 for(uword i=0; i < N; ++i)
68 {
69 const uword row = it.row();
70 const uword col = it.col();
71
72 (*locs_mem) = row; locs_mem++;
73 (*locs_mem) = X_n_cols_m1 - col; locs_mem++;
74
75 ++it;
76 }
77 }
78
79 const Col<eT> vals(const_cast<eT*>(X.values), N, false);
80
81 SpMat<eT> tmp(locs, vals, X_n_rows, X_n_cols, true, false);
82
83 out.steal_mem(tmp);
84 }
85
86
87
88 template<typename T1>
89 inline
90 void
apply_proxy(SpMat<typename T1::elem_type> & out,const T1 & X,const uword dim)91 spop_reverse::apply_proxy(SpMat<typename T1::elem_type>& out, const T1& X, const uword dim)
92 {
93 arma_extra_debug_sigprint();
94
95 typedef typename T1::elem_type eT;
96
97 const SpProxy<T1> P(X);
98
99 const uword P_n_rows = P.get_n_rows();
100 const uword P_n_cols = P.get_n_cols();
101
102 const uword P_n_rows_m1 = P_n_rows - 1;
103 const uword P_n_cols_m1 = P_n_cols - 1;
104
105 const uword N = P.get_n_nonzero();
106
107 if(N == uword(0))
108 {
109 out.zeros(P_n_rows, P_n_cols);
110 return;
111 }
112
113 umat locs(2, N, arma_nozeros_indicator());
114 Col<eT> vals( N, arma_nozeros_indicator());
115
116 uword* locs_mem = locs.memptr();
117 eT* vals_mem = vals.memptr();
118
119 typename SpProxy<T1>::const_iterator_type it = P.begin();
120
121 if(dim == 0)
122 {
123 for(uword i=0; i < N; ++i)
124 {
125 const uword row = it.row();
126 const uword col = it.col();
127
128 (*locs_mem) = P_n_rows_m1 - row; locs_mem++;
129 (*locs_mem) = col; locs_mem++;
130
131 (*vals_mem) = (*it); vals_mem++;
132
133 ++it;
134 }
135 }
136 else
137 if(dim == 1)
138 {
139 for(uword i=0; i < N; ++i)
140 {
141 const uword row = it.row();
142 const uword col = it.col();
143
144 (*locs_mem) = row; locs_mem++;
145 (*locs_mem) = P_n_cols_m1 - col; locs_mem++;
146
147 (*vals_mem) = (*it); vals_mem++;
148
149 ++it;
150 }
151 }
152
153 SpMat<eT> tmp(locs, vals, P_n_rows, P_n_cols, true, false);
154
155 out.steal_mem(tmp);
156 }
157
158
159
160 template<typename T1>
161 inline
162 void
apply(SpMat<typename T1::elem_type> & out,const SpOp<T1,spop_reverse> & in)163 spop_reverse::apply(SpMat<typename T1::elem_type>& out, const SpOp<T1,spop_reverse>& in)
164 {
165 arma_extra_debug_sigprint();
166
167 const uword dim = in.aux_uword_a;
168
169 arma_debug_check( (dim > 1), "reverse(): parameter 'dim' must be 0 or 1" );
170
171 if(is_SpMat<T1>::value)
172 {
173 const unwrap_spmat<T1> tmp(in.m);
174
175 spop_reverse::apply_spmat(out, tmp.M, dim);
176 }
177 else
178 {
179 spop_reverse::apply_proxy(out, in.m, dim);
180 }
181 }
182
183
184
185 //! @}
186