1

I am currently writing a Linear Algebra module for Python 3.x wherein I deal with self-defined matrix objects.

Is there any way I can make the basic arithmetic operators like +, -, * adhere to my matrix objects? For example -

>>> A = matrix("1 2;3 4") >>> B = matrix("1 0; 0 1") >>> A + B [2 2] [3 5] >>> A * A [7 10] [15 22] 

Right now I have written separate functions for addition, multiplication, etc. but typing A.multiply(A) is much more cumbersome than simply A*A.

4 Answers 4

5

You are looking for special methods. Particularly at emulating numerical types section.

Also, as you're trying to implement matrices and matrices are containers, you may find useful to define custom container methods for your type.

UPDATE: Here is an example of custom objects using special methods to implement arithmetical operators:

class Value(object): def __init__(self, x): self.x = x def __add__(self, other): if not isinstance(other, Value): raise TypeError return Value(self.x + other.x) def __mul__(self, other): if not isinstance(other, Value): raise TypeError return Value(self.x * other.x) assert (Value(2) + Value(3)).x == 5 assert (Value(2) * Value(3)).x == 6 
Sign up to request clarification or add additional context in comments.

2 Comments

I feel this falls in the category 'link only' answers. I cannot raise the appropriate flag because it has been upvoted, so would you mind improving your answer with perhaps a code example?
@TimCastelijns after some thought I think you're completely right about examples. Added one.
2

Unless you're doing this specifically to learn or for practice you should look at numerical python, numpy, which is the de facto standard solution for basic linear algebra and matrices. It has a matrix class which does what you are looking for.

Comments

1

You can override the built in methods for numerical types.

class matrix: def __init__(self, string_matrix): self.matrix = string_matrix.split(";") for i in range(len(self.matrix)): self.matrix[i] = map(int, self.matrix[i].split()) def __add__(self, other): return_matrix = [[i for i in row] for row in self.matrix] for i in range(len(self.matrix)): for j in range(len(self.matrix[i])): return_matrix[i][j] = self.matrix[i][j] + other.matrix[i][j] return list_to_matrix(return_matrix) def __str__(self): return repr(self.matrix) def list_to_matrix(list_matrix): string_form = "" for row in list_matrix: for item in row: if (item != row[-1]): string_form += str(item) + " " else: string_form += str(item) if (row != list_matrix[-1]): string_form += ";" return matrix(string_form) 

You will probably want to include a couple of checks (such as adding matrices of different dimensions, or adding a matrix to something that is not a matrix, etc) but this works as a simple example. Also notice that I'm returning a matrix object using the list_to_matrix() function - if that isn't the desired functionality you can change it pretty readily. You would use a similar process for all other arithmetic functions you need to implement.

Output:

>>> a = matrix("3 4;1 4") >>> b = matrix("2 3;0 0") >>> print(a) [[3, 4], [1, 4]] >>> print(b) [[2, 3], [0, 0]] >>> print(a + b) [[5, 7], [1, 4]] 

As mentioned in one of the other answers, numpy might be a good resource to use for your matrix operations - a lot of this functionality is already built in.

>>> import numpy as np >>> a = np.matrix("3 4;1 4") >>> b = np.matrix("2 3;0 0") >>> print(a) [[3 4] [1 4]] >>> print(b) [[2 3] [0 0]] >>> print(a + b) [[5 7] [1 4]] 

Comments

0

If you define some special methods within the class, Python will call them for arithmetic operations. An example class that define addition, multiplication, division, and subtraction:

class motar: def __add__(self, other): return "9999" def __mul__(self, other): return "8888" def __sub__(self, other): return "7777" def __div__(self, other): return "6666" m = [ motar() for x in range(2) ] # create two instances # arithmetic operations on class instances will call # ... the special methods defined above: print m[0] + m[1] print m[0] * m[1] print m[0] - m[1] print m[0] / m[1] 

Gives:

9999 8888 7777 6666 

1 Comment

More obscure than helpful, but upvoting to counter the stray downvote. Still, a bit of explanation could improve this demonstration a lot by pointing out how this is useful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.