'''
>>> import sys
>>> import os
>>> sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
>>> from module.mat import Mat
>>> from module.vec import Vec

>>> # getitem
>>> M = Mat(({1,3,5}, {'a'}), {(1,'a'):4, (5,'a'): 2})
>>> M[1,'a']
4
>>> M[3,'a']
0

>>> # equal
>>> Mat(({'a','b'}, {'A','B'}), {('a','B'):0}) == Mat(({'a','b'}, {'A','B'}), {('b','B'):0})
True
>>> A = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
>>> B = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):0})
>>> C = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):5})
>>> A == B
True
>>> B == A
True
>>> A == C
False
>>> C == A
False
>>> A == Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
True

>>> # setitem
>>> M = Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):7})
>>> M['b', 5] = 9
>>> M['c', 5] = 13
>>> M == Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):9, ('c',5):13})
True
>>> N = Mat(({((),), 7}, {True, False}), {})
>>> N[(7, False)] = 1
>>> N[(((),), True)] = 2
>>> N == Mat(({((),), 7}, {True, False}), {(7,False):1, (((),), True):2})
True

>>> # add
>>> A1 = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
>>> A2 = Mat(({3, 6}, {'x','y'}), {(3,'y'):4})
>>> B = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (3,'y'):4, (6,'y'):3})
>>> A1 + A2 == B
True
>>> A2 + A1 == B
True
>>> A1 == Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
True
>>> zero = Mat(({3,6}, {'x','y'}), {})
>>> B + zero == B
True
>>> C1 = Mat(({1,3}, {2,4}), {(1,2):2, (3,4):3})
>>> C2 = Mat(({1,3}, {2,4}), {(1,4):1, (1,2):4})
>>> D = Mat(({1,3}, {2,4}), {(1,2):6, (1,4):1, (3,4):3})
>>> C1 + C2 == D
True

>>> # scalar_mul
>>> M = Mat(({1,3,5}, {2,4}), {(1,2):4, (5,4):2, (3,4):3})
>>> 0*M == Mat(({1, 3, 5}, {2, 4}), {})
True
>>> 1*M == M
True
>>> 0.25*M == Mat(({1,3,5}, {2,4}), {(1,2):1.0, (5,4):0.5, (3,4):0.75})
True
    
>>> # transpose
>>> M = Mat(({0,1}, {0,1}), {(0,1):3, (1,0):2, (1,1):4})
>>> M.transpose() == Mat(({0,1}, {0,1}), {(0,1):2, (1,0):3, (1,1):4})
True
>>> M = Mat(({'x','y','z'}, {2,4}), {('x',4):3, ('x',2):2, ('y',4):4, ('z',4):5})
>>> Mt = Mat(({2,4}, {'x','y','z'}), {(4,'x'):3, (2,'x'):2, (4,'y'):4, (4,'z'):5})
>>> M.transpose() == Mt
True

>>> # vector_matrix_mul
>>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8})
>>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
>>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0})
True
>>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8})
True
>>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
True
>>> v2 = Vec({'a','b'}, {})
>>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {})
>>> v2*M2 == Vec({0, 2, 4, 6, 7},{})
True
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3 = Mat(({'a', 'b'}, {0, 1}), {('a', 1): 1, ('b', 1): 1, ('a', 0): 1, ('b', 0): 1})
>>> v3*M3 == Vec({0, 1},{0: 2, 1: 2})
True

>>> # matrix_vector_mul
>>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
>>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2})
>>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3})
True
>>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
True
>>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2})
True
>>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {})
>>> u2 = Vec({1, 2, 3, 5, 8}, {})
>>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{})
True
>>> M3 = Mat(({0,1},{'a','b'}),{(0,'a'):1, (0,'b'):1, (1,'a'):1, (1,'b'):1})
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3*v3 == Vec({0, 1},{0: 2, 1: 2})
True
    
>>> # matrix_matrix_mul
>>> A = Mat(({0,1,2}, {0,1,2}), {(1,1):4, (0,0):0, (1,2):1, (1,0):5, (0,1):3, (0,2):2})
>>> B = Mat(({0,1,2}, {0,1,2}), {(1,0):5, (2,1):3, (1,1):2, (2,0):0, (0,0):1, (0,1):4})
>>> A*B == Mat(({0,1,2}, {0,1,2}), {(0,0):15, (0,1):12, (1,0):25, (1,1):31})
True
>>> C = Mat(({0,1,2}, {'a','b'}), {(0,'a'):4, (0,'b'):-3, (1,'a'):1, (2,'a'):1, (2,'b'):-2})
>>> D = Mat(({'a','b'}, {'x','y'}), {('a','x'):3, ('a','y'):-2, ('b','x'):4, ('b','y'):-1})
>>> C*D == Mat(({0,1,2}, {'x','y'}), {(0,'y'):-5, (1,'x'):3, (1,'y'):-2, (2,'x'):-5})
True
>>> M = Mat(({0, 1}, {'a', 'c', 'b'}), {})
>>> N = Mat(({'a', 'c', 'b'}, {(1, 1), (2, 2)}), {})
>>> M*N == Mat(({0,1}, {(1,1), (2,2)}), {})
True
>>> E = Mat(({'a','b'},{'A','B'}), {('a','A'):1,('a','B'):2,('b','A'):3,('b','B'):4})
>>> F = Mat(({'A','B'},{'c','d'}),{('A','d'):5})
>>> E*F == Mat(({'a', 'b'}, {'d', 'c'}), {('b', 'd'): 15, ('a', 'd'): 5})
True
>>> F.transpose()*E.transpose() == Mat(({'d', 'c'}, {'a', 'b'}), {('d', 'b'): 15, ('d', 'a'): 5})
True

>>> #mat_sparsity
>>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Vec(set(range(100000)),{0:2}))[0]
2
>>> (Vec(set(range(100000)),{0:2})*Mat((set(range(10000)),set(range(100000))),{(0,0):1}).transpose())[0]
2
>>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Mat((set(range(100000)), set(range(9999))), {(0,0):2}))[0,0]
2
'''

