How to subsitute symbols in sympyfied expression properly? - python

my goal is to have a string turned into a symbolic expression using sympify and then make substitutions.
import sympy as sp
Eq_Str = 'a*x+b'
Eq_Sym = sp.sympify(Eq_Str)
Then, for instance, substitute a for something else:
Eq_Sym.subs(a,2)
But I get the error:
Traceback (most recent call last):
File "<ipython-input-5-e9892d6ffa06>", line 1, in <module>
Eq_Sym.subs(a,2)
NameError: name 'a' is not defined
I understand that there is no symbol a in the workspace. Am I right?
Is there a way to get the symbols from the set I get from Eq_Sym.free_symbols into the workspace so I can substitute them in Eq_Sym.
Thank you very much for taking the time to read this.

you can use globals() for that:
import sympy as sp
Eq_Str = 'a*x+b'
Eq_Sym = sp.sympify(Eq_Str)
for s in Eq_Sym.free_symbols :
globals()[s.name] = s;
print (Eq_Sym.subs(a,2)); #b + 2*x

Related

CodeError for Functions

Here is the code for my question. I was trying to translate a pseudocode into python. The function, ExCamel, forms a return string, OutString, from a given string,InString,by:
1:Separating the original words(a word is assumed to start with a capital letter)
2:Converting all characters to lower case.
InString=str(input("Enter a statement: "))
def ExCamel(InString):
NextChar=chr()
OutString=str()
n=int()
OutString=""
return OutString
for n in range(1,len(ExCamel(Instring))):
NextChar=InString[n:n+1]
if NextChar==upper(NextChar):
if n>1:
OutString=OutString+""
NextChar=lower(NextChar)
OutString=OutString+NextChar
But it gives an output of:
Traceback (most recent call last):
File "C:/Users/user/PycharmProjects/George/TrynaCreate.py", line 7, in <module>
for n in range(1,len(ExCamel(Instring))):
NameError: name 'Instring' is not defined
This just seems like a silly mistake which happens with most of us:
you have defined
InString
but you are using In's'tring
Hope that helps :)

Creating a TTree with Branches in Using Root through Python

