22
33# ---- shared matrix helpers (loaded early for implicit collation) ----
44
5+ # Assert hoist is a valid environment for BLAS/LAPACK helpers.
6+ assert_hoist_env <- function (hoist ) {
7+ if (! inherits(hoist , " environment" )) {
8+ stop(" internal: hoist must be a hoist environment" )
9+ }
10+ invisible (TRUE )
11+ }
12+
13+ # Assert a Fortran value is a rank-2 matrix.
14+ assert_rank2_matrix <- function (x , message ) {
15+ stopifnot(inherits(x , Fortran ), is_string(message ))
16+ if (x @ value @ rank != 2L ) {
17+ stop(message , call. = FALSE )
18+ }
19+ invisible (TRUE )
20+ }
21+
22+ # Assert a Fortran value is a scalar or vector.
23+ assert_rank_leq1 <- function (x , message ) {
24+ stopifnot(inherits(x , Fortran ), is_string(message ))
25+ if (x @ value @ rank > 1L ) {
26+ stop(message , call. = FALSE )
27+ }
28+ invisible (TRUE )
29+ }
30+
31+ # Assert a Fortran value is rank 0-2.
32+ assert_rank_leq2 <- function (x , message ) {
33+ stopifnot(inherits(x , Fortran ), is_string(message ))
34+ if (x @ value @ rank > 2L ) {
35+ stop(message , call. = FALSE )
36+ }
37+ invisible (TRUE )
38+ }
39+
40+ # Assert right-hand side rank is vector or matrix.
41+ assert_rhs_rank <- function (
42+ rank ,
43+ err_scalar ,
44+ err_high ,
45+ call_scalar = FALSE ,
46+ call_high = FALSE
47+ ) {
48+ stopifnot(
49+ is_wholenumber(rank ),
50+ is_string(err_scalar ),
51+ is_string(err_high ),
52+ is_bool(call_scalar ),
53+ is_bool(call_high )
54+ )
55+ if (rank > 2L ) {
56+ stop(err_high , call. = call_high )
57+ }
58+ if (rank == 0L ) {
59+ stop(err_scalar , call. = call_scalar )
60+ }
61+ invisible (TRUE )
62+ }
63+
64+ # Assert conformability and warn on unknown.
65+ assert_conformable_dims <- function (left , right , context , err_msg ) {
66+ stopifnot(is_string(context ), is_string(err_msg ))
67+ conform <- check_conformable(left , right )
68+ if (! conform $ ok ) {
69+ stop(err_msg , call. = FALSE )
70+ }
71+ if (conform $ unknown ) {
72+ warn_conformability_unknown(left , right , context )
73+ }
74+ invisible (TRUE )
75+ }
76+
577# Return the R symbol name if operand is a bare symbol; otherwise NULL.
678symbol_name_or_null <- function (x ) {
779 stopifnot(inherits(x , Fortran ))
@@ -235,9 +307,7 @@ gemm <- function(
235307 dest = NULL ,
236308 context = " gemm"
237309) {
238- if (! inherits(hoist , " environment" )) {
239- stop(" internal: hoist must be a hoist environment" )
240- }
310+ assert_hoist_env(hoist )
241311 A_name <- ensure_blas_operand_name(left , hoist )
242312 B_name <- ensure_blas_operand_name(right , hoist )
243313
@@ -281,9 +351,7 @@ gemv <- function(
281351 dest = NULL ,
282352 context = " gemv"
283353) {
284- if (! inherits(hoist , " environment" )) {
285- stop(" internal: hoist must be a hoist environment" )
286- }
354+ assert_hoist_env(hoist )
287355 A_name <- ensure_blas_operand_name(A , hoist )
288356 x_name <- ensure_blas_operand_name(x , hoist )
289357
@@ -312,7 +380,8 @@ gemv <- function(
312380}
313381
314382symmetrize_upper_to_lower <- function (target , n , hoist ) {
315- stopifnot(is_string(target ), inherits(hoist , " environment" ))
383+ stopifnot(is_string(target ))
384+ assert_hoist_env(hoist )
316385
317386 idx_i <- hoist $ declare_tmp(mode = " integer" , dims = list (1L ))
318387 idx_j <- hoist $ declare_tmp(mode = " integer" , dims = list (1L ))
@@ -341,7 +410,8 @@ diag_length_expr <- function(nrow, ncol, context) {
341410}
342411
343412zero_lower_triangle <- function (target , n , hoist ) {
344- stopifnot(is_string(target ), inherits(hoist , " environment" ))
413+ stopifnot(is_string(target ))
414+ assert_hoist_env(hoist )
345415
346416 idx_i <- hoist $ declare_tmp(mode = " integer" , dims = NULL )
347417 idx_j <- hoist $ declare_tmp(mode = " integer" , dims = NULL )
@@ -368,9 +438,7 @@ syrk <- function(
368438 dest = NULL ,
369439 context = " syrk"
370440) {
371- if (! inherits(hoist , " environment" )) {
372- stop(" internal: hoist must be a hoist environment" )
373- }
441+ assert_hoist_env(hoist )
374442 X_name <- ensure_blas_operand_name(X , hoist )
375443
376444 x_dims <- matrix_dims(X )
@@ -428,9 +496,7 @@ outer_mul <- function(
428496 dest = NULL ,
429497 context = " outer"
430498) {
431- if (! inherits(hoist , " environment" )) {
432- stop(" internal: hoist must be a hoist environment" )
433- }
499+ assert_hoist_env(hoist )
434500
435501 x <- maybe_cast_double(x )
436502 y <- maybe_cast_double(y )
@@ -482,16 +548,12 @@ triangular_solve <- function(
482548 dest = NULL ,
483549 context = " triangular solve"
484550) {
485- if (! inherits(hoist , " environment" )) {
486- stop(" internal: hoist must be a hoist environment" )
487- }
551+ assert_hoist_env(hoist )
488552
489553 A <- maybe_cast_double(A )
490554 B <- maybe_cast_double(B )
491555
492- if (A @ value @ rank != 2L ) {
493- stop(" triangular solve expects a matrix" )
494- }
556+ assert_rank2_matrix(A , " triangular solve expects a matrix" )
495557
496558 a_dims <- matrix_dims(A )
497559 conform <- check_conformable(a_dims $ rows , a_dims $ cols )
@@ -504,29 +566,27 @@ triangular_solve <- function(
504566 n <- a_dims $ rows
505567
506568 b_rank <- B @ value @ rank
507- if ( b_rank > 2L ) {
508- stop( " triangular solve only supports vector or matrix right-hand sides " )
509- }
510- if ( b_rank == 0L ) {
511- stop( " triangular solve expects a vector or matrix right-hand side " )
512- } else if (b_rank == 1L ) {
569+ assert_rhs_rank(
570+ b_rank ,
571+ err_scalar = " triangular solve expects a vector or matrix right-hand side " ,
572+ err_high = " triangular solve only supports vector or matrix right-hand sides "
573+ )
574+ if (b_rank == 1L ) {
513575 b_len <- dim_or_one(B , 1L )
514- conform <- check_conformable(n , b_len )
515- if (! conform $ ok ) {
516- stop(" non-conformable arguments in triangular solve" , call. = FALSE )
517- }
518- if (conform $ unknown ) {
519- warn_conformability_unknown(n , b_len , " triangular solve" )
520- }
576+ assert_conformable_dims(
577+ n ,
578+ b_len ,
579+ context = " triangular solve" ,
580+ err_msg = " non-conformable arguments in triangular solve"
581+ )
521582 } else {
522583 b_rows <- dim_or_one(B , 1L )
523- conform <- check_conformable(n , b_rows )
524- if (! conform $ ok ) {
525- stop(" non-conformable arguments in triangular solve" , call. = FALSE )
526- }
527- if (conform $ unknown ) {
528- warn_conformability_unknown(n , b_rows , " triangular solve" )
529- }
584+ assert_conformable_dims(
585+ n ,
586+ b_rows ,
587+ context = " triangular solve" ,
588+ err_msg = " non-conformable arguments in triangular solve"
589+ )
530590 }
531591
532592 A_name <- ensure_blas_operand_name(A , hoist )
@@ -581,51 +641,45 @@ lapack_solve <- function(
581641 dest = NULL ,
582642 context = " solve"
583643) {
584- if (! inherits(hoist , " environment" )) {
585- stop(" internal: hoist must be a hoist environment" )
586- }
644+ assert_hoist_env(hoist )
587645
588646 A <- maybe_cast_double(A )
589647 B <- maybe_cast_double(B )
590648
591- if (A @ value @ rank != 2L ) {
592- stop(context , " expects a matrix for `a`" , call. = FALSE )
593- }
649+ assert_rank2_matrix(A , paste0(context , " expects a matrix for `a`" ))
594650
595651 a_dims <- matrix_dims(A )
596652 assert_square_matrix(a_dims $ rows , a_dims $ cols , context )
597653 n <- a_dims $ rows
598654
599655 b_rank <- B @ value @ rank
600- if (b_rank > 2L ) {
601- stop(
656+ assert_rhs_rank(
657+ b_rank ,
658+ err_scalar = paste0(context , " expects a vector or matrix right-hand side" ),
659+ err_high = paste0(
602660 context ,
603- " only supports vector or matrix right-hand sides" ,
604- call. = FALSE
605- )
606- }
607- if (b_rank == 0L ) {
608- stop(context , " expects a vector or matrix right-hand side" , call. = FALSE )
609- }
661+ " only supports vector or matrix right-hand sides"
662+ ),
663+ call_scalar = FALSE ,
664+ call_high = FALSE
665+ )
610666
611667 if (b_rank == 1L ) {
612668 b_len <- dim_or_one(B , 1L )
613- conform <- check_conformable(n , b_len )
614- if (! conform $ ok ) {
615- stop(" non-conformable arguments in " , context , call. = FALSE )
616- }
617- if (conform $ unknown ) {
618- warn_conformability_unknown(n , b_len , context )
619- }
669+ assert_conformable_dims(
670+ n ,
671+ b_len ,
672+ context = context ,
673+ err_msg = paste0(" non-conformable arguments in " , context )
674+ )
620675 } else {
621676 b_rows <- dim_or_one(B , 1L )
622- conform <- check_conformable(n , b_rows )
623- if (! conform $ ok ) {
624- stop(" non-conformable arguments in " , context , call. = FALSE )
625- }
626- if (conform $ unknown ) {
627- warn_conformability_unknown(n , b_rows , context )
628- }
677+ assert_conformable_dims(
678+ n ,
679+ b_rows ,
680+ context = context ,
681+ err_msg = paste0(" non-conformable arguments in " , context )
682+ )
629683 }
630684
631685 A_name <- ensure_blas_operand_name(A , hoist )
@@ -669,14 +723,10 @@ lapack_solve <- function(
669723}
670724
671725lapack_inverse <- function (A , scope , hoist , dest = NULL , context = " solve" ) {
672- if (! inherits(hoist , " environment" )) {
673- stop(" internal: hoist must be a hoist environment" )
674- }
726+ assert_hoist_env(hoist )
675727
676728 A <- maybe_cast_double(A )
677- if (A @ value @ rank != 2L ) {
678- stop(context , " expects a matrix for `a`" , call. = FALSE )
679- }
729+ assert_rank2_matrix(A , paste0(context , " expects a matrix for `a`" ))
680730
681731 a_dims <- matrix_dims(A )
682732 assert_square_matrix(a_dims $ rows , a_dims $ cols , context )
@@ -723,14 +773,10 @@ lapack_inverse <- function(A, scope, hoist, dest = NULL, context = "solve") {
723773}
724774
725775lapack_chol <- function (A , scope , hoist , dest = NULL , context = " chol" ) {
726- if (! inherits(hoist , " environment" )) {
727- stop(" internal: hoist must be a hoist environment" )
728- }
776+ assert_hoist_env(hoist )
729777
730778 A <- maybe_cast_double(A )
731- if (A @ value @ rank != 2L ) {
732- stop(context , " expects a matrix" , call. = FALSE )
733- }
779+ assert_rank2_matrix(A , paste0(context , " expects a matrix" ))
734780
735781 a_dims <- matrix_dims(A )
736782 assert_square_matrix(a_dims $ rows , a_dims $ cols , context )
@@ -778,14 +824,10 @@ lapack_chol2inv <- function(
778824 dest = NULL ,
779825 context = " chol2inv"
780826) {
781- if (! inherits(hoist , " environment" )) {
782- stop(" internal: hoist must be a hoist environment" )
783- }
827+ assert_hoist_env(hoist )
784828
785829 R <- maybe_cast_double(R )
786- if (R @ value @ rank != 2L ) {
787- stop(context , " expects a matrix" , call. = FALSE )
788- }
830+ assert_rank2_matrix(R , paste0(context , " expects a matrix" ))
789831
790832 r_dims <- matrix_dims(R )
791833 assert_square_matrix(r_dims $ rows , r_dims $ cols , context )
@@ -827,14 +869,10 @@ lapack_chol2inv <- function(
827869}
828870
829871diag_extract <- function (x , scope , hoist , dest = NULL , context = " diag" ) {
830- if (! inherits(hoist , " environment" )) {
831- stop(" internal: hoist must be a hoist environment" )
832- }
872+ assert_hoist_env(hoist )
833873
834874 x <- maybe_cast_double(x )
835- if (x @ value @ rank != 2L ) {
836- stop(context , " expects a matrix input" , call. = FALSE )
837- }
875+ assert_rank2_matrix(x , paste0(context , " expects a matrix input" ))
838876
839877 x_dims <- matrix_dims(x )
840878 diag_len <- diag_length_expr(x_dims $ rows , x_dims $ cols , context )
@@ -882,14 +920,10 @@ diag_matrix <- function(
882920 dest = NULL ,
883921 context = " diag"
884922) {
885- if (! inherits(hoist , " environment" )) {
886- stop(" internal: hoist must be a hoist environment" )
887- }
923+ assert_hoist_env(hoist )
888924
889925 x <- maybe_cast_double(x )
890- if (x @ value @ rank > 1L ) {
891- stop(context , " expects a vector or scalar input" , call. = FALSE )
892- }
926+ assert_rank_leq1(x , paste0(context , " expects a vector or scalar input" ))
893927
894928 diag_len <- diag_length_expr(nrow , ncol , context )
895929 x_scalar <- passes_as_scalar(x @ value )
0 commit comments