fn_as_scalar.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 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12 
13 
16 
17 
18 
19 template<uword N>
21  {
22  template<typename T1>
23  inline static typename T1::elem_type apply(const T1& X);
24  };
25 
26 
27 
28 template<>
30  {
31  template<typename T1, typename T2>
32  inline static typename T1::elem_type apply(const Glue<T1,T2,glue_times>& X);
33  };
34 
35 
36 template<>
38  {
39  template<typename T1, typename T2, typename T3>
40  inline static typename T1::elem_type apply(const Glue< Glue<T1, T2, glue_times>, T3, glue_times>& X);
41  };
42 
43 
44 
45 template<uword N>
46 template<typename T1>
47 inline
48 typename T1::elem_type
50  {
52 
53  typedef typename T1::elem_type eT;
54 
55  const unwrap<T1> tmp(X);
56  const Mat<eT>& A = tmp.M;
57 
58  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
59 
60  return A.mem[0];
61  }
62 
63 
64 
65 template<typename T1, typename T2>
66 inline
67 typename T1::elem_type
69  {
71 
72  typedef typename T1::elem_type eT;
73 
74  // T1 must result in a matrix with one row
75  // T2 must result in a matrix with one column
76 
77  const partial_unwrap<T1> tmp1(X.A);
78  const partial_unwrap<T2> tmp2(X.B);
79 
80  const Mat<eT>& A = tmp1.M;
81  const Mat<eT>& B = tmp2.M;
82 
83  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
84  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
85 
86  const uword B_n_rows = (tmp2.do_trans == false) ? B.n_rows : B.n_cols;
87  const uword B_n_cols = (tmp2.do_trans == false) ? B.n_cols : B.n_rows;
88 
89  const eT val = tmp1.get_val() * tmp2.get_val();
90 
91  arma_debug_check( (A_n_rows != 1) || (B_n_cols != 1) || (A_n_cols != B_n_rows), "as_scalar(): incompatible dimensions" );
92 
93  return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem);
94  }
95 
96 
97 
98 template<typename T1, typename T2, typename T3>
99 inline
100 typename T1::elem_type
102  {
104 
105  typedef typename T1::elem_type eT;
106 
107  // T1 * T2 must result in a matrix with one row
108  // T3 must result in a matrix with one column
109 
110  typedef typename strip_inv <T2 >::stored_type T2_stripped_1;
111  typedef typename strip_diagmat<T2_stripped_1>::stored_type T2_stripped_2;
112 
113  const strip_inv <T2> strip1(X.A.B);
114  const strip_diagmat<T2_stripped_1> strip2(strip1.M);
115 
116  const bool tmp2_do_inv = strip1.do_inv;
117  const bool tmp2_do_diagmat = strip2.do_diagmat;
118 
119  if(tmp2_do_diagmat == false)
120  {
121  const Mat<eT> tmp(X);
122 
123  arma_debug_check( (tmp.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
124 
125  return tmp[0];
126  }
127  else
128  {
129  const partial_unwrap<T1> tmp1(X.A.A);
130  const partial_unwrap<T2_stripped_2> tmp2(strip2.M);
131  const partial_unwrap<T3> tmp3(X.B);
132 
133  const Mat<eT>& A = tmp1.M;
134  const Mat<eT>& B = tmp2.M;
135  const Mat<eT>& C = tmp3.M;
136 
137  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
138  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
139 
140  const bool B_is_vec = B.is_vec();
141 
142  const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
143  const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
144 
145  const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
146  const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
147 
148  const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
149 
151  (
152  (A_n_rows != 1) ||
153  (C_n_cols != 1) ||
154  (A_n_cols != B_n_rows) ||
155  (B_n_cols != C_n_rows)
156  ,
157  "as_scalar(): incompatible dimensions"
158  );
159 
160 
161  if(B_is_vec == true)
162  {
163  if(tmp2_do_inv == true)
164  {
165  return val * op_dotext::direct_rowvec_invdiagvec_colvec(A.mem, B, C.mem);
166  }
167  else
168  {
169  return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
170  }
171  }
172  else
173  {
174  if(tmp2_do_inv == true)
175  {
176  return val * op_dotext::direct_rowvec_invdiagmat_colvec(A.mem, B, C.mem);
177  }
178  else
179  {
180  return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
181  }
182  }
183  }
184  }
185 
186 
187 
188 template<typename T1>
189 inline
190 typename T1::elem_type
192  {
194 
195  typedef typename T1::elem_type eT;
196 
197  const unwrap<T1> tmp(X.get_ref());
198  const Mat<eT>& A = tmp.M;
199 
200  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
201 
202  return A.mem[0];
203  }
204 
205 
206 
207 template<typename T1, typename T2, typename T3>
208 inline
209 typename T1::elem_type
211  {
213 
214  typedef typename T1::elem_type eT;
215 
216  // T1 * T2 must result in a matrix with one row
217  // T3 must result in a matrix with one column
218 
219  typedef typename strip_diagmat<T2>::stored_type T2_stripped;
220 
221  const strip_diagmat<T2> strip(X.A.B);
222 
223  const partial_unwrap<T1> tmp1(X.A.A);
224  const partial_unwrap<T2_stripped> tmp2(strip.M);
225  const partial_unwrap<T3> tmp3(X.B);
226 
227  const Mat<eT>& A = tmp1.M;
228  const Mat<eT>& B = tmp2.M;
229  const Mat<eT>& C = tmp3.M;
230 
231 
232  const uword A_n_rows = (tmp1.do_trans == false) ? A.n_rows : A.n_cols;
233  const uword A_n_cols = (tmp1.do_trans == false) ? A.n_cols : A.n_rows;
234 
235  const bool B_is_vec = B.is_vec();
236 
237  const uword B_n_rows = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_rows : B.n_cols );
238  const uword B_n_cols = (B_is_vec == true) ? B.n_elem : ( (tmp2.do_trans == false) ? B.n_cols : B.n_rows );
239 
240  const uword C_n_rows = (tmp3.do_trans == false) ? C.n_rows : C.n_cols;
241  const uword C_n_cols = (tmp3.do_trans == false) ? C.n_cols : C.n_rows;
242 
243  const eT val = tmp1.get_val() * tmp2.get_val() * tmp3.get_val();
244 
246  (
247  (A_n_rows != 1) ||
248  (C_n_cols != 1) ||
249  (A_n_cols != B_n_rows) ||
250  (B_n_cols != C_n_rows)
251  ,
252  "as_scalar(): incompatible dimensions"
253  );
254 
255 
256  if(B_is_vec == true)
257  {
258  return val * op_dot::direct_dot(A.n_elem, A.mem, B.mem, C.mem);
259  }
260  else
261  {
262  return val * op_dotext::direct_rowvec_diagmat_colvec(A.mem, B, C.mem);
263  }
264  }
265 
266 
267 
268 template<typename T1, typename T2>
271 typename T1::elem_type
273  {
275  arma_ignore(junk);
276 
277  if(is_glue_times_diag<T1>::value == false)
278  {
279  const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
280 
281  arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
282 
284  }
285  else
286  {
287  return as_scalar_diag(X);
288  }
289  }
290 
291 
292 
293 template<typename T1>
294 inline
296 typename T1::elem_type
298  {
300 
301  typedef typename T1::elem_type eT;
302 
303  const unwrap<T1> tmp(X.get_ref());
304  const Mat<eT>& A = tmp.M;
305 
306  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
307 
308  return A.mem[0];
309  }
310 
311 
312 
313 template<typename T1>
316 typename T1::elem_type
318  {
320 
321  return -(as_scalar(X.P.Q));
322  }
323 
324 
325 
326 template<typename T1>
327 inline
329 typename T1::elem_type
331  {
333 
334  typedef typename T1::elem_type eT;
335 
336  const unwrap_cube<T1> tmp(X.get_ref());
337  const Cube<eT>& A = tmp.M;
338 
339  arma_debug_check( (A.n_elem != 1), "as_scalar(): expression doesn't evaluate to exactly one element" );
340 
341  return A.mem[0];
342  }
343 
344 
345 
346 template<typename T>
349 const typename arma_scalar_only<T>::result &
350 as_scalar(const T& x)
351  {
352  return x;
353  }
354 
355 
356 
arma_inline arma_warn_unused bool is_vec() const
returns true if the object can be interpreted as a column or row vector
Definition: Mat_meat.hpp:3824
Class which implements the immediate multiplication of two or more matrices.
static eT direct_rowvec_invdiagvec_colvec(const eT *A_mem, const Mat< eT > &B, const eT *C_mem)
arma_inline const derived & get_ref() const
Definition: Base_meat.hpp:22
T1 stored_type
Definition: strip.hpp:22
arma_hot static arma_pure arma_float_only< eT >::result direct_dot(const uword n_elem, const eT *const A, const eT *const B)
arma_aligned const Proxy< T1 > P
Definition: eOp_bones.hpp:31
const uword n_cols
number of columns in the matrix (read-only)
Definition: Mat_bones.hpp:30
eT get_val() const
Definition: unwrap.hpp:407
static eT direct_rowvec_invdiagmat_colvec(const eT *A_mem, const Mat< eT > &B, const eT *C_mem)
const uword n_elem
number of elements in the matrix (read-only)
Definition: Mat_bones.hpp:31
const uword n_rows
number of rows in the matrix (read-only)
Definition: Mat_bones.hpp:29
#define arma_extra_debug_print
Definition: debug.hpp:1118
u32 uword
Definition: typedef.hpp:85
static const bool do_diagmat
Definition: strip.hpp:30
static eT direct_rowvec_diagmat_colvec(const eT *A_mem, const Mat< eT > &B, const eT *C_mem)
#define arma_debug_check
Definition: debug.hpp:1084
const T1 & A
first operand
Definition: Glue_bones.hpp:44
static const bool do_trans
Definition: unwrap.hpp:410
const Mat< eT > M
Definition: unwrap.hpp:32
T1::elem_type as_scalar_diag(const Base< typename T1::elem_type, T1 > &X)
static const bool do_inv
Definition: strip.hpp:66
#define arma_ignore(variable)
Dense cube class.
Definition: Cube_bones.hpp:30
const T2 & B
second operand
Definition: Glue_bones.hpp:45
arma_inline arma_warn_unused T1::elem_type as_scalar(const Glue< T1, T2, glue_times > &X, const typename arma_not_cx< typename T1::elem_type >::result *junk=0)
const T1 & M
Definition: strip.hpp:32
#define arma_extra_debug_sigprint
Definition: debug.hpp:1116
const Mat< eT > M
Definition: unwrap.hpp:413
Analog of the Base class, intended for cubes.
#define arma_warn_unused
Dense matrix class.
#define arma_inline
arma_inline const derived & get_ref() const
arma_aligned const eT *const mem
pointer to the memory used by the matrix (memory is read-only)
Definition: Mat_bones.hpp:40
T1 stored_type
Definition: strip.hpp:58
s32 sword
Definition: typedef.hpp:86
Template metaprogram depth_lhs calculates the number of Glue<Tx,Ty, glue_type> instances on the left ...
const T1 & M
Definition: strip.hpp:68
static T1::elem_type apply(const T1 &X)


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