Chris@49
|
1 // Copyright (C) 2012-2013 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2012-2013 Conrad Sanderson
|
Chris@49
|
3 //
|
Chris@49
|
4 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
7
|
Chris@49
|
8
|
Chris@49
|
9
|
Chris@49
|
10 template<typename T1, typename T2>
|
Chris@49
|
11 inline
|
Chris@49
|
12 void
|
Chris@49
|
13 glue_hist::apply(Mat<uword>& out, const mtGlue<uword,T1,T2,glue_hist>& in)
|
Chris@49
|
14 {
|
Chris@49
|
15 arma_extra_debug_sigprint();
|
Chris@49
|
16
|
Chris@49
|
17 typedef typename T1::elem_type eT;
|
Chris@49
|
18
|
Chris@49
|
19 const uword dim = in.aux_uword;
|
Chris@49
|
20
|
Chris@49
|
21 const unwrap_check_mixed<T1> tmp1(in.A, out);
|
Chris@49
|
22 const unwrap_check_mixed<T2> tmp2(in.B, out);
|
Chris@49
|
23
|
Chris@49
|
24 const Mat<eT>& X = tmp1.M;
|
Chris@49
|
25 const Mat<eT>& C = tmp2.M;
|
Chris@49
|
26
|
Chris@49
|
27
|
Chris@49
|
28 arma_debug_check
|
Chris@49
|
29 (
|
Chris@49
|
30 ((C.is_vec() == false) && (C.is_empty() == false)),
|
Chris@49
|
31 "hist(): parameter 'centers' must be a vector"
|
Chris@49
|
32 );
|
Chris@49
|
33
|
Chris@49
|
34 arma_debug_check
|
Chris@49
|
35 (
|
Chris@49
|
36 (dim > 1),
|
Chris@49
|
37 "hist(): parameter 'dim' must be 0 or 1"
|
Chris@49
|
38 );
|
Chris@49
|
39
|
Chris@49
|
40 const uword X_n_rows = X.n_rows;
|
Chris@49
|
41 const uword X_n_cols = X.n_cols;
|
Chris@49
|
42 const uword X_n_elem = X.n_elem;
|
Chris@49
|
43
|
Chris@49
|
44 const uword C_n_elem = C.n_elem;
|
Chris@49
|
45
|
Chris@49
|
46 if( C_n_elem == 0 )
|
Chris@49
|
47 {
|
Chris@49
|
48 out.reset();
|
Chris@49
|
49 return;
|
Chris@49
|
50 }
|
Chris@49
|
51
|
Chris@49
|
52 // for vectors we are currently ignoring the "dim" parameter
|
Chris@49
|
53
|
Chris@49
|
54 uword out_n_rows = 0;
|
Chris@49
|
55 uword out_n_cols = 0;
|
Chris@49
|
56
|
Chris@49
|
57 if(X.is_vec())
|
Chris@49
|
58 {
|
Chris@49
|
59 if(X.is_rowvec())
|
Chris@49
|
60 {
|
Chris@49
|
61 out_n_rows = 1;
|
Chris@49
|
62 out_n_cols = C_n_elem;
|
Chris@49
|
63 }
|
Chris@49
|
64 else
|
Chris@49
|
65 if(X.is_colvec())
|
Chris@49
|
66 {
|
Chris@49
|
67 out_n_rows = C_n_elem;
|
Chris@49
|
68 out_n_cols = 1;
|
Chris@49
|
69 }
|
Chris@49
|
70 }
|
Chris@49
|
71 else
|
Chris@49
|
72 {
|
Chris@49
|
73 if(dim == 0)
|
Chris@49
|
74 {
|
Chris@49
|
75 out_n_rows = C_n_elem;
|
Chris@49
|
76 out_n_cols = X_n_cols;
|
Chris@49
|
77 }
|
Chris@49
|
78 else
|
Chris@49
|
79 if(dim == 1)
|
Chris@49
|
80 {
|
Chris@49
|
81 out_n_rows = X_n_rows;
|
Chris@49
|
82 out_n_cols = C_n_elem;
|
Chris@49
|
83 }
|
Chris@49
|
84 }
|
Chris@49
|
85
|
Chris@49
|
86 out.zeros(out_n_rows, out_n_cols);
|
Chris@49
|
87
|
Chris@49
|
88
|
Chris@49
|
89 const eT* C_mem = C.memptr();
|
Chris@49
|
90 const eT center_0 = C_mem[0];
|
Chris@49
|
91
|
Chris@49
|
92 if(X.is_vec())
|
Chris@49
|
93 {
|
Chris@49
|
94 const eT* X_mem = X.memptr();
|
Chris@49
|
95 uword* out_mem = out.memptr();
|
Chris@49
|
96
|
Chris@49
|
97 for(uword i=0; i < X_n_elem; ++i)
|
Chris@49
|
98 {
|
Chris@49
|
99 const eT val = X_mem[i];
|
Chris@49
|
100
|
Chris@49
|
101 if(is_finite(val))
|
Chris@49
|
102 {
|
Chris@49
|
103 eT opt_dist = (val >= center_0) ? (val - center_0) : (center_0 - val);
|
Chris@49
|
104 uword opt_index = 0;
|
Chris@49
|
105
|
Chris@49
|
106 for(uword j=1; j < C_n_elem; ++j)
|
Chris@49
|
107 {
|
Chris@49
|
108 const eT center = C_mem[j];
|
Chris@49
|
109 const eT dist = (val >= center) ? (val - center) : (center - val);
|
Chris@49
|
110
|
Chris@49
|
111 if(dist < opt_dist)
|
Chris@49
|
112 {
|
Chris@49
|
113 opt_dist = dist;
|
Chris@49
|
114 opt_index = j;
|
Chris@49
|
115 }
|
Chris@49
|
116 else
|
Chris@49
|
117 {
|
Chris@49
|
118 break;
|
Chris@49
|
119 }
|
Chris@49
|
120 }
|
Chris@49
|
121
|
Chris@49
|
122 out_mem[opt_index]++;
|
Chris@49
|
123 }
|
Chris@49
|
124 else
|
Chris@49
|
125 {
|
Chris@49
|
126 // -inf
|
Chris@49
|
127 if(val < eT(0)) { out_mem[0]++; }
|
Chris@49
|
128
|
Chris@49
|
129 // +inf
|
Chris@49
|
130 if(val > eT(0)) { out_mem[C_n_elem-1]++; }
|
Chris@49
|
131
|
Chris@49
|
132 // ignore NaN
|
Chris@49
|
133 }
|
Chris@49
|
134 }
|
Chris@49
|
135 }
|
Chris@49
|
136 else
|
Chris@49
|
137 {
|
Chris@49
|
138 if(dim == 0)
|
Chris@49
|
139 {
|
Chris@49
|
140 for(uword col=0; col < X_n_cols; ++col)
|
Chris@49
|
141 {
|
Chris@49
|
142 const eT* X_coldata = X.colptr(col);
|
Chris@49
|
143 uword* out_coldata = out.colptr(col);
|
Chris@49
|
144
|
Chris@49
|
145 for(uword row=0; row < X_n_rows; ++row)
|
Chris@49
|
146 {
|
Chris@49
|
147 const eT val = X_coldata[row];
|
Chris@49
|
148
|
Chris@49
|
149 if(arma_isfinite(val))
|
Chris@49
|
150 {
|
Chris@49
|
151 eT opt_dist = (center_0 >= val) ? (center_0 - val) : (val - center_0);
|
Chris@49
|
152 uword opt_index = 0;
|
Chris@49
|
153
|
Chris@49
|
154 for(uword j=1; j < C_n_elem; ++j)
|
Chris@49
|
155 {
|
Chris@49
|
156 const eT center = C_mem[j];
|
Chris@49
|
157 const eT dist = (center >= val) ? (center - val) : (val - center);
|
Chris@49
|
158
|
Chris@49
|
159 if(dist < opt_dist)
|
Chris@49
|
160 {
|
Chris@49
|
161 opt_dist = dist;
|
Chris@49
|
162 opt_index = j;
|
Chris@49
|
163 }
|
Chris@49
|
164 else
|
Chris@49
|
165 {
|
Chris@49
|
166 break;
|
Chris@49
|
167 }
|
Chris@49
|
168 }
|
Chris@49
|
169
|
Chris@49
|
170 out_coldata[opt_index]++;
|
Chris@49
|
171 }
|
Chris@49
|
172 else
|
Chris@49
|
173 {
|
Chris@49
|
174 // -inf
|
Chris@49
|
175 if(val < eT(0)) { out_coldata[0]++; }
|
Chris@49
|
176
|
Chris@49
|
177 // +inf
|
Chris@49
|
178 if(val > eT(0)) { out_coldata[C_n_elem-1]++; }
|
Chris@49
|
179
|
Chris@49
|
180 // ignore NaN
|
Chris@49
|
181 }
|
Chris@49
|
182 }
|
Chris@49
|
183 }
|
Chris@49
|
184 }
|
Chris@49
|
185 else
|
Chris@49
|
186 if(dim == 1)
|
Chris@49
|
187 {
|
Chris@49
|
188 for(uword row=0; row < X_n_rows; ++row)
|
Chris@49
|
189 {
|
Chris@49
|
190 for(uword col=0; col < X_n_cols; ++col)
|
Chris@49
|
191 {
|
Chris@49
|
192 const eT val = X.at(row,col);
|
Chris@49
|
193
|
Chris@49
|
194 if(arma_isfinite(val))
|
Chris@49
|
195 {
|
Chris@49
|
196 eT opt_dist = (center_0 >= val) ? (center_0 - val) : (val - center_0);
|
Chris@49
|
197 uword opt_index = 0;
|
Chris@49
|
198
|
Chris@49
|
199 for(uword j=1; j < C_n_elem; ++j)
|
Chris@49
|
200 {
|
Chris@49
|
201 const eT center = C_mem[j];
|
Chris@49
|
202 const eT dist = (center >= val) ? (center - val) : (val - center);
|
Chris@49
|
203
|
Chris@49
|
204 if(dist < opt_dist)
|
Chris@49
|
205 {
|
Chris@49
|
206 opt_dist = dist;
|
Chris@49
|
207 opt_index = j;
|
Chris@49
|
208 }
|
Chris@49
|
209 else
|
Chris@49
|
210 {
|
Chris@49
|
211 break;
|
Chris@49
|
212 }
|
Chris@49
|
213 }
|
Chris@49
|
214
|
Chris@49
|
215 out.at(row,opt_index)++;
|
Chris@49
|
216 }
|
Chris@49
|
217 else
|
Chris@49
|
218 {
|
Chris@49
|
219 // -inf
|
Chris@49
|
220 if(val < eT(0)) { out.at(row,0)++; }
|
Chris@49
|
221
|
Chris@49
|
222 // +inf
|
Chris@49
|
223 if(val > eT(0)) { out.at(row,C_n_elem-1)++; }
|
Chris@49
|
224
|
Chris@49
|
225 // ignore NaN
|
Chris@49
|
226 }
|
Chris@49
|
227 }
|
Chris@49
|
228 }
|
Chris@49
|
229 }
|
Chris@49
|
230 }
|
Chris@49
|
231 }
|