Skip to content

BUG: special: test_kolmogorov fails on 32-bit platforms #9509

@rgommers

Description

@rgommers

Test was marked as xfail in gh-9494. It should be investigated why it fails though, looks like a real bug.

First observed on MacPython/scipy-wheels#37.

/venv/lib/python3.7/site-packages/scipy/special/tests/test_kolmogorov.py:243: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Data for _smirnovp>
data = array([[ 3.        ,  0.33333333, -1.66666667],
       [ 4.        ,  0.25      , -2.125     ],
       [ 5.        ,  ...5882353, -3.71393676],
       [18.        ,  0.05555556, -3.750371  ],
       [19.        ,  0.05263158, -3.78331196]])
dtype = dtype('float64')
dtypes = [<class 'int'>, <class 'float'>, <class 'float'>]

    def check(self, data=None, dtype=None, dtypes=None):
        """Check the special function against the data."""
    
        if self.knownfailure:
            pytest.xfail(reason=self.knownfailure)
    
        if data is None:
            data = self.data
    
        if dtype is None:
            dtype = data.dtype
        else:
            data = data.astype(dtype)
    
        rtol, atol = self.get_tolerances(dtype)
    
        # Apply given filter functions
        if self.param_filter:
            param_mask = np.ones((data.shape[0],), np.bool_)
            for j, filter in zip(self.param_columns, self.param_filter):
                if filter:
                    param_mask &= list(filter(data[:,j]))
            data = data[param_mask]
    
        # Pick parameters from the correct columns
        params = []
        for idx, j in enumerate(self.param_columns):
            if np.iscomplexobj(j):
                j = int(j.imag)
                params.append(data[:,j].astype(complex))
            elif dtypes and idx < len(dtypes):
                params.append(data[:, j].astype(dtypes[idx]))
            else:
                params.append(data[:,j])
    
        # Helper for evaluating results
        def eval_func_at_params(func, skip_mask=None):
            if self.vectorized:
                got = func(*params)
            else:
                got = []
                for j in range(len(params[0])):
                    if skip_mask is not None and skip_mask[j]:
                        got.append(np.nan)
                        continue
                    got.append(func(*tuple([params[i][j] for i in range(len(params))])))
                got = np.asarray(got)
            if not isinstance(got, tuple):
                got = (got,)
            return got
    
        # Evaluate function to be tested
        got = eval_func_at_params(self.func)
    
        # Grab the correct results
        if self.result_columns is not None:
            # Correct results passed in with the data
            wanted = tuple([data[:,icol] for icol in self.result_columns])
        else:
            # Function producing correct results passed in
            skip_mask = None
            if self.nan_ok and len(got) == 1:
                # Don't spend time evaluating what doesn't need to be evaluated
                skip_mask = np.isnan(got[0])
            wanted = eval_func_at_params(self.result_func, skip_mask=skip_mask)
    
        # Check the validity of each output returned
        assert_(len(got) == len(wanted))
    
        for output_num, (x, y) in enumerate(zip(got, wanted)):
            if np.issubdtype(x.dtype, np.complexfloating) or self.ignore_inf_sign:
                pinf_x = np.isinf(x)
                pinf_y = np.isinf(y)
                minf_x = np.isinf(x)
                minf_y = np.isinf(y)
            else:
                pinf_x = np.isposinf(x)
                pinf_y = np.isposinf(y)
                minf_x = np.isneginf(x)
                minf_y = np.isneginf(y)
            nan_x = np.isnan(x)
            nan_y = np.isnan(y)
    
            olderr = np.seterr(all='ignore')
            try:
                abs_y = np.absolute(y)
                abs_y[~np.isfinite(abs_y)] = 0
                diff = np.absolute(x - y)
                diff[~np.isfinite(diff)] = 0
    
                rdiff = diff / np.absolute(y)
                rdiff[~np.isfinite(rdiff)] = 0
            finally:
                np.seterr(**olderr)
    
            tol_mask = (diff <= atol + rtol*abs_y)
            pinf_mask = (pinf_x == pinf_y)
            minf_mask = (minf_x == minf_y)
    
            nan_mask = (nan_x == nan_y)
    
            bad_j = ~(tol_mask & pinf_mask & minf_mask & nan_mask)
    
            point_count = bad_j.size
            if self.nan_ok:
                bad_j &= ~nan_x
                bad_j &= ~nan_y
                point_count -= (nan_x | nan_y).sum()
    
            if not self.distinguish_nan_and_inf and not self.nan_ok:
                # If nan's are okay we've already covered all these cases
                inf_x = np.isinf(x)
                inf_y = np.isinf(y)
                both_nonfinite = (inf_x & nan_y) | (nan_x & inf_y)
                bad_j &= ~both_nonfinite
                point_count -= both_nonfinite.sum()
    
            if np.any(bad_j):
                # Some bad results: inform what, where, and how bad
                msg = [""]
                msg.append("Max |adiff|: %g" % diff.max())
                msg.append("Max |rdiff|: %g" % rdiff.max())
                msg.append("Bad results (%d out of %d) for the following points (in output %d):"
                           % (np.sum(bad_j), point_count, output_num,))
                for j in np.nonzero(bad_j)[0]:
                    j = int(j)
                    fmt = lambda x: "%30s" % np.array2string(x[j], precision=18)
                    a = "  ".join(map(fmt, params))
                    b = "  ".join(map(fmt, got))
                    c = "  ".join(map(fmt, wanted))
                    d = fmt(rdiff)
                    msg.append("%s => %s != %s  (rdiff %s)" % (a, b, c, d))
