nebius/SWE-bench-extra huggingface dataset:
Repository: kvesteri/intervals

Issue:
length should return the actual length for discrete intervals
``IntInterval.from_string('[0, 2)').length`` should be `1` not `2`

Comments:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index ab8d128..41c7cdc 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,12 @@ Changelog
 Here you can see the full list of changes between each intervals release.
 
 
+0.9.1 (2020-12-31)
+^^^^^^^^^^^^^^^^^^
+
+- Fixed discrete interval length (#53)
+
+
 0.9.0 (2020-07-16)
 ^^^^^^^^^^^^^^^^^^
 
diff --git a/intervals/__init__.py b/intervals/__init__.py
index 1636366..32d7508 100644
--- a/intervals/__init__.py
+++ b/intervals/__init__.py
@@ -32,4 +32,4 @@ __all__ = (
 )
 
 
-__version__ = '0.9.0'
+__version__ = '0.9.1'
diff --git a/intervals/interval.py b/intervals/interval.py
index 81bb4b9..9d27a28 100644
--- a/intervals/interval.py
+++ b/intervals/interval.py
@@ -456,6 +456,11 @@ class AbstractInterval(object):
 
     @property
     def length(self):
+        if self.discrete:
+            if not self:
+                return 0
+            if not self.lower_inc or not self.upper_inc:
+                return canonicalize(self, lower_inc=True, upper_inc=True).length
         return abs(self.upper - self.lower)
 
     @property


Test patch:
diff --git a/tests/interval/test_properties.py b/tests/interval/test_properties.py
index d70a8e8..083c9a4 100644
--- a/tests/interval/test_properties.py
+++ b/tests/interval/test_properties.py
@@ -15,16 +15,20 @@ from intervals import (
 
 class TestIntervalProperties(object):
     @mark.parametrize(
-        ('number_range', 'length'),
+        ('interval', 'length'),
         (
-            ([1, 4], 3),
-            ([-1, 1], 2),
-            ((-inf, inf), inf),
-            ((1, inf), inf),
+            (IntInterval([1, 4]), 3),
+            (IntInterval([-1, 1]), 2),
+            (IntInterval([-inf, inf]), inf),
+            (IntInterval([1, inf]), inf),
+            (IntInterval.from_string('(0, 3)'), 1),
+            (IntInterval.from_string('[0, 3)'), 2),
+            (IntInterval.from_string('(0, 2)'), 0),
+            (IntInterval.from_string('(0, 1)'), 0)
         )
     )
-    def test_length(self, number_range, length):
-        assert IntInterval(number_range).length == length
+    def test_length(self, interval, length):
+        assert interval.length == length
 
     @mark.parametrize(
         ('number_range', 'radius'),
Repository: kymatio/kymatio

Issue:
BUG missing one second-order wavelet for low-T Sc1D and JTFS
MWE 

```python
import numpy as np
from kymatio.numpy import Scattering1D

N = 1024
x = np.zeros(N)
S = Scattering1D(J=8, shape=(N,), T=2)
Sx = S(x)
```

Traceback:

```
IndexError                                Traceback (most recent call last)
Cell In [5], line 7
      4 kwargs = dict(J=8, shape=(N,))
      6 S = Scattering1D(**kwargs, T=2)
----> 7 S(x)

File ~/kymatio/kymatio/frontend/numpy_frontend.py:10, in ScatteringNumPy.__call__(self, x)
      7 def __call__(self, x):
      8     """This method is an alias for `scattering`."""
---> 10     return self.scattering(x)

File ~/kymatio/kymatio/scattering1d/frontend/base_frontend.py:116, in ScatteringBase1D.scattering(self, x)
    113 elif self.out_type == 'dict':
    114     S = dict()
--> 116 for path in S_gen:
    117     path['order'] = len(path['n'])
    118     if self.average == 'local':

File ~/kymatio/kymatio/scattering1d/core/scattering1d.py:97, in scattering1d(U_0, backend, filters, oversampling, average_local)
     94 sub2_adj = min(j2, log2_T) if average_local else j2
     95 k2 = max(sub2_adj - k1 - oversampling, 0)
---> 97 U_2_c = backend.cdgmm(U_1_hat, psi2[n2]['levels'][k1])
     98 U_2_hat = backend.subsample_fourier(U_2_c, 2**k2)
     99 # take the modulus

IndexError: list index out of range
```

Comments:

Patch:
diff --git a/kymatio/scattering1d/filter_bank.py b/kymatio/scattering1d/filter_bank.py
index 63e7dd5..b1d69ea 100644
--- a/kymatio/scattering1d/filter_bank.py
+++ b/kymatio/scattering1d/filter_bank.py
@@ -377,8 +377,8 @@ def scattering_filter_factory(N, J, Q, T, filterbank):
             j = get_max_dyadic_subsampling(xi, sigma, **filterbank_kwargs)
 
             # Resample to smaller resolutions if necessary (beyond 1st layer)
-            # The idiom min(previous_J, j, log2_T) implements "j1 < j2"
-            for level in range(1, min(previous_J, j, log2_T)):
+            # The idiom min(previous_J, j, 1+log2_T) implements "j1 < j2"
+            for level in range(1, min(previous_J, j, 1+log2_T)):
                 psi_level = psi_levels[0].reshape(2 ** level, -1).mean(axis=0)
                 psi_levels.append(psi_level)
             psi_f.append({'levels': psi_levels, 'xi': xi, 'sigma': sigma, 'j': j})


Test patch:
diff --git a/tests/scattering1d/test_numpy_scattering1d.py b/tests/scattering1d/test_numpy_scattering1d.py
index 8c84f7f..9908bff 100644
--- a/tests/scattering1d/test_numpy_scattering1d.py
+++ b/tests/scattering1d/test_numpy_scattering1d.py
@@ -114,6 +114,16 @@ class TestScattering1DNumpy:
         Sx = sc(x)
         assert Sx.shape[-1] == 1
 
+    def test_981(self, backend):
+        """
+        Tests against bug #981, in which some low values of T triggered an
+        `IndexError` in second-order backend.cdgmm
+        """
+        N = 1024
+        x = np.zeros(N)
+        sc = Scattering1D(J=8, shape=(N,), T=2)
+        Sx = sc(x)
+        assert Sx.shape[-1] == N/sc.T
 
 
 frontends = ['numpy', 'sklearn']