I am trying to create a tree with branches in root through python. I have a .root file and I am trying to create branches that are the variables (or data pts) of my .root file. Here is my attempt:
f = ROOT.TFile('event.root', 'read') #opening the file and creating a file object f
T = ROOT.TTree("T", "simple tree")
#ntuple = ROOT.TNtuple("ntuple","Demo ntuple","px:py:pz:m")
T.Scan("px:py:pz:m")
This just gives me:
Error in TTreeFormula::Compile: Bad numerical expression : “px”
Error in TTreeFormula::Compile: Bad numerical expression : “py”
Error in TTreeFormula::Compile: Bad numerical expression : “pz”
Error in TTreeFormula::Compile: Bad numerical expression : “m”
Row * px * py * pz * m *
which I understand why since I did not define my variables. So I am looking through an example, https://www.niser.ac.in/sercehep2017/notes/RootTutorial_TTree.pdf, (slide 3) and I attempt to define my variable that should be contained in my .root file as:
f = ROOT.TFile('event.root', 'read') #opening the file and creating a file object f
T = ROOT.TTree("T", "simple tree")
px_as_floats = float(px)
py_as_float = float(py)
pz_as_float = float(pz)
m_as_float = float(m)
T.Branch("px",&px,"px/F")
T.Branch("py",&py,"py/F")
T.Branch("pz,&pz,"pz/F")
T.Branch("m",&m,"m/F")
But, I end up with this error:
Traceback (most recent call last):
File “”, line 1, in
File “/mnt/c/1/writeroot.py”, line 17
T.Branch(“px”,&px,“px/F”)
^
SyntaxError: invalid syntax
Is there a way to write this in python? Writing:
T.ROOT.Branch(“px”,&px,“px/F”)
did not work either.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/mnt/c/1/writeroot.py", line 17
T.ROOT.Branch("pt1",&pt1,"pt/F")
^
SyntaxError: invalid syntax
How can I fix the syntax.
Ultimately I am trying to load the dictionary used from the .root file to my tree and then do some calculations on the items in the dictionary.
In other words, how do you extract the dictionary from the .root file?
When I type:
When I type gFile->ls(), I get
TFile** rdata.root
TFile* rdata.root
KEY: TH1F mass;1 masses
KEY: TNtuple tnt;1 tnt
Unless you are trying to make bitwise AND operation, the symobl & is not valid. I assume that you want to send pointer to original variable.
We don't do this in python. If that's the case look up on google for local and global variable.
Tl;dr in python all mutable types are passed by reference
Personally I would have wrote this like:
T.Branch("px",px,"px/F")
T.Branch("py",py,"py/F")
T.Branch("pz", pz,"pz/F")
T.Branch("m",m,"m/F")

Export a matrix with symbolic variables from Matlab to Python

I have a matrix with symbolic variable in MATLAB like this:
syms x
f = [x^2 x^3 x^4];
save ('sym.mat','f')
Thus I saved the f matrix as sym.mat. Now I want to import this matrix into python. So I tried this:
import scipy.io as sio
matrix = sio.loadmat('sym.mat')
sym = matrix['f']
But it didn't work. I got this error, which is just a regular python keyerror.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'f'
However if f is not a symbolic matrix then this code works fine. Any ideas how I can deal with these matrices with symbolic variables?
Scipy can't load MATLAB symbolic variables.
The best way to deal with your problem is to convert your Symbolic matrix into Matrix of chars(not matlab strings since it will cause errors too)
So here is what I mean:
In MATLAB, you can do something like that:
syms x
f = [x^2 x^3 x^4];
for i = 1:numel(f)
if i == 1
f2 = char(f(i));
else
f2 = [f2 ',' char(f(i))];
end
end
save('sym.mat','f2')
This will display:
x^2,x^3,x^4
Now, In python you could do something like that:
import scipy.io as sio
path = 'H:\MatlabScripts'
matrix = sio.loadmat(path + '\sym.mat')
sym = matrix['f2'][0].split(',')
print(sym)
The result will be:
['x^2', 'x^3', 'x^4']

mpmath laplace inverse function in python

I am trying to find the laplace inverse of an expression for which all but one variable are already defined at the time of declaration:
from numpy import *
import mpmath as mp
p0 = 1
E = 2
c= 3
L = 4
x = 2.5
t = linspace(1,5,10)
ulaplace = []
def U(s):
return(c*p0*(-exp(L*s/c) + exp(s*(L + 2*x)/c))*exp(-s*x/c)/(E*s**2*(exp(2*L*s/c) + 1)))
for ti in t:
ulaplace.append(mp.invertlaplace(U, ti, method='talbot'))
But I am getting this error:
Traceback (most recent call last):
File "D:\TEMP\IDLEscripts\CompareAnalyticalSolutions2.py", line 46, in <module>
ulaplace.append(mp.invertlaplace(U, ti, method='talbot'))
File "C:\Python35\lib\site-packages\mpmath\calculus\inverselaplace.py", line 805, in invertlaplace
fp = [f(p) for p in rule.p]
File "C:\Python35\lib\site-packages\mpmath\calculus\inverselaplace.py", line 805, in <listcomp>
fp = [f(p) for p in rule.p]
File "D:\TEMP\IDLEscripts\CompareAnalyticalSolutions2.py", line 43, in U
return(c*p0*(-exp(L*s/c) + exp(s*(L + 2*x)/c))*exp(-s*x/c)/(E*s**2*(exp(2*L*s/c) + 1)))
TypeError: attribute of type 'int' is not callable
I also tried the lambda function format suggested by the doc website but still got the same error.
Does the mpmath.invertlaplace function require that everything be in numerical termsat the time of definition? I am asking because this worked:
>>> import mpmath as mp
>>> def F(s):
return 1/s
>>> mp.invertlaplace(F,5, method = 'talbot')
mpf('1.0')
If so, I need to be able to circumvent this. The whole point for me is to play around with the other variables and see how they affect the inverse laplacian. Furthermore one would think that the function gets evaluated before it is passed on to mpmath.
If not, then what on earth is going on here?
Allright I got it. Basically the function that mp.invertlaplace needs to itself only use mpmath defined functions. In the code provided in the original question I am using exp from the numpy library. So exp(x) is really numpy.exp(x). To make the code work it needs to call the mpmath.exp function as follows:
def U(s):
return -p0*mp.exp(s*x/c)/(E*s*(-s*mp.exp(L*s/c)/c - s*mp.exp(-L*s/c)/c)) + p0*mp.exp(-s*x/c)/(E*s*(-s*mp.exp(L*s/c)/c - s*mp.exp(-L*s/c)/c))
I have not tested the above on the reduced example I provided in the original question, since it is a subset of the more general script. However it should work and this appears to be the root of the problem.

Maximum match length of a regular expression

What is the easiest way to determine the maximum match length of a regular expression?
Specifically, I am using Python's re module.
E.g. for foo((bar){2,3}|potato) it would be 12.
Obviously, regexes using operators like * and + have theoretically unbounded match lengths; in those cases returning an error or something is fine. Giving an error for regexes using the (?...) extensions is also fine.
I would also be ok with getting an approximate upper bound, as long as it is always greater than the actual maximum length, but not too much greater.
Using pyparsing's invRegex module:
import invRegex
data='foo(bar{2,3}|potato)'
print(list(invRegex.invert(data)))
# ['foobarr', 'foobarrr', 'foopotato']
print(max(map(len,invRegex.invert(data))))
# 9
Another alternative is to use ipermute from this module.
import inverse_regex
data='foo(bar{2,3}|potato)'
print(list(inverse_regex.ipermute(data)))
# ['foobarr', 'foobarrr', 'foopotato']
print(max(map(len,inverse_regex.ipermute(data))))
# 9
Solved, I think. Thanks to unutbu for pointing me to sre_parse!
import sre_parse
def get_regex_max_match_len(regex):
minlen, maxlen = sre_parse.parse(regex).getwidth()
if maxlen >= sre_parse.MAXREPEAT: raise ValueError('unbounded regex')
return maxlen
Results in:
>>> get_regex_max_match_len('foo((bar){2,3}|potato)')
12
>>> get_regex_max_match_len('.*')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in get_regex_max_match_len
ValueError: unbounded regex

Categories

Resources