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 glue_histc
20 //! @{
21
22
23 template<typename eT>
24 inline
25 void
apply_noalias(Mat<uword> & C,const Mat<eT> & A,const Mat<eT> & B,const uword dim)26 glue_histc::apply_noalias(Mat<uword>& C, const Mat<eT>& A, const Mat<eT>& B, const uword dim)
27 {
28 arma_extra_debug_sigprint();
29
30 arma_debug_check( ((B.is_vec() == false) && (B.is_empty() == false)), "histc(): parameter 'edges' must be a vector" );
31
32 const uword A_n_rows = A.n_rows;
33 const uword A_n_cols = A.n_cols;
34
35 const uword B_n_elem = B.n_elem;
36
37 if( B_n_elem == uword(0) ) { C.reset(); return; }
38
39 arma_debug_check
40 (
41 ((Col<eT>(const_cast<eT*>(B.memptr()), B_n_elem, false, false)).is_sorted("strictascend") == false),
42 "hist(): given 'edges' vector does not contain monotonically increasing values"
43 );
44
45 const eT* B_mem = B.memptr();
46 const uword B_n_elem_m1 = B_n_elem - 1;
47
48 if(dim == uword(0))
49 {
50 C.zeros(B_n_elem, A_n_cols);
51
52 for(uword col=0; col < A_n_cols; ++col)
53 {
54 const eT* A_coldata = A.colptr(col);
55 uword* C_coldata = C.colptr(col);
56
57 for(uword row=0; row < A_n_rows; ++row)
58 {
59 const eT x = A_coldata[row];
60
61 for(uword i=0; i < B_n_elem_m1; ++i)
62 {
63 if( (B_mem[i] <= x) && (x < B_mem[i+1]) ) { C_coldata[i]++; break; }
64 else if( B_mem[B_n_elem_m1] == x ) { C_coldata[B_n_elem_m1]++; break; } // for compatibility with Matlab
65 }
66 }
67 }
68 }
69 else
70 if(dim == uword(1))
71 {
72 C.zeros(A_n_rows, B_n_elem);
73
74 if(A.n_rows == 1)
75 {
76 const uword A_n_elem = A.n_elem;
77 const eT* A_mem = A.memptr();
78 uword* C_mem = C.memptr();
79
80 for(uword j=0; j < A_n_elem; ++j)
81 {
82 const eT x = A_mem[j];
83
84 for(uword i=0; i < B_n_elem_m1; ++i)
85 {
86 if( (B_mem[i] <= x) && (x < B_mem[i+1]) ) { C_mem[i]++; break; }
87 else if( B_mem[B_n_elem_m1] == x ) { C_mem[B_n_elem_m1]++; break; } // for compatibility with Matlab
88 }
89 }
90 }
91 else
92 {
93 for(uword row=0; row < A_n_rows; ++row)
94 for(uword col=0; col < A_n_cols; ++col)
95 {
96 const eT x = A.at(row,col);
97
98 for(uword i=0; i < B_n_elem_m1; ++i)
99 {
100 if( (B_mem[i] <= x) && (x < B_mem[i+1]) ) { C.at(row,i)++; break; }
101 else if( B_mem[B_n_elem_m1] == x ) { C.at(row,B_n_elem_m1)++; break; } // for compatibility with Matlab
102 }
103 }
104 }
105 }
106 }
107
108
109
110 template<typename T1, typename T2>
111 inline
112 void
apply(Mat<uword> & C,const mtGlue<uword,T1,T2,glue_histc> & expr)113 glue_histc::apply(Mat<uword>& C, const mtGlue<uword,T1,T2,glue_histc>& expr)
114 {
115 arma_extra_debug_sigprint();
116
117 const uword dim = expr.aux_uword;
118
119 arma_debug_check( (dim > 1), "histc(): parameter 'dim' must be 0 or 1" );
120
121 const quasi_unwrap<T1> UA(expr.A);
122 const quasi_unwrap<T2> UB(expr.B);
123
124 if(UA.is_alias(C) || UB.is_alias(C))
125 {
126 Mat<uword> tmp;
127
128 glue_histc::apply_noalias(tmp, UA.M, UB.M, dim);
129
130 C.steal_mem(tmp);
131 }
132 else
133 {
134 glue_histc::apply_noalias(C, UA.M, UB.M, dim);
135 }
136 }
137
138
139
140 template<typename T1, typename T2>
141 inline
142 void
apply(Mat<uword> & C,const mtGlue<uword,T1,T2,glue_histc_default> & expr)143 glue_histc_default::apply(Mat<uword>& C, const mtGlue<uword,T1,T2,glue_histc_default>& expr)
144 {
145 arma_extra_debug_sigprint();
146
147 const quasi_unwrap<T1> UA(expr.A);
148 const quasi_unwrap<T2> UB(expr.B);
149
150 const uword dim = (T1::is_xvec) ? uword(UA.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0);
151
152 if(UA.is_alias(C) || UB.is_alias(C))
153 {
154 Mat<uword> tmp;
155
156 glue_histc::apply_noalias(tmp, UA.M, UB.M, dim);
157
158 C.steal_mem(tmp);
159 }
160 else
161 {
162 glue_histc::apply_noalias(C, UA.M, UB.M, dim);
163 }
164 }
165
166
167 //! @}
168