diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b1f17e2d..7c8f376a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -30,6 +30,11 @@ jobs: - name: Setup uses: eddelbuettel/github-actions/r-ci@master + - name: Setup ccache for R + uses: eddelbuettel/github-actions/ccache-with-R@master + with: + key: ${{ matrix.name }}-${{ matrix.openmp }} + - name: Configure run: ./configure; cat src/Makevars diff --git a/ChangeLog b/ChangeLog index 6a00f94b..919ab55c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2026-07-09 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): RcppArmadillo 15.4.1-1 + * inst/NEWS.Rd: Idem + * configure.ac: Idem + * configure: Idem + + * inst/include/armadillo_bits/: Armadillo 15.4.1 + + * .github/workflows/ci.yaml: Enable ccache in matrix + 2026-06-18 Dirk Eddelbuettel * DESCRIPTION (Version, Date): RcppArmadillo 15.4.0-1 diff --git a/DESCRIPTION b/DESCRIPTION index 65fdf3d5..0fc38ff3 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.4.0-1 -Date: 2026-06-17 +Version: 15.4.1-1 +Date: 2026-07-09 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/configure b/configure index d000293c..52db7a7d 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.72 for RcppArmadillo 15.4.0-1. +# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.4.1-1. # # Report bugs to . # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RcppArmadillo' PACKAGE_TARNAME='rcpparmadillo' -PACKAGE_VERSION='15.4.0-1' -PACKAGE_STRING='RcppArmadillo 15.4.0-1' +PACKAGE_VERSION='15.4.1-1' +PACKAGE_STRING='RcppArmadillo 15.4.1-1' PACKAGE_BUGREPORT='edd@debian.org' PACKAGE_URL='' @@ -1223,7 +1223,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 15.4.0-1 to adapt to many kinds of systems. +'configure' configures RcppArmadillo 15.4.1-1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1285,7 +1285,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RcppArmadillo 15.4.0-1:";; + short | recursive ) echo "Configuration of RcppArmadillo 15.4.1-1:";; esac cat <<\_ACEOF @@ -1366,7 +1366,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RcppArmadillo configure 15.4.0-1 +RcppArmadillo configure 15.4.1-1 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1482,7 +1482,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 15.4.0-1, which was +It was created by RcppArmadillo $as_me 15.4.1-1, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3946,7 +3946,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 15.4.0-1, which was +This file was extended by RcppArmadillo $as_me 15.4.1-1, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4001,7 +4001,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 15.4.0-1 +RcppArmadillo config.status 15.4.1-1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 38accb23..95836716 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],[15.4.0-1],[edd@debian.org]) +AC_INIT([RcppArmadillo],[15.4.1-1],[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 a55e772f..6d1c6b7e 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,16 @@ \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 15.4.1-1 [github-only] (2026-07-09)}{ + \itemize{ + \item Upgraded to Armadillo release 15.4.1 (Medium Roast Agave) + \itemize{ + \item Fix for rare infinite recursion bug in sparse version of \code{diagmat()} + \item More efficient checks for aliasing + } + } +} + \section{Changes in RcppArmadillo version 15.4.0-1 (2026-06-17)}{ \itemize{ \item Upgraded to Armadillo release 15.4.0 (Medium Roast Agave) diff --git a/inst/include/armadillo_bits/Mat_bones.hpp b/inst/include/armadillo_bits/Mat_bones.hpp index a56e4f7b..e68144db 100644 --- a/inst/include/armadillo_bits/Mat_bones.hpp +++ b/inst/include/armadillo_bits/Mat_bones.hpp @@ -938,6 +938,12 @@ class Mat::fixed : public Mat arma_warn_unused arma_inline eT* memptr(); arma_warn_unused arma_inline const eT* memptr() const; + arma_inline subview_row row(const uword row_num); + arma_inline const subview_row row(const uword row_num) const; + + arma_inline subview_col col(const uword col_num); + arma_inline const subview_col col(const uword col_num) const; + arma_warn_unused arma_inline bool is_vec() const; inline const Mat& fill(const eT val); diff --git a/inst/include/armadillo_bits/Mat_meat.hpp b/inst/include/armadillo_bits/Mat_meat.hpp index b2e3d272..df18a054 100644 --- a/inst/include/armadillo_bits/Mat_meat.hpp +++ b/inst/include/armadillo_bits/Mat_meat.hpp @@ -10746,6 +10746,66 @@ Mat::fixed::memptr() const +template +template +arma_inline +subview_row +Mat::fixed::row(const uword row_num) + { + arma_debug_sigprint(); + + arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" ); + + return subview_row(*this, row_num); + } + + + +template +template +arma_inline +const subview_row +Mat::fixed::row(const uword row_num) const + { + arma_debug_sigprint(); + + arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" ); + + return subview_row(*this, row_num); + } + + + +template +template +arma_inline +subview_col +Mat::fixed::col(const uword col_num) + { + arma_debug_sigprint(); + + arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" ); + + return subview_col(*this, col_num); + } + + + +template +template +arma_inline +const subview_col +Mat::fixed::col(const uword col_num) const + { + arma_debug_sigprint(); + + arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" ); + + return subview_col(*this, col_num); + } + + + template template arma_inline diff --git a/inst/include/armadillo_bits/SpBase_bones.hpp b/inst/include/armadillo_bits/SpBase_bones.hpp index 66b66105..29533b58 100644 --- a/inst/include/armadillo_bits/SpBase_bones.hpp +++ b/inst/include/armadillo_bits/SpBase_bones.hpp @@ -52,8 +52,6 @@ struct SpBase { arma_inline const derived& get_ref() const; - arma_inline bool is_alias(const SpMat& X) const; - arma_warn_unused inline const SpOp t() const; //!< Hermitian transpose arma_warn_unused inline const SpOp ht() const; //!< Hermitian transpose arma_warn_unused inline const SpOp st() const; //!< simple transpose diff --git a/inst/include/armadillo_bits/SpBase_meat.hpp b/inst/include/armadillo_bits/SpBase_meat.hpp index dab1f5cb..1f4fb24f 100644 --- a/inst/include/armadillo_bits/SpBase_meat.hpp +++ b/inst/include/armadillo_bits/SpBase_meat.hpp @@ -31,16 +31,6 @@ SpBase::get_ref() const -template -arma_inline -bool -SpBase::is_alias(const SpMat& X) const - { - return (*this).get_ref().is_alias(X); - } - - - template inline const SpOp diff --git a/inst/include/armadillo_bits/SpGlue_bones.hpp b/inst/include/armadillo_bits/SpGlue_bones.hpp index 6d69c1cc..4495cb35 100644 --- a/inst/include/armadillo_bits/SpGlue_bones.hpp +++ b/inst/include/armadillo_bits/SpGlue_bones.hpp @@ -37,7 +37,8 @@ struct SpGlue : public SpBase< typename T1::elem_type, SpGlue& X) const; + template + arma_inline bool is_alias(const SpMat& X) const; const T1& A; //!< first operand; must be derived from SpBase const T2& B; //!< second operand; must be derived from SpBase diff --git a/inst/include/armadillo_bits/SpGlue_meat.hpp b/inst/include/armadillo_bits/SpGlue_meat.hpp index 4fa35d6e..0f3aa8d3 100644 --- a/inst/include/armadillo_bits/SpGlue_meat.hpp +++ b/inst/include/armadillo_bits/SpGlue_meat.hpp @@ -54,9 +54,10 @@ SpGlue::~SpGlue() template +template arma_inline bool -SpGlue::is_alias(const SpMat& X) const +SpGlue::is_alias(const SpMat& X) const { return (A.is_alias(X) || B.is_alias(X)); } diff --git a/inst/include/armadillo_bits/SpMat_bones.hpp b/inst/include/armadillo_bits/SpMat_bones.hpp index 05c795a9..3d48c9eb 100644 --- a/inst/include/armadillo_bits/SpMat_bones.hpp +++ b/inst/include/armadillo_bits/SpMat_bones.hpp @@ -649,7 +649,8 @@ class SpMat : public SpBase< eT, SpMat > template inline void init_xform_mt(const SpBase& x, const Functor& func); //! don't use this unless you're writing internal Armadillo code - arma_inline bool is_alias(const SpMat& X) const; + template + arma_inline bool is_alias(const SpMat& X) const; protected: diff --git a/inst/include/armadillo_bits/SpMat_meat.hpp b/inst/include/armadillo_bits/SpMat_meat.hpp index acb9eb7e..fa652898 100644 --- a/inst/include/armadillo_bits/SpMat_meat.hpp +++ b/inst/include/armadillo_bits/SpMat_meat.hpp @@ -6015,11 +6015,14 @@ SpMat::init_xform_mt(const SpBase& A, const Functor& func) template +template arma_inline bool -SpMat::is_alias(const SpMat& X) const +SpMat::is_alias(const SpMat& X) const { - return (&X == this); + arma_debug_sigprint(); + + return (is_same_type::yes) && (void_ptr(this) == void_ptr(&X)); } diff --git a/inst/include/armadillo_bits/SpOp_bones.hpp b/inst/include/armadillo_bits/SpOp_bones.hpp index c46834c3..271b654c 100644 --- a/inst/include/armadillo_bits/SpOp_bones.hpp +++ b/inst/include/armadillo_bits/SpOp_bones.hpp @@ -38,7 +38,8 @@ struct SpOp : public SpBase< typename T1::elem_type, SpOp > inline SpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); inline ~SpOp(); - arma_inline bool is_alias(const SpMat& X) const; + template + arma_inline bool is_alias(const SpMat& X) const; const T1& m; //!< the operand; must be derived from SpBase elem_type aux; //!< auxiliary data, using the element type as used by T1 diff --git a/inst/include/armadillo_bits/SpOp_meat.hpp b/inst/include/armadillo_bits/SpOp_meat.hpp index 86a14d43..6bbc6ff6 100644 --- a/inst/include/armadillo_bits/SpOp_meat.hpp +++ b/inst/include/armadillo_bits/SpOp_meat.hpp @@ -64,9 +64,10 @@ SpOp::~SpOp() template +template arma_inline bool -SpOp::is_alias(const SpMat& X) const +SpOp::is_alias(const SpMat& X) const { return m.is_alias(X); } diff --git a/inst/include/armadillo_bits/SpSubview_bones.hpp b/inst/include/armadillo_bits/SpSubview_bones.hpp index fdb36240..ce64d7bb 100644 --- a/inst/include/armadillo_bits/SpSubview_bones.hpp +++ b/inst/include/armadillo_bits/SpSubview_bones.hpp @@ -323,7 +323,8 @@ class SpSubview : public SpBase< eT, SpSubview > inline const_row_iterator end_row(const uword row_num) const; //! don't use this unless you're writing internal Armadillo code - arma_inline bool is_alias(const SpMat& X) const; + template + arma_inline bool is_alias(const SpMat& X) const; private: diff --git a/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp b/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp index 47ed069f..cb04ee6e 100644 --- a/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp +++ b/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp @@ -89,6 +89,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list > inline static void schur_inplace(SpMat& out, const SpSubview_col_list& in); inline static void div_inplace(SpMat& out, const SpSubview_col_list& in); + template + arma_inline bool is_alias(const SpMat& X) const; friend class SpMat; }; diff --git a/inst/include/armadillo_bits/SpSubview_col_list_meat.hpp b/inst/include/armadillo_bits/SpSubview_col_list_meat.hpp index 5ca7456c..cbc81e91 100644 --- a/inst/include/armadillo_bits/SpSubview_col_list_meat.hpp +++ b/inst/include/armadillo_bits/SpSubview_col_list_meat.hpp @@ -714,4 +714,15 @@ SpSubview_col_list::div_inplace(SpMat& out, const SpSubview_col_list& +template +template +arma_inline +bool +SpSubview_col_list::is_alias(const SpMat& X) const + { + return m.is_alias(X); + } + + + //! @} diff --git a/inst/include/armadillo_bits/SpSubview_meat.hpp b/inst/include/armadillo_bits/SpSubview_meat.hpp index dda6dab0..0abb4108 100644 --- a/inst/include/armadillo_bits/SpSubview_meat.hpp +++ b/inst/include/armadillo_bits/SpSubview_meat.hpp @@ -1786,9 +1786,10 @@ SpSubview::end_row(const uword row_num) const template +template arma_inline bool -SpSubview::is_alias(const SpMat& X) const +SpSubview::is_alias(const SpMat& X) const { return m.is_alias(X); } diff --git a/inst/include/armadillo_bits/arma_version.hpp b/inst/include/armadillo_bits/arma_version.hpp index 00ea4cc2..50d053dd 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 4 -#define ARMA_VERSION_PATCH 0 +#define ARMA_VERSION_PATCH 1 #define ARMA_VERSION_NAME "Medium Roast Agave" diff --git a/inst/include/armadillo_bits/diskio_meat.hpp b/inst/include/armadillo_bits/diskio_meat.hpp index 53285666..e4112ee1 100644 --- a/inst/include/armadillo_bits/diskio_meat.hpp +++ b/inst/include/armadillo_bits/diskio_meat.hpp @@ -1865,7 +1865,7 @@ diskio::load_csv_ascii(Mat& x, std::istream& f, std::string& err_msg, const try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; } - if(strict) { x.fill(Datum::nan); } // take into account that each row may have a unique number of columns + if(strict && is_real::yes) { x.fill(Datum::nan); } // take into account that each row may have a unique number of columns const bool use_mp = (arma_config::openmp) && (f_n_rows >= 2) && (f_n_cols >= 64); diff --git a/inst/include/armadillo_bits/memory.hpp b/inst/include/armadillo_bits/memory.hpp index 49f4ac36..3e1f9071 100644 --- a/inst/include/armadillo_bits/memory.hpp +++ b/inst/include/armadillo_bits/memory.hpp @@ -22,9 +22,8 @@ struct memory { - template arma_malloc inline static eT* acquire(const uword n_elem); - - template arma_inline static void release(eT* mem); + template arma_inline static eT* acquire(const uword n_elem); + template arma_inline static void release( eT* mem ); template arma_inline static bool is_aligned(const eT* mem); template arma_inline static void mark_as_aligned( eT*& mem); @@ -33,9 +32,10 @@ struct memory +// NOTE: arma_inline is used as a partial workaround for bugs in GCC 15: +// NOTE: false positive warnings from -Wmismatched-new-delete and -Wmaybe-uninitialized template -arma_malloc -inline +arma_inline eT* memory::acquire(const uword n_elem) { diff --git a/inst/include/armadillo_bits/mtSpOp_meat.hpp b/inst/include/armadillo_bits/mtSpOp_meat.hpp index 9a851d85..dd0081ca 100644 --- a/inst/include/armadillo_bits/mtSpOp_meat.hpp +++ b/inst/include/armadillo_bits/mtSpOp_meat.hpp @@ -94,7 +94,7 @@ arma_inline bool mtSpOp::is_alias(const SpMat& X) const { - return (void_ptr(&X) == void_ptr(&m)); + return m.is_alias(X); } diff --git a/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp b/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp index 60d75b7e..418bb2f8 100644 --- a/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp +++ b/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp @@ -52,6 +52,9 @@ struct mtSpReduceOp : public SpBase< out_eT, mtSpReduceOp > inline mtSpReduceOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); inline ~mtSpReduceOp(); + template + arma_inline bool is_alias(const SpMat& X) const; + const T1& m; //!< the operand; must be derived from SpBase uword aux_uword_a; //!< auxiliary data, uword format uword aux_uword_b; //!< auxiliary data, uword format diff --git a/inst/include/armadillo_bits/mtSpReduceOp_meat.hpp b/inst/include/armadillo_bits/mtSpReduceOp_meat.hpp index 531ce239..fd87b9ae 100644 --- a/inst/include/armadillo_bits/mtSpReduceOp_meat.hpp +++ b/inst/include/armadillo_bits/mtSpReduceOp_meat.hpp @@ -52,4 +52,15 @@ mtSpReduceOp::~mtSpReduceOp() +template +template +arma_inline +bool +mtSpReduceOp::is_alias(const SpMat& X) const + { + return m.is_alias(X); + } + + + //! @} diff --git a/inst/include/armadillo_bits/op_diagmat_bones.hpp b/inst/include/armadillo_bits/op_diagmat_bones.hpp index 91ded0bc..e072a18c 100644 --- a/inst/include/armadillo_bits/op_diagmat_bones.hpp +++ b/inst/include/armadillo_bits/op_diagmat_bones.hpp @@ -27,6 +27,9 @@ struct op_diagmat template inline static void apply(Mat& out, const Op& X); + template + inline static void apply(Mat_noalias& out, const Op& X); + template inline static void apply(Mat& out, const Proxy& P); @@ -48,6 +51,9 @@ struct op_diagmat2 template inline static void apply(Mat& out, const Op& X); + template + inline static void apply(Mat_noalias& out, const Op& X); + template inline static void apply(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset); }; diff --git a/inst/include/armadillo_bits/op_diagmat_meat.hpp b/inst/include/armadillo_bits/op_diagmat_meat.hpp index 1dd0e58a..5f59f84b 100644 --- a/inst/include/armadillo_bits/op_diagmat_meat.hpp +++ b/inst/include/armadillo_bits/op_diagmat_meat.hpp @@ -104,6 +104,20 @@ op_diagmat::apply(Mat& out, const Op& X) +template +inline +void +op_diagmat::apply(Mat_noalias& out, const Op& X) + { + arma_debug_sigprint(); + + const Proxy P(X.m); + + op_diagmat::apply(out, P); + } + + + template inline void @@ -701,6 +715,23 @@ op_diagmat2::apply(Mat& out, const Op& +template +inline +void +op_diagmat2::apply(Mat_noalias& out, const Op& X) + { + arma_debug_sigprint(); + + const uword row_offset = X.aux_uword_a; + const uword col_offset = X.aux_uword_b; + + const Proxy P(X.m); + + op_diagmat2::apply(out, P, row_offset, col_offset); + } + + + template inline void diff --git a/inst/include/armadillo_bits/op_diagvec_bones.hpp b/inst/include/armadillo_bits/op_diagvec_bones.hpp index 64bd7cb1..68461681 100644 --- a/inst/include/armadillo_bits/op_diagvec_bones.hpp +++ b/inst/include/armadillo_bits/op_diagvec_bones.hpp @@ -27,6 +27,9 @@ struct op_diagvec template inline static void apply(Mat& out, const Op& X); + template + inline static void apply(Mat_noalias& out, const Op& X); + template inline static void apply_proxy(Mat& out, const Proxy& P); @@ -45,6 +48,9 @@ struct op_diagvec2 template inline static void apply(Mat& out, const Op& X); + template + inline static void apply(Mat_noalias& out, const Op& X); + template inline static void apply_proxy(Mat& out, const Proxy& P, const uword row_offset, const uword col_offset); }; diff --git a/inst/include/armadillo_bits/op_diagvec_meat.hpp b/inst/include/armadillo_bits/op_diagvec_meat.hpp index 42117a3e..c4ff93b9 100644 --- a/inst/include/armadillo_bits/op_diagvec_meat.hpp +++ b/inst/include/armadillo_bits/op_diagvec_meat.hpp @@ -48,6 +48,20 @@ op_diagvec::apply(Mat& out, const Op& X) +template +inline +void +op_diagvec::apply(Mat_noalias& out, const Op& X) + { + arma_debug_sigprint(); + + const Proxy P(X.m); + + op_diagvec::apply_proxy(out, P); + } + + + template inline void @@ -491,6 +505,26 @@ op_diagvec2::apply(Mat& out, const Op& +template +inline +void +op_diagvec2::apply(Mat_noalias& out, const Op& X) + { + arma_debug_sigprint(); + + const uword a = X.aux_uword_a; + const uword b = X.aux_uword_b; + + const uword row_offset = (b > 0) ? a : 0; + const uword col_offset = (b == 0) ? a : 0; + + const Proxy P(X.m); + + op_diagvec2::apply_proxy(out, P, row_offset, col_offset); + } + + + template inline void diff --git a/inst/include/armadillo_bits/op_repelem_bones.hpp b/inst/include/armadillo_bits/op_repelem_bones.hpp index 0f58c952..d826a262 100644 --- a/inst/include/armadillo_bits/op_repelem_bones.hpp +++ b/inst/include/armadillo_bits/op_repelem_bones.hpp @@ -28,6 +28,8 @@ struct op_repelem template inline static void apply_noalias(Mat& out, const obj& X, const uword copies_per_row, const uword copies_per_col); template inline static void apply(Mat& out, const Op& in); + + template inline static void apply(Mat_noalias& out, const Op& in); }; diff --git a/inst/include/armadillo_bits/op_repelem_meat.hpp b/inst/include/armadillo_bits/op_repelem_meat.hpp index 9da9f431..5e9342a4 100644 --- a/inst/include/armadillo_bits/op_repelem_meat.hpp +++ b/inst/include/armadillo_bits/op_repelem_meat.hpp @@ -100,4 +100,21 @@ op_repelem::apply(Mat& out, const Op& in) +template +inline +void +op_repelem::apply(Mat_noalias& out, const Op& in) + { + arma_debug_sigprint(); + + const uword copies_per_row = in.aux_uword_a; + const uword copies_per_col = in.aux_uword_b; + + const quasi_unwrap U(in.m); + + op_repelem::apply_noalias(out, U.M, copies_per_row, copies_per_col); + } + + + //! @} diff --git a/inst/include/armadillo_bits/op_vectorise_bones.hpp b/inst/include/armadillo_bits/op_vectorise_bones.hpp index eabe2eed..c446f655 100644 --- a/inst/include/armadillo_bits/op_vectorise_bones.hpp +++ b/inst/include/armadillo_bits/op_vectorise_bones.hpp @@ -34,8 +34,6 @@ struct op_vectorise_col template inline static void apply_direct(Mat_noalias& out, const T1& expr); template inline static void apply_subview(Mat& out, const subview& sv); - - template inline static void apply_proxy(Mat& out, const Proxy& P); }; diff --git a/inst/include/armadillo_bits/op_vectorise_meat.hpp b/inst/include/armadillo_bits/op_vectorise_meat.hpp index 27d4e201..40cf856f 100644 --- a/inst/include/armadillo_bits/op_vectorise_meat.hpp +++ b/inst/include/armadillo_bits/op_vectorise_meat.hpp @@ -80,39 +80,12 @@ op_vectorise_col::apply_direct(Mat& out, const T1& expr) } } else - if( (quasi_unwrap::has_orig_mem) || (is_Mat::stored_type>::value) || (arma_config::openmp && Proxy::use_mp) ) { - const quasi_unwrap U(expr); + Mat tmp = expr; - if(U.is_alias(out)) - { - Mat tmp(U.M.memptr(), U.M.n_elem, 1); - - out.steal_mem(tmp); - } - else - { - out.set_size(U.M.n_elem, 1); - - arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem); - } - } - else - { - const Proxy P(expr); + tmp.set_size(tmp.n_elem, 1); - if(P.is_alias(out)) - { - Mat tmp; - - op_vectorise_col::apply_proxy(tmp, P); - - out.steal_mem(tmp); - } - else - { - op_vectorise_col::apply_proxy(out, P); - } + out.steal_mem(tmp); } } @@ -133,12 +106,17 @@ op_vectorise_col::apply(Mat_noalias& out, const Op inline void -op_vectorise_col::apply_direct(Mat_noalias& out, const T1& expr) +op_vectorise_col::apply_direct(Mat_noalias& actual_out, const T1& expr) { arma_debug_sigprint(); typedef typename T1::elem_type eT; + Mat& out = actual_out; + + // no special handling for T1 = Mat, as that currently can't happen; + // the Mat class uses the Mat_noalias type only for delayed expressions + if(is_subview::value) { const subview& sv = reinterpret_cast< const subview& >(expr); @@ -146,19 +124,12 @@ op_vectorise_col::apply_direct(Mat_noalias& out, const T op_vectorise_col::apply_subview(out, sv); } else - if( (quasi_unwrap::has_orig_mem) || (is_Mat::stored_type>::value) || (arma_config::openmp && Proxy::use_mp) ) { - const quasi_unwrap U(expr); - - out.set_size(U.M.n_elem, 1); + Mat tmp = expr; - arrayops::copy(out.memptr(), U.M.memptr(), U.M.n_elem); - } - else - { - const Proxy P(expr); + tmp.set_size(tmp.n_elem, 1); - op_vectorise_col::apply_proxy(out, P); + out.steal_mem(tmp); } } @@ -190,71 +161,6 @@ op_vectorise_col::apply_subview(Mat& out, const subview& sv) -template -inline -void -op_vectorise_col::apply_proxy(Mat& out, const Proxy& P) - { - arma_debug_sigprint(); - - typedef typename T1::elem_type eT; - - const uword N = P.get_n_elem(); - - out.set_size(N, 1); - - if(N == 0) { return; } - - eT* outmem = out.memptr(); - - if(Proxy::use_at == false) - { - // TODO: add handling of aligned access ? - - typename Proxy::ea_type A = P.get_ea(); - - uword i,j; - - for(i=0, j=1; j < N; i+=2, j+=2) - { - const eT tmp_i = A[i]; - const eT tmp_j = A[j]; - - outmem[i] = tmp_i; - outmem[j] = tmp_j; - } - - if(i < N) - { - outmem[i] = A[i]; - } - } - else - { - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - - if(n_rows == 1) - { - for(uword i=0; i < n_cols; ++i) - { - outmem[i] = P.at(0,i); - } - } - else - { - for(uword col=0; col < n_cols; ++col) - for(uword row=0; row < n_rows; ++row) - { - *outmem = P.at(row,col); - outmem++; - } - } - } - } - - - template inline void diff --git a/inst/include/armadillo_bits/spdiagview_bones.hpp b/inst/include/armadillo_bits/spdiagview_bones.hpp index 9f4b24be..269965ef 100644 --- a/inst/include/armadillo_bits/spdiagview_bones.hpp +++ b/inst/include/armadillo_bits/spdiagview_bones.hpp @@ -107,6 +107,9 @@ class spdiagview : public SpBase< eT, spdiagview > inline static void extract(SpMat& out, const spdiagview& in); inline static void extract( Mat& out, const spdiagview& in); + template + arma_inline bool is_alias(const SpMat& X) const; + friend class SpMat; }; diff --git a/inst/include/armadillo_bits/spdiagview_meat.hpp b/inst/include/armadillo_bits/spdiagview_meat.hpp index 480dc256..d7a36841 100644 --- a/inst/include/armadillo_bits/spdiagview_meat.hpp +++ b/inst/include/armadillo_bits/spdiagview_meat.hpp @@ -1076,4 +1076,15 @@ spdiagview::randn() +template +template +arma_inline +bool +spdiagview::is_alias(const SpMat& X) const + { + return m.is_alias(X); + } + + + //! @} diff --git a/inst/include/armadillo_bits/spop_diagmat_bones.hpp b/inst/include/armadillo_bits/spop_diagmat_bones.hpp index f19a1cda..fb61b223 100644 --- a/inst/include/armadillo_bits/spop_diagmat_bones.hpp +++ b/inst/include/armadillo_bits/spop_diagmat_bones.hpp @@ -26,6 +26,9 @@ struct spop_diagmat template inline static void apply(SpMat& out, const SpOp& in); + template + inline static void apply(SpMat_noalias& out, const SpOp& in); + template inline static void apply_noalias(SpMat& out, const SpBase& expr); @@ -40,7 +43,6 @@ struct spop_diagmat template inline static void apply_noalias(SpMat& out, const SpGlue& expr); - }; @@ -51,6 +53,9 @@ struct spop_diagmat2 template inline static void apply(SpMat& out, const SpOp& in); + template + inline static void apply(SpMat_noalias& out, const SpOp& in); + template inline static void apply_noalias(SpMat& out, const SpMat& X, const uword row_offset, const uword col_offset); }; diff --git a/inst/include/armadillo_bits/spop_diagmat_meat.hpp b/inst/include/armadillo_bits/spop_diagmat_meat.hpp index 19503b8c..314e2c89 100644 --- a/inst/include/armadillo_bits/spop_diagmat_meat.hpp +++ b/inst/include/armadillo_bits/spop_diagmat_meat.hpp @@ -46,6 +46,18 @@ spop_diagmat::apply(SpMat& out, const SpOp +inline +void +spop_diagmat::apply(SpMat_noalias& out, const SpOp& in) + { + arma_debug_sigprint(); + + spop_diagmat::apply_noalias(out, in.m); + } + + + template inline void @@ -374,6 +386,23 @@ spop_diagmat2::apply(SpMat& out, const SpOp +inline +void +spop_diagmat2::apply(SpMat_noalias& out, const SpOp& in) + { + arma_debug_sigprint(); + + const uword row_offset = in.aux_uword_a; + const uword col_offset = in.aux_uword_b; + + const unwrap_spmat U(in.m); + + spop_diagmat2::apply_noalias(out, U.M, row_offset, col_offset); + } + + + template inline void