示例#1
0
    def calc_grad_theta(self, xmins, xmaxs, As_vectorized, BasMats, pts0, dt,
                        nTimeSteps, nStepsOdeSolver, pts_at_T, grad_per_point,
                        dim_domain, dim_range, nCs, incs):

        if dim_domain != dim_range:
            raise ValueError
        if pts_at_T is None:
            raise ValueError
        if len(incs) != dim_domain:
            raise ValueError(len(incs), dim_domain)

        if As_vectorized.ndim != 2:
            raise ValueError(As_vectorized.shape)
        if As_vectorized.shape[1] != (dim_domain + 1) * dim_domain:
            raise ValueError(As_vectorized.shape,
                             (dim_domain + 1) * dim_domain)

        nPts = pts0.shape[0]

        if not isinstance(pts0, CpuGpuArray):
            raise TypeError
        if not isinstance(pts_at_T, CpuGpuArray):
            raise TypeError

        # number of threads per block has to be >= than number of cells

    #    if self.nCells <= 128:
    #      threadsPerBlock = 128
        if self.nCells <= 256:
            threadsPerBlock = 256
#          threadsPerBlock = 256/4
        elif 256 < self.nCells <= 512:
            threadsPerBlock = 512
        elif 512 < self.nCells <= 625:
            threadsPerBlock = 625
        elif 512 < self.nCells <= 1024:
            threadsPerBlock = 1024
        else:
            raise NotImplementedError

        nBlocks = int(np.ceil(float(nPts) / float(threadsPerBlock)))

        if 0:
            print '(nPts', nPts
            print 'nBlocks', nBlocks
            print 'threadsPerBlock = ', threadsPerBlock
            print

        d = len(BasMats)

        if not isinstance(grad_per_point, CpuGpuArray):
            raise TypeError
        if grad_per_point.shape != (nPts, dim_range, d):
            raise ValueError(grad_per_point.shape)

        if 1:

            nC0, nC1, nC2, inc_x, inc_y, inc_z = self.parse_nCs_and_incs(
                dim_domain, incs, nCs)

            if dim_domain == dim_range:
                calc_gpu = self.calc_grad_theta_gpu
            else:
                raise NotImplementedError
            if 0:
                ipshell('hi')
                1 / 0
            calc_gpu(pts0.gpu,
                     pts_at_T.gpu,
                     drv.In(As_vectorized),
                     BasMats.gpu,
                     grad_per_point.gpu,
                     np.int32(d),
                     self.my_dtype(dt),
                     np.int32(nTimeSteps),
                     np.int32(nStepsOdeSolver),
                     np.int32(nPts),
                     np.int32(nC0),
                     np.int32(nC1),
                     np.int32(nC2),
                     np.float64(inc_x),
                     np.float64(inc_y),
                     np.float64(inc_z),
                     grid=(nBlocks, 1, 1),
                     block=(threadsPerBlock, 1, 1))

        return grad_per_point
    def calc_ll(self, theta):
        """
        Computes the ll per measurments.
        """
        cpa_space = self.cpa_space
        src = self.src
        signal = self.signal
        params_flow_int = self.params_flow_int
        transformed = self.transformed
        sigma_signal = self.sigma_signal
        ll = self.ll

        if src.shape[1] != cpa_space.dim_domain:
            raise ValueError(src.shape)

        cpa_space.theta2Avees(theta)
        cpa_space.update_pat()

        cpa_space.calc_T_inv(pts=src, out=transformed, **params_flow_int)

        if transformed.shape != src.shape:
            raise ValueError(transformed.shape, src.shape)

        if 0:
            # I think this is irrelevant here.
            # (it was relevant for the 1d case)
            scale_pts = src.shape[0]  # Assuming we normalized src
            # to [0,1],
            # we need to scale it
            # t0 [0,1,..,num_of_samples+1]

            transformed.gpu *= scale_pts

        if self.interp_type_for_ll == 'gpu_linear':
            resampler(pts_gpu=transformed.gpu,
                      img_gpu=signal.src.gpu,
                      img_wrapped_gpu=signal.transformed.gpu)
        else:
            remap_fwd_opencv(pts_inv=transformed,
                             img=signal.src,
                             img_wrapped_fwd=signal.transformed,
                             interp_method=self.interp_type_for_ll)

#        if signal.dst.shape[1]>1:
#            raise NotImplementedError("Only 1D signals for now")

#        plt.figure(17);
#        signal.transformed.gpu2cpu()
#        if not signal.transformed.cpu.any():
#            raise ValueError('wtf')
#        plt.subplot(221)
#        plt.imshow(signal.src.cpu.reshape(256,-1))
#        plt.subplot(222)
#        plt.imshow(signal.transformed.cpu.reshape(256,-1))
#
#        ipshell('hi')
#        2/0
        calc_signal_err_per_sample(signal.transformed.gpu, signal.dst.gpu,
                                   self.signal.err.gpu)

        #           print  np.allclose(signal.transformed.gpu.get()-
        #                              signal.dst.gpu.get(),
        #                              self.signal.err.gpu.get())
        #        if self.dim_signal != 1:
        #            raise NotImplementedError
        calc_ll_per_sample(ll=ll.gpu,
                           err=self.signal.err.gpu,
                           sigma=sigma_signal)

        if 0:
            res = -0.5 / (sigma_signal**2) * (
                (signal.transformed.gpu - signal.dst.gpu)**2).get()

            np.allclose(res.ravel(), ll.gpu.get())
            ipshell('stop')
            1 / 0


#        1/0
#        ipshell('stop');
#        if any(theta):
#            1/0
示例#3
0
def create_cont_constraint_mat_separable(H, v1s, v2s, nSides, nConstraints, nC,
                                         dim_domain, dim_range, tess):
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != 2:
        raise ValueError
    if dim_range not in [1, 2]:
        raise ValueError
    nHomoCoo = dim_domain + 1
    length_Avee = dim_range * nHomoCoo
    L1 = np.zeros((nConstraints / 2, nC * nHomoCoo))

    nPtsInSide = 2  #  Since, in 2D, the side is always a line joining 2 pts.
    #    if nSides != nConstraints/(nPtsInSide*dim_domain):
    #        raise ValueError(nSides,nConstraints)

    if nSides != nConstraints / (nPtsInSide * dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print nSides, nConstraints / (nPtsInSide * dim_range)
        ipshell('stop')
        raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range))

    if nSides != H.shape[0]:
        raise ValueError(nSides, H.shape)

#    M = nPtsInSide*dim_range
    M = nPtsInSide
    if dim_range == 1:
        raise NotImplementedError
        for i in range(nSides):
            v1 = v1s[i]
            v2 = v2s[i]

            h = H[i]
            a, b = h.nonzero()[0]  # idx for the relevant As
            # s stands for start
            # e stands for end
            s1 = a * length_Avee
            e1 = s1 + nHomoCoo
            s2 = b * length_Avee
            e2 = s2 + nHomoCoo

            # Constraint 1:
            L[i * M, s1:e1] = v1
            L[i * M, s2:e2] = -v1
            # Constraint 2:
            L[i * M + 1, s1:e1] = v2
            L[i * M + 1, s2:e2] = -v2

    elif dim_range == 2:
        for i in range(nSides):
            v1 = v1s[i]
            v2 = v2s[i]

            if np.allclose(v1, v2):
                raise ValueError(v1, v2)

            h = H[i]
            a, b = h.nonzero()[0]  # idx for the relevant As

            # L1 is acting on columns of the following form:
            #   [ a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 ... a_Nc b_Nc c_Nc d_Nc]
            # s stands for start
            # e stands for end
            s1 = a * nHomoCoo
            e1 = s1 + nHomoCoo
            s2 = b * nHomoCoo
            e2 = s2 + nHomoCoo

            try:
                # Constraint 1:
                row = np.zeros(L1.shape[1])
                row[s1:e1] = v1
                row[s2:e2] = -v1
                # x component
                L1[i * M] = row
            except:
                ipshell('fail')
                raise

            # Constraint 2:
            row = np.zeros(L1.shape[1])
            row[s1:e1] = v2
            row[s2:e2] = -v2
            # x component
            L1[i * M + 1] = row

    else:
        raise ValueError(dim_range)

    return L1
示例#4
0
    def __init__(self,cpa_space,scale_spatial=1.0/10,scale_value=0.001*1,
                          left_blk_rel_scale=None,
                          right_vec_scale=None):
#        scale_spatial=0.0
        if cpa_space.only_local:
            raise NotImplementedError('only_local=', cpa_space.only_local)
 
    
        self.scale_spatial = scale_spatial
        self.scale_value = scale_value                      
        if left_blk_rel_scale is None:                        
            raise ValueError("You need to pass this argument. 0.5 may be a good value")       
        if right_vec_scale is None:                        
            raise ValueError("You need to pass this argument. 0.5 may be a good value")
        self.left_blk_rel_scale = left_blk_rel_scale
        self.right_vec_scale = right_vec_scale                      
        # Covariance on the joint Lie algebra
        self.pa_cov  = create_joint_algebra_cov(cpa_space,
                                  scale_spatial=scale_spatial,
                                  scale_value=scale_value,
#                                  scale_value=1.0, %FOR DEBUGGING
                                  left_blk_rel_scale=left_blk_rel_scale,
                                  right_vec_scale=right_vec_scale)
                      
        # Covariance on the subspace of that Lie algebra                                         
        self.cpa_cov = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov)
