+1 vote

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?

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.

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.

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?

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

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.

+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.

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.