SyFi  0.3
syfi/symbol_factory.cpp
Go to the documentation of this file.
00001 // Copyright (C) 2006-2009 Kent-Andre Mardal and Simula Research Laboratory
00002 //
00003 // This file is part of SyFi.
00004 //
00005 // SyFi is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // SyFi is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with SyFi. If not, see <http://www.gnu.org/licenses/>.
00017 
00018 #include "symbol_factory.h"
00019 #include "utilities.h"
00020 
00021 #include <stdexcept>
00022 #include <sstream>
00023 #include <map>
00024 using namespace std;
00025 using namespace GiNaC;
00026 
00027 namespace SyFi
00028 {
00029 
00030         // TODO: make structure for these
00031         //namespace space
00032         //{
00033         unsigned int nsd = 2;
00034         //GiNaC::symbol p[4];
00035         GiNaC::symbol x("(x is not initialized since initSyFi has never been called)");
00036         GiNaC::symbol y("(y is not initialized since initSyFi has never been called)");
00037         GiNaC::symbol z("(z is not initialized since initSyFi has never been called)");
00038         GiNaC::symbol t("(t is not initialized since initSyFi has never been called)");
00039         GiNaC::lst    p;
00040         //}
00041 
00042         GiNaC::symbol infinity("(infinity is not initialized since initSyFi has never been called)");
00043         GiNaC::symbol DUMMY("(DUMMY is not initialized since initSyFi has never been called)");
00044 
00045         // Initialize global variables of SyFi
00046         void initSyFi(unsigned int nsd_)
00047         {
00048                 // initSyFi uses the global coordinates x      for nsd == 1
00049                 // initSyFi uses the global coordinates x,y    for nsd == 2
00050                 // initSyFi uses the global coordinates x,y,z  for nsd == 3
00051                 // when nsd > 3 the coordinates can be found in the p, which is of type lst
00052 
00053                 // FIXME: this whole thing is just a mess, but it's a nontrivial job to fix it all over syfi...
00054 
00055                 SyFi::nsd      = nsd_;
00056                 SyFi::t        = get_symbol("t");
00057 
00058                 SyFi::infinity = get_symbol("infinity");
00059                 SyFi::DUMMY    = get_symbol("DUMMY");
00060 
00061                 SyFi::x        = get_symbol("(SyFi::x is not initialized)");
00062                 SyFi::y        = get_symbol("(SyFi::y is not initialized)");
00063                 SyFi::z        = get_symbol("(SyFi::z is not initialized)");
00064 
00065                 /*
00066                 std::cout << "SyFi::p before remove_all:" << std::endl;
00067                 std::cout << SyFi::p << std::endl;
00068                 */
00069 
00070                 SyFi::p.remove_all();
00071 
00072                 /*
00073                 std::cout << "SyFi::p after remove_all:" << std::endl;
00074                 std::cout << SyFi::p << std::endl;
00075                 */
00076 
00077                 if ( nsd  > 3 )
00078                 {
00079                         SyFi::x = get_symbol("(SyFi::x is an invalid symbol when nsd>3)");
00080                         SyFi::y = get_symbol("(SyFi::y is an invalid symbol when nsd>3)");
00081                         SyFi::z = get_symbol("(SyFi::z is an invalid symbol when nsd>3)");
00082 
00083                         ex tmp = get_symbolic_vector(nsd, "x");
00084                         for (unsigned int i=0; i<tmp.nops(); i++)
00085                         {
00086                                 p.append(tmp.op(i));
00087                         }
00088                 }
00089                 else
00090                 {
00091                         if ( nsd  > 0 )
00092                         {
00093                                 SyFi::x = get_symbol("x");
00094                                 SyFi::p.append(SyFi::x);
00095                         }
00096                         if ( nsd  > 1 )
00097                         {
00098                                 SyFi::y = get_symbol("y");
00099                                 SyFi::p.append(SyFi::y);
00100                         }
00101                         if ( nsd  > 2 )
00102                         {
00103                                 SyFi::z = get_symbol("z");
00104                                 SyFi::p.append(SyFi::z);
00105                         }
00106                 }
00107 
00108                 /*
00109                 std::cout << "SyFi::p at end of initSyFi:" << std::endl;
00110                 std::cout << SyFi::p << std::endl;
00111                 */
00112         }
00113 
00114         // =========== symbol factory implementation from ginac manual page 14-15
00115 
00116         map<string, symbol> symbol_collection;
00117 
00118         bool symbol_exists(const string & name)
00119         {
00120                 return symbol_collection.find(name) != symbol_collection.end();
00121         }
00122 
00123         const symbol & get_symbol(const string & name)
00124         {
00125                 map<string, symbol>::iterator i = symbol_collection.find(name);
00126                 if( i != symbol_collection.end() )
00127                 {
00128                         return i->second;
00129                 }
00130                 return symbol_collection.insert(make_pair(name, symbol(name))).first->second;
00131         }
00132 
00133         const symbol & isymb(const string & a, int b)
00134         {
00135                 return get_symbol(istr(a,b));
00136         }
00137 
00138         const symbol & isymb(const string & a, int b, int c)
00139         {
00140                 return get_symbol(istr(a,b,c));
00141         }
00142 
00143         GiNaC::ex get_symbolic_vector(int m, const std::string & basename)
00144         {
00145                 GiNaC::matrix A(m,1);
00146                 for(int i=0; i<m; i++)
00147                 {
00148                         A.set(i, 0, isymb(basename, i));
00149                 }
00150                 GiNaC::ex e = A;
00151                 return e;
00152         }
00153 
00154         GiNaC::ex get_symbolic_matrix(int m, int n, const std::string & basename)
00155         {
00156                 GiNaC::matrix A(m,n);
00157                 for(int i=0; i<m; i++)
00158                 {
00159                         for(int j=0; j<n; j++)
00160                         {
00161                                 A.set(i, j, isymb(basename, i,j));
00162                         }
00163                 }
00164                 GiNaC::ex e = A;
00165                 return e;
00166         }
00167 
00168 }                                                                //namespace SyFi
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator