Cadabra Q&A - Recent questions and answers
https://cadabra.science/qa/qa
Powered by Question2AnswerAnswered: imp package was removed from python 3.12
https://cadabra.science/qa/2863/imp-package-was-removed-from-python-3-12?show=2868#a2868
<p>Can one of you please test the current <code>2.4.5.8</code> now on github? You will most likely need to clean your cadabra notebook cache (<code>Tools > Clear package cache</code>).</p>Bug reportshttps://cadabra.science/qa/2863/imp-package-was-removed-from-python-3-12?show=2868#a2868Mon, 20 May 2024 12:53:29 +0000Answered: Why does evaluate of metric eating vector shows only non-zero components.
https://cadabra.science/qa/2855/does-evaluate-metric-eating-vector-shows-only-zero-components?show=2865#a2865
<p>That's an intentional choice, as for most 'interesting' tensors, there will typically be far more zero components than non-zero components (e.g. Riemann tensors). I guess we could make it configurable, but I haven't had the need for that so far.</p>General questionshttps://cadabra.science/qa/2855/does-evaluate-metric-eating-vector-shows-only-zero-components?show=2865#a2865Sun, 19 May 2024 20:10:55 +0000Answered: Christoffel symbols computation in $d$ dimensions with split indices
https://cadabra.science/qa/2851/christoffel-symbols-computation-dimensions-split-indices?show=2861#a2861
<p>Hi again raulastur.</p>
<p>Perhaps this would be repetitive, since Arina already post an answer to your question... but Ok, we learn by asymptotic approximation!</p>
<h2>Modifications to your work</h2>
<p>As usual, you have to declare the objects and properties</p>
<pre><code>{\mu,\nu,\rho,\sigma,\kappa,\lambda,\eta,\chi#}::Indices(full, position=fixed, values={1,2,3,4}).
{A,B,C,D}::Indices(subspace, position=fixed, parent=full, values={2,3,4}).
{i,j, m,n,p,q,r,v#}::Indices(subspace2, position=fixed, parent=subspace, values={2,3}).
{s1,s2,s3}::Indices(subspace1, position=fixed, parent=subspace, values={4}).
\partial{#}::PartialDerivative.
g_{\mu\nu}::Metric.
g^{\mu\nu}::InverseMetric.
g_{\mu? \nu?}::Symmetric.
g^{\mu? \nu?}::Symmetric.
b_{i j}::Metric.
b^{i j}::InverseMetric.
{\delta^{\mu?}_{\nu?},\delta_{\mu?}^{\nu?}}::KroneckerDelta.
{b_{i j},b^{i j}}::Depends(\partial{#}).</code></pre>
<p>I wanted to keep your definitions almost untouched. </p>
<p>I've added the dependence of the $b$ field on the partial derivative (although it is not important in the following code.</p>
<p>Then, I assume that the long sequence of substitutions would be applied to other expressions as well, so instead of your approach, I prefer to define a set of substitution rules</p>
<pre><code>rl := { g_{1 m} -> 0, g_{1 4} -> 1, g_{m 1} -> 0, g_{m n} -> b_{m n}, g_{m 4} -> U_{m}, g^{4 1} -> 1,
g_{4 m} -> U_{m}, g_{4 4} -> f, g^{1 1} -> U_{m} b^{m n} U_{n} - f, g^{1 m} -> - U_{n} b^{n m}, g^{1 4} -> 1,
g^{m 1} -> - U_{n} b^{n m}, g^{m n} -> b^{n m}, g^{m 4} -> 0, g^{4 1} -> 1, g^{4 m} -> 0, g^{4 4} -> 0,
\partial_{1}{U_{m}} -> 0, \partial_{1 \mu?}{U_{m}} -> 0,
\partial_{\mu? 1}{U_{m}} -> 0, \partial_{\mu? 1}{b_{i j}} -> 0};</code></pre>
<p>Above, I changed the substitutions that used double question marks, <code>U??</code> or other.</p>
<p>Also include the Christoffel definition</p>
<pre><code>Gtog:= \Gamma^{\lambda?}_{\mu? \nu?} = (1/2) * g^{\lambda? \kappa} (\partial_{\nu?}{ g_{\kappa \mu?}}
+ \partial_{\mu?}{g_{\kappa \nu?}} + \partial_{\kappa}{g_{\mu? \nu?} } );</code></pre>
<p>Note that the summed index has to run over the <code>full</code> space, while the other indices have the question mark (<code>?</code>) to ensure that the rule could be applied to whatever type of index (like <code>4</code>).</p>
<p>Now, I define the expression to be manipulated,</p>
<pre><code>Gamma4ij := \Gamma^{4}_{i j};</code></pre>
<p>and expand the indices</p>
<pre><code>substitute(Gamma4ij, Gtog)
split_index(Gamma4ij, $\mu, 1, A$, repeat=True)
split_index(Gamma4ij, $A, i, 4$, repeat=True);</code></pre>
<p>Finally, I use the substitution rule <code>rl</code> to obtain the result:</p>
<pre><code>substitute(Gamma4ij, rl, repeat=True);</code></pre>
<p>The result I obtain is $\partial<em>1 b</em>{i j}$.</p>
<h3>Why?</h3>
<p>When you used the double question mark notation, <code>U??</code>, in the substitution rule, it would substitute not just the variable called <code>U</code>, but <em>any</em> variable. Look at this example:</p>
<pre><code>ex:=A_{m n} + B_{m n};
substitute(_, $A? + B? -> 0$ );
substitute(_, $M?? + N?? -> 0$ );</code></pre>
<p>Hope this would help you.</p>
<p>Dox</p>General questionshttps://cadabra.science/qa/2851/christoffel-symbols-computation-dimensions-split-indices?show=2861#a2861Fri, 17 May 2024 09:45:10 +0000Answered: How can I store the result of evaluating g(.,v) as a co-vector?
https://cadabra.science/qa/2852/how-can-i-store-the-result-of-evaluating-g-v-as-a-co-vector?show=2853#a2853
<p>Hi, Paul
If you write something like:</p>
<pre><code>ex:= v_{b} = g_{a b} v^{a};
gv = evaluate(ex,join(g,v), rhsonly=True);
wb = comp.components_to_subrule(gv);</code></pre>
<p>You get a list consisting of the components of the v_b co-vector.</p>General questionshttps://cadabra.science/qa/2852/how-can-i-store-the-result-of-evaluating-g-v-as-a-co-vector?show=2853#a2853Tue, 14 May 2024 17:53:21 +0000Answered: why can't cadabra find cdb.sympy.calculus?
https://cadabra.science/qa/2845/why-cant-cadabra-find-cdb-sympy-calculus?show=2846#a2846
<p>Similar issue to your other question: upgrade to a more recent version.</p>General questionshttps://cadabra.science/qa/2845/why-cant-cadabra-find-cdb-sympy-calculus?show=2846#a2846Tue, 07 May 2024 21:00:04 +0000Answered: how to compute metric(vector,vector) or g(v,w) where g,v,w already defined without haqving to repeat the definitions.
https://cadabra.science/qa/2839/compute-metric-already-defined-without-haqving-definitions?show=2840#a2840
<p>If you have the rules <code>g</code> and <code>v</code> which define the component values, you can feed those into <code>evaluate</code>. For example, to compute $g_{a b} v^{a} v^{b}$ with the values of your example, do</p>
<pre><code>{m,n,a,b,c,d,q,r,s}::Indices(values={0,1}).
g_{a b}::Metric.
g^{a b}::InverseMetric.
g:={g_{0 0}=28, g_{0 1}=2, g_{1 0}=3, g_{1 1}=-1};
v:={v^{0}=12, v^{1}=-11};
ex:=g_{a b} v^{a} v^{b};
evaluate(ex, join(g,v));</code></pre>
<p>Does that answer your question?</p>General questionshttps://cadabra.science/qa/2839/compute-metric-already-defined-without-haqving-definitions?show=2840#a2840Tue, 07 May 2024 14:40:18 +0000Answered: How to calculate Christoffel symbols with metric defined by abstract matrices?
https://cadabra.science/qa/2780/calculate-christoffel-symbols-defined-abstract-matrices?show=2836#a2836
<p>Let me hint some ideas... although it is a not very helpful example.</p>
<p><strong>Comment 0:</strong> I'll stick to the suggested code, and not the written line-element.</p>
<h2>My suggestions</h2>
<p>Firstly, let's assing some properties</p>
<pre><code>{t,x,y,z}::Coordinate;
{\mu,\nu,\rho,\sigma,\lambda,\kappa,\chi,\gamma}::Indices(values={t,x,y,z},position=independent);
{i,j,k,l,m,n}::Indices(values={x,y,z},position=independent);
\partial{#}::PartialDerivative;
g_{\mu\nu}::Metric;
g^{\mu\nu}::InverseMetric;
h_{i j}::Metric;
h^{i j}::InverseMetric;</code></pre>
<p><strong>Comment 1:</strong> the separation between Latin and Greek indices.</p>
<p>Then, assign some dependencies,</p>
<pre><code>h_{i j}::Depends(t);
N{#}::Depends(x,y,z);</code></pre>
<p>Now, instead of trying to declare sets of components, like <code>g_{0 i}=N_i</code> for the metric, I used a detail declaration,</p>
<pre><code>ss := { g_{t t}=0,
g_{t x}=N_x,
g_{t y}=N_y,
g_{t z}=N_z,
g_{x t}=N_x,
g_{y t}=N_y,
g_{z t}=N_z,
g_{x x}=h_{x x},
g_{y y}=h_{y y},
g_{z z}=h_{z z},
g_{y z}=h_{y z},
g_{z y}=h_{y z},
};
complete(ss, $g^{\mu\nu}$);</code></pre>
<p><strong>Comment 2:</strong> for the sake of "readability" of the output, I used a simplified version of the /spacial/ submetric. If you use a complete example the output is longer.</p>
<p>Finally, you can define the Christoffel rule,</p>
<pre><code>ch:= \Gamma^{\mu}_{\nu\rho} =
1/2 g^{\mu\sigma} (
\partial_{\rho}{g_{\nu\sigma}}
+\partial_{\nu}{g_{\rho\sigma}}
-\partial_{\sigma}{g_{\nu\rho}} );</code></pre>
<p>and evaluate its components,</p>
<pre><code>evaluate(ch, ss, rhsonly=True);</code></pre>
<h3>A more complete metric</h3>
<p>Just if you want to try it</p>
<pre><code>ss := { g_{t t}=N,
g_{t x}=N_x,
g_{t y}=N_y,
g_{t z}=N_z,
g_{x t}=N_x,
g_{y t}=N_y,
g_{z t}=N_z,
g_{x x}=h_{x x},
g_{y y}=h_{y y},
g_{z z}=h_{z z},
g_{x y}=h_{x y},
g_{y x}=h_{x y},
g_{x z}=h_{x z},
g_{z x}=h_{x z},
g_{y z}=h_{y z},
g_{z y}=h_{y z},
};
complete(ss, $g^{\mu\nu}$);</code></pre>
<h2>Additional reflexions</h2>
<p>If you have evaluated the above code, you'll find that it is not very useful! </p>
<p><em>Really long expressions.</em></p>
<p>What if we don't give explicit expressions?</p>
<p><strong>TO BE CONTINUED!</strong></p>General questionshttps://cadabra.science/qa/2780/calculate-christoffel-symbols-defined-abstract-matrices?show=2836#a2836Fri, 26 Apr 2024 09:19:59 +0000convert other format to cadabra2 format
https://cadabra.science/qa/2833/convert-other-format-to-cadabra2-format
<p>From <a rel="nofollow" href="https://cadabra.science/notebooks/scalar_manipulations.html">Using Cadabra and Sympy together</a>, I learn how to convert cadabra2 format to sympy format, but how to do the reverse operation? I.e. How to convert other formals, e.g. sympy format, to cadabra2 format?</p>General questionshttps://cadabra.science/qa/2833/convert-other-format-to-cadabra2-formatWed, 24 Apr 2024 13:31:05 +0000Answered: function expand_power not work for fractional power
https://cadabra.science/qa/2804/function-expand_power-not-work-for-fractional-power?show=2832#a2832
<p>I found a way to do it. One can use function <code>refine</code> in sympy, for example,</p>
<pre><code>from sympy import refine, sqrt, Q
from sympy.abc import L
ex:=(\lambda**{-2})**{1/2};
substitute(_,$\lambda->L$);
refine(_._sympy_(), Q.positive(L));</code></pre>
<p>But there is an another question: How to transform sympy expression to cadabra2 expression?</p>General questionshttps://cadabra.science/qa/2804/function-expand_power-not-work-for-fractional-power?show=2832#a2832Wed, 24 Apr 2024 13:16:26 +0000Answered: bug of unwrap
https://cadabra.science/qa/2828/bug-of-unwrap?show=2829#a2829
<p>Hi Eureka. </p>
<p>I don't thing it is a bug, just a misunderstanding of the philosophy of <code>cadabra</code>.</p>
<p>According to the <code>unwrap</code> documentation:</p>
<blockquote>
<p>Derivatives will be set to zero if an object inside does not depend on it.</p>
</blockquote>
<p>Hence, the command is not a computational aid... I mean, stricktly speaking you have not declare any dependence for <code>u</code>! So the algorithm set its derivative to zero.</p>
<p>My advice would be to use first a substitution rule, e.g.</p>
<pre><code>rl := \partial_{u}{u} -> 1;
ex:=\partial_u{u f};
product_rule(_)
substitute(ex, rl)
unwrap(ex);</code></pre>
<p>or if your calculation is "simple", call the <code>sympy</code> module:</p>
<pre><code>from cdb.sympy.calculus import *
ex := u f;
d_ex = diff(ex);</code></pre>
<p><strong>NOTE</strong> the absence of the colon in the last assignation (it is a <code>python</code> assignation not a <code>cadabra</code> one).</p>
<p>Hope this would be useful!</p>
<p>Cheers, Dox.</p>Bug reportshttps://cadabra.science/qa/2828/bug-of-unwrap?show=2829#a2829Tue, 23 Apr 2024 09:46:30 +0000Answered: make copy expression easier
https://cadabra.science/qa/2809/make-copy-expression-easier?show=2824#a2824
<p>I would only like to add that a possible variant is </p>
<pre><code>substitute($@[ex]$, $a -> c$)</code></pre>
<p>Using square brackets also creates a copy and does not affect the original expression.</p>Feature requestshttps://cadabra.science/qa/2809/make-copy-expression-easier?show=2824#a2824Mon, 22 Apr 2024 21:42:55 +0000Answered: Instructions on keyboard shortcuts
https://cadabra.science/qa/2822/instructions-on-keyboard-shortcuts?show=2823#a2823
<p>Hi Eureka.</p>
<p>The answer to your question depends whether you are using the <code>native</code> or the <code>jupyter-notebook</code> user interface.</p>
<p>In the native user interface the help is in the menu bar, shown to the right of the listed actions. There is no CLI to comment code lines, AFAIK.</p>
<p>The <code>jupyter-notebook</code> has many key bindings, and they are not specific to <code>cadabra</code>. See for example <a rel="nofollow" href="https://defkey.com/jupyter-notebook-shortcuts">https://defkey.com/jupyter-notebook-shortcuts</a> or <a rel="nofollow" href="https://cheatography.com/weidadeyue/cheat-sheets/jupyter-notebook/">https://cheatography.com/weidadeyue/cheat-sheets/jupyter-notebook/</a>.</p>Feature requestshttps://cadabra.science/qa/2822/instructions-on-keyboard-shortcuts?show=2823#a2823Mon, 22 Apr 2024 09:11:10 +0000bug of stop evaluation
https://cadabra.science/qa/2821/bug-of-stop-evaluation
<p>When I use <code>stop evaluation</code> to stop evaluation, but it never works.</p>Bug reportshttps://cadabra.science/qa/2821/bug-of-stop-evaluationSun, 21 Apr 2024 11:50:54 +0000question about keep_weight
https://cadabra.science/qa/2814/question-about-keep_weight
<p>In the following code,</p>
<pre><code>{u,v,x}::Coordinate.
f::Coordinate.
{a,b,c,d,e,g,h,p,r#}::Indices(full,values={u,v,x},position=independent).
\partial{#}::PartialDerivative.
\nabla{#}::Derivative.
g_{a b}::Metric.
g^{a b}::InverseMetric.
g_a^b::KroneckerDelta.
g^a_b::KroneckerDelta.
g^{a b}::Symmetric.
g_{a b}::Symmetric.
{n_u,n_v,\gamma,w,\alpha,\lambda,A,B,C}::Depends({u,v,f,x}).
{u,v}::Weight(label=field,value=1);
{f}::Weight(label=field,value=2);
metric:={g_{u v}=1,
g_{v u}=1,g_{v v}=-u**2\alpha,g_{v x}=u w,
g_{x v}=u w,g_{x x}=\gamma};
complete(_,$g^{a b}$);
from cdb.sympy.calculus import *
lamb:=(g^{a b}\partial_a{u v}\partial_b{u v})**{-1/2} ;
evaluate(_,metric,rhsonly=True);
substitute(_,$v->f/u$)
simplify(_);
substitute(_,$\alpha->a,w**2\gamma**{-1}->b$);
series(_,$f$,0,5/2);
substitute(_,$\bigO(A??)->0$)
keep_weight(_,$field=1$);</code></pre>
<p>The final result is not right. There seems to be something wrong here.</p>General questionshttps://cadabra.science/qa/2814/question-about-keep_weightFri, 19 Apr 2024 03:46:06 +0000Setting Python version in cmake
https://cadabra.science/qa/2803/setting-python-version-in-cmake
<p>I'm the cadabra2 port maintainer for MacPorts. The update to version 2.4.5.6 has caused an issue:
Rather than picking up the MacPorts version of Python (it was set to 3.11 for the previous release, but should be updated to version 3.12, as that's now default), the cmake script picks up the macOS version instead (on my Ventura system, that would be 3.9.6). I can properly set <code>-DPYTHON_LIBRARIES</code> and <code>-DPYTHON_SITE_PATH</code>, but I don't see a way of choosing the path to the python binary.</p>Installation troublehttps://cadabra.science/qa/2803/setting-python-version-in-cmakeThu, 18 Apr 2024 13:39:33 +0000Answered: Error printing as mma format
https://cadabra.science/qa/2776/error-printing-as-mma-format?show=2798#a2798
<p>As I said, the MicroTeX branch is work in progress.</p>
<p>You can always copy an expression to the clipboard by using the <code>pyperclip</code> package. For instance,</p>
<pre><code>import pyperclip
ex:=A_{m n};
pyperclip.copy( ex.mma_form() )</code></pre>General questionshttps://cadabra.science/qa/2776/error-printing-as-mma-format?show=2798#a2798Thu, 18 Apr 2024 09:01:10 +0000bug of function keep_weight
https://cadabra.science/qa/2788/bug-of-function-keep_weight
<p>The following code: </p>
<pre><code>{u,v}::Weight(label=field,value=1);
ex:=(u v)**{1/2};
keep_weight(_,$field=1$);</code></pre>
<p>I get the wrong result $0$, while the following code </p>
<pre><code>{u,v}::Weight(label=field,value=1);
ex:=(u v)**{1/2}+u u;
keep_weight(_,$field=1$);</code></pre>
<p>work fine. It seems a bug.</p>Bug reportshttps://cadabra.science/qa/2788/bug-of-function-keep_weightWed, 17 Apr 2024 09:38:20 +0000Answered: The output is lost in WSL2
https://cadabra.science/qa/2775/the-output-is-lost-in-wsl2?show=2785#a2785
<p>If you know the absolute path to the file you can always use that in the <code>open</code> call, no? What do you mean with "I can't get the output there"? Does the <code>open</code> call fail or does reading from that file fail?</p>Bug reportshttps://cadabra.science/qa/2775/the-output-is-lost-in-wsl2?show=2785#a2785Wed, 17 Apr 2024 07:50:59 +0000Answered: Formula rendering in jupyter notebook 7 and jupyter lab
https://cadabra.science/qa/2773/formula-rendering-in-jupyter-notebook-7-and-jupyter-lab?show=2779#a2779
<p>According to <a rel="nofollow" href="https://docs.mathjax.org/en/latest/output/linebreaks.html">https://docs.mathjax.org/en/latest/output/linebreaks.html</a>, automatic line breaking is not yet implemented in MathJax 3. I do not know if that web page is the current status, but it would explain why formulas do not wrap.</p>General questionshttps://cadabra.science/qa/2773/formula-rendering-in-jupyter-notebook-7-and-jupyter-lab?show=2779#a2779Sat, 13 Apr 2024 13:04:45 +0000Answered: Other languages support in LaTeX cell
https://cadabra.science/qa/2756/other-languages-support-in-latex-cell?show=2777#a2777
<p>The <code>microtex</code> branch now contains a version of Cadabra which no longer relies on LaTeX for maths typesetting. You can either build that yourself, or try the new (and still experimental) AppImage builds from the download page. </p>
<p>Let me know if this helps with the issue you reported please.</p>Feature requestshttps://cadabra.science/qa/2756/other-languages-support-in-latex-cell?show=2777#a2777Sat, 13 Apr 2024 13:01:50 +0000Question about Gaussian normal coordinate
https://cadabra.science/qa/2774/question-about-gaussian-normal-coordinate
<p>When I do calculation under Gaussian normal coordinate:</p>
<p>$$
d s^2=-2 d u d v-u^2\alpha(x) d v^2-2u w_i(x) dv dx^i+\gamma_{ij}(x) d x^i d x^j\,\quad x=(uv\,,x^i)
$$</p>
<p>How to get inverse metric and others directly? I don't know how to deal with $w_i$ and $\gamma_{ij}$.</p>General questionshttps://cadabra.science/qa/2774/question-about-gaussian-normal-coordinateThu, 11 Apr 2024 07:20:30 +0000Answered: unwrap of partial derivatives
https://cadabra.science/qa/2768/unwrap-of-partial-derivatives?show=2769#a2769
<p>Hi Arina. Great question!</p>
<p>I believe that the mismatch between the expected and actual behaviour of the <code>unwrap</code> algorithm is due to the "phylosophy" of CADABRA, i.e., it is a software centred in manipulation rather than calculation.</p>
<p>The "calculation" component of CADABRA came with the release of version 2.X, through the interaction with PYTHON (in particular with <code>sympy</code>).</p>
<p>Note that if instead of <code>unwrap</code>, you pass your expression to SYMPY, using <code>map_sympy</code>, as follows</p>
<pre><code>map_sympy($\partial_{t}{a}$);</code></pre>
<p>you get the expected result (of executing a calculation).</p>
<p>Hope this can help you!</p>
<hr>
<h1>UPDATE</h1>
<p>I understand the point in your comment, hahaha.</p>
<p>It seems to me that <code>unwrap</code> is useful to "move objects out" because they are constant.</p>
<h2>Example</h2>
<p>In General Relativity the metric is covariantly constant, but its partial derivative is nonvanishing in general. So, you should assign a dependence on the partial derivative but not of the covariant derivative.</p>
<pre><code>{l,m,n}::Indices.
\partial{#}::PartialDerivative.
\nabla{#}::Derivative.
g_{m n}::Depends(\partial{#});
\Psi::Depends(\partial{#},\nabla{#});</code></pre>
<p>Now if you define the derivatives of $g \Psi$, and <code>unwrap</code>, the difference is noticeable.</p>
<pre><code>ex1 := \partial_{l}{ g_{m n} \Psi };
unwrap(ex1);
ex2 := \nabla_{l}{ g_{m n} \Psi };
unwrap(ex2);</code></pre>Bug reportshttps://cadabra.science/qa/2768/unwrap-of-partial-derivatives?show=2769#a2769Thu, 28 Mar 2024 08:32:42 +0000Answered: Question about Installation of Cadabra on Ubuntu&Conda
https://cadabra.science/qa/2762/question-about-installation-of-cadabra-on-ubuntu%26conda?show=2763#a2763
<p>First of all, I would <em>strongly</em> advise you not to run anything like this as root user, that's just asking for trouble. It's not the cause of the problem you are having, but still important advice.</p>
<p>The Conda package maintainer has unfortunately abandoned it, and therefore there has not been any update for a long time. You are far better off just installing an Ubuntu package for Cadabra for Ubuntu from the download page; those are provided by me and maintained. And it is also what is written on <a rel="nofollow" href="https://cadabra.science/jupyter.html">https://cadabra.science/jupyter.html</a> . I would remove the Conda packages first before you try this though.</p>
<p>Let me know if this gets you any further.</p>Installation troublehttps://cadabra.science/qa/2762/question-about-installation-of-cadabra-on-ubuntu%26conda?show=2763#a2763Fri, 22 Mar 2024 14:41:23 +0000Answered: The Solution of Einstein's Equation in General Dimensions
https://cadabra.science/qa/2492/the-solution-of-einsteins-equation-in-general-dimensions?show=2760#a2760
<p>The following code should be useful:</p>
<pre><code>{M,N,O,P,Q,R,S}::Indices(full, position=independent);
{\alpha,\beta,\mu,\nu,\sigma,\gamma,\lambda}::Indices(subspace1, position=independent, parent=full);
{\alpha,\beta,\mu,\nu,\sigma,\gamma,\lambda}::Integer(0..d-1).
w::Coordinate;
g_{\mu\nu}::Metric.
g^{\mu\nu}::InverseMetric.
g_{\mu\nu}::Symmetric.
g^{\mu\nu}::Symmetric.
g^{\mu}_{\nu}::KroneckerDelta.
g_{\mu}^{\nu}::KroneckerDelta.
from cdb.utils.indices import *
ex:=g_{M N} g^{M O} P^N;
replace_index(_,r"g",r'O',r'\mu');
split_index(_, $M,\mu,w$,repeat=True);
eliminate_metric(_);
eliminate_kronecker(_);
substitute(_,$P^w->A$);</code></pre>General questionshttps://cadabra.science/qa/2492/the-solution-of-einsteins-equation-in-general-dimensions?show=2760#a2760Thu, 21 Mar 2024 09:13:37 +0000Answered: how to swap indices for partial derivatives
https://cadabra.science/qa/2750/how-to-swap-indices-for-partial-derivatives?show=2751#a2751
<p>Hi bin_go.</p>
<p>I'm noting there is plenty of space in your code to improve, but I'm not here for that (in particular because I don't know your workcase scenario).</p>
<p>So, let me illustrate the use of the algorithm <code>indexsort</code> with an example inspired in your code.</p>
<h2>My example</h2>
<p>First, I'll define the indices and the symbol for the partial derivative.</p>
<pre><code>{a,b,c,d}::Indices("flat",position = free).
{a,b,c,d}::Integer(1..N).
\partial{#}::PartialDerivative.</code></pre>
<p>In this example, I'd define some functions of the "coordinates", but saying that they depends on the derivative</p>
<pre><code>{z,w,v{#}}::Depends(\partial{#});</code></pre>
<p>Define the expression</p>
<pre><code> ex := 2 \chi w**(3) M**(\xi+1) \delta{z}
\partial_{a b}{z} \partial_{a c d}{z} v_{b} v_{c} v_{d} -
2 \chi w**(3) M**(\xi+1) \delta{z}
\partial_{a b}{z} \partial_{c d a}{z} v_{b} v_{c} v_{d};</code></pre>
<p>Note that the result is not simplified, unless we sort the indices</p>
<pre><code> indexsort(ex);</code></pre>
<p>Hope this would help.</p>
<p>Cheers,
Dox.</p>General questionshttps://cadabra.science/qa/2750/how-to-swap-indices-for-partial-derivatives?show=2751#a2751Wed, 20 Mar 2024 08:25:07 +0000Answered: Hello i am a beginner in using Cadabra 2
https://cadabra.science/qa/2747/hello-i-am-a-beginner-in-using-cadabra-2?show=2748#a2748
<p>This means that the indices on the left-hand side and the right-hand side of a replacement rule do not match. For instance,</p>
<pre><code>ex:=A_{m n};
substitute(ex, $A_{m n} = B_{m}$);</code></pre>
<p>You would mess up your equations if it would allow such substitutions.</p>
<p>You <em>can</em> do this if you really want to, by using the <code>-></code> notation,</p>
<pre><code>substitute(ex, $A_{m n} -> B_{m}$);</code></pre>
<p>This will work (but may of course still be wrong).</p>
<p>If you don't get the error from something like this, please post a minimal example.</p>General questionshttps://cadabra.science/qa/2747/hello-i-am-a-beginner-in-using-cadabra-2?show=2748#a2748Sat, 16 Mar 2024 19:45:48 +0000Answered: NameError after upgrade
https://cadabra.science/qa/2745/nameerror-after-upgrade?show=2746#a2746
<p>This depends a lot on how you installed Cadabra before. Did it come from the Cadabra package in the Ubuntu repositories? Or from an earlier install from source? If you installed from a previous package, you should do</p>
<pre><code>sudo apt remove cadabra2</code></pre>
<p>to remove it (and then re-install from source).</p>
<p>If you installed from source, you will need to do some more work. Typically, when you install from source, and do not pass any installation directory parameters, things go into</p>
<pre><code>/usr/local/lib/python3.x/dist-packages/</code></pre>
<p>(replace <code>python3.x</code> with the appropriate Python version). For me this contains (among non-cadabra things),</p>
<pre><code>cadabra2.cpython-310-aarch64-linux-gnu.so
cadabra2_defaults.py
cdb_appdirs.py
cadabra2_jupyter/
cdb/
notebook/</code></pre>
<p>(names will differ on a different architecture). Erase all these (both the files and the directories). Then there is also a bunch of <code>cadabra*</code> binaries in</p>
<pre><code>/usr/local/bin/</code></pre>
<p>Finally, there is a directory</p>
<pre><code>/usr/local/share/cadabra2/</code></pre>
<p>If you erase all this and re-install from source, hopefully things go better.</p>Installation troublehttps://cadabra.science/qa/2745/nameerror-after-upgrade?show=2746#a2746Tue, 05 Mar 2024 18:15:32 +0000Output not displaying as rendered latex
https://cadabra.science/qa/2739/output-not-displaying-as-rendered-latex
<p>I am not sure when this started as far as what was upgraded. In Jupyterlab all output is showing as latex statements inside $$s and not rendering. </p>
<p>If I copy the output and paste it into a markdown cell it renders correctly. </p>
<p>I.E.
{\mu,\nu,\rho}::Indices(position=free).
x::Coordinate.
\partial{#}::Derivative.</p>
<p>F<em>{\mu\nu}::AntiSymmetric;
F</em>{\mu\nu}::Depends(x).
A_{\mu}::Depends(x,\partial{#}).
\delta{#}::Accent;</p>
<p>Output:
${}\text{Property Accent attached to}\delta{#}.$</p>
<p>Input:
S:= -1/4 \int{ F_{\mu\nu} F^{\mu\nu} }{x};</p>
<p>Output:
${} - \frac{1}{4}\int F^{\mu \nu} F_{\mu \nu}\,\,{\rm d}x$</p>
<p>If I view the file in Jupyter notebook the code renders correctly.</p>
<p>?? Thanks,
ChuckW</p>
<p>When I posted this the 2nd example output rendered correctly in the post but not in Jupyterlab?</p>Installation troublehttps://cadabra.science/qa/2739/output-not-displaying-as-rendered-latexThu, 15 Feb 2024 18:26:19 +0000How to create derivatives of coordinates with indices?
https://cadabra.science/qa/2738/how-to-create-derivatives-of-coordinates-with-indices
<p>I have two sets of coordinates, and two partial derivatives which can act on these coordinates. These should work in a way such that:</p>
<p>$$
\partial_{x^{\mu}} x^{\nu} = \delta_{\mu}^{\nu} = \partial_{a<em>{\nu}} a\</em>{\mu}.
$$</p>
<p>How would I go about implementing this in Cadabra? I've tried defining partial derivatives of corresponding coordinates directly, I've tried using notation like DX and DA to differentiate between the two and then using LaTeXform to make it more tidy but I inadvertently run into a stop of some sort. </p>
<p>Any and all help will be greatly appreciated!</p>General questionshttps://cadabra.science/qa/2738/how-to-create-derivatives-of-coordinates-with-indicesThu, 15 Feb 2024 17:28:42 +0000Answered: meld returns zero where it shouldn't?
https://cadabra.science/qa/2734/meld-returns-zero-where-it-shouldnt?show=2736#a2736
<p>There is a bug in the logic that sets terms to zero when overlapping symmetry sets contain multiple identical indices. I have disabled that logic in meld for now, as I don't have time to think this through carefully. It shouldn't influence anything else as this was strictly a shortcut to find zeroes in particular situations, which meld will still find now, only slower.</p>Bug reportshttps://cadabra.science/qa/2734/meld-returns-zero-where-it-shouldnt?show=2736#a2736Thu, 08 Feb 2024 18:44:43 +0000Answered: derivatives with two indices
https://cadabra.science/qa/2729/derivatives-with-two-indices?show=2732#a2732
<p>If <code>\partial_{G P}{...}</code> really indicates a single derivative (e.g. <code>G</code> and <code>P</code> are spinor indices obtained from a vector index with the use of a Pauli matrix or something like that), then it may make sense to revert to single-index notation temporarily.</p>
<p>Alternatively, just write a substitution rule, e.g.</p>
<pre><code>{G,P,M,N,K,L}::Indices;
\partial{#}::PartialDerivative;
test:=\partial_{G P}{A_{M N}*A^{K L}};
pr:= \partial_{G P}{A?? B??} = \partial_{G P}{A??} B??
+ A?? \partial_{G P}{B??};
substitute(test, pr);</code></pre>
<p>Cadabra does not have functionality to treat multiple indices as one out-of-the-box at the moment.</p>General questionshttps://cadabra.science/qa/2729/derivatives-with-two-indices?show=2732#a2732Thu, 18 Jan 2024 11:23:35 +0000Answered: Operations with fractional powers of negative numbers
https://cadabra.science/qa/2726/operations-with-fractional-powers-of-negative-numbers?show=2727#a2727
<p>It's not the fractional power, it's the '-1' inside the square root (any factor except '+1' leads to the same problem). This indeed should have returned unevaluated, I'm not sure why I left the hard <code>assert</code> in the code which makes it bail out, other than to indicate to myself that this code was unfinished. I have filed an issue so we do not lose track of this again, <a rel="nofollow" href="https://github.com/kpeeters/cadabra2/issues/290">https://github.com/kpeeters/cadabra2/issues/290</a>.</p>
<p>The sympy bridge can help with this,</p>
<pre><code>simplify($(-X)**{-5/2} X$);</code></pre>
<p>returns what you want.</p>Bug reportshttps://cadabra.science/qa/2726/operations-with-fractional-powers-of-negative-numbers?show=2727#a2727Tue, 16 Jan 2024 19:15:49 +0000Answered: Interaction between 'canonicalise' and vector spinors
https://cadabra.science/qa/2723/interaction-between-canonicalise-and-vector-spinors?show=2724#a2724
<p>Well spotted. Effectively, what went wrong here is that the <code>canonicalise</code> function would incorrectly treat <code>\psi^a \bar{\psi^b}</code> as having the spinor line contracted (so as if the Dirac bar would be sitting on the first factor). The niceties of implicit notation...</p>
<p>I have pushed a fix to github now. If you need an updated binary package let me know.</p>Bug reportshttps://cadabra.science/qa/2723/interaction-between-canonicalise-and-vector-spinors?show=2724#a2724Thu, 11 Jan 2024 20:02:55 +0000Answered: evaluate() returns RuntimeError when using the explicit value of an index
https://cadabra.science/qa/2710/evaluate-returns-runtimeerror-using-explicit-value-index?show=2720#a2720
<p>In line with Kasper's comment, here is a solution with all index locations filled with indices, not values. I post it here in the hope it helps someone else, until the issue is fixed.</p>
<p>Instead of calculating explcitly the <code>K_1 e_1</code> multiplication do the more general <code>K_i e_j</code> multiplication, as follows:</p>
<pre><code>d = 3
{i,j,k,l,m,n}::Indices(rotation, values={1..3}).
\epsilon{#}::EpsilonTensor.
ex := K_{i j m} = \epsilon_{i m n} e_{j}_{n};
s = 'e_{1}_{1} = 1, e_{1}_{2} = 0, e_{1}_{3} = 0,' + \
'e_{2}_{1} = 0, e_{2}_{2} = 1, e_{2}_{3} = 0,' + \
'e_{3}_{1} = 0, e_{3}_{2} = 0, e_{3}_{3} = 1'
Ex(s);
evaluate(ex, Ex(s), rhsonly=True);</code></pre>
<p>This works and you can then pick out the <code>K_1 e_1</code> matrix elements: they are the <code>1,m,1</code> elements in the result (with <code>m</code> any of <code>{1,2,3}</code>). (as it happens, they vanish, which is the correct result).</p>
<p>GPN</p>General questionshttps://cadabra.science/qa/2710/evaluate-returns-runtimeerror-using-explicit-value-index?show=2720#a2720Tue, 09 Jan 2024 09:34:59 +0000Answered: remove_zero_components and components_to_subrule fail with AttributeError
https://cadabra.science/qa/2714/remove_zero_components-components_to_subrule-attributeerror?show=2717#a2717
<p>You have a mixture of two installations, one in <code>/usr/lib/python3.10/dist-packages/</code> and one (packages only) in <code>/home/gpn/.config/cadabra_packages/</code>.</p>
<p>I would remove (or temporarily move into a different location) the <code>/home/gpn/.config/cadabra_packages/</code> folder and then try again. </p>Bug reportshttps://cadabra.science/qa/2714/remove_zero_components-components_to_subrule-attributeerror?show=2717#a2717Tue, 09 Jan 2024 08:46:02 +0000Answered: How do I use object properties in a python executable?
https://cadabra.science/qa/2711/how-do-i-use-object-properties-in-a-python-executable?show=2712#a2712
<p>Use the following:</p>
<pre><code>import cadabra2 as cad
cad.Indices(cad.Ex("[a,b,c,d]"),
cad.Ex("name=spacetime, position=independent"))</code></pre>
<p>The <code>Indices</code> function takes two Cadabra expression <code>Ex</code> objects. The first is the list of indices, the second all the arguments.</p>General questionshttps://cadabra.science/qa/2711/how-do-i-use-object-properties-in-a-python-executable?show=2712#a2712Sat, 06 Jan 2024 12:12:11 +0000Answered: Simplification of sum of terms r a^m + s a^m to (r+s)a^m
https://cadabra.science/qa/2707/simplification-of-sum-of-terms-r-a-m-s-a-m-to-r-s-a-m?show=2708#a2708
<p>The problem in your code arises because <code>b^{4}</code> is not the same as <code>b**4</code>. If you do <code>print(tree(ex))</code> on the output, you can see that one of the terms has <code>b^{4}</code> and the other <code>b**4</code> (represented as <code>\pow{b}{4}</code>.</p>
<p>You can solve this in various ways. One way is to convert the <code>b**4</code> to <code>b^{4}</code> with another rule. But since you really mean a power, perhaps a quicker way to achieve the wanted result is to use powers everywhere, not superscripts:</p>
<pre><code>a::Symbol;
b::Symbol;
{a**m?, b**n?, a, b}::NonCommuting;
{m,n,r,s}::Integer.
r1 := {
a b**m? -> (1+b a) b**{m?-1},
a b -> 1 + b a,
};
def act(ex):
converge(ex):
substitute(ex,r1)
distribute(ex)
collect_factors(ex)
return ex
act($a b**5$);</code></pre>
<p>I have cut out a few other unnecessary steps in your <code>act</code> function (you don't need to call <code>collect_terms</code> to collect terms in an exponent, and you also never need to call the brute force hammer <code>simplify</code> unless you need a simplification for which SymPy is needed).</p>General questionshttps://cadabra.science/qa/2707/simplification-of-sum-of-terms-r-a-m-s-a-m-to-r-s-a-m?show=2708#a2708Mon, 01 Jan 2024 20:59:09 +0000Answered: Display "hand-made" latex
https://cadabra.science/qa/2702/display-hand-made-latex?show=2703#a2703
<p>Timely question ;-) I have <em>just</em> pushed a change to github which allows you to do</p>
<pre><code>s = LaTeXString(
r'\begin{array}{lll}'
r' 0 & 0 & 0 \\'
r' 0 & 0 & 1 \\'
r' 0 & -1 & 0'
r'\end{array}'
)
s;</code></pre>
<p>which will then show (in cadabra2-gtk and the jupyter frontend) the typeset result. </p>
<p>In other words, this is like a normal string, but with information that the content can be processed as LaTeX.</p>General questionshttps://cadabra.science/qa/2702/display-hand-made-latex?show=2703#a2703Fri, 29 Dec 2023 14:10:52 +0000Answered: Replacing expressions in a matrix
https://cadabra.science/qa/2700/replacing-expressions-in-a-matrix?show=2701#a2701
<p>Some answers I gathered in the hope they help others.</p>
<p>Answer #1:</p>
<p>The following code isn't pretty, but it solves issue #1 by creating a python matrix and storing values into that matrix..</p>
<pre><code>from cdb.core.component import *
from cdb.utils.node import *
d = 3
{k,l,m,n}::Indices(rotation, values={1..3}).
\epsilon{#}::EpsilonTensor.
Kl := (K_{l})_{m n} = \epsilon_{l m n};
evaluate(Kl, rhsonly=True);
mat = [[0 for _ in range(d)] for _ in range(d)]
for ex in Kl[r'\equals']:
lhs = get_lhs(ex.ex())
rhs = get_rhs(ex.ex())
if ${a?,b?,c?}$.matches(lhs):
n = int(str(nth_arg(lhs,0)))
if n == 1:
i = int(str(nth_arg(lhs,1)))
j = int(str(nth_arg(lhs,2)))
mat[i-1][j-1] = str(rhs)</code></pre>
<p>After this, depending on your use case, you can, e.g. turn the matrix into a string and display the string in a LaTeX format, as follows.</p>
<p>Answer #2: beginning in version <code>2.4.5.2</code>, the following (using the new feature <code>LaTeXString</code>) works:</p>
<pre><code>K1 = r'\left[ \begin{array}{cc} '
for i in range(d):
for j in range(d):
if j%d > 0: K1 += ' & '
K1 += str(mat[i][j])
if i%d < d-1: K1 += r' \\'
K1 += r' '
else:
K1 += r'\end{array} \right]'
LaTeXString(K1);</code></pre>
<p>Good luck</p>General questionshttps://cadabra.science/qa/2700/replacing-expressions-in-a-matrix?show=2701#a2701Wed, 27 Dec 2023 19:54:04 +0000Answered: Displaying a matrix with matplotlib error "non-GUI backend"
https://cadabra.science/qa/2698/displaying-a-matrix-with-matplotlib-error-non-gui-backend?show=2699#a2699
<p>Cadabra doesn't use <code>plt.show()</code>. Just display the <code>fig</code> object with</p>
<pre><code>fig;</code></pre>
<p>or</p>
<pre><code>display(fig)</code></pre>General questionshttps://cadabra.science/qa/2698/displaying-a-matrix-with-matplotlib-error-non-gui-backend?show=2699#a2699Mon, 25 Dec 2023 18:48:01 +0000Answered: Displaying components of the epsilon matrix
https://cadabra.science/qa/2696/displaying-components-of-the-epsilon-matrix?show=2697#a2697
<p>Tensors do not have component values by default in Cadabra. You typically write down some tensor expression in abstract form (like that <code>Ki</code> line of yours) and then <code>evaluate</code> the components of that expression by making use of implicit or explicit rules about the components of the tensors that make up this expression.</p>
<p>In your case, try something like</p>
<pre><code>from cdb.core.component import *
{i,j,k,l,m,n}::Indices(topological, values={1,2,3}).
\epsilon{#}::EpsilonTensor.
Ki := (K_{i})_{m n} = \epsilon_{i m n}.
evaluate(Ki, rhsonly=True);
get_component(Ki, $1, 2, 3$);</code></pre>
<p>Note that I have also added the range of the indices.</p>
<p>There isn't anything simple at the moment to get a two-index object in the form of a matrix, unfortunately.</p>General questionshttps://cadabra.science/qa/2696/displaying-components-of-the-epsilon-matrix?show=2697#a2697Sun, 24 Dec 2023 23:16:23 +0000Answered: LaTeXForm expansion fails with "free indices do not match"
https://cadabra.science/qa/2692/latexform-expansion-fails-with-free-indices-do-not-match?show=2693#a2693
<p>That message says that the left-hand side ($\sigma_{\beta}$) does not have the same free indices as the right-hand side. As it stands, the right-hand side does not have any free indices, as functional arguments (things which do not have a sub- or super-script symbol) do not propagate their indices outside the function. </p>
<p>If you add</p>
<pre><code>inner{a?? b??}::IndexInherit.</code></pre>
<p>then the index $\beta$ on the $e_\beta$ inside <code>inner</code> will be 'visible' on the outside of <code>inner</code>, and things match up.</p>General questionshttps://cadabra.science/qa/2692/latexform-expansion-fails-with-free-indices-do-not-match?show=2693#a2693Fri, 22 Dec 2023 13:31:08 +0000Answered: How to collect terms containing derivatives
https://cadabra.science/qa/2680/how-to-collect-terms-containing-derivatives?show=2691#a2691
<p>Hi alonli!</p>
<p>The notation you're using makes me think that you've read our article. If so, thank you very much! It is awesome to note that our work benefits other researchers.</p>
<p>Now, I understand that what you're providing in the question is (probably) a simple example of what you really want to do. However, there are many manipulations that are doing nothing (including the indiscriminate use of the algorithm <code>canonicalise</code>, which is slow because it tries many "simplification" algorithms).</p>
<p>I came out with a shorter list of algorithms that work better in your example (you might have to modify it to fit your necessities):</p>
<pre><code>{a#,b#}::Indices.
\delta{#}::KroneckerDelta.
{a#,b#}::Integer(0..3)
\partial{#}::PartialDerivative.
\epsilon{#}::EpsilonTensor(delta=-\delta).
h_{a1 b1}::Symmetric.
toh := {h_{a1 a1} = h, h_{a1}^{a1} = h}.
def LLmanip(ex):
expand_delta(ex)
distribute(ex)
eliminate_kronecker(ex)
substitute(ex, toh)
sort_product(ex)
rename_dummies(ex)
lower_free_indices(ex)
meld(ex)
rename_dummies(ex)
return ex
LL := \delta^{a1 b1 a2 b2 a3 b3 a4 b4} \partial_{a1}{h_{a2 b2}} \partial_{b1}{h_{a3 b3}} h_{a4 b4};
LLmanip(LL);</code></pre>
<p>I want to drive your attention to the single use of the algorithm <code>meld</code> intead of several <code>canonicalise</code>, single <code>sort_product</code> and <code>rename_dummies</code>, and the lack of the <code>sort_sum</code> (perhaps you might still want it there).</p>
<p>I know that it is useful to define functions for general purpose manipulations, but it is important to keep them "optimal", because once your expressions start to get a bit complex, the functions become very time consuming.</p>
<p>Cheers,
Dox.</p>General questionshttps://cadabra.science/qa/2680/how-to-collect-terms-containing-derivatives?show=2691#a2691Mon, 18 Dec 2023 09:30:53 +0000Answered: Negative powers of 0
https://cadabra.science/qa/2673/negative-powers-of-0?show=2674#a2674
<p>Picky ;-) But yes, you are right. I have pushed a fix to github (it will now raise an exception).</p>Bug reportshttps://cadabra.science/qa/2673/negative-powers-of-0?show=2674#a2674Tue, 12 Dec 2023 20:02:48 +0000Answered: meld sets to zero when it shouldn't?
https://cadabra.science/qa/2668/meld-sets-to-zero-when-it-shouldnt?show=2671#a2671
<p>Hi GNP. I was playing with your code (thank you for sharing it!), and I noticed that the problem is not with the <code>meld</code> algorithm, but with the previous<code>sort_product</code>.</p>
<p>If you comment the <code>sort_product</code> the result of both codes is the same (and nontrivial).</p>
<p>Cheers,
Dox.</p>Bug reportshttps://cadabra.science/qa/2668/meld-sets-to-zero-when-it-shouldnt?show=2671#a2671Wed, 06 Dec 2023 14:21:02 +0000Answered: Partial derivative of a vector
https://cadabra.science/qa/2669/partial-derivative-of-a-vector?show=2670#a2670
<p>Whenever you <code>evaluate</code>, the expression should not contain derivatives, otherwise simplification by sympy will throw that error. But you can turn that off, so the following does what you want:</p>
<pre><code>\partial{#}::PartialDerivative;
{t,x,y,z}::Coordinate;
{\mu, \nu}::Indices(values={t,x,y,z});
A^{\mu}::Depends(\partial{#});
dA:=\partial_{\mu}{ A^{\mu} };
evaluate(dA, simplify=False);</code></pre>
<p>If you replace the last two lines with</p>
<pre><code>dA:=\partial_{\mu}{ A^{\nu} };
evaluate(dA, simplify=False);</code></pre>
<p>you get that 2x2 expression.</p>General questionshttps://cadabra.science/qa/2669/partial-derivative-of-a-vector?show=2670#a2670Wed, 06 Dec 2023 14:09:56 +0000Answered: A vector-field basis of derivatives?
https://cadabra.science/qa/2665/a-vector-field-basis-of-derivatives?show=2667#a2667
<p>@dbutter thank you! I applied your advice and here is what I got. I think some useful ideas are:</p>
<ul>
<li>define a new class <code>VectorField</code></li>
<li>define the operation <code>v(f)</code>, where <code>v</code> is a vector field and <code>f</code> is a scalar field, as a python <code>__call__</code></li>
</ul>
<p>I hope this helps someone additional.</p>
<pre><code>from cdb.core.manip import multiply_through
\partial{#}::PartialDerivative;
{\mu,\nu}::Indices(spacetime,position=fixed);
{f,}::Depends(\partial{#});
{u^{\mu},v^{\mu}, \partial_{\nu}{f}, \partial_{\mu\nu}{f}, e_{\nu}, f, (1/f)}::SortOrder;
def find_first_index(v):
for ix in v.top().free_indices():
if ix.parent_rel==super:
return ix
raise TypeError(f'{0} has no contravariant index')
class VectorField:
def __init__(self, v: Ex):
self.v = v
def __call__(self, s: Ex):
return self.of_scalar(s)
def of_scalar(self,s):
ix = find_first_index(self.v)
ex = self.v
return $@(ex) \partial_{@(ix)}{@(s)}$
u = VectorField($u^{\mu}$)
v = VectorField($v^{\mu}$)
f := f.
lhs := \commutator{u}{v} f ;
rhs = u(v(f)) - v(u(f));
ex := @(lhs) = @(rhs);
product_rule(ex);
distribute(ex);
sort_product(ex);
meld(ex);
factor_out(ex,$\partial_{\nu}{f}$, right=True);
substitute(ex, $\partial_{\nu}{f} -> e_{\nu} f$);
multiply_through(ex, $1/f$)
collect_factors(ex);</code></pre>
<p>Thanks
GPN</p>General questionshttps://cadabra.science/qa/2665/a-vector-field-basis-of-derivatives?show=2667#a2667Tue, 05 Dec 2023 10:41:44 +0000Answered: Is eliminate_metric supposed to move partial derivative indices?
https://cadabra.science/qa/2508/eliminate_metric-supposed-move-partial-derivative-indices?show=2664#a2664
<p>I did not find a way to do exactly what you want. But here is an alternative. Define <code>\nabla</code> as a <code>Derivative</code> or <code>PartialDerivative</code>.</p>
<pre><code>{\mu, \nu}::Indices(position=independent).
\partial{#}::PartialDerivative.
g_{\mu \nu}::Metric.
g^{\mu \nu}::InverseMetric.
g_{\mu}^{\nu}::KroneckerDelta.
g^{\mu}_{\nu}::KroneckerDelta.
g_{\mu \nu}::Depends(\partial{#}).
g^{\mu \nu}::Depends(\partial{#}).
\nabla{#}::PartialDerivative.
\nabla{#}::Depends(\partial{#}).
expr:=g^{\mu \nu}\nabla_{\nu}{A_{\mu}};
eliminate_metric(_);</code></pre>
<p>The crucial point is that the covariant derivative of the metric is 0, so you do <em>not</em> need to add</p>
<pre><code>g_{\mu \nu}::Depends(\nabla{#}).
g^{\mu \nu}::Depends(\nabla{#}).
</code></pre>
<p>As a result the metric "passes through" the <code>\nabla</code> derivative operator. I hope this helps.</p>
<p>GPN</p>General questionshttps://cadabra.science/qa/2508/eliminate_metric-supposed-move-partial-derivative-indices?show=2664#a2664Mon, 04 Dec 2023 22:15:18 +0000Answered: Avoiding index classes when handling ExNodes
https://cadabra.science/qa/2653/avoiding-index-classes-when-handling-exnodes?show=2661#a2661
<p>Here is a solution that solves some of these issues:</p>
<pre><code>{a,b,c,d,a#}::Indices(vector).
{i,j,k,l,i#}::Indices(isospin).
\nabla{#}::Derivative.
\partial{#}::PartialDerivative.
def expand_nabla(ex):
for nabla in ex[r'\nabla']:
nabla.name=r'\partial'
dindex = nabla.indices().__next__()
for arg in nabla.args():
ret:=0;
for index in arg.free_indices():
indexprop = Indices.get(index, ignore_parent_rel = True)
if indexprop.set_name == 'vector':
t2:= @(arg);
dummy = indexprop.get_dummy(ex)
if index.parent_rel==sub:
t1:= -\Gamma^{@(dummy)}_{@(dindex) @(index)};
t2[index]:= _{@(dummy)};
else:
t1:= \Gamma^{@(index)}_{@(dindex) @(dummy)};
t2[index]:= ^{@(dummy)};
ret += Ex(str(nabla.multiplier)) * t1 * t2
nabla += ret
return ex</code></pre>
<p>This version grabs a dummy index by looking at the entire expression tree, while in practice, we might just want to look at the term in the top-level sum. It knows to ignore isospin indices and only grab vector indices. We also need \nabla and \partial to have IndexInherit (inherited from Derivative). </p>General questionshttps://cadabra.science/qa/2653/avoiding-index-classes-when-handling-exnodes?show=2661#a2661Sun, 03 Dec 2023 14:22:53 +0000Answered: How to get the `weight` value of an object?
https://cadabra.science/qa/2440/how-to-get-the-weight-value-of-an-object?show=2652#a2652
<p>I have pushed a fix based on dbutter's suggestion, so in short, you can now do</p>
<pre><code>x::Weight(value=1, label=field);
weight = Weight.get($x$, label="field").value("field")</code></pre>
<p>to get the weight on the Python side.</p>General questionshttps://cadabra.science/qa/2440/how-to-get-the-weight-value-of-an-object?show=2652#a2652Fri, 01 Dec 2023 20:13:45 +0000