#        
#        self.cpa_cov_debug = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov*(10**2))
#        
#        C=self.cpa_cov        
#        D=self.cpa_cov_debug
#        ipshell('hi')
#        1/0
        # computing inverse
        if 0:
            try:
                 
                self.pa_cov_inv = inv(self.pa_cov)
    #            ipshell("STOP")
            except:
                ipshell("Failed to invert")
                raise
        else:
            pass
            
         
        self.cpa_cov_inv = inv(self.cpa_cov)
        
#        if cpa_space.dim_domain==2:
#            if cpa_space.tess=='tri':
#                nV = len(cpa_space.local_stuff['vert_tess'])
#                if nV*2 != cpa_space.d:
#                    raise ValueError( nV ,  cpa_space.d)
        
#       
         
        if cpa_space.local_stuff:
            A2v = cpa_space.local_stuff.linop_Avees2velTess
            B = cpa_space.B
    #        H =  A2v.matmat(B.dot(B.T))
            H =  A2v.matmat(B).dot(B.T)
             
#            self.velTess_cpa_cov = H.dot(self.pa_cov).dot(H.T)            
#            self.velTess_cpa_cov_inv = inv(self.velTess_cpa_cov)

            self.velTess_cov_byB = H.dot(self.pa_cov).dot(H.T)     
            try:
                self.velTess_cov_byB_inv = inv(self.velTess_cov_byB) 
            except:
#                self.velTess_cov_byB=None
                self.velTess_cov_byB_inv=None
                
 
            
            if 0:
                self.velTess_cov  = create_cov_velTess(cpa_space=cpa_space,
                                        scale_spatial=scale_spatial,
                                        scale_value = scale_value)
                self.velTess_cov_inv = inv( self.velTess_cov)
示例#5
0
    def create_verts_and_H_type_II(self,dim_range):
        """
        This assummes 3D 
        
        H encodes the n'bors info.
        """    
        if self.type != 'II':
            raise ValueError(self.type)
        dim_domain=self.dim_domain
        nC = self.nC
        cells_multiidx=self.cells_multiidx
        cells_verts=self.cells_verts_homo_coo
#        nCx=self.nCx
#        nCy=self.nCy
#        nCz=self.nCz
        
        if dim_domain !=3:
            raise ValueError(dim_domain)
        if dim_range != dim_domain:
            raise NotImplementedError(dim_range)
#        if dim_range not in (1,dim_domain):
#            raise NotImplementedError(dim_range) 
        
        nbrs = np.zeros((nC,nC))
        
        mi=cells_multiidx # shorter name
        for i in range(nC):
            for j in range(nC):
                if mi[i] == mi[j]:
                    continue
                else:
    #               pair = (np.abs(mi[i][0]-mi[j][0]),
    #                       np.abs(mi[i][1]-mi[j][1]))
    #               if set(pair) == set([0,1]):
    #                   nbrs[i,j]=1
                   triplet = (np.abs(mi[i][0]-mi[j][0]),
                              np.abs(mi[i][1]-mi[j][1]),
                              np.abs(mi[i][2]-mi[j][2]))
                   triplet=np.asarray(triplet)
                   if (triplet==0).sum()==2 and (triplet==1).sum()==1:
                       nbrs[i,j]=1            
    
    
        nSides=nbrs.sum().astype(np.int)/2   
        
        
    
        
        # H is larger than we need
        # but it was easier to code this way.
        # Later we eliminate the unused rows.
        H = np.zeros((nC**2,nC))
    #    H = sparse.lil_matrix((nC**2,nC))
        
        for i in range(nC):
            for j in range(nC):   
                # k is the index of the row in H.
                # Most rows won't be used.
                k = i*nC + j
                if i < j:
                    continue
                nbr = nbrs[i,j]
                if nbr:
                    H[k,i]=-1
                    H[k,j]=+1
    
         
        
        verts1 = []
        verts2 = []    
        verts3 = []   
        verts4 = []
        counter = 0  
        for h in H:
            if h.any():  
    #        if h.nnz:
            
                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.            
    #            h = np.asarray(h.todense().tolist()[0])  # Workaround.
                
                 
                counter+=4
                # Find the vertex pair
                i = (h==1).nonzero()[0][0]     
                j = (h==-1).nonzero()[0][0]
    #            a = mi[i]
    #            b = mi[j]
                
                vi = cells_verts[i]
                vj = cells_verts[j]
                           
                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)
                
                side = set(vi).intersection(vj)
                if len(side) != 4: # adjcant boxes share 4 verts
                    ipshell('oops')
                    raise ValueError(len(side),side)
                try:
                    v1,v2,v3,v4 = np.asarray(list(side))
                except:
                    ipshell('hi')
                    raise                
        
                verts1.append(v1)
                verts2.append(v2)
                verts3.append(v3)
                verts4.append(v4)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b
        
        if counter != nSides*4:
            raise ValueError(counter,nEdges)      
         
        # Every side conntect 4 vertices. 
        # At every vertex, all components of the velocity must agree.
    #    nConstraints = nSides*4*dim_domain
        nConstraints = nSides*4*dim_range 
     
        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)   
        verts3 = np.asarray(verts3) 
        verts4 = np.asarray(verts4) 
    
        H = np.asarray([h for h in H if h.any()])    
    #    H = np.asarray([h for h in H if h.nnz])                                   
     
    
    
    #    
     #    ipshell('hi')
    #    1/0 
        
        
        return verts1,verts2,verts3,verts4,H,nSides,nConstraints    
    def calc_ll(self, theta):
        """
        Computes the ll per measurments.
        """
        cpa_space = self.cpa_space
        src = self.src
        signal = self.signal
        params_flow_int = self.params_flow_int
        transformed = self.transformed
        sigma_signal = self.sigma_signal
        ll = self.ll

        if src.shape[1] != cpa_space.dim_domain:
            raise ValueError(src.shape)

        cpa_space.theta2Avees(theta)
        cpa_space.update_pat()

        cpa_space.calc_T_inv(pts=src, out=transformed, **params_flow_int)

        if transformed.shape != src.shape:
            raise ValueError(transformed.shape, src.shape)

        if 0:
            # I think this is irrelevant here.
            # (it was relevant for the 1d case)
            scale_pts = src.shape[0]  # Assuming we normalized src
            # to [0,1],
            # we need to scale it
            # t0 [0,1,..,num_of_samples+1]

            transformed.gpu *= scale_pts

        if self.interp_type_for_ll == "gpu_linear":
            resampler(pts_gpu=transformed.gpu, img_gpu=signal.src.gpu, img_wrapped_gpu=signal.transformed.gpu)
        else:
            remap_fwd_opencv(
                pts_inv=transformed,
                img=signal.src,
                img_wrapped_fwd=signal.transformed,
                interp_method=self.interp_type_for_ll,
            )

        #        if signal.dst.shape[1]>1:
        #            raise NotImplementedError("Only 1D signals for now")

        #        plt.figure(17);
        #        signal.transformed.gpu2cpu()
        #        if not signal.transformed.cpu.any():
        #            raise ValueError('wtf')
        #        plt.subplot(221)
        #        plt.imshow(signal.src.cpu.reshape(256,-1))
        #        plt.subplot(222)
        #        plt.imshow(signal.transformed.cpu.reshape(256,-1))
        #
        #        ipshell('hi')
        #        2/0
        calc_signal_err_per_sample(signal.transformed.gpu, signal.dst.gpu, self.signal.err.gpu)

        #           print  np.allclose(signal.transformed.gpu.get()-
        #                              signal.dst.gpu.get(),
        #                              self.signal.err.gpu.get())
        #        if self.dim_signal != 1:
        #            raise NotImplementedError
        calc_ll_per_sample(ll=ll.gpu, err=self.signal.err.gpu, sigma=sigma_signal)

        if 0:
            res = -0.5 / (sigma_signal ** 2) * ((signal.transformed.gpu - signal.dst.gpu) ** 2).get()

            np.allclose(res.ravel(), ll.gpu.get())
            ipshell("stop")
            1 / 0
