func Solve(a sparse.Matrix, b, xInit *mat64.Vector, settings *Settings, method Method) (result Result, err error) { stats := Stats{ StartTime: time.Now(), } dim, c := a.Dims() if dim != c { panic("iterative: matrix is not square") } if xInit != nil && dim != xInit.Len() { panic("iterative: mismatched size of the initial guess") } if b.Len() != dim { panic("iterative: mismatched size of the right-hand side vector") } if xInit == nil { xInit = mat64.NewVector(dim, nil) } if settings == nil { settings = DefaultSettings(dim) } ctx := Context{ X: mat64.NewVector(dim, nil), Residual: mat64.NewVector(dim, nil), } // X = xInit ctx.X.CopyVec(xInit) if mat64.Norm(ctx.X, math.Inf(1)) > 0 { // Residual = Ax sparse.MulMatVec(ctx.Residual, 1, false, a, ctx.X) stats.MatVecMultiplies++ } // Residual = Ax - b ctx.Residual.SubVec(ctx.Residual, b) if mat64.Norm(ctx.Residual, 2) >= settings.Tolerance { err = iterate(method, a, b, settings, &ctx, &stats) } result = Result{ X: ctx.X, Stats: stats, Runtime: time.Since(stats.StartTime), } return result, err }
func Solve(a sparse.Matrix, b, xInit []float64, settings *Settings, method Method) (result Result, err error) { stats := Stats{ StartTime: time.Now(), } dim := len(xInit) if dim == 0 { panic("iterative: invalid dimension") } r, c := a.Dims() if r != c { panic("iterative: matrix is not square") } if c != dim { panic("iterative: mismatched size of the matrix") } if len(b) != dim { panic("iterative: mismatched size of the right-hand side vector") } if settings == nil { settings = DefaultSettings(dim) } ctx := Context{ X: make([]float64, dim), Residual: make([]float64, dim), } copy(ctx.X, xInit) copy(ctx.Residual, b) if floats.Norm(ctx.X, math.Inf(1)) > 0 { sparse.MulMatVec(-1, false, a, ctx.X, 1, 1, ctx.Residual, 1) stats.MatVecMultiplies++ } if floats.Norm(ctx.Residual, 2) >= settings.Tolerance { err = iterate(method, a, b, settings, &ctx, &stats) } result = Result{ X: ctx.X, Stats: stats, Runtime: time.Since(stats.StartTime), } return result, err }