annotate armadillo-3.900.4/include/armadillo_bits/op_mean_meat.hpp @ 84:55a047986812 tip

Update library URI so as not to be document-local
author Chris Cannam
date Wed, 22 Apr 2020 14:21:57 +0100
parents 1ec0e2823891
children
rev   line source
Chris@49 1 // Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
Chris@49 2 // Copyright (C) 2009-2012 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 //! \addtogroup op_mean
Chris@49 10 //! @{
Chris@49 11
Chris@49 12
Chris@49 13
Chris@49 14 //! \brief
Chris@49 15 //! For each row or for each column, find the mean value.
Chris@49 16 //! The result is stored in a dense matrix that has either one column or one row.
Chris@49 17 //! The dimension, for which the means are found, is set via the mean() function.
Chris@49 18 template<typename T1>
Chris@49 19 inline
Chris@49 20 void
Chris@49 21 op_mean::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in)
Chris@49 22 {
Chris@49 23 arma_extra_debug_sigprint();
Chris@49 24
Chris@49 25 typedef typename T1::elem_type eT;
Chris@49 26
Chris@49 27 const unwrap_check<T1> tmp(in.m, out);
Chris@49 28 const Mat<eT>& X = tmp.M;
Chris@49 29
Chris@49 30 const uword dim = in.aux_uword_a;
Chris@49 31 arma_debug_check( (dim > 1), "mean(): incorrect usage. dim must be 0 or 1");
Chris@49 32
Chris@49 33 const uword X_n_rows = X.n_rows;
Chris@49 34 const uword X_n_cols = X.n_cols;
Chris@49 35
Chris@49 36 if(dim == 0)
Chris@49 37 {
Chris@49 38 arma_extra_debug_print("op_mean::apply(), dim = 0");
Chris@49 39
Chris@49 40 out.set_size( (X_n_rows > 0) ? 1 : 0, X_n_cols );
Chris@49 41
Chris@49 42 if(X_n_rows > 0)
Chris@49 43 {
Chris@49 44 eT* out_mem = out.memptr();
Chris@49 45
Chris@49 46 for(uword col=0; col < X_n_cols; ++col)
Chris@49 47 {
Chris@49 48 out_mem[col] = op_mean::direct_mean( X.colptr(col), X_n_rows );
Chris@49 49 }
Chris@49 50 }
Chris@49 51 }
Chris@49 52 else
Chris@49 53 if(dim == 1)
Chris@49 54 {
Chris@49 55 arma_extra_debug_print("op_mean::apply(), dim = 1");
Chris@49 56
Chris@49 57 out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
Chris@49 58
Chris@49 59 if(X_n_cols > 0)
Chris@49 60 {
Chris@49 61 eT* out_mem = out.memptr();
Chris@49 62
Chris@49 63 for(uword row=0; row < X_n_rows; ++row)
Chris@49 64 {
Chris@49 65 out_mem[row] = op_mean::direct_mean( X, row );
Chris@49 66 }
Chris@49 67 }
Chris@49 68 }
Chris@49 69 }
Chris@49 70
Chris@49 71
Chris@49 72
Chris@49 73 template<typename eT>
Chris@49 74 arma_pure
Chris@49 75 inline
Chris@49 76 eT
Chris@49 77 op_mean::direct_mean(const eT* const X, const uword n_elem)
Chris@49 78 {
Chris@49 79 arma_extra_debug_sigprint();
Chris@49 80
Chris@49 81 typedef typename get_pod_type<eT>::result T;
Chris@49 82
Chris@49 83 const eT result = arrayops::accumulate(X, n_elem) / T(n_elem);
Chris@49 84
Chris@49 85 return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, n_elem);
Chris@49 86 }
Chris@49 87
Chris@49 88
Chris@49 89
Chris@49 90 template<typename eT>
Chris@49 91 arma_pure
Chris@49 92 inline
Chris@49 93 eT
Chris@49 94 op_mean::direct_mean_robust(const eT* const X, const uword n_elem)
Chris@49 95 {
Chris@49 96 arma_extra_debug_sigprint();
Chris@49 97
Chris@49 98 // use an adapted form of the mean finding algorithm from the running_stat class
Chris@49 99
Chris@49 100 typedef typename get_pod_type<eT>::result T;
Chris@49 101
Chris@49 102 uword i,j;
Chris@49 103
Chris@49 104 eT r_mean = eT(0);
Chris@49 105
Chris@49 106 for(i=0, j=1; j<n_elem; i+=2, j+=2)
Chris@49 107 {
Chris@49 108 const eT Xi = X[i];
Chris@49 109 const eT Xj = X[j];
Chris@49 110
Chris@49 111 r_mean = r_mean + (Xi - r_mean)/T(j); // we need i+1, and j is equivalent to i+1 here
Chris@49 112 r_mean = r_mean + (Xj - r_mean)/T(j+1);
Chris@49 113 }
Chris@49 114
Chris@49 115
Chris@49 116 if(i < n_elem)
Chris@49 117 {
Chris@49 118 const eT Xi = X[i];
Chris@49 119
Chris@49 120 r_mean = r_mean + (Xi - r_mean)/T(i+1);
Chris@49 121 }
Chris@49 122
Chris@49 123 return r_mean;
Chris@49 124 }
Chris@49 125
Chris@49 126
Chris@49 127
Chris@49 128 template<typename eT>
Chris@49 129 inline
Chris@49 130 eT
Chris@49 131 op_mean::direct_mean(const Mat<eT>& X, const uword row)
Chris@49 132 {
Chris@49 133 arma_extra_debug_sigprint();
Chris@49 134
Chris@49 135 typedef typename get_pod_type<eT>::result T;
Chris@49 136
Chris@49 137 const uword X_n_cols = X.n_cols;
Chris@49 138
Chris@49 139 eT val = eT(0);
Chris@49 140
Chris@49 141 uword i,j;
Chris@49 142 for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
Chris@49 143 {
Chris@49 144 val += X.at(row,i);
Chris@49 145 val += X.at(row,j);
Chris@49 146 }
Chris@49 147
Chris@49 148 if(i < X_n_cols)
Chris@49 149 {
Chris@49 150 val += X.at(row,i);
Chris@49 151 }
Chris@49 152
Chris@49 153 const eT result = val / T(X_n_cols);
Chris@49 154
Chris@49 155 return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, row);
Chris@49 156 }
Chris@49 157
Chris@49 158
Chris@49 159
Chris@49 160 template<typename eT>
Chris@49 161 inline
Chris@49 162 eT
Chris@49 163 op_mean::direct_mean_robust(const Mat<eT>& X, const uword row)
Chris@49 164 {
Chris@49 165 arma_extra_debug_sigprint();
Chris@49 166
Chris@49 167 typedef typename get_pod_type<eT>::result T;
Chris@49 168
Chris@49 169 const uword X_n_cols = X.n_cols;
Chris@49 170
Chris@49 171 eT r_mean = eT(0);
Chris@49 172
Chris@49 173 for(uword col=0; col < X_n_cols; ++col)
Chris@49 174 {
Chris@49 175 r_mean = r_mean + (X.at(row,col) - r_mean)/T(col+1);
Chris@49 176 }
Chris@49 177
Chris@49 178 return r_mean;
Chris@49 179 }
Chris@49 180
Chris@49 181
Chris@49 182
Chris@49 183 template<typename eT>
Chris@49 184 inline
Chris@49 185 eT
Chris@49 186 op_mean::mean_all(const subview<eT>& X)
Chris@49 187 {
Chris@49 188 arma_extra_debug_sigprint();
Chris@49 189
Chris@49 190 typedef typename get_pod_type<eT>::result T;
Chris@49 191
Chris@49 192 const uword X_n_rows = X.n_rows;
Chris@49 193 const uword X_n_cols = X.n_cols;
Chris@49 194 const uword X_n_elem = X.n_elem;
Chris@49 195
Chris@49 196 arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
Chris@49 197
Chris@49 198 eT val = eT(0);
Chris@49 199
Chris@49 200 if(X_n_rows == 1)
Chris@49 201 {
Chris@49 202 const Mat<eT>& A = X.m;
Chris@49 203
Chris@49 204 const uword start_row = X.aux_row1;
Chris@49 205 const uword start_col = X.aux_col1;
Chris@49 206
Chris@49 207 const uword end_col_p1 = start_col + X_n_cols;
Chris@49 208
Chris@49 209 uword i,j;
Chris@49 210 for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
Chris@49 211 {
Chris@49 212 val += A.at(start_row, i);
Chris@49 213 val += A.at(start_row, j);
Chris@49 214 }
Chris@49 215
Chris@49 216 if(i < end_col_p1)
Chris@49 217 {
Chris@49 218 val += A.at(start_row, i);
Chris@49 219 }
Chris@49 220 }
Chris@49 221 else
Chris@49 222 {
Chris@49 223 for(uword col=0; col < X_n_cols; ++col)
Chris@49 224 {
Chris@49 225 val += arrayops::accumulate(X.colptr(col), X_n_rows);
Chris@49 226 }
Chris@49 227 }
Chris@49 228
Chris@49 229 const eT result = val / T(X_n_elem);
Chris@49 230
Chris@49 231 return arma_isfinite(result) ? result : op_mean::mean_all_robust(X);
Chris@49 232 }
Chris@49 233
Chris@49 234
Chris@49 235
Chris@49 236 template<typename eT>
Chris@49 237 inline
Chris@49 238 eT
Chris@49 239 op_mean::mean_all_robust(const subview<eT>& X)
Chris@49 240 {
Chris@49 241 arma_extra_debug_sigprint();
Chris@49 242
Chris@49 243 typedef typename get_pod_type<eT>::result T;
Chris@49 244
Chris@49 245 const uword X_n_rows = X.n_rows;
Chris@49 246 const uword X_n_cols = X.n_cols;
Chris@49 247
Chris@49 248 const uword start_row = X.aux_row1;
Chris@49 249 const uword start_col = X.aux_col1;
Chris@49 250
Chris@49 251 const uword end_row_p1 = start_row + X_n_rows;
Chris@49 252 const uword end_col_p1 = start_col + X_n_cols;
Chris@49 253
Chris@49 254 const Mat<eT>& A = X.m;
Chris@49 255
Chris@49 256
Chris@49 257 eT r_mean = eT(0);
Chris@49 258
Chris@49 259 if(X_n_rows == 1)
Chris@49 260 {
Chris@49 261 uword i=0;
Chris@49 262
Chris@49 263 for(uword col = start_col; col < end_col_p1; ++col, ++i)
Chris@49 264 {
Chris@49 265 r_mean = r_mean + (A.at(start_row,col) - r_mean)/T(i+1);
Chris@49 266 }
Chris@49 267 }
Chris@49 268 else
Chris@49 269 {
Chris@49 270 uword i=0;
Chris@49 271
Chris@49 272 for(uword col = start_col; col < end_col_p1; ++col)
Chris@49 273 for(uword row = start_row; row < end_row_p1; ++row, ++i)
Chris@49 274 {
Chris@49 275 r_mean = r_mean + (A.at(row,col) - r_mean)/T(i+1);
Chris@49 276 }
Chris@49 277 }
Chris@49 278
Chris@49 279 return r_mean;
Chris@49 280 }
Chris@49 281
Chris@49 282
Chris@49 283
Chris@49 284 template<typename eT>
Chris@49 285 inline
Chris@49 286 eT
Chris@49 287 op_mean::mean_all(const diagview<eT>& X)
Chris@49 288 {
Chris@49 289 arma_extra_debug_sigprint();
Chris@49 290
Chris@49 291 typedef typename get_pod_type<eT>::result T;
Chris@49 292
Chris@49 293 const uword X_n_elem = X.n_elem;
Chris@49 294
Chris@49 295 arma_debug_check( (X_n_elem == 0), "mean(): given object has no elements" );
Chris@49 296
Chris@49 297 eT val = eT(0);
Chris@49 298
Chris@49 299 for(uword i=0; i<X_n_elem; ++i)
Chris@49 300 {
Chris@49 301 val += X[i];
Chris@49 302 }
Chris@49 303
Chris@49 304 const eT result = val / T(X_n_elem);
Chris@49 305
Chris@49 306 return arma_isfinite(result) ? result : op_mean::mean_all_robust(X);
Chris@49 307 }
Chris@49 308
Chris@49 309
Chris@49 310
Chris@49 311 template<typename eT>
Chris@49 312 inline
Chris@49 313 eT
Chris@49 314 op_mean::mean_all_robust(const diagview<eT>& X)
Chris@49 315 {
Chris@49 316 arma_extra_debug_sigprint();
Chris@49 317
Chris@49 318 typedef typename get_pod_type<eT>::result T;
Chris@49 319
Chris@49 320 const uword X_n_elem = X.n_elem;
Chris@49 321
Chris@49 322 eT r_mean = eT(0);
Chris@49 323
Chris@49 324 for(uword i=0; i<X_n_elem; ++i)
Chris@49 325 {
Chris@49 326 r_mean = r_mean + (X[i] - r_mean)/T(i+1);
Chris@49 327 }
Chris@49 328
Chris@49 329 return r_mean;
Chris@49 330 }
Chris@49 331
Chris@49 332
Chris@49 333
Chris@49 334 template<typename T1>
Chris@49 335 inline
Chris@49 336 typename T1::elem_type
Chris@49 337 op_mean::mean_all(const Base<typename T1::elem_type, T1>& X)
Chris@49 338 {
Chris@49 339 arma_extra_debug_sigprint();
Chris@49 340
Chris@49 341 typedef typename T1::elem_type eT;
Chris@49 342
Chris@49 343 const unwrap<T1> tmp(X.get_ref());
Chris@49 344 const Mat<eT>& A = tmp.M;
Chris@49 345
Chris@49 346 const uword A_n_elem = A.n_elem;
Chris@49 347
Chris@49 348 arma_debug_check( (A_n_elem == 0), "mean(): given object has no elements" );
Chris@49 349
Chris@49 350 return op_mean::direct_mean(A.memptr(), A_n_elem);
Chris@49 351 }
Chris@49 352
Chris@49 353
Chris@49 354
Chris@49 355 template<typename eT>
Chris@49 356 arma_inline
Chris@49 357 eT
Chris@49 358 op_mean::robust_mean(const eT A, const eT B)
Chris@49 359 {
Chris@49 360 return A + (B - A)/eT(2);
Chris@49 361 }
Chris@49 362
Chris@49 363
Chris@49 364
Chris@49 365 template<typename T>
Chris@49 366 arma_inline
Chris@49 367 std::complex<T>
Chris@49 368 op_mean::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
Chris@49 369 {
Chris@49 370 return A + (B - A)/T(2);
Chris@49 371 }
Chris@49 372
Chris@49 373
Chris@49 374
Chris@49 375 //! @}
Chris@49 376