# HG changeset patch # User Rik # Date 1583957665 25200 # Node ID f67f582da4479428e63ff4dfbb09f0ba7dc147a0 # Parent 37ee7c5cc6b2584053c2ada4d235908866bda1f3# Parent 4609d001daeefb6939b923a78806b332c91091f5 maint: merge stable to default. diff -r 37ee7c5cc6b2 -r f67f582da447 scripts/linear-algebra/condest.m --- a/scripts/linear-algebra/condest.m Sun Feb 16 21:37:13 2020 -0500 +++ b/scripts/linear-algebra/condest.m Wed Mar 11 13:14:25 2020 -0700 @@ -208,7 +208,7 @@ warning ("off", "Octave:nearly-singular-matrix", "local"); if (! have_solve_normest1) - ## prepare solve in normest1 form + ## prepare solve in normest1 form if (issparse (A)) [L, U, P, Pc] = lu (A); solve = @(flag, x) solve_sparse (flag, x, n, real_op, L, U, P, Pc); @@ -240,15 +240,18 @@ endfunction function value = solve_sparse (flag, x, n, real_op, L , U , P , Pc) + ## FIXME: Sparse algorithm is less accurate than full matrix version + ## See BIST test for non-orthogonal matrix where relative tolerance + ## of 1e-12 is used for sparse, but 4e-16 for full matrix. switch (flag) case "dim" value = n; case "real" value = real_op; case "notransp" - value = P' * (L' \ (U' \ (Pc * x))); + value = Pc' * (U \ (L \ (P * x))); case "transp" - value = Pc' * (U \ (L \ (P * x))); + value = P' * (L' \ (U' \ (Pc * x))); endswitch endfunction @@ -259,9 +262,9 @@ case "real" value = real_op; case "notransp" - value = P' * (L' \ (U' \ x)); + value = U \ (L \ (P * x)); case "transp" - value = U \ (L \ (P * x)); + value = P' * (L' \ (U' \ x)); endswitch endfunction @@ -339,6 +342,7 @@ %! cA_test = norm (inv (A^2), 1) * norm (A^2, 1); %! assert (cA, cA_test, -2^-6); +## Test singular matrices %!test <*46737> %! A = [ 0 0 0 %! 0 3.33333 0.0833333 @@ -347,6 +351,19 @@ %! assert (cest, Inf); %! assert (v, []); +## Test non-orthogonal matrices +%!test <*57968> +%! A = reshape (sqrt (0:15), 4, 4); +%! cexp = norm (A, 1) * norm (inv (A), 1); +%! cest = condest (A); +%! assert (cest, cexp, -2*eps); + +%!test <*57968> +%! As = sparse (reshape (sqrt (0:15), 4, 4)); +%! cexp = norm (As, 1) * norm (inv (As), 1); +%! cest = condest (As); +%! assert (cest, cexp, -1e-12); + ## Test input validation %!error condest () %!error condest (1,2,3,4,5,6,7)