Welcome to Cadabra Q&A, where you can ask questions and receive answers from other members of the community.
+1 vote

I wonder where I could find the complete description of Cadabra's data structure, this and this are a little simple, I need more details. More examples about how to program in Cadabra is also OK.

in General questions by (1.4k points)
edited by

Are you intending to use this from Python or from C++?

Hi @Eureka,

So far that's the available documentation. The first link is a webpage whose aim is to introduce to the user into the programming capabilities of Cadabra. The second was the documentation of the 1.X version of cadabra, and does not apply in its totality to the versions 2.X.

Given that @Kasper is the (almost) sole developer of cadabra and its documentation, it would be great if you could provide more detail of your necessities, i.e. what type of structure do you have in mind? Specific end? Road map?

Python.....................................................

As @doxdrum already mentioned, please give a bit more detail about what you want to do. The docs are limited in part because I simply did not have the time to write more, and in part because not many people have written code for Cadabra in Python, so it isn't always obvious to me what is missing.

For example, I want to program a functiion to implement cyclicity of trace preliminarily. This is a very simple example:

{\mu,\nu,\rho}::Indices(vector).
{a^{\mu},b^{\mu},c^{\mu}}::NonCommuting.
tr{#}::Trace.
ex:=tr(a^{\mu} b^{\nu} c^{\rho}  a^{\mu} b^{\rho} c^{\nu}+b^{\mu} c^{\nu} a^{\rho} b^{\nu} c^{\mu} a^{\rho}+c^{\mu} a^{\nu} b^{\mu} c^{\rho} a^{\nu} b^{\rho});

A more complicate example as this, here all operators are noncommuting in the trace, I want to add them up directly by using cyclicity of trace. I don't know how to deal with dummy indices and something like it. Firstly, I must know the data structure in Cadabra before realizing this function. I can also study through others' codes, but I don't find more examples about it.

This functionality has been added now, just waiting for some small cleanups before it goes into the master branch.

It's amazing! Thanks for your great work. When can I use this function? I very need this function for recent work. If possible, I still want to know more details about how to program using python in cadabra. I might have to program some functioins by myself in the future.

The version currently in the github master branch can use cyclic symmetry of the trace to sort products, so you can do

{\mu,\nu,\rho}::Indices(vector).
{a^{\mu},b^{\mu},c^{\mu}}::NonCommuting.
tr{#}::Trace.
ex:=tr(a^{\mu} b^{\nu} c^{\rho}  a^{\mu} b^{\rho} c^{\nu}
        +b^{\mu} c^{\nu} a^{\rho} b^{\nu}c^{\mu} a^{\rho}
        +c^{\mu} a^{\nu} b^{\mu} c^{\rho} a^{\nu} b^{\rho} );

sort_product(_)
rename_dummies(_);

to produce

$$3 {\rm tr}( a^{\mu} b^{\nu} c^{\rho} a^{\mu} b^{\rho} c^{\nu} )$$

Thanks to Conor Behan for implementing this.

Thanks to you & Conor Behan. This property is very useful for many situations.

i find if there are scalar in trace, this property won't work. For example,

{\mu,\nu,\rho}::Indices(vector).
{a^{\mu},b^{\mu},c^{\mu}}::NonCommuting.
tr{#}::Trace.
{m,n,l,a{#},b{#},c{#}}::SortOrder.
ex:=tr(m a^{\mu} b^{\nu} c^{\rho}  a^{\mu} b^{\rho} c^{\nu}
        +n b^{\mu} c^{\nu} a^{\rho} b^{\nu} c^{\mu} a^{\rho}
        +l c^{\mu} a^{\nu} b^{\mu} c^{\rho}   a^{\nu} b^{\rho});
sort_product(_);
rename_dummies(_);

Untrace first, so do something like

{\mu,\nu,\rho}::Indices(vector).
{a^{\mu},b^{\mu},c^{\mu}}::ImplicitIndex;
tr{#}::Trace.
ex:=tr(m a^{\mu} b^{\nu} c^{\rho}  a^{\mu} b^{\rho} c^{\nu}
    +n b^{\mu} c^{\nu} a^{\rho} b^{\nu} c^{\mu} a^{\rho}
    +l c^{\mu} a^{\nu} b^{\mu} c^{\rho}   a^{\nu} b^{\rho});
distribute(_);
untrace(_);
sort_product(_);
rename_dummies(_);
factor_in(_, $m,n,l$);

to get

$$(m+n+l) {\rm tr}( a^{\mu} b^{\nu} c^{\rho} a^{\mu} b^{\rho} c^{\nu} )$$

Note that for untrace to work, you need to give your $a,b,c$ objects the ImplicitIndex property; just doing NonCommuting is not enough (if you do the latter, untrace will take them out of the trace).

The following code still doesn't work

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
\ahl{#}::LaTeXForm("{\hat{\alpha}_{\parallel}}").
\ahp{#}::LaTeXForm("{\hat{\alpha}_{\perp}}").
\vh{#}::LaTeXForm("{\hat{V}}").
{\vh{#},\ahl{#},\ahp{#}}::SortOrder.
{\ahl^{\mu},\ahp^{\mu},\vh^{\mu\nu}}::NonCommuting.
\vh^{\mu\nu}::AntiSymmetric.
ex:=tr{\ahl^{\mu} \ahp^{\nu} \vh^{\mu\nu}+\ahp^{\mu} \vh^{\mu\nu} \ahl^{\nu}};
sort_product(_);
rename_dummies(_);
canonicalise(_);

the result should be zero. When I delete the SortOrder property, the result will be right, Can we hardly customize the order of operators?

And this also doesn't work

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
{a^{\mu}}::SelfNonCommuting.
ex:=tr{a^{\mu} a^{\mu} a^{\nu} a^{\nu}+a^{\mu} a^{\nu} a^{\nu} a^{\mu}};
sort_product(_);
rename_dummies(_);

Connor fixed various issues with sorting products inside a trace; the current version on github runs both of these examples fine.

Thanks. But following code still doesn't work

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
{a^{\mu},b^{\mu}}::ImplicitIndex.
{a^{\mu},b^{\mu}}::NonCommuting.
a^{\mu}::SelfNonCommuting.
ex:=tr{a^{\mu} b^{\mu} a^{\nu} a^{\nu}+b^{\mu} a^{\nu} a^{\nu} a^{\mu}};
distribute(_);
sort_product(_);
rename_dummies(_);

if I add 'combine', it will work fine, but I don't know how to expand it. I have a try

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
{a^{\mu},b^{\mu}}::ImplicitIndex.
{a^{\mu},b^{\mu}}::NonCommuting.
a^{\mu}::SelfNonCommuting.
ex:=tr{a^{\mu} b^{\mu} a^{\nu} a^{\nu}+b^{\mu} a^{\nu} a^{\nu} a^{\mu}};
combine(_);
sort_product(_);
expand(_);

It doesn't work.

@Eureka I compiled cadabra 5 hours ago, and the first example you wrote works fine. I have probems with the second.

Version 2.2.7 (build 2268.ba747e0b49 dated 2019-12-01)

@doxdrum Which example works fine? You mean this?

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
{a^{\mu},b^{\mu}}::ImplicitIndex.
{a^{\mu},b^{\mu}}::NonCommuting.
a^{\mu}::SelfNonCommuting.
ex:=tr{a^{\mu} b^{\mu} a^{\nu} a^{\nu}+b^{\mu} a^{\nu} a^{\nu} a^{\mu}};
distribute(_);
sort_product(_);
rename_dummies(_);

I have updated Cadabra to the lastest version, but it doesn't work.

Version 2.2.7 (build 2271.04b735df41 dated 2019-12-03)

There have been commits more recent than 5 hours ago, @doxdrum's build is not the most recent. I can reproduce the problem in @Eureka's last comment; have not yet had time to diagnose it.

I just found out what's going on here. Please wait for one more patch to be accepted.

Connor's latest patch has now been merged (and verified to handle this problem).

There still seems to be some bugs. For example,

{\mu,\nu}::Indices(vector).
tr{#}::Trace.
{a^{\mu},b^{\mu}}::NonCommuting.
{a^{\mu},b^{\mu}}::SelfNonCommuting.
ex:=tr{a^{\mu} b^{\mu} b^{\nu} a^{\nu}}+tr{a^{\mu} a^{\nu} b^{\nu} b^{\mu} };
sort_product(_);
rename_dummies(_);

Version 2.2.7 (build 2275.333ca654f6 dated 2019-12-03)

Ok, but you can see why that happens right? Alphabetically, a^{\mu} comes before a^{\nu} so it would be "wrong" for it to put the "a"s together in the first trace.

Currently what I'm thinking is that we should set a^{\mu} < a^{\nu} if both indices are free and a^{\mu} = a^{\nu} if both indices are dummies. If only one index is a dummy, the free one comes first. Would this have any unintended consequences?

I don't know. Maybe you should first consider order of a&b, then consider order of indices.

Hi@cbehan, are there any progress in this bug?

After changing my mind a couple times I think I know what patch to submit for this. Hopefully it will happen tomorrow.

The latest fix by @cbehan is now in github master.

Ok, It works fine. Thanks.

Hi@cbehan@kasper, following code is still invalid

{\mu,\nu}::Indices(vector).
u^{\mu}::ImplicitIndex.
u^{\mu}::SelfNonCommuting.
tr{#}::Trace.
ex:=tr{u^{\mu} u^{\mu} u^{\nu} u^{\nu}}-tr{u^{\mu} u^{\nu} u^{\nu} u^{\mu}};
sort_product(_);

Version 2.2.9 (build 2310.4b47f18980 dated 2019-12-28), Linux

Ok. In this case, the letters are the same and the free indices are the same which means that a single sort order has not been determined yet. We will need to detect that this has happened and then put an ordering on the set of dummy index topologies.

In the above example, this means deciding whether we prefer {{1,2}, {3,4}} or {{1,4}, {2,3}}. More generally, we should expect to see all possible ways of breaking up {1, ..., 2n} into unordered pairs.

I knew this was coming... By far the easiest way to solve this is to piggyback on work Dom has been doing to make multi-term symmetries more manageable. @cbehan, I'll email you privately with details.

1 Answer

+1 vote

This is now handled cleanly by Dom's new meld algorithm, which is now on github. Instead of sort_product, just use meld(_). Documentation on this will be in a forthcoming paper.

by (76.5k points)

Thanks. I have used this new algorithm for a while, but there are still some bugs in 'meld' algorithm, for example

{\mu,\nu}::Indices(vector).
V^{\mu\nu}::AntiSymmetric.
{{V^{\mu\nu},u^{\mu}}::NonCommuting.
u^{\mu}::SelfNonCommuting.
tr{#}::Trace.
ex:=tr{V^{\mu\nu}u^{\mu}u^{\nu}};
meld(_);

the result is zero, it's wrong.

...