00001 #include "tools.h"
00002
00003 GiNaC::symbol x("x");
00004 GiNaC::symbol y("y");
00005 GiNaC::symbol z("z");
00006 GiNaC::symbol infinity("infinity");
00007 GiNaC::symbol DUMMY("DUMMY");
00008
00009 int nsd = 2;
00010
00011
00012
00013
00014
00015
00016
00017 void print(GiNaC::lst& l) {
00018
00019
00020
00021 GiNaC::lst::const_iterator i = l.begin();
00022 cout <<"GiNaC::lst("<<*i;
00023 ++i;
00024
00025 for (; i != l.end() ; ++i) {
00026 cout << ","<< *i;
00027 }
00028 cout <<");"<<endl;
00029 }
00030
00031 void print(GiNaC::exvector& v) {
00032 cout <<"v=[";
00033 for (int i=0; i< v.size()-1; i++) {
00034 cout <<v[i]<<"," <<endl;
00035 }
00036 cout <<v[v.size()-1]<< "]"<<endl;
00037
00038 }
00039
00040 GiNaC::lst cross(GiNaC::lst& v1, GiNaC::lst& v2) {
00041 GiNaC::lst ret;
00042 if ( v1.nops() != v2.nops() ) {
00043 cout <<"incompatible vectors "<<endl;
00044 cout <<"v1.nops() "<<v1.nops();
00045 cout <<" v2.nops() "<<v2.nops()<<endl; ;
00046 return GiNaC::lst();
00047 }
00048 ret.append( v1.op(1)*v2.op(2) - v1.op(2)*v2.op(1));
00049 ret.append(- v1.op(0)*v2.op(2) + v1.op(2)*v2.op(0));
00050 ret.append( v1.op(0)*v2.op(1) - v1.op(1)*v2.op(0));
00051 return ret;
00052 }
00053
00054 GiNaC::ex inner(GiNaC::ex a, GiNaC::ex b, bool transposed){
00055 if (GiNaC::is_a<GiNaC::matrix>(a) && GiNaC::is_a<GiNaC::matrix>(b)) {
00056 GiNaC::matrix ma = GiNaC::ex_to<GiNaC::matrix>(a);
00057 GiNaC::matrix mb = GiNaC::ex_to<GiNaC::matrix>(b);
00058 if ( !transposed ) {
00059 if (ma.cols() != mb.cols() || ma.rows() != mb.rows() ) {
00060 cout <<"Incompatible matrices "<<endl;
00061 cout <<"a.cols() "<<ma.cols()<<endl;
00062 cout <<"a.rows() "<<ma.rows()<<endl;
00063 cout <<"b.cols() "<<mb.cols()<<endl;
00064 cout <<"b.rows() "<<mb.rows()<<endl;
00065 cout <<"a="<<a<<endl;
00066 cout <<"b="<<b<<endl;
00067 return DUMMY;
00068 }
00069
00070 GiNaC::ex ret;
00071 for (int i=0; i<ma.rows(); i++) {
00072 for (int j=0; j<ma.cols(); j++) {
00073 ret += ma(i,j)*mb(i,j);
00074 }
00075 }
00076 return ret;
00077 }
00078 else {
00079 if (ma.cols() != mb.rows() || ma.rows() != mb.cols() ) {
00080 cout <<"Incompatible matrices "<<endl;
00081 cout <<"a.cols() "<<ma.cols()<<endl;
00082 cout <<"a.rows() "<<ma.rows()<<endl;
00083 cout <<"b.cols() "<<mb.cols()<<endl;
00084 cout <<"b.rows() "<<mb.rows()<<endl;
00085 cout <<"a="<<a<<endl;
00086 cout <<"b="<<b<<endl;
00087 return DUMMY;
00088 }
00089
00090 GiNaC::ex ret;
00091 for (int i=0; i<ma.rows(); i++) {
00092 for (int j=0; j<ma.cols(); j++) {
00093 ret += ma(i,j)*mb(j,i);
00094 }
00095 }
00096 return ret;
00097 }
00098 } else if (GiNaC::is_a<GiNaC::lst>(a)
00099 && GiNaC::is_a<GiNaC::lst>(b)) {
00100 return inner(GiNaC::ex_to<GiNaC::lst>(a), GiNaC::ex_to<GiNaC::lst>(b));
00101 } else {
00102 return a*b;
00103 }
00104 }
00105
00106
00107 GiNaC::ex inner(GiNaC::lst v1, GiNaC::lst v2) {
00108 GiNaC::ex ret;
00109 if ( v1.nops() != v2.nops() ) {
00110 cout <<"incompatible vectors "<<endl;
00111 cout <<"v1.nops() "<<v1.nops();
00112 cout <<" v2.nops() "<<v2.nops()<<endl; ;
00113 return 0;
00114 }
00115 int i;
00116 for (i = 0; i <= v1.nops()-1 ; ++i) {
00117 if ( GiNaC::is_a<GiNaC::lst>(v1.op(i)) &&
00118 GiNaC::is_a<GiNaC::lst>(v2.op(i)) ) {
00119 ret += inner(GiNaC::ex_to<GiNaC::lst>(v1.op(i)),
00120 GiNaC::ex_to<GiNaC::lst>(v2.op(i)));
00121 } else {
00122 ret += v1.op(i)*v2.op(i);
00123 }
00124 }
00125 return ret;
00126 }
00127
00128 GiNaC::lst matvec(GiNaC::matrix& M, GiNaC::lst& x) {
00129 GiNaC::lst ret;
00130 int nr = M.rows();
00131 int nc = M.cols();
00132 for (int i = 0; i < nr; i++) {
00133 GiNaC::ex tmp;
00134 for (int j = 0; j < nc; j++) {
00135 tmp = tmp + M(i,j)*(x.op(j));
00136 }
00137 ret.append(tmp);
00138 }
00139 return ret;
00140 }
00141
00142
00143 GiNaC::ex matvec(GiNaC::ex A, GiNaC::ex x) {
00144 if (GiNaC::is_a<GiNaC::matrix>(A) && GiNaC::is_a<GiNaC::matrix>(x)) {
00145 GiNaC::matrix AA = GiNaC::ex_to<GiNaC::matrix>(A);
00146 GiNaC::matrix xx = GiNaC::ex_to<GiNaC::matrix>(x);
00147 return AA.mul(xx);
00148 }
00149 return DUMMY;
00150
00151 }
00152
00153
00154
00155
00156 GiNaC::ex inner(GiNaC::exvector& v1, GiNaC::exvector& v2){
00157 GiNaC::ex ret;
00158 for (int i=0; i< v1.size(); i++) {
00159 ret += v1[i]*v2[i];
00160 }
00161 return ret;
00162 }
00163
00164
00165 GiNaC::ex homogenous_pol(int order, int nsd, const string a){
00166 if ( nsd == 1) {
00167 GiNaC::symbol a0(istr(a,0));
00168 return GiNaC::lst(a0*pow(x,order), a0, pow(x,order));
00169 } else if ( nsd == 2 ) {
00170 GiNaC::ex variables = GiNaC::symbolic_matrix(1,order+1, a);
00171 GiNaC::lst basis;
00172 GiNaC::ex ret;
00173 for (int i=0; i<= order; i++) {
00174 basis.append(pow(x,i)*pow(y,order-i));
00175 ret += variables.op(i)*basis.op(i);
00176 }
00177 return GiNaC::lst(ret, matrix_to_lst2(variables), basis);
00178 } else if ( nsd == 3 ) {
00179 GiNaC::lst basis;
00180 for (int i=0; i<= order; i++) {
00181 for (int j=0; j<= order; j++) {
00182 for (int k=0; k<= order; k++) {
00183 if ( i + j + k == order ) {
00184 basis.append(pow(x,i)*pow(y,j)*pow(z,k));
00185 }
00186 }
00187 }
00188 }
00189 GiNaC::ex variables = GiNaC::symbolic_matrix(1,basis.nops(), a);
00190 GiNaC::ex ret;
00191 for (int i=0; i<basis.nops(); i++) {
00192 ret += variables.op(i)*basis.op(i);
00193 }
00194 return GiNaC::lst(ret, matrix_to_lst2(variables), basis);
00195 } else {
00196 cout <<"Homogenous polynomials only implemented in 1D, 2D and 3D";
00197 return DUMMY;
00198 }
00199
00200 }
00201
00202 GiNaC::lst homogenous_polv(int no_fields, int order, int nsd, const string a){
00203 GiNaC::lst ret1;
00204 GiNaC::lst ret2;
00205 GiNaC::lst ret3;
00206 GiNaC::lst basis_tmp;
00207 for (int i=1; i<= no_fields; i++) {
00208 GiNaC::lst basis;
00209 std::ostringstream s;
00210 s <<a<<""<<i<<"_";
00211 GiNaC::ex polspace = homogenous_pol(order, nsd, s.str());
00212 ret1.append(polspace.op(0));
00213 ret2.append(polspace.op(1));
00214 basis_tmp = GiNaC::ex_to<GiNaC::lst>(polspace.op(2));
00215 for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin();
00216 basis_iterator != basis_tmp.end(); ++basis_iterator) {
00217 GiNaC::lst tmp_lst;
00218 for (int d=1; d<=no_fields; d++) tmp_lst.append(0);
00219 tmp_lst.let_op(i-1) = (*basis_iterator);
00220 ret3.append(tmp_lst);
00221 }
00222 }
00223 return GiNaC::lst(ret1,ret2,ret3);
00224 }
00225
00226
00227 GiNaC::ex pol(int order, int nsd, const string a) {
00228 GiNaC::ex ret;
00229 int dof;
00230 GiNaC::ex A;
00231 GiNaC::lst basis;
00232
00233
00234 if (nsd == 1) {
00235
00236
00237
00238
00239 dof = order+1;
00240 A = GiNaC::symbolic_matrix(1,dof, a);
00241 int o=0;
00242 for (GiNaC::const_iterator i = A.begin(); i != A.end(); ++i) {
00243 ret += (*i)*pow(x,o);
00244 basis.append(pow(x,o));
00245 o++;
00246 }
00247 }
00248 else if ( nsd == 2) {
00249
00250
00251
00252
00253
00254
00255
00256 dof = (order+1)*(order+2)/2;
00257 A = GiNaC::symbolic_matrix(1, dof , a);
00258
00259 size_t i=0;
00260 for (int o = 0; o <= order; o++) {
00261 for (int d = 0; d <= o; d++) {
00262 ret += A.op(i)*pow(y,d)*pow(x,o-d);
00263 basis.append(pow(y,d)*pow(x,o-d));
00264 i++;
00265 }
00266 }
00267 }
00268 else if (nsd = 3) {
00269
00270
00271
00272
00273
00274
00275 dof = 0;
00276 for (int j=0; j<= order; j++) {
00277 dof += (j+1)*(j+2)/2;
00278 }
00279 A = GiNaC::symbolic_matrix(1, dof , a);
00280
00281
00282 size_t i=0;
00283 for (int o = 0; o <= order; o++) {
00284 for (int d = 0; d <= o; d++) {
00285 for (int f = 0; f <= o; f++) {
00286 if ( o-d-f >= 0) {
00287 ret += A.op(i)*pow(y,f)*pow(z,d)*pow(x,o-d-f);
00288 basis.append(pow(y,f)*pow(z,d)*pow(x,o-d-f));
00289 i++;
00290 }
00291 }
00292 }
00293 }
00294 }
00295 return GiNaC::lst(ret,matrix_to_lst2(A), basis);
00296 }
00297
00298 GiNaC::lst polv(int no_fields, int order, int nsd, const string a){
00299 GiNaC::lst ret1;
00300 GiNaC::lst ret2;
00301 GiNaC::lst ret3;
00302 GiNaC::lst basis_tmp;
00303 for (int i=1; i<= no_fields; i++) {
00304 GiNaC::lst basis;
00305 std::ostringstream s;
00306 s <<a<<""<<i<<"_";
00307 GiNaC::ex polspace = pol(order, nsd, s.str());
00308 ret1.append(polspace.op(0));
00309 ret2.append(polspace.op(1));
00310 basis_tmp = GiNaC::ex_to<GiNaC::lst>(polspace.op(2));
00311 for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin();
00312 basis_iterator != basis_tmp.end(); ++basis_iterator) {
00313 GiNaC::lst tmp_lst;
00314 for (int d=1; d<=no_fields; d++) tmp_lst.append(0);
00315 tmp_lst.let_op(i-1) = (*basis_iterator);
00316 ret3.append(tmp_lst);
00317 }
00318 }
00319 return GiNaC::lst(ret1,ret2,ret3);
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 }
00334
00335
00336 GiNaC::ex polb(int order, int nsd, const string a) {
00337
00338 GiNaC::ex ret;
00339 int dof;
00340 GiNaC::ex A;
00341 GiNaC::lst basis;
00342
00343 if (nsd == 1) {
00344
00345
00346
00347
00348 dof = order+1;
00349 A = GiNaC::symbolic_matrix(1,dof, a);
00350 int o=0;
00351 for (GiNaC::const_iterator i = A.begin(); i != A.end(); ++i) {
00352 ret += (*i)*pow(x,o);
00353 basis.append(pow(x,o));
00354 o++;
00355 }
00356 }
00357 else if ( nsd == 2) {
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 dof = (order+1)*(order+1);
00368 A = GiNaC::symbolic_matrix(1, dof , a);
00369
00370
00371 size_t i=0;
00372 for (int o = 0; o <= order; o++) {
00373 for (int d = 0; d <= order; d++) {
00374 ret += A.op(i)*pow(y,d)*pow(x,o);
00375 basis.append(pow(y,d)*pow(x,o));
00376 i++;
00377 }
00378 }
00379 }
00380 else if (nsd = 3) {
00381
00382
00383
00384
00385
00386
00387 dof = (order+1)*(order+1)*(order+1);
00388 A = GiNaC::symbolic_matrix(1, dof , a);
00389
00390
00391 size_t i=0;
00392 for (int o = 0; o <= order; o++) {
00393 for (int d = 0; d <= order; d++) {
00394 for (int f = 0; f <= order; f++) {
00395 ret += A.op(i)*pow(y,f)*pow(z,d)*pow(x,o);
00396 basis.append(pow(y,f)*pow(z,d)*pow(x,o));
00397 i++;
00398 }
00399 }
00400 }
00401 }
00402
00403 return GiNaC::lst(ret,matrix_to_lst2(A), basis);
00404 }
00405
00406 GiNaC::ex div(GiNaC::ex v){
00407 GiNaC::ex ret = DUMMY;
00408 if (GiNaC::is_a<GiNaC::matrix>(v)) {
00409 GiNaC::matrix m = GiNaC::ex_to<GiNaC::matrix>(v);
00410 if ( m.cols() == 1) {
00411 if (nsd == 1) {
00412 ret = diff(m,x);
00413 } else if (nsd == 2) {
00414 ret = diff(m.op(0),x) + diff(m.op(1),y) ;
00415 } else if (nsd == 3) {
00416 ret = diff(m.op(0),x) + diff(m.op(1),y) + diff(m.op(2),z) ;
00417 }
00418 } else {
00419 GiNaC::matrix retm = GiNaC::matrix(m.cols(),1);
00420 if ( nsd != m.rows() ) {
00421 throw(std::invalid_argument("The number of rows must equal nsd."));
00422 }
00423 GiNaC::symbol xr;
00424 GiNaC::ex tmp;
00425 for (int c=0; c<m.cols(); c++){
00426 for (int r=0; r<m.rows(); r++){
00427 if (r+1 == 1) xr = x;
00428 if (r+1 == 2) xr = y;
00429 if (r+1 == 3) xr = z;
00430 retm(c,0) += diff(m(c,r), xr);
00431 }
00432 }
00433 ret = retm;
00434 }
00435 }
00436 return ret;
00437 }
00438
00439 GiNaC::ex div(GiNaC::lst& v) {
00440 nsd = v.nops();
00441 GiNaC::ex ret;
00442 if (nsd == 1) {
00443 ret = v.op(0).diff(x);
00444 }
00445 else if (nsd == 2) {
00446 ret = v.op(0).diff(x) + v.op(1).diff(y);
00447 }
00448 else if (nsd == 3) {
00449 ret = v.op(0).diff(x) + v.op(1).diff(y) + v.op(2).diff(z);
00450 }
00451 return ret;
00452 }
00453
00454 GiNaC::ex div(GiNaC::exvector& v) {
00455 GiNaC::ex ret;
00456 if (nsd == 2) {
00457 ret = v[0].diff(x) + v[1].diff(y);
00458 }
00459 else if (nsd == 3) {
00460 ret = v[0].diff(x) + v[1].diff(y) + v[2].diff(z);
00461 }
00462 return ret;
00463 }
00464
00465 GiNaC::lst coeffs(GiNaC::lst pols) {
00466 GiNaC::lst cc;
00467 GiNaC::lst tmp;
00468 for (int i=0; i<= pols.nops()-1; i++) {
00469 tmp = coeffs(pols.op(i));
00470 cc = collapse(GiNaC::lst(cc, tmp));
00471 }
00472 return cc;
00473 }
00474
00475 GiNaC::lst coeffs(GiNaC::ex pol) {
00476 GiNaC::lst cc;
00477 GiNaC::ex c, b;
00478 for (int i=pol.ldegree(x); i<=pol.degree(x); ++i) {
00479 for (int j=pol.ldegree(y); j<=pol.degree(y); ++j) {
00480 for (int k=pol.ldegree(z); k<=pol.degree(z); ++k) {
00481 c = pol.coeff(x,i).coeff(y, j).coeff(z,k);
00482 if ( c != 0 ) cc.append(c);
00483 }
00484 }
00485 }
00486 return cc;
00487 }
00488
00489
00490
00491
00492
00493 GiNaC::exvector coeff(GiNaC::ex pol) {
00494 GiNaC::exvector cc;
00495 GiNaC::ex c, b;
00496 for (int i=pol.ldegree(x); i<=pol.degree(x); ++i) {
00497 for (int j=pol.ldegree(y); j<=pol.degree(y); ++j) {
00498 for (int k=pol.ldegree(z); k<=pol.degree(z); ++k) {
00499 c = pol.coeff(x,i).coeff(y, j).coeff(z,k);
00500 if ( c != 0 ) cc.insert(cc.begin(),c);
00501 }
00502 }
00503 }
00504 return cc;
00505 }
00506
00507 int dirac(int i, int j) {
00508 if (i==j) return 1;
00509 else return 0;
00510 }
00511
00512 ex_ex_map pol2basisandcoeff(GiNaC::ex e) {
00513 e = expand(e);
00514 GiNaC::ex c;
00515 GiNaC::ex b;
00516 ex_ex_map map;
00517 for (int i=e.ldegree(x); i<=e.degree(x); ++i) {
00518 for (int j=e.ldegree(y); j<=e.degree(y); ++j) {
00519 for (int k=e.ldegree(z); k<=e.degree(z); ++k) {
00520 c = e.coeff(x,i).coeff(y, j).coeff(z,k);
00521 b = pow(x,i)*pow(y,j)*pow(z,k);
00522 map[b] = c;
00523 }
00524 }
00525 }
00526 return map;
00527 }
00528
00529 void print(ex_int_map map) {
00530 GiNaC::ex b;
00531 int c;
00532 ex_int_it iter;
00533 iter = map.begin();
00534 cout <<"{" <<b<<":"<<c;
00535 for (iter = map.begin(); iter != map.end(); iter++) {
00536 b = (*iter).first; c = map[b];
00537 cout <<", "<<b<<":"<<c;
00538 }
00539 cout <<"}"<<endl;
00540
00541 }
00542
00543
00544
00545 void print(ex_ex_map map) {
00546 GiNaC::ex b;
00547 GiNaC::ex c;
00548 ex_ex_it iter;
00549 cout <<"{" <<b<<":"<<c;
00550 for (iter = map.begin(); iter != map.end(); iter++) {
00551 b = (*iter).first; c = map[b];
00552 cout <<", "<<b<<":"<<c;
00553 }
00554 cout <<"}"<<endl;
00555
00556 }
00557
00558
00559 GiNaC::lst ex2equations(GiNaC::ex rel) {
00560 GiNaC::ex lhs = rel.lhs();
00561 GiNaC::ex rhs = rel.rhs();
00562
00563 GiNaC::ex l;
00564 GiNaC::ex r;
00565
00566 GiNaC::lst eqs;
00567
00568 for (int i=lhs.ldegree(x); i<=lhs.degree(x); ++i) {
00569 for (int j=lhs.ldegree(y); j<=lhs.degree(y); ++j) {
00570 for (int k=lhs.ldegree(z); k<=lhs.degree(z); ++k) {
00571 l = lhs.coeff(x,i).coeff(y, j).coeff(z,k);
00572 r = rhs.coeff(x,i).coeff(y, j).coeff(z,k);
00573
00574 if ( (l != 0 && (r == 0 || r == 1) ) ) eqs.append(l == r);
00575 }
00576 }
00577 }
00578 eqs.sort();
00579 return eqs;
00580 }
00581
00582 GiNaC::lst collapse(GiNaC::lst l) {
00583 GiNaC::lst lc;
00584 GiNaC::lst::const_iterator iter1, iter2;
00585
00586 for (iter1 = l.begin(); iter1 != l.end(); ++iter1) {
00587 if (GiNaC::is_a<GiNaC::lst>(*iter1)) {
00588 for (iter2 = GiNaC::ex_to<GiNaC::lst>(*iter1).begin(); iter2 != GiNaC::ex_to<GiNaC::lst>(*iter1).end(); ++iter2) {
00589 lc.append(*iter2);
00590 }
00591 } else {
00592 lc.append(*iter1);
00593 }
00594 }
00595 lc.sort();
00596 lc.unique();
00597 return lc;
00598 }
00599
00600
00601 GiNaC::matrix equations2matrix(const GiNaC::ex &eqns, const GiNaC::ex &symbols) {
00602
00603 GiNaC::matrix sys(eqns.nops(),symbols.nops());
00604 GiNaC::matrix rhs(eqns.nops(),1);
00605 GiNaC::matrix vars(symbols.nops(),1);
00606
00607 for (size_t r=0; r<eqns.nops(); r++) {
00608 const GiNaC::ex eq = eqns.op(r).op(0)-eqns.op(r).op(1);
00609 GiNaC::ex linpart = eq;
00610 for (size_t c=0; c<symbols.nops(); c++) {
00611 const GiNaC::ex co = eq.coeff(GiNaC::ex_to<GiNaC::symbol>(symbols.op(c)),1);
00612 linpart -= co*symbols.op(c);
00613 sys(r,c) = co;
00614 }
00615 linpart = linpart.expand();
00616 rhs(r,0) = -linpart;
00617 }
00618 return sys;
00619 }
00620
00621 GiNaC::ex grad(GiNaC::ex f) {
00622 if (GiNaC::is_a<GiNaC::matrix>(f)) {
00623 GiNaC::matrix m = GiNaC::ex_to<GiNaC::matrix>(f);
00624 GiNaC::matrix ret_m(nsd,m.rows());
00625 for (int r=0; r< m.rows(); r++) {
00626 if (nsd == 1) {
00627
00628 return diff(f, x);
00629 } else if ( nsd == 2) {
00630 ret_m(0,r) = diff(m.op(r),x);
00631 ret_m(1,r) = diff(m.op(r),y);
00632 } else if ( nsd == 3) {
00633 ret_m(0,r) = diff(m.op(r),x);
00634 ret_m(1,r) = diff(m.op(r),y);
00635 ret_m(2,r) = diff(m.op(r),z);
00636 }
00637 }
00638 return ret_m;
00639 } else {
00640
00641 if (nsd == 1) {
00642
00643 return diff(f,x);
00644 } else if ( nsd == 2) {
00645 return GiNaC::matrix(nsd,1,GiNaC::lst(diff(f,x), diff(f,y)));
00646 } else if ( nsd == 3) {
00647 return GiNaC::matrix(nsd,1,GiNaC::lst(diff(f,x), diff(f,y), diff(f,z)));
00648 } else {
00649 throw(std::invalid_argument("nsd must be either 1, 2, or 3."));
00650 return GiNaC::lst();
00651 }
00652 }
00653 }
00654
00655 GiNaC::lst lst_equals(GiNaC::ex a, GiNaC::ex b) {
00656 GiNaC::lst ret;
00657 if ( (GiNaC::is_a<GiNaC::lst>(a)) && (GiNaC::is_a<GiNaC::lst>(b)) ) {
00658 for (int i=0; i<= a.nops()-1; i++) {
00659 ret.append(b.op(i) == a.op(i));
00660 }
00661 } else if ( !(GiNaC::is_a<GiNaC::lst>(a)) && !(GiNaC::is_a<GiNaC::lst>(b))) {
00662 ret.append(b == a);
00663 } else if ( !(GiNaC::is_a<GiNaC::lst>(a)) && (GiNaC::is_a<GiNaC::lst>(b))) {
00664 ret.append(b.op(0) == a);
00665 } else {
00666 throw(std::invalid_argument("Make sure that the lists a and b are comparable."));
00667 }
00668 return ret;
00669 }
00670
00671 GiNaC::ex lst_to_matrix2(const GiNaC::lst& l)
00672 {
00673 GiNaC::lst::const_iterator itr, itc;
00674
00675
00676 size_t rows = l.nops(), cols = 0;
00677 for (itr = l.begin(); itr != l.end(); ++itr) {
00678 if (!GiNaC::is_a<GiNaC::lst>(*itr))
00679
00680 cols = 1;
00681 if (itr->nops() > cols)
00682 cols = itr->nops();
00683 }
00684
00685 GiNaC::matrix &M = *new GiNaC::matrix(rows, cols);
00686 M.setflag(GiNaC::status_flags::dynallocated);
00687
00688 unsigned i;
00689 for (itr = l.begin(), i = 0; itr != l.end(); ++itr, ++i) {
00690 unsigned j;
00691 if (cols == 1) {
00692 M(i, 0) = *itr;
00693 } else {
00694 for (itc = GiNaC::ex_to<GiNaC::lst>(*itr).begin(), j = 0; itc != GiNaC::ex_to<GiNaC::lst>(*itr).end(); ++itc, ++j)
00695 M(i, j) = *itc;
00696 }
00697 }
00698 return M;
00699 }
00700
00701
00702 GiNaC::lst matrix_to_lst2(const GiNaC::ex& m) {
00703 if (GiNaC::is_a<GiNaC::matrix>(m)) {
00704 GiNaC::matrix A = GiNaC::ex_to<GiNaC::matrix>(m);
00705 int cols = A.cols();
00706 int rows = A.rows();
00707
00708 GiNaC::lst ret;
00709 if ( cols == 1 ) {
00710 for (int i=0; i<=A.rows()-1; i++) {
00711 ret.append(A(i,0));
00712 }
00713 } else if ( rows == 1 ) {
00714 for (int i=0; i<=A.cols()-1; i++) {
00715 ret.append(A(0,i));
00716 }
00717 } else {
00718 for (int i=0; i<=A.rows()-1; i++) {
00719 GiNaC::lst rl;
00720 for (int j=0; j<=A.cols()-1; j++) {
00721 rl.append(A(i,j));
00722 }
00723 ret.append(rl);
00724 }
00725 }
00726 return ret;
00727 } else {
00728 return GiNaC::lst();
00729 }
00730 }
00731
00732
00733
00734 int find(GiNaC::ex e, GiNaC::lst list){
00735 for (int i=0; i< list.nops(); i++) {
00736 if ( e == list.op(i) ) return i;
00737 }
00738 return -1;
00739 }
00740
00741 void visitor_subst_pow(GiNaC::ex e, ex_ex_map& map, ex_int_map& intmap, string a) {
00742 static int i=0;
00743 if (map.find(e) != map.end()) {
00744 intmap[e] = intmap[e]+1;
00745 return;
00746 }
00747 if (GiNaC::is_exactly_a<GiNaC::power>(e)) {
00748 std::ostringstream s;
00749 s <<a<<i++;
00750 map[e] = GiNaC::symbol(s.str());
00751 intmap[e] = 0;
00752 for (int i=0; i< e.nops(); i++) {
00753 GiNaC::ex e2 = e.op(i);
00754
00755 visitor_subst_pow(e2,map,intmap, a);
00756 }
00757 }
00758 else if (GiNaC::is_a<GiNaC::function>(e)) {
00759 std::ostringstream s;
00760 s <<a<<i++;
00761 map[e] = GiNaC::symbol(s.str());
00762 intmap[e] = 0;
00763 for (int i=0; i< e.nops(); i++) {
00764 GiNaC::ex e2 = e.op(i);
00765
00766 visitor_subst_pow(e2,map,intmap, a);
00767 }
00768 }
00769 else if (GiNaC::is_a<GiNaC::mul>(e)) {
00770 if (e.nops() > 4 && e.nops() < 10 ) {
00771 std::ostringstream s;
00772 s <<a<<i++;
00773 map[e] = GiNaC::symbol(s.str());
00774 intmap[e] = 0;
00775 }
00776
00777 for (int i=0; i< e.nops(); i++) {
00778 GiNaC::ex e2 = e.op(i);
00779 visitor_subst_pow(e2,map,intmap, a);
00780 }
00781 }
00782 else if (GiNaC::is_a<GiNaC::add>(e)) {
00783 for (int i=0; i< e.nops(); i++) {
00784 GiNaC::ex e2 = e.op(i);
00785 visitor_subst_pow(e2,map,intmap,a);
00786 }
00787 }
00788
00789
00790 }
00791
00792
00793
00794
00795 void check_visitor(GiNaC::ex e, GiNaC::lst& exlist) {
00796 if (find(e, exlist) >= 0) return;
00797
00798
00799 if (GiNaC::is_a<GiNaC::numeric>(e)) {
00800 }
00801 else if (GiNaC::is_a<GiNaC::add>(e) ) {
00802
00803
00804 if (e.nops() > 4 && e.nops() < 10 ) exlist.append(e);
00805 for (int i=0; i< e.nops(); i++) {
00806 GiNaC::ex e2 = e.op(i);
00807
00808
00809 check_visitor(e2,exlist);
00810 }
00811 }
00812 else if (GiNaC::is_a<GiNaC::mul>(e)) {
00813 for (int i=0; i< e.nops(); i++) {
00814 GiNaC::ex e2 = e.op(i);
00815
00816 exlist.append(e2);
00817 check_visitor(e2,exlist);
00818 }
00819 }
00820 else if (GiNaC::is_a<GiNaC::lst>(e)) {
00821 for (int i=0; i< e.nops(); i++) {
00822 GiNaC::ex e2 = e.op(i);
00823
00824
00825 check_visitor(e2,exlist);
00826 }
00827 }
00828 else if (GiNaC::is_exactly_a<GiNaC::power>(e)) {
00829 exlist.append(e);
00830 for (int i=0; i< e.nops(); i++) {
00831 GiNaC::ex e2 = e.op(i);
00832
00833 check_visitor(e2,exlist);
00834 }
00835 }
00836 else if (GiNaC::is_a<GiNaC::function>(e)) {
00837 exlist.append(e);
00838 for (int i=0; i< e.nops(); i++) {
00839 GiNaC::ex e2 = e.op(i);
00840
00841 check_visitor(e2,exlist);
00842 }
00843 }
00844
00845
00846
00847 else {
00848
00849
00850 }
00851
00852 exlist.sort();
00853 exlist.unique();
00854 }
00855
00856
00857 string istr(string a, int b) {
00858 std::ostringstream s;
00859 s <<a<<b;
00860 return s.str();
00861 }
00862
00863 void EQUAL_OR_DIE(GiNaC::ex e, char* s) {
00864 if (!compare(e, string(s))) {
00865 cout <<"ERROR: expression e: " <<e<<" is not equal to "<<s<<endl;
00866 exit(-1);
00867 }
00868 }
00869
00870
00871 bool compare(GiNaC::ex e, string s) {
00872 std::ostringstream ss;
00873 ss<<e;
00874 string es = ss.str();
00875 if ( es == s) return true;
00876 else return false;
00877 }
00878
00879 void matrix_from_equations(const GiNaC::ex &eqns, const GiNaC::ex &symbols, GiNaC::matrix& A, GiNaC::matrix& b) {
00880
00881 GiNaC::matrix sys(eqns.nops(),symbols.nops());
00882 GiNaC::matrix rhs(eqns.nops(),1);
00883 GiNaC::matrix vars(symbols.nops(),1);
00884
00885 for (size_t r=0; r<eqns.nops(); r++) {
00886 const GiNaC::ex eq = eqns.op(r).op(0)-eqns.op(r).op(1);
00887 GiNaC::ex linpart = eq;
00888 for (size_t c=0; c<symbols.nops(); c++) {
00889 const GiNaC::ex co = eq.coeff(GiNaC::ex_to<GiNaC::symbol>(symbols.op(c)),1);
00890 linpart -= co*symbols.op(c);
00891 sys(r,c) = co;
00892 }
00893 linpart = linpart.expand();
00894 rhs(r,0) = -linpart;
00895 }
00896 A = sys;
00897 b = rhs;
00898 }
00899
00900
00901 void print(std::map<std::pair<int,int>, GiNaC::ex>& A) {
00902 map<std::pair<int,int>,GiNaC::ex>::iterator iter;
00903 for (iter = A.begin(); iter != A.end() ; iter++) {
00904 cout <<"A["<<(*iter).first.first<<","<<(*iter).first.second<<"]="<<(*iter).second<<endl;
00905 }
00906 }
00907
00908
00909 GiNaC::ex legendre1D(const GiNaC::symbol x, int n){
00910 GiNaC::ex P;
00911
00912
00913 P=1/(pow(2,n)*GiNaC::factorial(n))*GiNaC::diff(GiNaC::pow((x*x-1),n),x,n);
00914
00915
00916
00917
00918 return P;
00919 }
00920
00921
00922 GiNaC::ex legendre(int order, int nsd, const string s){
00923
00924 GiNaC::ex leg;
00925 GiNaC::ex A;
00926 GiNaC::lst basis;
00927 int dof;
00928
00929 GiNaC::ex b;
00930
00931
00932 if(nsd == 1){
00933 dof = order+1;
00934 A = GiNaC::symbolic_matrix(1,dof,s);
00935 int o=0;
00936 for(GiNaC::const_iterator i = A.begin(); i!=A.end(); ++i){
00937 b= legendre1D(x,o);
00938 leg+= (*i)*b;
00939 basis.append(b);
00940 o++;
00941 }
00942 }
00943
00944 else if(nsd == 2){
00945
00946
00947
00948
00949
00950
00951 dof = (order+1)*(order+2)/2;
00952 A = GiNaC::symbolic_matrix(1,dof,s);
00953 size_t i=0;
00954 for (int o = 0; o <= order; o++) {
00955 for (int d = 0; d <= o; d++) {
00956 b = legendre1D(y,d)*legendre1D(x,o-d);
00957 leg += A.op(i)*b;
00958 basis.append(b);
00959 i++;
00960
00961 }
00962 }
00963 }
00964 else if(nsd==3){
00965 dof = 0;
00966 for (int j=0; j<= order; j++) {
00967 dof += (j+1)*(j+2)/2;
00968 }
00969 A = GiNaC::symbolic_matrix(1, dof , s);
00970
00971
00972 size_t i=0;
00973 for (int o = 0; o <= order; o++) {
00974 for (int d = 0; d <= o; d++) {
00975 for (int f = 0; f <= o; f++) {
00976 if ( o-d-f >= 0) {
00977 b = legendre1D(y,f)*legendre1D(z,d)*legendre1D(x,o-d-f);
00978 leg += A.op(i)*b;
00979 basis.append(b);
00980 i++;
00981 }
00982 }
00983 }
00984 }
00985 }
00986 return GiNaC::lst(leg,matrix_to_lst2(A), basis);
00987 }
00988
00989 GiNaC::lst legendrev(int no_fields, int order, int nsd, const string a) {
00990 GiNaC::lst ret1;
00991 GiNaC::lst ret2;
00992 GiNaC::lst ret3;
00993 GiNaC::lst basis_tmp;
00994 for (int i=1; i<= no_fields; i++) {
00995 GiNaC::lst basis;
00996 std::ostringstream s;
00997 s <<a<<""<<i<<"_";
00998 GiNaC::ex polspace = legendre(order, nsd, s.str());
00999 ret1.append(polspace.op(0));
01000 ret2.append(polspace.op(1));
01001 basis_tmp = GiNaC::ex_to<GiNaC::lst>(polspace.op(2));
01002 for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin();
01003 basis_iterator != basis_tmp.end(); ++basis_iterator) {
01004 GiNaC::lst tmp_lst;
01005 for (int d=1; d<=no_fields; d++) tmp_lst.append(0);
01006 tmp_lst.let_op(i-1) = (*basis_iterator);
01007 ret3.append(tmp_lst);
01008 }
01009 }
01010 return GiNaC::lst(ret1,ret2,ret3);
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021