SyFi 0.3
|
00001 // Copyright (C) 2006-2009 Kent-Andre Mardal and Simula Research Laboratory. 00002 // Licensed under the GNU GPL Version 2, or (at your option) any later version. 00003 00004 #include "symbol_factory.h" 00005 #include "utilities.h" 00006 00007 #include <stdexcept> 00008 #include <sstream> 00009 #include <map> 00010 using namespace std; 00011 using namespace GiNaC; 00012 00013 namespace SyFi 00014 { 00015 00016 // TODO: make structure for these 00017 //namespace space 00018 //{ 00019 unsigned int nsd = 2; 00020 //GiNaC::symbol p[4]; 00021 GiNaC::symbol x("(x is not initialized since initSyFi has never been called)"); 00022 GiNaC::symbol y("(y is not initialized since initSyFi has never been called)"); 00023 GiNaC::symbol z("(z is not initialized since initSyFi has never been called)"); 00024 GiNaC::symbol t("(t is not initialized since initSyFi has never been called)"); 00025 GiNaC::lst p; 00026 //} 00027 00028 GiNaC::symbol infinity("(infinity is not initialized since initSyFi has never been called)"); 00029 GiNaC::symbol DUMMY("(DUMMY is not initialized since initSyFi has never been called)"); 00030 00031 // Initialize global variables of SyFi 00032 void initSyFi(unsigned int nsd_) 00033 { 00034 // initSyFi uses the global coordinates x for nsd == 1 00035 // initSyFi uses the global coordinates x,y for nsd == 2 00036 // initSyFi uses the global coordinates x,y,z for nsd == 3 00037 // when nsd > 3 the coordinates can be found in the p, which is of type lst 00038 00039 // FIXME: this whole thing is just a mess, but it's a nontrivial job to fix it all over syfi... 00040 00041 SyFi::nsd = nsd_; 00042 SyFi::t = get_symbol("t"); 00043 00044 SyFi::infinity = get_symbol("infinity"); 00045 SyFi::DUMMY = get_symbol("DUMMY"); 00046 00047 SyFi::x = get_symbol("(SyFi::x is not initialized)"); 00048 SyFi::y = get_symbol("(SyFi::y is not initialized)"); 00049 SyFi::z = get_symbol("(SyFi::z is not initialized)"); 00050 00051 /* 00052 std::cout << "SyFi::p before remove_all:" << std::endl; 00053 std::cout << SyFi::p << std::endl; 00054 */ 00055 00056 SyFi::p.remove_all(); 00057 00058 /* 00059 std::cout << "SyFi::p after remove_all:" << std::endl; 00060 std::cout << SyFi::p << std::endl; 00061 */ 00062 00063 if ( nsd > 3 ) 00064 { 00065 SyFi::x = get_symbol("(SyFi::x is an invalid symbol when nsd>3)"); 00066 SyFi::y = get_symbol("(SyFi::y is an invalid symbol when nsd>3)"); 00067 SyFi::z = get_symbol("(SyFi::z is an invalid symbol when nsd>3)"); 00068 00069 ex tmp = get_symbolic_vector(nsd, "x"); 00070 for (unsigned int i=0; i<tmp.nops(); i++) 00071 { 00072 p.append(tmp.op(i)); 00073 } 00074 } 00075 else 00076 { 00077 if ( nsd > 0 ) 00078 { 00079 SyFi::x = get_symbol("x"); 00080 SyFi::p.append(SyFi::x); 00081 } 00082 if ( nsd > 1 ) 00083 { 00084 SyFi::y = get_symbol("y"); 00085 SyFi::p.append(SyFi::y); 00086 } 00087 if ( nsd > 2 ) 00088 { 00089 SyFi::z = get_symbol("z"); 00090 SyFi::p.append(SyFi::z); 00091 } 00092 } 00093 00094 /* 00095 std::cout << "SyFi::p at end of initSyFi:" << std::endl; 00096 std::cout << SyFi::p << std::endl; 00097 */ 00098 } 00099 00100 // =========== symbol factory implementation from ginac manual page 14-15 00101 00102 map<string, symbol> symbol_collection; 00103 00104 bool symbol_exists(const string & name) 00105 { 00106 return symbol_collection.find(name) != symbol_collection.end(); 00107 } 00108 00109 const symbol & get_symbol(const string & name) 00110 { 00111 map<string, symbol>::iterator i = symbol_collection.find(name); 00112 if( i != symbol_collection.end() ) 00113 { 00114 return i->second; 00115 } 00116 return symbol_collection.insert(make_pair(name, symbol(name))).first->second; 00117 } 00118 00119 const symbol & isymb(const string & a, int b) 00120 { 00121 return get_symbol(istr(a,b)); 00122 } 00123 00124 const symbol & isymb(const string & a, int b, int c) 00125 { 00126 return get_symbol(istr(a,b,c)); 00127 } 00128 00129 GiNaC::ex get_symbolic_vector(int m, const std::string & basename) 00130 { 00131 GiNaC::matrix A(m,1); 00132 for(int i=0; i<m; i++) 00133 { 00134 A.set(i, 0, isymb(basename, i)); 00135 } 00136 GiNaC::ex e = A; 00137 return e; 00138 } 00139 00140 GiNaC::ex get_symbolic_matrix(int m, int n, const std::string & basename) 00141 { 00142 GiNaC::matrix A(m,n); 00143 for(int i=0; i<m; i++) 00144 { 00145 for(int j=0; j<n; j++) 00146 { 00147 A.set(i, j, isymb(basename, i,j)); 00148 } 00149 } 00150 GiNaC::ex e = A; 00151 return e; 00152 } 00153 00154 } //namespace SyFi