op_trimat_meat.hpp
Go to the documentation of this file.
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 
17 
18 
19 
20 template<typename eT>
21 inline
22 void
23 op_trimat::fill_zeros(Mat<eT>& out, const bool upper)
24  {
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
59  {
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
109  {
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
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  {
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
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  {
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 
arma_hot static arma_inline void copy(eT *dest, const eT *src, const uword n_elem)
arma_inline const T1 & conj(const Base< typename T1::pod_type, T1 > &A)
Definition: fn_elem.hpp:430
const uword n_rows
number of rows in the matrix (read-only)
Definition: Mat_bones.hpp:29
arma_aligned const T1 & m
storage of reference to the operand (eg. a matrix)
Definition: Op_bones.hpp:45
arma_inline arma_warn_unused eT * colptr(const uword in_col)
returns a pointer to array of eTs for a specified column; no bounds check
Definition: Mat_meat.hpp:4000
u32 uword
Definition: typedef.hpp:85
#define arma_debug_check
Definition: debug.hpp:1084
const Mat< eT > M
Definition: unwrap.hpp:32
static arma_hot void inplace_set(eT *dest, const eT val, const uword n_elem)
arma_inline arma_warn_unused eT & at(const uword i)
linear element accessor (treats the matrix as a vector); no bounds check.
Definition: Mat_meat.hpp:3692
arma_inline arma_warn_unused bool is_square() const
returns true if the object has the same number of non-zero rows and columnns
Definition: Mat_meat.hpp:3860
#define arma_ignore(variable)
void copy_size(const Mat< eT2 > &m)
change the matrix (without preserving data) to have the same dimensions as the given matrix ...
Definition: Mat_meat.hpp:4303
static void fill_zeros(Mat< eT > &A, const bool upper)
#define arma_extra_debug_sigprint
Definition: debug.hpp:1116
static void apply_htrans(Mat< eT > &out, const Mat< eT > &A, const bool upper, const typename arma_not_cx< eT >::result *junk=0)
Dense matrix class.
arma_aligned uword aux_uword_a
storage of auxiliary data, uword format
Definition: Op_bones.hpp:47
static void apply(Mat< typename T1::elem_type > &out, const Op< T1, op_trimat > &in)


armadillo_matrix
Author(s):
autogenerated on Fri Apr 16 2021 02:31:58