From a1951eb12321f7798d016d9952860fb2c08ab434 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=BChle=2C=20Laura=20Christine=20=28lakue103=29?=
 <laura.kuehle@uni-duesseldorf.de>
Date: Thu, 20 Oct 2022 18:13:50 +0200
Subject: [PATCH] Vectorized '_calculate_reconstructions()' in
 OrthonormalLegendre basis.

---
 scripts/tcd/Basis_Function.py | 49 +++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/scripts/tcd/Basis_Function.py b/scripts/tcd/Basis_Function.py
index b5463d5..01eaf27 100644
--- a/scripts/tcd/Basis_Function.py
+++ b/scripts/tcd/Basis_Function.py
@@ -533,17 +533,44 @@ class OrthonormalLegendre(Legendre):
 
         Notes
         -----
-            To increase speed. this function uses a simplified calculation
+            To increase speed, this function uses a simplified calculation
             specific to the orthonormal Legendre polynomial basis.
 
         """
-        left_reconstructions = [
-            sum(projection[degree][cell] * (-1)**degree
-                * np.sqrt(degree + 0.5)
-                for degree in range(self._polynomial_degree+1))
-            for cell in range(len(projection[0]))]
-        right_reconstructions = [
-            sum(projection[degree][cell] * np.sqrt(degree + 0.5)
-                for degree in range(self._polynomial_degree+1))
-            for cell in range(len(projection[0]))]
-        return left_reconstructions, right_reconstructions
+        left_reconstruction = projection.T @ (self._root_vector *
+                                              self._sign_vector)
+        right_reconstruction = projection.T @ self._sign_vector
+
+        return left_reconstruction, right_reconstruction
+
+    @property
+    @cache
+    def _root_vector(self):
+        """Return root vector.
+
+        Return vector with the roots of all degrees plus 0.5.
+
+        Returns
+        -------
+        ndarray
+            Root vector.
+
+        """
+        return np.array([np.sqrt(degree+0.5)
+                         for degree in range(self.polynomial_degree+1)])
+
+    @property
+    @cache
+    def _sign_vector(self):
+        """Return sign vector.
+
+        Return identity vector with sign changes for all even degrees.
+
+        Returns
+        -------
+        ndarray
+            Sign vector.
+
+        """
+        return np.array([-1 if degree % 2 else 1
+                         for degree in range(self._polynomial_degree+1)])
-- 
GitLab