Skip to content

Commit

Permalink
Merge pull request #2 from Xanonymous-GitHub/release-1.1.3
Browse files Browse the repository at this point in the history
more convenient support
  • Loading branch information
Xanonymous-GitHub authored Mar 10, 2020
2 parents fbf6c92 + 4f035fc commit e857d8d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 37 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ print(my_matrix.inverse)
[-2, 1]
[1.5, -0.5]

#special use by '**' power operator:
print(my_matrix ** -1)
#result:
[-2, 1]
[1.5, -0.5]

my_matrix2 = Mx.Matrix("1,2,3;4,5,6;7,8,9")

print(my_matrix2)
Expand Down Expand Up @@ -183,4 +189,4 @@ print(i)
[1, 0, 0]
[0, 1, 0]
[0, 0, 1]
```
```
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="xmatrix",
version="1.1.2",
version="1.1.3",
author="Xanonymous",
author_email="[email protected]",
description="Help you calculate matrix.",
Expand Down
81 changes: 46 additions & 35 deletions xmatrix/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
More style details on:https://www.python.org/dev/peps/pep-0008
"""

from math import isclose


class Matrix:
"""Define the Matrix class"""
Expand Down Expand Up @@ -59,12 +61,7 @@ def __sub__(self, other):
def __mul__(self, other):
if isinstance(other, int):
# method accept single integer to be calculated.
new = list()
for i, x in enumerate(self.__storage):
new_tmp = list()
for _, y in enumerate(x):
new_tmp.append(y)
new.append(new_tmp)
new = self.__make_copy(self.__storage)
return Matrix(self.__rate(new, other))
# If the matrices cannot be multiplied, throw an error.
resource = other.raw
Expand All @@ -77,7 +74,7 @@ def __mul__(self, other):
return
# if the second matrix is an identity_matrix, the answer will be the same as first matrix.
if self.is_unit_matrix(resource):
new = self.__storage[:].copy()
new = self.__make_copy(self.__storage)
return Matrix(new)
new = list()
for i, x in enumerate(self.__storage):
Expand All @@ -94,9 +91,10 @@ def __rmul__(self, other):
return self.__mul__(other)

def __pow__(self, power: int, modulo=None):
# if self is an identity matrix or power assign 1, than return self.
if self.is_unit_matrix(self.__storage) or power == 1:
new = self.__storage[:].copy()
return Matrix(new)
return Matrix(self.__make_copy(self.__storage))
# if power == 0, than return identity matrix.
if not power:
n = len(self.__storage)
tmp_n = n
Expand All @@ -110,61 +108,55 @@ def __pow__(self, power: int, modulo=None):
tmp.insert(0, tmp_tmp)
tmp_n -= 1
return Matrix(tmp)
# if the matrix is not a square or invalid, return error.
if not len(self.__storage) == len(self.__storage[0]):
self.__error_handler("Unable to calculate power, not square.")
return
tmp = Matrix(self.__storage[:].copy())
# if the power < 0, recursive the positive power by self inverse.
tmp = Matrix(self.__make_copy(self.__storage))
if power < 0:
tmp = tmp.inverse
if tmp is not None:
return tmp ** (power * -1)
return self.__error_handler("Unable to calculate power, determinant is zero.")
# calculate the positive power value of this matrix.
for x in range(power - 1):
self.__storage = self.__mul__(tmp).raw
new = self.__storage[:].copy()
self.__storage = tmp.raw[:].copy()
new = self.__make_copy(self.__storage)
self.__storage = self.__make_copy(tmp.raw)
return Matrix(new)

def __eq__(self, other):
return other.raw == self.__storage

@property
def inverse(self):
def make_new(old):
new_thing = list()
for _, xx in enumerate(old):
new_tmp = list()
for _, yy in enumerate(xx):
new_tmp.append(yy)
new_thing.append(new_tmp)
return new_thing

determinant = self.__determinant(self.__storage)
if not determinant:
self.__error_handler("The determinant is zero, can't be inverse.")
return
new = self.__make_copy(self.__storage)
if len(self.__storage) == 1:
new = make_new(self.__storage[:].copy())
new[0][0] = new[0][0] ** -1
return Matrix(new)
if len(self.__storage) == 2:
new = make_new(self.__storage[:].copy())
new[0][0], new[1][1] = new[1][1], new[0][0]
new[0][1] *= -1
new[1][0] *= -1
new = self.__rate(new, 1 / determinant)
return Matrix(new)
return Matrix(self.__rate(new, 1 / determinant))
ans = list()
new = make_new(self.__storage[:].copy())
for i, x in enumerate(self.__storage):
ans_tmp = list()
for j, y in enumerate(x):
h = (-1 if i % 2 else 1) * (-1 if j % 2 else 1)
ans_tmp.append(h * self.__determinant(self.__get_ans_range(i, j, new)))
ans.append(ans_tmp)
ans = self.__transpose(ans)
new = self.__rate(ans, 1 / determinant)
return Matrix(new)
return Matrix(self.__rate(ans, 1 / determinant))

@property
def transpose(self):
new = self.__storage[:].copy()
return Matrix(self.__transpose(new))
return Matrix(self.__transpose(self.__make_copy(self.__storage)))

def __determinant(self, r) -> int or float:
if not self.__valid(r):
Expand Down Expand Up @@ -198,19 +190,22 @@ def raw(self) -> list:
# get the real value of the object
return self.__storage

@staticmethod
def __pretty(r) -> str:
# Detect if the value can be an integer.
def __pretty(self, r) -> str:
# Detect if the value can be more short.
for i, x in enumerate(r):
for j, y in enumerate(x):
if abs(r[i][j] - int(r[i][j])) < 10 ** -3:
# try to turn the data to integer.
if abs(r[i][j] - int(r[i][j])) < 10 ** -4:
r[i][j] = int(r[i][j])
# the max floating point length in python is 16 so we use 15 to calculate.
if isinstance(r[i][j], float):
r[i][j] = self.__get_near_number(r[i][j], 15)
# format the value then return
return '\n'.join(map(str, r)) + '\n'

@staticmethod
def __error_handler(msg):
print(msg)
return print(msg)

@staticmethod
def __transpose(resource: list) -> list:
Expand Down Expand Up @@ -252,6 +247,22 @@ def __magnification_iteration(r: list, rate) -> list:
r[i][0] *= rate
return r

@staticmethod
def __make_copy(old: list) -> list:
new = list()
for _, x in enumerate(old):
new_tmp = list()
for _, y in enumerate(x):
new_tmp.append(y)
new.append(new_tmp)
return new

# find the max nearly round number of the float value.
def __get_near_number(self, data: float, pos: int) -> int or float:
if not isclose(data, round(data, pos), rel_tol=1e-4):
return round(data, pos + 1)
return self.__get_near_number(data, pos - 1)


class UnitMatrix(Matrix):
def __init__(self, n):
Expand Down

0 comments on commit e857d8d

Please sign in to comment.