示例#7
0
    def create_verts_and_H_type_I(self, dim_range, valid_outside):
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """
        if self.type != 'I':
            raise ValueError(self.type)
        dim_domain = self.dim_domain
        nC = self.nC
        cells_multiidx = self.cells_multiidx
        cells_verts = self.cells_verts_homo_coo
        nCx = self.nCx
        nCy = self.nCy

        if dim_domain != 2:
            raise ValueError(dim_domain)
        if dim_range not in (1, 2):
            raise NotImplementedError(dim_range)

        nbrs = np.zeros((nC, nC), dtype=np.bool)

        if valid_outside:
            left = np.zeros((nC, nC), np.bool)
            right = np.zeros((nC, nC), np.bool)
            top = np.zeros((nC, nC), np.bool)
            bottom = np.zeros((nC, nC), np.bool)

        print 'Encoding continuity constraints.'
        print 'If nC is large, this may take some time.'
        print 'For a given configuration, however, this is done only once;'
        print 'the results computed here will be saved and reused the next time'
        print 'you use the same configuration.'

        # TODO: Cython
        #

        for i in range(nC):
            if nC > 200 and i % 200 == 0:
                print i, '/', nC
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                shared_verts = set(vi).intersection(vj)

                if len(mi) != 3:
                    raise ValueError
                if len(mj) != 3:
                    raise ValueError
                if mi == mj:
                    # same cell, nothing to do here
                    continue
                elif mi[:-1] == mj[:-1]:
                    # Same rect boxs, different triangles
                    s = set([mi[-1], mj[-1]])
                    if s in [
                            set([0, 1]),
                            set([1, 2]),
                            set([2, 3]),
                            set([3, 0])
                    ]:
                        nbrs[i, j] = 1
                else:
                    # different rect boxes

                    if valid_outside:
                        #                 try to deal with the extension
                        if mi[0] == mj[0] == 0:  # leftmost col
                            if mi[2] == mj[2] == 3:  # left triangle
                                if np.abs(mi[1] - mj[1]) == 1:  # adjacent rows
                                    nbrs[i, j] = 1
                                    left[i, j] = True
                                    continue

                        if mi[0] == mj[0] == nCx - 1:  # rightmost col
                            if mi[2] == mj[2] == 1:  # right triangle
                                if np.abs(mi[1] - mj[1]) == 1:  # adjacent rows
                                    nbrs[i, j] = 1
                                    right[i, j] = True
                                    continue

                        if mi[1] == mj[1] == 0:  # uppermost row
                            if mi[2] == mj[2] == 0:  # upper triangle
                                if np.abs(mi[0] - mj[0]) == 1:  # adjacent cols
                                    nbrs[i, j] = 1
                                    top[i, j] = True
                                    continue

                        if mi[1] == mj[1] == nCy - 1:  # lowermost row
                            if mi[2] == mj[2] == 2:  # lower triangle
                                if np.abs(mi[0] - mj[0]) == 1:  # adjacent cols
                                    nbrs[i, j] = 1
                                    bottom[i, j] = True
                                    continue

                    if set([mi[2], mj[2]]) not in [set([0, 2]), set([1, 3])]:
                        continue

                    pair = (mi[0] - mj[0]), (mi[1] - mj[1])

                    # Recall the order of triangles is
                    #         0
                    #       3   1
                    #         2

                    # vertical nbr's
                    if pair == (0, 1) and (mi[2], mj[2]) == (0, 2):

                        nbrs[i, j] = 1
                    elif pair == (0, -1) and (mi[2], mj[2]) == (2, 0):

                        nbrs[i, j] = 1
                    # horizontal nbr's
                    elif pair == (1, 0) and (mi[2], mj[2]) == (3, 1):

                        nbrs[i, j] = 1
                    elif pair == (-1, 0) and (mi[2], mj[2]) == (1, 3):

                        nbrs[i, j] = 1

        print 'Creating H of size (nC**2,nC)=({},{})'.format(nC**2, nC)
        try:
            H = np.zeros((nC**2, nC))
        except MemoryError:
            msg = 'Got MemoryError when trying to call np.zeros((nC**2,nC))'
            ipshell(msg)
            raise MemoryError('np.zeros((nC**2,nC))', 'nC={}'.format(nC))

#        H = sparse.lil_matrix((nC**2,nC))

        for i in range(nC):
            for j in range(nC):
                k = i * nC + j
                if i < j:
                    continue
                nbr = nbrs[i, j]
                if nbr:
                    H[k, i] = -1
                    H[k, j] = +1

    #    ipshell('save H')
    #    1/0
        verts1 = []
        verts2 = []
        k = 0
        print 'Extracting the vertices'
        for count, h in enumerate(H):
            if H.shape[0] > 1000:
                if count % 100000 == 0:
                    print count, '/', H.shape[0]
    #        ipshell('..')

            if h.any():
                #            if h.nnz:
                #                ipshell('STOP')
                #                # Make h dense and flat
                #                h=np.asarray(h.todense()).ravel()

                i = (h == 1).nonzero()[0][0]
                j = (h == -1).nonzero()[0][0]

                mi = cells_multiidx[i]
                mj = cells_multiidx[j]

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                shared_verts = set(vi).intersection(vj)

                if len(shared_verts) == 0:
                    continue
                if len(shared_verts) == 1:
                    # single vertex
                    if any([left[i, j], right[i, j], top[i, j], bottom[i, j]]):
                        # shared_vert is a set that contains a single tuple.
                        v_aux = list(shared_verts)[0]  # v_aux is a tuple
                        v_aux = list(
                            v_aux)  # Now v_aux is a list (i.e. mutable)
                        if left[i, j] or right[i, j]:
                            v_aux[
                                0] -= 10  # Create a new vertex  with the same y
                        elif top[i, j] or bottom[i, j]:
                            v_aux[
                                1] -= 10  # Create a new vertex  with the same x
                        else:
                            raise ValueError("WTF?")
                        v_aux = tuple(v_aux)
                        shared_verts.add(v_aux)  # add it to the set
    #                    ipshell('hello')
    #                    print shared_verts
                    else:
                        # We can skip it since the continuity at this vertex
                        # will be imposed via the edges.
                        continue

                if len(shared_verts) != 2:
                    ipshell('oops')
                    raise ValueError(len(shared_verts), shared_verts)
                try:
                    v1, v2 = np.asarray(list(shared_verts))
                except:
                    ipshell('oops2')
                    raise
                k += 2
                verts1.append(v1)
                verts2.append(v2)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b

    #    nEdges=nbrs.sum().astype(np.int)/2
    #    if k != nEdges*2:
    #        raise ValueError(k,nEdges)

        nEdges = k / 2

        # Every edge connects 2 vertices.
        # At every vertex, all components of the velocity must agree.
        nConstraints = nEdges * 2 * dim_range

        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)

        H = np.asarray([h for h in H if h.any()])
        #        H = np.asarray([h for h in H if h.nnz])
        print 'H is ready'

        return verts1, verts2, H, nEdges, nConstraints
示例#8
0
    def __init__(self,
                 cpa_space,
                 scale_spatial=1.0 / 10,
                 scale_value=0.001 * 1,
                 left_blk_rel_scale=None,
                 right_vec_scale=None):
        #        scale_spatial=0.0
        if cpa_space.only_local:
            raise NotImplementedError('only_local=', cpa_space.only_local)

        self.scale_spatial = scale_spatial
        self.scale_value = scale_value
        if left_blk_rel_scale is None:
            raise ValueError(
                "You need to pass this argument. 0.5 may be a good value")
        if right_vec_scale is None:
            raise ValueError(
                "You need to pass this argument. 0.5 may be a good value")
        self.left_blk_rel_scale = left_blk_rel_scale
        self.right_vec_scale = right_vec_scale
        # Covariance on the joint Lie algebra
        self.pa_cov = create_joint_algebra_cov(
            cpa_space,
            scale_spatial=scale_spatial,
            scale_value=scale_value,
            #                                  scale_value=1.0, %FOR DEBUGGING
            left_blk_rel_scale=left_blk_rel_scale,
            right_vec_scale=right_vec_scale)

        # Covariance on the subspace of that Lie algebra
        self.cpa_cov = self.pa_cov_to_cpa_cov(cpa_space, self.pa_cov)
        #
        #        self.cpa_cov_debug = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov*(10**2))
        #
        #        C=self.cpa_cov
        #        D=self.cpa_cov_debug
        #        ipshell('hi')
        #        1/0
        # computing inverse
        if 0:
            try:

                self.pa_cov_inv = inv(self.pa_cov)
    #            ipshell("STOP")
            except:
                ipshell("Failed to invert")
                raise
        else:
            pass

        self.cpa_cov_inv = inv(self.cpa_cov)

        #        if cpa_space.dim_domain==2:
        #            if cpa_space.tess=='tri':
        #                nV = len(cpa_space.local_stuff['vert_tess'])
        #                if nV*2 != cpa_space.d:
        #                    raise ValueError( nV ,  cpa_space.d)

        #

        if cpa_space.local_stuff:
            A2v = cpa_space.local_stuff.linop_Avees2velTess
            B = cpa_space.B
            #        H =  A2v.matmat(B.dot(B.T))
            H = A2v.matmat(B).dot(B.T)

            #            self.velTess_cpa_cov = H.dot(self.pa_cov).dot(H.T)
            #            self.velTess_cpa_cov_inv = inv(self.velTess_cpa_cov)

            self.velTess_cov_byB = H.dot(self.pa_cov).dot(H.T)
            try:
                self.velTess_cov_byB_inv = inv(self.velTess_cov_byB)
            except:
                #                self.velTess_cov_byB=None
                self.velTess_cov_byB_inv = None

            if 0:
                self.velTess_cov = create_cov_velTess(
                    cpa_space=cpa_space,
                    scale_spatial=scale_spatial,
                    scale_value=scale_value)
                self.velTess_cov_inv = inv(self.velTess_cov)
def create_cont_constraint_mat(N, H, verts, nSides, nConstraints, nC,
                               dim_domain, dim_range, tess):
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != N:
        raise ValueError
    if dim_range != N:
        raise NotImplementedError
    nHomoCoo = dim_domain + 1
    #    length_Avee = dim_domain*nHomoCoo
    length_Avee = dim_range * nHomoCoo
    L = np.zeros((nConstraints, nC * length_Avee))
    #
    if tess == 'II':
        nPtsInSide = 2**(N - 1)
    else:
        raise ValueError
#    if nSides != nConstraints/(nPtsInSide*dim_domain):
#        raise ValueError(nSides,nConstraints)

    if nSides != nConstraints / (nPtsInSide * dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print nSides, nConstraints / (nPtsInSide * dim_range)
        ipshell('stop')
        raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range))

    if nSides != H.shape[0]:
        raise ValueError(nSides, H.shape)

    M = nPtsInSide * dim_range

    verts = np.asarray(map(np.asarray, verts))

    # verts.shape is (2**(N-1),nSides,N+1))
    if verts.shape != (2**(N - 1), nSides, N + 1):
        raise ValueError(verts.shape)

    if dim_range == N:

        # loop over interfaces
        for i in range(nSides):

            verts_in_this_side = verts[:, i, :]

            h = H[i]
            a, b = h.nonzero()[0]  # idx for the relevant As
            # s stands for start
            # e stands for end
            s1 = a * length_Avee
            e1 = s1 + nHomoCoo
            s2 = b * length_Avee
            e2 = s2 + nHomoCoo

            # loop over vertices in this inter-cell interface
            for j in range(nPtsInSide):
                row = np.zeros(L.shape[1])
                row[s1:e1] = verts_in_this_side[j]
                row[s2:e2] = -verts_in_this_side[j]

                # loop over coordinates in this vertex
                for coo in range(N):
                    L[i * M + j * N + coo] = np.roll(row, coo * nHomoCoo)

    else:
        raise ValueError(dim_range)

    return L
示例#10
0
def create_cont_constraint_mat(H, v1s, v2s, v3s, v4s, nSides, nConstraints, nC,
                               dim_domain, dim_range, tess):
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != 3:
        raise ValueError
    if dim_range not in [1, 3]:
        raise ValueError
    nHomoCoo = dim_domain + 1
    #    length_Avee = dim_domain*nHomoCoo
    length_Avee = dim_range * nHomoCoo
    L = np.zeros((nConstraints, nC * length_Avee))
    #
    if tess == 'II':
        nPtsInSide = 4
    elif tess == 'I':
        nPtsInSide = 3
#    if nSides != nConstraints/(nPtsInSide*dim_domain):
#        raise ValueError(nSides,nConstraints)

    if nSides != nConstraints / (nPtsInSide * dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print nSides, nConstraints / (nPtsInSide * dim_range)
        ipshell('stop')
        raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range))

    if nSides != H.shape[0]:
        raise ValueError(nSides, H.shape)

    M = nPtsInSide * dim_range
    if dim_range == 1:
        for i in range(nSides):
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess == 'II':
                v4 = v4s[i]
            h = H[i]
            a, b = h.nonzero()[0]  # idx for the relevant As
            # s stands for start
            # e stands for end
            s1 = a * length_Avee
            e1 = s1 + nHomoCoo
            s2 = b * length_Avee
            e2 = s2 + nHomoCoo

            # Constraint 1:
            L[i * M, s1:e1] = v1
            L[i * M, s2:e2] = -v1
            # Constraint 2:
            # x component
            L[i * M + 1, s1:e1] = v2
            L[i * M + 1, s2:e2] = -v2
            # Constraint 3:
            L[i * M + 2, s1:e1] = v3
            L[i * M + 2, s2:e2] = -v3
            if tess == 'II':
                # Constraint 4:
                L[i * M + 3, s1:e1] = v4
                L[i * M + 3, s2:e2] = -v4

    elif dim_range == 3:
        for i in range(nSides):
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess == 'II':
                v4 = v4s[i]
            if np.allclose(v1, v2):
                raise ValueError(v1, v2)
            if np.allclose(v1, v3):
                raise ValueError(v1, v3)
            if np.allclose(v2, v3):
                raise ValueError(v2, v3)
            if tess == 'II':
                if np.allclose(v1, v4):
                    raise ValueError(v1, v4)
                if np.allclose(v2, v4):
                    raise ValueError(v2, v4)
                if np.allclose(v3, v4):
                    raise ValueError(v3, v4)

            h = H[i]
            a, b = h.nonzero()[0]  # idx for the relevant As
            # s stands for start
            # e stands for end
            s1 = a * length_Avee
            e1 = s1 + nHomoCoo
            s2 = b * length_Avee
            e2 = s2 + nHomoCoo

            # Constraint 1:
            row = np.zeros(L.shape[1])
            row[s1:e1] = v1
            row[s2:e2] = -v1
            # x component
            L[i * M] = row
            # y component
            L[i * M + 1] = np.roll(row, nHomoCoo)
            # z component
            L[i * M + 2] = np.roll(row, 2 * nHomoCoo)

            # Constraint 2:
            row = np.zeros(L.shape[1])
            row[s1:e1] = v2
            row[s2:e2] = -v2
            # x component
            L[i * M + 3] = row
            # y component
            L[i * M + 4] = np.roll(row, nHomoCoo)
            # z component
            L[i * M + 5] = np.roll(row, nHomoCoo * 2)

            # Constraint 3:
            row = np.zeros(L.shape[1])
            row[s1:e1] = v3
            row[s2:e2] = -v3
            # x component
            L[i * M + 6] = row
            # y component
            L[i * M + 7] = np.roll(row, nHomoCoo)
            # z component
            L[i * M + 8] = np.roll(row, 2 * nHomoCoo)
            #            ipshell('qqq')
            #            1/0

            if tess == 'II':
                # Constraint 4:
                row = np.zeros(L.shape[1])
                row[s1:e1] = v4
                row[s2:e2] = -v4

                # x component
                L[i * M + 9] = row
                # y component
                L[i * M + 10] = np.roll(row, nHomoCoo)
                # z component
                L[i * M + 11] = np.roll(row, 2 * nHomoCoo)

    else:
        raise ValueError(dim_range)

    return L
示例#11
0
    def create_verts_and_H_type_II(self,
#                                   nC, cells_multiidx, cells_verts,dim_domain,
                                   dim_range):  
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """    
        if self.type != 'II':
            raise ValueError(self.type)
        dim_domain=self.dim_domain
        nC = self.nC
        cells_multiidx=self.cells_multiidx
        cells_verts=self.cells_verts_homo_coo
