def __init__(self, sig, err_lvl, x_true, PSF, recon=False, cmap='Greys', per_BC=False, per_BC_pad=False, per_t=0.0, restrict_dom=(None,None)): """ class representing a system we wish to invert. INPUT: sig - x_true_ftn parameter. err_lvl - desired noise level (ratio of 100). x_true - function from functions.py representing the true solution. PSF - Point Spread Function. recon - weather or not this is a PSF reconstruction problem. cmap - matplotlib colormap string name. per_BC - use periodic boundary condtions? per_BC_pad - pad the image to apply periodic BC without distortion? per_t - truncate amount (left, right, top, and bottom). restrict_dom - 2-tuple index to restrict (left, right) = (top, bottom) """ super(Inverse_System_2D, self).__init__() self.per_BC = per_BC self.per_BC_pad = per_BC_pad nx, ny = shape(x_true) nx = float(nx) ny = float(ny) n = nx * ny hx = 1/nx hy = 1/ny if not per_BC: tx = arange(0, 1, hx) ty = arange(0, 1, hy) # A discritization : if not recon: A1 = d_psf(tx, hx, PSF(tx, hx, sig=sig)) A2 = d_psf(ty, hy, PSF(ty, hy, sig=sig)) else: A1 = d_int(tx, hx) A2 = d_int(ty, hy) # Set up true solution x_true and data b = A*x_true + error : Ax = dot(dot(A1, x_true), A2.T) sigma = err_lvl/100.0 * norm(Ax) / sqrt(n) eta = sigma * randn(nx, ny) b = Ax + eta U1,S1,V1 = svd(A1) U2,S2,V2 = svd(A2) S = tensordot(S2, S1, 0) UTb = dot(dot(U1.T, b), U2) Vx = dot(V1.T, dot(x_true, V2)) self.A1 = A1 self.A2 = A2 self.U1 = U1 self.U2 = U2 self.V1 = V1 self.V2 = V2 self.S1 = S1 self.S2 = S2 else: left = -per_t right = per_t bottom = -per_t top = per_t tx = arange(left, right, hx) ty = arange(bottom, top, hy) # A discritization : if not recon: X,Y = meshgrid(tx,ty) ahat = fft2(fftshift(PSF(X, Y, hx, hy, sig=sig))) else: print "reconstruction not implemented" exit(1) # Set up true solution x_true and data b = A*x_true + error : l = restrict_dom[0] r = restrict_dom[1] Ax = real(ifft2(ahat * fft2(x_true))) Ax = Ax[l:r, l:r] x_true = x_true[l:r, l:r] nx2,ny2 = shape(Ax) nx2 = float(nx2) ny2 = float(ny2) n2 = nx2 * ny2 sigma = err_lvl/100.0 * norm(Ax) / sqrt(n2) eta = sigma * randn(nx2, ny2) b = Ax + eta bhat = fft2(b) if self.per_BC_pad: p_d = ((ny/4, ny/4), (nx/4, nx/4)) b_pad = pad(b, p_d, 'constant') bphat = fft2(b_pad) DT = pad(ones(ny2), (ny/4, ny/4), 'constant') D = pad(ones(nx2), (nx/4, nx/4), 'constant') M = tensordot(DT, D, 0) # mask array ATDb = real(ifft2(conj(ahat) * fft2(b_pad))) UTb = bphat self.D = D self.DT = DT self.M = M self.ATDb = ATDb self.bphat = bphat self.b_pad = b_pad else: if l is not None and r is not None: ml = 0.5*(r - l) mr = 1.5*(r - l) else: ml = 0 mr = nx ahat = ahat[ml:mr, ml:mr] UTb = bhat S = abs(ahat) Vx = fft2(x_true) self.ahat = ahat # 2D problems can only be filtered by Tikhonov regularization self.filt_type = 'Tikhonov' self.cmap = cmap self.per_BC = per_BC self.per_BC_pad = per_BC_pad self.rng = arange(0, 1, 0.1) self.n = n self.nx = nx self.ny = ny self.tx = tx self.ty = ty self.x_true = x_true self.Ax = Ax self.err_lvl = err_lvl self.sigma = sigma self.b = b self.S = S self.UTb = UTb self.Vx = Vx
def __init__(self, xi, xf, n, sig, err_lvl, x_true_ftn, PSF, recon=False): """ class representing a 1D system we wish to invert. INPUT: xi - begin of domain. xf - end of domain. n - number of cells. sig - x_true_ftn parameter. err_lvl - desired noise level (ratio of 100). x_true - function from functions.py representing the true solution. PSF - Point Spread Function for reconstruction problem recon - weather or not this is a PSF reconstruction problem. """ super(Inverse_System_1D, self).__init__() n = float(n) omega = xf - xi h = omega/n t = arange(xi, xf, h) # A discritization : if not recon: A = d_psf(t, h, PSF(t, h, sig)) else: A = d_int(t, h) # Set up true solution x_true and data b = A*x_true + error : x_true = x_true_ftn(t, h, sig) Ax = dot(A, x_true) sigma = err_lvl/100.0 * norm(Ax) / sqrt(n) eta = sigma * randn(n, 1) b = Ax + eta.T[0] x_ls = solve(A,b) U,S,V = svd(A) UTb = dot(U.T, b) # create regularization matrices for GMRF : diags = [-ones(n+1), ones(n+1)] D = array(spdiags(diags, [0, 1], n-1, n).todense()) L = dot(D.T, D) # by default, filter by Tikhonov parameterization self.filt_type = 'Tikhonov' self.rng = arange(0, 1, 0.1) self.omega = omega self.n = n self.h = h self.t = t self.A = A self.x_true = x_true self.x_ls = x_ls self.Ax = Ax self.err_lvl = err_lvl self.sigma = sigma self.b = b self.U = U self.S = S self.V = V self.Vx = dot(V, x_true) self.UTb = UTb self.D = D self.L = L