3 * Implementation of GiNaC's simp_lor objects.
4 * No real implementation yet, to be done.
6 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 // default constructor, destructor, copy constructor assignment operator and helpers
41 simp_lor::simp_lor() : type(invalid)
43 debugmsg("simp_lor default constructor",LOGLEVEL_CONSTRUCT);
44 tinfo_key=TINFO_simp_lor;
49 debugmsg("simp_lor destructor",LOGLEVEL_DESTRUCT);
53 simp_lor::simp_lor(simp_lor const & other)
55 debugmsg("simp_lor copy constructor",LOGLEVEL_CONSTRUCT);
59 simp_lor const & simp_lor::operator=(simp_lor const & other)
61 debugmsg("simp_lor operator=",LOGLEVEL_ASSIGNMENT);
71 void simp_lor::copy(simp_lor const & other)
78 void simp_lor::destroy(bool call_parent)
81 indexed::destroy(call_parent);
91 simp_lor::simp_lor(simp_lor_types const t) : type(t)
93 debugmsg("simp_lor constructor from simp_lor_types",LOGLEVEL_CONSTRUCT);
94 tinfo_key=TINFO_simp_lor;
97 simp_lor::simp_lor(simp_lor_types const t, ex const & i1, ex const & i2) :
98 indexed(i1,i2), type(t)
100 debugmsg("simp_lor constructor from simp_lor_types,ex,ex",LOGLEVEL_CONSTRUCT);
101 tinfo_key=TINFO_simp_lor;
102 ASSERT(all_of_type_lorentzidx());
105 simp_lor::simp_lor(simp_lor_types const t, string const & n, ex const & i1) :
106 indexed(i1), type(t), name(n)
108 debugmsg("simp_lor constructor from simp_lor_types,string,ex",LOGLEVEL_CONSTRUCT);
109 tinfo_key=TINFO_simp_lor;
110 ASSERT(all_of_type_lorentzidx());
113 simp_lor::simp_lor(simp_lor_types const t, string const & n, exvector const & iv) :
114 indexed(iv), type(t), name(n)
116 debugmsg("simp_lor constructor from simp_lor_types,string,exvector",LOGLEVEL_CONSTRUCT);
117 tinfo_key=TINFO_simp_lor;
118 ASSERT(all_of_type_lorentzidx());
121 simp_lor::simp_lor(simp_lor_types const t, string const & n, exvector * ivp) :
122 indexed(ivp), type(t), name(n)
124 debugmsg("simp_lor constructor from simp_lor_types,string,exvector*",LOGLEVEL_CONSTRUCT);
125 tinfo_key=TINFO_simp_lor;
126 ASSERT(all_of_type_lorentzidx());
130 // functions overriding virtual functions from bases classes
135 basic * simp_lor::duplicate() const
137 debugmsg("simp_lor duplicate",LOGLEVEL_DUPLICATE);
138 return new simp_lor(*this);
141 void simp_lor::printraw(ostream & os) const
143 debugmsg("simp_lor printraw",LOGLEVEL_PRINT);
144 os << "simp_lor(type=" << (unsigned)type
145 << ",name=" << name << ",indices=";
147 os << ",hash=" << hashvalue << ",flags=" << flags << ")";
150 void simp_lor::printtree(ostream & os, unsigned indent) const
152 debugmsg("simp_lor printtree",LOGLEVEL_PRINT);
153 os << string(indent,' ') << "simp_lor object: "
154 << "type=" << (unsigned)type
155 << ", name=" << name << ", ";
156 os << seq.size() << " indices" << endl;
157 printtreeindices(os,indent);
158 os << string(indent,' ') << "hash=" << hashvalue
159 << " (0x" << hex << hashvalue << dec << ")"
160 << ", flags=" << flags << endl;
163 void simp_lor::print(ostream & os, unsigned upper_precedence) const
165 debugmsg("simp_lor print",LOGLEVEL_PRINT);
175 os << "INVALID_SIMP_LOR_OBJECT";
181 void simp_lor::printcsrc(ostream & os, unsigned type, unsigned upper_precedence) const
183 debugmsg("simp_lor print csrc",LOGLEVEL_PRINT);
184 print(os,upper_precedence);
187 bool simp_lor::info(unsigned inf) const
189 return indexed::info(inf);
192 ex simp_lor::eval(int level) const
194 if (type==simp_lor_g) {
195 // canonicalize indices
197 int sig=canonicalize_indices(iv,false); // symmetric
199 // something has changed while sorting indices, more evaluations later
200 if (sig==0) return exZERO();
201 return ex(sig)*simp_lor(type,name,iv);
203 lorentzidx const & idx1=ex_to_lorentzidx(seq[0]);
204 lorentzidx const & idx2=ex_to_lorentzidx(seq[1]);
205 if ((!idx1.is_symbolic())&&(!idx2.is_symbolic())) {
206 // both indices are numeric
207 if ((idx1.get_value()==idx2.get_value())) {
209 if (idx1.get_value()==0) {
213 if (idx1.is_covariant()!=idx2.is_covariant()) {
214 // (_i,~i) or (~i,_i), i=1..3
217 // (_i,_i) or (~i,~i), i=1..3
222 // at least one off-diagonal
225 } else if (idx1.is_symbolic() &&
226 idx1.is_co_contra_pair(idx2)) {
227 return Dim()-idx1.get_dim_parallel_space();
236 int simp_lor::compare_same_type(basic const & other) const
238 ASSERT(other.tinfo() == TINFO_simp_lor);
239 const simp_lor *o = static_cast<const simp_lor *>(&other);
242 return indexed::compare_same_type(other);
244 return name.compare(o->name);
246 return type < o->type ? -1 : 1;
249 bool simp_lor::is_equal_same_type(basic const & other) const
251 ASSERT(other.tinfo() == TINFO_simp_lor);
252 const simp_lor *o = static_cast<const simp_lor *>(&other);
253 if (type!=o->type) return false;
254 if (name!=o->name) return false;
255 return indexed::is_equal_same_type(other);
258 unsigned simp_lor::return_type(void) const
260 return return_types::commutative;
263 unsigned simp_lor::return_type_tinfo(void) const
268 ex simp_lor::thisexprseq(exvector const & v) const
270 return simp_lor(type,name,v);
273 ex simp_lor::thisexprseq(exvector * vp) const
275 return simp_lor(type,name,vp);
279 // virtual functions which can be overridden by derived classes
285 // non-virtual functions in this class
290 bool simp_lor::all_of_type_lorentzidx(void) const
292 // used only inside of ASSERTs
293 for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
294 if (!is_ex_of_type(*cit,lorentzidx)) return false;
300 // static member variables
309 const simp_lor some_simp_lor;
310 type_info const & typeid_simp_lor=typeid(some_simp_lor);
316 simp_lor lor_g(ex const & mu, ex const & nu)
318 return simp_lor(simp_lor::simp_lor_g,mu,nu);
321 simp_lor lor_vec(string const & n, ex const & mu)
323 return simp_lor(simp_lor::simp_lor_vec,n,mu);
326 ex simplify_simp_lor_mul(ex const & m, scalar_products const & sp)
328 ASSERT(is_ex_exactly_of_type(m,mul));
329 exvector v_contracted;
331 // collect factors in an exvector, store squares twice
333 v_contracted.reserve(2*n);
334 for (int i=0; i<n; ++i) {
336 if (is_ex_exactly_of_type(f,power)&&f.op(1).is_equal(exTWO())) {
337 v_contracted.push_back(f.op(0));
338 v_contracted.push_back(f.op(0));
340 v_contracted.push_back(f);
344 unsigned replacements;
345 bool something_changed=false;
347 exvector::iterator it=v_contracted.begin();
348 while (it!=v_contracted.end()) {
349 // process only lor_g objects
350 if (is_ex_exactly_of_type(*it,simp_lor) &&
351 (ex_to_simp_lor(*it).type==simp_lor::simp_lor_g)) {
352 simp_lor const & g=ex_to_simp_lor(*it);
353 ASSERT(g.seq.size()==2);
354 idx const & first_idx=ex_to_lorentzidx(g.seq[0]);
355 idx const & second_idx=ex_to_lorentzidx(g.seq[1]);
356 // g_{mu,mu} should have been contracted in simp_lor::eval()
357 ASSERT(!first_idx.is_equal(second_idx));
358 ex saved_g=*it; // save to restore it later
360 // try to contract first index
362 if (first_idx.is_symbolic()) {
363 replacements = subs_index_in_exvector(v_contracted,
364 first_idx.toggle_covariant(),second_idx);
365 if (replacements==0) {
366 // not contracted, restore g object
369 // a contracted index should occur exactly once
370 ASSERT(replacements==1);
372 something_changed=true;
376 // try second index only if first was not contracted
377 if ((replacements==0)&&(second_idx.is_symbolic())) {
378 // first index not contracted, *it is again the original g object
379 replacements = subs_index_in_exvector(v_contracted,
380 second_idx.toggle_covariant(),first_idx);
381 if (replacements==0) {
382 // not contracted except in itself, restore g object
385 // a contracted index should occur exactly once
386 ASSERT(replacements==1);
388 something_changed=true;
395 // process only lor_vec objects
396 bool jump_to_next=false;
397 exvector::iterator it1=v_contracted.begin();
398 while (it1!=v_contracted.end()-1) {
399 if (is_ex_exactly_of_type(*it1,simp_lor) &&
400 (ex_to_simp_lor(*it1).type==simp_lor::simp_lor_vec)) {
401 exvector::iterator it2=it1+1;
402 while ((it2!=v_contracted.end())&&!jump_to_next) {
403 if (is_ex_exactly_of_type(*it2,simp_lor) &&
404 (ex_to_simp_lor(*it2).type==simp_lor::simp_lor_vec)) {
405 simp_lor const & vec1=ex_to_simp_lor(*it1);
406 simp_lor const & vec2=ex_to_simp_lor(*it2);
407 ASSERT(vec1.seq.size()==1);
408 ASSERT(vec2.seq.size()==1);
409 lorentzidx const & idx1=ex_to_lorentzidx(vec1.seq[0]);
410 lorentzidx const & idx2=ex_to_lorentzidx(vec2.seq[0]);
411 if (idx1.is_symbolic() &&
412 idx1.is_co_contra_pair(idx2) &&
413 sp.is_defined(vec1,vec2)) {
414 *it1=sp.evaluate(vec1,vec2);
416 something_changed=true;
426 if (something_changed) {
427 return mul(v_contracted);
432 ex simplify_simp_lor(ex const & e, scalar_products const & sp)
434 // all simplification is done on expanded objects
435 ex e_expanded=e.expand();
437 // simplification of sum=sum of simplifications
438 if (is_ex_exactly_of_type(e_expanded,add)) {
440 for (int i=0; i<e_expanded.nops(); ++i) {
441 sum += simplify_simp_lor(e_expanded.op(i),sp);
446 // simplification of commutative product=commutative product of simplifications
447 if (is_ex_exactly_of_type(e_expanded,mul)) {
448 return simplify_simp_lor_mul(e,sp);
451 // cannot do anything
457 static symbol * d=new symbol("dim");
465 void scalar_products::reg(simp_lor const & v1, simp_lor const & v2,
468 if (v1.compare_same_type(v2)>0) {
472 spm[make_key(v1,v2)]=sp;
475 bool scalar_products::is_defined(simp_lor const & v1, simp_lor const & v2) const
477 if (v1.compare_same_type(v2)>0) {
478 return is_defined(v2,v1);
480 return spm.find(make_key(v1,v2))!=spm.end();
483 ex scalar_products::evaluate(simp_lor const & v1, simp_lor const & v2) const
485 if (v1.compare_same_type(v2)>0) {
486 return evaluate(v2,v1);
488 return spm.find(make_key(v1,v2))->second;
491 void scalar_products::debugprint(void) const
493 cerr << "map size=" << spm.size() << endl;
494 for (spmap::const_iterator cit=spm.begin(); cit!=spm.end(); ++cit) {
495 spmapkey const & k=(*cit).first;
496 cerr << "item key=((" << k.first.first
497 << "," << k.first.second << "),";
498 k.second.printraw(cerr);
499 cerr << ") value=" << (*cit).second << endl;
503 spmapkey scalar_products::make_key(simp_lor const & v1, simp_lor const & v2)
505 ASSERT(v1.type==simp_lor::simp_lor_vec);
506 ASSERT(v2.type==simp_lor::simp_lor_vec);
507 lorentzidx anon=ex_to_lorentzidx(v1.seq[0]).create_anonymous_representative();
508 ASSERT(anon.is_equal_same_type(ex_to_lorentzidx(v2.seq[0]).create_anonymous_representative()));
509 return spmapkey(strstrpair(v1.name,v2.name),anon);