#        nCx=self.nCx
#        nCy=self.nCy
        
        if dim_domain !=2:
            raise ValueError(dim_domain)
        if dim_range not in (1,dim_domain):
            raise NotImplementedError(dim_range)  
               
        nbrs = np.zeros((nC,nC))
        for i in range(nC):
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]            
                
                if mi == mj:
                    continue
                else:
                   pair = (np.abs(mi[0]-mj[0]),
                           np.abs(mi[1]-mj[1]))
                           
                   if set(pair) == set([0,1]):
                       nbrs[i,j]=1
                       
                               
        
        nEdges=nbrs.sum().astype(np.int)/2
    
        H = np.zeros((nC**2,nC))
    #    H = sparse.lil_matrix((nC**2,nC))
        
        for i in range(nC):
            for j in range(nC):        
                k = i*nC + j
                if i < j:
                    continue
                nbr = nbrs[i,j]
                if nbr:
                    H[k,i]=-1
                    H[k,j]=+1
    
    #    ipshell('hi')
    #    1/0    
        
        verts1 = []
        verts2 = []        
        k = 0
        for h in H:
    #        ipshell('..')        
            if h.any():  
    #        if h.nnz:
            
                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.            
    #            h = np.asarray(h.todense().tolist()[0])  # Workaround.
                
                 
                k+=2
                i = (h==1).nonzero()[0][0]     
                j = (h==-1).nonzero()[0][0]
                
    #            if set([i,j])==set([6,9]):
    #                ipshell('debug')
    #                1/0
    #            a = mi
    #            b = mj
                
                vi = cells_verts[i]
                vj = cells_verts[j]
                
                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)
               
                edge = set(vi).intersection(vj)
                if len(edge) != 2:
                    ipshell('oops')
                    raise ValueError(len(edge),edge)
                try:
                    v1,v2 = np.asarray(list(edge))
                except:
                    ipshell('oops2')
                    raise                
        
                verts1.append(v1)
                verts2.append(v2)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b
        
        if k != nEdges*2:
            raise ValueError(k,nEdges)      
            
        # Every edge connects 2 vertices. 
        # At every vertex, all components of the velocity must agree.
        #nConstraints = nEdges*2*dim_domain
        nConstraints = nEdges*2*dim_range
        
     
    
    
    
     
        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)    
    
        H = np.asarray([h for h in H if h.any()])    
    #    H = np.asarray([h for h in H if h.nnz])                                   
      
     #    ipshell('hi')
    #    1/0 
        
        
        return verts1,verts2,H,nEdges,nConstraints    
