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 //! @}