]> gitweb.michael.orlitzky.com - octave.d.git/commitdiff
tests/preconditioned_conjugate_gradient_method_tests.m: make reliable? master codeberg/master
authorMichael Orlitzky <michael@orlitzky.com>
Mon, 13 Apr 2026 11:08:10 +0000 (07:08 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Mon, 13 Apr 2026 11:08:10 +0000 (07:08 -0400)
This was ultimately made reliable by the new "condmax" parameter to
random_positive_definite_matrix(), but there are some additional
tweaks afterwards:

  * Reorder / rename some stuff to improve readability
  * Use a higher condmax than default, since we are preconditioning
  * Pass the full "M" matrix to pcg(), to more closely match what
    our own PCG function is doing.

The tests "always" pass now.

tests/preconditioned_conjugate_gradient_method_tests.m

index 7342ca82cb2d058bb7e0bb3017d04901c7ef46c7..17c7918bec84300c2ca56605563d195fa63aa6a9 100644 (file)
@@ -63,24 +63,27 @@ unit_test_equals("PCGM agrees with Simple PCGM when M != I", ...
 
 # Test again Octave's pcg() function.
 for n = [ 5, 10, 25, 50, 100 ]
-  A = random_positive_definite_matrix(n, 100);
+  ## Since we are preconditioning, a larger condition number
+  ## (<= 100000) is acceptable.
+  A = random_positive_definite_matrix(n, 100, 100000);
+  b  = unifrnd(-100, 100, n, 1);
+  g = @(x) A*x - b;
 
-  # Use the cholesky factorization as a preconditioner.
-  Ct = perturb(chol(A));
-  C = Ct';
-  M = Ct*C;
+  ## Use a perturbed cholesky factorization (so, almost the Cholesky
+  ## factorization of A) as a preconditioner. Using the actual Cholesky
+  ## factorization would make the solution too easy.
+  R = perturb(chol(A));
+  M = R' * R;
 
-  # Assumed by Octave's implementation when you don't supply a
-  # preconditioner.
+  # The origin is assumed by Octave's implementation when you don't supply a
+  # starting point.
   x0 = zeros(n, 1);
-  b  = unifrnd(-100, 100, n, 1);
-  g = @(x) A*x - b;
 
   ## pcg() stops when the /relative/ norm falls below tolerance. To
   ## eliminate the relativity, we divide the tolerance by the
   ## quantity that pcg() will divide by.
   [o_x, o_flag, o_relres, o_iter] = pcg(A, b, tolerance/norm(g(x0)), ...
-                                       max_iterations, C, C');
+                                       max_iterations, M, []);
   [x, k] = preconditioned_conjugate_gradient_method(A,
                                                    M,
                                                    b,