示例#12
0
    def create_verts_and_H_type_I(self,dim_range,valid_outside):  
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """    
        if self.type != 'I':
            raise ValueError(self.type)
        dim_domain=self.dim_domain
        nC = self.nC
        cells_multiidx=self.cells_multiidx
        cells_verts=self.cells_verts_homo_coo
        nCx=self.nCx
        nCy=self.nCy
        
        if dim_domain !=2:
            raise ValueError(dim_domain)
        if dim_range not in (1,2):
            raise NotImplementedError(dim_range) 
            
        nbrs = np.zeros((nC,nC),dtype=np.bool)
        
        if valid_outside:
            left=np.zeros((nC,nC),np.bool)    
            right=np.zeros((nC,nC),np.bool) 
            top=np.zeros((nC,nC),np.bool) 
            bottom=np.zeros((nC,nC),np.bool) 

 
        print 'Encoding continuity constraints.'
        print 'If nC is large, this may take some time.'
        print 'For a given configuration, however, this is done only once;'
        print 'the results computed here will be saved and reused the next time'
        print 'you use the same configuration.'
    
        # TODO: Cython
#        
        
        for i in range(nC):
            if nC > 200 and i % 200==0:
                print i,'/',nC
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]
                
                vi = cells_verts[i]
                vj = cells_verts[j]
                
                vi=self.make_it_hashable(vi)
                vj=self.make_it_hashable(vj)
                
                shared_verts = set(vi).intersection(vj)            
                
                if len(mi)!=3:
                    raise ValueError
                if len(mj)!=3:
                    raise ValueError
                if mi == mj:  
                    # same cell, nothing to do here
                    continue
                elif mi[:-1]==mj[:-1]:
                    # Same rect boxs, different triangles
                    s = set([mi[-1],mj[-1]])
                    if s in [set([0,1]),set([1,2]),set([2,3]),set([3,0])]:
                        nbrs[i,j]=1
                else:
                    # different rect boxes
                
    
                    if valid_outside:
        #                 try to deal with the extension
                        if mi[0]==mj[0]==0: # leftmost col
                            if mi[2]==mj[2]==3: # left triangle                     
                                if np.abs(mi[1]-mj[1])==1: # adjacent rows
                                    nbrs[i,j]=1
                                    left[i,j]=True
                                    continue
        
                        if mi[0]==mj[0]==nCx-1: # rightmost col
                            if mi[2]==mj[2]==1: # right triangle                     
                                if np.abs(mi[1]-mj[1])==1: # adjacent rows
                                    nbrs[i,j]=1
                                    right[i,j]=True
                                    continue
        
                        if mi[1]==mj[1]==0: # uppermost row
                            if mi[2]==mj[2]==0: # upper triangle                     
                                if np.abs(mi[0]-mj[0])==1: # adjacent cols
                                    nbrs[i,j]=1
                                    top[i,j]=True
                                    continue
        
                        if mi[1]==mj[1]==nCy-1: # lowermost row
                            if mi[2]==mj[2]==2: # lower triangle                     
                                if np.abs(mi[0]-mj[0])==1: # adjacent cols
                                    nbrs[i,j]=1
                                    bottom[i,j]=True
                                    continue                    
                        
                    if set([mi[2],mj[2]]) not in [set([0,2]),set([1,3])]:
                        continue
                        
                    pair = (mi[0]-mj[0]),(mi[1]-mj[1])
                    
                    
                    # Recall the order of triangles is 
                    #         0
                    #       3   1
                    #         2
                    
                    # vertical nbr's     
                    if pair == (0,1) and (mi[2],mj[2])==(0,2):
                       
                        nbrs[i,j]=1
                    elif pair == (0,-1) and (mi[2],mj[2])==(2,0):  
                        
                        nbrs[i,j]=1
                    # horizontal nbr's    
                    elif pair == (1,0) and  (mi[2],mj[2])==(3,1):    
                         
                        nbrs[i,j]=1 
                    elif pair == (-1,0) and  (mi[2],mj[2])==(1,3):    
                         
                        nbrs[i,j]=1      
                  
       
    
        print 'Creating H of size (nC**2,nC)=({},{})'.format(nC**2,nC) 
        try:  
            H = np.zeros((nC**2,nC))
        except MemoryError:
            msg='Got MemoryError when trying to call np.zeros((nC**2,nC))'
            ipshell(msg)
            raise MemoryError('np.zeros((nC**2,nC))','nC={}'.format(nC))
             
        
#        H = sparse.lil_matrix((nC**2,nC))
        
        for i in range(nC):
            for j in range(nC):        
                k = i*nC + j
                if i < j:
                    continue
                nbr = nbrs[i,j]
                if nbr:
                    H[k,i]=-1
                    H[k,j]=+1
        
    #    ipshell('save H')
    #    1/0
        verts1 = []
        verts2 = []        
        k = 0
        print 'Extracting the vertices'
        for count,h in enumerate(H):
            if H.shape[0]>1000:
                if count % 100000 == 0:
                    print count,'/',H.shape[0] 
    #        ipshell('..')     
        
            if h.any():  
#            if h.nnz:
#                ipshell('STOP')
#                # Make h dense and flat
#                h=np.asarray(h.todense()).ravel()
                                                   
                                    
                i = (h==1).nonzero()[0][0]     
                j = (h==-1).nonzero()[0][0]
    
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]
                
                vi = cells_verts[i]
                vj = cells_verts[j]
               
                vi=self.make_it_hashable(vi)
                vj=self.make_it_hashable(vj)
                
                shared_verts = set(vi).intersection(vj)
                
                if len(shared_verts) ==0:
                    continue
                if len(shared_verts) ==1:                
                    # single vertex
                    if any([left[i,j],right[i,j],top[i,j],bottom[i,j]]):
                        # shared_vert is a set that contains a single tuple.                    
                        v_aux = list(shared_verts)[0] # v_aux is a tuple
                        v_aux = list(v_aux) # Now v_aux is a list (i.e. mutable)
                        if left[i,j] or right[i,j]:
                            v_aux[0]-=10 # Create a new vertex  with the same y
                        elif top[i,j] or bottom[i,j]:
                            v_aux[1]-=10 # Create a new vertex  with the same x
                        else:
                            raise ValueError("WTF?")                        
                        v_aux = tuple(v_aux)
                        shared_verts.add(v_aux) # add it to the set  
    #                    ipshell('hello')
    #                    print shared_verts
                    else:
                        # We can skip it since the continuity at this vertex 
                        # will be imposed via the edges.
                        continue 
                
                if len(shared_verts) != 2:
                    ipshell('oops')
                    raise ValueError(len(shared_verts),shared_verts)
                try:
                    v1,v2 = np.asarray(list(shared_verts))
                except:
                    ipshell('oops2')
                    raise                
                k+=2    
                verts1.append(v1)
                verts2.append(v2)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b
        
    #    nEdges=nbrs.sum().astype(np.int)/2    
    #    if k != nEdges*2:
    #        raise ValueError(k,nEdges)      
    
        nEdges = k/2   
            
        # Every edge connects 2 vertices. 
        # At every vertex, all components of the velocity must agree.
        nConstraints = nEdges*2*dim_range
        
            
     
        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)    
        
        
        H = np.asarray([h for h in H if h.any()])    
#        H = np.asarray([h for h in H if h.nnz])                                   
        print 'H is ready'   
         
        return verts1,verts2,H,nEdges,nConstraints    
示例#13
0
    def create_verts_and_H_type_II(self,dim_range):
        """
    
        """
        dim_domain = self.dim_domain
        nCs = self.nCs
        nC = self.nC
        cells_multiidx=self.cells_multiidx
        cells_verts=self.cells_verts_homo_coo
        N = len(nCs)

        if dim_domain !=N:
            raise ValueError(dim_domain)
        
        nbrs = np.zeros((nC,nC))
        
        
        mi=cells_multiidx # shorter name
        for i in range(nC):
            for j in range(nC):
                if mi[i] == mi[j]:
                    continue
                else:
                     
                    
                    t = np.abs(np.asarray(mi[i])-np.asarray(mi[j]))
                   
                    
                    if (t==0).sum()==N-1 and (t==1).sum()==1:
                       nbrs[i,j]=1            
    
        
        nSides=nbrs.sum().astype(np.int)/2   
        
        
    
        
        # H is larger than we need
        # but it was easier to code this way.
        # Later we eliminate the unused rows.
        H = np.zeros((nC**2,nC))
    #    H = sparse.lil_matrix((nC**2,nC))
        
        for i in range(nC):
            for j in range(nC):   
                # k is the index of the row in H.
                # Most rows won't be used.
                k = i*nC + j
                if i < j:
                    continue
                nbr = nbrs[i,j]
                if nbr:
                    H[k,i]=-1
                    H[k,j]=+1
    
         
        
    #    verts1 = []
    #    verts2 = []    
    #    verts3 = []   
    #    verts4 = []
        
        verts = [[] for i in range(2**(N-1))]
        counter = 0  
        for h in H:
            if h.any():  
    #        if h.nnz:
            
                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.            
    #            h = np.asarray(h.todense().tolist()[0])  # Workaround.
            
                # update: the sparsity issue was because I used arrays
                # while the sparse functions want matrices.
                
                 
                counter+=2**(N-1)
                # Find the vertex pair
                i = (h==1).nonzero()[0][0]     
                j = (h==-1).nonzero()[0][0]
    
                
                vi = cells_verts[i]
                vj = cells_verts[j]
                
                vi=self.make_it_hashable(vi)
                vj=self.make_it_hashable(vj)
                           
                side = set(vi).intersection(vj)
                if len(side) != 2**(N-1): # adjcant boxes share 2**(N-1) verts
                    ipshell('oops')
                    raise ValueError(len(side),side)
                
                _verts = np.asarray(list(side))
                
    #            try:
    #                
    #                v1,v2,v3,v4 = np.asarray(list(side))
    #            except:
    #                ipshell('hi')
    #                raise                
        
    #            verts1.append(v1)
    #            verts2.append(v2)
    #            verts3.append(v3)
    #            verts4.append(v4)
                for i in range(2**(N-1)):
                    verts[i].append(_verts[i])
                
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b
        
        if counter != nSides*2**(N-1):
            raise ValueError(counter,nSides)      
         
        # Every side conntect 2**(N-1) vertices. 
        # At every vertex, all components of the velocity must agree.
    ##############    nConstraints = nSides*2**(N-1)*dim_domain
        nConstraints = nSides*2**(N-1)*dim_range 
    # 
    #    verts1 = np.asarray(verts1)
    #    verts2 = np.asarray(verts2)   
    #    verts3 = np.asarray(verts3) 
    #    verts4 = np.asarray(verts4) 
    
        H = np.asarray([h for h in H if h.any()])    
    #    H = np.asarray([h for h in H if h.nnz])                                   
     
    
    
    #  
        
        
        return verts,H,nSides,nConstraints    
示例#14
0
    def create_verts_and_H_type_I(self, dim_range, valid_outside):
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """
        if self.type != 'I':
            raise ValueError(self.type)
        dim_domain = self.dim_domain
        nC = self.nC
        cells_multiidx = self.cells_multiidx
        cells_verts = self.cells_verts_homo_coo
        nCx = self.nCx
        nCy = self.nCy
        nCz = self.nCz

        if valid_outside:
            raise NotImplementedError('dim_domain =', dim_domain,
                                      'valid_outside =', valid_outside)
        if dim_domain != 3:
            raise ValueError(dim_domain)

        nbrs = np.zeros((nC, nC))

        mi = cells_multiidx  # shorter name
        for i in range(nC):
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]

                # tetrahedron index within the box
                ti = mi[-1]
                tj = mj[-1]
                if len(mi) != 4:
                    raise ValueError(len(mi))
                if len(mj) != 4:
                    raise ValueError(len(mj))

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                if mi == mj:
                    continue
                elif mi[:-1] == mj[:-1]:
                    # Same rect boxs, different tetrahedra
                    if ti == 0 or tj == 0:
                        if tj == ti:
                            raise ValueError
                        else:
                            nbrs[i, j] = 1

                else:
                    # Different boxes
                    if len(set(vi).intersection(vj)) == 3:
                        nbrs[i, j] = 1

        nSides = nbrs.sum().astype(np.int) / 2

        # H is larger than we need
        # but it was easier to code this way.
        # Later we eliminate the unused rows.
        H = np.zeros((nC**2, nC))
        #    H = sparse.lil_matrix((nC**2,nC))

        for i in range(nC):
            for j in range(nC):
                # k is the index of the row in H.
                # Most rows won't be used.
                k = i * nC + j
                if i < j:
                    continue
                nbr = nbrs[i, j]
                if nbr:
                    H[k, i] = -1
                    H[k, j] = +1

        verts1 = []
        verts2 = []
        verts3 = []
        verts4 = []
        counter = 0
        for h in H:
            if h.any():
                #        if h.nnz:

                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.
                #            h = np.asarray(h.todense().tolist()[0])  # Workaround.

                # Find the vertex pair
                i = (h == 1).nonzero()[0][0]
                j = (h == -1).nonzero()[0][0]

                mi = cells_multiidx[i]  # for debugging
                mj = cells_multiidx[j]  # for debugging
                ti = mi[-1]
                tj = mj[-1]

                #            a = mi
                #            b = mj

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                side = set(vi).intersection(vj)
                len_side = len(side)
                if len_side == 3:
                    v1, v2, v3 = np.asarray(list(side))
                    v4 = None

                    verts1.append(v1)
                    verts2.append(v2)
                    verts3.append(v3)
                    verts4.append(v4)
                elif len_side == 2:
                    if ti == 0 and tj == 0:
                        # That's ok. Can ignore it:
                        # these should be the two "Central" tetrahedra
                        # of two adjacent cell.
                        continue
                    else:
                        raise ValueError
                elif len_side == 1:
                    continue
                    # I thinkg this should be ok.
                    # I don't have time now to check this happens only when
                    # it should... TODO
                else:
                    print('len(side) = ', len(side))
                    ipshell('wtf')
                    raise ValueError(len(side), side)

                counter += len_side
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b

        # Every side connects 3 vertices.
        nPtsInSide = 3

        if counter != nSides * nPtsInSide:
            ipshell('WTF')
            raise ValueError(counter, nSides)

        # At every vertex, all components of the velocity must agree.

        nConstraints = nSides * nPtsInSide * dim_range

        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)
        verts3 = np.asarray(verts3)
        verts4 = np.asarray(verts4)

        H = np.asarray([h for h in H if h.any()])
        #    H = np.asarray([h for h in H if h.nnz])

        #
        #    ipshell('hi')
        #    1/0

        return verts1, verts2, verts3, verts4, H, nSides, nConstraints
