-
Notifications
You must be signed in to change notification settings - Fork 0
/
symbols.py
283 lines (210 loc) · 8.48 KB
/
symbols.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
import sympy as sym
from sympy.abc import s,t
import sympy.integrals as integrals
from sympy.functions import *
import copy
import random
from wiggles.signals import *
import pickle
#Exports Wiggles type signal to a file
def export_wiggles(wiggles_obj, file_path):
with open(file_path, 'wb') as f:
pickle.dump(wiggles_obj, f)
#Imports Wiggles type signal from a file
def import_wiggles(file_path):
with open(file_path, 'rb') as f:
wiggles_obj = pickle.load(f)
return wiggles_obj
#Easily create a symbolic unit_step (Heaviside) in sympy or symbols wiggles format
def unit_step(n):
return Heaviside(n)
#Easily create a symbolic unit_impulse (DiracDelta) in sympy or symbols wiggles format
def unit_impulse(n):
return DiracDelta(n)
#Easily create a symbolic exponential function in sympy or symbols wiggles format
def exp(n):
return sym.exp(n)
#Easily create a symbolic sin function in sympiy or symbols wiggles format
def sin(n):
return symfun.sin(n)
#Easily create a symbolic cos function in sympy or symbols wiggles format
def cos(n):
return symfun.cos(n)
#Useful utility functions to enable addition, sub, etc
class utilities():
def make_name(self):
return random.randint(0,100)
def process(self):
self.expression = sym.expand(self.expression)
self.expression = sym.apart(self.expression)
def expand(self):
self.expression = sym.expand(self.expression)
def apart(self):
self.expression = sym.apart(self.expression)
def __repr__(self):
print(self.expression)
def __str__(self):
return str(self.expression)
def __add__(self,n):
change = copy.deepcopy(self)
change.expression = change.expression+n
return change
def __radd__(self,n):
change = copy.deepcopy(self)
change.expression = n+change.expression
return change
def __pow__(self,n):
change = copy.deepcopy(self)
change.expression = change.expression**n
return change
def __rpow__(self,n):
change = copy.deepcopy(self)
change.expression = n**change.expression
return change
def __sub__(self,n):
change = copy.deepcopy(self)
change.expression = change.expression-n
return change
def __rsub__(self,n):
change = copy.deepcopy(self)
change.expression = n-change.expression
return change
def __mul__(self,n):
change = copy.deepcopy(self)
change.expression = change.expression*n
return change
def __rmul__(self,n):
change = copy.deepcopy(self)
change.expression = n*change.expression
return change
def __truediv__(self,n):
change = copy.deepcopy(self)
change.expression = change.expression/n
return change
def __rtruediv__(self,n):
change = copy.deepcopy(self)
change.expression = n/change.expression
return change
def show(self):
(self.to_continuous()).show()
def compare(self,obj,obj1=None,obj2=None,obj3=None,obj4=None,spacing=None):
if(obj1!=None):
self.to_continuous().compare(obj.to_continuous(),obj1.to_continuous(),spacing)
elif(obj2!=None):
self.to_continuous().compare(obj.to_continuous(),obj1.to_continuous(),obj2.to_continuous(),spacing)
elif(obj3!=None):
self.to_continuous().compare(obj.to_continuous(),obj1.to_continuous(),obj2.to_continuous(),obj3.to_continuous(),spacing)
elif(obj4!=None):
self.to_continuous().compare(obj.to_continuous(),obj1.to_continuous(),obj2.to_continuous(),obj3.to_continuous(),obj4.to_continuous(),spacing)
else:
self.to_continuous().compare(obj.to_continuous(),spacing)
#To easily make equations in time domain
class time_domain(utilities):
#Class variables used for different visual and operational settings
name = ""
#Exports Wiggles type signal to a file
def export_wiggles(self, file_path):
with open(file_path, 'wb') as f:
pickle.dump(self, f)
def __init__(self,func=None,sympy_exp=None,name=chr(random.randint(ord('a'), ord('z')))):
self.name = name
if(sympy_exp==None and func!=None):
self.expression = func(t)
elif(sympy_exp!=None and func==None):
self.expression = sympy_exp
else:
print("Incorect parameters. Either Provide a function or an sympy expression")
def __getitem__(self,key):
return self.evaluate(t,key)
def evaluate(self,variable,value=None):
if value != None:
return sym.N(self.expression.subs(variable,value))
else:
return sym.N(self.expression.subs(variable))
def quick_evaluate(self,key):
return self.evaluate(t,key)
def laplace_transform(self,process=0):
if(process==1):
self.process()
llt = integrals.laplace_transform(self.expression,t,s)
if(type(llt) == tuple):
temp = frequency_domain(sympy_exp=(llt[0]))
temp.residue = llt[1:3]
else:
temp = frequency_domain(sympy_exp=llt)
return temp
def fourier_transform(self,process=0):
if(process==1):
self.process()
llt = integrals.fourier_transform(self.expression,t,s)
if(type(llt) == tuple):
temp = frequency_domain(sympy_exp=(llt[0]))
temp.residue = llt[1:3]
else:
temp = frequency_domain(sympy_exp=llt)
return temp
def to_continuous(self,start=0,stop=1,step=0.001):
change = continuous(func=self.quick_evaluate,start=start,stop=stop,step=step)
change.name = self.name
change.domain = 'frequency'
return change
def solve(self,equals=0):
return sym.solve(self.expression-equals, t)
def poles(self):
return sym.solve((self.expression)**-1, t)
def zeros(self):
return sym.solve(self.expression, t)
def roots(self):
dic = {'zeros':self.zeros(),'poles':self.poles()}
return dic
#To easily make equations in time domain
class frequency_domain(utilities):
#Class variables used for different visual and operational settings
name = ""
#Exports Wiggles type signal to a file
def export_wiggles(self, file_path):
with open(file_path, 'wb') as f:
pickle.dump(self, f)
def __init__(self,func=None,sympy_exp=None,name=chr(random.randint(ord('a'), ord('z')))):
self.name = name
if(sympy_exp==None and func!=None):
self.expression = func(s)
elif(sympy_exp!=None and func==None):
self.expression = sympy_exp
else:
print("Incorect parameters. Either Provide a function or an sympy expression")
def __getitem__(self,key):
return self.evaluate(s,key)
def evaluate(self,variable,value=None):
if value != None:
return sym.N(self.expression.subs(variable,value))
else:
return sym.N(self.expression.subs(variable))
def quick_evaluate(self,key):
return self.evaluate(s,key)
def inverse_laplace_transform(self,process=0):
if(process==1):
self.process()
llt = integrals.inverse_laplace_transform(self.expression,s,t)
temp = time_domain(sympy_exp=llt)
return temp
def inverse_fourier_transform(self,process=0):
if(process==1):
self.process()
llt = integrals.inverse_fourier_transform(self.expression,s,t)
temp = time_domain(sympy_exp=llt)
return temp
def to_continuous(self,start=0,stop=1,step=0.001):
change = continuous(func=self.quick_evaluate,start=start,stop=stop,step=step,name=self.name)
change.xlabel= "frequency"
change.domain = 'frequency'
return change
def solve(self,equals=0):
return sym.solve(self.expression-equals, s)
def poles(self):
return sym.solve((self.expression)**-1, s)
def zeros(self):
return sym.solve(self.expression, s)
def roots(self):
dic = {'zeros':self.zeros(),'poles':self.poles()}
return dic