From 323ee1a9ad58063b65e132de166ef84a41593b1d Mon Sep 17 00:00:00 2001 From: Sonu0305 Date: Mon, 14 Sep 2026 15:01:38 +0400 Subject: [PATCH 1/4] Fix empty array edge cases in stepwisefit --- inst/Regression/stepwisefit.m | 40 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/inst/Regression/stepwisefit.m b/inst/Regression/stepwisefit.m index 67c2359a8..2fb728222 100644 --- a/inst/Regression/stepwisefit.m +++ b/inst/Regression/stepwisefit.m @@ -139,15 +139,21 @@ error ("stepwisefit: at least two input arguments required"); endif - if (! ismatrix (X) || ! isvector (y)) - error ("stepwisefit: X must be a matrix and y a vector"); + if (! ismatrix (X)) + error ("stepwisefit: X must be a matrix."); + endif + if (! (isvector (y) || isempty (y))) + error ("stepwisefit: Y must be a column vector."); + endif + if (! iscolumn (y)) + error ("stepwisefit: Y must be a column vector."); endif y = y(:); ## Validate row compatibility BEFORE any concatenation if (rows (X) != rows (y)) - error ("stepwisefit: X must be a matrix and y a vector"); + error ("stepwisefit: X and Y must have the same number of rows"); endif ## Parse Name-Value pairs @@ -210,6 +216,22 @@ n = rows (Xc); p = columns (Xc); + if (n == 0) + b = NaN (p, 1); + se = NaN (p, 1); + pval = NaN (p, 1); + finalmodel = false (1, p); + stats = struct ('source', 'stepwisefit', 'df0', 0, 'dfe', -1, ... + 'SStotal', 0, 'SSresid', 0, 'fstat', NaN, 'pval', NaN, ... + 'rmse', NaN, 'intercept', NaN, 'wasnan', wasnan, ... + 'xr', zeros(0, p), 'yr', zeros(0, 1), 'B', NaN (p, 1), ... + 'SE', NaN (p, 1), 'TSTAT', NaN (p, 1), 'PVAL', NaN (p, 1), ... + 'covb', NaN (p+1, p+1)); + history = struct ('B', NaN (p, 1), 'rmse', NaN, 'df0', 0, 'in', false(1, p)); + nextstep = 0; + return; + endif + ## Validate Keep and InModel type (if provided) if (! isempty (Keep) && ! islogical (Keep)) error ("stepwisefit: Keep must be a logical vector"); @@ -657,14 +679,22 @@ ## Test input validation %!error ... %! stepwisefit () -%!error ... +%!error ... %! stepwisefit (ones (2,2,2), [1;2]) -%!error ... +%!error ... %! stepwisefit (ones (3,2), ones (2,1)) %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'UnknownOpt', 5) %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'Display', 'maybe') + +%!test +%! ## Edge cases with empty arrays +%! b = stepwisefit (zeros (0, 3), zeros (0, 1)); +%! assert_equal (size (b), [3 1]); +%! assert_equal (isnan (b), true (3, 1)); +%! +%! fail ("stepwisefit ([], [])", "stepwisefit: Y must be a column vector."); %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'Scale', 123) %!error ... From 6821bcb755f5e2dc7519d889fcc5b4b4d12d79cb Mon Sep 17 00:00:00 2001 From: Sonu0305 Date: Mon, 14 Sep 2026 15:54:25 +0400 Subject: [PATCH 2/4] Refactor tests to use %!error instead of %!fail --- inst/Regression/stepwisefit.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/Regression/stepwisefit.m b/inst/Regression/stepwisefit.m index 2fb728222..cbef65359 100644 --- a/inst/Regression/stepwisefit.m +++ b/inst/Regression/stepwisefit.m @@ -674,7 +674,7 @@ %!test %! X = randn (20,4); %! y = randn (20,1); -%! fail ('stepwisefit (X,y,''Keep'',[true false])'); +%!error stepwisefit (X,y,'Keep',[true false]) ## Test input validation %!error ... @@ -694,7 +694,7 @@ %! assert_equal (size (b), [3 1]); %! assert_equal (isnan (b), true (3, 1)); %! -%! fail ("stepwisefit ([], [])", "stepwisefit: Y must be a column vector."); +%!error stepwisefit ([], []) %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'Scale', 123) %!error ... From 8e0f953017341cc92a696916176e4784f442f9cd Mon Sep 17 00:00:00 2001 From: Sonu0305 Date: Mon, 14 Sep 2026 19:45:57 +0400 Subject: [PATCH 3/4] Fix stepwisefit empty array logic and tests --- inst/Regression/stepwisefit.m | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/inst/Regression/stepwisefit.m b/inst/Regression/stepwisefit.m index cbef65359..3f2d061f3 100644 --- a/inst/Regression/stepwisefit.m +++ b/inst/Regression/stepwisefit.m @@ -153,7 +153,7 @@ ## Validate row compatibility BEFORE any concatenation if (rows (X) != rows (y)) - error ("stepwisefit: X and Y must have the same number of rows"); + error ("stepwisefit: X and Y must have the same number of rows."); endif ## Parse Name-Value pairs @@ -221,13 +221,13 @@ se = NaN (p, 1); pval = NaN (p, 1); finalmodel = false (1, p); - stats = struct ('source', 'stepwisefit', 'df0', 0, 'dfe', -1, ... + stats = struct ('source', 'stepwisefit', 'df0', -1, 'dfe', 0, ... 'SStotal', 0, 'SSresid', 0, 'fstat', NaN, 'pval', NaN, ... - 'rmse', NaN, 'intercept', NaN, 'wasnan', wasnan, ... + 'rmse', NaN, 'intercept', 0, 'wasnan', wasnan, ... 'xr', zeros(0, p), 'yr', zeros(0, 1), 'B', NaN (p, 1), ... 'SE', NaN (p, 1), 'TSTAT', NaN (p, 1), 'PVAL', NaN (p, 1), ... - 'covb', NaN (p+1, p+1)); - history = struct ('B', NaN (p, 1), 'rmse', NaN, 'df0', 0, 'in', false(1, p)); + 'covb', NaN (p, p)); + history = struct ('B', zeros (p, 0), 'rmse', zeros (0, 0), 'df0', zeros (0, 0), 'in', false (0, p)); nextstep = 0; return; endif @@ -671,17 +671,15 @@ %! [b1] = stepwisefit (X, y); %! [b2] = stepwisefit (X, y, 'Scale', 'on'); %! assert_equal (rows (b1) == rows (b2), true); -%!test -%! X = randn (20,4); -%! y = randn (20,1); -%!error stepwisefit (X,y,'Keep',[true false]) +%!error ... +%! stepwisefit (randn (20,4), randn (20,1), 'Keep', [true false]) ## Test input validation %!error ... %! stepwisefit () %!error ... %! stepwisefit (ones (2,2,2), [1;2]) -%!error ... +%!error ... %! stepwisefit (ones (3,2), ones (2,1)) %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'UnknownOpt', 5) @@ -690,11 +688,11 @@ %!test %! ## Edge cases with empty arrays -%! b = stepwisefit (zeros (0, 3), zeros (0, 1)); +%! b = stepwisefit (zeros (0, 3), zeros (0, 1), 'Display', 'off'); %! assert_equal (size (b), [3 1]); %! assert_equal (isnan (b), true (3, 1)); %! -%!error stepwisefit ([], []) +%!error stepwisefit ([], [], 'Display', 'off') %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'Scale', 123) %!error ... From 737ecd8932d78ac19de4d8523a06c6271c459c87 Mon Sep 17 00:00:00 2001 From: Sonu0305 Date: Mon, 14 Sep 2026 19:48:56 +0400 Subject: [PATCH 4/4] Apply 80-char limits to stepwisefit.m --- inst/Regression/stepwisefit.m | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/inst/Regression/stepwisefit.m b/inst/Regression/stepwisefit.m index 3f2d061f3..1f8400169 100644 --- a/inst/Regression/stepwisefit.m +++ b/inst/Regression/stepwisefit.m @@ -195,7 +195,8 @@ ## Validate PRemove (if provided) if (! isempty (PRemove)) - if (! (isscalar (PRemove) && isnumeric (PRemove) && PRemove > 0 && PRemove < 1)) + if (! (isscalar (PRemove) && isnumeric (PRemove) && PRemove > 0 + && PRemove < 1)) error ("stepwisefit: PRemove must be a scalar strictly between 0 and 1"); endif if (PRemove < PEnter) @@ -204,7 +205,8 @@ endif ## Validate MaxIter - if (! (isscalar (MaxIter) && isnumeric (MaxIter) && MaxIter > 0 && fix (MaxIter) == MaxIter)) + if (! (isscalar (MaxIter) && isnumeric (MaxIter) && MaxIter > 0 + && fix (MaxIter) == MaxIter)) error ("stepwisefit: MaxIter must be a positive integer"); endif @@ -225,9 +227,11 @@ 'SStotal', 0, 'SSresid', 0, 'fstat', NaN, 'pval', NaN, ... 'rmse', NaN, 'intercept', 0, 'wasnan', wasnan, ... 'xr', zeros(0, p), 'yr', zeros(0, 1), 'B', NaN (p, 1), ... - 'SE', NaN (p, 1), 'TSTAT', NaN (p, 1), 'PVAL', NaN (p, 1), ... + 'SE', NaN (p, 1), 'TSTAT', NaN (p, 1), ... + 'PVAL', NaN (p, 1), ... 'covb', NaN (p, p)); - history = struct ('B', zeros (p, 0), 'rmse', zeros (0, 0), 'df0', zeros (0, 0), 'in', false (0, p)); + history = struct ('B', zeros (p, 0), 'rmse', zeros (0, 0), ... + 'df0', zeros (0, 0), 'in', false (0, p)); nextstep = 0; return; endif @@ -692,7 +696,8 @@ %! assert_equal (size (b), [3 1]); %! assert_equal (isnan (b), true (3, 1)); %! -%!error stepwisefit ([], [], 'Display', 'off') +%!error ... +%! stepwisefit ([], [], 'Display', 'off') %!error ... %! stepwisefit (randn (10,2), randn (10,1), 'Scale', 123) %!error ...