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