Thanks to visit codestin.com
Credit goes to github.com

Skip to content

empirical_covariance silently returns invalid results on inputs with a complex dtype #25519

Description

@qbarthelemy

Describe the bug

Considering complex inputs $X$, like in radar image processing, we want to estimate the covariance matrix.

When assume_centered=True, empirical_covariance returns the pseudo-covariance matrix : $X^T X / n$ . See code.

When assume_centered=False, empirical_covariance returns np.cov(X.T, bias=1) here, which computes the actual covariance matrix for complex inputs, using the Hermitian dot product : $X^H X / n$ . See code.

This inconsistency can be easily tested using an already centered complex array $X$:
empirical_covariance(X, assume_centered=False) is not equal to empirical_covariance(X, assume_centered=True).

Steps/Code to Reproduce

import numpy as np
from numpy.testing import assert_array_almost_equal
from sklearn.covariance import empirical_covariance


n_samples, n_features = 100, 2
rs = np.random.RandomState(2023)
X = rs.randn(n_samples, n_features) + 1.0j * rs.randn(n_samples, n_features)
X -= np.mean(X, axis=0, keepdims=True)

C1 = empirical_covariance(X, assume_centered=True)
C2 = empirical_covariance(X, assume_centered=False)
assert_array_almost_equal(C1, C2)

Expected Results

No error is thrown.

Actual Results

Traceback (most recent call last):
  File "dev_covariance_emc_bug.py", line 16, in <module>
    assert_array_equal(C1, C2)
  File "...\Anaconda3\envs\env_ml\lib\site-packages\numpy\testing\_private\utils.py", line 934, in assert_array_equal
    assert_array_compare(operator.__eq__, x, y, err_msg=err_msg,
  File "...\Anaconda3\envs\env_ml\lib\site-packages\numpy\testing\_private\utils.py", line 844, in assert_array_compare
    raise AssertionError(msg)

AssertionError:
Arrays are not equal

Mismatched elements: 4 / 4 (100%)
Max absolute difference: 2.19497247
Max relative difference: 2.23809636
 x: array([[0.074856+0.226382j, 0.226072+0.032869j],
       [0.226072+0.032869j, 0.116201+0.326903j]])
 y: array([[ 2.258123+0.j     , -0.03445 +0.13383j],
       [-0.03445 -0.13383j,  2.038931+0.j     ]])

Versions

System:
    python: 3.8.16 (default, Jan 17 2023, 22:25:28) [MSC v.1916 64 bit (AMD64)]
executable: ...\Anaconda3\envs\env_ml\python.exe
   machine: Windows-10-10.0.17763-SP0

Python dependencies:
      sklearn: 1.2.0
          pip: 22.3.1
   setuptools: 65.6.3
        numpy: 1.23.5
        scipy: 1.9.3
       Cython: None
       pandas: None
   matplotlib: None
       joblib: 1.2.0
threadpoolctl: 3.1.0

Built with OpenMP: True

threadpoolctl info:
       user_api: openmp
   internal_api: openmp
         prefix: vcomp
       filepath: ...\Anaconda3\envs\env_ml\Lib\site-packages\sklearn\.libs\vcomp140.dll
        version: None
    num_threads: 12

       user_api: blas
   internal_api: mkl
         prefix: mkl_rt
       filepath: ...\Anaconda3\envs\env_ml\Library\bin\mkl_rt.1.dll
        version: 2021.4-Product
threading_layer: intel
    num_threads: 6

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions