ssor.jl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. export ssor
  2. """
  3. x,flag,err,iter,resvec = ssor(A::SparseMatrixCSC, b::Vector; omega::Real=2/3, tol::Real=1e-2, maxIter::Int=1,out::Int=0)
  4. Symmetric successive over-relaxation applied to the linear system A*x = b.
  5. !! Note that upper/lower triangular matrix are never build to save memory !!
  6. Input:
  7. A - sparse matrix CSC
  8. b - right hand side vector
  9. omega - relaxation parameter (omega=1.0: Gauss Seidel)
  10. tol - error tolerance (default=1e-2)
  11. maxIter - maximum number of iterations (default=1)
  12. out - flag for output (-1 : no output, 0 : only errors, 1 : final status, 2: error at each iteration)
  13. Output:
  14. x - solution
  15. flag - exit flag ( 0 : desired tolerance achieved,
  16. -1 : maxIter reached without converging)
  17. err - error, i.e., norm(A*x-b)/norm(b)
  18. iter - number of iterations
  19. resvec - error at each iteration
  20. """
  21. function ssor(A::SparseMatrixCSC,b::Vector;tol::Real=1e-2,maxIter::Int=1,omega::Real=1.0,out::Int=0,storeInterm::Bool=false;)
  22. n = length(b)
  23. OmInvD = omega./diag(A) #D矩阵 并乘以omega
  24. x = zeros(eltype(A),n)
  25. r = b - A * x
  26. rnorm0 = norm(r)
  27. value = 0.0
  28. flag = -1
  29. iter = 0
  30. for iter = 1:maxIter
  31. println(iter)
  32. #第一次迭代
  33. for i = 1:n
  34. value = b[i]
  35. for j = 1:n
  36. for gidx = A.colptr[j] : A.colptr[j+1]-1
  37. if A.rowval[gidx] == i
  38. value -= A.nzval[gidx] * x[j]
  39. end
  40. end
  41. end
  42. x[i] = x[i] + value*OmInvD[i]
  43. end
  44. #第二次迭代
  45. for i = n:-1:1
  46. value = b[i]
  47. for j = 1:n
  48. for gidx = A.colptr[j] : A.colptr[j+1]-1
  49. if A.rowval[gidx] == i
  50. value -= A.nzval[gidx] * x[j]
  51. end
  52. end
  53. end
  54. x[i] = x[i] + value*OmInvD[i]
  55. end
  56. r = b - A*x
  57. println(norm(r) / rnorm0 )
  58. if norm(r) / rnorm0 < tol
  59. flag = 0; break
  60. end
  61. end
  62. println(r)
  63. println(x)
  64. return x,flag, norm(r) / rnorm0,iter
  65. end