Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-2.4.4/include/armadillo_bits/op_trimat_meat.hpp @ 0:8b6102e2a9b0
Armadillo Library
author | maxzanoni76 <max.zanoni@eecs.qmul.ac.uk> |
---|---|
date | Wed, 11 Apr 2012 09:27:06 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:8b6102e2a9b0 |
---|---|
1 // Copyright (C) 2010-2011 NICTA (www.nicta.com.au) | |
2 // Copyright (C) 2010-2011 Conrad Sanderson | |
3 // Copyright (C) 2011 Ryan Curtin | |
4 // | |
5 // This file is part of the Armadillo C++ library. | |
6 // It is provided without any warranty of fitness | |
7 // for any purpose. You can redistribute this file | |
8 // and/or modify it under the terms of the GNU | |
9 // Lesser General Public License (LGPL) as published | |
10 // by the Free Software Foundation, either version 3 | |
11 // of the License or (at your option) any later version. | |
12 // (see http://www.opensource.org/licenses for more info) | |
13 | |
14 | |
15 //! \addtogroup op_trimat | |
16 //! @{ | |
17 | |
18 | |
19 | |
20 template<typename eT> | |
21 inline | |
22 void | |
23 op_trimat::fill_zeros(Mat<eT>& out, const bool upper) | |
24 { | |
25 arma_extra_debug_sigprint(); | |
26 | |
27 const uword N = out.n_rows; | |
28 | |
29 if(upper) | |
30 { | |
31 // upper triangular: set all elements below the diagonal to zero | |
32 | |
33 for(uword i=0; i<N; ++i) | |
34 { | |
35 eT* data = out.colptr(i); | |
36 | |
37 arrayops::inplace_set( &data[i+1], eT(0), (N-(i+1)) ); | |
38 } | |
39 } | |
40 else | |
41 { | |
42 // lower triangular: set all elements above the diagonal to zero | |
43 | |
44 for(uword i=1; i<N; ++i) | |
45 { | |
46 eT* data = out.colptr(i); | |
47 | |
48 arrayops::inplace_set( data, eT(0), i ); | |
49 } | |
50 } | |
51 } | |
52 | |
53 | |
54 | |
55 template<typename T1> | |
56 inline | |
57 void | |
58 op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in) | |
59 { | |
60 arma_extra_debug_sigprint(); | |
61 | |
62 typedef typename T1::elem_type eT; | |
63 | |
64 const unwrap<T1> tmp(in.m); | |
65 const Mat<eT>& A = tmp.M; | |
66 | |
67 arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" ); | |
68 | |
69 const uword N = A.n_rows; | |
70 const bool upper = (in.aux_uword_a == 0); | |
71 | |
72 if(&out != &A) | |
73 { | |
74 out.copy_size(A); | |
75 | |
76 if(upper) | |
77 { | |
78 // upper triangular: copy the diagonal and the elements above the diagonal | |
79 for(uword i=0; i<N; ++i) | |
80 { | |
81 const eT* A_data = A.colptr(i); | |
82 eT* out_data = out.colptr(i); | |
83 | |
84 arrayops::copy( out_data, A_data, i+1 ); | |
85 } | |
86 } | |
87 else | |
88 { | |
89 // lower triangular: copy the diagonal and the elements below the diagonal | |
90 for(uword i=0; i<N; ++i) | |
91 { | |
92 const eT* A_data = A.colptr(i); | |
93 eT* out_data = out.colptr(i); | |
94 | |
95 arrayops::copy( &out_data[i], &A_data[i], N-i ); | |
96 } | |
97 } | |
98 } | |
99 | |
100 op_trimat::fill_zeros(out, upper); | |
101 } | |
102 | |
103 | |
104 | |
105 template<typename T1> | |
106 inline | |
107 void | |
108 op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<Op<T1, op_htrans>, op_trimat>& in) | |
109 { | |
110 arma_extra_debug_sigprint(); | |
111 | |
112 typedef typename T1::elem_type eT; | |
113 | |
114 const unwrap<T1> tmp(in.m.m); | |
115 const Mat<eT>& A = tmp.M; | |
116 | |
117 const bool upper = (in.aux_uword_a == 0); | |
118 | |
119 op_trimat::apply_htrans(out, A, upper); | |
120 } | |
121 | |
122 | |
123 | |
124 template<typename eT> | |
125 inline | |
126 void | |
127 op_trimat::apply_htrans | |
128 ( | |
129 Mat<eT>& out, | |
130 const Mat<eT>& A, | |
131 const bool upper, | |
132 const typename arma_not_cx<eT>::result* junk | |
133 ) | |
134 { | |
135 arma_extra_debug_sigprint(); | |
136 arma_ignore(junk); | |
137 | |
138 // This specialisation is for trimatl(trans(X)) = trans(trimatu(X)) and also | |
139 // trimatu(trans(X)) = trans(trimatl(X)). We want to avoid the creation of an | |
140 // extra temporary. | |
141 | |
142 // It doesn't matter if the input and output matrices are the same; we will | |
143 // pull data from the upper or lower triangular to the lower or upper | |
144 // triangular (respectively) and then set the rest to 0, so overwriting issues | |
145 // aren't present. | |
146 | |
147 arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" ); | |
148 | |
149 const uword N = A.n_rows; | |
150 | |
151 if(&out != &A) | |
152 { | |
153 out.copy_size(A); | |
154 } | |
155 | |
156 // We can't really get away with any array copy operations here, | |
157 // unfortunately... | |
158 | |
159 if(upper) | |
160 { | |
161 // Upper triangular: but since we're transposing, we're taking the lower | |
162 // triangular and putting it in the upper half. | |
163 for(uword row = 0; row < N; ++row) | |
164 { | |
165 eT* out_colptr = out.colptr(row); | |
166 | |
167 for(uword col = 0; col <= row; ++col) | |
168 { | |
169 //out.at(col, row) = A.at(row, col); | |
170 out_colptr[col] = A.at(row, col); | |
171 } | |
172 } | |
173 } | |
174 else | |
175 { | |
176 // Lower triangular: but since we're transposing, we're taking the upper | |
177 // triangular and putting it in the lower half. | |
178 for(uword row = 0; row < N; ++row) | |
179 { | |
180 for(uword col = row; col < N; ++col) | |
181 { | |
182 out.at(col, row) = A.at(row, col); | |
183 } | |
184 } | |
185 } | |
186 | |
187 op_trimat::fill_zeros(out, upper); | |
188 } | |
189 | |
190 | |
191 | |
192 template<typename eT> | |
193 inline | |
194 void | |
195 op_trimat::apply_htrans | |
196 ( | |
197 Mat<eT>& out, | |
198 const Mat<eT>& A, | |
199 const bool upper, | |
200 const typename arma_cx_only<eT>::result* junk | |
201 ) | |
202 { | |
203 arma_extra_debug_sigprint(); | |
204 arma_ignore(junk); | |
205 | |
206 arma_debug_check( (A.is_square() == false), "trimatu()/trimatl(): given matrix must be square" ); | |
207 | |
208 const uword N = A.n_rows; | |
209 | |
210 if(&out != &A) | |
211 { | |
212 out.copy_size(A); | |
213 } | |
214 | |
215 if(upper) | |
216 { | |
217 // Upper triangular: but since we're transposing, we're taking the lower | |
218 // triangular and putting it in the upper half. | |
219 for(uword row = 0; row < N; ++row) | |
220 { | |
221 eT* out_colptr = out.colptr(row); | |
222 | |
223 for(uword col = 0; col <= row; ++col) | |
224 { | |
225 //out.at(col, row) = std::conj( A.at(row, col) ); | |
226 out_colptr[col] = std::conj( A.at(row, col) ); | |
227 } | |
228 } | |
229 } | |
230 else | |
231 { | |
232 // Lower triangular: but since we're transposing, we're taking the upper | |
233 // triangular and putting it in the lower half. | |
234 for(uword row = 0; row < N; ++row) | |
235 { | |
236 for(uword col = row; col < N; ++col) | |
237 { | |
238 out.at(col, row) = std::conj( A.at(row, col) ); | |
239 } | |
240 } | |
241 } | |
242 | |
243 op_trimat::fill_zeros(out, upper); | |
244 } | |
245 | |
246 | |
247 | |
248 //! @} |