1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17
18
19 //! \addtogroup op_cumprod
20 //! @{
21
22
23
24 template<typename eT>
25 inline
26 void
apply_noalias(Mat<eT> & out,const Mat<eT> & X,const uword dim)27 op_cumprod::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim)
28 {
29 arma_extra_debug_sigprint();
30
31 uword n_rows = X.n_rows;
32 uword n_cols = X.n_cols;
33
34 out.set_size(n_rows,n_cols);
35
36 if(out.n_elem == 0) { return; }
37
38 if(dim == 0)
39 {
40 if(n_cols == 1)
41 {
42 const eT* X_mem = X.memptr();
43 eT* out_mem = out.memptr();
44
45 eT acc = eT(1);
46
47 for(uword row=0; row < n_rows; ++row)
48 {
49 acc *= X_mem[row];
50
51 out_mem[row] = acc;
52 }
53 }
54 else
55 {
56 for(uword col=0; col < n_cols; ++col)
57 {
58 const eT* X_colmem = X.colptr(col);
59 eT* out_colmem = out.colptr(col);
60
61 eT acc = eT(1);
62
63 for(uword row=0; row < n_rows; ++row)
64 {
65 acc *= X_colmem[row];
66
67 out_colmem[row] = acc;
68 }
69 }
70 }
71 }
72 else
73 if(dim == 1)
74 {
75 if(n_rows == 1)
76 {
77 const eT* X_mem = X.memptr();
78 eT* out_mem = out.memptr();
79
80 eT acc = eT(1);
81
82 for(uword col=0; col < n_cols; ++col)
83 {
84 acc *= X_mem[col];
85
86 out_mem[col] = acc;
87 }
88 }
89 else
90 {
91 if(n_cols > 0)
92 {
93 arrayops::copy( out.colptr(0), X.colptr(0), n_rows );
94
95 for(uword col=1; col < n_cols; ++col)
96 {
97 const eT* out_colmem_prev = out.colptr(col-1);
98 eT* out_colmem = out.colptr(col );
99 const eT* X_colmem = X.colptr(col );
100
101 for(uword row=0; row < n_rows; ++row)
102 {
103 out_colmem[row] = out_colmem_prev[row] * X_colmem[row];
104 }
105 }
106 }
107 }
108 }
109 }
110
111
112
113 template<typename T1>
114 inline
115 void
apply(Mat<typename T1::elem_type> & out,const Op<T1,op_cumprod> & in)116 op_cumprod::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumprod>& in)
117 {
118 arma_extra_debug_sigprint();
119
120 typedef typename T1::elem_type eT;
121
122 const uword dim = in.aux_uword_a;
123
124 arma_debug_check( (dim > 1), "cumprod(): parameter 'dim' must be 0 or 1" );
125
126 const quasi_unwrap<T1> U(in.m);
127
128 if(U.is_alias(out))
129 {
130 Mat<eT> tmp;
131
132 op_cumprod::apply_noalias(tmp, U.M, dim);
133
134 out.steal_mem(tmp);
135 }
136 else
137 {
138 op_cumprod::apply_noalias(out, U.M, dim);
139 }
140 }
141
142
143
144 template<typename T1>
145 inline
146 void
apply(Mat<typename T1::elem_type> & out,const Op<T1,op_cumprod_vec> & in)147 op_cumprod_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cumprod_vec>& in)
148 {
149 arma_extra_debug_sigprint();
150
151 typedef typename T1::elem_type eT;
152
153 const quasi_unwrap<T1> U(in.m);
154
155 const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0);
156
157 if(U.is_alias(out))
158 {
159 Mat<eT> tmp;
160
161 op_cumprod::apply_noalias(tmp, U.M, dim);
162
163 out.steal_mem(tmp);
164 }
165 else
166 {
167 op_cumprod::apply_noalias(out, U.M, dim);
168 }
169 }
170
171
172
173 //! @}
174
175