I just started to learn how to use xAct and xTensor. I would like to define the following vector field on a manifold equipped with a Lorentzian metric.

My attempt was

DefManifold[M, 4, {a, b, c, d, e}]
DefMetric[-1, met[-a, -b], CD]
DefTensor[X[a], M]
DefTensor[u[a], M]
n = Sqrt[-X[b] X[-b]]
IndexSet[u[a], X[a]/n]

However, when evaluating u[a]u[-a] I get -((X[-a]X[a])/(X[-f]X[f])) that I would like to be simplified to $-1$.

Moreover, despite the use of abstract indices, I don't get what I expect entering e.g u[b]

Is there a way to solve both problems at once?

  • $\begingroup$ Do you have to normalize explicitly ? For this case you can maybe skip the normalization and use TagSet like u /: u[-a_] u[a_] = -1. For more complicated cases where there are introduced new indices on the right hand side of the rule and you want a rule to be applied automatically you could look into AutomaticRules in that package. $\endgroup$ Oct 22, 2022 at 21:36
  • $\begingroup$ When I evaluated u[-a]*u[a] with your code the u[-a] did not change, I got (u[-a] X[a])/Sqrt[- X[-b] X[b]] $\endgroup$ Oct 22, 2022 at 21:44
  • $\begingroup$ The xTensor documentation for IndexSet shows that the element on the left in the list has to be a pattern with pattern objects _. This is not the case however for MakeRule as the indices for the element in the list on the left are automatically converted to patterns. $\endgroup$ Oct 22, 2022 at 22:07
  • $\begingroup$ Thank you for your answers. I used the IndexSet[u[a_], X[a]/n] as you suggested and it seems to work. However, it still doesn't simplify the norm of $u$ to $-1$, even with the assumption that the norm of $X$ is non-zero. $\endgroup$ Oct 24, 2022 at 7:09
  • $\begingroup$ Is there a reason why you do not want to use u /: u[-a_]*u[a_] = -1 ? Doing that the vector is normalized without having to use an explicit normalization factor. $\endgroup$ Oct 24, 2022 at 16:47

1 Answer 1


Discusion and context

I checked the xact google group and I did not find a clear or safe answer to this question. In one of the answers here the user was perhaps given a solution that modifies how xAct works and later the same person mentions a potential danger that explained why one of the potential solutions for this was not implemented. It is unclear to me whether the solution that the user provided before is safe or whether it would work here. Hence, I have refrained myself from trying that method. Instead, in the following I will give 3 possible solutions to this issue regarding normalization.

See references in the last section to search for functions that you might not be familiar with.

Functions in the text below that belong to the xAct/xTensor package will be followed by (xAct/xTensor).

Setting up definitions:

<< xAct`xTensor`;
DefManifold[M, 4, {a, b, c, d, e}];
DefMetric[-1, met[-a, -b], CD];
DefTensor[X[a], M];
DefTensor[u[a], M];(*normalized X*)

Note: If like me you finding all the printing that xact does each time one defines something then you could use $DefInfoQ = False

First solution: use UpValues (maybe easiest/best generic solution)

I think the best/easiest solution would be to momentarily forget about the un-normalized vector X and to introduce it only when needed using :

expression /. IndexRule[u[a_],X[a]/normalization]

Then one could avoid explicit normalization of u and instead associate an upvalue (a property) to the normalized vector u using the same method as provided in this answer on stack exchange (without using IndexSet[u[a_], X[a]/n](xAct/xTensor) and thus contrarily to the method in the original question) :

u /: u[-a_] u[a_] = -1

This has the benefit of keeping the equations clean without carrying around a normalization factor in certain expressions.

2nd solution: not defining the normalization factor

If for whatever reason the user wishes to use IndexSet[u[a], X[a]/normalization](xAct/xTensor) then one option might be to not use an explicit definition for the normalization:

IndexSet[u[a_], X[a]/normalization];

Then one could use MakeRule (xAct/xTensor):

rule = MakeRule[{X[-a]*X[a], -normalization^2}];

and use

u[-c]*u[c] /. rule

(* -1 *)

u[-c]*u[c]*X[a]*X[b] /. rule

(* - X[a] X[b] *)

Using rule each time could be tedious so one could use AutomaticRules (xAct/xTensor):

AutomaticRules[X, rule];

Now one no longer needs to use explicitly rule


(* -1 *)

Third solution : use Scalar(xAct/xTensor) and PutScalar(xAct/xTensor)

If one would like to explicitly see something like $\frac{X^a}{\sqrt{-X^b X_b}}$ in the equations and thus define the normalization, then one should use Scalar (xAct/xTensor) to specify explicitly that $X^b X_b$ should be considered as a scalar/number and should always be grouped together under the head Scalar. Using Scalar is particularly important to prevent simplification from an expression like $\frac{X^a}{X^a X_a}$ if what was meant was $\frac{X^a}{\sum_b \left(X^b X_b\right)}$ when the Einstein notation is removed. That might also be important when computing derivatives. Other scenarios where Scalar could be needed is when taking squares of a scalar to prevent index clashes see the documentation page here for examples.

Explicit normalization:

n = (-Scalar[X[b] X[-b]])^(1/2);
IndexSet[u[a_], X[a]/n];

Simplification of $ u_c u^c $ using PutScalar(xAct/xTensor) and Simplification(xAct/xTensor):

u[-c]*u[c] // PutScalar // Simplification

(* -1 *)


I found it difficult to find the documentation with the xact website. Here is a list of references mainly for xTensor and xTras:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.