-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpureTensor.py
140 lines (119 loc) · 5.21 KB
/
pureTensor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import abstractTensor
import tensor
import coefficient
import monomial
import relation
import doublyDefined #TODO: make interface PureTensorable so we can hide all this nonsense in tensor product
class pureTensor(abstractTensor.abstractTensor):
"""
File: pureTensor.py
Author: Chris Campbell
Email: c (dot) j (dot) campbell (at) ed (dot) ac (dot) uk
Github: https://github.com/campbellC
Description: A pureTensor is simply a pure tensor element in a tensor product.
"""
##############################################################################
###### CONSTRUCTORS
##############################################################################
def __init__(self, monomials=(), coeff=coefficient.coefficient(1)):
if type(monomials) not in [list,tuple]:
monomials = (monomials,)
monomials= tuple(monomials)
self.coefficient = coeff
index = 0
while index < len(monomials):
if type(monomials[index]) in [coefficient.coefficient,int,float]:
monomials = monomials[:index] + (monomial.monomial(monomials[index]),) + monomials[index+1:]
index +=1
for i in monomials:
self.coefficient = self.coefficient * i.coefficient
self.monomials = tuple( [x.withCoefficientOf1() for x in monomials])
##############################################################################
###### MATHEMATICAL METHODS
##############################################################################
def isZero(self):
new = self.clean()
if len(new.monomials) == 0:
return True
for mono in new.monomials:
if mono.isZero():
return True
else:
return new.coefficient.isZero()
def clean(self):
"""Cleaning a pure tensors simply makes all components have coefficient one
and makes the coefficient to multiple of all components' coefficients"""
newCoefficient = reduce(lambda x,y: x * y, [x.coefficient for x in self.monomials], self.coefficient)
if newCoefficient.isZero():
return pureTensor()
newMonos = [x.clean() for x in self.monomials]
return pureTensor(tuple(newMonos), newCoefficient)
def __iter__(self):
yield self
def isAddable(self,other):
return self.monomials == other.monomials
def __add__(self,other ):
if other == 0:
return self
new1 = self.clean()
other = other.clean()
if isinstance(other,pureTensor):
if new1.isAddable(other):
if self.isZero():
return other
else:
newCoefficient = new1.coefficient + other.coefficient
return pureTensor(self.monomials,newCoefficient)
else:
return tensor.tensor((new1,other))
else:
return NotImplemented
def __mul__(self,other):
if self.isZero():
return self
newMonos = self.monomials[:-1] + (self.monomials[-1] * other,)
return pureTensor(newMonos,self.coefficient).clean()
def __rmul__(self,other):
if self.isZero():
return self
newMonos = (other * self.monomials[0],) + self.monomials[1:]
return pureTensor(newMonos,self.coefficient).clean()
def degree(self):
return reduce(lambda x,y: x+ y, self.monomials)
def tensorProduct(self,other):
"""Add other as a component(s) on the right of self. e.g. (a|b).tensorProduct(c) = a|b|c"""
if type(other) in [relation.relation,doublyDefined.doublyDefined,coefficient.coefficient, str, float, int, monomial.monomial]:
return self.tensorProduct(pureTensor(other))
if not isinstance(other,pureTensor):
return reduce(lambda x,y: x+y, [self.tensorProduct(z) for z in other], tensor.tensor())
return pureTensor(self.monomials + other.monomials, self.coefficient * other.coefficient)
def subTensor(self,a,b):
return self[a:b]
def __getitem__(self,index):
if isinstance(index,slice):
return pureTensor(self.monomials[index])
return self.monomials[index]
def __len__(self):
return len(self.monomials)
##############################################################################
###### PRINTING AND TYPING
##############################################################################
def __repr__(self): # TODO: add the +1 -1 stuff here.
if self.isZero():
return "0"
else:
if self.coefficient == -1:
return '-' + '|'.join([repr(x) for x in self.monomials])
elif self.coefficient == 1:
return '|'.join([repr(x) for x in self.monomials])
else:
return repr(self.coefficient) + '*' + '|'.join([repr(x) for x in self.monomials])
def toLatex(self):
if self.isZero():
return "0"
else:
coefficientJoiner = '*'
if self.coefficient == -1:
coefficientJoiner = ''
return self.coefficient.toLatex() + coefficientJoiner +'('+ \
'|'.join([i.toLatex() for i in self.monomials])+ ')'