>               assert_(False, "\n".join(msg))
E               AssertionError: 
E               Max |adiff|: 0.0121951
E               Max |rdiff|: 0.00370991
E               Bad results (9 out of 17) for the following points (in output 0):
E                                           10             0.10000000000000045 =>             -3.299372741951227 !=            -3.2871776200000262  (rdiff           0.003709906601031427)
E                                           11             0.09090909090909136 =>            -3.3821190947447826 !=            -3.3765011172167076  (rdiff           0.001663845896401149)
E                                           12             0.08333333333333377 =>             -3.442344918605228 !=             -3.452983216477585  (rdiff           0.003080900544662628)
E                                           13             0.07692307692307737 =>            -3.5286334525977225 !=              -3.51919949033359  (rdiff           0.002680712556945199)
E                                           14             0.07142857142857187 =>             -3.567990913442175 !=            -3.5770818225331054  (rdiff           0.002541431687042837)
E                                           15             0.06666666666666711 =>             -3.626015070796918 !=            -3.6281071210061473  (rdiff           0.000576623054241369)
E                                           17             0.05882352941176515 =>            -3.7120917372777273 !=             -3.713936755727941  (rdiff           0.000496782409492605)
E                                           18               0.055555555555556 =>             -3.743328749446484 !=            -3.7503710029676434  (rdiff           0.001877748498905016)
E                                           19             0.05263157894736886 =>             -3.776645292919359 !=            -3.7833119595860536  (rdiff           0.001762124492484152)

a          = '                            19             0.05263157894736886'
abs_y      = array([1.66666667, 2.125     , 2.456     , 2.70524691, 2.89932766,
       3.05457306, 3.18150316, 3.28717762, 3.37650112, 3.45298322,
       3.51919949, 3.57708182, 3.62810712, 3.6734235 , 3.71393676,
       3.750371  , 3.78331196])
atol       = 1.1125369292536007e-307
b          = '            -3.776645292919359'
bad_j      = array([False, False, False, False, False, False, False,  True,  True,
        True,  True,  True,  True, False,  True,  True,  True])
