[GiNaC-list] Covariant derivative(its long..)
mdias at ift.unesp.br
mdias at ift.unesp.br
Mon Apr 4 04:47:47 CEST 2005
Hi,
I tried this very confuse code, and I am happy if somebody could help-me. I
tried to make covariant derivative derivated from a indexed. Use it like:
D(indexed(A,mu),nu)
But the fatal errors in this code (among millions..):
i) simplify_indexed() crashs or doesnt work !!
II) get_free_indexes not work, so D^\alpha(A_beta)A^\beta A_\alpha
-D^\beta(A_alpha)A^\beta A_\alpha is not zero
In the last post , Christian Bauer suggests "override is eval_indexed() (for
automatic evaluation) and
contract_with()/add_indexed()/scalar_mul_indexed() (for manual evaluation,
AKA simplify_indexed())" and showed the way: look color.cpp source.
Any suggestions are welcome
Marco
#include <iostream>
#include <ginac/ginac.h>
#define N 4
#define N1 8
using namespace std;
using namespace GiNaC;
const unsigned TINFO_covdiff = 0x42420001U;
class covdiff : public indexed {
GINAC_DECLARE_REGISTERED_CLASS(covdiff, indexed)
public:
covdiff(const ex & b,const ex & i1);
covdiff(const ex & b, const ex & i1, const ex & i2);
covdiff(const ex & b, const ex & i1, const ex & i2,const ex & i3);
covdiff(const ex & b, const ex & i1, const ex & i2,const ex & i3, const ex & i4);
covdiff(const ex & b, const lst & iv);
size_t nops() const;
ex op(size_t i) const;
ex & let_op(size_t i);
ex subs(const exmap & m, unsigned options) const;
protected:
void do_print(const print_context & c, unsigned level) const;
ex symtree, arg,index;
lst seq;
};
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(covdiff, indexed,
print_func<print_context>(&covdiff::do_print))
covdiff::covdiff(const ex & b, const ex & i1) : inherited(b,
i1),arg(b),index(i1), symtree(not_symmetric())
{
tinfo_key = TINFO_covdiff;
}
covdiff::covdiff(const ex & b, const ex & i1, const ex & i2) : inherited(b, i1,
i2),arg(b), symtree(not_symmetric())
{
seq =i1,i2;
tinfo_key = TINFO_covdiff;
}
covdiff::covdiff(const ex & b, const ex & i1, const ex & i2, const ex & i3) :
inherited(b, i1, i2, i3),arg(b), symtree(not_symmetric())
{ seq=i1,i2,i3;
tinfo_key = TINFO_covdiff;
}
covdiff::covdiff(const ex & b, const ex & i1, const ex & i2, const ex & i3,
const ex & i4) : inherited(b, i1, i2, i3, i4),arg(b), symtree(not_symmetric())
{seq = i1,i2,i3,i4;
tinfo_key = TINFO_covdiff;
}
covdiff::covdiff(const ex & b, const lst & iv) : inherited(b),arg(b),
symtree(not_symmetric())
{
seq=iv;
tinfo_key = TINFO_covdiff;
}
//archiving
covdiff::covdiff(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
{
if (!n.find_ex("symmetry", symtree, sym_lst)) {
// GiNaC versions <= 0.9.0 had an unsigned "symmetry" property
unsigned symm = 0;
n.find_unsigned("symmetry", symm);
switch (symm) {
case 1:
symtree = sy_symm();
break;
case 2:
symtree = sy_anti();
break;
default:
symtree = not_symmetric();
break;
}
const_cast<symmetry &>(ex_to<symmetry>(symtree)).validate(seq.nops() - 1);
}
}
void covdiff::archive(archive_node &n) const
{
inherited::archive(n);
n.add_ex("symmetry", symtree);
}
ex covdiff::unarchive(const archive_node &n, lst &sym_lst)
{
return (new covdiff(n, sym_lst))->setflag(status_flags::dynallocated);
}
//comparation method
void covdiff::do_print(const print_context & c, unsigned level) const
{
if (is_a<print_tree>(c))
covdiff::print(c,level);
if (seq.nops() > 1) {
for( lst::const_iterator it=seq.begin();it != seq.end();++it)
c.s<<"D"<<*it;
c.s<<"("<<arg<<")";
}
else
c.s << "D"<<index <<" ("<<arg<<")";
}
int covdiff::compare_same_type(const basic & other) const
{
GINAC_ASSERT(is_a<covdiff>(other));
return inherited::compare_same_type(other);
}
ex covdiff::op(size_t i) const{
if(i==0)
return arg;
if(seq.nops() > 0 && i != 0)
return seq[i-1];
if(seq.nops()==0 && i==1)
return index;
else
throw std::range_error("covdiff::let_op(): no such operand");
}
size_t covdiff::nops() const
{
if(seq.nops()>0)
return seq.nops()+1;
else return 2;
}
ex & covdiff:: let_op(size_t i)
{
ensure_if_modifiable();
if(i==0)
return arg;
if(seq.nops() > 0 && i != 0)
return seq[i-1];
if(seq.nops()==0 && i==1)
return index;
else
throw std::range_error("covdiff::let_op(): no such operand");
}
ex covdiff::subs(const exmap & m, unsigned options) const
{
size_t num = nops();
if (num) {
// Substitute in subexpressions
for (size_t i=0; i<num; i++) {
const ex & orig_op = op(i);
const ex & subsed_op = orig_op.subs(m, options);
if (!are_ex_trivially_equal(orig_op, subsed_op)) {
// Something changed, clone the object
basic *copy = duplicate();
copy->setflag(status_flags::dynallocated);
copy->clearflag(status_flags::hash_calculated |
status_flags::expanded);
// Substitute the changed operand
copy->let_op(i++) = subsed_op;
// Substitute the other operands
for (; i<num; i++)
copy->let_op(i) = op(i).subs(m, options);
// Perform substitutions on the new object as a
whole
return copy->subs_one_level(m, options);
}
}
}
// Nothing changed or no subexpressions
return subs_one_level(m, options);
}
ex Derivative_helper(ex e, ex var)
{
lst iv;
if(is_a<covdiff>(e)){
for(size_t i=1; i<e.nops();i++)
iv.append(e.op(i));
iv.append(var);
return covdiff(e.op(0),iv);
}else
if(is_a<indexed>(e)){
if(is_a<su3f>(e.op(0)) && e.nops()==4)
return 0;
else
return covdiff(e,var);
}
else
return 0;
}
struct make_diff : public map_function{
ex var;
make_diff(ex var_): var(var_){}
ex operator()(const ex & e)
{
if(is_a<add>(e))
return e.map(*this);
else
if(is_a<mul>(e))
{
ex result =0;
for(size_t i=0;i<e.nops();++i)
{
result +=e.subs(e.op(i)==Derivative_helper(e.op(i),var));
};
return result;
}else
return Derivative_helper(e,var);
}
};
ex D(ex e, ex index){
ex result;
make_diff D(index);
return D(e);
}
-------------------------------------------------
This mail sent through IMP: http://horde.org/imp/
More information about the GiNaC-list
mailing list