tools.cpp

Go to the documentation of this file.
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 //  for (GiNaC::lst::const_iterator i = l.begin(); i != l.end(); ++i)
00019 //    cout << *i << endl;
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;  // contains the polynom  
00204   GiNaC::lst ret2;  // contains the coefficients   
00205   GiNaC::lst ret3;  // constains the basis functions  
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; // ex to return   
00229   int dof; // degrees of freedom  
00230   GiNaC::ex A;    // ex holding the coefficients a_0 .. a_dof  
00231   GiNaC::lst basis; 
00232 
00233 
00234   if (nsd == 1) {
00235     /* 1D: 
00236      * P^n = a_0 + a_1*x + .... + a_n*x^n 
00237      * dof : n+1
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     /* 2D: structure of coefficients (a_i)  
00251      * [ a_0      a_1 x     a_3 x^2     a_6 x^3  
00252      * [ a_2 y    a_4 xy    a_7 x^2y  
00253      * [ a_5 y^2  a_8 xy^2  
00254      * [ a_9 y^3 
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   /* Similar structure as in 2D, but 
00271    * structured as a tetraheder, i.e., 
00272    *   a_o + a_1 x + a_2 y + a_3 z 
00273    * + a_4 x^2 + a_5 xy +  
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;  // contains the polynom  
00300   GiNaC::lst ret2;  // contains the coefficients   
00301   GiNaC::lst ret3;  // constains the basis functions  
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 /* Old Code: 
00324   GiNaC::lst ret; 
00325   for (int i=1; i<= nsd; i++) { 
00326     std::ostringstream s; 
00327     s <<a<<"^"<<i<<"_"; 
00328     GiNaC::ex p = pol(order, nsd, s.str()); 
00329     ret.append(p); 
00330   }
00331   return ret; 
00332   */
00333 }
00334 
00335 
00336 GiNaC::ex polb(int order, int nsd, const string a) {
00337 
00338   GiNaC::ex ret; // ex to return   
00339   int dof; // degrees of freedom  
00340   GiNaC::ex A;    // ex holding the coefficients a_0 .. a_dof  
00341   GiNaC::lst basis; 
00342 
00343   if (nsd == 1) {
00344     /* 1D: 
00345      * P^n = a_0 + a_1*x + .... + a_n*x^n 
00346      * dof : n+1
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     /* 2D: structure of coefficients (a_i)  
00360      * [ a_0      a_1 x     a_3 x^2     a_6 x^3  
00361      * [ a_2 y    a_4 xy    a_7 x^2y  
00362      * [ a_5 y^2  a_8 xy^2  
00363      * [ a_9 y^3 
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   /* Similar structure as in 2D, but 
00383    * structured as a tetraheder, i.e., 
00384    *   a_o + a_1 x + a_2 y + a_3 z 
00385    * + a_4 x^2 + a_5 xy +  
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 //      if (! (l == 0 && r == 0 ) )  eqs.append(l == r); OLD VERSION 
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); // lhs-rhs==0
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 //         ret_m(0,r) = diff(m.op(r),x); 
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 //      return GiNaC::matrix(nsd,1,GiNaC::lst(diff(f,x))); 
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)) /*&& (a.nops() == b.nops())*/ ) { 
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      // Find number of rows and columns
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 //              throw (std::invalid_argument("lst_to_matrix: argument must be a list of lists"));
00680              cols = 1; 
00681          if (itr->nops() > cols)
00682              cols = itr->nops();
00683      }
00684      // Allocate and fill matrix
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 //       cout <<"power e "<<e2<<endl; 
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 //       cout <<"function e "<<e2<<endl; 
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 //  cout <<"ex e "<<e<<endl; 
00799   if (GiNaC::is_a<GiNaC::numeric>(e)) { 
00800   }
00801   else if (GiNaC::is_a<GiNaC::add>(e) ) {
00802 //    cout <<"e "<<e <<endl; 
00803 //    cout <<"e.nops() "<<e.nops() <<endl; 
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 //       cout <<"add e "<<e2<<endl; 
00808 //       exlist.append(e2); 
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 //       cout <<"mul e "<<e2<<endl; 
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 //       cout <<"GiNaC::lst e "<<e2<<endl; 
00824 //       exlist.append(e2); 
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 //       cout <<"power e "<<e2<<endl; 
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 //       cout <<"function e "<<e2<<endl; 
00841        check_visitor(e2,exlist); 
00842     }
00843   }
00844 
00845 
00846 
00847   else {
00848 //       exlist.append(e); 
00849 //    cout <<"atom e "<<e<<endl; 
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         // build matrix from equation system
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); // lhs-rhs==0
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 // Rodrigue's formula for Legendre polynomial of 1D
00912   // The interval [-1, 1]
00913    P=1/(pow(2,n)*GiNaC::factorial(n))*GiNaC::diff(GiNaC::pow((x*x-1),n),x,n);
00914   // -----------------
00915   // The interval [0,1]
00916 //  GiNaC::ex xx = 2*x - 1; 
00917  // P=1/(pow(2,2*n)*GiNaC::factorial(n))*GiNaC::diff(GiNaC::pow((xx*xx-1),n),x,n);
00918   return P;
00919 }
00920 
00921 
00922 GiNaC::ex legendre(int order, int nsd, const string s){
00923   // The Legendre polynomials to be used in FiniteElement
00924   GiNaC::ex leg;
00925   GiNaC::ex A;
00926   GiNaC::lst basis; 
00927   int dof;
00928 
00929   GiNaC::ex b; 
00930 
00931   // 1D
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   // 2D
00944   else if(nsd == 2){  // NB: Only for tensor products on TRIANGLES (not boxes)
00945     /* 2D: structure of coefficients (a_i)
00946      * [ a_0           a_1 P_1(x)           a_3 P_2(x)        a_6 P_3(x)
00947      * [ a_2 P_1(y)    a_4 P_1(x)*P_1(y)    a_7 P_2(x)*P_1(y)
00948      * [ a_5 P_2(y)    a_8 P_1(x)*P_2(y)
00949      * [ a_9 P_3(y)
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;  // contains the polynom  
00991   GiNaC::lst ret2;  // contains the coefficients   
00992   GiNaC::lst ret3;  // constains the basis functions  
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 

Generated on Tue Jun 13 13:18:39 2006 for SyFi by  doxygen 1.4.4