diff --git a/DESCRIPTION b/DESCRIPTION index fd154e80..88c2717c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: RcppArmadillo Type: Package Title: 'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library -Version: 0.12.8.0.0.1 -Date: 2024-02-19 +Version: 0.12.8.1.0 +Date: 2024-03-02 Author: Dirk Eddelbuettel, Romain Francois, Doug Bates, Binxiang Ni, and Conrad Sanderson Maintainer: Dirk Eddelbuettel Description: 'Armadillo' is a templated C++ linear algebra library (by Conrad diff --git a/configure b/configure index 51881b81..fdbc1a34 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for RcppArmadillo 0.12.8.0.0. +# Generated by GNU Autoconf 2.71 for RcppArmadillo 0.12.8.1.0. # # Report bugs to . # @@ -610,8 +610,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RcppArmadillo' PACKAGE_TARNAME='rcpparmadillo' -PACKAGE_VERSION='0.12.8.0.0' -PACKAGE_STRING='RcppArmadillo 0.12.8.0.0' +PACKAGE_VERSION='0.12.8.1.0' +PACKAGE_STRING='RcppArmadillo 0.12.8.1.0' PACKAGE_BUGREPORT='edd@debian.org' PACKAGE_URL='' @@ -1229,7 +1229,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures RcppArmadillo 0.12.8.0.0 to adapt to many kinds of systems. +\`configure' configures RcppArmadillo 0.12.8.1.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1291,7 +1291,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RcppArmadillo 0.12.8.0.0:";; + short | recursive ) echo "Configuration of RcppArmadillo 0.12.8.1.0:";; esac cat <<\_ACEOF @@ -1372,7 +1372,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RcppArmadillo configure 0.12.8.0.0 +RcppArmadillo configure 0.12.8.1.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1486,7 +1486,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RcppArmadillo $as_me 0.12.8.0.0, which was +It was created by RcppArmadillo $as_me 0.12.8.1.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3944,7 +3944,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by RcppArmadillo $as_me 0.12.8.0.0, which was +This file was extended by RcppArmadillo $as_me 0.12.8.1.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3999,7 +3999,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -RcppArmadillo config.status 0.12.8.0.0 +RcppArmadillo config.status 0.12.8.1.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 7fa47ea6..9675a541 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ AC_PREREQ([2.69]) ## Process this file with autoconf to produce a configure script. -AC_INIT([RcppArmadillo],[0.12.8.0.0],[edd@debian.org]) +AC_INIT([RcppArmadillo],[0.12.8.1.0],[edd@debian.org]) ## Set R_HOME, respecting an environment variable if one is set : ${R_HOME=$(R RHOME)} diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 0ed715bf..9852da7f 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,19 @@ \newcommand{\ghpr}{\href{https://github.com/RcppCore/RcppArmadillo/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/RcppCore/RcppArmadillo/issues/#1}{##1}} +\section{Changes in RcppArmadillo version 0.12.8.1.0 (2024-03-02)}{ + \itemize{ + \item Upgraded to Armadillo release 12.8.1 (Cortisol Injector) + \itemize{ + \item Workaround in \code{norm()} for yet another bug in macOS + accelerate framework + } + \item Update README for RcppArmadillo usage counts + \item Update examples to use '#include ' for + faster compilation excluding unused Rcpp features + } +} + \section{Changes in RcppArmadillo version 0.12.8.0.0 (2024-02-06)}{ \itemize{ \item Upgraded to Armadillo release 12.8.0 (Cortisol Injector) diff --git a/inst/include/armadillo_bits/arma_version.hpp b/inst/include/armadillo_bits/arma_version.hpp index 092454dc..70f35c67 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 12 #define ARMA_VERSION_MINOR 8 -#define ARMA_VERSION_PATCH 0 +#define ARMA_VERSION_PATCH 1 #define ARMA_VERSION_NAME "Cortisol Injector" diff --git a/inst/include/armadillo_bits/compiler_setup.hpp b/inst/include/armadillo_bits/compiler_setup.hpp index 775b82a9..7d9bbde5 100644 --- a/inst/include/armadillo_bits/compiler_setup.hpp +++ b/inst/include/armadillo_bits/compiler_setup.hpp @@ -115,7 +115,7 @@ #if defined(__APPLE__) || defined(__apple_build_version__) // NOTE: Apple accelerate framework has broken implementations of functions that return a float value, - // NOTE: such as sdot(), slange(), clange(), slansy(), clanhe(), slangb() + // NOTE: such as sdot(), slange(), clange(), slansy(), clanhe(), slangb(), snrm2(), sasum() #undef ARMA_BLAS_FLOAT_BUG #define ARMA_BLAS_FLOAT_BUG diff --git a/inst/include/armadillo_bits/op_norm_meat.hpp b/inst/include/armadillo_bits/op_norm_meat.hpp index 2f50f14c..05157766 100644 --- a/inst/include/armadillo_bits/op_norm_meat.hpp +++ b/inst/include/armadillo_bits/op_norm_meat.hpp @@ -174,7 +174,7 @@ op_norm::vec_norm_1(const Proxy& P, const typename arma_cx_only::stored_type> R(P.Q); @@ -224,26 +224,32 @@ op_norm::vec_norm_1_direct_std(const Mat& X) const uword N = X.n_elem; const eT* A = X.memptr(); - if(N < uword(32)) + eT out_val = eT(0); + + #if defined(ARMA_USE_ATLAS) { - return op_norm::vec_norm_1_direct_mem(N,A); + arma_extra_debug_print("atlas::cblas_asum()"); + out_val = atlas::cblas_asum(N,A); } - else + #elif defined(ARMA_USE_BLAS) { - #if defined(ARMA_USE_ATLAS) - { - return atlas::cblas_asum(N,A); - } - #elif defined(ARMA_USE_BLAS) + if(has_blas_float_bug::value) { - return blas::asum(N,A); + out_val = op_norm::vec_norm_1_direct_mem(N,A); } - #else + else { - return op_norm::vec_norm_1_direct_mem(N,A); + arma_extra_debug_print("blas::asum()"); + out_val = blas::asum(N,A); } - #endif } + #else + { + out_val = op_norm::vec_norm_1_direct_mem(N,A); + } + #endif + + return (out_val <= eT(0)) ? eT(0) : out_val; } @@ -397,7 +403,7 @@ op_norm::vec_norm_2(const Proxy& P, const typename arma_not_cx::stored_type> tmp(P.Q); @@ -476,7 +482,7 @@ op_norm::vec_norm_2(const Proxy& P, const typename arma_cx_only::stored_type> R(P.Q); @@ -519,36 +525,38 @@ op_norm::vec_norm_2_direct_std(const Mat& X) const uword N = X.n_elem; const eT* A = X.memptr(); - eT result; + eT out_val = eT(0); - if(N < uword(32)) + #if defined(ARMA_USE_ATLAS) { - result = op_norm::vec_norm_2_direct_mem(N,A); + arma_extra_debug_print("atlas::cblas_nrm2()"); + out_val = atlas::cblas_nrm2(N,A); } - else + #elif defined(ARMA_USE_BLAS) { - #if defined(ARMA_USE_ATLAS) + if(has_blas_float_bug::value) { - result = atlas::cblas_nrm2(N,A); + out_val = op_norm::vec_norm_2_direct_mem(N,A); } - #elif defined(ARMA_USE_BLAS) - { - result = blas::nrm2(N,A); - } - #else + else { - result = op_norm::vec_norm_2_direct_mem(N,A); + arma_extra_debug_print("blas::nrm2()"); + out_val = blas::nrm2(N,A); } - #endif } + #else + { + out_val = op_norm::vec_norm_2_direct_mem(N,A); + } + #endif - if( (result != eT(0)) && arma_isfinite(result) ) + if( (out_val != eT(0)) && arma_isfinite(out_val) ) { - return result; + return (out_val < eT(0)) ? eT(0) : out_val; } else { - arma_extra_debug_print("op_norm::vec_norm_2_direct_std(): detected possible underflow or overflow"); + arma_extra_debug_print("detected possible underflow or overflow"); return op_norm::vec_norm_2_direct_robust(X); } @@ -563,7 +571,7 @@ op_norm::vec_norm_2_direct_mem(const uword N, const eT* A) { arma_extra_debug_sigprint(); - eT acc; + eT acc = eT(0); #if (defined(ARMA_SIMPLE_LOOPS) || defined(__FAST_MATH__)) { @@ -673,7 +681,9 @@ op_norm::vec_norm_2_direct_robust(const Mat& X) acc1 += val_i * val_i; } - return ( std::sqrt(acc1 + acc2) * max_val ); + const eT out_val = std::sqrt(acc1 + acc2) * max_val; + + return (out_val <= eT(0)) ? eT(0) : out_val; } @@ -882,9 +892,12 @@ op_norm::mat_norm_2(const Mat& X) if(X.internal_has_nonfinite()) { arma_debug_warn_level(1, "norm(): given matrix has non-finite elements"); } Col S; + svd(S, X); - return (S.n_elem > 0) ? S[0] : T(0); + const T out_val = (S.n_elem > 0) ? S[0] : T(0); + + return (out_val <= T(0)) ? T(0) : out_val; } diff --git a/inst/include/armadillo_bits/spop_norm_meat.hpp b/inst/include/armadillo_bits/spop_norm_meat.hpp index 402ea290..85485068 100644 --- a/inst/include/armadillo_bits/spop_norm_meat.hpp +++ b/inst/include/armadillo_bits/spop_norm_meat.hpp @@ -53,9 +53,12 @@ spop_norm::mat_norm_2(const SpMat& X, const typename arma_real_only::res const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); Col eigval; + eigs_sym(eigval, C, 1); - return (eigval.n_elem > 0) ? T(std::sqrt(eigval[0])) : T(0); + const T out_square_val = (eigval.n_elem > 0) ? T(eigval[0]) : T(0); + + return (out_square_val <= T(0)) ? T(0) : T(std::sqrt(out_square_val)); } @@ -84,9 +87,12 @@ spop_norm::mat_norm_2(const SpMat& X, const typename arma_cx_only::resul const SpMat C = (A.n_rows <= A.n_cols) ? (A*B) : (B*A); Col eigval; + eigs_gen(eigval, C, 1); - return (eigval.n_elem > 0) ? T(std::sqrt(std::real(eigval[0]))) : T(0); + const T out_square_val = (eigval.n_elem > 0) ? T(std::real(eigval[0])) : T(0); + + return (out_square_val <= T(0)) ? T(0) : T(std::sqrt(out_square_val)); } diff --git a/inst/include/armadillo_bits/translate_blas.hpp b/inst/include/armadillo_bits/translate_blas.hpp index 91fb6a2d..0cd98bdb 100644 --- a/inst/include/armadillo_bits/translate_blas.hpp +++ b/inst/include/armadillo_bits/translate_blas.hpp @@ -145,6 +145,9 @@ namespace blas eT result[2]; // paranoia: using two elements instead of one + result[0] = eT(0); + result[1] = eT(0); + blas::gemv(&trans, &m, &n, &alpha, x, &m, y, &inc, &beta, &result[0], &inc); return result[0]; @@ -186,11 +189,14 @@ namespace blas eT result[2]; // paranoia: using two elements instead of one + result[0] = eT(0); + result[1] = eT(0); + blas::gemv(&trans, &m, &n, &alpha, x, &m, y, &inc, &beta, &result[0], &inc); return result[0]; } - + return eT(0); } @@ -205,6 +211,8 @@ namespace blas if(is_float::value) { + // WARNING: sasum() from Accelerate framework (macOS) may return 'double' instead of 'float' + blas_int n = blas_int(n_elem); blas_int inc = 1; @@ -235,6 +243,8 @@ namespace blas if(is_float::value) { + // WARNING: snrm2() from Accelerate framework (macOS) may return 'double' instead of 'float' + blas_int n = blas_int(n_elem); blas_int inc = 1;