Since there is not much out there on the interwebs as far as hints to build the procedures for this class, I will post the procedures I got to work here.
Essentially this is an exercise in learning the features of Python, since, for the less patient student, there are already libraries like numpy, scipy, and even sage, not to mention the commercial CAS like Mathematica and MATLAB.
I happened to enjoy doing a little troubleshooting and tinkering to get these to work, and I learned about iterating through the keys and values of dictionary items in the process.
I also got a feel for how arithmetic operators are overloaded using special labels such as __neg__ and __mul__
############################################################################
# Copyright 2013 Philip N. Klein
# implementation code: H
def getitem(v,k):
"""
Return the value of entry k in v.
Be sure getitem(v,k) returns 0 if k is not represented in v.f.
>>> v = Vec({'a','b','c', 'd'},{'a':2,'c':1,'d':3})
>>> v['d']
3
>>> v['b']
0
"""
assert k in v.D
return v.f[k] if k in v.f else 0
def setitem(v,k,val):
"""
Set the element of v with label d to be val.
setitem(v,d,val) should set the value for key d even if d
is not previously represented in v.f, and even if val is 0.
>>> v = Vec({'a', 'b', 'c'}, {'b':0})
>>> v['b'] = 5
>>> v['b']
5
>>> v['a'] = 1
>>> v['a']
1
>>> v['a'] = 0
>>> v['a']
0
"""
assert k in v.D
v.f[k] = val
def equal(u,v):
"""
Return true iff u is equal to v.
Because of sparse representation, it is not enough to compare dictionaries
Consider using brackets notation u[...] and v[...] in your procedure
to access entries of the input vectors. This avoids some sparsity bugs.
>>> Vec({'a', 'b', 'c'}, {'a':0}) == Vec({'a', 'b', 'c'}, {'b':0})
True
>>> Vec({'a', 'b', 'c'}, {'a': 0}) == Vec({'a', 'b', 'c'}, {})
True
>>> Vec({'a', 'b', 'c'}, {}) == Vec({'a', 'b', 'c'}, {'a': 0})
True
Be sure that equal(u, v) checks equalities for all keys from u.f and v.f even if
some keys in u.f do not exist in v.f (or vice versa)
>>> Vec({'x','y','z'},{'y':1,'x':2}) == Vec({'x','y','z'},{'y':1,'z':0})
False
>>> Vec({'a','b','c'}, {'a':0,'c':1}) == Vec({'a','b','c'}, {'a':0,'c':1,'b':4})
False
>>> Vec({'a','b','c'}, {'a':0,'c':1,'b':4}) == Vec({'a','b','c'}, {'a':0,'c':1})
False
The keys matter:
>>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'b':1})
False
The values matter:
>>> Vec({'a','b'},{'a':1}) == Vec({'a','b'},{'a':2})
False
"""
assert u.D == v.D
if ((u.f == {}) | (v.f == {})):
if (u.f == {}):
u = Vec(u.D, {d:0 for d in u.D})
if (v.f == {}):
v = Vec(v.D, {d:0 for d in v.D})
counter = 0
for k in u.D:
if v[k] == u[k]:
counter += 1
return counter == len(u.D)
def add(u,v):
"""
Returns the sum of the two vectors.
Consider using brackets notation u[...] and v[...] in your procedure
to access entries of the input vectors. This avoids some sparsity bugs.
Do not seek to create more sparsity than exists in the two input vectors.
Doing so will unnecessarily complicate your code and will hurt performance.
Make sure to add together values for all keys from u.f and v.f even if some keys in u.f do not
exist in v.f (or vice versa)
>>> a = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2})
>>> b = Vec({'a','e','i','o','u'}, {'o':4,'u':7})
>>> c = Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2,'o':4,'u':7})
>>> a + b == c
True
>>> a == Vec({'a','e','i','o','u'}, {'a':0,'e':1,'i':2})
True
>>> b == Vec({'a','e','i','o','u'}, {'o':4,'u':7})
True
>>> d = Vec({'x','y','z'}, {'x':2,'y':1})
>>> e = Vec({'x','y','z'}, {'z':4,'y':-1})
>>> f = Vec({'x','y','z'}, {'x':2,'y':0,'z':4})
>>> d + e == f
True
>>> d == Vec({'x','y','z'}, {'x':2,'y':1})
True
>>> e == Vec({'x','y','z'}, {'z':4,'y':-1})
True
>>> b + Vec({'a','e','i','o','u'}, {}) == b
True
"""
assert u.D == v.D
return Vec(u.D, {d:getitem(u,d)+getitem(v,d) for d in u.D})
def dot(u,v):
"""
Returns the dot product of the two vectors.
Consider using brackets notation u[...] and v[...] in your procedure
to access entries of the input vectors. This avoids some sparsity bugs.
>>> u1 = Vec({'a','b'}, {'a':1, 'b':2})
>>> u2 = Vec({'a','b'}, {'b':2, 'a':1})
>>> u1*u2
5
>>> u1 == Vec({'a','b'}, {'a':1, 'b':2})
True
>>> u2 == Vec({'a','b'}, {'b':2, 'a':1})
True
>>> v1 = Vec({'p','q','r','s'}, {'p':2,'s':3,'q':-1,'r':0})
>>> v2 = Vec({'p','q','r','s'}, {'p':-2,'r':5})
>>> v1*v2
-4
>>> w1 = Vec({'a','b','c'}, {'a':2,'b':3,'c':4})
>>> w2 = Vec({'a','b','c'}, {'a':12,'b':8,'c':6})
>>> w1*w2
72
The pairwise products should not be collected in a set before summing
because a set eliminates duplicates
>>> v1 = Vec({1, 2}, {1 : 3, 2 : 6})
>>> v2 = Vec({1, 2}, {1 : 2, 2 : 1})
>>> v1 * v2
12
"""
assert u.D == v.D
return sum(v.f[key]*u.f[key] for key in v.f)
#s = 0
#for key in v.f:
# s += v.f[key]*u.f[key]
#return s
def scalar_mul(v, alpha):
"""
Returns the scalar-vector product alpha times v.
Consider using brackets notation v[...] in your procedure
to access entries of the input vector. This avoids some sparsity bugs.
>>> zero = Vec({'x','y','z','w'}, {})
>>> u = Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4})
>>> 0*u == zero
True
>>> 1*u == u
True
>>> 0.5*u == Vec({'x','y','z','w'},{'x':0.5,'y':1,'z':1.5,'w':2})
True
>>> u == Vec({'x','y','z','w'},{'x':1,'y':2,'z':3,'w':4})
True
"""
return Vec(v.D, {d:alpha*value for d, value in v.f.items()})
def neg(v):
"""
Returns the negation of a vector.
Consider using brackets notation v[...] in your procedure
to access entries of the input vector. This avoids some sparsity bugs.
>>> u = Vec({1,3,5,7},{1:1,3:2,5:3,7:4})
>>> -u
Vec({1, 3, 5, 7},{1: -1, 3: -2, 5: -3, 7: -4})
>>> u == Vec({1,3,5,7},{1:1,3:2,5:3,7:4})
True
>>> -Vec({'a','b','c'}, {'a':1}) == Vec({'a','b','c'}, {'a':-1})
True
"""
return Vec(v.D, {d:-getitem(v, d) for d in v.D})
Note that in order to upload, vec.py was renamed vec.txt
Download and save as vec.py before "from vec import Vec" in Python session.