The basic imports and the variables we'll be using:


```python
from __future__ import division
import sympy
from sympy import *
from sympy import Rational as frac
import simpletensors
from simpletensors import Vector, TensorProduct, SymmetricTensorProduct, Tensor
init_printing()


var('vartheta, varphi')
var('nu, m, delta, c, t')

# These are related scalar functions of time
var('r, v, Omega', cls=Function)
r = r(t)
v = v(t)
Omega = Omega(t)

# These get redefined momentarily, but have to exist first
var('nHat, lambdaHat, ellHat', cls=Function)
# And now we define them as vector functions of time
nHat = Vector('nHat', r'\hat{n}', [cos(Omega*t),sin(Omega*t),0,])(t)
lambdaHat = Vector('lambdaHat', r'\hat{\lambda}', [-sin(Omega*t),cos(Omega*t),0,])(t)
ellHat = Vector('ellHat', r'\hat{\ell}', [0,0,1,])(t)

# These are the spin functions -- first, the individual components as regular sympy.Function objects; then the vectors themselves
var('S_n, S_lambda, S_ell', cls=Function)
var('Sigma_n, Sigma_lambda, Sigma_ell', cls=Function)
SigmaVec = Vector('SigmaVec', r'\vec{\Sigma}', [Sigma_n(t), Sigma_lambda(t), Sigma_ell(t)])(t)
SVec = Vector('S', r'\vec{S}', [S_n(t), S_lambda(t), S_ell(t)])(t)
```

## Examples and tests


```python
nHat
```


```python
diff(nHat, t)
```


```python
diff(lambdaHat, t)
```


```python
diff(lambdaHat, t).components
```


```python
diff(lambdaHat, t).subs(t,0).components
```


```python
diff(lambdaHat, t, 2).components
```


```python
diff(lambdaHat, t, 2).subs(t,0).components
```


```python
diff(ellHat, t)
```


```python
diff(nHat, t, 2)
```


```python
diff(nHat,t, 3)
```


```python
diff(nHat,t, 4)
```


```python
diff(SigmaVec,t, 0)
```


```python
SigmaVec.fdiff()
```


```python
diff(SigmaVec,t, 1)
```


```python
diff(SigmaVec,t, 2)
```


```python
diff(SigmaVec,t, 2) | nHat
```


```python
T1 = TensorProduct(SigmaVec, SigmaVec, ellHat, coefficient=1)
T2 = TensorProduct(SigmaVec, nHat, lambdaHat, coefficient=1)
tmp = Tensor(T1,T2)
display(T1, T2, tmp)
```


```python
diff(tmp, t, 1)
```


```python
T1+T2
```


```python
T2*ellHat
```


```python
ellHat*T2
```


```python
T1.trace(0,1)
```


```python
T2*ellHat
```


```python
for k in range(1,4):
    display((T2*ellHat).trace(0,k))
```


```python
for k in range(1,4):
    display((T2*ellHat).trace(0,k).subs(t,0))
```


```python
T1.trace(0,1) * T2
```

Sympy can be a little tricky because it caches things, which means that the first implementation of this code silently changed tensors in place, without meaning to.  Let's just check that our variables haven't changed:


```python
display(T1, T2)
```


```python
T3 = SymmetricTensorProduct(SigmaVec, SigmaVec, ellHat, coefficient=1)
display(T3)
T3.trace(0,1)
```


```python
diff(T3, t, 1)
```


```python
T3.symmetric
```




    True




```python
T3*ellHat
```


```python
ellHat*T3
```


```python
T1+T3
```


```python
T1 = SymmetricTensorProduct(SigmaVec, SigmaVec, ellHat, nHat, coefficient=1)
display(T1)
display(T1.trace())
```


```python
T1*T2
```


```python
type(_)
```




    simpletensors.TensorProductFunction_73




```python
import simpletensors
isinstance(__, simpletensors.TensorProductFunction)
```




    True




```python
SymmetricTensorProduct(nHat, nHat, nHat).trace()
```


```python
diff(T1.trace(), t, 1)
```


```python
diff(T1.trace(), t, 2)
```


```python
diff(T1.trace(), t, 2).subs(t,0)
```


```python

```

0756c326c6e14f23762d25d34aff36b6200d4bd4
ipynb
Jupyter Notebook
Waveforms/TestTensors.ipynb
keefemitman/PostNewtonian
853d6577cb0002da5eebe1cb55f0c28fbc114324
MIT
2015-03-26T01:04:36.000Z
2022-02-01T19:26:21.000Z
Waveforms/TestTensors.ipynb
keefemitman/PostNewtonian
853d6577cb0002da5eebe1cb55f0c28fbc114324
MIT
2015-01-08T23:46:29.000Z
2017-09-20T19:13:51.000Z
Waveforms/TestTensors.ipynb
keefemitman/PostNewtonian
853d6577cb0002da5eebe1cb55f0c28fbc114324
MIT
2016-05-13T02:36:14.000Z
2021-11-23T21:36:32.000Z
Qwen/Qwen-72B
1. YES
2. YES