How to use recursion inside a class function - python

I made a class function that deals with matrices or a list within a list. Sort of like a calculator that looks like this:
class RealMat:
def __init__(self, mat):
self.mat = mat
def __add__(self, other):
if len(self.mat) != len(other.mat) or len(self.mat[0]) != len(self.mat[0]):
return None
result = self.mat
for i in range(len(self.mat)):
for j in range(len(self.mat[0])):
result[i][j] = self.mat[i][j] + other.mat[i][j]
return RealMat(result)
def __sub__(self, other):
if len(self.mat) != len(other.mat) or len(self.mat[0]) != len(self.mat[0]):
return None
result = self.mat
for i in range(len(self.mat)):
for j in range(len(self.mat[0])):
result[i][j] = self.mat[i][j] - other.mat[i][j]
return RealMat(result)
def __mul__(self, other):
if isinstance(other, int):
for x in range(len(self.mat)):
for y in range(len(self.mat[0])):
self.mat[x][y] = self.mat[x][y] * other
return RealMat(self.mat)
if len(self.mat[0])!=len(other.mat):
return None
column=0
result=[[0]*len(self.mat) for i in range(len(other.mat[0]))]
for x in range(len(other.mat[0])):
row = 0
for x in range(len(self.mat)):
total = 0
i = 0
for x in range(len(self.mat[0])):
total += self.mat[row][i] * other.mat[i][column]
i += 1
result[row][column] = total
row += 1
column += 1
return RealMat(result)
def __rmul__(self, factor):
for x in range(len(self.mat)):
for y in range(len(self.mat[0])):
self.mat[x][y] = self.mat[x][y] * factor
return RealMat(self.mat)
def __pow__(self, n):
if len(self.mat) != len(self.mat[0]):
return None
if n == 0:
identity = [[1 if i == j else 0 for i in range(len(self.mat))] for j in range(len(self.mat))]
return RealMat(identity)
result = RealMat(self.mat)
for x in range(n-1):
result = result * RealMat(self.mat)
return result
def __eq__(self, other):
if len(self.mat) != len(other.mat) or len(self.mat[0]) != len(other.mat[0]):
return False
for x in range(len(self.mat)):
for y in range(len(self.mat[0])):
if self.mat[x][y] != other.mat[x][y]:
return False
return True
def getMatrixMinor(self,i,j):
return [row[:j] + row[j+1:] for row in (self.mat[:i]+self.mat[i+1:])]
def getMatrixDeternminant(self):
if len(self.mat) == 2:
return self.mat[0][0]*self.mat[1][1]-self.mat[0][1]*self.mat[1][0]
determinant = 0
for c in range(len(self.mat)):
determinant += ((-1)**c)*self.mat[0][c]*getMatrixDeternminant(getMatrixMinor(self.mat,0,c))
return determinant
All the other code works fine and I'm happy with it but I can't seem to make my determinant finder code to work
def getMatrixMinor(self,i,j):
return [row[:j] + row[j+1:] for row in (self.mat[:i]+self.mat[i+1:])]
This code gets me the minor matrix while this:
def getMatrixDeternminant(self):
if len(self.mat) == 2:
return self.mat[0][0]*self.mat[1][1]-self.mat[0][1]*self.mat[1][0]
determinant = 0
for c in range(len(self.mat)):
determinant += ((-1)**c)*self.mat[0][c]*getMatrixDeternminant(getMatrixMinor(self.mat,0,c))
return determinant
Solves the determinant of nxn matrix. However it keeps saying "getMatrixDeternminant is not defined" when I try to recurse it. Maybe because it is inside a class? I just got into OOP so I am not well versed in this. Can someone point out what I did wrong?
edit* I tried using the self.getMatrixDeternminant()
def getMatrixMinor(self,m,i,j):
return [row[:j] + row[j+1:] for row in (m[:i]+m[i+1:])]
def getMatrixDeternminant(self):
if len(self.mat) == 2:
return self.mat[0][0]*self.mat[1][1]-self.mat[0][1]*self.mat[1][0]
determinant = 0
for c in range(len(self.mat)):
determinant += ((-1)**c)*self.mat[0][c]*self.getMatrixDeternminant(self.getMatrixMinor(self.mat,0,c))
return determinant
it says:
TypeError: getMatrixDeternminant() takes 1 positional argument but 2 were given
Edit**: I actually got the code from somewhere and tried to implement it in my class. This is the original code:
def getMatrixMinor(m,i,j):
return [row[:j] + row[j+1:] for row in (m[:i]+m[i+1:])]
def getMatrixDeternminant(m):
#base case for 2x2 matrix
if len(m) == 2:
return m[0][0]*m[1][1]-m[0][1]*m[1][0]
determinant = 0
for c in range(len(m)):
determinant += ((-1)**c)*m[0][c]*getMatrixDeternminant(getMatrixMinor(m,0,c))
return determinant

