def matrix(self, shape=None): """ This function returns the object as a matrix of DFT or iDFT resp. """ N=self.N prodN=np.prod(N) if shape is not None: dim=np.prod(np.array(shape)) elif hasattr(self, 'shape'): dim=np.prod(np.array(shape)) else: raise ValueError('Missing shape of the DFT.') proddN=dim*prodN ZN_input=Grid.get_ZNl(N, fft_form=0) ZN_output=Grid.get_ZNl(N, fft_form='c') if self.inverse: DFTcoef=lambda k, l, N: np.exp(2*np.pi*1j*np.sum(k*l/N)) else: DFTcoef=lambda k, l, N: np.exp(-2*np.pi*1j*np.sum(k*l/N))/np.prod(N) DTM=np.zeros([self.pN(), self.pN()], dtype=np.complex128) for ii, kk in enumerate(itertools.product(*tuple(ZN_output))): for jj, ll in enumerate(itertools.product(*tuple(ZN_input))): DTM[ii, jj]=DFTcoef(np.array(kk, dtype=np.float), np.array(ll), N) DTMd=npmatlib.zeros([proddN, proddN], dtype=np.complex128) for ii in range(dim): DTMd[prodN*ii:prodN*(ii+1), prodN*ii:prodN*(ii+1)]=DTM return DTMd
def matrix(self, shape=None): """ This function returns the object as a matrix of DFT or iDFT resp. """ N = self.N prodN = np.prod(N) if shape is not None: dim = np.prod(np.array(shape)) elif hasattr(self, 'shape'): dim = np.prod(np.array(shape)) else: raise ValueError('Missing shape of the DFT.') proddN = dim * prodN ZN_input = Grid.get_ZNl(N, fft_form=0) ZN_output = Grid.get_ZNl(N, fft_form='c') if self.inverse: DFTcoef = lambda k, l, N: np.exp(2 * np.pi * 1j * np.sum(k * l / N) ) else: DFTcoef = lambda k, l, N: np.exp(-2 * np.pi * 1j * np.sum( k * l / N)) / np.prod(N) DTM = np.zeros([self.pN(), self.pN()], dtype=np.complex128) for ii, kk in enumerate(itertools.product(*tuple(ZN_output))): for jj, ll in enumerate(itertools.product(*tuple(ZN_input))): DTM[ii, jj] = DFTcoef(np.array(kk, dtype=np.float), np.array(ll), N) DTMd = npmatlib.zeros([proddN, proddN], dtype=np.complex128) for ii in range(dim): DTMd[prodN * ii:prodN * (ii + 1), prodN * ii:prodN * (ii + 1)] = DTM return DTMd
def get_weights_circ(r, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with constant circular inclusion Parameters ---------- r - the parameter determining the size of inclusion Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) ZN2l = Grid.get_ZNl(Nbar, fft_form='c') meas_puc = np.prod(Y) circ = 0 for m in range(d): Nshape = np.ones(d, dtype=np.int) Nshape[m] = Nbar[m] Nrep = np.copy(Nbar) Nrep[m] = 1 xi_p2 = np.tile(np.reshape((ZN2l[m]/Y[m])**2, Nshape), Nrep) circ += xi_p2 circ = circ**0.5 ind = mean_index(Nbar, fft_form='c') circ[ind] = 1. Wphi = r**2 * sp.jn(1, 2*np.pi*circ*r) / (circ*r) Wphi[ind] = np.pi*r**2 Wphi = Wphi / meas_puc return Wphi
def get_weights_circ(r, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with constant circular inclusion Parameters ---------- r - the parameter determining the size of inclusion Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) ZN2l = Grid.get_ZNl(Nbar, fft_form='c') meas_puc = np.prod(Y) circ = 0 for m in range(d): Nshape = np.ones(d, dtype=np.int) Nshape[m] = Nbar[m] Nrep = np.copy(Nbar) Nrep[m] = 1 xi_p2 = np.tile(np.reshape((ZN2l[m] / Y[m])**2, Nshape), Nrep) circ += xi_p2 circ = circ**0.5 ind = mean_index(Nbar, fft_form='c') circ[ind] = 1. Wphi = r**2 * sp.jn(1, 2 * np.pi * circ * r) / (circ * r) Wphi[ind] = np.pi * r**2 Wphi = Wphi / meas_puc return Wphi
def get_weights_lin(h, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with bilinear inclusion at rectangular area Parameters ---------- h - the parameter determining the size of inclusion (half-size of support) Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) meas_puc = np.prod(Y) ZN2l = Grid.get_ZNl(Nbar, fft_form='c') Wphi = np.ones(Nbar) / meas_puc for ii in np.arange(d): Nshape = np.ones(d, dtype=np.int) Nshape[ii] = Nbar[ii] Nrep = np.copy(Nbar) Nrep[ii] = 1 Wphi *= h[ii]*np.tile(np.reshape((np.sinc(h[ii]*ZN2l[ii]/Y[ii]))**2, Nshape), Nrep) return Wphi
def get_weights_lin(h, Nbar, Y): """ it evaluates integral weights, which are used for upper-lower bounds calculation, with bilinear inclusion at rectangular area Parameters ---------- h - the parameter determining the size of inclusion (half-size of support) Nbar - no. of points of regular grid where the weights are evaluated Y - the size of periodic unit cell Returns ------- Wphi - integral weights at regular grid sizing Nbar """ d = np.size(Y) meas_puc = np.prod(Y) ZN2l = Grid.get_ZNl(Nbar, fft_form='c') Wphi = np.ones(Nbar) / meas_puc for ii in np.arange(d): Nshape = np.ones(d, dtype=np.int) Nshape[ii] = Nbar[ii] Nrep = np.copy(Nbar) Nrep[ii] = 1 Wphi *= h[ii] * np.tile( np.reshape((np.sinc(h[ii] * ZN2l[ii] / Y[ii]))**2, Nshape), Nrep) return Wphi
def get_shift_inclusion(N, h, Y): N = np.array(N, dtype=np.int) Y = np.array(Y, dtype=np.float) dim = N.size ZN = Grid.get_ZNl(N) SS = np.ones(N, dtype=np.complex128) for ii in np.arange(dim): Nshape = np.ones(dim, dtype=np.int) Nshape[ii] = N[ii] Nrep = N Nrep[ii] = 1 SS *= np.tile(np.reshape(np.exp(-2*np.pi*1j*(h[ii]*ZN[ii]/Y[ii])), Nshape), Nrep) return SS
def get_shift_inclusion(N, h, Y): N = np.array(N, dtype=np.int) Y = np.array(Y, dtype=np.float) dim = N.size ZN = Grid.get_ZNl(N) SS = np.ones(N, dtype=np.complex128) for ii in np.arange(dim): Nshape = np.ones(dim, dtype=np.int) Nshape[ii] = N[ii] Nrep = N Nrep[ii] = 1 SS *= np.tile( np.reshape(np.exp(-2 * np.pi * 1j * (h[ii] * ZN[ii] / Y[ii])), Nshape), Nrep) return SS
def matrix(self): """ This function returns the object as a matrix of DFT or iDFT resp. """ N=self.N prodN=np.prod(N) proddN=self.d*prodN ZNl=Grid.get_ZNl(N, fft_form='c') if self.inverse: DFTcoef=lambda k, l, N: np.exp(2*np.pi*1j*np.sum(k*l/N)) else: DFTcoef=lambda k, l, N: np.exp(-2*np.pi*1j*np.sum(k*l/N))/np.prod(N) DTM=np.zeros([self.pN(), self.pN()], dtype=np.complex128) for ii, kk in enumerate(itertools.product(*tuple(ZNl))): for jj, ll in enumerate(itertools.product(*tuple(ZNl))): DTM[ii, jj]=DFTcoef(np.array(kk, dtype=np.float), np.array(ll), N) DTMd=npmatlib.zeros([proddN, proddN], dtype=np.complex128) for ii in range(self.d): DTMd[prodN*ii:prodN*(ii+1), prodN*ii:prodN*(ii+1)]=DTM return DTMd