示例#15
0
    def create_verts_and_H_type_II(
        self,
        #                                   nC, cells_multiidx, cells_verts,dim_domain,
        dim_range):
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """
        if self.type != 'II':
            raise ValueError(self.type)
        dim_domain = self.dim_domain
        nC = self.nC
        cells_multiidx = self.cells_multiidx
        cells_verts = self.cells_verts_homo_coo
        #        nCx=self.nCx
        #        nCy=self.nCy

        if dim_domain != 2:
            raise ValueError(dim_domain)
        if dim_range not in (1, dim_domain):
            raise NotImplementedError(dim_range)

        nbrs = np.zeros((nC, nC))
        for i in range(nC):
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]

                if mi == mj:
                    continue
                else:
                    pair = (np.abs(mi[0] - mj[0]), np.abs(mi[1] - mj[1]))

                    if set(pair) == set([0, 1]):
                        nbrs[i, j] = 1

        nEdges = nbrs.sum().astype(np.int) / 2

        H = np.zeros((nC**2, nC))
        #    H = sparse.lil_matrix((nC**2,nC))

        for i in range(nC):
            for j in range(nC):
                k = i * nC + j
                if i < j:
                    continue
                nbr = nbrs[i, j]
                if nbr:
                    H[k, i] = -1
                    H[k, j] = +1

    #    ipshell('hi')
    #    1/0

        verts1 = []
        verts2 = []
        k = 0
        for h in H:
            #        ipshell('..')
            if h.any():
                #        if h.nnz:

                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.
                #            h = np.asarray(h.todense().tolist()[0])  # Workaround.

                k += 2
                i = (h == 1).nonzero()[0][0]
                j = (h == -1).nonzero()[0][0]

                #            if set([i,j])==set([6,9]):
                #                ipshell('debug')
                #                1/0
                #            a = mi
                #            b = mj

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                edge = set(vi).intersection(vj)
                if len(edge) != 2:
                    ipshell('oops')
                    raise ValueError(len(edge), edge)
                try:
                    v1, v2 = np.asarray(list(edge))
                except:
                    ipshell('oops2')
                    raise

                verts1.append(v1)
                verts2.append(v2)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b

        if k != nEdges * 2:
            raise ValueError(k, nEdges)

        # Every edge connects 2 vertices.
        # At every vertex, all components of the velocity must agree.
        #nConstraints = nEdges*2*dim_domain
        nConstraints = nEdges * 2 * dim_range

        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)

        H = np.asarray([h for h in H if h.any()])
        #    H = np.asarray([h for h in H if h.nnz])

        #    ipshell('hi')
        #    1/0

        return verts1, verts2, H, nEdges, nConstraints
示例#16
0
    def create_verts_and_H_type_II(self, dim_range):
        """
        This assummes 3D 
        
        H encodes the n'bors info.
        """
        if self.type != 'II':
            raise ValueError(self.type)
        dim_domain = self.dim_domain
        nC = self.nC
        cells_multiidx = self.cells_multiidx
        cells_verts = self.cells_verts_homo_coo
        #        nCx=self.nCx
        #        nCy=self.nCy
        #        nCz=self.nCz

        if dim_domain != 3:
            raise ValueError(dim_domain)
        if dim_range != dim_domain:
            raise NotImplementedError(dim_range)
#        if dim_range not in (1,dim_domain):
#            raise NotImplementedError(dim_range)

        nbrs = np.zeros((nC, nC))

        mi = cells_multiidx  # shorter name
        for i in range(nC):
            for j in range(nC):
                if mi[i] == mi[j]:
                    continue
                else:
                    #               pair = (np.abs(mi[i][0]-mi[j][0]),
                    #                       np.abs(mi[i][1]-mi[j][1]))
                    #               if set(pair) == set([0,1]):
                    #                   nbrs[i,j]=1
                    triplet = (np.abs(mi[i][0] - mi[j][0]),
                               np.abs(mi[i][1] - mi[j][1]),
                               np.abs(mi[i][2] - mi[j][2]))
                    triplet = np.asarray(triplet)
                    if (triplet == 0).sum() == 2 and (triplet == 1).sum() == 1:
                        nbrs[i, j] = 1

        nSides = nbrs.sum().astype(np.int) / 2

        # H is larger than we need
        # but it was easier to code this way.
        # Later we eliminate the unused rows.
        H = np.zeros((nC**2, nC))
        #    H = sparse.lil_matrix((nC**2,nC))

        for i in range(nC):
            for j in range(nC):
                # k is the index of the row in H.
                # Most rows won't be used.
                k = i * nC + j
                if i < j:
                    continue
                nbr = nbrs[i, j]
                if nbr:
                    H[k, i] = -1
                    H[k, j] = +1

        verts1 = []
        verts2 = []
        verts3 = []
        verts4 = []
        counter = 0
        for h in H:
            if h.any():
                #        if h.nnz:

                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.
                #            h = np.asarray(h.todense().tolist()[0])  # Workaround.

                counter += 4
                # Find the vertex pair
                i = (h == 1).nonzero()[0][0]
                j = (h == -1).nonzero()[0][0]
                #            a = mi[i]
                #            b = mi[j]

                vi = cells_verts[i]
                vj = cells_verts[j]

                vi = self.make_it_hashable(vi)
                vj = self.make_it_hashable(vj)

                side = set(vi).intersection(vj)
                if len(side) != 4:  # adjcant boxes share 4 verts
                    ipshell('oops')
                    raise ValueError(len(side), side)
                try:
                    v1, v2, v3, v4 = np.asarray(list(side))
                except:
                    ipshell('hi')
                    raise

                verts1.append(v1)
                verts2.append(v2)
                verts3.append(v3)
                verts4.append(v4)
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b

        if counter != nSides * 4:
            raise ValueError(counter, nEdges)

        # Every side conntect 4 vertices.
        # At every vertex, all components of the velocity must agree.

    #    nConstraints = nSides*4*dim_domain
        nConstraints = nSides * 4 * dim_range

        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)
        verts3 = np.asarray(verts3)
        verts4 = np.asarray(verts4)

        H = np.asarray([h for h in H if h.any()])
        #    H = np.asarray([h for h in H if h.nnz])

        #
        #    ipshell('hi')
        #    1/0

        return verts1, verts2, verts3, verts4, H, nSides, nConstraints
def create_cont_constraint_mat(H,v1s,v2s,v3s,v4s,nSides,nConstraints,nC,
                               dim_domain,dim_range,tess):    
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != 3:
        raise ValueError
    if dim_range not in [1,3]:
        raise ValueError
    nHomoCoo=dim_domain+1        
#    length_Avee = dim_domain*nHomoCoo
    length_Avee = dim_range*nHomoCoo
    L = np.zeros((nConstraints,nC*length_Avee))    
    # 
    if tess=='II':
        nPtsInSide = 4
    elif tess=='I':
        nPtsInSide = 3    
#    if nSides != nConstraints/(nPtsInSide*dim_domain):
#        raise ValueError(nSides,nConstraints)

    
    if nSides != nConstraints/(nPtsInSide*dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print  nSides , nConstraints/(nPtsInSide*dim_range)
        ipshell('stop')
        raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range))

        
    if nSides != H.shape[0]:
        raise ValueError(nSides,H.shape)

    M = nPtsInSide*dim_range
    if dim_range == 1:
        for i in range(nSides):        
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess=='II':
                v4 = v4s[i]        
            h = H[i]
            a,b = h.nonzero()[0]  # idx for the relevant As   
            # s stands for start
            # e stands for end                            
            s1 = a*length_Avee 
            e1 = s1+nHomoCoo  
            s2 = b*length_Avee
            e2 = s2+nHomoCoo  
            
            # Constraint 1:              
            L[i*M,s1:e1]= v1                         
            L[i*M,s2:e2]= -v1                                  
            # Constraint 2:      
            # x component  
            L[i*M+1,s1:e1]= v2                         
            L[i*M+1,s2:e2]= -v2               
            # Constraint 3:                 
            L[i*M+2,s1:e1]= v3                         
            L[i*M+2,s2:e2]= -v3
            if tess=='II':
                # Constraint 4:                 
                L[i*M+3,s1:e1]= v4                         
                L[i*M+3,s2:e2]= -v4    
               
    elif dim_range==3:
        for i in range(nSides):        
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess=='II':
                v4 = v4s[i]   
            if np.allclose(v1,v2):
                raise ValueError(v1,v2)
            if np.allclose(v1,v3):
                raise ValueError(v1,v3)
            if np.allclose(v2,v3):
                raise ValueError(v2,v3)
            if tess=='II':
                if np.allclose(v1,v4):
                    raise ValueError(v1,v4)               
                if np.allclose(v2,v4):
                    raise ValueError(v2,v4)            
                if np.allclose(v3,v4):
                    raise ValueError(v3,v4)                
            
            
            h = H[i]
            a,b = h.nonzero()[0]  # idx for the relevant As   
            # s stands for start
            # e stands for end                            
            s1 = a*length_Avee 
            e1 = s1+nHomoCoo  
            s2 = b*length_Avee
            e2 = s2+nHomoCoo  
            
                                                           
            # Constraint 1: 
            row = np.zeros(L.shape[1])
            row[s1:e1]=v1
            row[s2:e2]=-v1            
            # x component  
            L[i*M]=row
            # y component       
            L[i*M+1]=np.roll(row,nHomoCoo)
            # z component       
            L[i*M+2]=np.roll(row,2*nHomoCoo)                        
            
            # Constraint 2: 
            row = np.zeros(L.shape[1])
            row[s1:e1]=v2
            row[s2:e2]=-v2   
            # x component  
            L[i*M+3]=row
            # y component       
            L[i*M+4]=np.roll(row,nHomoCoo)
            # z component       
            L[i*M+5]=np.roll(row,nHomoCoo*2)     
            
            # Constraint 3: 
            row = np.zeros(L.shape[1])
            row[s1:e1]=v3
            row[s2:e2]=-v3             
            # x component  
            L[i*M+6]=row
            # y component       
            L[i*M+7]=np.roll(row,nHomoCoo)
            # z component       
            L[i*M+8]=np.roll(row,2*nHomoCoo)           
#            ipshell('qqq')
#            1/0
            
            if tess=='II':
                # Constraint 4:      
                row = np.zeros(L.shape[1])
                row[s1:e1]=v4
                row[s2:e2]=-v4              
                
                # x component  
                L[i*M+9]=row
                # y component       
                L[i*M+10]=np.roll(row,nHomoCoo)
                # z component       
                L[i*M+11]=np.roll(row,2*nHomoCoo)         
            
            
    else:
        raise ValueError(dim_range)

    
    return L
示例#18
0
    def create_verts_and_H_type_I(self,dim_range,valid_outside):
        """
        This assummes 2D 
        
        H encodes the n'bors info.
        """    
        if self.type != 'I':
            raise ValueError(self.type)
        dim_domain=self.dim_domain
        nC = self.nC
        cells_multiidx=self.cells_multiidx
        cells_verts=self.cells_verts_homo_coo
        nCx=self.nCx
        nCy=self.nCy
        nCz=self.nCz
        
        if valid_outside:
            raise NotImplementedError('dim_domain =',dim_domain,
                                      'valid_outside =',valid_outside)
        if dim_domain !=3:
            raise ValueError(dim_domain)
        
        nbrs = np.zeros((nC,nC))
        
        mi=cells_multiidx # shorter name
        for i in range(nC):
            for j in range(nC):
                # shorter names
                mi = cells_multiidx[i]
                mj = cells_multiidx[j]
                
                # tetrahedron index within the box
                ti = mi[-1]
                tj = mj[-1]
                if len(mi)!=4:
                    raise ValueError(len(mi))
                if len(mj)!=4:
                    raise ValueError(len(mj))
                  
                vi = cells_verts[i]
                vj = cells_verts[j]

                vi=self.make_it_hashable(vi)
                vj=self.make_it_hashable(vj)      
     
                if mi == mj:
                    continue
                elif mi[:-1]==mj[:-1]:
                    # Same rect boxs, different tetrahedra
                    if ti==0 or tj==0: 
                        if tj==ti:
                            raise ValueError
                        else:                                        
                            nbrs[i,j]=1
                            
                else:
                   # Different boxes            
                    if len(set(vi).intersection(vj))==3:                                
                        nbrs[i,j]=1 
                
    
        nSides=nbrs.sum().astype(np.int)/2   
        
        
    
        
        # H is larger than we need
        # but it was easier to code this way.
        # Later we eliminate the unused rows.
        H = np.zeros((nC**2,nC))
    #    H = sparse.lil_matrix((nC**2,nC))
        
        for i in range(nC):
            for j in range(nC):   
                # k is the index of the row in H.
                # Most rows won't be used.
                k = i*nC + j
                if i < j:
                    continue
                nbr = nbrs[i,j]
                if nbr:
                    H[k,i]=-1
                    H[k,j]=+1
    
         
        
        verts1 = []
        verts2 = []    
        verts3 = []   
        verts4 = []
        counter = 0  
        for h in H:
            if h.any():  
    #        if h.nnz:
            
                # Very annoying: I think there is a bug in the sparse matrix object.
                # Even after 'todense' it is impossible to flatten it properly.            
    #            h = np.asarray(h.todense().tolist()[0])  # Workaround.
                
                 
                
                # Find the vertex pair
                i = (h==1).nonzero()[0][0]     
                j = (h==-1).nonzero()[0][0]
                
                mi = cells_multiidx[i] # for debugging
                mj = cells_multiidx[j] # for debugging
                ti = mi[-1]
                tj = mj[-1]                
                
    #            a = mi
    #            b = mj
                
                vi = cells_verts[i]
                vj = cells_verts[j]
                           
                vi=self.make_it_hashable(vi)
                vj=self.make_it_hashable(vj)

                side = set(vi).intersection(vj)
                len_side = len(side)
                if len_side == 3:                 
                    v1,v2,v3 = np.asarray(list(side))
                    v4=None
                                    
            
                    verts1.append(v1)
                    verts2.append(v2)
                    verts3.append(v3)
                    verts4.append(v4)
                elif len_side==2:
                    if ti == 0 and tj == 0:
                        # That's ok. Can ignore it:
                        # these should be the two "Central" tetrahedra 
                        # of two adjacent cell. 
                        continue
                    else:
                        raise ValueError
                elif len_side == 1:
                    continue
                    # I thinkg this should be ok.
                    # I don't have time now to check this happens only when 
                    # it should... TODO
                else:
                    print ('len(side) = ',len(side))
                    ipshell('wtf')
                    raise ValueError(len(side),side)                
                
                counter+=len_side
        #        if a != (1,1):
        #            continue
        #        print a, ' is a nbr of ',b
    
        # Every side connects 3 vertices. 
        nPtsInSide = 3  
    
        
        if counter != nSides*nPtsInSide:
            ipshell('WTF')
            raise ValueError(counter,nSides)      
        
       
        # At every vertex, all components of the velocity must agree.
     
        nConstraints = nSides*nPtsInSide*dim_range 
     
        verts1 = np.asarray(verts1)
        verts2 = np.asarray(verts2)   
        verts3 = np.asarray(verts3) 
        verts4 = np.asarray(verts4) 
    
        H = np.asarray([h for h in H if h.any()])    
    #    H = np.asarray([h for h in H if h.nnz])                                   
     
    
    
    #    
     #    ipshell('hi')
    #    1/0 
        
        
        return verts1,verts2,verts3,verts4,H,nSides,nConstraints    
示例#19
0
    def calc_grad_theta(self, xmins, xmaxs, 
                            As_vectorized, 
                            BasMats,
                            pts0,dt,nTimeSteps,
                      nStepsOdeSolver,pts_at_T,
                      grad_per_point,
                      dim_domain,dim_range,
                      nCs,
                      incs):
         
        if dim_domain != dim_range:
            raise ValueError
        if pts_at_T is None:
            raise ValueError                        
        if len(incs)!=dim_domain:
            raise ValueError(len(incs),dim_domain)
 
         
        if As_vectorized.ndim != 2:
            raise ValueError(As_vectorized.shape)         
        if As_vectorized.shape[1]!= (dim_domain+1)*dim_domain:
            raise ValueError(As_vectorized.shape,(dim_domain+1)*dim_domain)            
           
        nPts = pts0.shape[0] 
         
        if not isinstance(pts0,CpuGpuArray):
            raise TypeError
        if not isinstance(pts_at_T,CpuGpuArray):
            raise TypeError 
        
         
        
         
        # number of threads per block has to be >= than number of cells 
    #    if self.nCells <= 128:           
    #      threadsPerBlock = 128
        if self.nCells <= 256:      
          threadsPerBlock = 256
#          threadsPerBlock = 256/4
        elif 256<self.nCells<=512:
          threadsPerBlock = 512
        elif 512<self.nCells<=625:
            threadsPerBlock=625
        elif 512<self.nCells<=1024:
          threadsPerBlock = 1024
        else:
          raise NotImplementedError

                
         
        nBlocks = int(np.ceil(float(nPts) / float(threadsPerBlock))) 
        
        if 0:
            print '(nPts',nPts
            print 'nBlocks',nBlocks
            print 'threadsPerBlock = ',threadsPerBlock
            print            
             
        d = len(BasMats)
        
        if not isinstance(grad_per_point,CpuGpuArray):
            raise TypeError
        if grad_per_point.shape != (nPts,dim_range,d):
            raise ValueError(grad_per_point.shape)
            
        if 1:            
 
            nC0,nC1,nC2,inc_x,inc_y,inc_z = self.parse_nCs_and_incs(dim_domain,incs,nCs)   
            
 
            if dim_domain == dim_range:               
                calc_gpu=self.calc_grad_theta_gpu
            else:
                raise NotImplementedError
            if 0:
                ipshell('hi')
                1/0
            calc_gpu(
              pts0.gpu,
              pts_at_T.gpu,            
              drv.In(As_vectorized), 
              BasMats.gpu,
              grad_per_point.gpu,
              np.int32(d),
              self.my_dtype(dt),
              np.int32(nTimeSteps),
              np.int32(nStepsOdeSolver),
              np.int32(nPts),
              np.int32(nC0),
              np.int32(nC1),
              np.int32(nC2),
              np.float64(inc_x),
              np.float64(inc_y),
              np.float64(inc_z),
              grid=(nBlocks,1,1), 
              block=(threadsPerBlock,1,1)
              ) 
 
        return grad_per_point
def create_cont_constraint_mat_separable(H,v1s,v2s,v3s,v4s,nSides,nConstraints,nC,
                               dim_domain,dim_range,tess):    
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != 3:
        raise ValueError
    if dim_range not in [1,3]:
        raise ValueError
    nHomoCoo=dim_domain+1        
    length_Avee = dim_range*nHomoCoo
    L1 = np.zeros((nConstraints/3,nC*nHomoCoo))

    
    # 
    if tess=='II':
        nPtsInSide = 4
    elif tess=='I':
        nPtsInSide = 3    
#    if nSides != nConstraints/(nPtsInSide*dim_domain):
#        raise ValueError(nSides,nConstraints)

    
    if nSides != nConstraints/(nPtsInSide*dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print  nSides , nConstraints/(nPtsInSide*dim_range)
        ipshell('stop')
        raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range))

        
    if nSides != H.shape[0]:
        raise ValueError(nSides,H.shape)

#    M = nPtsInSide*dim_range
    M = nPtsInSide
    if dim_range == 1:
        raise NotImplementedError
        for i in range(nSides):        
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess=='II':
                v4 = v4s[i]        
            h = H[i]
            a,b = h.nonzero()[0]  # idx for the relevant As   
            # s stands for start
            # e stands for end                            
            s1 = a*length_Avee 
            e1 = s1+nHomoCoo  
            s2 = b*length_Avee
            e2 = s2+nHomoCoo  
            
            # Constraint 1:              
            L[i*M,s1:e1]= v1                         
            L[i*M,s2:e2]= -v1                                  
            # Constraint 2:  
            L[i*M+1,s1:e1]= v2                         
            L[i*M+1,s2:e2]= -v2               
            # Constraint 3:                 
            L[i*M+2,s1:e1]= v3                         
            L[i*M+2,s2:e2]= -v3
            if tess=='II':
                # Constraint 4:                 
                L[i*M+3,s1:e1]= v4                         
                L[i*M+3,s2:e2]= -v4    
               
    elif dim_range==3:
        for i in range(nSides):        
            v1 = v1s[i]
            v2 = v2s[i]
            v3 = v3s[i]
            if tess=='II':
                v4 = v4s[i]   
            if np.allclose(v1,v2):
                raise ValueError(v1,v2)
            if np.allclose(v1,v3):
                raise ValueError(v1,v3)
            if np.allclose(v2,v3):
                raise ValueError(v2,v3)
            if tess=='II':
                if np.allclose(v1,v4):
                    raise ValueError(v1,v4)               
                if np.allclose(v2,v4):
                    raise ValueError(v2,v4)            
                if np.allclose(v3,v4):
                    raise ValueError(v3,v4)                
            
            
            h = H[i]
            a,b = h.nonzero()[0]  # idx for the relevant As   
            
            
            # L1 is acting on columns of the following form:
            #   [ a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 ... a_Nc b_Nc c_Nc d_Nc] 
            # s stands for start
            # e stands for end                            
            s1 = a*nHomoCoo
            e1 = s1+nHomoCoo  
            s2 = b*nHomoCoo
            e2 = s2+nHomoCoo  
            
               
            try:                                        
                # Constraint 1: 
                row = np.zeros(L1.shape[1])
                row[s1:e1]=v1
                row[s2:e2]=-v1            
                # x component  
                L1[i*M]=row     
            except:
                ipshell('fail')
                raise                      
            
            # Constraint 2: 
            row = np.zeros(L1.shape[1])
            row[s1:e1]=v2
            row[s2:e2]=-v2   
            # x component  
            L1[i*M+1]=row
            
            
            # Constraint 3: 
            row = np.zeros(L1.shape[1])
            row[s1:e1]=v3
            row[s2:e2]=-v3             
            # x component  
            L1[i*M+2]=row
          
            
            if tess=='II':
                # Constraint 4:      
                row = np.zeros(L1.shape[1])
                row[s1:e1]=v4
                row[s2:e2]=-v4              
                
                # x component  
                L1[i*M+3]=row                   
            
            
    else:
        raise ValueError(dim_range)

    
    return L1
def create_cont_constraint_mat(N,H,verts,nSides,nConstraints,nC,
                               dim_domain,dim_range,tess):    
    """
    L is the matrix that encodes the constraints of the consistent subspace.
    Its null space space is the sought-after consistent subspace
    (unless additional constraints are added; e.g., sub-algerba or bdry 
    conditions).
    """
    if dim_domain != N:
        raise ValueError
    if dim_range != N:
        raise NotImplementedError
    nHomoCoo=dim_domain+1        
#    length_Avee = dim_domain*nHomoCoo
    length_Avee = dim_range*nHomoCoo
    L = np.zeros((nConstraints,nC*length_Avee))    
    # 
    if tess=='II':
        nPtsInSide = 2**(N-1)
    else:
        raise ValueError
#    if nSides != nConstraints/(nPtsInSide*dim_domain):
#        raise ValueError(nSides,nConstraints)

    
    if nSides != nConstraints/(nPtsInSide*dim_range):
        print " print  nSides , nConstraints/(nPtsInSide*dim_range):"
        print  nSides , nConstraints/(nPtsInSide*dim_range)
        ipshell('stop')
        raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range))

        
    if nSides != H.shape[0]:
        raise ValueError(nSides,H.shape)

    M = nPtsInSide*dim_range
    
    verts = np.asarray(map(np.asarray,verts))
    
    # verts.shape is (2**(N-1),nSides,N+1))
    if verts.shape != (2**(N-1),nSides,N+1):
        raise ValueError(verts.shape)
        
    if dim_range==N:
         
        # loop over interfaces 
        for i in range(nSides): 
            
            verts_in_this_side = verts[:,i,:]
            
            h = H[i]
            a,b = h.nonzero()[0]  # idx for the relevant As   
            # s stands for start
            # e stands for end                            
            s1 = a*length_Avee 
            e1 = s1+nHomoCoo  
            s2 = b*length_Avee
            e2 = s2+nHomoCoo  
            
            
            # loop over vertices in this inter-cell interface
            for j in range(nPtsInSide):
                row = np.zeros(L.shape[1])                
                row[s1:e1]=verts_in_this_side[j]
                row[s2:e2]=-verts_in_this_side[j]
                
                
                # loop over coordinates in this vertex
                for coo in range(N):
                    L[i*M+j*N+coo]=np.roll(row,coo*nHomoCoo)
                    
             
    else:
        raise ValueError(dim_range)

    
    return L