1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
// Copyright 2008-2016 National ICT Australia (NICTA)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
//! \addtogroup glue_times
//! @{
//! \brief
//! Template metaprogram depth_lhs
//! calculates the number of Glue<Tx,Ty, glue_type> instances on the left hand side argument of Glue<Tx,Ty, glue_type>
//! ie. it recursively expands each Tx, until the type of Tx is not "Glue<..,.., glue_type>" (i.e the "glue_type" changes)
template<typename glue_type, typename T1>
struct depth_lhs
{
static constexpr uword num = 0;
};
template<typename glue_type, typename T1, typename T2>
struct depth_lhs< glue_type, Glue<T1,T2,glue_type> >
{
static constexpr uword num = 1 + depth_lhs<glue_type, T1>::num;
};
template<bool do_inv_detect>
struct glue_times_redirect2_helper
{
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
};
template<>
struct glue_times_redirect2_helper<true>
{
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
};
template<bool do_inv_detect>
struct glue_times_redirect3_helper
{
template<typename T1, typename T2, typename T3>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>,T3,glue_times>& X);
};
template<>
struct glue_times_redirect3_helper<true>
{
template<typename T1, typename T2, typename T3>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>,T3,glue_times>& X);
};
template<uword N>
struct glue_times_redirect
{
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
};
template<>
struct glue_times_redirect<2>
{
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
};
template<>
struct glue_times_redirect<3>
{
template<typename T1, typename T2, typename T3>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>,T3,glue_times>& X);
};
template<>
struct glue_times_redirect<4>
{
template<typename T1, typename T2, typename T3, typename T4>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X);
};
//! Class which implements the immediate multiplication of two or more matrices
class glue_times
{
public:
template<typename T1, typename T2>
struct traits
{
static constexpr bool is_row = T1::is_row;
static constexpr bool is_col = T2::is_col;
static constexpr bool is_xvec = false;
};
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X);
template<typename T1>
arma_hot inline static void apply_inplace(Mat<typename T1::elem_type>& out, const T1& X);
template<typename T1, typename T2>
arma_hot inline static void apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign);
//
template<typename eT, const bool do_trans_A, const bool do_trans_B, typename TA, typename TB>
arma_inline static uword mul_storage_cost(const TA& A, const TB& B);
template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_scalar_times, typename TA, typename TB>
arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const eT val);
template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_scalar_times, typename TA, typename TB, typename TC>
arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const TC& C, const eT val);
template<typename eT, const bool do_trans_A, const bool do_trans_B, const bool do_trans_C, const bool do_trans_D, const bool do_scalar_times, typename TA, typename TB, typename TC, typename TD>
arma_hot inline static void apply(Mat<eT>& out, const TA& A, const TB& B, const TC& C, const TD& D, const eT val);
};
class glue_times_diag
{
public:
template<typename T1, typename T2>
struct traits
{
static constexpr bool is_row = T1::is_row;
static constexpr bool is_col = T2::is_col;
static constexpr bool is_xvec = false;
};
template<typename T1, typename T2>
arma_hot inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X);
};
//! @}
|