Skip to content

Instantly share code, notes, and snippets.

@pierrelux
Created November 28, 2014 20:29
Show Gist options
  • Save pierrelux/9bdc578dc09377303c12 to your computer and use it in GitHub Desktop.
Save pierrelux/9bdc578dc09377303c12 to your computer and use it in GitHub Desktop.
def bicgstab(x0, b, atv, eps, kmax):
n = b.shape[0]
errtol = eps*np.linalg.norm(b)
error = []
x = x0
rho = np.zeros(kmax+1)
if np.isclose(np.linalg.norm(x), 0.):
r = b
else:
r = b - atv(x)
hatr0=r
k=-1.
rho[0]=1.
alpha=1.
omega=1.
v=np.zeros(n)
p=np.zeros(n)
rho[1]=hatr0.T.dot(r)
zeta=np.linalg.norm(r)
error.append(zeta)
# Bi-CGSTAB iteration
while((zeta > errtol) and (k < kmax)):
k=k+1
if np.isclose(omega, 0.):
print 'Bi-CGSTAB breakdown, omega=0'
beta=(rho[k+1]/rho[k])*(alpha/omega)
p=r+beta*(p - omega*v)
v = atv(p)
tau=hatr0.T.dot(v)
if np.isclose(tau, 0.):
print 'Bi-CGSTAB breakdown, tau=0'
alpha=rho[k+1]/tau
s=r-alpha*v
t=atv(s)
tau=t.T.dot(t)
if np.isclose(tau, 0):
print 'Bi-CGSTAB breakdown, t=0'
omega=t.T.dot(s)/tau
rho[k+2]=-omega*(hatr0.T.dot(t))
x=x+alpha*p+omega*s
r=s-omega*t
zeta=np.linalg.norm(r)
total_iters=k
error.append(zeta)
return x, error, total_iters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment