From 0d54ec50c2a4456f7e6eca51b1f7cb8dd5388682 Mon Sep 17 00:00:00 2001
From: Isuru Fernando <isuruf@gmail.com>
Date: Tue, 30 Jan 2018 16:25:10 -0600
Subject: [PATCH] Introduce deriv_multiplier

---
 sumpy/expansion/__init__.py | 127 ++++++++----------------------------
 1 file changed, 27 insertions(+), 100 deletions(-)

diff --git a/sumpy/expansion/__init__.py b/sumpy/expansion/__init__.py
index f4144a86..f12cde63 100644
--- a/sumpy/expansion/__init__.py
+++ b/sumpy/expansion/__init__.py
@@ -246,6 +246,10 @@ def _spmv(spmat, x, sparse_vectors):
 
 class LinearRecurrenceBasedDerivativeWrangler(DerivativeWrangler):
 
+    def __init__(self, order, dim, deriv_multiplier):
+        super(LinearRecurrenceBasedDerivativeWrangler, self).__init__(order, dim)
+        self.deriv_multiplier = deriv_multiplier
+
     def get_coefficient_identifiers(self):
         return self.stored_identifiers
 
@@ -304,77 +308,12 @@ class LinearRecurrenceBasedDerivativeWrangler(DerivativeWrangler):
             matrix_row = []
             for icol, coeff in row:
                 diff = row_rscale - sum(stored_identifiers[icol])
-                matrix_row.append((icol, coeff * rscale**diff))
+                mult = (rscale*self.deriv_multiplier)**diff
+                matrix_row.append((icol, coeff * mult))
             matrix_rows.append((irow, matrix_row))
 
         return defaultdict(list, matrix_rows)
 
-    @memoize_method
-    def _get_stored_ids_and_coeff_mat(self):
-        stored_identifiers = []
-        identifiers_so_far = {}
-
-        import time
-        start_time = time.time()
-        logger.debug("computing recurrence for Taylor coefficients: start")
-
-        # Sparse matrix, indexed by row
-        coeff_matrix_transpose = defaultdict(list)
-
-        # Build up the matrix transpose by row.
-        from six import iteritems
-        for i, identifier in enumerate(self.get_full_coefficient_identifiers()):
-            expr = self.try_get_recurrence_for_derivative(
-                    identifier, identifiers_so_far)
-
-            if expr is None:
-                # Identifier should be stored
-                coeff_matrix_transpose[len(stored_identifiers)] = [(i, 1)]
-                stored_identifiers.append(identifier)
-            else:
-                expr = dict((identifiers_so_far[ident], val) for ident, val in
-                            iteritems(expr))
-                result = _spmv(coeff_matrix_transpose, expr, sparse_vectors=True)
-                for j, item in iteritems(result):
-                    coeff_matrix_transpose[j].append((i, item))
-
-            identifiers_so_far[identifier] = i
-
-        stored_identifiers = stored_identifiers
-
-        coeff_matrix = defaultdict(list)
-        for i, row in iteritems(coeff_matrix_transpose):
-            for j, val in row:
-                coeff_matrix[j].append((i, val))
-
-        logger.debug("computing recurrence for Taylor coefficients: "
-                     "done after {dur:.2f} seconds"
-                     .format(dur=time.time() - start_time))
-
-        logger.debug("number of Taylor coefficients was reduced from {orig} to {red}"
-                     .format(orig=len(self.get_full_coefficient_identifiers()),
-                             red=len(stored_identifiers)))
-
-        return stored_identifiers, coeff_matrix
-
-    def try_get_recurrence_for_derivative(self, deriv, in_terms_of):
-        """
-        :arg deriv: a tuple of integers identifying a derivative for which
-            a recurrence is sought
-        :arg in_terms_of: a container supporting efficient containment testing
-            indicating availability of derivatives for use in recurrences
-        """
-
-        raise NotImplementedError
-
-    def get_derivative_taker(self, expr, var_list):
-        from sumpy.tools import LinearRecurrenceBasedMiDerivativeTaker
-        return LinearRecurrenceBasedMiDerivativeTaker(expr, var_list, self)
-
-
-class NewLinearRecurrenceBasedDerivativeWrangler \
-        (LinearRecurrenceBasedDerivativeWrangler):
-
     @memoize_method
     def _get_stored_ids_and_coeff_mat(self):
         from scipy.linalg.interpolative import interp_decomp
@@ -432,17 +371,23 @@ class NewLinearRecurrenceBasedDerivativeWrangler \
 
         return stored_identifiers, coeff_matrix
 
-    @memoize_method
-    def get_coefficient_matrix(self, rscale):
-        _, coeff_matrix = self._get_stored_ids_and_coeff_mat()
-        return coeff_matrix
+    def get_pde_dict(self):
+        """
+        Return the PDE as a dictionary of derivative_identifier: coeff such that
+        sum(derivative_identifer * coeff) = 0 is the PDE.
+        """
+
+        raise NotImplementedError
 
     def get_derivative_taker(self, expr, var_list):
         from sumpy.tools import NewLinearRecurrenceBasedMiDerivativeTaker
         return NewLinearRecurrenceBasedMiDerivativeTaker(expr, var_list, self)
 
 
-class LaplaceDerivativeWrangler(NewLinearRecurrenceBasedDerivativeWrangler):
+class LaplaceDerivativeWrangler(LinearRecurrenceBasedDerivativeWrangler):
+
+    def __init__(self, order, dim):
+        super(LaplaceDerivativeWrangler, self).__init__(order, dim, 1)
 
     def get_pde_dict(self):
         pde_dict = {}
@@ -456,35 +401,17 @@ class LaplaceDerivativeWrangler(NewLinearRecurrenceBasedDerivativeWrangler):
 class HelmholtzDerivativeWrangler(LinearRecurrenceBasedDerivativeWrangler):
 
     def __init__(self, order, dim, helmholtz_k_name):
-        super(HelmholtzDerivativeWrangler, self).__init__(order, dim)
-        self.helmholtz_k_name = helmholtz_k_name
-
-    def try_get_recurrence_for_derivative(self, deriv, in_terms_of):
-        deriv = np.array(deriv, dtype=int)
+        multiplier = sym.Symbol(helmholtz_k_name)
+        super(HelmholtzDerivativeWrangler, self).__init__(order, dim, multiplier)
 
-        for dim in np.where(2 <= deriv)[0]:
-            # Check if we can reduce this dimension in terms of the other
-            # dimensions.
-
-            reduced_deriv = deriv.copy()
-            reduced_deriv[dim] -= 2
-            coeffs = {}
-
-            for other_dim in range(self.dim):
-                if other_dim == dim:
-                    continue
-                needed_deriv = reduced_deriv.copy()
-                needed_deriv[other_dim] += 2
-                needed_deriv = tuple(needed_deriv)
-
-                if needed_deriv not in in_terms_of:
-                    break
-
-                coeffs[needed_deriv] = -1
-            else:
-                k = sym.Symbol(self.helmholtz_k_name)
-                coeffs[tuple(reduced_deriv)] = -k*k
-                return coeffs
+    def get_pde_dict(self, **kwargs):
+        pde_dict = {}
+        for d in range(self.dim):
+            mi = [0]*self.dim
+            mi[d] = 2
+            pde_dict[tuple(mi)] = 1
+        pde_dict[tuple([0]*self.dim)] = -1
+        return pde_dict
 
 # }}}
 
-- 
GitLab