SyFi
0.3
|
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