{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Iterative solvers and preconditioning\n", "\n", "A successful family of methods, usually referred to as Conjugate\n", "Gradient-like algorithms, or Krylov subspace methods, can be viewed as\n", "Galerkin or least-squares methods applied to a linear system $Ax =b$.\n", "This view is different from the standard approaches to deriving the\n", "classical Conjugate Gradient method in the literature. Nevertheless,\n", "the fundamental ideas of least squares and Galerkin approximations\n", "can be used to derive the most\n", "popular and successful methods for linear systems, and this is the\n", "topic of the present chapter. Such a view may increase the general\n", "understanding of variational methods and their applicability.\n", "\n", "\n", "Given a linear system" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto1\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "Ax = b,\\quad x,b\\in\\mathbb{R}^n,\\ A\\in\\mathbb{R}^{n,n}\n", "\\label{_auto1} \\tag{1}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and a start vector $x^0$,\n", "we want to construct an iterative solution method that produces approximations\n", "$x^1,x^2,\\ldots$, which hopefully converge to the exact solution $x$.\n", "In iteration no. $k$ we seek an approximation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linalg:xk:update\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "x^{k+1} = x^{k} + u,\\quad u = \\sum_{j=0}^k c_j{q}_j\n", "\\label{linalg:xk:update} \\tag{2}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "where ${q}_j\\in\\mathbb{R}^n$ are known vectors\n", "<!-- spanning the space $V_{k+1}$, -->\n", "and $c_j$ are constants to be determined.\n", "To be specific, let $q_0,\\ldots,q_k$ be basis vectors for $V_{k+1}$:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "V_{k+1} = \\hbox{span}\\{q_0,\\ldots,q_k\\}{\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The associated inner product $(\\cdot,\\cdot )$ is here\n", "the standard Euclidean inner product on $\\mathbb{R}^n$.\n", "\n", "The corresponding error in the equation $Ax =b$, the residual, becomes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "r^{k+1} = b -Ax^{k+1} =\n", "r^{k} -\\sum_{j=0}^kc_jA{q}_j {\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conjugate gradient-like iterative methods\n", "<div id=\"ch:linalg:CGmethods\"></div>\n", "\n", "\n", "## The Galerkin method\n", "\n", "Galerkin's method states that the error in the equation, the residual,\n", "is orthogonal to the space $V_{k+1}$ where we seek the approximation to\n", "the problem.\n", "\n", "The Galerkin (or projection) method aims at finding $u=\\sum_jc_jq_j\\in V_{k+1}$\n", "such that" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "(r^{k+1},v)=0,\\quad\\forall v\\in V_{k+1}{\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This statement is\n", "equivalent to the residual being orthogonal to each basis vector:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linalg2:cg:eq1\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "(r^{k+1},{q}_i )=0,\\quad i=0,\\ldots,k{\\thinspace .}\n", "\\label{linalg2:cg:eq1} \\tag{3}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inserting the expression for $r^{k+1}$ in ([3](#linalg2:cg:eq1))\n", "gives a linear system\n", "for $c_j$:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto2\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "\\sum_{j=0}^k (A{q}_i,{q}_j )c_j = (r^{k},{q}_i),\\quad i=0,\\ldots,k\n", "{\\thinspace .}\n", "\\label{_auto2} \\tag{4}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The least squares method\n", "\n", "The idea of the least-squares method is to\n", "minimize the square of the norm of the\n", "residual with respect to the free parameters $c_0,\\ldots,c_k$.\n", "That is, we minimize $(r^{k+1},r^{k+1})$:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "{\\partial\\over\\partial c_i} (r^{k+1},r^{k+1}) =\n", "2({\\partial r^{k+1}\\over\n", "\\partial c_i},r^{k+1}) =0,\\quad i=0,\\ldots,k{\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since $\\partial r^{k+1} /\\partial c_i = -A{q}_i$, this approach leads to\n", "the following linear system:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"ch:linalg:ls:eq1\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "\\sum_{j=0}^k (A{q}_i,A{q}_j)c_j = (r^{k+1},A{q}_i),\\quad i=0,\\ldots,k{\\thinspace .}\n", "\\label{ch:linalg:ls:eq1} \\tag{5}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Krylov subspaces\n", "\n", "\n", "To obtain a complete algorithm, we need to establish a rule to update\n", "the basis $\\mathcal{B}=\\{q_0,\\ldots,{q}_k\\}$ for the next iteration.\n", "That is, we need to\n", "compute a new basis vector ${q}_{k+1}\\in V_{k+2}$ such that" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linalg2:cg:Basis\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "\\mathcal{B} =\\{ {q}_0,\\ldots,{q}_{k+1}\\}\n", "\\label{linalg2:cg:Basis} \\tag{6}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "is a basis for the space $V_{k+2}$ that is used in the next iteration.\n", "The present family of methods applies the *Krylov space*, where $V_k$\n", "is defined as" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto3\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "V_{k} = \\mbox{span} \\left\\lbrace r^0,Ar^0,A^2r^0,\\ldots\n", "A^{k-1}r^0 \\right\\rbrace {\\thinspace .}\n", "\\label{_auto3} \\tag{7}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some frequent names\n", "of the associated iterative methods are therefore\n", "{Krylov subspace iterations}, Krylov projection methods,\n", "or simply Krylov methods.\n", "It is a fact that $V_{k} \\subset V_{k+1}$ and that $r^0\n", "Ar^0,\\ldots A^{k-1}r^0$ are linearly independent\n", "vectors.\n", "\n", "## Computation of the basis vectors\n", "\n", "A potential formula for updating ${q}_{k+1}$, such that\n", "${q}_{k+1}\\in V_{k+2}$, is" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linalg:q:update1\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "{q}_{k+1} = r^{k+1} + \\sum_{j=0}^k\\beta_j{q}_j{\\thinspace .}\n", "\\label{linalg:q:update1} \\tag{8}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(Since $r^{k+1}$ involves $Aq_k$, and $q_k\\in V_{k+1}$, multiplying\n", "by $A$ raises the dimension of the Krylov space by 1, so $Aq_k\\in V_{k+2}$.)\n", "The free parameters $\\beta_j$ can be used to enforce desirable\n", "orthogonality properties of ${q}_0,\\ldots,{q}_{k+1}$. For example,\n", "it is convenient to require that the coefficient matrices in the linear\n", "systems for $c_0,\\ldots,c_k$ are diagonal.\n", "Otherwise, we must solve a $(k+1)\\times (k+1)$ linear system in each iteration.\n", "If $k$ should approach\n", "$n$, the systems for the coefficients $c_i$ are of\n", "the same size as our original system $Ax =b$!\n", "A diagonal matrix, however, ensures an efficient closed form solution for\n", "$c_0,\\ldots,c_k$.\n", "\n", "\n", "To obtain a diagonal coefficient matrix, we require in Galerkin's method\n", "that" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "(A{q}_i,{q}_j)=0\\quad \\mbox{when}\\ i\\neq j,\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "whereas we in the least-squares method require" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "(A{q}_i,A{q}_j)=0\\quad \\mbox{when}\\ i\\neq j{\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can define\n", "the inner product" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto4\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "\\langle u,v\\rangle\\equiv (Au,v ) =u^TAv,\n", "\\label{_auto4} \\tag{9}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "provided $A$ is symmetric and positive definite. Another\n", "useful inner product is" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto5\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "[u,v ]\\equiv (Au,Av) = u^TA^TAv {\\thinspace .}\n", "\\label{_auto5} \\tag{10}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These inner products will be referred to as the $A$ product, with the\n", "associated $A$ norm, and the $A^TA$ product, with the associated\n", "$A^TA$ norm.\n", "\n", "The orthogonality condition on the ${q}_i$ vectors are then\n", "$\\langle {q}_{k+1},{q}_i\\rangle =0$ in the Galerkin method\n", "and $[{q}_{k+1},{q}_i]=0$ in the least-squares method, where $i$\n", "runs from 0 to $k$.\n", "A standard Gram-Schmidt process can be used for constructing\n", "${q}_{k+1}$ orthogonal to ${q}_0,\\ldots,{q}_k$. This leads to the determination\n", "of the $\\beta_0,\\ldots,\\beta_k$ constants as" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linsys:betaiG\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "\\beta_i = { \\langle r^{k+1},{q}_i\\rangle\\over\\langle{q}_i,{q}_i\\rangle}\n", "\\quad\\hbox{(Galerkin)} \\label{linsys:betaiG} \\tag{11}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto6\"></div>\n", "\n", "$$\n", "\\begin{equation} \n", "\\beta_i = { [r^{k+1},{q}_i]\\over [{q}_i,{q}_i] }\n", "\\quad\\hbox{(least squares)}\n", "\\label{_auto6} \\tag{12}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "for $i=0,\\ldots,k$.\n", "\n", "## Computation of a new solution vector\n", "\n", "The orthogonality condition on the basis vectors ${q}_i$ leads to\n", "the following solution for $c_0,\\ldots,c_k$:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linsys:alpha:G\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "c_i = { (r^{k},{q}_i)\\over \\langle {q}_i,{q}_i\\rangle}\n", "\\quad\\hbox{(Galerkin)} \\label{linsys:alpha:G} \\tag{13}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linsys:alpha:LS\"></div>\n", "\n", "$$\n", "\\begin{equation} \n", "c_i = { (r^{k},A{q}_i)\\over [ {q}_i,{q}_i]}\n", "\\quad\\hbox{(least squares)} \\label{linsys:alpha:LS} \\tag{14}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In iteration $k$, $(r^{k},{q}_i)=0$ and\n", "$(r^{k},A{q}_i)=0$, for $i=0,\\ldots,k-1$, in the Galerkin and\n", "least squares case, respectively. Hence, $c_i =0$, for $i=0,\\ldots,\n", "k-1$. In other words," ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "x^{k+1} = x^{k} + c_k{q}_k {\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When $A$ is symmetric and positive definite, one can show that also\n", "$\\beta_i=0$, for $0=1,\\ldots,k-1$, in both the Galerkin and least\n", "squares methods. This means that $x^k$ and\n", "${q}_{k+1}$ can be updated using only ${q}_k$ and not the previous\n", "${q}_0,\\ldots,{q}_{k-1}$ vectors. This property has of course dramatic\n", "effects on the storage requirements of the algorithms as the number of\n", "iterations increases.\n", "\n", "For the suggested algorithms to work, we must require that the\n", "denominators in ([13](#linsys:alpha:G)) and ([14](#linsys:alpha:LS)) do\n", "not vanish. This is always fulfilled for the least-squares method,\n", "while a (positive or negative) definite matrix $A$ avoids break-down\n", "of the Galerkin-based iteration (provided ${q}_i \\neq 0$).\n", "\n", "The Galerkin solution method for linear systems was originally devised\n", "as a *direct method* in the 1950s. After $n$ iterations the exact\n", "solution is found in exact arithmetic, but at a higher cost than when\n", "using Gaussian elimination. Naturally, the method did not receive\n", "significant popularity before researchers discovered (in the beginning\n", "of the 1970s) that the method could produce a good approximation to\n", "$x$ for $k\\ll n$ iterations. The method, called the Conjugate\n", "Gradient method, has from then on caught considerable interest as an\n", "iterative scheme for solving linear systems arising from PDEs\n", "discretized such that the coefficient matrix becomes sparse.\n", "\n", "Finally, we mention how to terminate the iteration.\n", "The simplest criterion is $||r^{k+1}||\\leq\\epsilon_r$, where\n", "$\\epsilon_r$ is a small prescribed tolerance.\n", "Sometimes it is more appropriate to use a relative residual,\n", "$||r^{k+1}||/||r^0||\\leq\\epsilon_r$.\n", "Termination criteria for Conjugate Gradient-like methods is a subject\n", "on its own.\n", "\n", "## Summary of the least squares method\n", "\n", "In the algorithm below, we have summarized\n", "the computational steps in the least-squares method.\n", "Notice that we update the residual recursively instead of using\n", "$r^k=b - Ax^k$ in each iteration since we then avoid a possibly\n", "expensive matrix-vector product.\n", "\n", "1. given a start vector $x^0$,\n", " compute $r^0=b - Ax^0$ and set ${q}_0 =r^0$.\n", "\n", "2. for $k=0,1,2,\\ldots$ until termination criteria are fulfilled:\n", "\n", "a. $c_k = {(r^{k},A{q}_k)/ [{q}_k,{q}_k]}$\n", "\n", "b. $x^{k+1} = x^{k} + c_k{q}_k$\n", "\n", "c. $r^{k+1} = r^{k} - c_kA{q}_k$\n", "\n", "d. if $A$ is symmetric then\n", "\n", "1. $\\beta_k = {[r^{k+1},{q}_k]/ [{q}_k,{q}_k]}$\n", "\n", "a. ${q}_{k+1} = r^{k+1} - \\beta_k{q}_k$\n", "\n", "\n", "\n", "b. else\n", "\n", "1. $\\beta_j = {[r^{k+1},{q}_j]/ [{q}_j,{q}_j]},\\quad j=0,\\ldots,k$\n", "\n", "2. ${q}_{k+1} = r^{k+1} - \\sum_{j=0}^k\\beta_j{q}_j$\n", "\n", "\n", "\n", "### Remark\n", "\n", "The algorithm above is just a summary of the steps in the derivation\n", "of the least-squares method and should not be directly used for\n", "practical computations without further developments.\n", "\n", "## Truncation and restart\n", "\n", "When $A$ is nonsymmetric, the storage requirements of ${q}_0,\\ldots,{q}_k$\n", "may be prohibitively large. It has become a standard trick to\n", "either *truncate* or *restart* the algorithm.\n", "In the latter case one restarts the algorithm every $K+1$-th step, i.e.,\n", "one aborts the iteration and starts the algorithm again with $x^0=x^K$.\n", "The other alternative is to truncate the sum $\\sum_{j=0}^k\\beta_j{q}_j$\n", "and use only the last $K$ vectors:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "x^{k+1} = x^{k} + \\sum_{j=k-K}^k \\beta_j{q}_j{\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Both the restarted and truncated version of the algorithm require\n", "storage of only $K+1$ basis vectors ${q}_{k-K},\\ldots,{q}_k$.\n", "The basis vectors are also often called *search direction vectors*.\n", "The truncated version of the least-squares algorithm above\n", "is widely known as *Generalized Minimum Residuals*, shortened as GMRES,\n", "or GMRES$(K)$ to explicitly indicate the\n", "number of search direction vectors.\n", "In the literature one encounters the name\n", "*Generalized Conjugate Residual method*, abbreviated CGR, for\n", "the restarted version of Orthomin. When $A$ is symmetric, the method\n", "is known under the name *Conjugate Residuals*.\n", "\n", "\n", "## Summary of the Galerkin method\n", "\n", "\n", "In case of Galerkin's method, we assume that $A$ is symmetric and\n", "positive definite. The resulting computational procedure\n", "is the famous Conjugate Gradient\n", "method.\n", "Since $A$ must be symmetric, the recursive update of\n", "${q}_{k+1}$ needs only one previous search direction vector ${q}_k$, that is,\n", "$\\beta_j=0$ for $j<k$.\n", "\n", "1. Given a start vector $x^0$,\n", " compute $r^0=b - Ax^0$ and set ${q}_0 =r^0$.\n", "\n", "2. for $k=1,2,\\ldots$ until termination criteria are fulfilled:\n", "\n", "a. $c_k = {(r^{k},{q}_k) / \\langle {q}_k,{q}_k\\rangle}$\n", "\n", "b. $x^{k} = x^{k-1} + c_k{q}_k$\n", "\n", "c. $r^{k} = r^{k-1} - c_kA{q}_k$\n", "\n", "d. $\\beta_k = {\\langle r^{k+1},{q}_k\\rangle / \\langle{q}_k,{q}_k\\rangle}$\n", "\n", "e. ${q}_{k+1} = r^{k+1} - \\beta_k{q}_k$\n", "\n", "\n", "The previous remark that the listed algorithm is just a summary of the\n", "steps in the solution procedure, and not an efficient algorithm\n", "that should be implemented in its present form, must be repeated here.\n", "In general, we recommend to rely on some high-quality linear algebra library\n", "that offers an implementation of the Conjugate gradient method.\n", "\n", "**The computational nature of Conjugate gradient-like methods.**\n", "\n", "Looking at the Galerkin and least squares algorithms above,\n", "one notice that the matrix $A$ is only used in matrix-vector\n", "products. This means that it is sufficient\n", "to store only the nonzero entries of $A$.\n", "The rest of the algorithms consists of vector operations of the\n", "type $y \\leftarrow ax + y$,\n", "the slightly more general variant $q\\leftarrow ax +y$, as well as\n", "inner products.\n", "\n", "\n", "\n", "## A framework based on the error\n", "\n", "Let us define the error $e^k = x - x^k$. Multiplying this equation by $A$\n", "leads to the well-known relation between the error and the residual\n", "for linear systems:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"linalg:erroreq\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "Ae^k = r^k {\\thinspace .}\n", "\\label{linalg:erroreq} \\tag{15}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using $r^k = Ae^k$ we can reformulate the Galerkin and\n", "least-squares methods in terms of the error. The Galerkin method can\n", "then be written" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto7\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "(r^k,{q}_i ) = (Ae^k,{q}_i) = \\langle e^k,{q}_i\\rangle = 0,\\quad\n", "i=0,\\ldots,k{\\thinspace .}\n", "\\label{_auto7} \\tag{16}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the least-squares method we obtain" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto8\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "(r^k,A{q}_i) = [e^k,{q}_i] =0,\\quad i=0,\\ldots,k{\\thinspace .}\n", "\\label{_auto8} \\tag{17}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This means that" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "\\begin{align*}\n", "\\langle e^k, v\\rangle &= 0\\quad\\forall v\\in V_{k+1}\\hbox{ (Galerkin)}\\\\\n", "\\lbrack e^k, v \\rbrack &= 0\\quad\\forall v\\in V_{k+1}\\hbox{ (least-squares)}\n", "\\end{align*}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In other words, the error is $A$-orthogonal to the space $V_{k+1}$ in the\n", "Galerkin method, whereas the error is $A^TA$-orthogonal to $V_{k+1}$ in\n", "the least-squares method. When the error is orthogonal to a space, we\n", "find the best approximation in the associated norm to the solution in\n", "that space. Specifically here, it means that for a symmetric and positive\n", "definite $A$, the Conjugate gradient method finds the optimal adjustment\n", "in $V_{k+1}$ of the vector $x^k$ (in the $A$-norm)\n", "in the update for $x^{k+1}$. Similarly, the\n", "least squares formulation finds the optimal adjustment in $V_{k+1}$\n", "measured in the $A^TA$-norm.\n", "\n", "A lot of Conjugate gradient-like methods were developed in the 1980s and\n", "1990s, some of the most popular methods do not fit\n", "directly into the framework presented here. The theoretical\n", "similarities between the methods are covered in the literature, and\n", "we refer to it for algorithms and practical\n", "comments related to widespread methods, such as the SYMMLQ method (for\n", "symmetric indefinite systems), the Generalized Minimal Residual\n", "(GMRES) method, the BiConjugate Gradient (BiCG) method, the\n", "Quasi-Minimal Residual (QMR) method, and the BiConjugate Gradient\n", "Stabilized (BiCGStab) method. When $A$ is symmetric and positive\n", "definite, the Conjugate gradient method is the optimal choice with\n", "respect to computational efficiency, but when $A$ is nonsymmetric,\n", "the performance of the methods is strongly problem dependent, and one\n", "needs to experiment.\n", "\n", "\n", "# Preconditioning\n", "<div id=\"ch:linalg2:preconditioning\"></div>\n", "\n", "\n", "## Motivation and Basic Principles\n", "\n", "\n", "<div id=\"ch:linalg2:condno\"></div>\n", "The Conjugate Gradient method has been subject to extensive analysis,\n", "and its convergence properties are well understood.\n", "To reduce the initial error $e^0 =x -x^0$ with a factor\n", "$0 <\\epsilon\\ll 1$ after $k$ iterations, or more precisely,\n", "$||e^k||_{A}\\leq\\epsilon ||e^0||_{A}$, it can be shown that\n", "$k$ is bounded by" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "{1\\over2}\\ln{2\\over\\epsilon}\\sqrt{\\kappa},\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "where $\\kappa$ is the ratio of the largest and smallest eigenvalue of\n", "$A$. The quantity $\\kappa$ is commonly referred to as\n", "the spectral *condition number*.\n", "Common finite element and finite difference discretizations of\n", "Poisson-like PDEs lead to $\\kappa\\sim h^{-2}$, where $h$ denotes the\n", "mesh size. This implies that the Conjugate Gradient method converges\n", "slowly in PDE problems with fine meshes, as the number of iterations is\n", "proportional to $h^{-1}$.\n", "\n", "To speed up the Conjugate Gradient method, we should\n", "manipulate the eigenvalue distribution. For instance, we could reduce\n", "the condition number $\\kappa$. This can be achieved by so-called\n", "*preconditioning*. Instead of applying the iterative method to\n", "the system $Ax =b$, we multiply by a matrix $M^{-1}$ and\n", "apply the iterative method to the mathematically equivalent system" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto9\"></div>\n", "\n", "$$\n", "\\begin{equation} M^{-1}Ax = M^{-1}b {\\thinspace .} \\label{_auto9} \\tag{18}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The aim now is to construct a nonsingular *preconditioning matrix or algorithm*\n", "such that $M^{-1}A$\n", "has a more favorable condition number than $A$.\n", "We remark that we use the notation $M^{-1}$ here to indicate that it should resemble the inverse \n", "of the matrix $A$. \n", "\n", "For increased flexibility we can write\n", "$M^{-1} = C_LC_R$ and transform the system according to" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<!-- Equation labels as ordinary links -->\n", "<div id=\"_auto10\"></div>\n", "\n", "$$\n", "\\begin{equation}\n", "C_LAC_R y = C_Lb,\\quad y =C_R^{-1}x ,\n", "\\label{_auto10} \\tag{19}\n", "\\end{equation}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "where $C_L$ is the *left* and $C_R$ is the *right*\n", "preconditioner. If the original coefficient matrix $A$ is symmetric\n", "and positive definite, $C_L = C_R^T$ leads to preservation of these\n", "properties in the transformed system. This is important when applying\n", "the Conjugate Gradient method to the preconditioned linear system.\n", "Even if $A$ and $M$ are symmetric and positive definite,\n", "$M^{-1}A$ does not necessarily inherit these properties. It\n", "appears that for practical purposes one can express the iterative\n", "algorithms such that it is sufficient to work with a single\n", "preconditioning matrix $M$ only. We\n", "shall therefore speak of preconditioning in terms of the left\n", "preconditioner $M$ in the following.\n", "\n", "## Use of the preconditioning matrix in the iterative methods\n", "\n", "Optimal convergence for the Conjugate Gradient method is\n", "achieved when the coefficient matrix $M^{-1}A$ equals the identity matrix\n", "$I$ and only one iteration is required. In the algorithm we need to perform matrix-vector products\n", "$M^{-1}Au$ for an arbitrary $u\\in\\mathbb{R}^n$.\n", "This means that we have to solve a linear system with $M$ as coefficient\n", "matrix in each iteration since we implement the product $y =M^{-1}Au$\n", "in a two step fashion: First we compute $v = Au$ and then we\n", "solve the linear system $My =v$ for $y$. The optimal choice $M =A$\n", "therefore involves the solution of $Ay =v$ in each iteration, which\n", "is a problem of the same complexity as our original system $Ax =b$.\n", "The strategy must hence be to compute an $M^{-1} \\approx A^{-1} $ such that the\n", "algorithmic operations involved in the inversion of $M$ are cheap.\n", "\n", "\n", "The preceding discussion motivates the following\n", "demands on the preconditioning matrix $M$:\n", "\n", " * $M^{-1}$ should be a good approximation to $A$,\n", "\n", " * $M^{-1}$ should be inexpensive to compute,\n", "\n", " * $M^{-1}$ should be sparse in order to minimize storage requirements,\n", "\n", " * linear systems with $M$ as coefficient matrix must be efficiently solved.\n", "\n", "Regarding the last property, such systems must be solved in\n", "$\\mathcal{O}(n)$ operations, that is, a complexity of the same order\n", "as the vector updates in the Conjugate Gradient-like algorithms.\n", "These four properties are contradictory and some sort of compromise\n", "must be sought.\n", "\n", "## Classical iterative methods as preconditioners\n", "<div id=\"ch:linalg:SORprecond\"></div>\n", "\n", "\n", "The simplest possible iterative method for solving $Ax=b$ is" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "x^{k+1} = x^{k} + r^{k} {\\thinspace .}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Applying this method to the preconditioned system\n", "$M^{-1}Ax =M^{-1}b$ results in the scheme" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", "x^{k+1} = x^{k} + M^{-1}r^{k} ,\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "which is nothing but the formula for classical iterative methods such as\n", "the Jacobi method, the Gauss-Seidel method, SOR (Successive over-relaxation),\n", "and SSOR (Symmetric successive over-relaxation).\n", "This motivates for choosing $M$ as one iteration of these classical methods.\n", "In particular, these methods provide simple formulas for $M$:\n", "\n", " * Jacobi preconditioning: $M =D$.\n", "\n", " * Gauss-Seidel preconditioning: $M = D + L$.\n", "\n", " * SOR preconditioning: $M = \\omega^{-1}D +L$.\n", "\n", " * SSOR preconditioning: $M = (2-\\omega )^{-1} \\left( \\omega^{-1}D + L\\right) \\left( \\omega^{-1}D\\right)^{-1} \\left( \\omega^{-1}D + U\\right)$\n", "\n", "Turning our attention to the four requirements of the preconditioning\n", "matrix, we realize that the suggested $M$ matrices do not demand\n", "additional storage, linear systems with $M$ as coefficient matrix are\n", "solved effectively in $\\mathcal{O}(n)$ operations, and $M$ needs no\n", "initial computation. The only questionable property is how well $M$\n", "approximates $A$, and that is the weak point of using classical\n", "iterative methods as preconditioners.\n", "\n", "The Conjugate Gradient method can only utilize the Jacobi and SSOR\n", "preconditioners among the classical iterative methods, because the $M$\n", "matrix in that case is on the form $M^{-1}=C_LC_L^T$, which is\n", "necessary to ensure that the coefficient matrix of the preconditioned\n", "system is symmetric and positive definite. For certain PDEs, like the\n", "Poisson equation, it can be shown that the SSOR preconditioner reduces\n", "the condition number with an order of magnitude, i.e., from\n", "$\\mathcal{O}(h^{-2})$ to $\\mathcal{O}(h^{-1})$, provided we use the\n", "optimal choice of the relaxation parameter $\\omega$. According to\n", "experiments, however, the performance of the SSOR preconditioned\n", "Conjugate Gradient method is not very sensitive to the choice of\n", "$\\omega$. \n", "\n", "## Incomplete factorization preconditioners\n", "<div id=\"linalg:ILU\"></div>\n", "\n", "\n", "Imagine that we choose $M =A$ and solve systems $My =v$ by a\n", "direct method. Such methods typically first compute the LU\n", "factorization $M =\\bar L\\bar U$ and thereafter perform two\n", "triangular solves. The lower and upper triangular factors $\\bar L$ and\n", "$\\bar U$ are computed from a Gaussian elimination procedure.\n", "Unfortunately, $\\bar L$ and $\\bar U$ contain nonzero values, so-called\n", "*fill-in*, in many locations where the original matrix $A$ contains\n", "zeroes. This decreased sparsity of $\\bar L$ and $\\bar U$ increases\n", "both the storage requirements and the computational efforts related to\n", "solving systems $My =v$. An idea to improve the situation is to\n", "compute *sparse* versions of the factors $\\bar L$ and $\\bar U$. This\n", "is achieved by performing Gaussian elimination, but neglecting the\n", "fill-in (!). In this way, we can compute approximate factors $\\widehat L$\n", "and $\\widehat U$ that become as sparse as $A$. The storage\n", "requirements are hence only doubled by introducing a preconditioner,\n", "and the triangular solves become an $\\mathcal{O}(n)$ operation since\n", "the number of nonzeroes in the $\\widehat L$ and $\\widehat U$ matrices\n", "(and $A$) is $\\mathcal{O}(n)$ when the underlying PDE is discretized\n", "by finite difference or finite element methods. We call $M\n", "=\\widehat L\\widehat U$ an *incomplete LU factorization*\n", "preconditioner, often just referred to as the ILU preconditioner.\n", "\n", "Instead of throwing away all fill-in entries, we can add them to the\n", "main diagonal. This yields the *modified incomplete LU factorization*\n", "(MILU). One can also allow a certain amount of fill-in\n", "to improve the quality of the preconditioner, at the expense of\n", "more storage for the factors. Libraries offering ILU preconditioners\n", "will then often have a tolerance for how small a fill-in element in\n", "the Gaussian elimination must be to be dropped, and a parameter that\n", "governs the maximum number of nonzeros per row in the factors.\n", "A popular ILU implementation is the open source C code\n", "[SuperLU](https://fs.hlrs.de/projects/craydoc/docs_merged/books/S-6532-30/S-6532-30.pdf). This preconditioner is available to Python programmers through the\n", "`scipy.sparse.linalg.spilu` function.\n", "\n", "The general algorithm for MILU preconditioning follows the steps of\n", "traditional exact Gaussian elimination, except that\n", "we restrict the computations to the nonzero entries in $A$.\n", "The factors $\\widehat L$ and $\\widehat U$ can be stored directly in the\n", "sparsity structure of $A$, that is, the algorithm overwrites a copy\n", "$M$ of $A$ with\n", "its MILU factorization. The steps in the MILU factorizations are\n", "listed below.\n", "\n", "\n", "1. Given a sparsity pattern as an index set $\\mathcal{I}$,\n", " copy $M_{i,j}\\leftarrow A_{i,j}$, $i,j=1,\\ldots,n$\n", "\n", "2. for $k=1,2,\\ldots, n$\n", "\n", "a. for $i=k+1,\\ldots,n$\n", "\n", " * if $(i,k)\\in\\mathcal{I}$ then\n", "\n", "a. $M_{i,k}\\leftarrow M_{i,k}/M_{k,k}$\n", "\n", "\n", " * else\n", "\n", "a. $M_{i,k} = 0$\n", "\n", "\n", " * $r=M_{i,k}$\n", "\n", " * for $j=k+1,\\ldots,n$\n", "\n", " * if $j=i$ then\n", "\n", " * $M_{i,j}\\leftarrow M_{i,j} - rM_{k,j} + \\sum_{p=k+1}^n\n", " \\left( M_{i,p} - rM_{k,p}\\right)$\n", "\n", "\n", " * else\n", "\n", " * if $(i,j)\\in\\mathcal{I}$ then\n", "\n", " * $M_{i,j}\\leftarrow M_{i,j} - rM_{k,j}$\n", "\n", "\n", " * else\n", "\n", " * $M_{i,j} =0$\n", "\n", "\n", "\n", "\n", "\n", "\n", "We also remark here that the algorithm above needs careful refinement\n", "before it should be implemented in a code. For example, one will not\n", "run through a series of $(i,j)$ indices and test for each of them if\n", "$(i,j)\\in\\mathcal{I}$. Instead one should run more directly through\n", "the sparsity structure of $A$.\n", "\n", "\n", "## Preconditioners developed for solving PDE problems\n", "\n", "The above mentioned preconditioners are general purpose \n", "preconditioners that may be applied to solve any linear system\n", "and may speed up the solution process significantly. For linear\n", "systems arising from PDE problems there are however often more\n", "efficient preconditioners that exploit the fact that the matrices\n", "come from discretized PDEs. These preconditioners often enable\n", "the solution of linear systems involving millions of unknowns\n", "in a matter of seconds or less on a regular desktop computer. \n", "This means that solving these huge linear systems often \n", "takes less time than printing them file. Moreover, these preconditioners\n", "may be used on parallel computers in a scalable fashion such that\n", "simulations involving billions of degrees of freedom are available\n", "e.g. by cloud services or super-computing centers. \n", "\n", "The most efficient preconditioners are the so-called multilevel preconditioners\n", "(e.g. multigrid and domain decomposition) which in particular for\n", "Poisson type problems yields error reduction of a factor 10 per iteration \n", "and hence a typical iteration count of the iterative method of 5-10. \n", "These preconditioners utilize the fact that different parts of the\n", "solution can be localized or represented on a coarser resolution during\n", "the computations before being glued together to a close match to\n", "the true solution. While a proper description of these methods\n", "are beyond the scope here, we mention that black-box preconditioners\n", "are implemented in open source frameworks such as PETSc, Hypre, and Trilinos\n", "and these frameworks are used by most available finite element software (such as FEniCS). \n", "\n", "\n", "While these multilevel preconditioners are available and efficient for PDEs similar\n", "to the Poisson problem there is currently no black-box solver that handles\n", "general systems of PDEs. We mention, however, a promising approach for \n", "tackling some systems of PDEs, namely the so-called operator preconditioning\n", "framework. This framework utilize tools from functional analysis to deduct\n", "appropriate block preconditioners typically involving blocks composed\n", "of for instance multilevel preconditioners in a systematic construction. \n", "The framework has extended the use of Poisson type multilevel preconditioners\n", "to many systems of PDEs with success." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 2 }