矢量类问题

时间:2015-03-01 14:10:38

标签: python

我有一类名为Vector的对象。我会尽早参加课程,因为我认为有必要,如果没有,请告诉我,我可以立即将其删除(以避免DV)。

class Vec:
    """
    A vector has two fields:
    D - the domain (a set)
    f - a dictionary mapping (some) domain elements to field elements
        elements of D not appearing in f are implicitly mapped to zero
    """
    def __init__(self, labels, function):
        self.D = labels
        self.f = function

    __getitem__ = getitem
    __setitem__ = setitem
    __neg__ = neg
    __rmul__ = scalar_mul #if left arg of * is primitive, assume it's a scalar

    def __mul__(self,other):
        #If other is a vector, returns the dot product of self and other
        if isinstance(other, Vec):
            return dot(self,other)
        else:
            return NotImplemented  #  Will cause other.__rmul__(self) to be invoked

    def __truediv__(self,other):  # Scalar division
        return (1/other)*self

    __add__ = add

    def __radd__(self, other):
        "Hack to allow sum(...) to work with vectors"
        if other == 0:
            return self

    def __sub__(a,b):
        "Returns a vector which is the difference of a and b."
        return a+(-b)

    __eq__ = equal

    def is_almost_zero(self):
        s = 0
        for x in self.f.values():
            if isinstance(x, int) or isinstance(x, float):
                s += x*x
            elif isinstance(x, complex):
                s += x*x.conjugate()
            else: return False
        return s < 1e-20

    def __str__(v):
        "pretty-printing"
        D_list = sorted(v.D, key=repr)
        numdec = 3
        wd = dict([(k,(1+max(len(str(k)), len('{0:.{1}G}'.format(v[k], numdec))))) if isinstance(v[k], int) or isinstance(v[k], float) else (k,(1+max(len(str(k)), len(str(v[k]))))) for k in D_list])
        s1 = ''.join(['{0:>{1}}'.format(str(k),wd[k]) for k in D_list])
        s2 = ''.join(['{0:>{1}.{2}G}'.format(v[k],wd[k],numdec) if isinstance(v[k], int) or isinstance(v[k], float) else '{0:>{1}}'.format(v[k], wd[k]) for k in D_list])
        return "\n" + s1 + "\n" + '-'*sum(wd.values()) +"\n" + s2

    def __hash__(self):
        "Here we pretend Vecs are immutable so we can form sets of them"
        h = hash(frozenset(self.D))
        for k,v in sorted(self.f.items(), key = lambda x:repr(x[0])):
            if v != 0:
                h = hash((h, hash(v)))
        return h

    def __repr__(self):
        return "Vec(" + str(self.D) + "," + str(self.f) + ")"

    def copy(self):
        "Don't make a new copy of the domain D"
        return Vec(self.D, self.f.copy())

我现在必须编写程序,以便它可以工作吗? 我完成了这项任务,我有8/9。这很棒,但我需要9/9,因为它被用于另一个任务。 (这是为了澄清我不会盲目地在这里发布作业问题。)

def getitem(v,k):
    kthelement = 0
    try:
        kthelement = v.f[k]
    except Exception:
        kthelement = 0
    return kthelement



def setitem(v,k,val):
    v.f[k] = val


def equal(u,v):
    result = False
    unmatched_item = set(v.f.items()) ^ set(u.f.items())
    if len(unmatched_item) == 0:
        result = True
    return result

前两个很好并且有效。第三个是问题所在。 它有时会起作用,然后进行一些比较,它在True或反向时返回False。

另外,如果,

D = {'a','b','c'}
v1 = Vec(D, {'a': 1})
v2 = Vec(D, {'a':1, 'b':0}

然后v1 == v2

请有人帮我解决这个问题。

2 个答案:

答案 0 :(得分:0)

您遇到的问题是,据我所知,您从未实现过为域中的项目返回0的机制。可能有很多方法可以解决这个问题,一种方法是在构造函数中构造字典:

def __init__(self, labels, function):
    self.D = labels
    self.f = {label: function.get(label, 0) for label in D}

我还没有完全考虑过你对函数其他部分的所有影响,但是如果你打算f来存储只包含dict d function中的D部分位于f中,然后实现该部分。

也就是说,如果您希望__init__成为用户可以直接操作的东西,您可能希望将其实现为属性(请参阅this question),在这种情况下您的原始{{1}可以工作,并且您将字典理解从我的__init__版本移到f属性设置器中。

另外,我应该补充一点,我在评论中假设您要排除 function中不在D内的任何内容,所以你&# 39;请注意使用原始代码:

D = {'a','b','c'}
v1 = Vec(D, {'a': 1})
v2 = Vec(D, {'a':1, 'b':0})

print(v1 == v2)

v3 = Vec(D, {'a': 1, 'e': 4})
print(v1 == v3)

返回:

False
False

但是随着词典的理解,它会返回:

True
True

如果您希望在找不到域中的标签(或允许它们放在.f属性中)时抛出错误,那么您也必须处理这种情况。

答案 1 :(得分:0)

我已经解决了。这将返回所需的结果。

def equal(u,v):
    counter = 0
    for k in u.D:
        if v[k] == u[k]:
            counter += 1
    return counter == len(u.D)