if __name__ == "__main__":
    import doctest
    doctest.testmod()
'''
>>> import sys
>>> import os
>>> sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
>>> from module.mat import Mat
>>> from module.vec import Vec

>>> # getitem
>>> M = Mat(({1,3,5}, {'a'}), {(1,'a'):4, (5,'a'): 2})
>>> M[1,'a']
4
>>> M[3,'a']
0

>>> # equal
>>> Mat(({'a','b'}, {'A','B'}), {('a','B'):0}) == Mat(({'a','b'}, {'A','B'}), {('b','B'):0})
True
>>> A = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
>>> B = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):0})
>>> C = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):5})
>>> A == B
True
>>> B == A
True
>>> A == C
False
>>> C == A
False
>>> A == Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1})
True

>>> # setitem
>>> M = Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):7})
>>> M['b', 5] = 9
>>> M['c', 5] = 13
>>> M == Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):9, ('c',5):13})
True
>>> N = Mat(({((),), 7}, {True, False}), {})
>>> N[(7, False)] = 1
>>> N[(((),), True)] = 2
>>> N == Mat(({((),), 7}, {True, False}), {(7,False):1, (((),), True):2})
True

>>> # add
>>> A1 = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
>>> A2 = Mat(({3, 6}, {'x','y'}), {(3,'y'):4})
>>> B = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (3,'y'):4, (6,'y'):3})
>>> A1 + A2 == B
True
>>> A2 + A1 == B
True
>>> A1 == Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3})
True
>>> zero = Mat(({3,6}, {'x','y'}), {})
>>> B + zero == B
True
>>> C1 = Mat(({1,3}, {2,4}), {(1,2):2, (3,4):3})
>>> C2 = Mat(({1,3}, {2,4}), {(1,4):1, (1,2):4})
>>> D = Mat(({1,3}, {2,4}), {(1,2):6, (1,4):1, (3,4):3})
>>> C1 + C2 == D
True

>>> # scalar_mul
>>> M = Mat(({1,3,5}, {2,4}), {(1,2):4, (5,4):2, (3,4):3})
>>> 0*M == Mat(({1, 3, 5}, {2, 4}), {})
True
>>> 1*M == M
True
>>> 0.25*M == Mat(({1,3,5}, {2,4}), {(1,2):1.0, (5,4):0.5, (3,4):0.75})
True
    
>>> # transpose
>>> M = Mat(({0,1}, {0,1}), {(0,1):3, (1,0):2, (1,1):4})
>>> M.transpose() == Mat(({0,1}, {0,1}), {(0,1):2, (1,0):3, (1,1):4})
True
>>> M = Mat(({'x','y','z'}, {2,4}), {('x',4):3, ('x',2):2, ('y',4):4, ('z',4):5})
>>> Mt = Mat(({2,4}, {'x','y','z'}), {(4,'x'):3, (2,'x'):2, (4,'y'):4, (4,'z'):5})
>>> M.transpose() == Mt
True

>>> # vector_matrix_mul
>>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8})
>>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
>>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0})
True
>>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8})
True
>>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7})
True
>>> v2 = Vec({'a','b'}, {})
>>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {})
>>> v2*M2 == Vec({0, 2, 4, 6, 7},{})
True
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3 = Mat(({'a', 'b'}, {0, 1}), {('a', 1): 1, ('b', 1): 1, ('a', 0): 1, ('b', 0): 1})
>>> v3*M3 == Vec({0, 1},{0: 2, 1: 2})
True

>>> # matrix_vector_mul
>>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
>>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2})
>>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3})
True
>>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1})
True
>>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2})
True
>>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {})
>>> u2 = Vec({1, 2, 3, 5, 8}, {})
>>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{})
True
>>> M3 = Mat(({0,1},{'a','b'}),{(0,'a'):1, (0,'b'):1, (1,'a'):1, (1,'b'):1})
>>> v3 = Vec({'a','b'},{'a':1,'b':1})
>>> M3*v3 == Vec({0, 1},{0: 2, 1: 2})
True
    
>>> # matrix_matrix_mul
>>> A = Mat(({0,1,2}, {0,1,2}), {(1,1):4, (0,0):0, (1,2):1, (1,0):5, (0,1):3, (0,2):2})
>>> B = Mat(({0,1,2}, {0,1,2}), {(1,0):5, (2,1):3, (1,1):2, (2,0):0, (0,0):1, (0,1):4})
>>> A*B == Mat(({0,1,2}, {0,1,2}), {(0,0):15, (0,1):12, (1,0):25, (1,1):31})
True
>>> C = Mat(({0,1,2}, {'a','b'}), {(0,'a'):4, (0,'b'):-3, (1,'a'):1, (2,'a'):1, (2,'b'):-2})
>>> D = Mat(({'a','b'}, {'x','y'}), {('a','x'):3, ('a','y'):-2, ('b','x'):4, ('b','y'):-1})
>>> C*D == Mat(({0,1,2}, {'x','y'}), {(0,'y'):-5, (1,'x'):3, (1,'y'):-2, (2,'x'):-5})
True
>>> M = Mat(({0, 1}, {'a', 'c', 'b'}), {})
>>> N = Mat(({'a', 'c', 'b'}, {(1, 1), (2, 2)}), {})
>>> M*N == Mat(({0,1}, {(1,1), (2,2)}), {})
True
>>> E = Mat(({'a','b'},{'A','B'}), {('a','A'):1,('a','B'):2,('b','A'):3,('b','B'):4})
>>> F = Mat(({'A','B'},{'c','d'}),{('A','d'):5})
>>> E*F == Mat(({'a', 'b'}, {'d', 'c'}), {('b', 'd'): 15, ('a', 'd'): 5})
True
>>> F.transpose()*E.transpose() == Mat(({'d', 'c'}, {'a', 'b'}), {('d', 'b'): 15, ('d', 'a'): 5})
True

>>> #mat_sparsity
>>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Vec(set(range(100000)),{0:2}))[0]
2
>>> (Vec(set(range(100000)),{0:2})*Mat((set(range(10000)),set(range(100000))),{(0,0):1}).transpose())[0]
2
>>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Mat((set(range(100000)), set(range(9999))), {(0,0):2}))[0,0]
2
'''

