Skip to content

Commit a91a1b6

Browse files
authored
Armadillo 15.2.5 (#505)
* Armadillo 15.2.5 * Roll micro version and date * Flip Ubuntu CI back to non-container * Update NEWS.Rd with Armadillo changes
1 parent 5f34c48 commit a91a1b6

44 files changed

Lines changed: 775 additions & 295 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ jobs:
1414
strategy:
1515
matrix:
1616
include:
17-
- { name: container, os: ubuntu-latest, container: rocker/r2u4ci }
17+
#- { name: container, os: ubuntu-latest, container: rocker/r2u4ci }
1818
- { name: macos, os: macos-latest, openmp: yes }
1919
#- { name: macos, os: macos-latest, openmp: no }
20-
#- { name: ubuntu, os: ubuntu-latest }
20+
- { name: ubuntu, os: ubuntu-latest }
2121

2222

2323
runs-on: ${{ matrix.os }}

ChangeLog

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
2026-04-16 Dirk Eddelbuettel <edd@debian.org>
2+
3+
* DESCRIPTION (Version, Date): Roll micro version and date
4+
5+
* inst/include/armadillo_bits/: Sync with Armadillo 15.2.5
6+
17
2026-04-11 Dirk Eddelbuettel <edd@debian.org>
28

39
* README.md (Rcpp): Updated status section
410

511
2026-03-26 Dirk Eddelbuettel <edd@debian.org>
612

7-
* DESCRIPTION (Version, Date): Roll minor version and date
13+
* DESCRIPTION (Version, Date): Roll micro version and date
814

915
* cleanup: No longer remove vignettes/*.pdf
1016

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: RcppArmadillo
22
Type: Package
33
Title: 'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library
4-
Version: 15.2.4-1.2
5-
Date: 2026-03-26
4+
Version: 15.2.4.99-0
5+
Date: 2026-04-16
66
Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org",
77
comment = c(ORCID = "0000-0001-6419-907X")),
88
person("Romain", "Francois", role = "aut",

inst/NEWS.Rd

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@
33
\newcommand{\ghpr}{\href{https://github.com/RcppCore/RcppArmadillo/pull/#1}{##1}}
44
\newcommand{\ghit}{\href{https://github.com/RcppCore/RcppArmadillo/issues/#1}{##1}}
55

6-
\section{Changes in RcppArmadillo version 15.x.y-1 [unreleased] (2026-xx-yy)}{
6+
\section{Changes in RcppArmadillo version 15.2.5-0 [unreleased] (2026-04-yy)}{
7+
\itemize{
8+
\item Upgraded to Armadillo release 15.2.5 (Medium Roast Deluxe)
9+
\itemize{
10+
\item Fix for handling NaN elements in \code{.is_zero()}
11+
\item Fix for handling NaN in tolerance and conformance checks
12+
\item Faster handling of diagonal views and submatrices with one row
13+
}
14+
}
715
\itemize{
816
\item Sunset the pre-C++14 fallback of including Armadillo 4.6.4 (Dirk in
917
\ghpr{504} closing \ghit{503})

inst/include/armadillo_bits/BaseCube_meat.hpp

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
244244

245245
typedef typename get_pod_type<elem_type>::result T;
246246

247-
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
247+
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
248248

249-
if(ProxyCube<derived>::use_at || is_Cube<typename ProxyCube<derived>::stored_type>::value)
249+
if(is_Cube<typename ProxyCube<derived>::stored_type>::value || ProxyCube<derived>::use_at)
250250
{
251251
const unwrap_cube<derived> U( (*this).get_ref() );
252252

@@ -263,22 +263,52 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
263263

264264
if(is_cx<elem_type>::yes)
265265
{
266-
for(uword i=0; i<n_elem; ++i)
266+
if(tol == T(0))
267267
{
268-
const elem_type val = Pea[i];
269-
270-
const T val_real = access::tmp_real(val);
271-
const T val_imag = access::tmp_imag(val);
272-
273-
if(eop_aux::arma_abs(val_real) > tol) { return false; }
274-
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
268+
for(uword i=0; i < n_elem; ++i)
269+
{
270+
const elem_type val = Pea[i];
271+
272+
const T val_real = access::tmp_real(val);
273+
const T val_imag = access::tmp_imag(val);
274+
275+
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
276+
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
277+
}
278+
}
279+
else
280+
{
281+
for(uword i=0; i < n_elem; ++i)
282+
{
283+
const elem_type val = Pea[i];
284+
285+
const T val_real = access::tmp_real(val);
286+
const T val_imag = access::tmp_imag(val);
287+
288+
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
289+
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
290+
}
275291
}
276292
}
277293
else // not complex
278294
{
279-
for(uword i=0; i < n_elem; ++i)
295+
if(tol == T(0))
296+
{
297+
for(uword i=0; i < n_elem; ++i)
298+
{
299+
const elem_type val = Pea[i];
300+
301+
if(val != elem_type(0)) { return false; }
302+
}
303+
}
304+
else
280305
{
281-
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
306+
for(uword i=0; i < n_elem; ++i)
307+
{
308+
const elem_type val = Pea[i];
309+
310+
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
311+
}
282312
}
283313
}
284314

inst/include/armadillo_bits/Base_meat.hpp

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
352352

353353
if(tol == T(0)) { return (*this).is_symmetric(); }
354354

355-
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
355+
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" );
356356

357357
const quasi_unwrap<derived> U( (*this).get_ref() );
358358

@@ -435,7 +435,7 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
435435

436436
if(tol == T(0)) { return (*this).is_hermitian(); }
437437

438-
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
438+
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" );
439439

440440
const quasi_unwrap<derived> U( (*this).get_ref() );
441441

@@ -464,9 +464,9 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
464464

465465
typedef typename get_pod_type<elem_type>::result T;
466466

467-
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
467+
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
468468

469-
if(Proxy<derived>::use_at || is_Mat<typename Proxy<derived>::stored_type>::value)
469+
if( (quasi_unwrap<derived>::has_orig_mem) || (is_Mat<typename Proxy<derived>::stored_type>::value) || (Proxy<derived>::use_at) )
470470
{
471471
const quasi_unwrap<derived> U( (*this).get_ref() );
472472

@@ -483,22 +483,52 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
483483

484484
if(is_cx<elem_type>::yes)
485485
{
486-
for(uword i=0; i<n_elem; ++i)
486+
if(tol == T(0))
487487
{
488-
const elem_type val = Pea[i];
489-
490-
const T val_real = access::tmp_real(val);
491-
const T val_imag = access::tmp_imag(val);
492-
493-
if(eop_aux::arma_abs(val_real) > tol) { return false; }
494-
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
488+
for(uword i=0; i < n_elem; ++i)
489+
{
490+
const elem_type val = Pea[i];
491+
492+
const T val_real = access::tmp_real(val);
493+
const T val_imag = access::tmp_imag(val);
494+
495+
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
496+
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
497+
}
498+
}
499+
else
500+
{
501+
for(uword i=0; i < n_elem; ++i)
502+
{
503+
const elem_type val = Pea[i];
504+
505+
const T val_real = access::tmp_real(val);
506+
const T val_imag = access::tmp_imag(val);
507+
508+
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
509+
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
510+
}
495511
}
496512
}
497513
else // not complex
498514
{
499-
for(uword i=0; i<n_elem; ++i)
515+
if(tol == T(0))
516+
{
517+
for(uword i=0; i < n_elem; ++i)
518+
{
519+
const elem_type val = Pea[i];
520+
521+
if(val != elem_type(0)) { return false; }
522+
}
523+
}
524+
else
500525
{
501-
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
526+
for(uword i=0; i < n_elem; ++i)
527+
{
528+
const elem_type val = Pea[i];
529+
530+
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
531+
}
502532
}
503533
}
504534

@@ -917,7 +947,7 @@ Base_extra_yes<elem_type,derived>::is_sympd(typename get_pod_type<elem_type>::re
917947

918948
typedef typename get_pod_type<elem_type>::result T;
919949

920-
arma_conform_check( (tol < T(0)), "is_sympd(): parameter 'tol' must be >= 0" );
950+
arma_conform_check( ((tol >= T(0)) == false), "is_sympd(): parameter 'tol' must be >= 0" );
921951

922952
Mat<elem_type> X = static_cast<const derived&>(*this);
923953

inst/include/armadillo_bits/Cube_meat.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4187,12 +4187,12 @@ Cube<eT>::clamp(const eT min_val, const eT max_val)
41874187

41884188
if(is_cx<eT>::no)
41894189
{
4190-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): min_val must be less than max_val" );
4190+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): min_val must be less than max_val" );
41914191
}
41924192
else
41934193
{
4194-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
4195-
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
4194+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
4195+
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
41964196
}
41974197

41984198
arrayops::clamp(memptr(), n_elem, min_val, max_val);

inst/include/armadillo_bits/Mat_meat.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7885,12 +7885,12 @@ Mat<eT>::clamp(const eT min_val, const eT max_val)
78857885

78867886
if(is_cx<eT>::no)
78877887
{
7888-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): min_val must be less than max_val" );
7888+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): min_val must be less than max_val" );
78897889
}
78907890
else
78917891
{
7892-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
7893-
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
7892+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
7893+
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
78947894
}
78957895

78967896
arrayops::clamp(memptr(), n_elem, min_val, max_val);

inst/include/armadillo_bits/SpBase_meat.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
527527

528528
typedef typename get_pod_type<elem_type>::result T;
529529

530-
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
530+
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
531531

532532
const SpProxy<derived> P( (*this).get_ref() );
533533

@@ -554,8 +554,8 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
554554
const T val_real = access::tmp_real(val);
555555
const T val_imag = access::tmp_imag(val);
556556

557-
if(eop_aux::arma_abs(val_real) > tol) { return false; }
558-
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
557+
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
558+
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
559559

560560
++it;
561561
}
@@ -564,7 +564,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
564564
{
565565
while(it != it_end)
566566
{
567-
if(eop_aux::arma_abs(*it) > tol) { return false; }
567+
if( (eop_aux::arma_abs(*it) <= tol) == false ) { return false; }
568568

569569
++it;
570570
}

inst/include/armadillo_bits/SpMat_meat.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,7 +3565,7 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
35653565

35663566
if(tol == T(0)) { return (*this).is_symmetric(); }
35673567

3568-
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
3568+
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" );
35693569

35703570
const SpMat<eT>& A = (*this);
35713571

@@ -3611,7 +3611,7 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
36113611

36123612
if(tol == T(0)) { return (*this).is_hermitian(); }
36133613

3614-
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
3614+
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" );
36153615

36163616
const SpMat<eT>& A = (*this);
36173617

@@ -4204,12 +4204,12 @@ SpMat<eT>::clamp(const eT min_val, const eT max_val)
42044204

42054205
if(is_cx<eT>::no)
42064206
{
4207-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): min_val must be less than max_val" );
4207+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): min_val must be less than max_val" );
42084208
}
42094209
else
42104210
{
4211-
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
4212-
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
4211+
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
4212+
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
42134213
}
42144214

42154215
if(n_nonzero == 0) { return *this; }
@@ -4389,7 +4389,7 @@ SpMat<eT>::sprandu(const uword in_rows, const uword in_cols, const double densit
43894389
{
43904390
arma_debug_sigprint();
43914391

4392-
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandu(): density must be in the [0,1] interval" );
4392+
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandu(): density must be in the [0,1] interval" );
43934393

43944394
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
43954395

@@ -4466,7 +4466,7 @@ SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double densit
44664466
{
44674467
arma_debug_sigprint();
44684468

4469-
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandn(): density must be in the [0,1] interval" );
4469+
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandn(): density must be in the [0,1] interval" );
44704470

44714471
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
44724472

0 commit comments

Comments
 (0)