Repository: kymatio/kymatio

Issue:
core scattering doesn't need max_order as input argument
instead, we could pass
`[phi_f, psi1_f]` to signify `max_order==1` 

and `[phi_f, psi1_f, psi2_f]` to signify `max_order==2`

fewer input arguments and potentially a greater consistency with JTFS

(which won't have a `max_order` but rather a `filters` list and a `filters_fr` list)


Discussion:

Resolving patch:
diff --git a/kymatio/scattering1d/core/scattering1d.py b/kymatio/scattering1d/core/scattering1d.py
--- a/kymatio/scattering1d/core/scattering1d.py
+++ b/kymatio/scattering1d/core/scattering1d.py
@@ -1,5 +1,5 @@
 
-def scattering1d(U_0, backend, psi1, psi2, phi, oversampling, max_order, average=True):
+def scattering1d(U_0, backend, filters, oversampling, average=True):
     """
     Main function implementing the 1-D scattering transform.
 
@@ -39,30 +39,25 @@ def scattering1d(U_0, backend, psi1, psi2, phi, oversampling, max_order, average
     average : boolean, optional
         whether to average the result. Default to True.
     """
-    cdgmm = backend.cdgmm
-    ifft = backend.ifft
-    irfft = backend.irfft
-    modulus = backend.modulus
-    rfft = backend.rfft
-    subsample_fourier = backend.subsample_fourier
-    unpad = backend.unpad
 
     # compute the Fourier transform
-    U_0_hat = rfft(U_0)
+    U_0_hat = backend.rfft(U_0)
 
     # Get S0
+    phi = filters[0]
     log2_T = phi['j']
     k0 = max(log2_T - oversampling, 0)
 
     if average:
-        S_0_c = cdgmm(U_0_hat, phi['levels'][0])
-        S_0_hat = subsample_fourier(S_0_c, 2**k0)
-        S_0_r = irfft(S_0_hat)
+        S_0_c = backend.cdgmm(U_0_hat, phi['levels'][0])
+        S_0_hat = backend.subsample_fourier(S_0_c, 2**k0)
+        S_0_r = backend.irfft(S_0_hat)
         yield {'coef': S_0_r, 'j': (), 'n': ()}
     else:
         yield {'coef': U_0, 'j': (), 'n': ()}
 
     # First order:
+    psi1 = filters[1]
     for n1 in range(len(psi1)):
         # Convolution + downsampling
         j1 = psi1[n1]['j']
@@ -70,28 +65,29 @@ def scattering1d(U_0, backend, psi1, psi2, phi, oversampling, max_order, average
         sub1_adj = min(j1, log2_T) if average else j1
         k1 = max(sub1_adj - oversampling, 0)
 
-        U_1_c = cdgmm(U_0_hat, psi1[n1]['levels'][0])
-        U_1_hat = subsample_fourier(U_1_c, 2**k1)
-        U_1_c = ifft(U_1_hat)
+        U_1_c = backend.cdgmm(U_0_hat, psi1[n1]['levels'][0])
+        U_1_hat = backend.subsample_fourier(U_1_c, 2**k1)
+        U_1_c = backend.ifft(U_1_hat)
 
         # Take the modulus
-        U_1_m = modulus(U_1_c)
+        U_1_m = backend.modulus(U_1_c)
 
-        if average or max_order > 1:
-            U_1_hat = rfft(U_1_m)
+        if average or len(filters) > 2:
+            U_1_hat = backend.rfft(U_1_m)
 
         if average:
             # Convolve with phi_J
             k1_J = max(log2_T - k1 - oversampling, 0)
-            S_1_c = cdgmm(U_1_hat, phi['levels'][k1])
-            S_1_hat = subsample_fourier(S_1_c, 2**k1_J)
-            S_1_r = irfft(S_1_hat)
+            S_1_c = backend.cdgmm(U_1_hat, phi['levels'][k1])
+            S_1_hat = backend.subsample_fourier(S_1_c, 2**k1_J)
+            S_1_r = backend.irfft(S_1_hat)
             yield {'coef': S_1_r, 'j': (j1,), 'n': (n1,)}
         else:
             yield {'coef': U_1_m, 'j': (j1,), 'n': (n1,)}
 
-        if max_order == 2:
+        if len(filters) > 2:
             # 2nd order
+            psi2 = filters[2]
             for n2 in range(len(psi2)):
                 j2 = psi2[n2]['j']
 
@@ -100,22 +96,22 @@ def scattering1d(U_0, backend, psi1, psi2, phi, oversampling, max_order, average
                     sub2_adj = min(j2, log2_T) if average else j2
                     k2 = max(sub2_adj - k1 - oversampling, 0)
 
-                    U_2_c = cdgmm(U_1_hat, psi2[n2]['levels'][k1])
-                    U_2_hat = subsample_fourier(U_2_c, 2**k2)
+                    U_2_c = backend.cdgmm(U_1_hat, psi2[n2]['levels'][k1])
+                    U_2_hat = backend.subsample_fourier(U_2_c, 2**k2)
                     # take the modulus
-                    U_2_c = ifft(U_2_hat)
+                    U_2_c = backend.ifft(U_2_hat)
 
-                    U_2_m = modulus(U_2_c)
+                    U_2_m = backend.modulus(U_2_c)
 
                     if average:
-                        U_2_hat = rfft(U_2_m)
+                        U_2_hat = backend.rfft(U_2_m)
 
                         # Convolve with phi_J
                         k2_log2_T = max(log2_T - k2 - k1 - oversampling, 0)
 
-                        S_2_c = cdgmm(U_2_hat, phi['levels'][k1 + k2])
-                        S_2_hat = subsample_fourier(S_2_c, 2**k2_log2_T)
-                        S_2_r = irfft(S_2_hat)
+                        S_2_c = backend.cdgmm(U_2_hat, phi['levels'][k1 + k2])
+                        S_2_hat = backend.subsample_fourier(S_2_c, 2**k2_log2_T)
+                        S_2_r = backend.irfft(S_2_hat)
 
                         yield {'coef': S_2_r, 'j': (j1, j2), 'n': (n1, n2)}
                     else:
diff --git a/kymatio/scattering1d/frontend/base_frontend.py b/kymatio/scattering1d/frontend/base_frontend.py
--- a/kymatio/scattering1d/frontend/base_frontend.py
+++ b/kymatio/scattering1d/frontend/base_frontend.py
@@ -135,8 +135,9 @@ def scattering(self, x):
 
         U_0 = self.backend.pad(x, pad_left=self.pad_left, pad_right=self.pad_right)
 
-        S_gen = scattering1d(U_0, self.backend, self.psi1_f, self.psi2_f, self.phi_f,
-            self.oversampling, self.max_order, average=self.average)
+        filters = [self.phi_f, self.psi1_f, self.psi2_f][:(1+self.max_order)]
+        S_gen = scattering1d(U_0, self.backend, filters,
+            self.oversampling, average=self.average)
 
         if self.out_type in ['array', 'list']:
             S = list()
@@ -204,8 +205,8 @@ def meta(self):
         class DryBackend:
             __getattr__ = lambda self, attr: (lambda *args: None)
 
-        S = scattering1d(None, DryBackend(), self.psi1_f, self.psi2_f,
-            self.phi_f, self.oversampling, self.max_order)
+        filters = [self.phi_f, self.psi1_f, self.psi2_f][:(1+self.max_order)]
+        S = scattering1d(None, DryBackend(), filters, self.oversampling)
         S = sorted(list(S), key=lambda path: (len(path['n']), path['n']))
         meta = dict(order=np.array([len(path['n']) for path in S]))
         meta['key'] = [path['n'] for path in S]


Test patch: