Documentation ¶
Overview ¶
Package iterative provides iterative algorithms for solving linear systems.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BiCG ¶
type BiCG struct {
// contains filtered or unexported fields
}
BiCG implements the biconjugate gradient iterative method with preconditioning for solving the system of linear equations
Ax = b,
where A is a non-symmetric matrix. For symmetric positive definite systems use CG.
BiCG needs MatVec, MatTransVec, PSolve, and PSolveTrans matrix operations.
type BiCGSTAB ¶
type BiCGSTAB struct {
// contains filtered or unexported fields
}
BiCGSTAB implements the BiConjugate Gradient STABilized iterative method with preconditioning for solving the system of linear equations
Ax = b,
where A is a non-symmetric matrix. For symmetric positive definite systems use CG.
BiCGSTAB needs MatVec and PSolve matrix operations.
type CG ¶
type CG struct {
// contains filtered or unexported fields
}
CG implements the Conjugate Gradient iterative method with preconditioning for solving the system of linear equations
Ax = b,
where A is a symmetric positive definite matrix.
CG needs MatVec and PSolve matrix operations.
Example ¶
package main import ( "fmt" "math" "github.com/vladimir-ch/iterative" ) func L2Projector(x0, x1 float64, n int, f func(float64) float64) (a iterative.MatrixOps, b []float64) { h := (x1 - x0) / float64(n) matvec := func(dst, src []float64) { h := h dst[0] = h / 3 * (src[0] + src[1]/2) for i := 1; i < n; i++ { dst[i] = h / 3 * (src[i-1]/2 + 2*src[i] + src[i+1]/2) } dst[n] = h / 3 * (src[n-1]/2 + src[n]) } b = make([]float64, n+1) b[0] = f(x0) * h / 2 for i := 1; i < n; i++ { b[i] = f(x0+float64(i)*h) * h } b[n] = f(x1) * h / 2 return iterative.MatrixOps{MatVec: matvec}, b } func main() { A, b := L2Projector(0, 1, 10, func(x float64) float64 { return x * math.Sin(x) }) res, err := iterative.LinearSolve(A, b, &iterative.CG{}, iterative.Settings{}) if err != nil { fmt.Println("Error:", err) } else { fmt.Printf("# iterations: %v\n", res.Stats.Iterations) fmt.Printf("Final residual: %.6e\n", res.Stats.ResidualNorm) fmt.Printf("Solution: %.6f\n", res.X) } }
Output: # iterations: 10 Final residual: 6.495861e-08 Solution: [-0.003341 0.006678 0.036530 0.085606 0.152981 0.237072 0.337006 0.447616 0.578244 0.682719 0.920847]
type Context ¶
type Context struct { // X is the current approximate solution. // On the first call to Method.Iterate, X // must contain the initial estimate. // Method must update X with the current // estimate when it commands // ComputeResidual and EndIteration. X []float64 // Residual is the current residual b-A*x. // On the first call to Method.Iterate, // Residual must contain the initial // residual. // TODO(vladimir-ch): Consider whether the // behavior should also include: Method // must update Residual with the current // value of b-A*x when it commands // EndIteration. Residual []float64 // ResidualNorm is (an estimate of) the // norm of the current residual. Method // must update it when it commands // CheckResidualNorm. It does not have to // be equal to the norm of Residual, some // methods (e.g., GMRES) can estimate the // residual norm without forming the // residual itself. // TODO(vladimir-ch): Actually this is // something that should be discussed. ResidualNorm float64 // Converged indicates to Method that the // ResidualNorm satisfies the stopping // criterion as a result of // CheckResidualNorm operation. If a // Method commands EndIteration with // Converged true, the caller must not // call Method.Iterate again without // calling Method.Init first. Converged bool // Src and Dst are the source and // destination vectors for various // Operations. Src, Dst []float64 }
Context mediates the communication between the Method and the caller. It must not be modified or accessed apart from the commanded Operations.
type GMRES ¶
type GMRES struct { // Restart is the restart parameter. // It must be 0 <= Restart <= dim. // If it is 0, it will be set to dim. Restart int // contains filtered or unexported fields }
GMRES implements the Generalized Minimum Residual method with the modified Gram-Schmidt orthogonalization. It uses restarts to control storage requirements.
type MatrixOps ¶
type MatrixOps struct { // MatVec computes A*x and stores the // result into dst. It must be non-nil. MatVec func(dst, x []float64) // MatTransVec computes A^T*x and stores // the result into dst. If the Method does // not command MatTransVec, this can be // nil. MatTransVec func(dst, x []float64) }
MatrixOps describes the matrix of the linear system in terms of A*x and A^T*x operations. TODO(vladimir-ch): Should this be an interface?
type Method ¶
type Method interface { // Init initializes the method for solving // a dim×dim linear system. Init(dim int) // Iterate retrieves data from Context, // updates it, and returns the next // operation. The caller must perform the // Operation using data in Context, and // depending on the state call Iterate // again. Iterate(*Context) (Operation, error) }
Method is an iterative method that produces a sequence of vectors converging to the vector x satisfying a system of linear equations
A x = b,
where A is non-singular dim×dim matrix, and x and b are vectors of dimension dim.
Method uses a reverse-communication interface between the iterative algorithm and the caller. Method acts as a client that commands the caller to perform needed operations via Operation returned from Iterate methods. This provides independence of Method on representation of the matrix A, and enables automation of common operations like checking for convergence and maintaining statistics.
type Operation ¶
type Operation uint64
Operation specifies the type of operation.
const ( NoOperation Operation = 0 // Multiply A*x where x is stored in // Context.Src and the result will be // stored in Context.Dst. MatVec Operation = 1 << (iota - 1) // Multiply A^T*x where x is stored in // Context.Src and the result will be // stored in Context.Dst. MatTransVec // Do the preconditioner solve // M z = r, // where r is stored in Context.Src, and // store the solution z in Context.Dst. PSolve // Do the preconditioner solve // M^T z = r, // where r is stored in Context.Src, and // store the solution z in Context.Dst. PSolveTrans // Compute b - A*x where x is stored in // Context.X and store the result into // Context.Dst. ComputeResidual // Check convergence using the current // approximation in Context.X and the // residual in Context.ResidualNorm. If // convergence is detected, // Context.Converged must be set to true // before calling Method.Iterate again. CheckResidualNorm // EndIteration indicates that Method has // finished what it considers to be one // iteration. It can be used to update an // iteration counter. If Context.Converged // is true, the iterative process must be // terminated, and Method.Init must be // called before calling Method.Iterate // again. EndIteration )
Operations commanded by Method.Iterate.
type Result ¶
type Result struct { // X is the approximate solution. X []float64 // Stats holds the statistics of the // solve. Stats Stats }
Result holds the result of an iterative solve.
func LinearSolve ¶
LinearSolve solves the system of n linear equations
A*x = b,
where the n×n matrix A is represented by the matrix-vector operations in a. The dimension of the problem n is determined by the length of b.
method is an iterative method used for finding an approximate solution of the linear system. It must not be nil. The operations in a must provide what the method needs.
settings provide means for adjusting the iterative process. Zero values of the fields mean default values.
type Settings ¶
type Settings struct { // X0 is an initial guess. // If it is nil, the zero vector will be // used. // If it is not nil, the length of X0 must // be equal to the dimension of the // system. X0 []float64 // Tolerance specifies error tolerance for // the final approximate solution produced // by the iterative method. Tolerance must // be smaller than one and greater than // the machine epsilon. // // If NormA is not zero, the stopping // criterion used will be // |r_i| < Tolerance * (|A|*|x_i| + |b|), // If NormA is zero (not available), the // stopping criterion will be // |r_i| < Tolerance * |b|. Tolerance float64 // NormA is an estimate of a norm |A| of // A, for example, an approximation of the // largest entry. Zero value means that // the norm is unknown, and it will not be // used in the stopping criterion. NormA float64 // MaxIterations is the limit on the // number of iterations. // If it is zero, it will be set to twice // the dimension of the system. MaxIterations int // PSolve describes the preconditioner // solve that stores into dst the solution // of the system // M z = rhs. // If it is nil, no preconditioning will // be used (M is the identitify). PSolve func(dst, rhs []float64) error // PSolveTrans describes the // preconditioner solve that stores into // dst the solution of the system // M^T z = rhs. // If it is nil, no preconditioning will // be used (M is the identitify). PSolveTrans func(dst, rhs []float64) error }
Settings holds various settings for solving a linear system.
type Stats ¶
type Stats struct { // Iterations is the number of iteration // done by Method. Iterations int // MatVec is the number of MatVec and // MatTransVec operations commanded by // Method. MatVec int // PSolve is the number of PSolve and // PSolveTrans operations commanded by // Method. PSolve int // ResidualNorm is the final norm of the // residual. ResidualNorm float64 // StartTime is an approximate time when // the solve was started. StartTime time.Time // Runtime is an approximate duration of // the solve. Runtime time.Duration }
Stats holds statistics about an iterative solve.