On Sat, Nov 22, 2014 at 7:23 AM, Bill Page <bill.p...@newsynthesis.org> wrote: > On 21 November 2014 at 20:18, Ondřej Čertík <ondrej.cer...@gmail.com> wrote: >> >> I am still confused about one thing: is this issue is already >> present in FriCAS before your changes? Because you can >> already use conjugate, sin, +, *, ..., even without defining the >> derivative for abs(x). I fail to see how defining the abs(x).diff(x) >> in the way you did it can introduce issues that weren't present >> in the first place. >> > > FriCAS currently does not implement a symbolic 'conjugate' operator. > The issue concerns whether adding 'conjugate' is a good idea and only > secondly how to differentiate it.
Ah, I had no idea that FriCAS does not implement conjugate(x). How do you handle complex numbers then? In SymPy and Sage, conjugate(x) is in it, so then adding a derivative of abs(x) does not make things worse. > >> ----- >> >> I have finished the writeup, it starts here (you might want to refresh >> your browser to see the latest changes): >> >> http://www.theoretical-physics.net/dev/math/complex.html#complex-conjugate >> >> and it was implemented with these two PRs: >> >> https://github.com/certik/theoretical-physics/pull/39 >> https://github.com/certik/theoretical-physics/pull/40 >> > > Thanks. > >> I must say one thing that I like about the "theta" is that it tells >> you immediately if the function is analytic or not (if theta is >> present it is not, if it is not present, then the expression does not >> depend on theta, and thus is analytic). For example, for log(z), >> the theta cancels, and so the result 1/z is analytic. >> > > Still looks ugly to me. > >> I found a bug in these results from FriCAS: >> >>> (4) -> D(abs(f(x)),x) >>> >>> , _ _ , >>> f(x)f (x) + f(x)f (x) >>> >>> (4) --------------------- >>> 2abs(f(x)) >>> Type: >>> Expression(Integer) >>> (5) -> D(abs(log(x)),x) >>> >>> _ _ >>> xlog(x) + x log(x) >>> (5) ------------------ >>> _ >>> 2xxabs(log(x)) >>> Type: >>> Expression(Integer) >> >> The bar must be over the whole f(x) as well as log(x), because >> conjugate(log(x)) is only equal log(conjugate(x)) if x is not >> negative real number. > > In FriCAS with my patch functions defined by > > f := operator 'f > > are currently assume to be holomorphic and log is holomorphic by definition so > > conjugate(log(x)) = log(conjugate(x)) > > Perhaps you are considering the wrong branch. > >> See the example here: >> http://www.theoretical-physics.net/dev/math/complex.html#id1 where I >> have it explicitly worked out. You can also check that easily in >> Python: >> >> In [1]: from cmath import log >> >> In [2]: x = -1+1j >> >> In [3]: log(x).conjugate() >> Out[3]: (0.34657359027997264-2.356194490192345j) >> >> In [4]: log(x.conjugate()) >> Out[4]: (0.34657359027997264-2.356194490192345j) >> >> In [5]: x = -1 >> >> In [6]: log(x).conjugate() >> Out[6]: -3.141592653589793j >> >> In [7]: log(x.conjugate()) >> Out[7]: 3.141592653589793j >> >> In [8]: log(x.conjugate()) - 2*pi*1j >> Out[8]: -3.141592653589793j >> >> >> Where [3] and [4] are equal, but [6] and [7] are not (you need to >> subtract 2*pi*i from [7], as in [8], in order to recover [6], >> consistent with the formula in the writeup). >> > > Complex 'log' is a multi-valued like 'sqrt' so you need to consider > more than one branch. Well, you are right that in theory you define log(z) as log(z)=log|z|+i*arg(z), and you define arg(z) as multivalued, i.e. you can add 2*pi*n to it, then you can add 2*pi*i*n to log(z). Since [6] and [7] differs by 2*pi*i, they are indeed the same number. However, this definition quickly becomes impractical, because you need to be able to numerically evaluate symbolic expressions, and you would need to carry the symbolic term 2*pi*i*n around. This multivalued approach has always been very confusing to me. But it is a valid approach (i.e. see http://en.wikipedia.org/wiki/Riemann_surface), so let's call this is an approach (A). The other approach, let's call it approach (B), is that languages like Fortran, C, Python, and CAS like Mathematica, SymPy, Sage all pick a branch cut, and all of them (as far as I know) pick it along the negative real axis. For this example I think it doesn't matter where you choose the branch cut, as the conjugate of log(-1) simply flips the sign of it, so it won't be equal to log(-1) anymore. In this approach you need to carry the corrections for branch cuts. Some examples of identities valid in each approach: (A) conjugate(log(z)) = log(conjugate(z)) (B) conjugate(log(z)) = log(conjugate(z)) -2*pi*i*floor((arg(z)+pi)/(2*pi)) or (A) log(a*b) = log(a) + log(b) (B) log(a*b) = log(a) + log(b) + 2*pi*i*floor((pi-arg(a)-arg(b))/(2*pi)) And so on. I have written a Python script to check many of these identities in (B), available here: http://www.theoretical-physics.net/dev/math/complex.html#testing-identities-using-computer-code and it works like a charm, i.e. those identities are valid for any complex numbers. On that page, I have also derived those identities step by step, i.e. you simply define arg(z) = atan2(Im z, Re z) and go from there, the floor() function comes from properties of the atan2() function. I don't think you can mix and match (A) with (B). You have to make a decision and be consistent everywhere. Bill, why don't you check if FriCAS is using approach (A) or (B)? This is very simple to do, simply check the left hand side and right hand side of any of these identities in (A). Since as you said, FriCAS doesn't support conjugate(), just use the log(a*b) case. Here is how you can check this in Python: >>> from cmath import log >>> a = -1 >>> b = -1 >>> log(a*b) 0j >>> log(a)+log(b) 6.283185307179586j So you can see that the left hand side log(a*b) does not equal the right hand side log(a)+log(b), so Python is using the approach (B). You can see the script above, where I check this, but for clarity, let's just verify that the (B) formula works in Python for this particular case: >>> def arg(x): return log(x).imag ... >>> from math import floor, pi >>> I = 1j >>> log(a)+log(b)+2*pi*I*floor((pi-arg(a)-arg(b))/(2*pi)) 0j I would assume that FriCAS is also using the approach (B), and thus conjugate(log(z)) is not equal to log(conjugate(z)), but let's wait until what you find. Ondrej -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.