In essence what I want to do is take the absolute value of a complex number that has a parameter both in real and imaginary parts and derive that in respect to that parameter. I then want to know for which value of that parameter the derivative is zero. So essentially I want to know Min/Max of the absolute value of a complex number with parameters.
I've encountered a problem in using sympy and don't quite know how to fix it/if its a problem at their end. Before I report it as bug I wanted to ask here. Ok so this is essentially what I want to do (the implementation is a bit more complex but the errors are the same)
0 import sympy
1 import mpmath
2 sympy.init_printing() # enable pretty printing
3 a,b = sympy.symbols("a,b") # a and b are symbols a and b
4 c = a+ 1j*b # complex number a+ib
5 d = sympy.Abs(c) # absolute value of c
6 e = d.diff(b,1) # derive d in respect to b one time
7 f = sympy.lambdify(b,e) # lambdify e with b as parameter
8 g = mpmath.findroot(f,0) # find root of f starting at 0
The error occurs in line 8 but because of f
. Calling f
with f(1)
for example yields the same error. The error is:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <lambda>
NameError: name 'Derivative' is not defined
I got the whole thing working but only if I wrote methods for stuff like the absolute value myself and avoided using the sympy functions. So for example
d = (sympy.re(c)**2 + sympy.im(c)**2)**0.5
worked fine but
d = sympy.sqrt(sympy.re(c)**2 + sympy.im(c)**2)
gave me an Error. That Error was essentially the same one as the one I describe next but with Sqrt
in place of the Add
.
It would be fine with me writing those methods myself but since the function is dynamically built at runtime(It's an electrical engineering toolbox) it's not a possibility to simply plug the stuff in; I have to rely on sympy.
I also got a Error that was something along the lines of:
Add doesn't contain Derivative Attribute.
which essentially meant that the complex number is an instance of the Add
class of sympy and that doesn't have an differentiation method, but I can't get that to reproduce as of now.
Printing e.subs(a,5).subs(b,1)
also shows that it doesn't substitute a
and b
inside the Derivative()
.
Sorry that some things are a bit vague, I originally troubleshot the whole thing yesterday and forgot to save the code. If the whole thing is not an Error in Sympy but rather a mistake on my part I sincerly apologise and would love to get pointed in the direction of how it's done properly.
The whole thing is run under Anaconda 5.1.0 and debugged/managed in Visual Studio. In case you're interested in my exact implementation the project is hosted at https://github.com/SV-97/iphipy
The interesting files are Systems.py and Main.py
This is what the lines 3-4 should have been
a, b = sympy.symbols("a, b", real=True) # a and b are REAL symbols a and b
c = a + I*b
By default, a
and b
are allowed to be complex numbers, which makes the computation of Abs(a+I*b)
messy, and the differentiation of that with respect to b
mathematically dubious.
Also, 1j
is a Python float, while I
is a SymPy object; use the latter in symbolic expressions.
Now e
will be computed as b/sqrt(a**2 + b**2)
. But there is nothing that mpmath.findroot
can do with this expression, given that it contains a symbol a
, and mpmath.findroot
is a numeric solver.
sympy.solve(e, b)
does return an answer, [0]
. Of course you may need a numeric solver in more complicated situations; but then make sure that everything except for the variable(s) being solved for has a numeric value.