@@ -60,6 +60,90 @@ arma::mat ptvdf(arma::mat x, arma::mat df, bool lower) {
6060 return arma::reshape (y, 1 , n);
6161}
6262
63+ // ' @title Check Equivalence
64+ // '
65+ // ' @description
66+ // ' This function evaluates whether equivalence criteria are met.
67+ // ' It first checks whether all primary endpoints satisfy
68+ // ' equivalence (if sequential testing is enabled). Then, it determines whether the
69+ // ' required number of endpoints (`k`) meet the equivalence threshold.
70+ // ' The function returns a structured matrix that includes equivalence decisions,
71+ // ' test results, mean estimates, and standard deviations.
72+ // '
73+ // ' @param typey An unsigned integer vector (`arma::uvec`) indicating the type of each endpoint:
74+ // ' - `1` = Primary endpoint
75+ // ' - `2` = Secondary endpoint
76+ // ' @param adseq A boolean flag (`TRUE` if sequential testing is enabled).
77+ // ' - If `TRUE`, all primary endpoints must pass equivalence for secondary endpoints to be evaluated.
78+ // ' - If `FALSE`, primary and secondary endpoints are evaluated independently.
79+ // ' @param tbioq A matrix (`arma::mat`) indicating the equivalence test results:
80+ // ' - `1` = Equivalence met
81+ // ' - `0` = Equivalence not met
82+ // ' @param k An integer specifying the minimum number of endpoints required to establish equivalence.
83+ // ' @param mu0 A matrix (`arma::mat`) containing the estimated means for the reference treatment group.
84+ // ' @param mu1 A matrix (`arma::mat`) containing the estimated means for the treatment under evaluation.
85+ // ' @param sd0 A matrix (`arma::mat`) containing the standard deviations for the reference treatment group.
86+ // ' @param sd1 A matrix (`arma::mat`) containing the standard deviations for the treatment under evaluation.
87+ // '
88+ // ' @details
89+ // ' - **Sequential Adjustment (`adseq = TRUE`)**:
90+ // ' - Ensures that all primary endpoints must meet equivalence before secondary endpoints are evaluated.
91+ // ' - **Non-Sequential Testing (`adseq = FALSE`)**:
92+ // ' - Evaluates all endpoints simultaneously without enforcing hierarchical constraints.
93+ // ' - **Final Equivalence Decision (`totaly`)**:
94+ // ' - `1` if at least `k` endpoints meet equivalence and (if sequential testing is enabled) all primary endpoints pass.
95+ // ' - `0` otherwise.
96+ // '
97+ // ' @return
98+ // ' An `arma::mat` containing the final equivalence decision along with test statistics:
99+ // ' - `totaly` (1 × 1 matrix): Binary indicator (1 = equivalence established, 0 = not established).
100+ // ' - `tbioq` (m × n matrix): Equivalence test results for each endpoint.
101+ // ' - `mu0, mu1` (m × n matrices): Mean estimates for the reference and treatment groups.
102+ // ' - `sd0, sd1` (m × n matrices): Standard deviations for the reference and treatment groups.
103+ // ' @export
104+ // [[Rcpp::export]]
105+ arma::mat check_equivalence (const arma::uvec& typey, bool adseq,
106+ const arma::mat& tbioq, int k,
107+ const arma::mat& mu0, const arma::mat& mu1,
108+ const arma::mat& sd0, const arma::mat& sd1) {
109+ // primary endpoints in case of sequencial adjustment
110+ int sumtypey;
111+ // in case no primary endpoint is added.
112+ if ( accu (typey) >= 0 ) {
113+ sumtypey = accu (tbioq.cols (typey)); // sum of primary endpoint rejected
114+ }else {
115+ sumtypey = 1 ;
116+ }
117+
118+ // Total number of primary endpoints
119+ int lentypey = typey.n_elem ;
120+
121+ // Determine if all primary endpoints meet the equivalence criteria under sequential adjustment.
122+ //
123+ // If `adseq` (sequential testing) is disabled (`false`), equivalence is not required for all primary endpoints,
124+ // so `sumpe` is automatically set to `true`.
125+ //
126+ // If `adseq` is enabled (`true`), `sumpe` is set to `true` only if all primary endpoints (`sumtypey`) meet
127+ // the required equivalence criteria (`lentypey`), meaning all must pass.
128+ bool sumpe = !adseq || (sumtypey == lentypey);
129+
130+ // Check if at least `k` endpoints meet equivalence criteria
131+ bool sumt = accu (tbioq) >= k;
132+
133+ // Store final equivalence decision
134+ arma::mat totaly (1 ,1 );
135+ totaly (0 , 0 ) = (sumt && sumpe) ? 1 : 0 ;
136+
137+ // Combine results into a response matrix
138+ arma::mat response0 = join_rows (totaly, tbioq);
139+ arma::mat response1 = join_rows (mu0, mu1);
140+ arma::mat response2 = join_rows (sd0, sd1);
141+ arma::mat response3 = join_rows (response0, response1);
142+
143+ return join_rows (response3, response2);
144+ }
145+
146+
63147// ' @title Simulate a 2x2 Crossover Design and Compute Difference of Means (DOM)
64148// '
65149// ' @description
@@ -168,9 +252,6 @@ arma::mat test_2x2_dom(int n, arma::vec muT, arma::vec muR,
168252 mat alpha0 = conv_to<mat>::from (alpha);
169253 mat tbioq = conv_to<mat>::from ((ptost < alpha0));
170254
171- // Initialize `sumpe` (Sequential Pass Status) to `true` (assume success by default)
172- bool sumpe = true ;
173-
174255 // `sumtypey` stores the number of primary endpoints that meet equivalence criteria.
175256 // Default to 1 in case no primary endpoints are specified.
176257 int sumtypey = 1 ;
@@ -184,10 +265,16 @@ arma::mat test_2x2_dom(int n, arma::vec muT, arma::vec muR,
184265 // Store the total number of primary endpoints
185266 int lentypey = typey.n_elem ;
186267
187- // If sequential adjustment (`adseq`) is enabled, ensure all primary endpoints meet equivalence
188- if (adseq) {
189- sumpe = (sumtypey == lentypey); // `true` if all primary endpoints pass, `false` otherwise
190- }
268+ // Determine if all primary endpoints meet the equivalence criteria under sequential adjustment.
269+ //
270+ // If `adseq` (sequential testing) is disabled (`false`), equivalence is not required for all primary endpoints,
271+ // so `sumpe` is automatically set to `true`.
272+ //
273+ // If `adseq` is enabled (`true`), `sumpe` is set to `true` only if all primary endpoints (`sumtypey`) meet
274+ // the required equivalence criteria (`lentypey`), meaning all must pass.
275+ //
276+ // This ensures that secondary endpoints are tested only if all primary endpoints demonstrate equivalence.
277+ bool sumpe = !adseq || (sumtypey == lentypey);
191278
192279 // Check the Total Number of Endpoints Meeting Equivalence Criteria
193280 bool sumt = accu (tbioq) >= k;
@@ -330,7 +417,6 @@ arma::mat test_2x2_rom(int n, arma::vec muT, arma::vec muR,
330417 mat tbioq = conv_to<mat>::from ((ptost < alpha0));
331418
332419 // primary endpoints in case of sequencial adjustment
333- bool sumpe = true ;
334420 int sumtypey;
335421 // in case no primary endpoint is added.
336422 if ( accu (typey) >= 0 ) {
@@ -342,9 +428,16 @@ arma::mat test_2x2_rom(int n, arma::vec muT, arma::vec muR,
342428
343429 int lentypey = typey.n_elem ;
344430
345- if (adseq == true ){
346- sumpe = sumtypey == lentypey;
347- }
431+ // Determine if all primary endpoints meet the equivalence criteria under sequential adjustment.
432+ //
433+ // If `adseq` (sequential testing) is disabled (`false`), equivalence is not required for all primary endpoints,
434+ // so `sumpe` is automatically set to `true`.
435+ //
436+ // If `adseq` is enabled (`true`), `sumpe` is set to `true` only if all primary endpoints (`sumtypey`) meet
437+ // the required equivalence criteria (`lentypey`), meaning all must pass.
438+ //
439+ // This ensures that secondary endpoints are tested only if all primary endpoints demonstrate equivalence.
440+ bool sumpe = !adseq || (sumtypey == lentypey);
348441
349442 bool sumt = accu (tbioq) >= k;
350443
@@ -476,39 +569,8 @@ arma::mat test_par_dom(int n, arma::vec muT, arma::vec muR,
476569 mat alpha0 = conv_to<mat>::from (alpha);
477570 mat tbioq = conv_to<mat>::from ((ptost < alpha0));
478571
479- // primary endpoints in case of sequencial adjustment
480- // primary endpoints in case of sequencial adjustment
481- bool sumpe = true ;
482- int sumtypey;
483- // in case no primary endpoint is added.
484- if ( accu (typey) >= 0 ) {
485- sumtypey = accu (tbioq.cols (typey)); // sum of primary endpoint rejected
486- }else {
487- sumtypey = 1 ;
488- }
489- // total number of primary endpoints
490- int lentypey = typey.n_elem ;
491-
492- if (adseq == true ){
493- sumpe = sumtypey == lentypey;
494- }
495-
496- bool sumt = accu (tbioq) >= k;
497-
498- mat totaly (1 ,1 );
499-
500- if (sumt&sumpe){
501- totaly (0 , 0 ) = 1 ;
502- }else {
503- totaly (0 , 0 ) = 0 ;
504- }
505-
506- mat response0 = join_rows<mat>(totaly,tbioq);
507- mat response1 = join_rows<mat>(mu0,mu1);
508- mat response2 = join_rows<mat>(sd0,sd1);
509- mat response3 = join_rows<mat>(response0,response1);
510-
511- return join_rows<mat>(response3,response2);
572+ // Call the check_equivalence function
573+ return check_equivalence (typey, adseq, tbioq, k, mu0, mu1, sd0, sd1);
512574}
513575
514576// ' @title Simulate a Parallel Design and Compute Ratio of Means (ROM)
@@ -611,39 +673,8 @@ arma::mat test_par_rom(int n, arma::vec muT, arma::vec muR,
611673 mat alpha0 = conv_to<mat>::from (alpha);
612674 mat tbioq = conv_to<mat>::from ((ptost < alpha0));
613675
614- // primary endpoints in case of sequencial adjustment
615- bool sumpe = true ;
616- int sumtypey;
617- // in case no primary endpoint is added.
618- if ( accu (typey) >= 0 ) {
619- sumtypey = accu (tbioq.cols (typey)); // sum of primary endpoint rejected
620- }else {
621- sumtypey = 1 ;
622- }
623-
624- // total number of primary endpoints
625- int lentypey = typey.n_elem ;
626- if (adseq == true ){
627- sumpe = sumtypey == lentypey;
628- }
629-
630- bool sumt = accu (tbioq) >= k;
631-
632- mat totaly (1 ,1 );
633-
634- if (sumt&sumpe){
635- totaly (0 , 0 ) = 1 ;
636- }else {
637- totaly (0 , 0 ) = 0 ;
638- }
639-
640-
641- mat response0 = join_rows<mat>(totaly,tbioq);
642- mat response1 = join_rows<mat>(mu0,mu1);
643- mat response2 = join_rows<mat>(sd0,sd1);
644- mat response3 = join_rows<mat>(response0,response1);
645-
646- return join_rows<mat>(response3,response2);
676+ // Call the check_equivalence function
677+ return check_equivalence (typey, adseq, tbioq, k, mu0, mu1, sd0, sd1);
647678}
648679
649680
0 commit comments