Hi! Here is a patch that adds the operation of complex conjugation to GiNaC. On strings of gamma matrices, it acts as hermitian conjugation. On function the default behaviour is to complex conjugate all arguments of the function. A different behaviour can be specified by using a function option. The patch also includes my previous patch to for the expansion of muls and powers, because nobody seems to have read my mail about that yet. Have a nice day, Chris Dams
Hi! On Mon, Dec 08, 2003 at 10:29:37AM +0000, Chris Dams wrote:
The patch also includes my previous patch to for the expansion of muls and powers, because nobody seems to have read my mail about that yet.
I have read it but I'm not satisfied with that patch. Blindly re-expanding results is prohibitively expensive in terms of efficiency. There has to be a more clever way of doing this, and I believe I have found it for power::expand(). I'm currently trying to implement it in a similar way for mul::expand(). Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
Hello, On Wed, 10 Dec 2003, Christian Bauer wrote:
I have read it but I'm not satisfied with that patch. Blindly re-expanding results is prohibitively expensive in terms of efficiency. There has to be a more clever way of doing this, and I believe I have found it for power::expand(). I'm currently trying to implement it in a similar way for mul::expand().
Hmmm, why is that? Building the expanded expression that is a sum of products must in time at least be proportional to the total number of factors in all the products. Checking whether anything can be further expanded should also be take proportional to that time (with a smaller factor), because the factors that occur in this sum of products should have set the flag that indicates that it is already expanded. Perhaps you could gain a little by using that knowledge and skip the call to mul::expandchildren and furthermore skip putting factors in the the non_adds epvector, as is done in mul::expand, after you check that none of the factors contains an add. The latter optimization could be done always, I suppose. But anyways, I do not see big losses nor big gains here. Bye, Chris
Hi! I've put something into CVS that I'm still not fully satisfied with but that appears to work and is faster than the original patch. Comments and suggestions are appreciated... Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
Hello, On Thu, 11 Dec 2003, Christian Bauer wrote:
I've put something into CVS that I'm still not fully satisfied with but that appears to work and is faster than the original patch. Comments and suggestions are appreciated...
chrisd@gamow:~/c++> more test.C #include<iostream> #include<ginac/ginac.h> using namespace std; using namespace GiNaC; int main() { symbol a("a"); symbol b("b"); symbol c("c"); symbol d("d"); ex result=power(sqrt(a+b)+sqrt(c+d),3); cout << result.expand() << endl; return 0; } chrisd@gamow:~/c++> g++ -o test test.C -lginac chrisd@gamow:~/c++> ./test (d+c)^(3/2)+3*(b+a)*sqrt(d+c)+(b+a)^(3/2)+3*sqrt(b+a)*(d+c) Bye, Chris
Hi. Concerning your complex conjugation patch (sorry for the late reply): On Mon, Dec 08, 2003 at 10:29:37AM +0000, Chris Dams wrote:
Here is a patch that adds the operation of complex conjugation to GiNaC. On strings of gamma matrices, it acts as hermitian conjugation. On function the default behaviour is to complex conjugate all arguments of the function. A different behaviour can be specified by using a function option. The patch also includes my previous patch to for the expansion of muls and powers, because nobody seems to have read my mail about that yet.
The digestion of your contribution took a while, because the complex conjugation of some functions (harmonic and multiple polylog) is a bit more involved, and I wanted to think of a solution to this before integrating the patch. In doing so I recognized the following: sin(x).conjugate() gives sin(x) ?! or simpler x.conjugate() gives x ?! if x is symbol. This seems to be a fundamental problem in my view. A possible solution would be not to use a virtual function '.conjugate()', but instead to use a Ginac-function 'ex conjugate(const ex&)', that only evaluates for numerics and gamma matrices. This would also ease my headaches with those polylogs ... Comments, suggestions ? Bye, Jens
Hello, On Tue, 16 Dec 2003, Jens Vollinga wrote:
The digestion of your contribution took a while, because the complex conjugation of some functions (harmonic and multiple polylog) is a bit more involved, and I wanted to think of a solution to this before integrating the patch.
In doing so I recognized the following: sin(x).conjugate() gives sin(x) ?! or simpler x.conjugate() gives x ?! if x is symbol.
This issue is discussed in http://www.ginac.de/lists/ginac-list/msg01354.html and follow-ups. An alternative to assuming all symbols to be real would be to have a global map (perhaps attached to the class symbol) that maps symbols to their complex conjugates.
This seems to be a fundamental problem in my view. A possible solution would be not to use a virtual function '.conjugate()', but instead to use a Ginac-function 'ex conjugate(const ex&)', that only evaluates for numerics and gamma matrices. This would also ease my headaches with those polylogs ...
I must say I am totally new to polylogs. Looking at their definition, I notice that they have a convergence radius of 1. Also the documentation says that they can only be evaluated numerically for arguments x_i with |x_i|<1. I only see problems for complex conjugation at branch cuts for |x|>1 (and only at the real axis I would guess). This is the same problem that was discussed in the aforementioned thread for the log. Therefore I still think that complex conjugating arguments would be best for these functions, or do you know of other problems with cc-ing these functions? Good day, Chris
Hi. On Thu, Dec 18, 2003 at 01:38:01PM +0000, Chris Dams wrote:
Hello,
On Tue, 16 Dec 2003, Jens Vollinga wrote:
The digestion of your contribution took a while, because the complex conjugation of some functions (harmonic and multiple polylog) is a bit more involved, and I wanted to think of a solution to this before integrating the patch.
In doing so I recognized the following: sin(x).conjugate() gives sin(x) ?! or simpler x.conjugate() gives x ?! if x is symbol.
This issue is discussed in http://www.ginac.de/lists/ginac-list/msg01354.html and follow-ups. An alternative to assuming all symbols to be real would be to have a global map (perhaps attached to the class symbol) that maps symbols to their complex conjugates.
Oops. Read the mails once, but forgot about it in the meantime ;-)
I must say I am totally new to polylogs. Looking at their definition, I notice that they have a convergence radius of 1. Also the documentation says that they can only be evaluated numerically for arguments x_i with |x_i|<1. I only see problems for complex conjugation at branch cuts for |x|>1 (and only at the real axis I would guess). This is the same problem that was discussed in the aforementioned thread for the log. Therefore I still think that complex conjugating arguments would be best for these functions, or do you know of other problems with cc-ing these functions?
Only harmonic and multiple polylogs take some knowledge to conjugate, the other polylogs could use the default behaviour. Harmonic polylogs can be evaluated everywhere now, so they would need the knowledge of how to cconj themselves. But I admit that this not a argument in favour of or against any implementation of cconj. Probably nobody uses these functions at the moment and there would/will be enough time to think about the mathematics of those certain functions. Style and execution speed don't matter either, I think. The crucial points in my opinion are: - The basic idea to give the user the obligation to subsitute the symbols afterwards is not so good (bad). It is counter-intuitive and asks for users to delve into debugging sessions. Functions (C++) with input parameters using cconj would have to extent their parameter list for cconj-symbols. What about an expression x+abs(x) if x is a symbol? How to substitute? (maybe this example is not so well devised, but it makes you feel that there could appear problems in similar cases...) - The way you proposed to do the cconj (in patch) is good, because every function can care about its cconj for itself. Ginac doesn't need to know about every new function a user might want to implement (impossible!). (Not an important argument: on top of that, with a Ginac-function you could nicely do cconj(cconj(x)) -> x and have a latex output for cconj(x) as x^*). Maybe all of this can be taken into account by the following approach: - Every class has a (private) method for cconj and there are macros for the Ginac-function. This is basically your patch. - There exists a Ginac-function cconj (or different name?). It evaluates by calling the (private) cconj methods. If (by a not yet specified way) the method signals, that it could cconj correctly, the Ginac-cconj is replaced by the result, otherwise Ginac-cconj remains unevaluated. That should give for symbol x("x"); ex a = sin(x) + 3 + 4*I - sin(2/3*I); cout << cconj(a) << endl; something like sin(cconj(x)) + 3 - 4*I - sin(-2/3*I) Bye, Jens
On Thu, 18 Dec 2003, Jens Vollinga wrote: [...]
Only harmonic and multiple polylogs take some knowledge to conjugate, the other polylogs could use the default behaviour. Harmonic polylogs can be evaluated everywhere now, so they would need the knowledge of how to cconj themselves.
Now I'm confused. Aren't those harmonic and multiple polylogs analytic?
Maybe all of this can be taken into account by the following approach: - Every class has a (private) method for cconj and there are macros for the Ginac-function. This is basically your patch. - There exists a Ginac-function cconj (or different name?). It evaluates by calling the (private) cconj methods. If (by a not yet specified way) the method signals, that it could cconj correctly, the Ginac-cconj is replaced by the result, otherwise Ginac-cconj remains unevaluated.
That should give for symbol x("x"); ex a = sin(x) + 3 + 4*I - sin(2/3*I); cout << cconj(a) << endl; something like sin(cconj(x)) + 3 - 4*I - sin(-2/3*I)
Looks good. Those private cconj methods could be elegnatly hooked at compile time, alike to what Cebix did with the print functions, I assume? Regards -richy. -- Richard B. Kreckel <Richard.Kreckel@GiNaC.DE> <http://www.ginac.de/~kreckel/>
Hello, On Thu, 18 Dec 2003, Richard B. Kreckel wrote:
On Thu, 18 Dec 2003, Jens Vollinga wrote: [...]
Only harmonic and multiple polylogs take some knowledge to conjugate, the other polylogs could use the default behaviour. Harmonic polylogs can be evaluated everywhere now, so they would need the knowledge of how to cconj themselves.
Now I'm confused. Aren't those harmonic and multiple polylogs analytic?
Me confused too.
Maybe all of this can be taken into account by the following approach: - Every class has a (private) method for cconj and there are macros for the Ginac-function. This is basically your patch. - There exists a Ginac-function cconj (or different name?). It evaluates by calling the (private) cconj methods. If (by a not yet specified way) the method signals, that it could cconj correctly, the Ginac-cconj is replaced by the result, otherwise Ginac-cconj remains unevaluated.
That should give for symbol x("x"); ex a = sin(x) + 3 + 4*I - sin(2/3*I); cout << cconj(a) << endl; something like sin(cconj(x)) + 3 - 4*I - sin(-2/3*I)
Looks good. Those private cconj methods could be elegnatly hooked at compile time, alike to what Cebix did with the print functions, I assume?
Do not know how it is with you, but almost all of the symbols I use are supposed to stand for something real. Having cconj(x) in a result is strange if I know that x is real (and having to do .subs(lst(cconj(x)==x,cconj(y)==y,...)) after a conjugation is at least as awkward as my original proposal of having the user use a list of the form {a==astar,astar==a,etc}). Is there anything wrong with each symbol containing a boolean that says whether it is real? You could then have the evaluation cconj(x) -> x for real symbols. Bye, Chris
Hi. On Fri, Dec 19, 2003 at 08:05:26PM +0100, chrisd@sci.kun.nl wrote:
On Thu, 18 Dec 2003, Richard B. Kreckel wrote:
On Thu, 18 Dec 2003, Jens Vollinga wrote: [...]
Only harmonic and multiple polylogs take some knowledge to conjugate, the other polylogs could use the default behaviour. Harmonic polylogs can be evaluated everywhere now, so they would need the knowledge of how to cconj themselves.
Now I'm confused. Aren't those harmonic and multiple polylogs analytic?
Me confused too.
I was confused. But now I am not confused anymore. Of course it is analytic and that`s it. What confused me is a bug in the 1/x transformation of the harmonic function in CVS HEAD. It gives wrong results for arguments with positive imaginary part in some cases. I have to debug that. It is probably a good idea to integrate this cconj into the checks and exams of the polylogs ... ;-) Concerning the substitution of cconj(x) with x, if x is a symbol known to be real, I agree with you. It looks like a waste of time. Bye, Jens
Salam On Fri, 19 Dec 2003 chrisd@sci.kun.nl wrote:
Do not know how it is with you, but almost all of the symbols I use are supposed to stand for something real. Having cconj(x) in a result is strange if I know that x is real (and having to do .subs(lst(cconj(x)==x,cconj(y)==y,...)) after a conjugation is at least as awkward as my original proposal of having the user use a list of the form {a==astar,astar==a,etc}). Is there anything wrong with each symbol containing a boolean that says whether it is real? You could then have the evaluation cconj(x) -> x for real symbols.
One remark. Maybe you all are aware of it but it was not spelled out in this thread (yet). We've always had the assumption of all symbols representing something complex by default in the backs of our minds. And I think this should not be changed. However, if the user wants to tell the system a bit more about a symbol's domain and the system can put that knowledge into use, that would be Just Fine (tm). Just consider the (in-)famous log(exp(x)) example. We do not let the anonymous evaluator simplify that to x. The reason is log() not being a single-valued function -- log(exp(42.0*I)) != 42.0*I. However, we do evaluate exp(log(x)) -> x anomymously because that is correct in the whole complex domain. If a flag saying "I am real" would be attached to some symbol x we could have a look into the pseudofunction evaluation routines and allow log(exp(x)) -> x. And many many others, too. Cheers -richy. -- Richard B. Kreckel <Richard.Kreckel@GiNaC.DE> <http://www.ginac.de/~kreckel/>
participants (5)
-
Chris Dams
-
chrisd@sci.kun.nl
-
Christian Bauer
-
Jens Vollinga
-
Richard B. Kreckel