Your getMatrixDeternminant [sic] calculates the determinant of the current object (self). However, your algorithm requires calculating the determinant of other matrices.
Therefore, first keep the algorithm as it was originally (usually you would make it a static method or keep it outside the class). Then, from your method, call that algorithm passing it your current matrix.

Related

Creating Polynomial Class in Python

I am currently working on creating a Polynomial class that includes add , mul and eval methods. I'm currently stuck on the addition portion, if someone could give me some help on how to get that figured out that would be greatly appreciated. Everything currently works without errors but when I do p3 = p1 + p2 and I print p3 I get back the two lists together. Any feedback would be greatly appreciated.
class Polynomial(object):
def __init__(self, *coeffs, num = 0):
self.coeffs = list(coeffs) # turned into a list
assert (type(num) is type(1))
self.num = num
# Needs to be operator overload
'''
def __mul__(self, other):
'''
def __eval__(self, other, coeff, x):
result = coeff[-1]
for i in range(-2, -len(coeff)-1, -1):
result = result * x + coeff[i]
return result
def __add__(self, other):
assert type(other) is Polynomial
num = self.coeffs + other.coeffs
return Polynomial(num)
def __sub__(self, other):
assert type(other) is Polynomial
num = self.coeffs - other.coeffs
return Polynomial(num)
def __represntation__(self):
return "Polynomial" + str(self.coeffs)
def __str__(self):
rep = ""
degree = len(self.coeffs) - 1
rep += str(self.coeffs[0]) + "x^" + str(degree)
for i in range(1, len(self.coeffs)-1):
coeff = self.coeffs[i]
if coeff < 0:
rep += " - " + str(-coeff) + "x^" + str(degree - i)
else:
rep += " + " + str(coeff) + "x^" + str(degree - i)
if self.coeffs[-1] < 0:
rep += " - " + str(-self.coeffs[-1])
else:
rep += " + " + str(self.coeffs[-1])
return rep
You cannot directly add two lists.
def __add__(self, other):
assert type(other) is Polynomial
assert len(self.coeffs) != len(other.coeffs)
new_ceffs = [item1 + item2 for (item1, item2) in zip(self.coeffs, other.coeffs)]
return Polynomial(new_ceffs)
The problem is here:
num = self.coeffs + other.coeffs
Adding one list to another list concatenates them. To simply add corresponding elements to each other, you'd want to do
from itertools import zip_longest
...
num = [a + b for (a, b) in zip_longest(self.coeffs, other.coeffs, fillvalue=0)]
We use zip_longest() instead of the more generic zip() because one polynomial is possibly longer than the other and we don't want to ruin it. Either one of them will group together the corresponding elements so that we can easily add them and make a list of those.
You would do something similar for subtraction.
you should reverse the order of coefficients passed to your constructor so that indexes in the self.coeffs list correspond to the exponents. This would simplify the rest of your code and allow you to use zip_longest for additions and subtractions.
When you get to other operations however, I think you will realize that your internal structure would be easier to manage if it was a dictionary. A dictionary is more permissive of missing entries thus avoiding preoccupations of allocating spaces for new indexes.
class Polynomial(object):
def __init__(self, *coeffs):
self.coeffs = {exp:c for exp,c in enumerate(coeffs[::-1])}
def __add__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
result.coeffs = {**self.coeffs}
for exp,c in other.coeffs.items():
result.coeffs[exp] = result.coeffs.get(exp,0) + c
return result
def __sub__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
result.coeffs = {**self.coeffs}
for exp,c in other.coeffs.items():
result.coeffs[exp] = result.coeffs.get(exp,0) - c
return result
def __mul__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
for exp1,c1 in self.coeffs.items():
for exp2,c2 in other.coeffs.items():
result.coeffs[exp1+exp2] = result.coeffs.get(exp1+exp2,0) + c1*c2
return result
def __representation__(self):
return "Polynomial" + str(self.coeffs)
def __str__(self):
result = [""]+[f"{c}x^{i}" for i,c in sorted(self.coeffs.items()) if c]+[""]
result = "+".join(reversed(result))
result = result.replace("+1x","+x")
result = result.replace("-1x","-x")
result = result.replace("x^0","")
result = result.replace("x^1+","x+")
result = result.replace("+-","-")
result = result.strip("+")
result = result.replace("+"," + ")
result = result[:1]+result[1:].replace("-"," - ")
return result.strip()

