コード例 #1
0
ファイル: wop.py プロジェクト: pcreed/WPolyanna
    def imp_ineq(self,r,index=None):
        """ Generate the set of inequalities cost functions improved
        by this weighted operation must satisfy.         

        This method returns a matrix A representing the set 
        of cost function of arity r improved by this weighted operation.
        The method imp uses the double description 
        method to compute the set of extreme rays of the polyhedron
        Ax <= 0, which correspond to a minimal set of cost functions
        that can be used to generate the set of cost functions improved by
        this weighted operation.
        
        :param r: The arity of the cost functions to be generated
        :type r: integer
        :param index: Dictionary mapping tuples to their index, in
            lexicographic order.
        :type index: :py:class:`dict`, Optional
        :returns: The inequality matrix.
        :rtype: :py:func:`list` of :py:func:`list` of integer            
        """
        
        if index is None:
            # Compute an index for the tuples
            index = dict()
            i = 0
            for x in it.product(range(self.dom),repeat=r):
                index[x] = i
                i += 1

        # The inequalities Ax <= 0 will define the cone of cost functions
        A = []        

        # Iterate over the tableaux
        # For each such X, we compute the tableau
        # obtained by applying the operations to X
        # We then generate the constraint this imposes
        # on a cost function, and add this to our matrix,
        # as long as it is non-zero
        D = range(self.dom)
        for X in it.combinations_with_replacement(
            it.product(D,repeat=r),self.arity):
            row = [0 for _ in range(self.dom**r)]
            for f in self.get_support():
                y = f.apply_to_tableau(X)
                row[index[y]] += self.get_weight(f)
            #Y = [f.apply_to_tableau(X) for f in self.ops]
            #for i in range(len(Y)):
            #    row[index[Y[i]]] += self.weights[i]
            if max([i != 0 for i in row]):
                if len(A) == 0:
                    A = [row]
                else:
                    i = binary_search(A,row)
                    if i == len(A) or A[i] != row:
                        A.insert(i,row)
        return A
コード例 #2
0
ファイル: wop.py プロジェクト: pcreed/WPolyanna
    def translations(self,arity,clone=None):
        """ Return the set of translations by elements of a clone.

        :param clone: The clone we want to translate by.
        :type clone: :class:`Clone`, Optional
        :returns: The matrix of translations, with columns index by the
            clone. Each row corresponds to a single translation,
            storing the weight assigned to the i-th operation in the
            clone at the i-th location.
        :rtype: :class:`cdd.Matrix`

        .. note:: If no clone is passed as input, we use the smallest
            clone containing all the elements of self.ops.
        """

        if clone is None:
            clone = Clone.generate(self.ops,arity)
        N = len(clone)

        # Each tuple of terms in the clone gives rise to a generator
        A = []
        for t in it.product(range(N),repeat=self.arity):
            F = [clone[i] for i in t]
            row = [0 for _ in range(N)]
            for (f,w) in self.weight_iter():#zip(self.ops,self.weights):
                try: 
                    row[clone.get_index(f.compose(F))] += w
                except KeyError:
                    raise KeyError

            # Add non-zero rows if they are are not already in A.
            # We keep A sorted to make this check more efficient
            if min(row) != 0:
                if len(A) == 0:
                    A = [row]
                else:
                    i = binary_search(A,row)
                    if i == len(A) or A[i] != row:
                        A.insert(i,row)
        return A
コード例 #3
0
ファイル: cost_function.py プロジェクト: pcreed/WPolyanna
    def wpol_ineq(self,arity,clone=None):
        """ Return the set of inequalities the weighted polymorphisms
        must satisfy.

        This method returns a matrix A, such that the set of weighted
        operations satisfying Aw <= 0 are the weighted polymorphisms
        of this cost function. 
        :param arity: The arity of the weighted polymorphisms.
        :type arity: integer
        :param clone: The supporting clone.
        :type clone: :class:`Clone`, Optional
        :returns: A set of inequalities defining the weighted
            polymorphisms.
        :rtype: :class:`cdd.Matrix`
        
        ..note:: We implicity assume that clone is a subset of the set
            of feasibility polymorphisms. If no clone is passed as an
            argument, then we use the clone containing all operations.
        """
        if clone is None:
            clone = Clone.all_operations(arity,self.dom)
            
        # N is the number of operations in the clone. We will need a
        # variable for each of these
        N = len(clone)
        A = []

        # Divide the tuples into sets of zero and non-zero cost 
        r = self.arity
        D = range(self.dom)
        T = [[],[]]
        neg,pos = False,False
        for t in it.product(D,repeat=r):
            if self[t] == 0:
                T[0].append(t)
            else:
                T[1].append(t)
                if self[t] > 0:
                    pos = True
                elif self[t] < 0:
                    neg = True
        
        # Tableaus containing at least one non-zero tuple
        for comb in it.product([0,1],repeat=arity):
            if sum(comb) > 0:
                for X in it.product(*[T[i] for i in comb]):
                    row = [0 for _ in range(N+1)]   
                    for i in xrange(0,N):
                        row[i+1] = self[clone[i].apply_to_tableau(X)]
                    # Insert row if not already in A
                    # We keep A sorted to make this check more efficient
                    if len(A) == 0:
                        A = [row]
                    else:
                        i = binary_search(A,row)
                        if i == len(A) or A[i] != row:
                            A.insert(i,row)

        # We only need tableaus with all zero tuples if there are some
        # positive weighted tuples
        if pos:
            for X in it.product(T[0],repeat=arity):
                row = [0 for _ in range(N+1)]
                trivial = True
                for i in xrange(0,N):
                    row[i+1] = self[clone[i].apply_to_tableau(X)]
                    if row[i+1] != 0:
                        trivial = False
                if not trivial:
                    if len(A) == 0:
                        A = [row]
                    else:
                        i = binary_search(A,row)
                        if i == len(A) or A[i] != row:
                            A.insert(i,row)
        return A