tools.cpp

Go to the documentation of this file.
00001 #include <tools.h>
00002 
00003 symbol x("x"); 
00004 symbol y("y"); 
00005 symbol z("z"); 
00006 symbol infinity("infinity"); 
00007 symbol DUMMY("DUMMY"); 
00008 
00009 numeric nsd = 2; 
00010 
00011 
00012 /*
00013 void print(exvector& v) {
00014   for (int i=0; i< v.size(); i++) {
00015     cout <<"v["<<i<<"]="<<v[i]<<endl; 
00016   }
00017 }
00018 */
00019 
00020 
00021         
00022 
00023 void print(lst& l) {
00024 //  for (lst::const_iterator i = l.begin(); i != l.end(); ++i)
00025 //    cout << *i << endl;
00026 //
00027   lst::const_iterator i = l.begin(); 
00028   cout <<"lst("<<*i; 
00029   ++i; 
00030 
00031   for (; i != l.end() ; ++i) {
00032     cout << ","<< *i;
00033   }
00034   cout <<");"<<endl; 
00035 }
00036 
00037 void print(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 lst cross(lst& v1, lst& v2) {
00047   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 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 
00061 
00062 ex inner(lst v1, lst v2) {
00063   ex ret; 
00064   if ( v1.nops() != v2.nops() ) {
00065     cout <<"incompatible vectors "<<endl; 
00066     cout <<"v1.nops() "<<v1.nops(); 
00067     cout <<"  v2.nops() "<<v2.nops()<<endl; ; 
00068     return 0; 
00069   }
00070   int i; 
00071   for (i = 0; i <= v1.nops()-1 ; ++i) {
00072           ret += v1.op(i)*v2.op(i);  
00073        
00074   }
00075   return ret; 
00076 }
00077 
00078 lst matvec(matrix& M, lst& x) {
00079   lst ret; 
00080   int nr = M.rows(); 
00081   int nc = M.cols(); 
00082   for (int i = 0; i < nr; i++) {
00083     ex tmp; 
00084     for (int j = 0; j < nc; j++) {
00085        tmp = tmp +  M(i,j)*(x.op(j)); 
00086     }
00087     ret.append(tmp); 
00088   }
00089   return ret; 
00090 }
00091 
00092 
00093 ex inner(exvector& v1, exvector& v2){
00094   ex ret; 
00095   for (int i=0; i< v1.size(); i++) {
00096     ret += v1[i]*v2[i]; 
00097   }
00098   return ret; 
00099 }
00100 
00101 
00102 
00103 ex pol(int order, int nsd, const string a) {
00104   ex ret; // ex to return   
00105   int dof; // degrees of freedom  
00106   ex A;    // ex holding the coefficients a_0 .. a_dof  
00107 
00108   if (nsd == 1) {
00109     /* 1D: 
00110      * P^n = a_0 + a_1*x + .... + a_n*x^n 
00111      * dof : n+1
00112      */ 
00113     dof = order+1; 
00114     A = symbolic_matrix(1,dof, a); 
00115     int o=0; 
00116     for (const_iterator i = A.begin(); i != A.end(); ++i)  {  
00117       ret += (*i)*pow(x,o); 
00118       o++; 
00119     }
00120   }
00121   else if ( nsd == 2) {
00122 
00123     /* 2D: structure of coefficients (a_i)  
00124      * [ a_0      a_1 x     a_3 x^2     a_6 x^3  
00125      * [ a_2 y    a_4 xy    a_7 x^2y  
00126      * [ a_5 y^2  a_8 xy^2  
00127      * [ a_9 y^3 
00128      */
00129     dof = (order+1)*(order+2)/2; 
00130     A = symbolic_matrix(1, dof , a); 
00131 
00132     size_t i=0; 
00133     for (int o = 0; o <= order; o++) {
00134       for (int d = 0; d <= o; d++) { 
00135         ret += A.op(i)*pow(y,d)*pow(x,o-d); 
00136         i++; 
00137       }
00138     }
00139   }
00140   else if (nsd = 3) {
00141 
00142   /* Similar structure as in 2D, but 
00143    * structured as a tetraheder, i.e., 
00144    *   a_o + a_1 x + a_2 y + a_3 z 
00145    * + a_4 x^2 + a_5 xy +  
00146    */
00147     dof = 0; 
00148     for (int j=0; j<= order; j++) { 
00149       dof += (j+1)*(j+2)/2; 
00150     }
00151     A = symbolic_matrix(1, dof , a); 
00152 
00153 
00154     size_t i=0; 
00155     for (int o = 0; o <= order; o++) {
00156       for (int d = 0; d <= o; d++) { 
00157         for (int f = 0; f <= o; f++) { 
00158           if ( o-d-f >= 0) {
00159             ret += A.op(i)*pow(y,f)*pow(z,d)*pow(x,o-d-f);  
00160             i++; 
00161           }
00162         }
00163       }
00164     }
00165   }
00166 
00167   return ret; 
00168 }
00169 
00170 lst polv(int order, int nsd, const string a){
00171   lst ret; 
00172   for (int i=1; i<= nsd; i++) { 
00173     std::ostringstream s; 
00174     s <<a<<"^"<<i<<"_"; 
00175     ex p = pol(order, nsd, s.str()); 
00176     ret.append(p); 
00177   }
00178   return ret; 
00179 }
00180 
00181 
00182 ex polb(int order, int nsd, const string a) {
00183 
00184   ex ret; // ex to return   
00185   int dof; // degrees of freedom  
00186   ex A;    // ex holding the coefficients a_0 .. a_dof  
00187 
00188   if (nsd == 1) {
00189     /* 1D: 
00190      * P^n = a_0 + a_1*x + .... + a_n*x^n 
00191      * dof : n+1
00192      */ 
00193     dof = order+1; 
00194     A = symbolic_matrix(1,dof, a); 
00195     int o=0; 
00196     for (const_iterator i = A.begin(); i != A.end(); ++i)  {  
00197       ret += (*i)*pow(x,o); 
00198       o++; 
00199     }
00200   }
00201   else if ( nsd == 2) {
00202 
00203     /* 2D: structure of coefficients (a_i)  
00204      * [ a_0      a_1 x     a_3 x^2     a_6 x^3  
00205      * [ a_2 y    a_4 xy    a_7 x^2y  
00206      * [ a_5 y^2  a_8 xy^2  
00207      * [ a_9 y^3 
00208      */
00209 
00210 
00211     dof = (order+1)*(order+1); 
00212     A = symbolic_matrix(1, dof , a); 
00213 
00214 
00215     size_t i=0; 
00216     for (int o = 0; o <= order; o++) {
00217       for (int d = 0; d <= order; d++) { 
00218         ret += A.op(i)*pow(y,d)*pow(x,o); 
00219         i++; 
00220       }
00221     }
00222   }
00223   else if (nsd = 3) {
00224 
00225   /* Similar structure as in 2D, but 
00226    * structured as a tetraheder, i.e., 
00227    *   a_o + a_1 x + a_2 y + a_3 z 
00228    * + a_4 x^2 + a_5 xy +  
00229    */
00230     dof = (order+1)*(order+1)*(order+1); 
00231     A = symbolic_matrix(1, dof , a); 
00232 
00233 
00234     size_t i=0; 
00235     for (int o = 0; o <= order; o++) {
00236       for (int d = 0; d <= order; d++) { 
00237         for (int f = 0; f <= order; f++) { 
00238             ret += A.op(i)*pow(y,f)*pow(z,d)*pow(x,o);  
00239             i++; 
00240         }
00241       }
00242     }
00243   }
00244 
00245   return ret; 
00246 }
00247 
00248 ex div(lst& v) {
00249   nsd = v.nops();  
00250   ex ret; 
00251   if (nsd == 1) {
00252     ret = v.op(0).diff(x);
00253   }
00254   else if (nsd == 2) {
00255     ret = v.op(0).diff(x) + v.op(1).diff(y); 
00256   }
00257   else if (nsd == 3) {
00258     ret = v.op(0).diff(x) + v.op(1).diff(y) + v.op(2).diff(z); 
00259   }
00260   return ret; 
00261 }
00262 
00263 ex div(exvector& v) {
00264   ex ret; 
00265   if (nsd == 2) {
00266     ret = v[0].diff(x) + v[1].diff(y); 
00267   }
00268   else if (nsd == 3) {
00269     ret = v[0].diff(x) + v[1].diff(y) + v[2].diff(z); 
00270   }
00271   return ret; 
00272 }
00273 
00274 lst coeffs(lst pols) {
00275   lst cc; 
00276   lst tmp; 
00277   for (int i=0; i<= pols.nops()-1; i++) {
00278     tmp = coeffs(pols.op(i)); 
00279     cc = collapse(lst(cc, tmp)); 
00280   }
00281   return cc; 
00282 }
00283 
00284 lst coeffs(ex pol) {
00285   lst cc; 
00286   ex c, b; 
00287   for (int i=pol.ldegree(x); i<=pol.degree(x); ++i) {
00288     for (int j=pol.ldegree(y); j<=pol.degree(y); ++j) {
00289       for (int k=pol.ldegree(z); k<=pol.degree(z); ++k) {
00290         c = pol.coeff(x,i).coeff(y, j).coeff(z,k); 
00291         if ( c != 0 ) cc.append(c); 
00292       }
00293     }
00294   }
00295   return cc; 
00296 }
00297 
00298 
00299 
00300 exvector coeff(ex pol) {
00301   exvector cc; 
00302   ex c, b; 
00303   for (int i=pol.ldegree(x); i<=pol.degree(x); ++i) {
00304     for (int j=pol.ldegree(y); j<=pol.degree(y); ++j) {
00305       for (int k=pol.ldegree(z); k<=pol.degree(z); ++k) {
00306         c = pol.coeff(x,i).coeff(y, j).coeff(z,k); 
00307         if ( c != 0 ) cc.insert(cc.begin(),c); 
00308       }
00309     }
00310   }
00311   return cc; 
00312 }
00313 
00314 int dirac(int i, int j) {
00315   if (i==j) return 1; 
00316   else return 0; 
00317 }
00318 
00319 ex_ex_map pol2basisandcoeff(ex e) { 
00320   ex c; 
00321   ex b; 
00322   ex_ex_map map; 
00323   for (int i=e.ldegree(x); i<=e.degree(x); ++i) {
00324     for (int j=e.ldegree(y); j<=e.degree(y); ++j) {
00325       for (int k=e.ldegree(z); k<=e.degree(z); ++k) {
00326         c = e.coeff(x,i).coeff(y, j).coeff(z,k); 
00327         b = pow(x,i)*pow(y,j)*pow(z,k); 
00328         map[b] = c;  
00329       }
00330     }
00331   }
00332   return map; 
00333 }
00334 
00335 void print(ex_int_map map) {
00336   ex b; 
00337   int c; 
00338   ex_int_it iter; 
00339   iter = map.begin(); 
00340   cout <<"{" <<b<<":"<<c; 
00341   for (iter = map.begin(); iter != map.end(); iter++) {  
00342     b = (*iter).first; c = map[b]; 
00343     cout <<", "<<b<<":"<<c; 
00344   }
00345   cout <<"}"<<endl; 
00346 
00347 }
00348 
00349 
00350 
00351 void print(ex_ex_map map) {
00352   ex b; 
00353   ex c; 
00354   ex_ex_it iter; 
00355   iter = map.begin(); 
00356   cout <<"{" <<b<<":"<<c; 
00357   for (iter = map.begin(); iter != map.end(); iter++) {  
00358     b = (*iter).first; c = map[b]; 
00359     cout <<", "<<b<<":"<<c; 
00360   }
00361   cout <<"}"<<endl; 
00362 
00363 }
00364 
00365 
00366 lst ex2equations(ex rel) {
00367   ex lhs = rel.lhs();  
00368   ex rhs = rel.rhs(); 
00369 
00370   ex l; 
00371   ex r; 
00372 
00373   lst eqs; 
00374 
00375   for (int i=lhs.ldegree(x); i<=lhs.degree(x); ++i) {
00376     for (int j=lhs.ldegree(y); j<=lhs.degree(y); ++j) {
00377       for (int k=lhs.ldegree(z); k<=lhs.degree(z); ++k) {
00378         l = lhs.coeff(x,i).coeff(y, j).coeff(z,k); 
00379         r = rhs.coeff(x,i).coeff(y, j).coeff(z,k); 
00380 //      if (! (l == 0 && r == 0 ) )  eqs.append(l == r); OLD VERSION 
00381         if ( (l != 0 && (r == 0 || r == 1) ) )  eqs.append(l == r); 
00382       }
00383     }
00384   }
00385   eqs.sort(); 
00386   return eqs; 
00387 }
00388 
00389 lst collapse(lst l) {
00390   lst lc;  
00391   lst::const_iterator iter1, iter2; 
00392 
00393   for (iter1 = l.begin(); iter1 != l.end(); ++iter1) {
00394      if (is_a<lst>(*iter1)) {
00395        for (iter2 = ex_to<lst>(*iter1).begin(); iter2 != ex_to<lst>(*iter1).end(); ++iter2) {
00396           lc.append(*iter2); 
00397        }
00398      } else {
00399        lc.append(*iter1); 
00400      }
00401   }
00402   lc.sort(); 
00403   lc.unique(); 
00404 return lc; 
00405 }
00406 
00407 
00408 matrix equations2matrix(const ex &eqns, const ex &symbols) {
00409 
00410   cout <<"no equations "<<eqns.nops()<<endl; 
00411   cout <<"no variables "<<symbols.nops()<<endl; 
00412         
00413   matrix sys(eqns.nops(),symbols.nops());
00414   matrix rhs(eqns.nops(),1);
00415   matrix vars(symbols.nops(),1);
00416         
00417   for (size_t r=0; r<eqns.nops(); r++) {
00418     const ex eq = eqns.op(r).op(0)-eqns.op(r).op(1); // lhs-rhs==0
00419     ex linpart = eq;
00420     for (size_t c=0; c<symbols.nops(); c++) {
00421       const ex co = eq.coeff(ex_to<symbol>(symbols.op(c)),1);
00422       linpart -= co*symbols.op(c);
00423       sys(r,c) = co;
00424     }
00425     linpart = linpart.expand();
00426     rhs(r,0) = -linpart;
00427   }
00428   cout <<"matrix "<<sys<<endl; 
00429   cout <<"rhs "<<rhs<<endl; 
00430   cout <<"vars"<<vars<<endl; 
00431   return sys; 
00432 }
00433 
00434 lst grad(ex f) {
00435   if (nsd == 1) {
00436     return lst(diff(f,x)); 
00437   } else if ( nsd == 2) {
00438     return lst(diff(f,x), diff(f,y));  
00439   } else if ( nsd == 3) {
00440     return lst(diff(f,x), diff(f,y), diff(f,z));  
00441   } else {
00442     //FIXME: proper error handling
00443     cout <<"THIS SHOULD NEVER HAPPEN"; 
00444     return lst(); 
00445   }
00446 
00447 }
00448 
00449 lst lst_equals(ex a, ex b) { 
00450   lst ret; 
00451   if ( (is_a<lst>(a)) && (is_a<lst>(b)) /*&& (a.nops() == b.nops())*/ ) { 
00452     for (int i=0; i<= a.nops()-1; i++) {
00453       ret.append(b.op(i) == a.op(i)); 
00454     }
00455   } else if ( !(is_a<lst>(a)) && !(is_a<lst>(b))) { 
00456       ret.append(b == a); 
00457   } else if ( !(is_a<lst>(a)) && (is_a<lst>(b))) { 
00458       ret.append(b.op(0) == a); 
00459   } else {
00460       //FIXME: proper error handling
00461       cout <<"THIS SHOULD NEVER HAPPEN"<<endl;    
00462   }
00463   return ret; 
00464 }
00465 
00466 ex lst_to_matrix2(const lst& l)
00467 {
00468      lst::const_iterator itr, itc;
00469  
00470      // Find number of rows and columns
00471      size_t rows = l.nops(), cols = 0;
00472      for (itr = l.begin(); itr != l.end(); ++itr) {
00473          if (!is_a<lst>(*itr))
00474 //              throw (std::invalid_argument("lst_to_matrix: argument must be a list of lists"));
00475              cols = 1; 
00476          if (itr->nops() > cols)
00477              cols = itr->nops();
00478      }
00479      // Allocate and fill matrix
00480      matrix &M = *new matrix(rows, cols);
00481      M.setflag(status_flags::dynallocated);
00482  
00483      unsigned i;
00484      for (itr = l.begin(), i = 0; itr != l.end(); ++itr, ++i) {
00485          unsigned j;
00486          if (cols == 1) {
00487              M(i, 0) = *itr;
00488          } else {
00489            for (itc = ex_to<lst>(*itr).begin(), j = 0; itc != ex_to<lst>(*itr).end(); ++itc, ++j)
00490                M(i, j) = *itc;
00491          }
00492      }
00493      return M;
00494 }
00495 
00496 
00497 lst matrix_to_lst2(const ex& m) {
00498    //FIXME : should check that this is a matrix 
00499    if (is_a<matrix>(m)) {
00500      matrix A = ex_to<matrix>(m);  
00501      int cols = A.cols(); 
00502      int rows = A.rows(); 
00503   
00504   
00505      lst ret; 
00506      if ( cols == 1) {
00507        for (int i=0; i<=A.rows()-1; i++) { 
00508          ret.append(A(i,0)); 
00509        }
00510      } else {
00511        for (int i=0; i<=A.rows()-1; i++) { 
00512          lst rl; 
00513          for (int j=0; j<=A.cols()-1; j++) { 
00514            rl.append(A(i,j)); 
00515          }
00516          ret.append(rl); 
00517        }
00518      }
00519      return ret; 
00520    } else { 
00521      return lst(); 
00522    }
00523 
00524 }
00525 
00526 
00527 
00528 int find(ex e, lst list){
00529   for (int i=0; i< list.nops(); i++) {
00530     if ( e == list.op(i) ) return i; 
00531   }
00532   return -1; 
00533 }
00534 
00535 void visitor_subst_pow(ex e, ex_ex_map& map, ex_int_map& intmap, string a) {  
00536   static int i=0;  
00537   if (map.find(e) != map.end()) { 
00538     intmap[e] = intmap[e]+1;
00539     return;   
00540   }
00541   if (is_exactly_a<power>(e)) { 
00542     std::ostringstream s; 
00543     s <<a<<i++; 
00544     map[e] = symbol(s.str()); 
00545     intmap[e] = 0;  
00546     for (int i=0; i< e.nops(); i++) { 
00547        ex e2 = e.op(i);  
00548 //       cout <<"power e "<<e2<<endl; 
00549        visitor_subst_pow(e2,map,intmap, a); 
00550     }
00551   }
00552   else if (is_a<function>(e)) { 
00553     std::ostringstream s; 
00554     s <<a<<i++; 
00555     map[e] = symbol(s.str()); 
00556     intmap[e] = 0;  
00557     for (int i=0; i< e.nops(); i++) { 
00558        ex e2 = e.op(i);  
00559 //       cout <<"function e "<<e2<<endl; 
00560        visitor_subst_pow(e2,map,intmap, a); 
00561     }
00562   }
00563   else if (is_a<mul>(e)) { 
00564     if (e.nops() > 4 && e.nops() < 10 ) { 
00565       std::ostringstream s; 
00566       s <<a<<i++; 
00567       map[e] = symbol(s.str()); 
00568       intmap[e] = 0;  
00569     }
00570 
00571     for (int i=0; i< e.nops(); i++) { 
00572        ex e2 = e.op(i);  
00573        visitor_subst_pow(e2,map,intmap, a); 
00574     }
00575   }
00576   else if (is_a<add>(e)) { 
00577     for (int i=0; i< e.nops(); i++) { 
00578        ex e2 = e.op(i);  
00579        visitor_subst_pow(e2,map,intmap,a); 
00580     }
00581   }
00582 
00583 
00584 }
00585 
00586 
00587 
00588 
00589 void check_visitor(ex e, lst& exlist) {
00590   if (find(e, exlist) >= 0) return;   
00591 
00592 //  cout <<"ex e "<<e<<endl; 
00593   if (is_a<numeric>(e)) { 
00594   }
00595   else if (is_a<add>(e) ) {
00596 //    cout <<"e "<<e <<endl; 
00597 //    cout <<"e.nops() "<<e.nops() <<endl; 
00598     if (e.nops() > 4 && e.nops() < 10 ) exlist.append(e); 
00599     for (int i=0; i< e.nops(); i++) { 
00600        ex e2 = e.op(i);  
00601 //       cout <<"add e "<<e2<<endl; 
00602 //       exlist.append(e2); 
00603        check_visitor(e2,exlist); 
00604     }
00605   } 
00606   else if (is_a<mul>(e)) { 
00607     for (int i=0; i< e.nops(); i++) { 
00608        ex e2 = e.op(i);  
00609 //       cout <<"mul e "<<e2<<endl; 
00610        exlist.append(e2); 
00611        check_visitor(e2,exlist); 
00612     }
00613   }
00614   else if (is_a<lst>(e)) { 
00615     for (int i=0; i< e.nops(); i++) { 
00616        ex e2 = e.op(i);  
00617 //       cout <<"lst e "<<e2<<endl; 
00618 //       exlist.append(e2); 
00619        check_visitor(e2,exlist); 
00620     }
00621   }
00622   else if (is_exactly_a<power>(e)) { 
00623     exlist.append(e); 
00624     for (int i=0; i< e.nops(); i++) { 
00625        ex e2 = e.op(i);  
00626 //       cout <<"power e "<<e2<<endl; 
00627        check_visitor(e2,exlist); 
00628     }
00629   }
00630   else if (is_a<function>(e)) { 
00631     exlist.append(e); 
00632     for (int i=0; i< e.nops(); i++) { 
00633        ex e2 = e.op(i);  
00634 //       cout <<"function e "<<e2<<endl; 
00635        check_visitor(e2,exlist); 
00636     }
00637   }
00638 
00639 
00640 
00641   else {
00642 //       exlist.append(e); 
00643 //    cout <<"atom e "<<e<<endl; 
00644   }
00645 
00646   exlist.sort(); 
00647   exlist.unique(); 
00648 }
00649 
00650 
00651 string istr(string a, int b) {
00652   std::ostringstream s; 
00653   s <<a<<b; 
00654   return s.str(); 
00655 }
00656 
00657 void EQUAL_OR_DIE(ex e, char* s) {
00658   if (!compare(e, string(s))) { 
00659     cout <<"ERROR: expression e: " <<e<<" is not equal to "<<s<<endl; 
00660     exit(-1); 
00661   }
00662 }
00663 
00664 
00665 bool compare(ex e, string s) { 
00666   std::ostringstream ss; 
00667   ss<<e; 
00668   string es = ss.str(); 
00669   if ( es == s) return true;  
00670   else return false; 
00671 }
00672 

Generated on Tue Nov 22 11:10:22 2005 for SyFi by  doxygen 1.4.4