How can i implement Vector addition for the form [1,2,3,4] + v where v is vector and [1,2,3,4] is a list in python?

Here is the code for the program:
I tried to implement a vector class as i learned about operator overloading in python. I was able to make a vector class which can be used much like a list with operations like len(vector) , vector1 + vector2 (addition operator overloading) and subtraction . But i found a problem. Here is the code of the program and i have stated the problem below :
class vector:
"""Initialize Vector"""
def __init__(self,d):
self.coords = [0]*d
def __len__(self):
return len(self.coords)
def __getitem__(self, item): #Getting an item from a vector
return self.coords[item]
def __setitem__(self, key, value):
self.coords[key] = value
def __add__(self, other):
if(len(self)!= len(other)):
print("Don't add these too ! they are not same types :P")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] + other[i]
return result
def __sub__(self, other):
if(len(self) != len(other)):
print("Dont subtract these two!")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] - other[i]
return result
def __eq__(self, other):
return self.coords == other.coords
def __ne__(self, other):
return self.coords != other.coords
def __str__(self):
return '<'+ str(self.coords)[1:-1] +'>'
print("Input for vector 1")
x = vector(2)
for i in range(0,len(x)):
x[i] = int(input('Enter a number\n'))
print("Input for vector 2")
y = vector(2)
for i in range(0,len(y)):
y[i] = int(input('Enter a number\n'))
z = x-y
print(str(x))
print(" + ")
print(str(y))
print(" = ")
print(str(z))
It works if i add a vector + list but list + vector gives an error. How can i implement the other .
You want to implement __radd__. Since it should do the same thing as __add__ here, you can just assign __add__ to it:
class vector:
...
def __add__(self, other):
if(len(self)!= len(other)):
print("Don't add these too ! they are not same types :P")
else:
result = vector(len(self))
for i in range(0,len(result)):
result[i] = self[i] + other[i]
return result
__radd__ = __add__
...

Issue with python __eq__ method in checking if 2 lists are equal

