18 void Pair::accept(GiNaC::visitor & v)
const {
if (
visitor *p =
dynamic_cast<visitor *
>(&v)) p->visit(*
this);
else inherited::accept(v); }
35 if(p1.compare(p2)>0) {
49 if(i1.compare(i2)>0) {
73 if(!is_a<Pair>(other))
throw Error(
"Pair::compare_same_type");
74 const Pair &o =
static_cast<const Pair &
>(other);
75 int c1 = lr[0].compare(o.lr[0]);
77 int c2 = lr[1].compare(o.lr[1]);
82 if(!is_a<Pair>(other))
throw Error(
"Pair::is_equal_same_type");
83 const Pair &o =
static_cast<const Pair &
>(other);
84 if(!lr[0].is_equal(o.lr[0]))
return false;
85 return lr[1].is_equal(o.lr[1]);
94 c.s << lr[0] <<
"." << lr[1];
103 if(is_a<Vector>(lr[0]) && is_a<Vector>(lr[1])) c << lr[0] <<
"." << lr[1];
104 else if(is_a<Vector>(lr[0]) && is_a<Index>(lr[1])) c << lr[0] <<
"(" << lr[1] <<
")";
105 else if(is_a<Index>(lr[0]) && is_a<Index>(lr[1])) c <<
"d_(" << lr[0] <<
"," << lr[1] <<
")";
114 if(is_a<Vector>(lr[0]) && is_a<Vector>(lr[1])) c <<
"SPD[" << lr[0] <<
"," << lr[1] <<
"]";
115 else if(is_a<Vector>(lr[0]) && is_a<Index>(lr[1])) c <<
"FVD[" << lr[0] <<
"," << lr[1] <<
"]";
116 else if(is_a<Index>(lr[0]) && is_a<Index>(lr[1])) {
117 auto ii = ex_to<Index>(lr[0]);
118 if(ii.type == Index::Type::VD) c <<
"MTD[" << lr[0] <<
"," << lr[1] <<
"]";
119 else if(ii.type ==
Index::Type::CF) c <<
"SUNFDelta[" << lr[0] <<
"," << lr[1] <<
"]";
120 else if(ii.type ==
Index::Type::CA) c <<
"SUNDelta[" << lr[0] <<
"," << lr[1] <<
"]";
121 else throw Error(
"Pair::fc_print unexpected.");
130 ensure_if_modifiable();
135 if(flags & status_flags::evaluated)
return *
this;
136 else if(!is_a<Vector>(lr[0]) && !is_a<Index>(lr[0]))
return SP(lr[0],lr[1]);
137 else if(!is_a<Vector>(lr[1]) && !is_a<Index>(lr[1]))
return SP(lr[0],lr[1]);
138 else if((is_a<Vector>(lr[0]) && is_a<Vector>(lr[1])))
139 return Pair(ex_to<Vector>(lr[0]),ex_to<Vector>(lr[1])).hold();
140 else if((is_a<Index>(lr[0]) && is_a<Index>(lr[1])))
141 return Pair(ex_to<Index>(lr[0]),ex_to<Index>(lr[1])).hold();
142 else if((is_a<Index>(lr[0]) && is_a<Vector>(lr[1])))
143 return Pair(ex_to<Vector>(lr[1]),ex_to<Index>(lr[0])).hold();
144 else return this->hold();
148 inherited::archive(n);
149 for(
int i=0; i<2; i++) n.add_ex(
"lr"+to_string(i), lr[i]);
153 inherited::read_archive(n);
154 for(
int i=0; i<2; i++) {
155 n.find_ex(
"lr"+to_string(i), lr[i]);
166 ex
SP(
const ex &
a,
bool use_map) {
return SP(
a,
a,use_map); }
175 ex
SP(
const ex &
a,
const ex & b,
bool use_map) {
177 if(is_a<Vector>(
a) && is_a<Vector>(b)) ret_sp =
Pair(ex_to<Vector>(
a), ex_to<Vector>(b));
178 else if(is_a<Vector>(
a) && is_a<Index>(b)) ret_sp =
Pair(ex_to<Vector>(
a), ex_to<Index>(b));
179 else if(is_a<Index>(
a) && is_a<Vector>(b)) ret_sp =
Pair(ex_to<Vector>(b), ex_to<Index>(
a));
180 else if(is_a<Index>(
a) && is_a<Index>(b)) ret_sp =
Pair(ex_to<Index>(
a), ex_to<Index>(b));
181 if(is_a<Pair>(ret_sp)) {
182 if(use_map)
return ret_sp.subs(
SP_map);
187 auto aex = expand(
a);
188 auto bex = expand(b);
189 if(is_zero(aex) || is_zero(bex))
return 0;
191 for(
auto item : aex) alst.append(item);
192 }
else alst.append(aex);
193 for(
int i=0; i<alst.nops(); i++) {
194 if(!is_a<mul>(alst.op(i))) alst.let_op(i) = lst{alst.op(i)};
197 for(
auto ii : alst.op(i)) {
198 if(is_a<Vector>(ii) || is_a<Index>(ii)) {
199 if(!is_zero(v-1))
throw Error(
"Error Found in SP @1 : "+
ex2str(alst));
203 if(is_zero(v-1))
throw Error(
"Error Found in SP @2 : "+
ex2str(alst));
204 alst.let_op(i) = lst{c,v};
208 for(
auto item : bex) blst.append(item);
209 }
else blst.append(bex);
210 for(
int i=0; i<blst.nops(); i++) {
211 if(!is_a<mul>(blst.op(i))) blst.let_op(i) = lst{blst.op(i)};
214 for(
auto ii : blst.op(i)) {
215 if(is_a<Vector>(ii) || is_a<Index>(ii)) {
216 if(!is_zero(v-1))
throw Error(
"Error Found in SP @3");
220 if(is_zero(v-1))
throw Error(
"Error Found in SP @4");
221 blst.let_op(i) = lst{c,v};
225 for(
auto ai : alst) {
226 for(
auto bi : blst) res += ai.op(0) * bi.op(0) *
SP(ai.op(1), bi.op(1), use_map);
237 ex
sp(
const ex &
a,
const ex & b) {
238 if(is_a<Vector>(
a) && is_a<Vector>(b))
return ex_to<Vector>(
a).name * ex_to<Vector>(b).name;
239 else throw Error(
"Error in sp(2).");
242 if(is_a<Vector>(
a))
return ex_to<Vector>(
a).name * ex_to<Vector>(
a).name;
243 else throw Error(
"Error in sp(1).");
252 ex &
letSP(
const ex &p1,
const ex &p2) {
253 if(!(is_a<Vector>(p1) || is_a<Index>(p1)) || !(is_a<Vector>(p2) || is_a<Index>(p2)))
254 throw Error(
"Invalide arguments for letSP (2).");
265 throw Error(
"Invalide arguments for letSP (1).");
275 if(!(is_a<Vector>(p1) || is_a<Index>(p1)) || !(is_a<Vector>(p2) || is_a<Index>(p2)))
276 throw Error(
"Invalide arguments for resetSP (2).");
286 throw Error(
"Invalide arguments for resetSP (1).");
303 auto ret = exin.subs(
SP_map);
306 for(
auto vp1 : vecs) {
307 for(
auto vp2 : vecs) {
308 spmap[
SP(vp1,vp2)]=
sp(vp1,vp2);
311 return ret.subs(spmap);
322 if(key.nops()!=2 || !is_a<Vector>(key.op(0)) || !is_a<Vector>(key.op(1)))
continue;
323 auto p1 = ex_to<Vector>(key.op(0));
324 auto p2 = ex_to<Vector>(key.op(1));
325 ret[p1.name * p2.name] = kv.second.subs(
SP_map);
#define IMPLEMENT_HAS(classname)
#define DEFAULT_CTOR(classname)
#define IMPLEMENT_ALL(classname)
class used to wrap error message
void read_archive(const archive_node &n) override
int compare_same_type(const GiNaC::basic &other) const override
const GiNaC::registered_class_info & get_class_info() const override
ex & let_op(size_t i) override
static GiNaC::registered_class_info & get_class_info_static()
ex op(size_t i) const override
void archive(archive_node &n) const override
size_t nops() const override
void accept(GiNaC::visitor &v) const override
ex derivative(const symbol &s) const override
bool is_equal_same_type(const basic &other) const override
void form_print(const FormFormat &c, unsigned level=0) const
FormFormat print function.
void print(const print_dflt &c, unsigned level=0) const
default print function
const char * class_name() const override
void fc_print(const FCFormat &c, unsigned level=0) const
FCFormat print function.
Pair * duplicate() const override
static lst all(const ex &e)
ex SP2sp(const ex &exin)
convert SP(a,b) to sp(a,b)
ex sp(const ex &a, const ex &b)
translated the vector dot a.b to a*b, useful in SecDec
exmap sp_map()
the SP_map with SP(a,b) replaced to sp(a,b)
ex & letSP(const ex &p1, const ex &p2)
return the reference of p1.p2
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
void clearSP(const ex &p1, const ex &p2)
delete the assignment of p1.p2
ex SP(const ex &a, bool use_map=false)