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