c          = '           -3.7833119595860536'
d          = '          0.001762124492484152'
data       = array([[ 3.        ,  0.33333333, -1.66666667],
       [ 4.        ,  0.25      , -2.125     ],
       [ 5.        ,  ...5882353, -3.71393676],
       [18.        ,  0.05555556, -3.750371  ],
       [19.        ,  0.05263158, -3.78331196]])
diff       = array([3.55271368e-15, 5.32907052e-15, 6.66133815e-15, 9.76996262e-15,
       1.02140518e-14, 1.24344979e-14, 1.554312...226e-03, 9.09090909e-03,
       2.09205021e-03, 2.70894418e-14, 1.84501845e-03, 7.04225352e-03,
       6.66666667e-03])
dtype      = dtype('float64')
dtypes     = [<class 'int'>, <class 'float'>, <class 'float'>]
eval_func_at_params = <function FuncData.check.<locals>.eval_func_at_params at 0xea13e7c4>
filter     = None
fmt        = <function FuncData.check.<locals>.<lambda> at 0xea13e6a4>
got        = (array([-1.66666667, -2.125     , -2.456     , -2.70524691, -2.89932766,
       -3.05457306, -3.18150316, -3.29937274,...3.44234492,
       -3.52863345, -3.56799091, -3.62601507, -3.6734235 , -3.71209174,
       -3.74332875, -3.77664529]),)
idx        = 1
j          = 16
minf_mask  = array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True])
minf_x     = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
minf_y     = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
msg        = ['', 'Max |adiff|: 0.0121951', 'Max |rdiff|: 0.00370991', 'Bad results (9 out of 17) for the following points (in outp...9136 =>            -3.3821190947447826 !=            -3.3765011172167076  (rdiff           0.001663845896401149)', ...]
nan_mask   = array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True])
nan_x      = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
nan_y      = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
olderr     = {'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'}
output_num = 0
param_mask = array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True])
params     = [array([ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), array([0.33333333, 0.25      , 0.2      ...090909, 0.08333333,
       0.07692308, 0.07142857, 0.06666667, 0.0625    , 0.05882353,
       0.05555556, 0.05263158])]
pinf_mask  = array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True])
pinf_x     = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
pinf_y     = array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False])
point_count = 17
rdiff      = array([2.13162821e-15, 2.50779789e-15, 2.71227123e-15, 3.61148647e-15,
       3.52290359e-15, 4.07078097e-15, 4.885465...256e-03, 2.54143169e-03,
       5.76623054e-04, 7.37444017e-15, 4.96782409e-04, 1.87774850e-03,
       1.76212449e-03])
rtol       = 1e-10
self       = <Data for _smirnovp>
tol_mask   = array([ True,  True,  True,  True,  True,  True,  True, False, False,
       False, False, False, False,  True, False, False, False])
wanted     = (array([-1.66666667, -2.125     , -2.456     , -2.70524691, -2.89932766,
       -3.05457306, -3.18150316, -3.28717762,...3.45298322,
       -3.51919949, -3.57708182, -3.62810712, -3.6734235 , -3.71393676,
       -3.750371  , -3.78331196]),)
x          = array([-1.66666667, -2.125     , -2.456     , -2.70524691, -2.89932766,
       -3.05457306, -3.18150316, -3.29937274, ... -3.44234492,
       -3.52863345, -3.56799091, -3.62601507, -3.6734235 , -3.71209174,
       -3.74332875, -3.77664529])
y          = array([-1.66666667, -2.125     , -2.456     , -2.70524691, -2.89932766,
       -3.05457306, -3.18150316, -3.28717762, ... -3.45298322,
       -3.51919949, -3.57708182, -3.62810712, -3.6734235 , -3.71393676,
       -3.750371  , -3.78331196])

/venv/lib/python3.7/site-packages/scipy/special/_testutils.py:307: AssertionError
``

Metadata

Metadata

Assignees

No one assigned

    Labels

    defectA clear bug or issue that prevents SciPy from being installed or used as expectedscipy.special

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions