2018-10-02 21:24:06 +08:00
|
|
|
''' mbinary
|
|
|
|
#########################################################################
|
|
|
|
# File : vector_norm.py
|
|
|
|
# Author: mbinary
|
|
|
|
# Mail: zhuheqin1@gmail.com
|
2019-01-31 12:09:46 +08:00
|
|
|
# Blog: https://mbinary.xyz
|
2018-10-02 21:24:06 +08:00
|
|
|
# Github: https://github.com/mbinary
|
|
|
|
# Created Time: 2018-10-02 21:14
|
|
|
|
# Description:
|
|
|
|
#########################################################################
|
|
|
|
'''
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
from random import randint, random
|
2018-10-02 21:24:06 +08:00
|
|
|
import numpy as np
|
2020-04-15 12:28:20 +08:00
|
|
|
from operator import neg, and_
|
2018-10-02 21:24:06 +08:00
|
|
|
from functools import reduce
|
|
|
|
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
class obj():
|
|
|
|
def __init__(self, data):
|
|
|
|
self.data = np.array(data)
|
|
|
|
|
|
|
|
def __add__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
2018-10-02 21:24:06 +08:00
|
|
|
return self.__class__(self.data + data)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def __radd__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
|
|
|
return self.__class__(data + self.data)
|
|
|
|
|
|
|
|
def __iadd__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
2018-10-02 21:24:06 +08:00
|
|
|
self.data += data
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def __mul__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
2018-10-02 21:24:06 +08:00
|
|
|
return self.__class__(self.data * data)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def __imul__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
2018-10-02 21:24:06 +08:00
|
|
|
self.data *= data
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def __rmul__(self, x):
|
|
|
|
data = x.data if self.__class__ == x.__class__ else x
|
2018-10-02 21:24:06 +08:00
|
|
|
return self.__class__(data * self.data)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def __neg__(self):
|
|
|
|
return neg(self)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def __abs__(self):
|
|
|
|
return abs(self.data)
|
|
|
|
'''
|
|
|
|
@property
|
|
|
|
def data(self):
|
|
|
|
return self.data
|
|
|
|
@data.setter
|
|
|
|
def data(self,s):
|
|
|
|
self.data = s
|
|
|
|
'''
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def norm(self, n=0):
|
2018-10-02 21:24:06 +08:00
|
|
|
'''the default is +oo norm'''
|
|
|
|
absolute = abs(self.data)
|
2020-04-15 12:28:20 +08:00
|
|
|
if n < 1:
|
|
|
|
return max(absolute)
|
2018-10-02 21:24:06 +08:00
|
|
|
return (sum(absolute**n))**(1/n)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def hasNorm(self):
|
|
|
|
'''check norm's three necessary conditions:
|
|
|
|
1. not neg
|
|
|
|
2. homogenious (qici)
|
|
|
|
3. triangle inequlity
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
there is much probably wrong
|
|
|
|
'''
|
2020-04-15 12:28:20 +08:00
|
|
|
bl = reduce(and_, [self.norm(i) >= 0 for i in range(3)])
|
2018-10-02 21:24:06 +08:00
|
|
|
if bl:
|
2020-04-15 12:28:20 +08:00
|
|
|
n = randint(2, 100)
|
|
|
|
bl = reduce(and_, [n*(self.norm(i)) == (n*self).norm(i)
|
|
|
|
for i in range(3)])
|
2018-10-02 21:24:06 +08:00
|
|
|
if bl:
|
2020-04-15 12:28:20 +08:00
|
|
|
another = self*randint(2, 10)-randint(1, 100)
|
|
|
|
return reduce(and_, [(another+self).norm(i) <= another.norm(i)+self.norm(i) for i in range(3)])
|
2018-10-02 21:24:06 +08:00
|
|
|
return False
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
class vector(obj):
|
2020-04-15 12:28:20 +08:00
|
|
|
def __init__(self, arr):
|
2018-10-02 21:24:06 +08:00
|
|
|
''' arr: iterable'''
|
2020-04-15 12:28:20 +08:00
|
|
|
self.data = np.array(arr)
|
|
|
|
|
|
|
|
def innerProduct(self, x):
|
2018-10-02 21:24:06 +08:00
|
|
|
return sum(self.data*x)
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def outerProduct(self, x):
|
2018-10-02 21:24:06 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class matrix(obj):
|
2020-04-15 12:28:20 +08:00
|
|
|
def __init__(self, s):
|
2018-10-02 21:24:06 +08:00
|
|
|
'''s is a list of lists'''
|
2020-04-15 12:28:20 +08:00
|
|
|
self.data = np.mat(s)
|
2018-10-02 21:24:06 +08:00
|
|
|
self.T = None
|
|
|
|
self. I = None
|
|
|
|
'''
|
|
|
|
@property
|
|
|
|
def T(self):
|
|
|
|
if self.T==None:self.T = self.data.T
|
|
|
|
return self.T
|
|
|
|
@T.setter
|
|
|
|
def T(self,s):
|
|
|
|
self.T = s
|
|
|
|
@property
|
|
|
|
def I(self):
|
|
|
|
if self.I == None: self.I = self.data.I
|
|
|
|
return self.I
|
|
|
|
|
|
|
|
@I.setter
|
|
|
|
def I(self,s):
|
|
|
|
self.I = s
|
|
|
|
'''
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
def E(self, n=None):
|
|
|
|
if n is None:
|
|
|
|
n = self.data.shape[0]
|
2018-10-02 21:24:06 +08:00
|
|
|
return np.eye(n)
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
def norm(self, n=0):
|
|
|
|
absolute = abs(self.data)
|
2018-10-02 21:24:06 +08:00
|
|
|
if n < 1:
|
|
|
|
# max of one row sum
|
|
|
|
return max([sum(i) for i in absolute])
|
2020-04-15 12:28:20 +08:00
|
|
|
if n == 1:
|
|
|
|
return self.norm1()
|
|
|
|
elif n == 2:
|
|
|
|
return self.norm2()
|
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def norm1(self):
|
|
|
|
''' max of sum of cols'''
|
|
|
|
absolute = abs(self.data)
|
2020-04-15 12:28:20 +08:00
|
|
|
return max(absolute.sum(axis=0))
|
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def norm2(self):
|
|
|
|
''' max of sum of rows'''
|
|
|
|
absolute = abs(self.data)
|
|
|
|
return max(absolute.sum(axis=1))
|
2020-04-15 12:28:20 +08:00
|
|
|
|
2018-10-02 21:24:06 +08:00
|
|
|
def norm_f(self):
|
|
|
|
return sum((self.data**2).sum(axis=1))**0.5
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
v1 = vector([1, -2, 3, 4])
|
|
|
|
v2 = vector([0, 2, 0, 5])
|
|
|
|
m1 = matrix([v1, v2, v2, v1])
|
2018-10-02 21:24:06 +08:00
|
|
|
print([v1.norm(i) for i in range(3)])
|