示例#1
0
class GeometryMap:
    """Base class for geometry map.
    """
    def __init__(self, syms, exprs):
        from sympy import Array, oo
        if not isinstance(exprs, list) and not isinstance(exprs, Array):
            raise ValueError(
                "The ctor arg of GeometryMap -- exprs -- should be a list of sympy expressions."
            )
        self._exprs = Array(exprs)

        # if not isinstance(syms, list):
        #     raise ValueError("The ctor arg of GeometryMap -- syms -- should be a list of sympy variables, or a list of (sympy.Symbol, inf, sup)")
        self._syms = []
        for sym in syms:
            if isinstance(sym, tuple):
                assert (len(sym) == 3)
                self._syms.append(sym)
            else:
                self._syms.append((sym, -oo, +oo))

    @property
    def exprs(self):
        return self._exprs

    def expr(self, i: int):
        return self._exprs[i]

    def subs(self, *arg):
        return GeometryMap(self, self._exprs.subs(*arg), self._syms)

    @property
    def syms(self):
        return [sym[0] for sym in self._syms]

    def sym(self, i: int):
        return self._syms[i][0]

    @property
    def sym_limits(self):
        return [sym[1:] for sym in self._syms]

    def sym_limit(self, i: int):
        return self._syms[i][1:]

    @cached_property
    def jacobian(self):
        from sympy import Array
        return self.exprs.diff(Array(self.syms))

    def lambdified(self, *arg, **kwarg):
        from sympy import lambdify
        return lambdify(self.syms, self.exprs.tolist(), *arg, **kwarg)
示例#2
0
    def create_inverse_stencil_(self):
        m = self.c_stencil.shape[0]
        K = 5
        from sympy import symbols, Array,Matrix
        p = K >> 1
        X = []
        for x in range(K):
            Y = []
            for y in range(K):
                Z = []
                for z in range(K):
                    s = symbols("s{}{}{}".format(x,y,z))
                    Z.append(s)
                Y.append(Z)
            X.append(Y)
        M = X
        
        for x in range(0,p+1):
            for y in range(0,p+1):
                for z in range(0,p+1):
                    c = (p,p,p)
                    for x_ in [-1,1]:
                        for y_ in [-1,1]:
                            for z_ in [-1,1]:
                                xi = p + x_*x
                                yi = p + y_*y
                                zi = p + z_*z
                                M[xi][yi][zi] = M[p-x][p-y][p-z]
        M = Array(M)
        #print(M)
        self.inverse_stencil = S0
        u = []
        for e in M:
            if e not in u:
                u.append(e)

        print("Degrees of freedom : {}".format(len(u)))
        #pad with K-1 zeros
        pad = 2*(K-1)
        C = np.zeros([m+pad,m+pad,m+pad])
        C[K-1:K-1+m,K-1:K-1+m,K-1:K-1+m] = self.c_stencil
        N = C.shape[0]
        p = N >> 1
        eqs = []
        B = []
        w = []
        for i in range(N-K):
            for j in range(i,N-K):
                for k in range(j,N-K):
                    constraint = 0
                    for a in range(K):
                        for b in range(K):
                            for c in range(K):
                                constraint += C[i+a,j+b,k+c]*M[a,b,c]
                    eq = []
                    for e in u:
                        eq.append(constraint.diff(e))

                    eqs.append(eq)
                    if i==p and j == p and k == p:
                        B.append(1.)
                        w.append(0.)
                    else:
                        B.append(0.)
                        w.append(np.sqrt((a-K/2.)**2 + (b-K/2.)**2 + (c-K/2.)**2))
        A = np.array(eqs,dtype=float)
        B = np.array(B,dtype=float)
        w = np.array(w,dtype=float)
        print("A : {}".format(A.shape))
        x = np.linalg.pinv(A).dot(B)
        print(x)
        from scipy.optimize import minimize

#        w = np.exp(-w/(np.max(w)/2.))
#        w[(w<0.75)*(w>0.25)] = 0
        
        w = np.zeros(B.shape)
        w[B==1] = 1.
        w[B==0] = 1./np.sum(B==0)

        res = minimize(lambda x: np.sum(((A.dot(x) - B))**2),x)
        print(res)
        x = res.x
        M_ = M.subs({u[i]:x[i] for i in range(len(u))})
        M = np.zeros([K,K,K],dtype=float)
        for a in range(K):
            for b in range(K):
                for c in range(K):
                    M[a,b,c] = M_[a,b,c]
        M1 = self.create_inverse_stencil_()
        print(M)
        print(M1)
        print(M-M1)
        delta = np.zeros([N,N,N])
        for i in range(N-K):
            for j in range(N-K):
                for k in range(N-K):
                    constraint = 0
                    for a in range(K):
                        for b in range(K):
                            for c in range(K):
                                delta[i,j,k] += C[i+a,j+b,k+c]*M1[a,b,c]


        #delta = convolve(self.c_stencil,M,mode='constant')
        print(delta)
        peak = np.max(delta)
        delta[delta == peak] = 0.
        print("Peak {} max sidelobe {}".format(peak,np.max(np.abs(delta))))
        print("Peak / max sidelobe {}".format(peak/np.max(np.abs(delta))))