from fractions import Fraction as F
class Matrix:
def __init__(self, rows):
if isinstance(rows, Matrix): rows=rows.tolist()
rows=list(rows)
if rows and not isinstance(rows[0], (list,tuple)): rows=[[v] for v in rows]
self.a=[[F(v) for v in r] for r in rows]
self.rows=len(self.a);self.cols=len(self.a[0]) if self.a else 0
assert all(len(r)==self.cols for r in self.a)
def tolist(self):return [r.copy() for r in self.a]
def __iter__(self):return iter([v for r in self.a for v in r])
def __getitem__(self,key):
if isinstance(key,tuple):
i,j=key
if isinstance(j,slice):return Matrix([self.a[i][j]])
return self.a[i][j]
return list(self)[key]
@property
def T(self):return Matrix(list(map(list,zip(*self.a))))
def col_join(self,B):
assert self.cols==B.cols
return Matrix(self.a+B.a)
def __mul__(self,B):
assert self.cols==B.rows
return Matrix([[sum(self.a[i][k]*B.a[k][j] for k in range(self.cols)) for j in range(B.cols)] for i in range(self.rows)])
def rref(self):
a=self.tolist();pivots=[];row=0
for col in range(self.cols):
candidates=[i for i in range(row,self.rows) if a[i][col]]
if not candidates:continue
p=candidates[0];a[row],a[p]=a[p],a[row];v=a[row][col]
a[row]=[x/v for x in a[row]]
for i in range(self.rows):
if i!=row:
v=a[i][col];a[i]=[x-v*y for x,y in zip(a[i],a[row])]
pivots.append(col);row+=1
if row==self.rows:break
return Matrix(a),pivots
def rank(self):return len(self.rref()[1])
def nullspace(self):
rr,pivots=self.rref();free=[j for j in range(self.cols) if j not in pivots];out=[]
for f in free:
v=[F(0)]*self.cols;v[f]=F(1)
for row,p in enumerate(pivots):v[p]=-rr.a[row][f]
out.append(Matrix(v))
return out
def det(self):
assert self.rows==self.cols
a=self.tolist();d=F(1)
for c in range(self.cols):
ps=[i for i in range(c,self.rows) if a[i][c]]
if not ps:return F(0)
p=ps[0]
if p!=c:a[c],a[p]=a[p],a[c];d=-d
pivot=a[c][c];d*=pivot
for i in range(c+1,self.rows):
f=a[i][c]/pivot
for j in range(c,self.cols):a[i][j]-=f*a[c][j]
return d
def gauss_jordan_solve(self,B):
assert self.rows==B.rows
rr,piv=Matrix([self.a[i]+B.a[i] for i in range(self.rows)]).rref()
assert list(range(self.cols))==[c for c in piv if c<self.cols]
assert all(c<self.cols for c in piv), 'inconsistent system'
return Matrix([rr.a[i][self.cols:] for i in range(self.cols)]),None
def inv(self):
assert self.rows==self.cols
I=Matrix([[int(i==j) for j in range(self.cols)] for i in range(self.rows)])
return self.gauss_jordan_solve(I)[0]
def Rational(a,b=1):return F(a,b)
def zeros(r,c):return Matrix([[0]*c for _ in range(r)])
def ones(r,c):return Matrix([[1]*c for _ in range(r)])
Evidence
algebra.py
Edition and provenance
algebra.py
SHA-256 5ee97feebb041bfd8bf679e44e541c1fd3ca5cf49abc5aa81d8d4fc8ccbff40c
C480–C1634/Research_Cycles/C0932_C1131/evidence/algebra.py
C480–C1634/Research_Cycles/C0932_C1131/prep/structural_transfer/exact_matrix.py
C480–C1634/Research_Cycles/C1132_C1431_Recovered/evidence/algebra.py