diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 02560170..b1f17e2d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,10 +14,10 @@ jobs: strategy: matrix: include: - - { name: container, os: ubuntu-latest, container: rocker/r2u4ci } + #- { name: container, os: ubuntu-latest, container: rocker/r2u4ci } - { name: macos, os: macos-latest, openmp: yes } #- { name: macos, os: macos-latest, openmp: no } - #- { name: ubuntu, os: ubuntu-latest } + - { name: ubuntu, os: ubuntu-latest } runs-on: ${{ matrix.os }} diff --git a/ChangeLog b/ChangeLog index 082c202d..ea2e006f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,16 @@ +2026-04-16 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): Roll micro version and date + + * inst/include/armadillo_bits/: Sync with Armadillo 15.2.5 + 2026-04-11 Dirk Eddelbuettel * README.md (Rcpp): Updated status section 2026-03-26 Dirk Eddelbuettel - * DESCRIPTION (Version, Date): Roll minor version and date + * DESCRIPTION (Version, Date): Roll micro version and date * cleanup: No longer remove vignettes/*.pdf diff --git a/DESCRIPTION b/DESCRIPTION index 92c96b68..43464cf0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: RcppArmadillo Type: Package Title: 'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library -Version: 15.2.4-1.2 -Date: 2026-03-26 +Version: 15.2.4.99-0 +Date: 2026-04-16 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("Romain", "Francois", role = "aut", diff --git a/inst/include/armadillo_bits/BaseCube_meat.hpp b/inst/include/armadillo_bits/BaseCube_meat.hpp index d22e479b..59b0ef7e 100644 --- a/inst/include/armadillo_bits/BaseCube_meat.hpp +++ b/inst/include/armadillo_bits/BaseCube_meat.hpp @@ -244,9 +244,9 @@ BaseCube::is_zero(const typename get_pod_type::res typedef typename get_pod_type::result T; - arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); - if(ProxyCube::use_at || is_Cube::stored_type>::value) + if(is_Cube::stored_type>::value || ProxyCube::use_at) { const unwrap_cube U( (*this).get_ref() ); @@ -263,22 +263,52 @@ BaseCube::is_zero(const typename get_pod_type::res if(is_cx::yes) { - for(uword i=0; i tol) { return false; } - if(eop_aux::arma_abs(val_imag) > tol) { return false; } + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + if(eop_aux::arma_abs(val_real) != T(0)) { return false; } + if(eop_aux::arma_abs(val_imag) != T(0)) { return false; } + } + } + else + { + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; } + if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; } + } } } else // not complex { - for(uword i=0; i < n_elem; ++i) + if(tol == T(0)) + { + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + if(val != elem_type(0)) { return false; } + } + } + else { - if(eop_aux::arma_abs(Pea[i]) > tol) { return false; } + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; } + } } } diff --git a/inst/include/armadillo_bits/Base_meat.hpp b/inst/include/armadillo_bits/Base_meat.hpp index ab2a3f60..7e4b07c3 100644 --- a/inst/include/armadillo_bits/Base_meat.hpp +++ b/inst/include/armadillo_bits/Base_meat.hpp @@ -352,7 +352,7 @@ Base::is_symmetric(const typename get_pod_type::re if(tol == T(0)) { return (*this).is_symmetric(); } - arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" ); const quasi_unwrap U( (*this).get_ref() ); @@ -435,7 +435,7 @@ Base::is_hermitian(const typename get_pod_type::re if(tol == T(0)) { return (*this).is_hermitian(); } - arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" ); const quasi_unwrap U( (*this).get_ref() ); @@ -464,9 +464,9 @@ Base::is_zero(const typename get_pod_type::result typedef typename get_pod_type::result T; - arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); - if(Proxy::use_at || is_Mat::stored_type>::value) + if( (quasi_unwrap::has_orig_mem) || (is_Mat::stored_type>::value) || (Proxy::use_at) ) { const quasi_unwrap U( (*this).get_ref() ); @@ -483,22 +483,52 @@ Base::is_zero(const typename get_pod_type::result if(is_cx::yes) { - for(uword i=0; i tol) { return false; } - if(eop_aux::arma_abs(val_imag) > tol) { return false; } + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + if(eop_aux::arma_abs(val_real) != T(0)) { return false; } + if(eop_aux::arma_abs(val_imag) != T(0)) { return false; } + } + } + else + { + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; } + if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; } + } } } else // not complex { - for(uword i=0; i tol) { return false; } + for(uword i=0; i < n_elem; ++i) + { + const elem_type val = Pea[i]; + + if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; } + } } } @@ -917,7 +947,7 @@ Base_extra_yes::is_sympd(typename get_pod_type::re typedef typename get_pod_type::result T; - arma_conform_check( (tol < T(0)), "is_sympd(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_sympd(): parameter 'tol' must be >= 0" ); Mat X = static_cast(*this); diff --git a/inst/include/armadillo_bits/Cube_meat.hpp b/inst/include/armadillo_bits/Cube_meat.hpp index 2571abc1..f44d0465 100644 --- a/inst/include/armadillo_bits/Cube_meat.hpp +++ b/inst/include/armadillo_bits/Cube_meat.hpp @@ -4187,12 +4187,12 @@ Cube::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" ); } arrayops::clamp(memptr(), n_elem, min_val, max_val); diff --git a/inst/include/armadillo_bits/Mat_meat.hpp b/inst/include/armadillo_bits/Mat_meat.hpp index cd3ee13e..b15d77a8 100644 --- a/inst/include/armadillo_bits/Mat_meat.hpp +++ b/inst/include/armadillo_bits/Mat_meat.hpp @@ -7885,12 +7885,12 @@ Mat::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" ); } arrayops::clamp(memptr(), n_elem, min_val, max_val); diff --git a/inst/include/armadillo_bits/SpBase_meat.hpp b/inst/include/armadillo_bits/SpBase_meat.hpp index c8a5796e..dab1f5cb 100644 --- a/inst/include/armadillo_bits/SpBase_meat.hpp +++ b/inst/include/armadillo_bits/SpBase_meat.hpp @@ -527,7 +527,7 @@ SpBase::is_zero(const typename get_pod_type::resul typedef typename get_pod_type::result T; - arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); const SpProxy P( (*this).get_ref() ); @@ -554,8 +554,8 @@ SpBase::is_zero(const typename get_pod_type::resul const T val_real = access::tmp_real(val); const T val_imag = access::tmp_imag(val); - if(eop_aux::arma_abs(val_real) > tol) { return false; } - if(eop_aux::arma_abs(val_imag) > tol) { return false; } + if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; } + if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; } ++it; } @@ -564,7 +564,7 @@ SpBase::is_zero(const typename get_pod_type::resul { while(it != it_end) { - if(eop_aux::arma_abs(*it) > tol) { return false; } + if( (eop_aux::arma_abs(*it) <= tol) == false ) { return false; } ++it; } diff --git a/inst/include/armadillo_bits/SpMat_meat.hpp b/inst/include/armadillo_bits/SpMat_meat.hpp index c17fed4d..161b75bf 100644 --- a/inst/include/armadillo_bits/SpMat_meat.hpp +++ b/inst/include/armadillo_bits/SpMat_meat.hpp @@ -3565,7 +3565,7 @@ SpMat::is_symmetric(const typename get_pod_type::result tol) cons if(tol == T(0)) { return (*this).is_symmetric(); } - arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" ); const SpMat& A = (*this); @@ -3611,7 +3611,7 @@ SpMat::is_hermitian(const typename get_pod_type::result tol) cons if(tol == T(0)) { return (*this).is_hermitian(); } - arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" ); const SpMat& A = (*this); @@ -4204,12 +4204,12 @@ SpMat::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" ); } if(n_nonzero == 0) { return *this; } @@ -4389,7 +4389,7 @@ SpMat::sprandu(const uword in_rows, const uword in_cols, const double densit { arma_debug_sigprint(); - arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandu(): density must be in the [0,1] interval" ); + arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandu(): density must be in the [0,1] interval" ); const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5); @@ -4466,7 +4466,7 @@ SpMat::sprandn(const uword in_rows, const uword in_cols, const double densit { arma_debug_sigprint(); - arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandn(): density must be in the [0,1] interval" ); + arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandn(): density must be in the [0,1] interval" ); const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5); diff --git a/inst/include/armadillo_bits/SpSubview_meat.hpp b/inst/include/armadillo_bits/SpSubview_meat.hpp index 22b06c69..dda6dab0 100644 --- a/inst/include/armadillo_bits/SpSubview_meat.hpp +++ b/inst/include/armadillo_bits/SpSubview_meat.hpp @@ -946,12 +946,12 @@ SpSubview::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" ); } if((n_elem == 0) || (n_nonzero == 0)) { return; } diff --git a/inst/include/armadillo_bits/arma_version.hpp b/inst/include/armadillo_bits/arma_version.hpp index c8e72351..9c9cbb42 100644 --- a/inst/include/armadillo_bits/arma_version.hpp +++ b/inst/include/armadillo_bits/arma_version.hpp @@ -23,7 +23,7 @@ #define ARMA_VERSION_MAJOR 15 #define ARMA_VERSION_MINOR 2 -#define ARMA_VERSION_PATCH 4 +#define ARMA_VERSION_PATCH 5 #define ARMA_VERSION_NAME "Medium Roast Deluxe" diff --git a/inst/include/armadillo_bits/arrayops_meat.hpp b/inst/include/armadillo_bits/arrayops_meat.hpp index 573ae6df..3cbcb843 100644 --- a/inst/include/armadillo_bits/arrayops_meat.hpp +++ b/inst/include/armadillo_bits/arrayops_meat.hpp @@ -994,7 +994,7 @@ arrayops::is_zero(const eT* mem, const uword n_elem, const eT abs_limit, const t { for(uword i=0; i abs_limit) { return false; } + if( (eop_aux::arma_abs(mem[i]) <= abs_limit) == false ) { return false; } } } @@ -1028,8 +1028,8 @@ arrayops::is_zero(const std::complex* mem, const uword n_elem, const T abs_li { const eT& val = mem[i]; - if(std::abs(std::real(val)) > abs_limit) { return false; } - if(std::abs(std::imag(val)) > abs_limit) { return false; } + if( (std::abs(std::real(val)) <= abs_limit) == false ) { return false; } + if( (std::abs(std::imag(val)) <= abs_limit) == false ) { return false; } } } diff --git a/inst/include/armadillo_bits/diagview_meat.hpp b/inst/include/armadillo_bits/diagview_meat.hpp index c0cfcd98..d48c2e1d 100644 --- a/inst/include/armadillo_bits/diagview_meat.hpp +++ b/inst/include/armadillo_bits/diagview_meat.hpp @@ -134,15 +134,25 @@ diagview::operator+=(const eT val) { arma_debug_sigprint(); - Mat& t_m = const_cast< Mat& >(m); + diagview& d = *this; + + Mat& d_m = const_cast< Mat& >(d.m); + + const uword d_n_elem = d.n_elem; + const uword d_row_offset = d.row_offset; + const uword d_col_offset = d.col_offset; - const uword t_n_elem = n_elem; - const uword t_row_offset = row_offset; - const uword t_col_offset = col_offset; + uword ii,jj; - for(uword ii=0; ii < t_n_elem; ++ii) + for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) { - t_m.at( ii + t_row_offset, ii + t_col_offset) += val; + d_m.at( ii + d_row_offset, ii + d_col_offset) += val; + d_m.at( jj + d_row_offset, jj + d_col_offset) += val; + } + + if(ii < d_n_elem) + { + d_m.at( ii + d_row_offset, ii + d_col_offset) += val; } } @@ -155,15 +165,25 @@ diagview::operator-=(const eT val) { arma_debug_sigprint(); - Mat& t_m = const_cast< Mat& >(m); + diagview& d = *this; + + Mat& d_m = const_cast< Mat& >(d.m); + + const uword d_n_elem = d.n_elem; + const uword d_row_offset = d.row_offset; + const uword d_col_offset = d.col_offset; - const uword t_n_elem = n_elem; - const uword t_row_offset = row_offset; - const uword t_col_offset = col_offset; + uword ii,jj; - for(uword ii=0; ii < t_n_elem; ++ii) + for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) { - t_m.at( ii + t_row_offset, ii + t_col_offset) -= val; + d_m.at( ii + d_row_offset, ii + d_col_offset) -= val; + d_m.at( jj + d_row_offset, jj + d_col_offset) -= val; + } + + if(ii < d_n_elem) + { + d_m.at( ii + d_row_offset, ii + d_col_offset) -= val; } } @@ -176,15 +196,25 @@ diagview::operator*=(const eT val) { arma_debug_sigprint(); - Mat& t_m = const_cast< Mat& >(m); + diagview& d = *this; + + Mat& d_m = const_cast< Mat& >(d.m); - const uword t_n_elem = n_elem; - const uword t_row_offset = row_offset; - const uword t_col_offset = col_offset; + const uword d_n_elem = d.n_elem; + const uword d_row_offset = d.row_offset; + const uword d_col_offset = d.col_offset; + + uword ii,jj; - for(uword ii=0; ii < t_n_elem; ++ii) + for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) { - t_m.at( ii + t_row_offset, ii + t_col_offset) *= val; + d_m.at( ii + d_row_offset, ii + d_col_offset) *= val; + d_m.at( jj + d_row_offset, jj + d_col_offset) *= val; + } + + if(ii < d_n_elem) + { + d_m.at( ii + d_row_offset, ii + d_col_offset) *= val; } } @@ -197,15 +227,25 @@ diagview::operator/=(const eT val) { arma_debug_sigprint(); - Mat& t_m = const_cast< Mat& >(m); + diagview& d = *this; + + Mat& d_m = const_cast< Mat& >(d.m); + + const uword d_n_elem = d.n_elem; + const uword d_row_offset = d.row_offset; + const uword d_col_offset = d.col_offset; + + uword ii,jj; - const uword t_n_elem = n_elem; - const uword t_row_offset = row_offset; - const uword t_col_offset = col_offset; + for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) + { + d_m.at( ii + d_row_offset, ii + d_col_offset) /= val; + d_m.at( jj + d_row_offset, jj + d_col_offset) /= val; + } - for(uword ii=0; ii < t_n_elem; ++ii) + if(ii < d_n_elem) { - t_m.at( ii + t_row_offset, ii + t_col_offset) /= val; + d_m.at( ii + d_row_offset, ii + d_col_offset) /= val; } } @@ -236,6 +276,12 @@ diagview::operator= (const Base& o) "diagview: given object has incompatible size" ); + constexpr bool is_gen_zeros = (is_same_type< T1, Gen, gen_zeros> >::yes) || (is_same_type< T1, Gen, gen_zeros> >::yes); + constexpr bool is_gen_ones = (is_same_type< T1, Gen, gen_ones > >::yes) || (is_same_type< T1, Gen, gen_ones > >::yes); + + if(is_gen_zeros) { d.zeros(); return; } + if(is_gen_ones ) { d.ones(); return; } + const bool have_alias = P.is_alias(d_m); if(have_alias) { arma_debug_print("aliasing detected"); } @@ -948,13 +994,25 @@ diagview::fill(const eT val) { arma_debug_sigprint(); - Mat& x = const_cast< Mat& >(m); + diagview& d = *this; - const uword local_n_elem = n_elem; + Mat& d_m = const_cast< Mat& >(d.m); - for(uword ii=0; ii < local_n_elem; ++ii) + const uword d_n_elem = d.n_elem; + const uword d_row_offset = d.row_offset; + const uword d_col_offset = d.col_offset; + + uword ii,jj; + + for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) + { + d_m.at( ii + d_row_offset, ii + d_col_offset) = val; + d_m.at( jj + d_row_offset, jj + d_col_offset) = val; + } + + if(ii < d_n_elem) { - x.at(ii+row_offset, ii+col_offset) = val; + d_m.at( ii + d_row_offset, ii + d_col_offset) = val; } } diff --git a/inst/include/armadillo_bits/diskio_meat.hpp b/inst/include/armadillo_bits/diskio_meat.hpp index 22c98faa..53f9db48 100644 --- a/inst/include/armadillo_bits/diskio_meat.hpp +++ b/inst/include/armadillo_bits/diskio_meat.hpp @@ -373,29 +373,37 @@ inline std::string diskio::gen_tmp_name(const std::string& x) { - union { uword val; void* ptr; } u; + arma_debug_sigprint(); + + const char* charlist = "0123456789abcdefghijklmnopqrstuvwxyz"; + const char* suffix1 = ".!"; + + constexpr std::size_t charlist_length = 36; + constexpr std::size_t suffix1_length = 2; + constexpr std::size_t suffix2_length = 6; + + typedef typename std::minstd_rand::result_type local_seed_type; + + std::minstd_rand local_engine; + std::uniform_int_distribution local_distr(0, charlist_length - 1); + + local_engine.seed( static_cast( (std::clock()) & 0xFFFF ) ); - u.val = uword(0); - u.ptr = const_cast(&x); + const std::size_t x_length = x.length(); - const u16 a = u16( (u.val >> 8) & 0xFFFF ); - const u16 b = u16( (std::clock()) & 0xFFFF ); + std::string out(x_length + suffix1_length + suffix2_length, '0'); // create string filled with char '0' (not 0) - std::ostringstream ss; + std::size_t count = 0; - ss << x << ".tmp_"; + for(; count < x_length; ++count) { out[count] = x[count]; } - ss.setf(std::ios_base::hex, std::ios_base::basefield); + for(std::size_t i=0; i < suffix1_length; ++i, ++count) { out[count] = suffix1[i]; } - ss.width(4); - ss.fill('0'); - ss << a; + local_distr(local_engine); // ignore first random number - ss.width(4); - ss.fill('0'); - ss << b; + for(std::size_t i=0; i < suffix2_length; ++i, ++count) { out[count] = charlist[ local_distr(local_engine)]; } - return ss.str(); + return out; } diff --git a/inst/include/armadillo_bits/fn_approx_equal.hpp b/inst/include/armadillo_bits/fn_approx_equal.hpp index ad33d1a0..78de182d 100644 --- a/inst/include/armadillo_bits/fn_approx_equal.hpp +++ b/inst/include/armadillo_bits/fn_approx_equal.hpp @@ -110,8 +110,8 @@ internal_approx_equal_worker arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" ); - if(use_abs_diff) { arma_conform_check( cond_rel< is_signed::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); } - if(use_rel_diff) { arma_conform_check( cond_rel< is_signed::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); } + if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); } + if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); } const Proxy PA(A.get_ref()); const Proxy PB(B.get_ref()); @@ -203,8 +203,8 @@ internal_approx_equal_worker arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" ); - if(use_abs_diff) { arma_conform_check( cond_rel< is_signed::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); } - if(use_rel_diff) { arma_conform_check( cond_rel< is_signed::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); } + if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); } + if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); } const ProxyCube PA(A.get_ref()); const ProxyCube PB(B.get_ref()); @@ -418,7 +418,7 @@ approx_equal(const SpBase& A, const SpBase::value >::lt(tol, T(0)), "approx_equal(): argument 'tol' must be >= 0" ); + arma_conform_check( (cond_rel< is_signed::value >::lt(tol, T(0)) || arma_isnan(tol)), "approx_equal(): argument 'tol' must be >= 0" ); const unwrap_spmat UA(A.get_ref()); const unwrap_spmat UB(B.get_ref()); @@ -460,8 +460,8 @@ approx_equal(const SpBase& A, const SpBase::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); - arma_conform_check( cond_rel< is_signed::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); + arma_conform_check( (cond_rel< is_signed::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); + arma_conform_check( (cond_rel< is_signed::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); return approx_equal(A.get_ref(), B.get_ref(), "abs", abs_tol); } diff --git a/inst/include/armadillo_bits/fn_clamp.hpp b/inst/include/armadillo_bits/fn_clamp.hpp index 17618af6..77d4652d 100644 --- a/inst/include/armadillo_bits/fn_clamp.hpp +++ b/inst/include/armadillo_bits/fn_clamp.hpp @@ -97,12 +97,12 @@ clamp(const SpBase& X, const typename T1::elem_type m if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "clamp(): imag(min_val) must be less than imag(max_val)" ); } SpMat out = X.get_ref(); diff --git a/inst/include/armadillo_bits/fn_rande.hpp b/inst/include/armadillo_bits/fn_rande.hpp index d7c655f4..2e3177d2 100644 --- a/inst/include/armadillo_bits/fn_rande.hpp +++ b/inst/include/armadillo_bits/fn_rande.hpp @@ -47,7 +47,7 @@ rande(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(lambda, unused); - arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); + arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); obj_type out(n_rows, n_cols, arma_nozeros_indicator()); @@ -138,7 +138,7 @@ rande(const distr_param& param = distr_param()) param.get_double_vals(lambda, unused); - arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); + arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); double out_val = double(0); @@ -162,7 +162,7 @@ rande(const distr_param& param = distr_param()) param.get_double_vals(lambda, unused); - arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); + arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); eT out_val = eT(0); @@ -189,7 +189,7 @@ rande(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(lambda, unused); - arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); + arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" ); cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); diff --git a/inst/include/armadillo_bits/fn_randg.hpp b/inst/include/armadillo_bits/fn_randg.hpp index bacf51ef..5c1cfc2d 100644 --- a/inst/include/armadillo_bits/fn_randg.hpp +++ b/inst/include/armadillo_bits/fn_randg.hpp @@ -47,7 +47,7 @@ randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(a,b); - arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); obj_type out(n_rows, n_cols, arma_nozeros_indicator()); @@ -138,7 +138,7 @@ randg(const distr_param& param = distr_param()) param.get_double_vals(a,b); - arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); double out_val = double(0); @@ -162,7 +162,7 @@ randg(const distr_param& param = distr_param()) param.get_double_vals(a,b); - arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); eT out_val = eT(0); @@ -189,7 +189,7 @@ randg(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(a,b); - arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); + arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" ); cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); diff --git a/inst/include/armadillo_bits/fn_randi.hpp b/inst/include/armadillo_bits/fn_randi.hpp index 24baf306..0a7e9b70 100644 --- a/inst/include/armadillo_bits/fn_randi.hpp +++ b/inst/include/armadillo_bits/fn_randi.hpp @@ -47,7 +47,7 @@ randi(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_int_vals(a,b); - arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" ); obj_type out(n_rows, n_cols, arma_nozeros_indicator()); @@ -142,7 +142,7 @@ randi(const distr_param& param) param.get_int_vals(a,b); - arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" ); sword out_val = sword(0); @@ -166,7 +166,7 @@ randi(const distr_param& param) param.get_int_vals(a,b); - arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" ); eT out_val = eT(0); @@ -218,7 +218,7 @@ randi(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_int_vals(a,b); - arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" ); cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator()); diff --git a/inst/include/armadillo_bits/fn_randn.hpp b/inst/include/armadillo_bits/fn_randn.hpp index 86a6b826..fbfb8862 100644 --- a/inst/include/armadillo_bits/fn_randn.hpp +++ b/inst/include/armadillo_bits/fn_randn.hpp @@ -62,7 +62,7 @@ randn(const distr_param& param) param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); const double val = double(arma_rng::randn()); @@ -86,7 +86,7 @@ randn(const distr_param& param) param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); eT val = eT(0); @@ -119,7 +119,7 @@ randn(const uword n_elem, const distr_param& param = distr_param()) param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), n_elem, mu, sd); } @@ -156,7 +156,7 @@ randn(const uword n_elem, const distr_param& param = distr_param(), const typena param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } @@ -188,7 +188,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } @@ -237,7 +237,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } @@ -284,7 +284,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } @@ -330,7 +330,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(mu,sd); - arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); + arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" ); arma_rng::randn::fill(out.memptr(), out.n_elem, mu, sd); } diff --git a/inst/include/armadillo_bits/fn_randu.hpp b/inst/include/armadillo_bits/fn_randu.hpp index 63363e1d..264eeb72 100644 --- a/inst/include/armadillo_bits/fn_randu.hpp +++ b/inst/include/armadillo_bits/fn_randu.hpp @@ -62,7 +62,7 @@ randu(const distr_param& param) param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); const double val = double(arma_rng::randu()); @@ -86,7 +86,7 @@ randu(const distr_param& param) param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); eT val = eT(0); @@ -119,7 +119,7 @@ randu(const uword n_elem, const distr_param& param = distr_param()) param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), n_elem, a, b); } @@ -156,7 +156,7 @@ randu(const uword n_elem, const distr_param& param = distr_param(), const typena param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } @@ -188,7 +188,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } @@ -237,7 +237,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } @@ -284,7 +284,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } @@ -330,7 +330,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_ param.get_double_vals(a,b); - arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" ); + arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" ); arma_rng::randu::fill(out.memptr(), out.n_elem, a, b); } diff --git a/inst/include/armadillo_bits/fn_spsolve.hpp b/inst/include/armadillo_bits/fn_spsolve.hpp index dc73b251..84fa6063 100644 --- a/inst/include/armadillo_bits/fn_spsolve.hpp +++ b/inst/include/armadillo_bits/fn_spsolve.hpp @@ -55,7 +55,7 @@ spsolve_helper const superlu_opts& opts = (settings.id == 1) ? static_cast(settings) : superlu_opts_default; - arma_conform_check( ( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ), "spsolve(): pivot_thresh must be in the [0,1] interval" ); + arma_conform_check( ( ((opts.pivot_thresh >= double(0)) == false) || ((opts.pivot_thresh <= double(1)) == false) ), "spsolve(): pivot_thresh must be in the [0,1] interval" ); if(sig == 's') // SuperLU solver { @@ -110,12 +110,12 @@ spsolve_helper if( (status == false) && (rcond > T(0)) ) { - arma_warn(2, "spsolve(): system is singular (rcond: ", rcond, ")"); + arma_warn(2, "spsolve(): system is singular; rcond: ", rcond); } if( (status == true) && (rcond > T(0)) && (rcond < std::numeric_limits::epsilon()) ) { - arma_warn(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")"); + arma_warn(2, "spsolve(): solution computed, but system is singular to working precision; rcond: ", rcond); } return status; diff --git a/inst/include/armadillo_bits/fn_svds.hpp b/inst/include/armadillo_bits/fn_svds.hpp index f991dc95..cbfa9e42 100644 --- a/inst/include/armadillo_bits/fn_svds.hpp +++ b/inst/include/armadillo_bits/fn_svds.hpp @@ -47,7 +47,7 @@ svds_helper "svds(): two or more output objects are the same object" ); - arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" ); const unwrap_spmat tmp(X.get_ref()); const SpMat& A = tmp.M; @@ -171,7 +171,7 @@ svds_helper "svds(): two or more output objects are the same object" ); - arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" ); + arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" ); const unwrap_spmat tmp(X.get_ref()); const SpMat& A = tmp.M; diff --git a/inst/include/armadillo_bits/glue_solve_meat.hpp b/inst/include/armadillo_bits/glue_solve_meat.hpp index 98015d64..830f4c85 100644 --- a/inst/include/armadillo_bits/glue_solve_meat.hpp +++ b/inst/include/armadillo_bits/glue_solve_meat.hpp @@ -380,7 +380,7 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const } else { - arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution"); } // TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten @@ -472,7 +472,7 @@ glue_solve_tri_default::apply(Mat& actual_out, const Base& A_expr, co } else { - arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type @@ -598,7 +598,7 @@ glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const } else { - arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution"); + arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type diff --git a/inst/include/armadillo_bits/gmm_diag_meat.hpp b/inst/include/armadillo_bits/gmm_diag_meat.hpp index fd1672ee..918d1fa4 100644 --- a/inst/include/armadillo_bits/gmm_diag_meat.hpp +++ b/inst/include/armadillo_bits/gmm_diag_meat.hpp @@ -683,9 +683,9 @@ gmm_diag::learn || (seed_mode == random_subset) || (seed_mode == random_spread); - arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" ); - arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" ); - arma_conform_check( (var_floor < eT(0) ), "gmm_diag::learn(): variance floor is negative" ); + arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" ); + arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" ); + arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_diag::learn(): variance floor must be > 0" ); const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; diff --git a/inst/include/armadillo_bits/gmm_full_meat.hpp b/inst/include/armadillo_bits/gmm_full_meat.hpp index 66cb910d..d8cd16a3 100644 --- a/inst/include/armadillo_bits/gmm_full_meat.hpp +++ b/inst/include/armadillo_bits/gmm_full_meat.hpp @@ -722,9 +722,9 @@ gmm_full::learn || (seed_mode == random_subset) || (seed_mode == random_spread); - arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" ); - arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" ); - arma_conform_check( (var_floor < eT(0) ), "gmm_full::learn(): variance floor is negative" ); + arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" ); + arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" ); + arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_full::learn(): variance floor must be > 0" ); const unwrap tmp_X(data.get_ref()); const Mat& X = tmp_X.M; diff --git a/inst/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp b/inst/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp index f4d0952f..d0907a81 100644 --- a/inst/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp +++ b/inst/include/armadillo_bits/newarp_SparseGenRealShiftSolve_meat.hpp @@ -77,8 +77,8 @@ SparseGenRealShiftSolve::SparseGenRealShiftSolve(const SpMat& mat_obj, c if( (x_rcond < std::numeric_limits::epsilon()) || arma_isnan(x_rcond) ) { - if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); } - else { arma_warn(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); } + if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); } + else { arma_warn(2, "matrix is singular to working precision; rcond: ", x_rcond); } return; } diff --git a/inst/include/armadillo_bits/op_clamp_meat.hpp b/inst/include/armadillo_bits/op_clamp_meat.hpp index 2dbf6f80..65531d2e 100644 --- a/inst/include/armadillo_bits/op_clamp_meat.hpp +++ b/inst/include/armadillo_bits/op_clamp_meat.hpp @@ -34,7 +34,7 @@ op_clamp::apply(Mat& out, const mtOp max_val), "clamp(): min_val must be less than max_val" ); + arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" ); if(is_Mat::value) { @@ -83,7 +83,7 @@ op_clamp::apply(Mat_noalias& out, const mtOp max_val), "clamp(): min_val must be less than max_val" ); + arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" ); if((quasi_unwrap::has_orig_mem) || (is_Mat::stored_type>::value) || (arma_config::openmp && Proxy::use_mp)) { @@ -186,7 +186,7 @@ op_clamp::apply(Cube& out, const mtOpCube max_val), "clamp(): min_val must be less than max_val" ); + arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" ); if(is_Cube::value) { @@ -350,8 +350,8 @@ op_clamp_cx::apply_direct(Mat& out, const Mat& X, const eT min_val, cons const T max_val_real = std::real(max_val); const T max_val_imag = std::imag(max_val); - arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" ); if(&out != &X) { @@ -401,8 +401,8 @@ op_clamp_cx::apply_proxy_noalias(Mat& out, const Proxy max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" ); const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); @@ -503,8 +503,8 @@ op_clamp_cx::apply_direct(Cube& out, const Cube& X, const eT min_val, co const T max_val_real = std::real(max_val); const T max_val_imag = std::imag(max_val); - arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" ); if(&out != &X) { @@ -554,8 +554,8 @@ op_clamp_cx::apply_proxy_noalias(Cube& out, const ProxyC const T max_val_real = std::real(max_val); const T max_val_imag = std::imag(max_val); - arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" ); const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); diff --git a/inst/include/armadillo_bits/op_expmat_meat.hpp b/inst/include/armadillo_bits/op_expmat_meat.hpp index f1083cbd..7fdd81e8 100644 --- a/inst/include/armadillo_bits/op_expmat_meat.hpp +++ b/inst/include/armadillo_bits/op_expmat_meat.hpp @@ -207,7 +207,7 @@ op_expmat_sym::apply_direct(Mat& out, const Base 0) && (is_cx::yes) && (sym_helper::check_diag_imag(X) == false)) { - arma_warn(1, "inv_sympd(): imaginary components on diagonal are non-zero"); + arma_warn(1, "expmat_sym(): imaginary components on diagonal are non-zero"); } if(is_op_diagmat::value || X.is_diagmat()) diff --git a/inst/include/armadillo_bits/op_htrans_meat.hpp b/inst/include/armadillo_bits/op_htrans_meat.hpp index 7c79bd1d..38e3c24c 100644 --- a/inst/include/armadillo_bits/op_htrans_meat.hpp +++ b/inst/include/armadillo_bits/op_htrans_meat.hpp @@ -65,7 +65,7 @@ op_htrans::apply_mat_noalias(Mat& out, const Mat& A, const typename arma op_htrans::apply_mat_noalias_large(out, A); } else - if( (A_n_rows != 0) && (A_n_cols != 0) ) + if(A_n_cols != 0) { eT* outptr = out.memptr(); diff --git a/inst/include/armadillo_bits/op_mean_bones.hpp b/inst/include/armadillo_bits/op_mean_bones.hpp index e30de199..2b736537 100644 --- a/inst/include/armadillo_bits/op_mean_bones.hpp +++ b/inst/include/armadillo_bits/op_mean_bones.hpp @@ -65,12 +65,18 @@ struct op_mean template inline static typename T1::elem_type mean_all(const T1& X); + template + inline static typename T1::elem_type mean_all_proxy(const Proxy& P); + template inline static typename T1::elem_type mean_all(const Op& X); template inline static eT mean_all_omit(const eT* X_mem, const uword N, functor is_omitted); + template + inline static typename T1::elem_type mean_all_omit(const Proxy& P, functor is_omitted); + // template diff --git a/inst/include/armadillo_bits/op_mean_meat.hpp b/inst/include/armadillo_bits/op_mean_meat.hpp index 4760e2e0..00ae24e0 100644 --- a/inst/include/armadillo_bits/op_mean_meat.hpp +++ b/inst/include/armadillo_bits/op_mean_meat.hpp @@ -435,17 +435,42 @@ op_mean::mean_all(const T1& X) arma_debug_sigprint(); typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; - const quasi_unwrap U(X); + eT result = eT(0); - if(U.M.n_elem == 0) + if( (is_Mat::stored_type>::value == false) && (Proxy::use_at == false) && (Proxy::use_mp == false) && (is_fp16::no) ) { - arma_conform_check(true, "mean(): object has no elements"); + arma_debug_print("op_mean::mean_all(): using proxy"); + + const Proxy P(X); + + if(P.get_n_elem() == 0) + { + arma_conform_check(true, "mean(): object has no elements"); + + return Datum::nan; + } + + result = op_mean::mean_all_proxy(P); + } + else + { + arma_debug_print("op_mean::mean_all(): using quasi_unwrap"); + + const quasi_unwrap U(X); + + if(U.M.n_elem == 0) + { + arma_conform_check(true, "mean(): object has no elements"); + + return Datum::nan; + } - return Datum::nan; + result = op_mean::direct_mean(U.M.memptr(), U.M.n_elem); } - return op_mean::direct_mean(U.M.memptr(), U.M.n_elem); + return result; } @@ -453,27 +478,70 @@ op_mean::mean_all(const T1& X) template inline typename T1::elem_type -op_mean::mean_all(const Op& in) +op_mean::mean_all_proxy(const Proxy& P) { arma_debug_sigprint(); typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; - const uword omit_mode = in.aux_uword_a; + const uword N = P.get_n_elem(); - if(arma_config::fast_math_warn) + const typename Proxy::ea_type Pea = P.get_ea(); + + eT acc1 = eT(0); + eT acc2 = eT(0); + + uword i,j; + + for(i=0, j=1; j < N; i+=2, j+=2) { - if(omit_mode == 1) { arma_warn(1, "omit_nan(): detection of NaN is not reliable in fast math mode"); } - if(omit_mode == 2) { arma_warn(1, "omit_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } + acc1 += Pea[i]; + acc2 += Pea[j]; } - const quasi_unwrap U(in.m); + if(i < N) + { + acc1 += Pea[i]; + } + + const eT mean = (acc1 + acc2) / T(N); + + if(arma_isfinite(mean)) { return mean; } - if(U.M.n_elem == 0) + // handle possible overflow + + eT r_mean = eT(0); + + for(uword ii=0; ii < N; ++ii) { - arma_conform_check(true, "mean(): object has no elements"); + const eT val = Pea[ii]; - return Datum::nan; + if(arma_isnonfinite(val)) { return mean; } + + r_mean = r_mean + (val - r_mean) / T(ii+1); + } + + return r_mean; + } + + + +template +inline +typename T1::elem_type +op_mean::mean_all(const Op& in) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const uword omit_mode = in.aux_uword_a; + + if(arma_config::fast_math_warn) + { + if(omit_mode == 1) { arma_warn(1, "omit_nan(): detection of NaN is not reliable in fast math mode"); } + if(omit_mode == 2) { arma_warn(1, "omit_nonfinite(): detection of non-finite values is not reliable in fast math mode"); } } auto is_omitted_1 = [](const eT& x) -> bool { return arma_isnan(x); }; @@ -481,8 +549,34 @@ op_mean::mean_all(const Op& in) eT result = eT(0); - if(omit_mode == 1) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_1); } - if(omit_mode == 2) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_2); } + if( (is_Mat::stored_type>::value == false) && (Proxy::use_at == false) && (Proxy::use_mp == false) ) + { + const Proxy P(in.m); + + if(P.get_n_elem() == 0) + { + arma_conform_check(true, "mean(): object has no elements"); + + return Datum::nan; + } + + if(omit_mode == 1) { result = op_mean::mean_all_omit(P, is_omitted_1); } + if(omit_mode == 2) { result = op_mean::mean_all_omit(P, is_omitted_2); } + } + else + { + const quasi_unwrap U(in.m); + + if(U.M.n_elem == 0) + { + arma_conform_check(true, "mean(): object has no elements"); + + return Datum::nan; + } + + if(omit_mode == 1) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_1); } + if(omit_mode == 2) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_2); } + } return result; } @@ -535,6 +629,55 @@ op_mean::mean_all_omit(const eT* X_mem, const uword N, functor is_omitted) +template +inline +typename T1::elem_type +op_mean::mean_all_omit(const Proxy& P, functor is_omitted) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + typedef typename T1::pod_type T; + + const uword N = P.get_n_elem(); + + uword count = 0; + eT acc = eT(0); + + for(uword i=0; i < N; ++i) + { + const eT val = P[i]; + + if(is_omitted(val) == false) { acc += val; ++count; } + } + + acc /= T(count); + + if(arma_isfinite(acc)) { return acc; } + + // handle possible overflow + + eT r_mean = eT(0); + + count = 0; + + for(uword i=0; i < N; ++i) + { + const eT val = P[i]; + + if(is_omitted(val) == false) + { + r_mean = r_mean + (val - r_mean) / T(count+1); // kept as count+1 to use same algorithm as op_mean::direct_mean_robust() + + ++count; + } + } + + return r_mean; + } + + + // diff --git a/inst/include/armadillo_bits/op_norm2est_meat.hpp b/inst/include/armadillo_bits/op_norm2est_meat.hpp index 9149d21c..badabde1 100644 --- a/inst/include/armadillo_bits/op_norm2est_meat.hpp +++ b/inst/include/armadillo_bits/op_norm2est_meat.hpp @@ -110,8 +110,8 @@ op_norm2est::norm2est typedef typename T1::pod_type T; typedef typename T1::elem_type eT; - arma_conform_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" ); - arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); + arma_conform_check( ((tolerance >= T(0)) == false), "norm2est(): parameter 'tolerance' must be > 0" ); + arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance); @@ -190,8 +190,8 @@ op_norm2est::norm2est typedef typename T1::pod_type T; typedef typename T1::elem_type eT; - arma_conform_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" ); - arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); + arma_conform_check( ((tolerance >= T(0)) == false), "norm2est(): parameter 'tolerance' must be > 0" ); + arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" ); const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance); diff --git a/inst/include/armadillo_bits/op_orth_null_meat.hpp b/inst/include/armadillo_bits/op_orth_null_meat.hpp index 2275d008..13308ff9 100644 --- a/inst/include/armadillo_bits/op_orth_null_meat.hpp +++ b/inst/include/armadillo_bits/op_orth_null_meat.hpp @@ -54,7 +54,7 @@ op_orth::apply_direct(Mat& out, const Base= 0"); + arma_conform_check( ((tol >= T(0)) == false), "orth(): tolerance must be > 0" ); Mat U; Col< T> s; @@ -141,7 +141,7 @@ op_null::apply_direct(Mat& out, const Base= 0"); + arma_conform_check( ((tol >= T(0)) == false), "null(): tolerance must be > 0" ); Mat U; Col< T> s; diff --git a/inst/include/armadillo_bits/op_pinv_meat.hpp b/inst/include/armadillo_bits/op_pinv_meat.hpp index 00842ff8..65365a2b 100644 --- a/inst/include/armadillo_bits/op_pinv_meat.hpp +++ b/inst/include/armadillo_bits/op_pinv_meat.hpp @@ -94,7 +94,7 @@ op_pinv::apply_direct(Mat& out, const Base= 0"); + arma_conform_check( ((tol >= T(0)) == false), "pinv(): tolerance must be > 0" ); // method_id = 0 -> default setting // method_id = 1 -> use standard algorithm diff --git a/inst/include/armadillo_bits/op_strans_meat.hpp b/inst/include/armadillo_bits/op_strans_meat.hpp index 216a9bc5..002e26b3 100644 --- a/inst/include/armadillo_bits/op_strans_meat.hpp +++ b/inst/include/armadillo_bits/op_strans_meat.hpp @@ -200,7 +200,7 @@ op_strans::apply_mat_noalias(Mat& out, const TA& A) op_strans::apply_mat_noalias_large(out, A); } else - if( (A_n_rows != 0) && (A_n_cols != 0) ) + if(A_n_cols != 0) { eT* outptr = out.memptr(); diff --git a/inst/include/armadillo_bits/op_wishrnd_meat.hpp b/inst/include/armadillo_bits/op_wishrnd_meat.hpp index 78f6480c..5e9341da 100644 --- a/inst/include/armadillo_bits/op_wishrnd_meat.hpp +++ b/inst/include/armadillo_bits/op_wishrnd_meat.hpp @@ -113,7 +113,7 @@ op_wishrnd::apply_noalias_mode2(Mat& out, const Mat& D, const eT df) { arma_debug_sigprint(); - arma_conform_check( (df <= eT(0)), "df must be greater than zero" ); + arma_conform_check( ((df > eT(0)) == false), "df must be greater than zero" ); arma_conform_check( (D.is_square() == false), "wishrnd(): given matrix must be square sized" ); if(D.is_empty()) { out.reset(); return true; } @@ -256,7 +256,7 @@ op_iwishrnd::apply_noalias_mode2(Mat& out, const Mat& Dinv, const eT df) { arma_debug_sigprint(); - arma_conform_check( (df <= eT(0)), "df must be greater than zero" ); + arma_conform_check( ((df > eT(0)) == false), "df must be greater than zero" ); arma_conform_check( (Dinv.is_square() == false), "iwishrnd(): given matrix must be square sized" ); if(Dinv.is_empty()) { out.reset(); return true; } diff --git a/inst/include/armadillo_bits/sp_auxlib_meat.hpp b/inst/include/armadillo_bits/sp_auxlib_meat.hpp index 8783deaf..680c6676 100644 --- a/inst/include/armadillo_bits/sp_auxlib_meat.hpp +++ b/inst/include/armadillo_bits/sp_auxlib_meat.hpp @@ -503,7 +503,7 @@ sp_auxlib::eigs_sym_arpack(Col& eigval, Mat& eigvec, const SpMat& X, arpack::seupd(&rvec, &howmny, select.memptr(), eigval.memptr(), eigvec.memptr(), &ldz, (eT*) &sigma, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info); // Check for errors. - if(info != 0) { arma_warn(1, "eigs_sym(): ARPACK error ", info, " in seupd()"); return false; } + if(info != 0) { arma_warn(1, "eigs_sym(): arpack::seupd() error: ", info); return false; } return (info == 0); } @@ -890,7 +890,7 @@ sp_auxlib::eigs_gen_arpack(Col< std::complex >& eigval, Mat< std::complex arpack::neupd(&rvec, &howmny, select.memptr(), dr.memptr(), di.memptr(), z.memptr(), &ldz, (T*) &sigmar, (T*) &sigmai, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); // Check for errors. - if(info != 0) { arma_warn(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; } + if(info != 0) { arma_warn(1, "eigs_gen(): arpack::neupd() error: ", info); return false; } // Put it into the outputs. eigval.set_size(n_eigvals); @@ -1138,7 +1138,7 @@ sp_auxlib::eigs_gen(Col< std::complex >& eigval, Mat< std::complex >& eigv (std::complex*) NULL, eigvec.memptr(), &ldz, (std::complex*) &sigma, (std::complex*) NULL, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info); // Check for errors. - if(info != 0) { arma_warn(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; } + if(info != 0) { arma_warn(1, "eigs_gen(): arpack::neupd() error: ", info); return false; } return (info == 0); } @@ -1258,7 +1258,7 @@ sp_auxlib::spsolve_simple(Mat& X, const SpBase& X, typename T1::pod_type& else if( (info == superlu::int_t(A.n_cols+1)) && (user_opts.allow_ugly) ) { - arma_warn(2, "spsolve(): system is singular to working precision (rcond: ", rcond, ")"); + arma_warn(2, "spsolve(): system is singular to working precision; rcond: ", rcond); status = true; } else @@ -1417,7 +1417,7 @@ sp_auxlib::spsolve_refine(Mat& X, typename T1::pod_type& else if(info < 0) { - arma_warn(1, "spsolve(): unknown SuperLU error code from gssvx(): ", info); + arma_warn(1, "spsolve(): superlu::gssvx() error: ", info); } // No need to extract the data from x, since it's using the same memory as X @@ -2013,11 +2013,11 @@ sp_auxlib::run_aupd_plain if(sym) { - arma_warn(1, "eigs_sym(): ARPACK error ", info, " in saupd()"); + arma_warn(1, "eigs_sym(): arpack::saupd() error: ", info); } else { - arma_warn(1, "eigs_gen(): ARPACK error ", info, " in naupd()"); + arma_warn(1, "eigs_gen(): arpack::naupd() error: ", info); } return; // Parent frame can look at the value of info. @@ -2200,7 +2200,7 @@ sp_auxlib::run_aupd_shiftinvert if( (x_rcond < std::numeric_limits::epsilon()) || arma_isnan(x_rcond) ) { - arma_warn(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); + arma_warn(2, "matrix is singular to working precision; rcond: ", x_rcond); info = blas_int(-1); return; } @@ -2270,11 +2270,11 @@ sp_auxlib::run_aupd_shiftinvert if(sym) { - arma_warn(2, "eigs_sym(): ARPACK error ", info, " in saupd()"); + arma_warn(2, "eigs_sym(): arpack::saupd() error: ", info); } else { - arma_warn(2, "eigs_gen(): ARPACK error ", info, " in naupd()"); + arma_warn(2, "eigs_gen(): arpack::naupd() error: ", info); } return; // Parent frame can look at the value of info. diff --git a/inst/include/armadillo_bits/spdiagview_meat.hpp b/inst/include/armadillo_bits/spdiagview_meat.hpp index 721afa61..1d3c4a4e 100644 --- a/inst/include/armadillo_bits/spdiagview_meat.hpp +++ b/inst/include/armadillo_bits/spdiagview_meat.hpp @@ -923,7 +923,7 @@ spdiagview::clamp(const eT min_val, const eT max_val) { arma_debug_sigprint(); - SpMat tmp(*this); + Mat tmp(*this); tmp.clamp(min_val, max_val); diff --git a/inst/include/armadillo_bits/subview_bones.hpp b/inst/include/armadillo_bits/subview_bones.hpp index 4f727737..30cbc933 100644 --- a/inst/include/armadillo_bits/subview_bones.hpp +++ b/inst/include/armadillo_bits/subview_bones.hpp @@ -395,11 +395,16 @@ class subview_col : public subview arma_warn_unused arma_inline const Op,op_strans> as_row() const; + inline void replace(const eT old_val, const eT new_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); + inline void randu(); + inline void randn(); arma_warn_unused inline bool is_finite() const; + arma_warn_unused inline bool is_zero(const pod_type tol = 0) const; arma_warn_unused inline bool has_inf() const; arma_warn_unused inline bool has_nan() const; @@ -555,11 +560,16 @@ class subview_row : public subview arma_warn_unused arma_inline const Op,op_strans> as_col() const; + inline void replace(const eT old_val, const eT new_val); + inline void fill(const eT val); inline void zeros(); inline void ones(); + inline void randu(); + inline void randn(); arma_warn_unused inline bool is_finite() const; + arma_warn_unused inline bool is_zero(const pod_type tol = 0) const; arma_warn_unused inline bool has_inf() const; arma_warn_unused inline bool has_nan() const; diff --git a/inst/include/armadillo_bits/subview_cube_meat.hpp b/inst/include/armadillo_bits/subview_cube_meat.hpp index 76b4ae96..e031e074 100644 --- a/inst/include/armadillo_bits/subview_cube_meat.hpp +++ b/inst/include/armadillo_bits/subview_cube_meat.hpp @@ -1226,12 +1226,12 @@ subview_cube::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview_cube::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview_cube::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview_cube::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "subview_cube::clamp(): imag(min_val) must be less than imag(max_val)" ); } const uword local_n_rows = n_rows; @@ -1395,18 +1395,21 @@ subview_cube::is_zero(const typename get_pod_type::result tol) const { arma_debug_sigprint(); + typedef typename get_pod_type::result T; + + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; const uword local_n_slices = n_slices; - if( (local_n_rows != 0) && (local_n_cols != 0) ) + if( (local_n_rows == 0) || (local_n_cols == 0) || (local_n_slices == 0) ) { return false; } + + for(uword slice = 0; slice < local_n_slices; ++slice) { - for(uword slice = 0; slice < local_n_slices; ++slice) + for(uword col = 0; col < local_n_cols; ++col) { - for(uword col = 0; col < local_n_cols; ++col) - { - if(arrayops::is_zero(slice_colptr(slice,col), local_n_rows, tol) == false) { return false; } - } + if(arrayops::is_zero(slice_colptr(slice,col), local_n_rows, tol) == false) { return false; } } } diff --git a/inst/include/armadillo_bits/subview_meat.hpp b/inst/include/armadillo_bits/subview_meat.hpp index 02bfdc15..e06d475b 100644 --- a/inst/include/armadillo_bits/subview_meat.hpp +++ b/inst/include/armadillo_bits/subview_meat.hpp @@ -979,34 +979,11 @@ subview::replace(const eT old_val, const eT new_val) const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; } + if(s_n_rows == 0) { return; } - if(s_n_rows == 1) + if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) { - Mat& A = const_cast< Mat& >(s.m); - - const uword A_n_rows = A.n_rows; - - eT* Aptr = &(A.at(s.aux_row1,s.aux_col1)); - - if(arma_isnan(old_val)) - { - for(uword ucol=0; ucol < s_n_cols; ++ucol) - { - (*Aptr) = (arma_isnan(*Aptr)) ? new_val : (*Aptr); - - Aptr += A_n_rows; - } - } - else - { - for(uword ucol=0; ucol < s_n_cols; ++ucol) - { - (*Aptr) = ((*Aptr) == old_val) ? new_val : (*Aptr); - - Aptr += A_n_rows; - } - } + arrayops::replace(s.colptr(0), s.n_elem, old_val, new_val); } else { @@ -1050,12 +1027,12 @@ subview::clamp(const eT min_val, const eT max_val) if(is_cx::no) { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): min_val must be less than max_val" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview::clamp(): min_val must be less than max_val" ); } else { - arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): real(min_val) must be less than real(max_val)" ); - arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview::clamp(): imag(min_val) must be less than imag(max_val)" ); + arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview::clamp(): real(min_val) must be less than real(max_val)" ); + arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "subview::clamp(): imag(min_val) must be less than imag(max_val)" ); } subview& s = *this; @@ -1085,33 +1062,17 @@ subview::fill(const eT val) const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; } + if(s_n_rows == 0) { return; } - if(s_n_rows == 1) + if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) { - Mat& A = const_cast< Mat& >(s.m); - - const uword A_n_rows = A.n_rows; - - eT* Aptr = &(A.at(s.aux_row1,s.aux_col1)); - - for(uword ii=0; ii < s_n_cols; ++ii) - { - (*Aptr) = val; Aptr += A_n_rows; - } + arrayops::inplace_set( s.colptr(0), val, s.n_elem ); } else { - if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) + for(uword ucol=0; ucol < s_n_cols; ++ucol) { - arrayops::inplace_set( s.colptr(0), val, s.n_elem ); - } - else - { - for(uword ucol=0; ucol < s_n_cols; ++ucol) - { - arrayops::inplace_set( s.colptr(ucol), val, s_n_rows ); - } + arrayops::inplace_set( s.colptr(ucol), val, s_n_rows ); } } } @@ -1130,35 +1091,17 @@ subview::zeros() const uword s_n_rows = s.n_rows; const uword s_n_cols = s.n_cols; - if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; } + if(s_n_rows == 0) { return; } - if(s_n_rows == 1) + if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) { - Mat& A = const_cast< Mat& >(s.m); - - const uword A_n_rows = A.n_rows; - - eT* Aptr = &(A.at(s.aux_row1,s.aux_col1)); - - constexpr eT eT_zero = eT(0); - - for(uword ii=0; ii < s_n_cols; ++ii) - { - (*Aptr) = eT_zero; Aptr += A_n_rows; - } + arrayops::fill_zeros( s.colptr(0), s.n_elem ); } else { - if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) ) + for(uword ucol=0; ucol < s_n_cols; ++ucol) { - arrayops::fill_zeros( s.colptr(0), s.n_elem ); - } - else - { - for(uword ucol=0; ucol < s_n_cols; ++ucol) - { - arrayops::fill_zeros( s.colptr(ucol), s_n_rows ); - } + arrayops::fill_zeros( s.colptr(ucol), s_n_rows ); } } } @@ -1212,13 +1155,22 @@ subview::randu() if(s_n_rows == 1) { + // NOTE: special handling to ensure that the same sequence is generated as per subview_row::randu() + podarray tmp(s_n_cols); eT* tmp_mem = tmp.memptr(); arma_rng::randu::fill( tmp_mem, s_n_cols ); - for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; } + eT* mem_ptr = startptr(); + + const uword m_n_rows = s.m.n_rows; + + for(uword ii=0; ii < s_n_cols; ++ii) + { + (*mem_ptr) = tmp_mem[ii]; mem_ptr += m_n_rows; + } } else { @@ -1254,13 +1206,22 @@ subview::randn() if(s_n_rows == 1) { + // NOTE: special handling to ensure that the same sequence is generated as per subview_row::randu() + podarray tmp(s_n_cols); eT* tmp_mem = tmp.memptr(); arma_rng::randn::fill( tmp_mem, s_n_cols ); - for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; } + eT* mem_ptr = startptr(); + + const uword m_n_rows = s.m.n_rows; + + for(uword ii=0; ii < s_n_cols; ++ii) + { + (*mem_ptr) = tmp_mem[ii]; mem_ptr += m_n_rows; + } } else { @@ -1578,15 +1539,18 @@ subview::is_zero(const typename get_pod_type::result tol) const { arma_debug_sigprint(); + typedef typename get_pod_type::result T; + + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; - if(local_n_rows != 0) + if( (local_n_rows == 0) || (local_n_cols == 0) ) { return false; } + + for(uword ii=0; ii < local_n_cols; ++ii) { - for(uword ii=0; ii::as_row() const +template +inline +void +subview_col::replace(const eT old_val, const eT new_val) + { + arma_debug_sigprint(); + + arrayops::replace( access::rwp(colmem), subview::n_rows, old_val, new_val ); + } + + + template inline void @@ -3603,6 +3579,30 @@ subview_col::ones() +template +inline +void +subview_col::randu() + { + arma_debug_sigprint(); + + arma_rng::randu::fill( access::rwp(colmem), subview::n_rows ); + } + + + +template +inline +void +subview_col::randn() + { + arma_debug_sigprint(); + + arma_rng::randn::fill( access::rwp(colmem), subview::n_rows ); + } + + + template inline bool @@ -3617,6 +3617,22 @@ subview_col::is_finite() const +template +inline +bool +subview_col::is_zero(const typename get_pod_type::result tol) const + { + arma_debug_sigprint(); + + typedef typename get_pod_type::result T; + + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); + + return arrayops::is_zero(colmem, subview::n_rows, tol); + } + + + template inline bool @@ -4598,6 +4614,40 @@ subview_row::as_col() const +template +inline +void +subview_row::replace(const eT old_val, const eT new_val) + { + arma_debug_sigprint(); + + eT* mem_ptr = access::rwp(rowmem); + + const uword local_s_n_cols = subview::n_cols; + const uword local_m_n_rows = subview::m.n_rows; + + if(arma_isnan(old_val)) + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + eT& val = (*mem_ptr); mem_ptr += local_m_n_rows; + + val = (arma_isnan(val)) ? new_val : val; + } + } + else + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + eT& val = (*mem_ptr); mem_ptr += local_m_n_rows; + + val = (val == old_val) ? new_val : val; + } + } + } + + + template inline void @@ -4642,6 +4692,58 @@ subview_row::ones() +template +inline +void +subview_row::randu() + { + arma_debug_sigprint(); + + const uword local_s_n_cols = subview::n_cols; + const uword local_m_n_rows = subview::m.n_rows; + + podarray tmp(local_s_n_cols); + + eT* tmp_mem = tmp.memptr(); + + arma_rng::randu::fill( tmp_mem, local_s_n_cols ); + + eT* mem_ptr = access::rwp(rowmem); + + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + (*mem_ptr) = tmp_mem[ii]; mem_ptr += local_m_n_rows; + } + } + + + +template +inline +void +subview_row::randn() + { + arma_debug_sigprint(); + + const uword local_s_n_cols = subview::n_cols; + const uword local_m_n_rows = subview::m.n_rows; + + podarray tmp(local_s_n_cols); + + eT* tmp_mem = tmp.memptr(); + + arma_rng::randn::fill( tmp_mem, local_s_n_cols ); + + eT* mem_ptr = access::rwp(rowmem); + + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + (*mem_ptr) = tmp_mem[ii]; mem_ptr += local_m_n_rows; + } + } + + + template inline bool @@ -4668,6 +4770,82 @@ subview_row::is_finite() const +template +inline +bool +subview_row::is_zero(const typename get_pod_type::result tol) const + { + arma_debug_sigprint(); + + typedef typename get_pod_type::result T; + + arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" ); + + const uword local_s_n_cols = subview::n_cols; + const uword local_m_n_rows = subview::m.n_rows; + + if(local_s_n_cols == 0) { return false; } + + const eT* mem_ptr = rowmem; + + if(is_cx::yes) + { + if(tol == T(0)) + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + const eT& val = (*mem_ptr); mem_ptr += local_m_n_rows; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + if(eop_aux::arma_abs(val_real) != T(0)) { return false; } + if(eop_aux::arma_abs(val_imag) != T(0)) { return false; } + } + } + else + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + const eT& val = (*mem_ptr); mem_ptr += local_m_n_rows; + + const T val_real = access::tmp_real(val); + const T val_imag = access::tmp_imag(val); + + // convoluted formulation to handle NaNs + if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; } + if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; } + } + } + } + else // not complex + { + if(tol == T(0)) + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + const eT val = (*mem_ptr); mem_ptr += local_m_n_rows; + + if(val != eT(0)) { return false; } + } + } + else + { + for(uword ii=0; ii < local_s_n_cols; ++ii) + { + const eT val = (*mem_ptr); mem_ptr += local_m_n_rows; + + // convoluted formulation to handle NaNs + if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; } + } + } + } + + return true; + } + + + template inline bool diff --git a/inst/include/armadillo_bits/typedef_elem.hpp b/inst/include/armadillo_bits/typedef_elem.hpp index dfea000c..2466cbce 100644 --- a/inst/include/armadillo_bits/typedef_elem.hpp +++ b/inst/include/armadillo_bits/typedef_elem.hpp @@ -26,7 +26,7 @@ #else #if UCHAR_MAX >= 0xff typedef unsigned char u8; - typedef char s8; + typedef char s8; // kept for compatibility with earlier versions of Armadillo #elif defined(UINT8_MAX) typedef uint8_t u8; typedef int8_t s8;