I have a python program in which I have a class called Vector and an empty list inside of that class which is being populated runtime.
Here is the init:
def __init__(self,n):
self.vector = [];
self.n = n;
for x in range(n):
self.vector.append(False);
And here is the eq:
def __eq__(self, other):
t = True
for x in range(self.n):
if self.vector[x] != other.vector[x]:
t = False;
return t
however, when I try to check if 2 objects of this type are equal, I always get true, even though I changed values inside of vector in Vector class.
Here is the code where I do the above:
vectors = []
n = tmp.size();
k = calculateCombinationCount(n,int(n/2))
for i in range(k):
for j in range(0,n-1):
if (tmp.vector[j] != tmp.vector[j+1]):
t = True
for x in vectors:
if x == tmp:
t = False;
if t:
vectors.append(tmp)
tmp.printVector();
tmp.swap(j,j+1);
I would appreciate any help that you can provide. Thank you :)
EDIT:
def swap(self,i,j):
tmp = self.vector[i]
self.vector[i] = self.vector[j]
self.vector[j] = tmp
def calculateCombinationCount(n,r):
k = factorial(n)/(factorial(int(r))*factorial(int(n-r)))
return int(k)
Right so I've updated your code to be much more pythonic (I can tell you come from another language, Java?).
from math import factorial
class Vector:
def __init__(self, size):
self.size = size
self.vector = [False] * size
def __eq__(self, other):
"""
Same if self.size == other.size
"""
assert self.size == other.size, (self.size, other.size)
return self.vector == other.vector
def print_vector(self):
print(self.vector)
def swap(self, i, j):
"""
More efficient and pythonic
"""
self.vector[i], self.vector[j] = self.vector[j], self.vector[i]
def calculate_combination_count(n, r):
"""
This is slow, I'd replace it with scipy.special.comb
https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html#scipy.special.comb
"""
return factorial(n) // (factorial(r) * factorial(n-r))
tmp = Vector(10)
vectors = []
n = tmp.size
k = calculate_combination_count(n, n // 2)
for i in range(k):
for j in range(0, n-1):
if tmp.vector[j] != tmp.vector[j + 1]:
if not any(vec == tmp for vec in vectors): # much more efficient
vectors.append(tmp)
tmp.print_vector()
tmp.swap(j, j + 1)
else: # Just to prove why it doesn't work
print('tmp.vector is all False: {}'.format(not all(tmp.vector)))
This prints out tmp.vector is all False: True repeatedly. I think this is your problem.
If you

Matrix class & Test

as part of my studies I created this Matrix class. To test the results I was provided with a 'test.py' file.
My problem now is that the test file always gives me this error:
> --------------------------------------------------------------------------- AttributeError Traceback (most recent call
> last) <ipython-input-7-daeb08264590> in <module>()
> 6 # and then selecting matrix.py
> 7
> ----> 8 import test
>
> /home/workspace/test.py in <module>()
> 76 return True
> 77
> ---> 78 test()
>
> /home/workspace/test.py in test()
> 57 assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
> 58 """
> ---> 59 assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
> 60 assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
> 61 assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
>
> /home/workspace/test.py in equal(m1, m2)
> 68
> 69 def equal(m1, m2):
> ---> 70 if len(m1.g) != len(m2.g): return False
> 71 if len(m1.g[0]) != len(m2.g[0]): return False
> 72 for r1, r2 in zip(m1.g, m2.g):
>
> AttributeError: 'list' object has no attribute 'g'
However when testing the cases myself, it works and show the same result.
matrix.py
import math
from math import sqrt
import numbers
def zeroes(height, width):
"""
Creates a matrix of zeroes.
"""
g = [[0.0 for _ in range(width)] for __ in range(height)]
return Matrix(g)
def identity(n):
"""
Creates a n x n identity matrix.
"""
I = zeroes(n, n)
for i in range(n):
I.g[i][i] = 1.0
return I
class Matrix(object):
# Constructor
def __init__(self, grid):
self.g = grid
self.h = len(grid)
self.w = len(grid[0])
#
# Primary matrix math methods
#############################
def determinant(self):
if not self.is_square():
raise(ValueError, "Cannot calculate determinant of non-square matrix.")
if self.h > 2:
raise(NotImplementedError, "Calculating determinant not implemented for matrices largerer than 2x2.")
if self.h == 1:
return self.g[0][0]
elif self.h == 2:
return (self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
def trace(self):
if not self.is_square():
raise(ValueError, "Cannot calculate the trace of a non-square matrix.")
sum_trace = 0
for i in range(self.h):
for j in range(self.w):
if i == j:
sum_trace = sum_trace + self.g[i][j]
return sum_trace
def inverse(self):
if not self.is_square():
raise(ValueError, "Non-square Matrix does not have an inverse.")
if self.h > 2:
raise(NotImplementedError, "inversion not implemented for matrices larger than 2x2.")
if self.h == 2:
if self.g[0][0] * self.g[1][1] == self.g[0][1] * self.g[1][0]:
return "ad = bc. Therefore Matrix does not have an inverse"
else:
det_A = 1/(self.g[0][0]*self.g[1][1]-self.g[0][1]*self.g[1][0])
inverse = [[det_A*self.g[1][1],det_A*-self.g[0][1]],[det_A*-self.g[1][0],det_A*self.g[0][0]]]
elif self.h == 1:
inverse = [[1/self.g[0][0]]]
def T(self):
matrix_transpose = []
#Iterate through columns (e.g. j=0)
for j in range(self.w):
#Reset row for each itteration
new_row = []
#Iterate through rows (e.g. j = 0, i loops 0;1)
for i in range(self.h):
#i = 0, j = 0; i = 1, j = 0 > new row created out of matrix columns
new_row.append(self.g[i][j])
#new_row appended to matrix_transpose
matrix_transpose.append(new_row)
return matrix_transpose
def is_square(self):
return self.h == self.w
#
# Begin Operator Overloading
############################
def __getitem__(self,idx):
return self.g[idx]
def __repr__(self):
s = ""
for row in self.g:
s += " ".join(["{} ".format(x) for x in row])
s += "\n"
return s
def __add__(self,other):
if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be added if the dimensions are the same")
matrix_addition = []
for i in range(self.h):
new_row = []
for j in range(self.w):
addition = self.g[i][j] + other.g[i][j]
new_row.append(addition)
matrix_addition.append(new_row)
return Matrix(matrix_addition)
def __neg__(self):
for i in range(self.h):
for j in range(self.w):
self.g[i][j] *= -1
return Matrix(self.g)
def __sub__(self, other):
if self.h != other.h or self.w != other.w:
raise(ValueError, "Matrices can only be substracted if the dimensions are the same")
matrix_substraction = []
for i in range(self.h):
new_row = []
for j in range(self.w):
addition = self.g[i][j] - other.g[i][j]
new_row.append(addition)
matrix_substraction.append(new_row)
return Matrix(matrix_substraction)
def __mul__(self, other):
#dot_product func
def dot_product(vector_one, vector_two):
dot_product = 0
for i in range(len(vector_one)):
dot_product += vector_one[i] * vector_two[i]
return dot_product
#get_row func
def get_row(matrix, row):
return matrix[row]
#get_column func
def get_column(matrix, column_number):
column = []
for i in range(len(matrix)):
column.append(matrix[i][column_number])
return column
result = []
for i in range(self.h):
row_result = []
for j in range(self.w):
vector_one = get_row(self.g, i)
vector_two = get_column(other.g, j)
calulated_dot_product = dot_product(vector_one, vector_two)
row_result.append(calulated_dot_product)
result.append(row_result)
return Matrix(result)
def __rmul__(self, other):
if isinstance(other, numbers.Number):
pass
for i in range(self.h):
for j in range(self.w):
self.g[i][j] = 2 * self.g[i][j]
return Matrix(self.g)
test.py
import matrix as m
def test():
I2 = m.Matrix([
[1, 0],
[0, 1]
])
I2_neg = m.Matrix([
[-1, 0],
[0, -1]
])
zero = m.Matrix([
[0,0],
[0,0]
])
m1 = m.Matrix([
[1,2,3],
[4,5,6]
])
m2 = m.Matrix([
[7,-2],
[-3,-5],
[4,1]
])
m1_x_m2 = m.Matrix([
[ 13, -9],
[ 37, -27]])
m2_x_m1 = m.Matrix([
[ -1, 4, 9],
[-23, -31, -39],
[ 8, 13, 18]])
m1_m2_inv = m.Matrix([
[1.5, -0.5],
[2.0555556, -0.722222222]
])
top_ones = m.Matrix([
[1,1],
[0,0],
])
left_ones = m.Matrix([
[1,0],
[1,0]
])
assert equal(-I2, I2_neg), "Error in your __neg__ function"
assert equal(I2 + I2_neg, zero), "Error in your __add__ function"
assert equal(m1 * m2, m1_x_m2), "Error in your __mul__ function"
assert equal(m2 * m1, m2_x_m1), "Error in your __mul__ function"
assert equal(m1_x_m2.inverse(), m1_m2_inv), "Error in your inverse function for the 1 x 1 case"
assert equal(I2.inverse(), I2), "Error in your inverse function for the 2 x 2 case"
assert equal(top_ones.T(), left_ones), "Error in your T function (transpose)"
assert equal(left_ones.T(), top_ones), "Error in your T function (transpose)"
assert equal(top_ones - left_ones.T(), m.zeroes(2,2)), "Error in your __sub__ function"
assert (4*m.identity(5))[0][0] == 4, "Error in your __rmul__ function"
assert (4*m.identity(5)).trace() == 20 , "Error in your trace function"
print("Congratulations! All tests pass. Your Matrix class is working as expected.")
def equal(m1, m2):
if len(m1.g) != len(m2.g): return False
if len(m1.g[0]) != len(m2.g[0]): return False
for r1, r2 in zip(m1.g, m2.g):
for v1, v2 in zip(r1, r2):
if abs(v1 - v2) > 0.0001:
return False
return True
test()
playground.py (To test it & import both files)
# Run this cell but don't modify it.
%load_ext autoreload
%autoreload 2
from matrix import Matrix, zeroes, identity
# Try running this code. You should get an assertion error.
# You will continue to get assertion errors until all the
# methods in matrix.py are correctly implemented.
# You can open matrix.py by selecting File > Open...
# and then selecting matrix.py
import test
I tried to break the problem down, so I could reduce the code I have to share here with you. But no matter what I tried to change, I got errors back from test.py. I hope anyone from you guys could look into it and maybe has an idea where the problem lies.
/Marc
A quick check in that codebase reveals that the methods inverse and T of the Matrix class do not return Matrix instances, but bare grids (2d-lists); these grids, of course, have no g attribute when the equal function in the test tries to compare them with Matrix instances. Wrap the return values of these two methods into matrixes:
class Matrix(object):
def inverse(self):
# ....
# not: return inverse
return Matrix(inverse)
def T(self):
# ...
# not: return matrix_transpose
return Matrix(matrix_transpose)

How to put scalar multiplication in this code?

import random
import operator
import sys
import unittest
__version__ = "0.3"
class MatrixError(Exception):
""" An exception class for Matrix """
pass
class Matrix(object):
""" A simple Python matrix class with
basic operations and operator overloading """
def __init__(self, m, n, init=True):
if init:
self.rows = [[0]*n for x in range(m)]
else:
self.rows = []
self.m = m
self.n = n
def __getitem__(self, idx):
return self.rows[idx]
def __setitem__(self, idx, item):
self.rows[idx] = item
def __str__(self):
s='\n'.join([' '.join([str(item) for item in row]) for row in self.rows])
return s + '\n'
def __repr__(self):
s=str(self.rows)
rank = str(self.getRank())
rep="Matrix: \"%s\", rank: \"%s\"" % (s,rank)
return rep
def reset(self):
""" Reset the matrix data """
self.rows = [[] for x in range(self.m)]
def transpose(self):
""" Transpose the matrix. Changes the current matrix """
self.m, self.n = self.n, self.m
self.rows = [list(item) for item in zip(*self.rows)]
def getTranspose(self):
""" Return a transpose of the matrix without
modifying the matrix itself """
m, n = self.n, self.m
mat = Matrix(m, n)
mat.rows = [list(item) for item in zip(*self.rows)]
return mat
def getRank(self):
return (self.m, self.n)
def __eq__(self, mat):
""" Test equality """
return (mat.rows == self.rows)
def __add__(self, mat):
""" Add a matrix to this matrix and
return the new matrix. Doesn't modify
the current matrix """
if self.getRank() != mat.getRank():
raise MatrixError, "Trying to add matrixes of varying rank!"
ret = Matrix(self.m, self.n)
for x in range(self.m):
row = [sum(item) for item in zip(self.rows[x], mat[x])]
ret[x] = row
return ret
def __sub__(self, mat):
""" Subtract a matrix from this matrix and
return the new matrix. Doesn't modify
the current matrix """
if self.getRank() != mat.getRank():
raise MatrixError, "Trying to add matrixes of varying rank!"
ret = Matrix(self.m, self.n)
for x in range(self.m):
row = [item[0]-item[1] for item in zip(self.rows[x], mat[x])]
ret[x] = row
return ret
def __mul__(self, mat):
""" Multiple a matrix with this matrix and
return the new matrix. Doesn't modify
the current matrix """
matm, matn = mat.getRank()
if (self.n != matm):
raise MatrixError, "Matrices cannot be multipled!"
mat_t = mat.getTranspose()
mulmat = Matrix(self.m, matn) or Matrix(self.m, a)
for x in range(self.m):
for y in range(mat_t.m) or y==a:
mulmat[x][y] = sum([item[0]*item[1] for item in zip(self.rows[x], mat_t[y])])or a*x
return mulmat
def __iadd__(self, mat):
""" Add a matrix to this matrix.
This modifies the current matrix """
# Calls __add__
tempmat = self + mat
self.rows = tempmat.rows[:]
return self
def __isub__(self, mat):
""" Add a matrix to this matrix.
This modifies the current matrix """
# Calls __sub__
tempmat = self - mat
self.rows = tempmat.rows[:]
return self
def __imul__(self, mat):
""" Add a matrix to this matrix.
This modifies the current matrix """
# Possibly not a proper operation
# since this changes the current matrix
# rank as well...
# Calls __mul__
tempmat = self * mat
self.rows = tempmat.rows[:]
self.m, self.n = tempmat.getRank()
return self
def save(self, filename):
open(filename, 'w').write(str(self))
#classmethod
def _makeMatrix(cls, rows):
m = len(rows)
n = len(rows[0])
# Validity check
if any([len(row) != n for row in rows[1:]]):
raise MatrixError, "inconsistent row length"
mat = Matrix(m,n, init=False)
mat.rows = rows
return mat
#classmethod
def makeRandom(cls, m, n, low=0, high=10):
""" Make a random matrix with elements in range (low-high) """
obj = Matrix(m, n, init=False)
for x in range(m):
obj.rows.append([random.randrange(low, high) for i in range(obj.n)])
return obj
#classmethod
def makeZero(cls, m, n):
""" Make a zero-matrix of rank (mxn) """
rows = [[0]*n for x in range(m)]
return cls.fromList(rows)
#classmethod
def makeId(cls, m):
""" Make identity matrix of rank (mxm) """
rows = [[0]*m for x in range(m)]
idx = 0
for row in rows:
row[idx] = 1
idx += 1
return cls.fromList(rows)
#classmethod
def readStdin(cls):
""" Read a matrix from standard input """
print 'Enter matrix row by row. Type "q" to quit'
rows = []
while True:
line = sys.stdin.readline().strip()
if line=='q': break
row = [int(x) for x in line.split()]
rows.append(row)
return cls._makeMatrix(rows)
#classmethod
def readGrid(cls, fname):
""" Read a matrix from a file """
rows = []
for line in open(fname).readlines():
row = [int(x) for x in line.split()]
rows.append(row)
return cls._makeMatrix(rows)
#classmethod
def fromList(cls, listoflists):
""" Create a matrix by directly passing a list
of lists """
# E.g: Matrix.fromList([[1 2 3], [4,5,6], [7,8,9]])
rows = listoflists[:]
return cls._makeMatrix(rows)
I'm trying to put a scalar multiplication but it always fail.
For example,
a = [[2,2],[2,3]]
If I multiply it's like, 3*a = [[2,2],[2,3],[2,2],[2,3],[2,2],[2,3]]
How could I fix it?
For example, a = [[2,2],[2,3]] If I multiply it's like, 3*a = [[2,2],[2,3],[2,2],[2,3],[2,2],[2,3]]
Here, a is a list and not a Matrix. You can't overload the multiplication of a standard list by a scalar.
You can't multiply the whole list. The output you got is like a string multiplication.
a="hello"
b=a*3
print b
gives the output as
hellohellohello
That is what happens in your case. Multiply one by one
for i in range(len(a)):
for j in range(len(i)):
a[i][j]*=3

Categories

Resources