From b92cf58a5e67ba2ce5a7e348308f57477a83db2f Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 3 Sep 2026 05:22:48 -0500 Subject: [PATCH 1/2] Armadillo 15.4.90, a first rc for 15.6.0 --- inst/include/armadillo | 6 + .../include/armadillo_bits/BaseCube_bones.hpp | 4 + inst/include/armadillo_bits/BaseCube_meat.hpp | 30 ++ inst/include/armadillo_bits/Cube_bones.hpp | 8 - inst/include/armadillo_bits/Cube_meat.hpp | 76 +--- inst/include/armadillo_bits/Mat_bones.hpp | 10 - inst/include/armadillo_bits/Mat_meat.hpp | 96 ----- inst/include/armadillo_bits/SpMat_bones.hpp | 6 - inst/include/armadillo_bits/SpMat_meat.hpp | 48 --- inst/include/armadillo_bits/arma_version.hpp | 6 +- inst/include/armadillo_bits/field_bones.hpp | 7 - inst/include/armadillo_bits/field_meat.hpp | 48 --- inst/include/armadillo_bits/fn_cubemul.hpp | 63 +++ inst/include/armadillo_bits/fn_permute.hpp | 37 ++ inst/include/armadillo_bits/fn_powext.hpp | 73 ---- inst/include/armadillo_bits/fn_strans.hpp | 20 + inst/include/armadillo_bits/fn_trans.hpp | 36 ++ .../armadillo_bits/glue_cubemul_bones.hpp | 44 +++ .../armadillo_bits/glue_cubemul_meat.hpp | 305 +++++++++++++++ .../armadillo_bits/glue_powext_bones.hpp | 12 - .../armadillo_bits/glue_powext_meat.hpp | 359 ------------------ .../armadillo_bits/glue_solve_bones.hpp | 3 + .../armadillo_bits/glue_solve_meat.hpp | 23 +- .../armadillo_bits/op_htrans_bones.hpp | 11 + .../include/armadillo_bits/op_htrans_meat.hpp | 86 +++++ .../armadillo_bits/op_permute_bones.hpp | 34 ++ .../armadillo_bits/op_permute_meat.hpp | 184 +++++++++ .../armadillo_bits/op_strans_bones.hpp | 14 +- .../include/armadillo_bits/op_strans_meat.hpp | 48 ++- inst/include/armadillo_bits/strip.hpp | 104 +++++ inst/include/armadillo_bits/traits.hpp | 45 +-- 31 files changed, 1050 insertions(+), 796 deletions(-) create mode 100644 inst/include/armadillo_bits/fn_cubemul.hpp create mode 100644 inst/include/armadillo_bits/fn_permute.hpp create mode 100644 inst/include/armadillo_bits/glue_cubemul_bones.hpp create mode 100644 inst/include/armadillo_bits/glue_cubemul_meat.hpp create mode 100644 inst/include/armadillo_bits/op_permute_bones.hpp create mode 100644 inst/include/armadillo_bits/op_permute_meat.hpp diff --git a/inst/include/armadillo b/inst/include/armadillo index ebeab003..cf9644a4 100644 --- a/inst/include/armadillo +++ b/inst/include/armadillo @@ -342,6 +342,7 @@ namespace arma #include "armadillo_bits/op_row_as_mat_bones.hpp" #include "armadillo_bits/op_col_as_mat_bones.hpp" #include "armadillo_bits/op_accu_bones.hpp" + #include "armadillo_bits/op_permute_bones.hpp" #include "armadillo_bits/op_sp_plus_bones.hpp" #include "armadillo_bits/op_sp_minus_bones.hpp" #include "armadillo_bits/op_sp_sum_bones.hpp" @@ -381,6 +382,7 @@ namespace arma #include "armadillo_bits/glue_mvnrnd_bones.hpp" #include "armadillo_bits/glue_quantile_bones.hpp" #include "armadillo_bits/glue_powext_bones.hpp" + #include "armadillo_bits/glue_cubemul_bones.hpp" #include "armadillo_bits/gmm_misc_bones.hpp" #include "armadillo_bits/gmm_diag_bones.hpp" @@ -616,6 +618,8 @@ namespace arma #include "armadillo_bits/fn_powext.hpp" #include "armadillo_bits/fn_diags_spdiags.hpp" #include "armadillo_bits/fn_balance.hpp" + #include "armadillo_bits/fn_permute.hpp" + #include "armadillo_bits/fn_cubemul.hpp" #include "armadillo_bits/fn_speye.hpp" #include "armadillo_bits/fn_spones.hpp" @@ -802,6 +806,7 @@ namespace arma #include "armadillo_bits/op_row_as_mat_meat.hpp" #include "armadillo_bits/op_col_as_mat_meat.hpp" #include "armadillo_bits/op_accu_meat.hpp" + #include "armadillo_bits/op_permute_meat.hpp" #include "armadillo_bits/op_sp_plus_meat.hpp" #include "armadillo_bits/op_sp_minus_meat.hpp" #include "armadillo_bits/op_sp_sum_meat.hpp" @@ -841,6 +846,7 @@ namespace arma #include "armadillo_bits/glue_mvnrnd_meat.hpp" #include "armadillo_bits/glue_quantile_meat.hpp" #include "armadillo_bits/glue_powext_meat.hpp" + #include "armadillo_bits/glue_cubemul_meat.hpp" #include "armadillo_bits/gmm_misc_meat.hpp" #include "armadillo_bits/gmm_diag_meat.hpp" diff --git a/inst/include/armadillo_bits/BaseCube_bones.hpp b/inst/include/armadillo_bits/BaseCube_bones.hpp index 5a765dab..54629785 100644 --- a/inst/include/armadillo_bits/BaseCube_bones.hpp +++ b/inst/include/armadillo_bits/BaseCube_bones.hpp @@ -53,6 +53,10 @@ struct BaseCube { arma_inline const derived& get_ref() const; + arma_warn_unused inline const OpCube t() const; + arma_warn_unused inline const OpCube ht() const; + arma_warn_unused inline const OpCube st() const; + arma_cold inline void print( const std::string extra_text = "") const; arma_cold inline void print(std::ostream& user_stream, const std::string extra_text = "") const; diff --git a/inst/include/armadillo_bits/BaseCube_meat.hpp b/inst/include/armadillo_bits/BaseCube_meat.hpp index 59b0ef7e..2d5a9898 100644 --- a/inst/include/armadillo_bits/BaseCube_meat.hpp +++ b/inst/include/armadillo_bits/BaseCube_meat.hpp @@ -31,6 +31,36 @@ BaseCube::get_ref() const +template +inline +const OpCube +BaseCube::t() const + { + return OpCube( static_cast(*this) ); + } + + + +template +inline +const OpCube +BaseCube::ht() const + { + return OpCube( static_cast(*this) ); + } + + + +template +inline +const OpCube +BaseCube::st() const + { + return OpCube( static_cast(*this) ); + } + + + template inline void diff --git a/inst/include/armadillo_bits/Cube_bones.hpp b/inst/include/armadillo_bits/Cube_bones.hpp index f3f1f83a..fd3eb2d0 100644 --- a/inst/include/armadillo_bits/Cube_bones.hpp +++ b/inst/include/armadillo_bits/Cube_bones.hpp @@ -406,14 +406,6 @@ class Cube : public BaseCube< eT, Cube > arma_cold inline bool load(const hdf5_name& spec, const file_type type = hdf5_binary); arma_cold inline bool load( std::istream& is, const file_type type = auto_detect); - [[deprecated("use save() instead")]] inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; - [[deprecated("use save() instead")]] inline bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; - [[deprecated("use save() instead")]] inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; - - [[deprecated("use load() instead")]] inline bool quiet_load(const std::string name, const file_type type = auto_detect); - [[deprecated("use load() instead")]] inline bool quiet_load(const hdf5_name& spec, const file_type type = hdf5_binary); - [[deprecated("use load() instead")]] inline bool quiet_load( std::istream& is, const file_type type = auto_detect); - // iterators diff --git a/inst/include/armadillo_bits/Cube_meat.hpp b/inst/include/armadillo_bits/Cube_meat.hpp index 508ddc6e..2a838cda 100644 --- a/inst/include/armadillo_bits/Cube_meat.hpp +++ b/inst/include/armadillo_bits/Cube_meat.hpp @@ -4716,7 +4716,7 @@ Cube::save(const hdf5_name& spec, const file_type type) const { Cube tmp; - op_strans_cube::apply_noalias(tmp, (*this)); + op_strans::apply_cube_noalias(tmp, (*this)); save_okay = diskio::save_hdf5_binary(tmp, spec, err_msg); } @@ -4879,7 +4879,7 @@ Cube::load(const hdf5_name& spec, const file_type type) load_okay = diskio::load_hdf5_binary(tmp, spec, err_msg); - if(load_okay) { op_strans_cube::apply_noalias((*this), tmp); } + if(load_okay) { op_strans::apply_cube_noalias((*this), tmp); } } else { @@ -4967,78 +4967,6 @@ Cube::load(std::istream& is, const file_type type) -template -inline -bool -Cube::quiet_save(const std::string name, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(name, type); - } - - - -template -inline -bool -Cube::quiet_save(const hdf5_name& spec, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(spec, type); - } - - - -template -inline -bool -Cube::quiet_save(std::ostream& os, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(os, type); - } - - - -template -inline -bool -Cube::quiet_load(const std::string name, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(name, type); - } - - - -template -inline -bool -Cube::quiet_load(const hdf5_name& spec, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(spec, type); - } - - - -template -inline -bool -Cube::quiet_load(std::istream& is, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(is, type); - } - - - template inline typename Cube::iterator diff --git a/inst/include/armadillo_bits/Mat_bones.hpp b/inst/include/armadillo_bits/Mat_bones.hpp index e68144db..b8578576 100644 --- a/inst/include/armadillo_bits/Mat_bones.hpp +++ b/inst/include/armadillo_bits/Mat_bones.hpp @@ -583,16 +583,6 @@ class Mat : public Base< eT, Mat > arma_cold inline bool load(const csv_name& spec, const file_type type = csv_ascii); arma_cold inline bool load( std::istream& is, const file_type type = auto_detect); - [[deprecated("use save() instead")]] inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; - [[deprecated("use save() instead")]] inline bool quiet_save(const hdf5_name& spec, const file_type type = hdf5_binary) const; - [[deprecated("use save() instead")]] inline bool quiet_save(const csv_name& spec, const file_type type = csv_ascii) const; - [[deprecated("use save() instead")]] inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; - - [[deprecated("use load() instead")]] inline bool quiet_load(const std::string name, const file_type type = auto_detect); - [[deprecated("use load() instead")]] inline bool quiet_load(const hdf5_name& spec, const file_type type = hdf5_binary); - [[deprecated("use load() instead")]] inline bool quiet_load(const csv_name& spec, const file_type type = csv_ascii); - [[deprecated("use load() instead")]] inline bool quiet_load( std::istream& is, const file_type type = auto_detect); - // for container-like functionality diff --git a/inst/include/armadillo_bits/Mat_meat.hpp b/inst/include/armadillo_bits/Mat_meat.hpp index df18a054..9a3d3408 100644 --- a/inst/include/armadillo_bits/Mat_meat.hpp +++ b/inst/include/armadillo_bits/Mat_meat.hpp @@ -8990,102 +8990,6 @@ Mat::load(std::istream& is, const file_type type) -template -inline -bool -Mat::quiet_save(const std::string name, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(name, type); - } - - - -template -inline -bool -Mat::quiet_save(const hdf5_name& spec, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(spec, type); - } - - - -template -inline -bool -Mat::quiet_save(const csv_name& spec, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(spec, type); - } - - - -template -inline -bool -Mat::quiet_save(std::ostream& os, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(os, type); - } - - - -template -inline -bool -Mat::quiet_load(const std::string name, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(name, type); - } - - - -template -inline -bool -Mat::quiet_load(const hdf5_name& spec, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(spec, type); - } - - - -template -inline -bool -Mat::quiet_load(const csv_name& spec, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(spec, type); - } - - - -template -inline -bool -Mat::quiet_load(std::istream& is, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(is, type); - } - - - template inline Mat::row_iterator::row_iterator() diff --git a/inst/include/armadillo_bits/SpMat_bones.hpp b/inst/include/armadillo_bits/SpMat_bones.hpp index 3d48c9eb..8a89af79 100644 --- a/inst/include/armadillo_bits/SpMat_bones.hpp +++ b/inst/include/armadillo_bits/SpMat_bones.hpp @@ -401,12 +401,6 @@ class SpMat : public SpBase< eT, SpMat > arma_cold inline bool load(const csv_name& spec, const file_type type = csv_ascii); arma_cold inline bool load( std::istream& is, const file_type type = arma_binary); - [[deprecated("use save() instead")]] inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; - [[deprecated("use save() instead")]] inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; - - [[deprecated("use load() instead")]] inline bool quiet_load(const std::string name, const file_type type = arma_binary); - [[deprecated("use load() instead")]] inline bool quiet_load( std::istream& is, const file_type type = arma_binary); - // necessary forward declarations diff --git a/inst/include/armadillo_bits/SpMat_meat.hpp b/inst/include/armadillo_bits/SpMat_meat.hpp index fa652898..8445e634 100644 --- a/inst/include/armadillo_bits/SpMat_meat.hpp +++ b/inst/include/armadillo_bits/SpMat_meat.hpp @@ -5000,54 +5000,6 @@ SpMat::load(std::istream& is, const file_type type) -template -inline -bool -SpMat::quiet_save(const std::string name, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(name, type); - } - - - -template -inline -bool -SpMat::quiet_save(std::ostream& os, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(os, type); - } - - - -template -inline -bool -SpMat::quiet_load(const std::string name, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(name, type); - } - - - -template -inline -bool -SpMat::quiet_load(std::istream& is, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(is, type); - } - - - /** * Initialize the matrix to the specified size. Data is not preserved, so the matrix is assumed to be entirely sparse (empty). */ diff --git a/inst/include/armadillo_bits/arma_version.hpp b/inst/include/armadillo_bits/arma_version.hpp index 42fc5a8a..89cb799f 100644 --- a/inst/include/armadillo_bits/arma_version.hpp +++ b/inst/include/armadillo_bits/arma_version.hpp @@ -22,9 +22,9 @@ #define ARMA_VERSION_MAJOR 15 -#define ARMA_VERSION_MINOR 4 -#define ARMA_VERSION_PATCH 2 -#define ARMA_VERSION_NAME "Medium Roast Agave" +#define ARMA_VERSION_MINOR 5 +#define ARMA_VERSION_PATCH 90 +#define ARMA_VERSION_NAME "experimental" diff --git a/inst/include/armadillo_bits/field_bones.hpp b/inst/include/armadillo_bits/field_bones.hpp index 4785f371..219e1d8b 100644 --- a/inst/include/armadillo_bits/field_bones.hpp +++ b/inst/include/armadillo_bits/field_bones.hpp @@ -221,13 +221,6 @@ class field arma_cold inline bool load( std::istream& is, const file_type type = auto_detect); - [[deprecated]] inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; - [[deprecated]] inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; - - [[deprecated]] inline bool quiet_load(const std::string name, const file_type type = auto_detect); - [[deprecated]] inline bool quiet_load( std::istream& is, const file_type type = auto_detect); - - // for container-like functionality typedef oT value_type; diff --git a/inst/include/armadillo_bits/field_meat.hpp b/inst/include/armadillo_bits/field_meat.hpp index 4786bc8c..077a7fa2 100644 --- a/inst/include/armadillo_bits/field_meat.hpp +++ b/inst/include/armadillo_bits/field_meat.hpp @@ -2079,54 +2079,6 @@ field::load(std::istream& is, const file_type type) -template -inline -bool -field::quiet_save(const std::string name, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(name, type); - } - - - -template -inline -bool -field::quiet_save(std::ostream& os, const file_type type) const - { - arma_debug_sigprint(); - - return (*this).save(os, type); - } - - - -template -inline -bool -field::quiet_load(const std::string name, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(name, type); - } - - - -template -inline -bool -field::quiet_load(std::istream& is, const file_type type) - { - arma_debug_sigprint(); - - return (*this).load(is, type); - } - - - //! construct a field from a given field template inline diff --git a/inst/include/armadillo_bits/fn_cubemul.hpp b/inst/include/armadillo_bits/fn_cubemul.hpp new file mode 100644 index 00000000..27ab05e7 --- /dev/null +++ b/inst/include/armadillo_bits/fn_cubemul.hpp @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_cubemul +//! @{ + + + +template +arma_warn_unused +inline +const GlueCube +cubemul(const BaseCube& A, const BaseCube& B) + { + arma_debug_sigprint(); + + return GlueCube(A.get_ref(), B.get_ref()); + } + + + +template +arma_warn_unused +inline +Cube +cubemul(const BaseCube& A, const Base& B) + { + arma_debug_sigprint(); + + return glue_cubemul::apply(A.get_ref(), B.get_ref()); + } + + + +template +arma_warn_unused +inline +Cube +cubemul(const Base& A, const BaseCube& B) + { + arma_debug_sigprint(); + + return glue_cubemul::apply(A.get_ref(), B.get_ref()); + } + + + +//! @} diff --git a/inst/include/armadillo_bits/fn_permute.hpp b/inst/include/armadillo_bits/fn_permute.hpp new file mode 100644 index 00000000..97a11687 --- /dev/null +++ b/inst/include/armadillo_bits/fn_permute.hpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup fn_permute +//! @{ + + + +template +arma_warn_unused +inline +const OpCube +permute(const BaseCube& expr, const uword dim0_map, const uword dim1_map, const uword dim2_map) + { + arma_debug_sigprint(); + + return OpCube(expr.get_ref(), dim0_map, dim1_map, dim2_map); + } + + + +//! @} diff --git a/inst/include/armadillo_bits/fn_powext.hpp b/inst/include/armadillo_bits/fn_powext.hpp index d42226c5..db6bddd2 100644 --- a/inst/include/armadillo_bits/fn_powext.hpp +++ b/inst/include/armadillo_bits/fn_powext.hpp @@ -43,23 +43,6 @@ pow -template -[[deprecated("refactor your code to use pow() in conjunction with repmat()")]] -inline -Mat -pow - ( - const subview_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - return glue_powext::apply(X,Y); - } - - - template arma_warn_unused inline @@ -77,23 +60,6 @@ pow -template -[[deprecated("refactor your code to use pow() in conjunction with repcube()")]] -inline -Cube -pow - ( - const subview_cube_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - return glue_powext::apply(X,Y); - } - - - // @@ -120,28 +86,6 @@ pow -template -[[deprecated("refactor your code to use pow() in conjunction with repmat()")]] -inline -typename -enable_if2 - < - is_cx::yes, - Mat - >::result -pow - ( - const subview_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - return glue_powext_cx::apply(X,Y); - } - - - template arma_warn_unused inline @@ -159,21 +103,4 @@ pow -template -[[deprecated("refactor your code to use pow() in conjunction with repcube()")]] -inline -Cube< std::complex > -pow - ( - const subview_cube_each1< std::complex >& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - return glue_powext_cx::apply(X,Y); - } - - - //! @} diff --git a/inst/include/armadillo_bits/fn_strans.hpp b/inst/include/armadillo_bits/fn_strans.hpp index a78b43c9..21c7db23 100644 --- a/inst/include/armadillo_bits/fn_strans.hpp +++ b/inst/include/armadillo_bits/fn_strans.hpp @@ -63,6 +63,26 @@ strans +// + + + +template +arma_warn_unused +inline +const OpCube +strans + ( + const BaseCube& expr + ) + { + arma_debug_sigprint(); + + return OpCube(expr.get_ref()); + } + + + // // handling of sparse matrices diff --git a/inst/include/armadillo_bits/fn_trans.hpp b/inst/include/armadillo_bits/fn_trans.hpp index 64ae8795..c04ba2d2 100644 --- a/inst/include/armadillo_bits/fn_trans.hpp +++ b/inst/include/armadillo_bits/fn_trans.hpp @@ -56,6 +56,42 @@ htrans +// + + + +template +arma_warn_unused +inline +const OpCube +trans + ( + const BaseCube& expr + ) + { + arma_debug_sigprint(); + + return OpCube(expr.get_ref()); + } + + + +template +arma_warn_unused +inline +const OpCube +htrans + ( + const BaseCube& expr + ) + { + arma_debug_sigprint(); + + return OpCube(expr.get_ref()); + } + + + // // handling of sparse matrices diff --git a/inst/include/armadillo_bits/glue_cubemul_bones.hpp b/inst/include/armadillo_bits/glue_cubemul_bones.hpp new file mode 100644 index 00000000..0432b963 --- /dev/null +++ b/inst/include/armadillo_bits/glue_cubemul_bones.hpp @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup glue_cubemul +//! @{ + + + +struct glue_cubemul + { + template + inline static void apply(Cube& out, const GlueCube& X); + + template + inline static void apply_noalias(Cube& out, const Cube& A, const Cube& B); + + // + + template + inline static Cube apply(const BaseCube& expr_A, const Base& expr_B); + + template + inline static Cube apply(const Base& expr_A, const BaseCube& expr_B); + }; + + + +//! @} diff --git a/inst/include/armadillo_bits/glue_cubemul_meat.hpp b/inst/include/armadillo_bits/glue_cubemul_meat.hpp new file mode 100644 index 00000000..8cb8ec98 --- /dev/null +++ b/inst/include/armadillo_bits/glue_cubemul_meat.hpp @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + +//! \addtogroup glue_cubemul +//! @{ + + + +template +inline +void +glue_cubemul::apply(Cube& out, const GlueCube& X) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const strip_trans SA(X.A); + const strip_trans SB(X.B); + + constexpr bool do_strans_A = strip_trans::do_strans; + constexpr bool do_htrans_A = strip_trans::do_htrans; + + constexpr bool do_strans_B = strip_trans::do_strans; + constexpr bool do_htrans_B = strip_trans::do_htrans; + + const unwrap_cube::stored_type> UA(SA.M); + const unwrap_cube::stored_type> UB(SB.M); + + const Cube& A = UA.M; + const Cube& B = UB.M; + + if(UA.is_alias(out) || UB.is_alias(out)) + { + Cube tmp; + + glue_cubemul::apply_noalias(tmp, A, B); + + out.steal_mem(tmp); + } + else + { + glue_cubemul::apply_noalias(out, A, B); + } + } + + + +template +inline +void +glue_cubemul::apply_noalias(Cube& out, const Cube& A, const Cube& B) + { + arma_debug_sigprint(); + + const uword A_n_slices = A.n_slices; + + arma_conform_check( (A_n_slices != B.n_slices), "cubemul(): given cubes must have the same number of slices" ); + + constexpr bool do_xtrans_A = (do_strans_A || do_htrans_A); + constexpr bool do_xtrans_B = (do_strans_B || do_htrans_B); + + const uword final_A_n_rows = (do_xtrans_A == false) ? A.n_rows : A.n_cols; + const uword final_A_n_cols = (do_xtrans_A == false) ? A.n_cols : A.n_rows; + + const uword final_B_n_rows = (do_xtrans_B == false) ? B.n_rows : B.n_cols; + const uword final_B_n_cols = (do_xtrans_B == false) ? B.n_cols : B.n_rows; + + if( (arma_config::check_conform) && (final_A_n_cols != final_B_n_rows) ) + { + std::ostringstream tmp; + + tmp << "cubemul(): incompatible dimensions: " << final_A_n_rows << 'x' << final_A_n_cols << 'x' << A.n_slices << " and " << final_B_n_rows << 'x' << final_B_n_cols << 'x' << B.n_slices; + + arma_stop_logic_error(tmp.str()); + } + + out.set_size(final_A_n_rows, final_B_n_cols, A_n_slices); + + if(out.is_empty()) { return; } + + for(uword s=0; s < A_n_slices; ++s) + { + const Mat A_slice_s(const_cast(A.slice_memptr(s)), A.n_rows, A.n_cols, false, true); + const Mat B_slice_s(const_cast(B.slice_memptr(s)), B.n_rows, B.n_cols, false, true); + + Mat out_slice_s(out.slice_memptr(s), final_A_n_rows, final_B_n_cols, false, true); + + if( (do_xtrans_A == false) && (do_xtrans_B == false) ) + { + out_slice_s = A_slice_s * B_slice_s; + } + else + if( (do_xtrans_A == false) && (do_xtrans_B == true ) ) + { + if(do_strans_B) { out_slice_s = A_slice_s * strans(B_slice_s); } + else if(do_htrans_B) { out_slice_s = A_slice_s * htrans(B_slice_s); } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == false) ) + { + if(do_strans_A) { out_slice_s = strans(A_slice_s) * B_slice_s; } + else if(do_htrans_A) { out_slice_s = htrans(A_slice_s) * B_slice_s; } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == true ) ) + { + if( (do_strans_A) && (do_strans_B) ) { out_slice_s = strans(A_slice_s) * strans(B_slice_s); } + else if( (do_strans_A) && (do_htrans_B) ) { out_slice_s = strans(A_slice_s) * htrans(B_slice_s); } + else if( (do_htrans_A) && (do_strans_B) ) { out_slice_s = htrans(A_slice_s) * strans(B_slice_s); } + else if( (do_htrans_A) && (do_htrans_B) ) { out_slice_s = htrans(A_slice_s) * htrans(B_slice_s); } + } + } + } + + + +// + + + +template +inline +Cube +glue_cubemul::apply(const BaseCube& expr_A, const Base& expr_B) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const strip_trans SA(expr_A.get_ref()); + const strip_trans SB(expr_B.get_ref()); + + constexpr bool do_strans_A = strip_trans::do_strans; + constexpr bool do_htrans_A = strip_trans::do_htrans; + + constexpr bool do_strans_B = strip_trans::do_strans; + constexpr bool do_htrans_B = strip_trans::do_htrans; + + const unwrap_cube::stored_type> UA(SA.M); + const quasi_unwrap::stored_type> UB(SB.M); + + const Cube& A = UA.M; + const Mat& B = UB.M; + + constexpr bool do_xtrans_A = (do_strans_A || do_htrans_A); + constexpr bool do_xtrans_B = (do_strans_B || do_htrans_B); + + const uword final_A_n_rows = (do_xtrans_A == false) ? A.n_rows : A.n_cols; + const uword final_A_n_cols = (do_xtrans_A == false) ? A.n_cols : A.n_rows; + + const uword final_B_n_rows = (do_xtrans_B == false) ? B.n_rows : B.n_cols; + const uword final_B_n_cols = (do_xtrans_B == false) ? B.n_cols : B.n_rows; + + if( (arma_config::check_conform) && (final_A_n_cols != final_B_n_rows) ) + { + std::ostringstream tmp; + + tmp << "cubemul(): incompatible dimensions: " << final_A_n_rows << 'x' << final_A_n_cols << 'x' << A.n_slices << " and " << final_B_n_rows << 'x' << final_B_n_cols; + + arma_stop_logic_error(tmp.str()); + } + + Cube out(final_A_n_rows, final_B_n_cols, A.n_slices, arma_nozeros_indicator()); + + if(out.is_empty() == false) + { + for(uword s=0; s < A.n_slices; ++s) + { + const Mat A_slice_s(const_cast(A.slice_memptr(s)), A.n_rows, A.n_cols, false, true); + + Mat out_slice_s(out.slice_memptr(s), final_A_n_rows, final_B_n_cols, false, true); + + if( (do_xtrans_A == false) && (do_xtrans_B == false) ) + { + out_slice_s = A_slice_s * B; + } + else + if( (do_xtrans_A == false) && (do_xtrans_B == true ) ) + { + if(do_strans_B) { out_slice_s = A_slice_s * strans(B); } + else if(do_htrans_B) { out_slice_s = A_slice_s * htrans(B); } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == false) ) + { + if(do_strans_A) { out_slice_s = strans(A_slice_s) * B; } + else if(do_htrans_A) { out_slice_s = htrans(A_slice_s) * B; } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == true ) ) + { + if( (do_strans_A) && (do_strans_B) ) { out_slice_s = strans(A_slice_s) * strans(B); } + else if( (do_strans_A) && (do_htrans_B) ) { out_slice_s = strans(A_slice_s) * htrans(B); } + else if( (do_htrans_A) && (do_strans_B) ) { out_slice_s = htrans(A_slice_s) * strans(B); } + else if( (do_htrans_A) && (do_htrans_B) ) { out_slice_s = htrans(A_slice_s) * htrans(B); } + } + } + } + + return out; + } + + + +template +inline +Cube +glue_cubemul::apply(const Base& expr_A, const BaseCube& expr_B) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const strip_trans SA(expr_A.get_ref()); + const strip_trans SB(expr_B.get_ref()); + + constexpr bool do_strans_A = strip_trans::do_strans; + constexpr bool do_htrans_A = strip_trans::do_htrans; + + constexpr bool do_strans_B = strip_trans::do_strans; + constexpr bool do_htrans_B = strip_trans::do_htrans; + + const quasi_unwrap::stored_type> UA(SA.M); + const unwrap_cube::stored_type> UB(SB.M); + + const Mat& A = UA.M; + const Cube& B = UB.M; + + constexpr bool do_xtrans_A = (do_strans_A || do_htrans_A); + constexpr bool do_xtrans_B = (do_strans_B || do_htrans_B); + + const uword final_A_n_rows = (do_xtrans_A == false) ? A.n_rows : A.n_cols; + const uword final_A_n_cols = (do_xtrans_A == false) ? A.n_cols : A.n_rows; + + const uword final_B_n_rows = (do_xtrans_B == false) ? B.n_rows : B.n_cols; + const uword final_B_n_cols = (do_xtrans_B == false) ? B.n_cols : B.n_rows; + + if( (arma_config::check_conform) && (final_A_n_cols != final_B_n_rows) ) + { + std::ostringstream tmp; + + tmp << "cubemul(): incompatible dimensions: " << final_A_n_rows << 'x' << final_A_n_cols << " and " << final_B_n_rows << 'x' << final_B_n_cols << 'x' << B.n_slices; + + arma_stop_logic_error(tmp.str()); + } + + Cube out(final_A_n_rows, final_B_n_cols, B.n_slices, arma_nozeros_indicator()); + + if(out.is_empty() == false) + { + for(uword s=0; s < B.n_slices; ++s) + { + const Mat B_slice_s(const_cast(B.slice_memptr(s)), B.n_rows, B.n_cols, false, true); + + Mat out_slice_s(out.slice_memptr(s), final_A_n_rows, final_B_n_cols, false, true); + + if( (do_xtrans_A == false) && (do_xtrans_B == false) ) + { + out_slice_s = A * B_slice_s; + } + else + if( (do_xtrans_A == false) && (do_xtrans_B == true ) ) + { + if(do_strans_B) { out_slice_s = A * strans(B_slice_s); } + else if(do_htrans_B) { out_slice_s = A * htrans(B_slice_s); } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == false) ) + { + if(do_strans_A) { out_slice_s = strans(A) * B_slice_s; } + else if(do_htrans_A) { out_slice_s = htrans(A) * B_slice_s; } + } + else + if( (do_xtrans_A == true ) && (do_xtrans_B == true ) ) + { + if( (do_strans_A) && (do_strans_B) ) { out_slice_s = strans(A) * strans(B_slice_s); } + else if( (do_strans_A) && (do_htrans_B) ) { out_slice_s = strans(A) * htrans(B_slice_s); } + else if( (do_htrans_A) && (do_strans_B) ) { out_slice_s = htrans(A) * strans(B_slice_s); } + else if( (do_htrans_A) && (do_htrans_B) ) { out_slice_s = htrans(A) * htrans(B_slice_s); } + } + } + } + + return out; + } + + + +//! @} diff --git a/inst/include/armadillo_bits/glue_powext_bones.hpp b/inst/include/armadillo_bits/glue_powext_bones.hpp index 433fd944..a374d7aa 100644 --- a/inst/include/armadillo_bits/glue_powext_bones.hpp +++ b/inst/include/armadillo_bits/glue_powext_bones.hpp @@ -30,17 +30,11 @@ struct glue_powext template inline static void apply(Mat& out, const Mat& A, const Mat& B); - // TODO: deprecated; remove in next major version - template inline static Mat apply(const subview_each1& X, const Base& Y); - // template inline static void apply(Cube& out, const GlueCube& X); template inline static void apply(Cube& out, const Cube& A, const Cube& B); - - // TODO: deprecated; remove in next major version - template inline static Cube apply(const subview_cube_each1& X, const Base& Y); }; @@ -52,17 +46,11 @@ struct glue_powext_cx template inline static void apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B); - // TODO: deprecated; remove in next major version - template inline static Mat apply(const subview_each1& X, const Base& Y); - // template inline static void apply(Cube& out, const mtGlueCube& X); template inline static void apply(Cube< std::complex >& out, const Cube< std::complex >& A, const Cube& B); - - // TODO: deprecated; remove in next major version - template inline static Cube< std::complex > apply(const subview_cube_each1< std::complex >& X, const Base& Y); }; diff --git a/inst/include/armadillo_bits/glue_powext_meat.hpp b/inst/include/armadillo_bits/glue_powext_meat.hpp index 37de7f18..c0d54d1b 100644 --- a/inst/include/armadillo_bits/glue_powext_meat.hpp +++ b/inst/include/armadillo_bits/glue_powext_meat.hpp @@ -97,117 +97,6 @@ glue_powext::apply(Mat& out, const Mat& A, const Mat& B) -// TODO: deprecated; remove in next major version -template -inline -Mat -glue_powext::apply - ( - const subview_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - typedef typename parent::elem_type eT; - - const parent& A = X.P; - - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - - Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); - - const quasi_unwrap tmp(Y.get_ref()); - const Mat& B = tmp.M; - - X.check_size(B); - - const eT* B_mem = B.memptr(); - - if(mode == 0) // each column - { - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]); - } - } - } - #endif - } - else - { - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]); - } - } - } - } - - if(mode == 1) // each row - { - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - const eT B_val = B_mem[i]; - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = eop_aux::pow(A_mem[row], B_val); - } - } - } - #endif - } - else - { - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - const eT B_val = B_mem[i]; - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = eop_aux::pow(A_mem[row], B_val); - } - } - } - } - - return out; - } - - - template inline void @@ -281,73 +170,6 @@ glue_powext::apply(Cube& out, const Cube& A, const Cube& B) -// TODO: deprecated; remove in next major version -template -inline -Cube -glue_powext::apply - ( - const subview_cube_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - const Cube& A = X.P; - - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - const uword A_n_slices = A.n_slices; - - Cube out(A_n_rows, A_n_cols, A_n_slices, arma_nozeros_indicator()); - - const quasi_unwrap tmp(Y.get_ref()); - const Mat& B = tmp.M; - - X.check_size(B); - - const eT* B_mem = B.memptr(); - const uword B_n_elem = B.n_elem; - - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_slices) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword s=0; s < A_n_slices; ++s) - { - const eT* A_slice_mem = A.slice_memptr(s); - eT* out_slice_mem = out.slice_memptr(s); - - for(uword i=0; i < B_n_elem; ++i) - { - out_slice_mem[i] = eop_aux::pow(A_slice_mem[i], B_mem[i]); - } - } - } - #endif - } - else - { - for(uword s=0; s < A_n_slices; ++s) - { - const eT* A_slice_mem = A.slice_memptr(s); - eT* out_slice_mem = out.slice_memptr(s); - - for(uword i=0; i < B_n_elem; ++i) - { - out_slice_mem[i] = eop_aux::pow(A_slice_mem[i], B_mem[i]); - } - } - } - - return out; - } - - - // @@ -428,118 +250,6 @@ glue_powext_cx::apply(Mat< std::complex >& out, const Mat< std::complex >& -// TODO: deprecated; remove in next major version -template -inline -Mat -glue_powext_cx::apply - ( - const subview_each1& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - typedef typename parent::elem_type eT; - typedef typename parent::pod_type T; - - const parent& A = X.P; - - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - - Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); - - const quasi_unwrap tmp(Y.get_ref()); - const Mat& B = tmp.M; - - X.check_size(B); - - const T* B_mem = B.memptr(); - - if(mode == 0) // each column - { - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = std::pow(A_mem[row], B_mem[row]); - } - } - } - #endif - } - else - { - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = std::pow(A_mem[row], B_mem[row]); - } - } - } - } - - if(mode == 1) // each row - { - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_cols) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - const eT B_val = B_mem[i]; - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = std::pow(A_mem[row], B_val); - } - } - } - #endif - } - else - { - for(uword i=0; i < A_n_cols; ++i) - { - const eT* A_mem = A.colptr(i); - eT* out_mem = out.colptr(i); - - const eT B_val = B_mem[i]; - - for(uword row=0; row < A_n_rows; ++row) - { - out_mem[row] = std::pow(A_mem[row], B_val); - } - } - } - } - - return out; - } - - - template inline void @@ -606,73 +316,4 @@ glue_powext_cx::apply(Cube< std::complex >& out, const Cube< std::complex -// TODO: deprecated; remove in next major version -template -inline -Cube< std::complex > -glue_powext_cx::apply - ( - const subview_cube_each1< std::complex >& X, - const Base& Y - ) - { - arma_debug_sigprint(); - - typedef typename std::complex eT; - - const Cube& A = X.P; - - const uword A_n_rows = A.n_rows; - const uword A_n_cols = A.n_cols; - const uword A_n_slices = A.n_slices; - - Cube out(A_n_rows, A_n_cols, A_n_slices, arma_nozeros_indicator()); - - const quasi_unwrap tmp(Y.get_ref()); - const Mat& B = tmp.M; - - X.check_size(B); - - const T* B_mem = B.memptr(); - const uword B_n_elem = B.n_elem; - - if( arma_config::openmp && mp_gate::eval(A.n_elem) ) - { - #if defined(ARMA_USE_OPENMP) - { - const int n_threads = int( (std::min)(uword(mp_thread_limit::get()), A_n_slices) ); - - #pragma omp parallel for schedule(static) num_threads(n_threads) - for(uword s=0; s < A_n_slices; ++s) - { - const eT* A_slice_mem = A.slice_memptr(s); - eT* out_slice_mem = out.slice_memptr(s); - - for(uword i=0; i < B_n_elem; ++i) - { - out_slice_mem[i] = std::pow(A_slice_mem[i], B_mem[i]); - } - } - } - #endif - } - else - { - for(uword s=0; s < A_n_slices; ++s) - { - const eT* A_slice_mem = A.slice_memptr(s); - eT* out_slice_mem = out.slice_memptr(s); - - for(uword i=0; i < B_n_elem; ++i) - { - out_slice_mem[i] = std::pow(A_slice_mem[i], B_mem[i]); - } - } - } - - return out; - } - - - //! @} diff --git a/inst/include/armadillo_bits/glue_solve_bones.hpp b/inst/include/armadillo_bits/glue_solve_bones.hpp index 49fe2104..babd70f9 100644 --- a/inst/include/armadillo_bits/glue_solve_bones.hpp +++ b/inst/include/armadillo_bits/glue_solve_bones.hpp @@ -133,6 +133,7 @@ namespace solve_opts static constexpr uword flag_no_trimat = uword(1u << 10); static constexpr uword flag_force_approx = uword(1u << 11); static constexpr uword flag_force_sym = uword(1u << 12); + static constexpr uword flag_scale_thresh = uword(1u << 13); struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} }; struct opts_fast : public opts { inline constexpr opts_fast() : opts(flag_fast ) {} }; @@ -148,6 +149,7 @@ namespace solve_opts struct opts_no_trimat : public opts { inline constexpr opts_no_trimat() : opts(flag_no_trimat ) {} }; struct opts_force_approx : public opts { inline constexpr opts_force_approx() : opts(flag_force_approx) {} }; struct opts_force_sym : public opts { inline constexpr opts_force_sym() : opts(flag_force_sym ) {} }; + struct opts_scale_thresh : public opts { inline constexpr opts_scale_thresh() : opts(flag_scale_thresh) {} }; static constexpr opts_none none; static constexpr opts_fast fast; @@ -163,6 +165,7 @@ namespace solve_opts static constexpr opts_no_trimat no_trimat; static constexpr opts_force_approx force_approx; static constexpr opts_force_sym force_sym; + static constexpr opts_scale_thresh scale_thresh; } diff --git a/inst/include/armadillo_bits/glue_solve_meat.hpp b/inst/include/armadillo_bits/glue_solve_meat.hpp index 830f4c85..1d339734 100644 --- a/inst/include/armadillo_bits/glue_solve_meat.hpp +++ b/inst/include/armadillo_bits/glue_solve_meat.hpp @@ -100,6 +100,7 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const const bool no_trimat = has_user_flags && bool(flags & solve_opts::flag_no_trimat ); const bool force_approx = has_user_flags && bool(flags & solve_opts::flag_force_approx); const bool force_sym = has_user_flags && bool(flags & solve_opts::flag_force_sym ); + const bool scale_thresh = has_user_flags && bool(flags & solve_opts::flag_scale_thresh); if(has_user_flags) { @@ -116,6 +117,7 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const if(no_trimat ) { arma_debug_print("no_trimat"); } if(force_approx) { arma_debug_print("force_approx"); } if(force_sym ) { arma_debug_print("force_sym"); } + if(scale_thresh) { arma_debug_print("scale_thresh"); } arma_conform_check( (fast && equilibrate ), "solve(): options 'fast' and 'equilibrate' are mutually exclusive" ); arma_conform_check( (fast && refine ), "solve(): options 'fast' and 'refine' are mutually exclusive" ); @@ -135,6 +137,7 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const if(refine) { arma_warn(2, "solve(): option 'refine' ignored for forced approximate solution" ); } if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for forced approximate solution" ); } if(force_sym) { arma_warn(2, "solve(): option 'force_sym' ignored for forced approximate solution" ); } + if(scale_thresh) { arma_warn(2, "solve(): option 'scale_thresh' ignored for forced approximate solution" ); } return auxlib::solve_approx_svd(actual_out, A, B_expr.get_ref()); // A is overwritten } @@ -162,6 +165,10 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const Mat tmp; Mat& out = (is_alias) ? tmp : actual_out; + const T rcond_threshold = (scale_thresh) ? T(std::numeric_limits::epsilon() * (std::max)(uword(1), (std::max)(A.n_rows, A.n_cols))) : T(std::numeric_limits::epsilon()); + + arma_debug_print("glue_solve_gen_full::apply(): rcond_threshold: ", rcond_threshold); + T rcond = T(0); bool status = false; @@ -364,7 +371,7 @@ glue_solve_gen_full::apply(Mat& actual_out, const Base& A_expr, const } - if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < std::numeric_limits::epsilon()) || arma_isnan(rcond)) ) + if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < rcond_threshold) || arma_isnan(rcond)) ) { status = false; } @@ -380,7 +387,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 close to singular; rcond: ", rcond, "; attempting approx solution"); } // TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten @@ -472,7 +479,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 close to singular; rcond: ", rcond, "; attempting approx solution"); } Mat triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type @@ -530,6 +537,7 @@ glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const const bool no_trimat = bool(flags & solve_opts::flag_no_trimat ); const bool force_approx = bool(flags & solve_opts::flag_force_approx); const bool force_sym = bool(flags & solve_opts::flag_force_sym ); + const bool scale_thresh = bool(flags & solve_opts::flag_scale_thresh); arma_debug_print("glue_solve_tri_full::apply(): enabled flags:"); @@ -544,6 +552,7 @@ glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const if(no_trimat ) { arma_debug_print("no_trimat"); } if(force_approx) { arma_debug_print("force_approx"); } if(force_sym ) { arma_debug_print("force_sym"); } + if(scale_thresh) { arma_debug_print("scale_thresh"); } arma_conform_check( (likely_sympd), "solve(): option 'likely_sympd' not applicable to triangular matrix" ); arma_conform_check( (force_sym ), "solve(): option 'force_sym' not applicable to triangular matrix" ); @@ -566,6 +575,10 @@ glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const if(is_alias) { arma_debug_print("glue_solve_tri_full::apply(): aliasing detected"); } + const T rcond_threshold = (scale_thresh) ? T(std::numeric_limits::epsilon() * (std::max)(uword(1), (std::max)(A.n_rows, A.n_cols))) : T(std::numeric_limits::epsilon()); + + arma_debug_print("glue_solve_tri_full::apply(): rcond_threshold: ", rcond_threshold); + T rcond = T(0); bool status = false; @@ -582,7 +595,7 @@ glue_solve_tri_full::apply(Mat& actual_out, const Base& A_expr, const } - if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < std::numeric_limits::epsilon()) || arma_isnan(rcond)) ) + if( (status == true) && (fast == false) && (allow_ugly == false) && ((rcond < rcond_threshold) || arma_isnan(rcond)) ) { status = false; } @@ -598,7 +611,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 close to 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/op_htrans_bones.hpp b/inst/include/armadillo_bits/op_htrans_bones.hpp index c4293d46..0147c328 100644 --- a/inst/include/armadillo_bits/op_htrans_bones.hpp +++ b/inst/include/armadillo_bits/op_htrans_bones.hpp @@ -83,6 +83,17 @@ struct op_htrans template inline static void apply(Mat_noalias& out, const Op& in, const typename arma_cx_only::result* junk = nullptr); + + // + + template + inline static void apply_cube_noalias(Cube& Y, const Cube& X); + + template + inline static void apply(Cube& out, const OpCube& in, const typename arma_not_cx::result* junk = nullptr); + + template + inline static void apply(Cube& out, const OpCube& in, const typename arma_cx_only::result* junk = nullptr); }; diff --git a/inst/include/armadillo_bits/op_htrans_meat.hpp b/inst/include/armadillo_bits/op_htrans_meat.hpp index cbe952ea..7037afdc 100644 --- a/inst/include/armadillo_bits/op_htrans_meat.hpp +++ b/inst/include/armadillo_bits/op_htrans_meat.hpp @@ -415,6 +415,92 @@ op_htrans::apply(Mat_noalias& out, const Op +inline +void +op_htrans::apply_cube_noalias(Cube& Y, const Cube& X) + { + arma_debug_sigprint(); + + const uword X_nr = X.n_rows; + const uword X_nc = X.n_cols; + const uword X_ns = X.n_slices; + + Y.set_size(X_nc, X_nr, X_ns); + + if(Y.is_empty()) { return; } + + for(uword s=0; s < X_ns; ++s) + { + const Mat X_slice_s(const_cast(X.slice_memptr(s)), X_nr, X_nc, false, true); + Mat Y_slice_s( Y.slice_memptr(s) , X_nc, X_nr, false, true); + + op_htrans::apply_mat_noalias(Y_slice_s, X_slice_s); + } + } + + + +template +inline +void +op_htrans::apply(Cube& out, const OpCube& in, const typename arma_not_cx::result* junk) + { + arma_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(in.m); + + if(U.is_alias(out)) + { + Cube tmp; + + op_strans::apply_cube_noalias(tmp, U.M); + + out.steal_mem(tmp); + } + else + { + op_strans::apply_cube_noalias(out, U.M); + } + } + + + +template +inline +void +op_htrans::apply(Cube& out, const OpCube& in, const typename arma_cx_only::result* junk) + { + arma_debug_sigprint(); + arma_ignore(junk); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(in.m); + + if(U.is_alias(out)) + { + Cube tmp; + + op_htrans::apply_cube_noalias(tmp, U.M); + + out.steal_mem(tmp); + } + else + { + op_htrans::apply_cube_noalias(out, U.M); + } + } + + + // // op_htrans2 diff --git a/inst/include/armadillo_bits/op_permute_bones.hpp b/inst/include/armadillo_bits/op_permute_bones.hpp new file mode 100644 index 00000000..bc91b916 --- /dev/null +++ b/inst/include/armadillo_bits/op_permute_bones.hpp @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_permute +//! @{ + + + +struct op_permute + { + template inline static void apply(Cube& out, const OpCube& in); + + template inline static void apply_noalias(Cube& Y, const Cube& X, const uword d0, const uword d1, const uword d2); + }; + + + +//! @} diff --git a/inst/include/armadillo_bits/op_permute_meat.hpp b/inst/include/armadillo_bits/op_permute_meat.hpp new file mode 100644 index 00000000..24bd6430 --- /dev/null +++ b/inst/include/armadillo_bits/op_permute_meat.hpp @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_permute +//! @{ + + + +template +inline +void +op_permute::apply(Cube& out, const OpCube& in) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(in.m); + const Cube& X = U.M; + + const uword d0 = in.aux_uword_a; + const uword d1 = in.aux_uword_b; + const uword d2 = in.aux_uword_c; + + const bool mapping_ok = (d0 <= uword(2)) && (d1 <= uword(2)) && (d2 <= uword(2)) && (d0 != d1) && (d0 != d2) && (d1 != d2); + + arma_conform_check( (mapping_ok == false), "permute(): each mapping dimension must be unique and one of: 0, 1, 2" ); + + if(U.is_alias(out)) + { + Cube tmp; + + op_permute::apply_noalias(tmp, X, d0, d1, d2); + + out.steal_mem(tmp); + } + else + { + op_permute::apply_noalias(out, X, d0, d1, d2); + } + } + + + +template +inline +void +op_permute::apply_noalias(Cube& Y, const Cube& X, const uword d0, const uword d1, const uword d2) + { + arma_debug_sigprint(); + + const uword X_nr = X.n_rows; + const uword X_nc = X.n_cols; + const uword X_ns = X.n_slices; + + const uword Y_nr = (d0 == uword(0)) ? X_nr : ((d0 == uword(1)) ? X_nc : X_ns); + const uword Y_nc = (d1 == uword(0)) ? X_nr : ((d1 == uword(1)) ? X_nc : X_ns); + const uword Y_ns = (d2 == uword(0)) ? X_nr : ((d2 == uword(1)) ? X_nc : X_ns); + + Y.set_size(Y_nr, Y_nc, Y_ns); + + if(Y.is_empty()) { return; } + + // {0,1,2} -> identity + // {0,2,1} -> swap columns/slices + // {1,0,2} -> transpose each slice + // {1,2,0} -> cyclic permutation + // {2,0,1} -> cyclic permutation + // {2,1,0} -> reverse/transpose-style permutation + + if( (d0 == uword(0)) && (d1 == uword(1)) && (d2 == uword(2)) ) + { + arma_debug_print("mapping {0,1,2}"); + + Y = X; + } + else + if( (d0 == uword(0)) && (d1 == uword(2)) && (d2 == uword(1)) ) + { + arma_debug_print("mapping {0,2,1}"); + + // for(uword s=0; s < X_ns; ++s) + // for(uword c=0; c < X_nc; ++c) + // { + // Y.slice(c).col(s) = X.slice(s).col(c); + // } + + for(uword s=0; s < X_ns; ++s) + { + const Mat X_slice_s(const_cast(X.slice_memptr(s)), X_nr, X_nc, false, true); + + for(uword c=0; c < X_nc; ++c) + { + Mat Y_slice_c(Y.slice_memptr(c), Y_nr, Y_nc, false, true); + + arrayops::copy(Y_slice_c.colptr(s), X_slice_s.colptr(c), X_nr); + } + } + } + else + if( (d0 == uword(1)) && (d1 == uword(0)) && (d2 == uword(2)) ) + { + arma_debug_print("mapping {1,0,2}"); + + // for(uword s=0; s < X_ns; ++s) + // { + // Y.slice(s) = X.slice(s).st(); + // } + + for(uword s=0; s < X_ns; ++s) + { + const Mat X_slice_s(const_cast(X.slice_memptr(s)), X_nr, X_nc, false, true); + Mat Y_slice_s( Y.slice_memptr(s) , Y_nr, Y_nc, false, true); + + op_strans::apply_mat_noalias(Y_slice_s, X_slice_s); + } + } + else + if( (d0 == uword(1)) && (d1 == uword(2)) && (d2 == uword(0)) ) + { + arma_debug_print("mapping {1,2,0}"); + + // better-than-nothing implementation + + for(uword s=0; s < X_ns; ++s) + for(uword c=0; c < X_nc; ++c) + for(uword r=0; r < X_nr; ++r) + { + Y.at(c, s, r) = X.at(r, c, s); + } + } + else + if( (d0 == uword(2)) && (d1 == uword(0)) && (d2 == uword(1)) ) + { + arma_debug_print("mapping {2,0,1}"); + + // better-than-nothing implementation + + for(uword s=0; s < X_ns; ++s) + for(uword c=0; c < X_nc; ++c) + for(uword r=0; r < X_nr; ++r) + { + Y.at(s, r, c) = X.at(r, c, s); + } + } + else + if( (d0 == uword(2)) && (d1 == uword(1)) && (d2 == uword(0)) ) + { + arma_debug_print("mapping {2,1,0}"); + + // better-than-nothing implementation + + for(uword s=0; s < X_ns; ++s) + for(uword c=0; c < X_nc; ++c) + for(uword r=0; r < X_nr; ++r) + { + Y.at(s, c, r) = X.at(r, c, s); + } + } + else + { + arma_stop_logic_error("permute(): unknown permutation"); + } + } + + + +//! @} diff --git a/inst/include/armadillo_bits/op_strans_bones.hpp b/inst/include/armadillo_bits/op_strans_bones.hpp index 546da70e..682e8b14 100644 --- a/inst/include/armadillo_bits/op_strans_bones.hpp +++ b/inst/include/armadillo_bits/op_strans_bones.hpp @@ -72,14 +72,14 @@ struct op_strans template inline static void apply(Mat_noalias& out, const Op& in); - }; - - - -struct op_strans_cube - { + + // + template - inline static void apply_noalias(Cube& out, const Cube& X); + inline static void apply_cube_noalias(Cube& Y, const Cube& X); + + template + inline static void apply(Cube& out, const OpCube& in); }; diff --git a/inst/include/armadillo_bits/op_strans_meat.hpp b/inst/include/armadillo_bits/op_strans_meat.hpp index 8beb9800..a9ca7302 100644 --- a/inst/include/armadillo_bits/op_strans_meat.hpp +++ b/inst/include/armadillo_bits/op_strans_meat.hpp @@ -479,8 +479,6 @@ op_strans::apply(Mat_noalias& out, const Op& out, const Op inline void -op_strans_cube::apply_noalias(Cube& out, const Cube& X) +op_strans::apply_cube_noalias(Cube& Y, const Cube& X) { - out.set_size(X.n_cols, X.n_rows, X.n_slices); + arma_debug_sigprint(); + + const uword X_nr = X.n_rows; + const uword X_nc = X.n_cols; + const uword X_ns = X.n_slices; - for(uword s=0; s < X.n_slices; ++s) + Y.set_size(X_nc, X_nr, X_ns); + + if(Y.is_empty()) { return; } + + for(uword s=0; s < X_ns; ++s) { - Mat out_slice( out.slice_memptr(s), X.n_cols, X.n_rows, false, true ); + const Mat X_slice_s(const_cast(X.slice_memptr(s)), X_nr, X_nc, false, true); + Mat Y_slice_s( Y.slice_memptr(s) , X_nc, X_nr, false, true); - const Mat X_slice( const_cast(X.slice_memptr(s)), X.n_rows, X.n_cols, false, true ); + op_strans::apply_mat_noalias(Y_slice_s, X_slice_s); + } + } + + + +template +inline +void +op_strans::apply(Cube& out, const OpCube& in) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const unwrap_cube U(in.m); + + if(U.is_alias(out)) + { + Cube tmp; + + op_strans::apply_cube_noalias(tmp, U.M); - op_strans::apply_mat_noalias(out_slice, X_slice); + out.steal_mem(tmp); + } + else + { + op_strans::apply_cube_noalias(out, U.M); } } diff --git a/inst/include/armadillo_bits/strip.hpp b/inst/include/armadillo_bits/strip.hpp index 8c34de74..6976cf57 100644 --- a/inst/include/armadillo_bits/strip.hpp +++ b/inst/include/armadillo_bits/strip.hpp @@ -210,6 +210,110 @@ struct strip_op_find_default< mtOp > +template +struct strip_trans + { + typedef T1 stored_type; + + inline + strip_trans(const T1& X) + : M(X) + { + arma_debug_sigprint(); + } + + static constexpr bool do_htrans = false; + static constexpr bool do_strans = false; + + const T1& M; + }; + + + +template +struct strip_trans< Op > + { + typedef T1 stored_type; + + inline + strip_trans(const Op& X) + : M(X.m) + { + arma_debug_sigprint(); + } + + static constexpr bool do_htrans = true; + static constexpr bool do_strans = false; + + const T1& M; + }; + + + +template +struct strip_trans< Op > + { + typedef T1 stored_type; + + inline + strip_trans(const Op& X) + : M(X.m) + { + arma_debug_sigprint(); + } + + static constexpr bool do_htrans = false; + static constexpr bool do_strans = true; + + const T1& M; + }; + + + +template +struct strip_trans< OpCube > + { + typedef T1 stored_type; + + inline + strip_trans(const OpCube& X) + : M(X.m) + { + arma_debug_sigprint(); + } + + static constexpr bool do_htrans = true; + static constexpr bool do_strans = false; + + const T1& M; + }; + + + +template +struct strip_trans< OpCube > + { + typedef T1 stored_type; + + inline + strip_trans(const OpCube& X) + : M(X.m) + { + arma_debug_sigprint(); + } + + static constexpr bool do_htrans = false; + static constexpr bool do_strans = true; + + const T1& M; + }; + + + +// + + + template struct sp_strip_trans { diff --git a/inst/include/armadillo_bits/traits.hpp b/inst/include/armadillo_bits/traits.hpp index bb5bede3..a9903e0a 100644 --- a/inst/include/armadillo_bits/traits.hpp +++ b/inst/include/armadillo_bits/traits.hpp @@ -30,45 +30,26 @@ struct get_pod_type< std::complex > -template -struct is_Mat_fixed_only - { - using yes = char[1]; - using no = char[2]; - - template static yes& check(typename X::Mat_fixed_type*); - template static no& check(...); - - static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); - }; +template +using arma_void_type = void; +template +struct is_Mat_fixed_only { static constexpr bool value = false; }; +template +struct is_Row_fixed_only { static constexpr bool value = false; }; -template -struct is_Row_fixed_only - { - using yes = char[1]; - using no = char[2]; - - template static yes& check(typename X::Row_fixed_type*); - template static no& check(...); - - static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); - }; +template +struct is_Col_fixed_only { static constexpr bool value = false; }; +template +struct is_Mat_fixed_only< T, arma_void_type > { static constexpr bool value = true; }; +template +struct is_Row_fixed_only< T, arma_void_type > { static constexpr bool value = true; }; template -struct is_Col_fixed_only - { - using yes = char[1]; - using no = char[2]; - - template static yes& check(typename X::Col_fixed_type*); - template static no& check(...); - - static constexpr bool value = ( sizeof(check(0)) == sizeof(yes) ); - }; +struct is_Col_fixed_only< T, arma_void_type > { static constexpr bool value = true; }; From 1131e0799a79e49881b635ba4947128867381e9a Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 3 Sep 2026 05:34:09 -0500 Subject: [PATCH 2/2] RcppArmadillo 15.5.90-1 with Armadillo 15.5.90 --- ChangeLog | 9 +++++++++ DESCRIPTION | 4 ++-- configure | 18 +++++++++--------- configure.ac | 2 +- inst/NEWS.Rd | 14 ++++++++++++++ 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 526cab6b..ec14ee10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2026-09-03 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): RcppArmadillo 15.5.90-1 + * inst/NEWS.Rd: Idem + * configure.ac: Idem + * configure: Idem + + * inst/include/armadillo*: Armadillo 15.5.90 aka 15.6.0-rc0 + 2026-07-25 Dirk Eddelbuettel * DESCRIPTION (Version, Date): RcppArmadillo 15.4.2-1 diff --git a/DESCRIPTION b/DESCRIPTION index e1733b54..66ed7aea 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.2-1 -Date: 2026-07-25 +Version: 15.5.90-1 +Date: 2026-09-03 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 3e00dd74..f83d2bce 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.2-1. +# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.5.90-1. # # Report bugs to . # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RcppArmadillo' PACKAGE_TARNAME='rcpparmadillo' -PACKAGE_VERSION='15.4.2-1' -PACKAGE_STRING='RcppArmadillo 15.4.2-1' +PACKAGE_VERSION='15.5.90-1' +PACKAGE_STRING='RcppArmadillo 15.5.90-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.2-1 to adapt to many kinds of systems. +'configure' configures RcppArmadillo 15.5.90-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.2-1:";; + short | recursive ) echo "Configuration of RcppArmadillo 15.5.90-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.2-1 +RcppArmadillo configure 15.5.90-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.2-1, which was +It was created by RcppArmadillo $as_me 15.5.90-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.2-1, which was +This file was extended by RcppArmadillo $as_me 15.5.90-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.2-1 +RcppArmadillo config.status 15.5.90-1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 071ab468..a8649b20 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.2-1],[edd@debian.org]) +AC_INIT([RcppArmadillo],[15.5.90-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 6ae55e8b..c81eb203 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,20 @@ \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.5.90-1 (2026-09-03)}{ + \itemize{ + \item Upgraded to Armadillo release 15.5.90 (experimental) + \itemize{ + \item Expanded \code{solve()} with \code{solve_opts::scale_thresh} + option to widen detection of poorly conditioned systems + \item Expanded \code{trans()} and \code{.t()} to handle cubes + \item Added \code{permute()} to rearrange dimensions of cubes + (generalised transpose) + \item Added \code{cubemul()} for batched matrix multiplication of cube slices + } + } +} + \section{Changes in RcppArmadillo version 15.4.2-1 (2026-07-25)}{ \itemize{ \item Upgraded to Armadillo release 15.4.2 (Medium Roast Agave)