From chrisd at sci.kun.nl Tue Dec 2 15:26:20 2003 From: chrisd at sci.kun.nl (Chris Dams) Date: Tue, 2 Dec 2003 14:26:20 +0000 (UTC) Subject: patch for expand. Message-ID: Hello everybody, I found out that calling the expand() method on an expression like (d*sqrt(a+b)+a*sqrt(c+d))*(b*sqrt(a+b)+a*sqrt(c+d)) results in sqrt(b+a)*b*sqrt(d+c)*a+(d+c)*a^2+d*(b+a)*b+d*sqrt(b+a)*sqrt(d+c)*a This result could be further expanded. A patch that is supposed to make this happen is attached. Best regards, Chris -------------- next part -------------- =================================================================== RCS file: /home/cvs/GiNaC/ginac/mul.cpp,v retrieving revision 1.79 diff -r1.79 mul.cpp 920c920 < setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); --- > setflag(status_flags::dynallocated)); 922,923c922 < return ((new add(distrseq))-> < setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); --- > return ex((new add(distrseq))->setflag(status_flags::dynallocated)).expand(); Index: ncmul.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/power.cpp,v retrieving revision 1.88 diff -r1.88 power.cpp 760,761c760 < return (new add(result))->setflag(status_flags::dynallocated | < status_flags::expanded); --- > return ex((new add(result))->setflag(status_flags::dynallocated)).expand(); 828c827 < return (new add(sum))->setflag(status_flags::dynallocated | status_flags::expanded); --- > return ex((new add(sum))->setflag(status_flags::dynallocated)).expand(); From kiat_trakul at yahoo.com Tue Dec 2 19:16:48 2003 From: kiat_trakul at yahoo.com (SOMKIAT TRAKULTRAIPRUK) Date: Tue, 2 Dec 2003 10:16:48 -0800 (PST) Subject: want to know about gamma function Message-ID: <20031202181648.75887.qmail@web60207.mail.yahoo.com> How to prove that gamma(3x) = 1/2pi * 3^(2x-1/2) * gamma(x) * gamma(x+1/3) * gamma(x+2/3) Thanks. --------------------------------- Do you Yahoo!? Free Pop-Up Blocker - Get it now -------------- next part -------------- An HTML attachment was scrubbed... URL: From chrisd at sci.kun.nl Mon Dec 8 11:29:37 2003 From: chrisd at sci.kun.nl (Chris Dams) Date: Mon, 8 Dec 2003 10:29:37 +0000 (UTC) Subject: complex conjugation Message-ID: 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 -------------- next part -------------- Index: ginac/basic.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/basic.cpp,v retrieving revision 1.81 diff -r1.81 basic.cpp 267a268,272 > ex basic::conjugate() const > { > return *this; > } > Index: ginac/basic.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/basic.h,v retrieving revision 1.67 diff -r1.67 basic.h 129a130,132 > // complex conjugation > virtual ex conjugate() const; > Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.70 diff -r1.70 clifford.cpp 486a487,498 > ex diracgamma5::conjugate() const > { return -1*ex(*this); > } > > ex diracgammaL::conjugate() const > { return (new diracgammaR) -> setflag(status_flags::dynallocated); > } > > ex diracgammaR::conjugate() const > { return (new diracgammaL) -> setflag(status_flags::dynallocated); > } > Index: ginac/clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.45 diff -r1.45 clifford.h 106a107,109 > public: > ex conjugate() const; > 119a123,125 > public: > ex conjugate() const; > 131a138,140 > > public: > ex conjugate() const; Index: ginac/container.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/container.h,v retrieving revision 1.11 diff -r1.11 container.h 367a368,391 > ex conjugate() const > { STLT*newcont = 0; > for(const_iterator i=seq.begin(); i!=seq.end(); ++i) > { if(newcont) > { newcont -> push_back(i->conjugate()); > continue; > } > ex x = i->conjugate(); > if(are_ex_trivially_equal(x,*i)) > continue; > newcont = new STLT; > reserve( *newcont, seq.size() ); > for(const_iterator j=seq.begin(); j!=i; ++j) > newcont -> push_back(*j); > newcont -> push_back(x); > } > if(newcont) { > ex result = thiscontainer(*newcont); > delete newcont; > return result; > } > return *this; > } > Index: ginac/ex.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/ex.h,v retrieving revision 1.73 diff -r1.73 ex.h 134a135,137 > // complex conjugation > ex conjugate() const { return bp->conjugate(); } > 710a714,716 > > inline ex conjugate(const ex & thisex) > { return thisex.conjugate(); } Index: ginac/expair.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/expair.cpp,v retrieving revision 1.3 diff -r1.3 expair.cpp 25a26 > #include "operators.h" 35a37,46 > > const expair expair::conjugate() const > { > ex newrest=rest.conjugate(); > ex newcoeff=coeff.conjugate(); > if(are_ex_trivially_equal(newrest,rest) > && are_ex_trivially_equal (newcoeff,coeff)) > return *this; > return expair(newrest, newcoeff); > } Index: ginac/expair.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/expair.h,v retrieving revision 1.27 diff -r1.27 expair.h 87c87,89 < --- > > const expair conjugate() const; > Index: ginac/expairseq.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/expairseq.cpp,v retrieving revision 1.73 diff -r1.73 expairseq.cpp 312a313,344 > epvector* conjugateepvector(const epvector&epv) > { > epvector *newepv = 0; > for(epvector::const_iterator i=epv.begin(); i!=epv.end(); ++i) > { if(newepv) > { newepv -> push_back( i->conjugate() ); > continue; > } > expair x = i->conjugate(); > if( x.is_equal(*i)) > continue; > newepv = new epvector; > newepv -> reserve(epv.size()); > for(epvector::const_iterator j=epv.begin(); j!=i; ++j) > newepv -> push_back(*j); > newepv -> push_back(x); > } > return newepv; > } > > ex expairseq::conjugate() const > { > epvector *newepv = conjugateepvector(seq); > ex x = overall_coeff.conjugate(); > if( !newepv && are_ex_trivially_equal( x, overall_coeff)) > return *this; > ex result=thisexpairseq( newepv ? *newepv : seq , x ); > if(newepv) > delete newepv; > return result; > } > Index: ginac/expairseq.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/expairseq.h,v retrieving revision 1.43 diff -r1.43 expairseq.h 51a52,55 > /** Complex conjugate every element of an epvector. Returns zero if this > * does not change anything. */ > epvector* conjugateepvector(const epvector&); > 79a84 > ex conjugate() const; Index: ginac/function.pl =================================================================== RCS file: /home/cvs/GiNaC/ginac/function.pl,v retrieving revision 1.84 diff -r1.84 function.pl 56a57,60 > $typedef_conjugate_funcp=generate( > 'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n", > 'const ex &','',''); > 72a77,78 > $conjugate_func_interface=generate(' function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','',''); > 112a119,124 > $conjugate_switch_statement=generate( > <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); > case ${N}: > return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1}); > END_OF_DIFF_SWITCH_STATEMENT > 156a169,178 > $conjugate_func_implementation=generate( > <<'END_OF_CONJUGATE_FUNC_IMPLEMENTATION','','',''); > function_options & function_options::conjugate_func(conjugate_funcp_${N} c) > { > test_and_set_nparams(${N}); > conjugate_f = conjugate_funcp(c); > return *this; > } > END_OF_CONJUGATE_FUNC_IMPLEMENTATION > 229a252 > typedef ex (* conjugate_funcp)(); 236a260 > $typedef_conjugate_funcp 245a270 > typedef ex (* conjugate_funcp_exvector)(const exvector &); 266a292 > $conjugate_func_interface 272a299 > function_options & conjugate_func(conjugate_funcp_exvector d); 304a332 > conjugate_funcp conjugate_f; 321a350 > bool conjugate_use_exvector_args; 371a401 > ex conjugate() const; 499c529 < eval_f = evalf_f = derivative_f = series_f = 0; --- > eval_f = evalf_f = conjugate_f = derivative_f = series_f = 0; 503a534 > conjugate_use_exvector_args = false; 531a563 > $conjugate_func_implementation 547a580,585 > function_options& function_options::conjugate_func(conjugate_funcp_exvector c) > { > conjugate_use_exvector_args = true; > conjugate_f = conjugate_funcp(c); > return *this; > } 923a962,983 > // end of generated lines > } > throw(std::logic_error("function::series(): invalid nparams")); > } > > /** Implementation of ex::conjugate for functions. > * \@see ex::series */ > ex function::conjugate() const > { > GINAC_ASSERT(serial const function_options &opt = registered_functions()[serial]; > > if (opt.conjugate_f==0) { > return exprseq::conjugate(); > } > > if (opt.conjugate_use_exvector_args) > return ((conjugate_funcp_exvector)(opt.conjugate_f))(seq); > > switch (opt.nparams) { > // the following lines have been generated for max. ${maxargs} parameters > ${conjugate_switch_statement} Index: ginac/idx.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/idx.h,v retrieving revision 1.49 diff -r1.49 idx.h 194a195,197 > // complex conjugation > ex conjugate() const { return toggle_dot(); } > Index: ginac/inifcns.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/inifcns.cpp,v retrieving revision 1.73 diff -r1.73 inifcns.cpp 71a72,75 > static ex abs_conjugate(const ex & x) > { return abs(x); > } > 76c80,81 < print_func(abs_print_csrc_float)); --- > print_func(abs_print_csrc_float). > conjugate_func(abs_conjugate)); 135a141,145 > static ex csgn_conjugate(const ex&x) > { > return csgn(x); > } > 138c148,149 < series_func(csgn_series)); --- > series_func(csgn_series). > conjugate_func(csgn_conjugate)); 212a224,228 > static ex eta_conjugate(const ex & x, const ex & y) > { > return -eta(x,y); > } > 217c233,234 < set_symmetry(sy_symm(0, 1))); --- > set_symmetry(sy_symm(0, 1)). > conjugate_func(eta_conjugate)); 418a436,440 > static ex factorial_conjugate(const ex & x) > { > return factorial(x); > } > 420c442,443 < evalf_func(factorial_evalf)); --- > evalf_func(factorial_evalf). > conjugate_func(factorial_conjugate)); 438a462,469 > // At the moment the numeric evaluation of a binomail function always > // gives a real number, but if this would be implemented using the gamma > // function, also complex conjugation should be changed (or rather, deleted). > static ex binomial_conjugate(const ex & x, const ex & y) > { > return binomial(x,y); > } > 440c471,472 < evalf_func(binomial_evalf)); --- > evalf_func(binomial_evalf). > conjugate_func(binomial_conjugate)); 472a505,509 > static ex Order_conjugate(const ex & x) > { > return Order(x); > } > 477c514,515 < latex_name("\\mathcal{O}")); --- > latex_name("\\mathcal{O}"). > conjugate_func(Order_conjugate)); Index: ginac/matrix.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/matrix.cpp,v retrieving revision 1.96 diff -r1.96 matrix.cpp 499a500,524 > // Complex conjugate every matrix entry. > ex matrix::conjugate() const > { exvector * ev = 0; > for(exvector::const_iterator i=m.begin(); i!=m.end(); ++i) { > ex x = i->conjugate(); > if(ev) { > ev->push_back(x); > continue; > } > if(are_ex_trivially_equal(x, *i)) > continue; > ev = new exvector; > ev->reserve(m.size()); > for(exvector::const_iterator j=m.begin(); j!=i; ++j) > ev->push_back(*j); > ev->push_back(x); > } > if(ev) { > ex result = matrix(row, col, *ev); > delete ev; > return result; > } > return *this; > } > Index: ginac/matrix.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/matrix.h,v retrieving revision 1.64 diff -r1.64 matrix.h 122a123 > ex conjugate() const; Index: ginac/mul.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/mul.cpp,v retrieving revision 1.79 diff -r1.79 mul.cpp 920c920 < setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); --- > setflag(status_flags::dynallocated)); 922,923c922 < return ((new add(distrseq))-> < setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); --- > return ex((new add(distrseq))->setflag(status_flags::dynallocated)).expand(); Index: ginac/ncmul.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/ncmul.cpp,v retrieving revision 1.49 diff -r1.49 ncmul.cpp 419a420,436 > ex ncmul::conjugate() const > { > if(return_type() != return_types::noncommutative) > return exprseq::conjugate(); > > if(return_type_tinfo() & 0xffffff00U != TINFO_clifford) > return exprseq::conjugate(); > > exvector ev; > ev.reserve(nops()); > for(const_iterator i=end(); i!=begin();) { > --i; > ev.push_back( i->conjugate() ); > } > return (new ncmul(ev, true)) -> setflag(status_flags::dynallocated); > } > Index: ginac/ncmul.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/ncmul.h,v retrieving revision 1.38 diff -r1.38 ncmul.h 62a63 > ex conjugate() const; Index: ginac/numeric.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/numeric.cpp,v retrieving revision 1.106 diff -r1.106 numeric.cpp 669a670,676 > ex numeric::conjugate() const > { > if(is_real()) > return *this; > return real().sub(I.mul(imag())); > } > Index: ginac/numeric.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/numeric.h,v retrieving revision 1.67 diff -r1.67 numeric.h 105a106 > ex conjugate() const; Index: ginac/power.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/power.cpp,v retrieving revision 1.88 diff -r1.88 power.cpp 518a519,528 > ex power::conjugate() const > { > ex newbasis=basis.conjugate(); > ex newexponent=exponent.conjugate(); > if(are_ex_trivially_equal(basis, newbasis) > && are_ex_trivially_equal(exponent, newexponent)) > return *this; > return (new power(newbasis, newexponent)) -> setflag(status_flags::dynallocated); > } > 760,761c770 < return (new add(result))->setflag(status_flags::dynallocated | < status_flags::expanded); --- > return ex((new add(result))->setflag(status_flags::dynallocated)).expand(); 828c837 < return (new add(sum))->setflag(status_flags::dynallocated | status_flags::expanded); --- > return ex((new add(sum))->setflag(status_flags::dynallocated)).expand(); Index: ginac/power.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/power.h,v retrieving revision 1.47 diff -r1.47 power.h 60a61 > ex conjugate() const; Index: ginac/pseries.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/pseries.cpp,v retrieving revision 1.72 diff -r1.72 pseries.cpp 409a410,426 > ex pseries::conjugate() const > { > epvector *newseq = conjugateepvector(seq); > ex newvar = var.conjugate(); > ex newpoint = point.conjugate(); > > if( !newseq > && are_ex_trivially_equal(newvar, var) > && are_ex_trivially_equal(point, newpoint) ) > return *this; > > ex result=(new pseries( newvar==newpoint, newseq ? *newseq : seq )) -> setflag(status_flags::dynallocated); > if(newseq) > delete newseq; > return result; > } > Index: ginac/pseries.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/pseries.h,v retrieving revision 1.35 diff -r1.35 pseries.h 53a54 > ex conjugate() const; From Christian.Bauer at Uni-Mainz.DE Wed Dec 10 18:06:56 2003 From: Christian.Bauer at Uni-Mainz.DE (Christian Bauer) Date: Wed, 10 Dec 2003 18:06:56 +0100 Subject: complex conjugation In-Reply-To: References: Message-ID: <20031210170656.GL1844@thep.physik.uni-mainz.de> 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/ From chrisd at sci.kun.nl Wed Dec 10 19:24:07 2003 From: chrisd at sci.kun.nl (chrisd at sci.kun.nl) Date: Wed, 10 Dec 2003 19:24:07 +0100 (CET) Subject: complex conjugation In-Reply-To: <20031210170656.GL1844@thep.physik.uni-mainz.de> Message-ID: 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 From Christian.Bauer at Uni-Mainz.DE Thu Dec 11 18:48:45 2003 From: Christian.Bauer at Uni-Mainz.DE (Christian Bauer) Date: Thu, 11 Dec 2003 18:48:45 +0100 Subject: expand() In-Reply-To: References: <20031210170656.GL1844@thep.physik.uni-mainz.de> Message-ID: <20031211174845.GP1844@thep.physik.uni-mainz.de> 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/ From chrisd at sci.kun.nl Fri Dec 12 13:41:30 2003 From: chrisd at sci.kun.nl (Chris Dams) Date: Fri, 12 Dec 2003 12:41:30 +0000 (UTC) Subject: expand() In-Reply-To: <20031211174845.GP1844@thep.physik.uni-mainz.de> Message-ID: 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 at gamow:~/c++> more test.C #include #include 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 at gamow:~/c++> g++ -o test test.C -lginac chrisd at 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 From chrisd at sci.kun.nl Mon Dec 15 15:25:21 2003 From: chrisd at sci.kun.nl (Chris Dams) Date: Mon, 15 Dec 2003 14:25:21 +0000 (UTC) Subject: problem with powers. Message-ID: Hello, Expanding an expression by calling the .expand() method is obsoleted by the now preferred method of the so-called "repeated reciprocal". You want to expand a*(a+b)? Here is how this is done nowadays. ex test = a*(a+b) ex expanded_test = 1/(1/test) Then again, maybe this was not the idea. A patch that is supposed to remove this feature from GiNaC is attached. Have a nice day, Chris -------------- next part -------------- Index: power.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/power.cpp,v retrieving revision 1.89 diff -r1.89 power.cpp 659c669 < return expand_mul(ex_to(expanded_basis), num_exponent); --- > return expand_mul(ex_to(expanded_basis), num_exponent, true); 716c726 < term.push_back(expand_mul(ex_to(b),numeric(k[l]))); --- > term.push_back(expand_mul(ex_to(b),numeric(k[l]),true)); 730c740 < term.push_back(expand_mul(ex_to(b),numeric(n-k_cum[m-2]))); --- > term.push_back(expand_mul(ex_to(b),numeric(n-k_cum[m-2]),true)); 790c800 < sum.push_back(expair(expand_mul(ex_to(r),_num2), --- > sum.push_back(expair(expand_mul(ex_to(r),_num2,true), 798c808 < sum.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to(r),_num2), --- > sum.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to(r),_num2,true), 833c843 < ex power::expand_mul(const mul & m, const numeric & n) const --- > ex power::expand_mul(const mul & m, const numeric & n, bool from_expand) const 853c863 < if (is_exactly_a(cit->rest) && new_coeff.is_pos_integer()) { --- > if (from_expand && is_exactly_a(cit->rest) && new_coeff.is_pos_integer()) { 866c876 < else --- > if (from_expand) 867a878 > return result; Index: power.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/power.h,v retrieving revision 1.47 diff -r1.47 power.h 60a61 > ex conjugate() const; 89c90 < ex expand_mul(const mul & m, const numeric & n) const; --- > ex expand_mul(const mul & m, const numeric & n, bool from_expand = false) const; From Christian.Bauer at Uni-Mainz.DE Tue Dec 16 16:00:21 2003 From: Christian.Bauer at Uni-Mainz.DE (Christian Bauer) Date: Tue, 16 Dec 2003 16:00:21 +0100 Subject: problem with powers. In-Reply-To: References: Message-ID: <20031216150021.GS1844@thep.physik.uni-mainz.de> Hi! On Mon, Dec 15, 2003 at 02:25:21PM +0000, Chris Dams wrote: > A patch that is supposed to remove this feature from GiNaC is attached. Thanks! Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/ From vollinga at thep.physik.uni-mainz.de Tue Dec 16 17:14:20 2003 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Tue, 16 Dec 2003 17:14:20 +0100 Subject: complex conjugation In-Reply-To: References: Message-ID: <20031216161420.GA12989@thep.physik.uni-mainz.de> 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 From chrisd at sci.kun.nl Thu Dec 18 14:38:01 2003 From: chrisd at sci.kun.nl (Chris Dams) Date: Thu, 18 Dec 2003 13:38:01 +0000 (UTC) Subject: complex conjugation In-Reply-To: <20031216161420.GA12989@thep.physik.uni-mainz.de> Message-ID: 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 From vollinga at thep.physik.uni-mainz.de Thu Dec 18 16:33:15 2003 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Thu, 18 Dec 2003 16:33:15 +0100 Subject: complex conjugation In-Reply-To: References: <20031216161420.GA12989@thep.physik.uni-mainz.de> Message-ID: <20031218153315.GA28137@thep.physik.uni-mainz.de> 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 From kreckel at thep.physik.uni-mainz.de Thu Dec 18 23:26:46 2003 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Thu, 18 Dec 2003 23:26:46 +0100 (CET) Subject: complex conjugation In-Reply-To: <20031218153315.GA28137@thep.physik.uni-mainz.de> Message-ID: 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 From chrisd at sci.kun.nl Fri Dec 19 20:05:26 2003 From: chrisd at sci.kun.nl (chrisd at sci.kun.nl) Date: Fri, 19 Dec 2003 20:05:26 +0100 (CET) Subject: complex conjugation In-Reply-To: Message-ID: 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 From vollinga at thep.physik.uni-mainz.de Sat Dec 20 00:24:29 2003 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Sat, 20 Dec 2003 00:24:29 +0100 Subject: complex conjugation In-Reply-To: References: Message-ID: <20031219232428.GA12688@thep.physik.uni-mainz.de> Hi. On Fri, Dec 19, 2003 at 08:05:26PM +0100, chrisd at 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 From kreckel at thep.physik.uni-mainz.de Sat Dec 20 16:54:44 2003 From: kreckel at thep.physik.uni-mainz.de (Richard B. Kreckel) Date: Sat, 20 Dec 2003 16:54:44 +0100 (CET) Subject: complex conjugation In-Reply-To: Message-ID: Salam On Fri, 19 Dec 2003 chrisd at 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