Repository: einsteinpy/einsteinpy

Issue:
Add lorentz_tranform to all the classes in symbolic module
🐞 **Problem**
Many classes like `MetricTensor`, `RiemannCurvatureTensor` does not have the `lorentz_transform()` function as of now!

🎯 **Goal**
Implement it in a similar way as that in `GenericVector` class in `symbolic/vector.py`

  - [x] `GenericVector`
  - [ ] `MetricTensor`
  - [ ] `ChristoffelSymbols`
  - [ ] `RiemannCurvatureTensor`
  - [ ] `RicciTensor`
  - [ ] `StressEnergyMomentumTensor`
  - [x] `EinsteinTensor`
  - [ ] `WeylTensor`
  - [ ] `SchoutenTensor`

📋  **Steps to solve the problem**

 * Comment below about what you've started working on.
 * Add, commit, push your changes
 * Submit a pull request and add this in comments - `Addresses #<put issue number here>`
 * Ask for a review in comments section of pull request
 * Celebrate your contribution to this project 🎉


Discussion:
pep8speaks: Hello @michiboo! Thanks for opening this PR. We checked the lines you've touched for [PEP 8](https://www.python.org/dev/peps/pep-0008) issues, and found:

* In the file [`src/einsteinpy/symbolic/einstein.py`](https://github.com/einsteinpy/einsteinpy/blob/b45e0f548e4e27273c4ab0b41245896157828a5d/src/einsteinpy/symbolic/einstein.py):

> [Line 132:10](https://github.com/einsteinpy/einsteinpy/blob/b45e0f548e4e27273c4ab0b41245896157828a5d/src/einsteinpy/symbolic/einstein.py#L132): [W292](https://duckduckgo.com/?q=pep8%20W292) no newline at end of file


shreyasbapat: Good thing @michiboo .

Can you join our chatroom, we can discuyss why this fails there :D
ritzvik: @michiboo Are you still on it??
michiboo: > @michiboo Are you still on it??

Hi Yes, sorry for the delay, been busy lately :/
ritzvik: @michiboo Can you rebase the commits. Then the ‘docs’ test would pass.
After that lemme take care of the unit tests.
codecov[bot]: # [Codecov](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=h1) Report
> Merging [#357](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=desc) into [master](https://codecov.io/gh/einsteinpy/einsteinpy/commit/17580ec82dae91bf39226df89115bb4876d5c199?src=pr&el=desc) will **decrease** coverage by `0.1%`.
> The diff coverage is `33.33%`.

[![Impacted file tree graph](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357/graphs/tree.svg?width=650&token=H3oDVYA11f&height=150&src=pr)](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##           master    #357      +/-   ##
=========================================
- Coverage    94.5%   94.4%   -0.11%     
=========================================
  Files          47      47              
  Lines        1765    1768       +3     
=========================================
+ Hits         1668    1669       +1     
- Misses         97      99       +2
```


| [Impacted Files](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/einsteinpy/symbolic/einstein.py](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357/diff?src=pr&el=tree#diff-c3JjL2VpbnN0ZWlucHkvc3ltYm9saWMvZWluc3RlaW4ucHk=) | `92% <33.33%> (-8%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=footer). Last update [17580ec...2c6660e](https://codecov.io/gh/einsteinpy/einsteinpy/pull/357?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/einsteinpy/symbolic/einstein.py b/src/einsteinpy/symbolic/einstein.py
index 10fa945..1eb2dc1 100644
--- a/src/einsteinpy/symbolic/einstein.py
+++ b/src/einsteinpy/symbolic/einstein.py
@@ -90,3 +90,23 @@ class EinsteinTensor(BaseRelativityTensor):
             new_tensor, self.syms, config=newconfig, parent_metric=metric
         )
         return new_obj
+
+    def lorentz_transform(self, transformation_matrix):
+        """
+        Performs a Lorentz transform on the tensor.
+
+        Parameters
+        ----------
+            transformation_matrix : ~sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray or list
+                Sympy Array or multi-dimensional list containing Sympy Expressions
+
+        Returns
+        -------
+            ~einsteinpy.symbolic.tensor.BaseRelativityTensor
+                lorentz transformed tensor(or vector)
+
+        """
+        t = super(EinsteinTensor, self).lorentz_transform(transformation_matrix)
+        return EinsteinTensor(
+            t.tensor(), syms=self.syms, config=self._config, parent_metric=None
+        )


Test patch:
diff --git a/src/einsteinpy/tests/test_symbolic/test_einstein.py b/src/einsteinpy/tests/test_symbolic/test_einstein.py
index a68d75d..79c5450 100644
--- a/src/einsteinpy/tests/test_symbolic/test_einstein.py
+++ b/src/einsteinpy/tests/test_symbolic/test_einstein.py
@@ -1,9 +1,14 @@
 import numpy as np
 import pytest
 import sympy
-from sympy import cos, simplify, sin, sinh, tensorcontraction
+from sympy import cos, cosh, simplify, sin, sinh, symbols, tensorcontraction
 
-from einsteinpy.symbolic import EinsteinTensor, MetricTensor, RicciScalar
+from einsteinpy.symbolic import (
+    EinsteinTensor,
+    MetricTensor,
+    RicciScalar,
+    simplify_sympy_array,
+)
 
 
 def schwarzschild_metric():
@@ -66,3 +71,32 @@ def test_EinsteinTensor_symbols_parent_metric_wrong_change_config():
     except Exception:
         boolstore = True
     assert boolstore
+
+
+def test_lorentz_transform():
+    # currently testing correct instance, proper theoretical tests needed
+    def get_lorentz_matrix():
+        list2d = [[0 for t1 in range(4)] for t2 in range(4)]
+        phi = symbols("phi")
+        list2d[0][0], list2d[0][1], list2d[1][0], list2d[1][1] = (
+            cosh(phi),
+            -sinh(phi),
+            -sinh(phi),
+            cosh(phi),
+        )
+        list2d[2][2], list2d[3][3] = 1, 1
+        return list2d
+
+    def get_tensor():
+        x, y, z, w = symbols("x y z w")
+        list2d = [[0 for t1 in range(4)] for t2 in range(4)]
+        list2d[0][0], list2d[0][1], list2d[1][0], list2d[1][1] = x, z, z, x
+        list2d[2][2], list2d[3][3] = y, y
+        return EinsteinTensor(
+            list2d, syms=(x, y, z, w), config="lu", parent_metric=None
+        )
+
+    tm = get_lorentz_matrix()
+    t0 = get_tensor()
+    t1 = t0.lorentz_transform(tm)
+    assert isinstance(t1, EinsteinTensor)