if __name__ == "__main__":
    import doctest
    doctest.testmod()
>>> import sys >>> import os >>> sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__)))) >>> from module.mat import Mat >>> from module.vec import Vec  >>> # getitem >>> M = Mat(({1,3,5}, {'a'}), {(1,'a'):4, (5,'a'): 2}) >>> M[1,'a'] 4 >>> M[3,'a'] 0  >>> # equal >>> Mat(({'a','b'}, {'A','B'}), {('a','B'):0}) == Mat(({'a','b'}, {'A','B'}), {('b','B'):0}) True >>> A = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1}) >>> B = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):0}) >>> C = Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1, ('b','B'):5}) >>> A == B True >>> B == A True >>> A == C False >>> C == A False >>> A == Mat(({'a','b'}, {'A','B'}), {('a','B'):2, ('b','A'):1}) True  >>> # setitem >>> M = Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):7}) >>> M['b', 5] = 9 >>> M['c', 5] = 13 >>> M == Mat(({'a','b','c'}, {5}), {('a', 5):3, ('b', 5):9, ('c',5):13}) True >>> N = Mat(({((),), 7}, {True, False}), {}) >>> N[(7, False)] = 1 >>> N[(((),), True)] = 2 >>> N == Mat(({((),), 7}, {True, False}), {(7,False):1, (((),), True):2}) True  >>> # add >>> A1 = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3}) >>> A2 = Mat(({3, 6}, {'x','y'}), {(3,'y'):4}) >>> B = Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (3,'y'):4, (6,'y'):3}) >>> A1 + A2 == B True >>> A2 + A1 == B True >>> A1 == Mat(({3, 6}, {'x','y'}), {(3,'x'):-2, (6,'y'):3}) True >>> zero = Mat(({3,6}, {'x','y'}), {}) >>> B + zero == B True >>> C1 = Mat(({1,3}, {2,4}), {(1,2):2, (3,4):3}) >>> C2 = Mat(({1,3}, {2,4}), {(1,4):1, (1,2):4}) >>> D = Mat(({1,3}, {2,4}), {(1,2):6, (1,4):1, (3,4):3}) >>> C1 + C2 == D True  >>> # scalar_mul >>> M = Mat(({1,3,5}, {2,4}), {(1,2):4, (5,4):2, (3,4):3}) >>> 0*M == Mat(({1, 3, 5}, {2, 4}), {}) True >>> 1*M == M True >>> 0.25*M == Mat(({1,3,5}, {2,4}), {(1,2):1.0, (5,4):0.5, (3,4):0.75}) True      >>> # transpose >>> M = Mat(({0,1}, {0,1}), {(0,1):3, (1,0):2, (1,1):4}) >>> M.transpose() == Mat(({0,1}, {0,1}), {(0,1):2, (1,0):3, (1,1):4}) True >>> M = Mat(({'x','y','z'}, {2,4}), {('x',4):3, ('x',2):2, ('y',4):4, ('z',4):5}) >>> Mt = Mat(({2,4}, {'x','y','z'}), {(4,'x'):3, (2,'x'):2, (4,'y'):4, (4,'z'):5}) >>> M.transpose() == Mt True  >>> # vector_matrix_mul >>> v1 = Vec({1, 2, 3}, {1: 1, 2: 8}) >>> M1 = Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7}) >>> v1*M1 == Vec({'a', 'b', 'c'},{'a': -8, 'b': 2, 'c': 0}) True >>> v1 == Vec({1, 2, 3}, {1: 1, 2: 8}) True >>> M1 == Mat(({1, 2, 3}, {'a', 'b', 'c'}), {(1, 'b'): 2, (2, 'a'):-1, (3, 'a'): 1, (3, 'c'): 7}) True >>> v2 = Vec({'a','b'}, {}) >>> M2 = Mat(({'a','b'}, {0, 2, 4, 6, 7}), {}) >>> v2*M2 == Vec({0, 2, 4, 6, 7},{}) True >>> v3 = Vec({'a','b'},{'a':1,'b':1}) >>> M3 = Mat(({'a', 'b'}, {0, 1}), {('a', 1): 1, ('b', 1): 1, ('a', 0): 1, ('b', 0): 1}) >>> v3*M3 == Vec({0, 1},{0: 2, 1: 2}) True  >>> # matrix_vector_mul >>> N1 = Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1}) >>> u1 = Vec({'a', 'b'}, {'a': 1, 'b': 2}) >>> N1*u1 == Vec({1, 3, 5, 7},{1: 3, 3: 9, 5: -2, 7: 3}) True >>> N1 == Mat(({1, 3, 5, 7}, {'a', 'b'}), {(1, 'a'): -1, (1, 'b'): 2, (3, 'a'): 1, (3, 'b'):4, (7, 'a'): 3, (5, 'b'):-1}) True >>> u1 == Vec({'a', 'b'}, {'a': 1, 'b': 2}) True >>> N2 = Mat(({('a', 'b'), ('c', 'd')}, {1, 2, 3, 5, 8}), {}) >>> u2 = Vec({1, 2, 3, 5, 8}, {}) >>> N2*u2 == Vec({('a', 'b'), ('c', 'd')},{}) True >>> M3 = Mat(({0,1},{'a','b'}),{(0,'a'):1, (0,'b'):1, (1,'a'):1, (1,'b'):1}) >>> v3 = Vec({'a','b'},{'a':1,'b':1}) >>> M3*v3 == Vec({0, 1},{0: 2, 1: 2}) True      >>> # matrix_matrix_mul >>> A = Mat(({0,1,2}, {0,1,2}), {(1,1):4, (0,0):0, (1,2):1, (1,0):5, (0,1):3, (0,2):2}) >>> B = Mat(({0,1,2}, {0,1,2}), {(1,0):5, (2,1):3, (1,1):2, (2,0):0, (0,0):1, (0,1):4}) >>> A*B == Mat(({0,1,2}, {0,1,2}), {(0,0):15, (0,1):12, (1,0):25, (1,1):31}) True >>> C = Mat(({0,1,2}, {'a','b'}), {(0,'a'):4, (0,'b'):-3, (1,'a'):1, (2,'a'):1, (2,'b'):-2}) >>> D = Mat(({'a','b'}, {'x','y'}), {('a','x'):3, ('a','y'):-2, ('b','x'):4, ('b','y'):-1}) >>> C*D == Mat(({0,1,2}, {'x','y'}), {(0,'y'):-5, (1,'x'):3, (1,'y'):-2, (2,'x'):-5}) True >>> M = Mat(({0, 1}, {'a', 'c', 'b'}), {}) >>> N = Mat(({'a', 'c', 'b'}, {(1, 1), (2, 2)}), {}) >>> M*N == Mat(({0,1}, {(1,1), (2,2)}), {}) True >>> E = Mat(({'a','b'},{'A','B'}), {('a','A'):1,('a','B'):2,('b','A'):3,('b','B'):4}) >>> F = Mat(({'A','B'},{'c','d'}),{('A','d'):5}) >>> E*F == Mat(({'a', 'b'}, {'d', 'c'}), {('b', 'd'): 15, ('a', 'd'): 5}) True >>> F.transpose()*E.transpose() == Mat(({'d', 'c'}, {'a', 'b'}), {('d', 'b'): 15, ('d', 'a'): 5}) True  >>> #mat_sparsity >>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Vec(set(range(100000)),{0:2}))[0] 2 >>> (Vec(set(range(100000)),{0:2})*Mat((set(range(10000)),set(range(100000))),{(0,0):1}).transpose())[0] 2 >>> (Mat((set(range(10000)),set(range(100000))),{(0,0):1})*Mat((set(range(100000)), set(range(9999))), {(0,0):2}))[0,0] 2