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 using std::cout; 20 using std::cerr; 21 using std::endl; 22 using std::ios; 23 using std::size_t; 24 25 template<typename elem_type, typename derived> struct Base; 26 template<typename elem_type, typename derived> struct BaseCube; 27 28 template<typename eT> class Mat; 29 template<typename eT> class Col; 30 template<typename eT> class Row; 31 template<typename eT> class Cube; 32 template<typename eT> class xvec_htrans; 33 template<typename oT> class field; 34 35 template<typename eT, bool do_conj> class xtrans_mat; 36 37 38 template<typename eT> class subview; 39 template<typename eT> class subview_col; 40 template<typename eT> class subview_cols; 41 template<typename eT> class subview_row; 42 template<typename eT> class subview_row_strans; 43 template<typename eT> class subview_row_htrans; 44 template<typename eT> class subview_cube; 45 template<typename oT> class subview_field; 46 47 template<typename eT> class SpValProxy; 48 template<typename eT> class SpMat; 49 template<typename eT> class SpCol; 50 template<typename eT> class SpRow; 51 template<typename eT> class SpSubview; 52 template<typename eT> class SpSubview_col; 53 template<typename eT> class SpSubview_row; 54 55 template<typename eT> class diagview; 56 template<typename eT> class spdiagview; 57 58 template<typename eT> class MapMat; 59 template<typename eT> class MapMat_val; 60 template<typename eT> class SpMat_MapMat_val; 61 template<typename eT> class SpSubview_MapMat_val; 62 63 template<typename eT, typename T1> class subview_elem1; 64 template<typename eT, typename T1, typename T2> class subview_elem2; 65 66 template<typename parent, unsigned int mode> class subview_each1; 67 template<typename parent, unsigned int mode, typename TB> class subview_each2; 68 69 template<typename eT> class subview_cube_each1; 70 template<typename eT, typename TB> class subview_cube_each2; 71 template<typename eT, typename T1> class subview_cube_slices; 72 73 template<typename eT, typename T1> class SpSubview_col_list; 74 75 76 class SizeMat; 77 class SizeCube; 78 79 class arma_empty_class {}; 80 81 class diskio; 82 83 class op_strans; 84 class op_htrans; 85 class op_htrans2; 86 class op_inv; 87 class op_inv_sympd; 88 class op_diagmat; 89 class op_trimat; 90 class op_vectorise_row; 91 class op_vectorise_col; 92 class glue_times; 93 class glue_times_diag; 94 95 class glue_rel_lt; 96 class glue_rel_gt; 97 class glue_rel_lteq; 98 class glue_rel_gteq; 99 class glue_rel_eq; 100 class glue_rel_noteq; 101 class glue_rel_and; 102 class glue_rel_or; 103 104 class op_rel_lt_pre; 105 class op_rel_lt_post; 106 class op_rel_gt_pre; 107 class op_rel_gt_post; 108 class op_rel_lteq_pre; 109 class op_rel_lteq_post; 110 class op_rel_gteq_pre; 111 class op_rel_gteq_post; 112 class op_rel_eq; 113 class op_rel_noteq; 114 115 class gen_eye; 116 class gen_ones; 117 class gen_zeros; 118 class gen_randu; 119 class gen_randn; 120 121 122 123 class spop_strans; 124 class spop_htrans; 125 class spop_vectorise_row; 126 class spop_vectorise_col; 127 128 class spglue_plus; 129 class spglue_minus; 130 class spglue_schur; 131 class spglue_times; 132 class spglue_max; 133 class spglue_min; 134 class spglue_rel_lt; 135 class spglue_rel_gt; 136 137 138 139 class op_internal_equ; 140 class op_internal_plus; 141 class op_internal_minus; 142 class op_internal_schur; 143 class op_internal_div; 144 145 146 147 struct traits_op_default 148 { 149 template<typename T1> 150 struct traits 151 { 152 static constexpr bool is_row = false; 153 static constexpr bool is_col = false; 154 static constexpr bool is_xvec = false; 155 }; 156 }; 157 158 159 struct traits_op_xvec 160 { 161 template<typename T1> 162 struct traits 163 { 164 static constexpr bool is_row = false; 165 static constexpr bool is_col = false; 166 static constexpr bool is_xvec = true; 167 }; 168 }; 169 170 171 struct traits_op_col 172 { 173 template<typename T1> 174 struct traits 175 { 176 static constexpr bool is_row = false; 177 static constexpr bool is_col = true; 178 static constexpr bool is_xvec = false; 179 }; 180 }; 181 182 183 struct traits_op_row 184 { 185 template<typename T1> 186 struct traits 187 { 188 static constexpr bool is_row = true; 189 static constexpr bool is_col = false; 190 static constexpr bool is_xvec = false; 191 }; 192 }; 193 194 195 struct traits_op_passthru 196 { 197 template<typename T1> 198 struct traits 199 { 200 static constexpr bool is_row = T1::is_row; 201 static constexpr bool is_col = T1::is_col; 202 static constexpr bool is_xvec = T1::is_xvec; 203 }; 204 }; 205 206 207 struct traits_glue_default 208 { 209 template<typename T1, typename T2> 210 struct traits 211 { 212 static constexpr bool is_row = false; 213 static constexpr bool is_col = false; 214 static constexpr bool is_xvec = false; 215 }; 216 }; 217 218 219 struct traits_glue_or 220 { 221 template<typename T1, typename T2> 222 struct traits 223 { 224 static constexpr bool is_row = (T1::is_row || T2::is_row ); 225 static constexpr bool is_col = (T1::is_col || T2::is_col ); 226 static constexpr bool is_xvec = (T1::is_xvec || T2::is_xvec); 227 }; 228 }; 229 230 231 232 template<const bool, const bool, const bool, const bool> class gemm; 233 template<const bool, const bool, const bool> class gemv; 234 235 236 template< typename eT, typename gen_type> class Gen; 237 238 template< typename T1, typename op_type> class Op; 239 template< typename T1, typename eop_type> class eOp; 240 template< typename T1, typename op_type> class SpToDOp; 241 template< typename T1, typename op_type> class CubeToMatOp; 242 template<typename out_eT, typename T1, typename op_type> class mtOp; 243 244 template< typename T1, typename T2, typename glue_type> class Glue; 245 template< typename T1, typename T2, typename eglue_type> class eGlue; 246 template<typename out_eT, typename T1, typename T2, typename glue_type> class mtGlue; 247 248 249 250 template< typename eT, typename gen_type> class GenCube; 251 252 template< typename T1, typename op_type> class OpCube; 253 template< typename T1, typename eop_type> class eOpCube; 254 template<typename out_eT, typename T1, typename op_type> class mtOpCube; 255 256 template< typename T1, typename T2, typename glue_type> class GlueCube; 257 template< typename T1, typename T2, typename eglue_type> class eGlueCube; 258 template<typename out_eT, typename T1, typename T2, typename glue_type> class mtGlueCube; 259 260 261 template<typename T1> struct Proxy; 262 template<typename T1> struct ProxyCube; 263 264 template<typename T1> class diagmat_proxy; 265 266 template<typename T1> struct unwrap; 267 template<typename T1> struct quasi_unwrap; 268 template<typename T1> struct unwrap_cube; 269 template<typename T1> struct unwrap_spmat; 270 271 272 273 274 struct state_type 275 { 276 #if defined(ARMA_USE_OPENMP) 277 int state; 278 #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) 279 std::atomic<int> state; 280 #else 281 int state; 282 #endif 283 state_typestate_type284 arma_inline state_type() : state(int(0)) {} 285 286 // openmp: "omp atomic" does an implicit flush on the affected variable 287 // C++11: std::atomic<>::load() and std::atomic<>::store() use std::memory_order_seq_cst by default, which has an implied fence 288 289 arma_inline operator intstate_type290 operator int () const 291 { 292 int out; 293 294 #if defined(ARMA_USE_OPENMP) 295 #pragma omp atomic read 296 out = state; 297 #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) 298 out = state.load(); 299 #else 300 out = state; 301 #endif 302 303 return out; 304 } 305 306 arma_inline 307 void operator =state_type308 operator= (const int in_state) 309 { 310 #if defined(ARMA_USE_OPENMP) 311 #pragma omp atomic write 312 state = in_state; 313 #elif (!defined(ARMA_DONT_USE_STD_MUTEX)) 314 state.store(in_state); 315 #else 316 state = in_state; 317 #endif 318 } 319 }; 320 321 322 template< typename T1, typename spop_type> class SpOp; 323 template<typename out_eT, typename T1, typename spop_type> class mtSpOp; 324 325 template< typename T1, typename T2, typename spglue_type> class SpGlue; 326 template<typename out_eT, typename T1, typename T2, typename spglue_type> class mtSpGlue; 327 328 329 template<typename T1> struct SpProxy; 330 331 332 333 struct arma_vec_indicator {}; 334 struct arma_fixed_indicator {}; 335 struct arma_reserve_indicator {}; 336 struct arma_layout_indicator {}; 337 338 template<bool do_zeros> struct arma_initmode_indicator {}; 339 340 struct arma_zeros_indicator : public arma_initmode_indicator<true > {}; 341 struct arma_nozeros_indicator : public arma_initmode_indicator<false> {}; 342 343 344 //! \addtogroup injector 345 //! @{ 346 347 template<typename Dummy = int> struct injector_end_of_row {}; 348 349 static const injector_end_of_row<> endr = injector_end_of_row<>(); 350 //!< endr indicates "end of row" when using the << operator; 351 //!< similar conceptual meaning to std::endl 352 353 //! @} 354 355 356 357 //! \addtogroup diskio 358 //! @{ 359 360 361 enum struct file_type : unsigned int 362 { 363 file_type_unknown, 364 auto_detect, //!< attempt to automatically detect the file type 365 raw_ascii, //!< raw text (ASCII), without a header 366 arma_ascii, //!< Armadillo text format, with a header specifying matrix type and size 367 csv_ascii, //!< comma separated values (CSV), without a header 368 raw_binary, //!< raw binary format (machine dependent), without a header 369 arma_binary, //!< Armadillo binary format (machine dependent), with a header specifying matrix type and size 370 pgm_binary, //!< Portable Grey Map (greyscale image) 371 ppm_binary, //!< Portable Pixel Map (colour image), used by the field and cube classes 372 hdf5_binary, //!< HDF5: open binary format, not specific to Armadillo, which can store arbitrary data 373 hdf5_binary_trans, //!< [NOTE: DO NOT USE - deprecated] as per hdf5_binary, but save/load the data with columns transposed to rows 374 coord_ascii, //!< simple co-ordinate format for sparse matrices (indices start at zero) 375 ssv_ascii, //!< similar to csv_ascii; uses semicolon (;) instead of comma (,) as the separator 376 }; 377 378 379 static constexpr file_type file_type_unknown = file_type::file_type_unknown; 380 static constexpr file_type auto_detect = file_type::auto_detect; 381 static constexpr file_type raw_ascii = file_type::raw_ascii; 382 static constexpr file_type arma_ascii = file_type::arma_ascii; 383 static constexpr file_type csv_ascii = file_type::csv_ascii; 384 static constexpr file_type raw_binary = file_type::raw_binary; 385 static constexpr file_type arma_binary = file_type::arma_binary; 386 static constexpr file_type pgm_binary = file_type::pgm_binary; 387 static constexpr file_type ppm_binary = file_type::ppm_binary; 388 static constexpr file_type hdf5_binary = file_type::hdf5_binary; 389 static constexpr file_type hdf5_binary_trans = file_type::hdf5_binary_trans; 390 static constexpr file_type coord_ascii = file_type::coord_ascii; 391 static constexpr file_type ssv_ascii = file_type::ssv_ascii; 392 393 394 struct hdf5_name; 395 struct csv_name; 396 397 398 //! @} 399 400 401 402 //! \addtogroup fn_spsolve 403 //! @{ 404 405 406 struct spsolve_opts_base 407 { 408 const unsigned int id; 409 spsolve_opts_basespsolve_opts_base410 inline spsolve_opts_base(const unsigned int in_id) : id(in_id) {} 411 }; 412 413 414 struct spsolve_opts_none : public spsolve_opts_base 415 { spsolve_opts_nonespsolve_opts_none416 inline spsolve_opts_none() : spsolve_opts_base(0) {} 417 }; 418 419 420 struct superlu_opts : public spsolve_opts_base 421 { 422 typedef enum {NATURAL, MMD_ATA, MMD_AT_PLUS_A, COLAMD} permutation_type; 423 424 typedef enum {REF_NONE, REF_SINGLE, REF_DOUBLE, REF_EXTRA} refine_type; 425 426 bool allow_ugly; 427 bool equilibrate; 428 bool symmetric; 429 double pivot_thresh; 430 permutation_type permutation; 431 refine_type refine; 432 superlu_optssuperlu_opts433 inline superlu_opts() 434 : spsolve_opts_base(1) 435 { 436 allow_ugly = false; 437 equilibrate = false; 438 symmetric = false; 439 pivot_thresh = 1.0; 440 permutation = COLAMD; 441 refine = REF_NONE; 442 } 443 }; 444 445 446 //! @} 447 448 449 450 //! \ingroup fn_eigs_sym fs_eigs_gen 451 //! @{ 452 453 454 struct eigs_opts 455 { 456 double tol; // tolerance 457 unsigned int maxiter; // max iterations 458 unsigned int subdim; // subspace dimension 459 eigs_optseigs_opts460 inline eigs_opts() 461 { 462 tol = 0.0; 463 maxiter = 1000; 464 subdim = 0; 465 } 466 }; 467 468 469 //! @} 470