test_norm.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. """Test functions for the sparse.linalg.norm module
  2. """
  3. import pytest
  4. import numpy as np
  5. from numpy.linalg import norm as npnorm
  6. from numpy.testing import assert_allclose, assert_equal
  7. from pytest import raises as assert_raises
  8. import scipy.sparse
  9. from scipy.sparse.linalg import norm as spnorm
  10. # https://github.com/scipy/scipy/issues/16031
  11. def test_sparray_norm():
  12. row = np.array([0, 0, 1, 1])
  13. col = np.array([0, 1, 2, 3])
  14. data = np.array([4, 5, 7, 9])
  15. test_arr = scipy.sparse.coo_array((data, (row, col)), shape=(2, 4))
  16. test_mat = scipy.sparse.coo_matrix((data, (row, col)), shape=(2, 4))
  17. assert_equal(spnorm(test_arr, ord=1, axis=0), np.array([4, 5, 7, 9]))
  18. assert_equal(spnorm(test_mat, ord=1, axis=0), np.array([4, 5, 7, 9]))
  19. assert_equal(spnorm(test_arr, ord=1, axis=1), np.array([9, 16]))
  20. assert_equal(spnorm(test_mat, ord=1, axis=1), np.array([9, 16]))
  21. class TestNorm:
  22. def setup_method(self):
  23. a = np.arange(9) - 4
  24. b = a.reshape((3, 3))
  25. self.b = scipy.sparse.csr_matrix(b)
  26. def test_matrix_norm(self):
  27. # Frobenius norm is the default
  28. assert_allclose(spnorm(self.b), 7.745966692414834)
  29. assert_allclose(spnorm(self.b, 'fro'), 7.745966692414834)
  30. assert_allclose(spnorm(self.b, np.inf), 9)
  31. assert_allclose(spnorm(self.b, -np.inf), 2)
  32. assert_allclose(spnorm(self.b, 1), 7)
  33. assert_allclose(spnorm(self.b, -1), 6)
  34. # Only floating or complex floating dtype supported by svds.
  35. with pytest.warns(UserWarning, match="The problem size"):
  36. assert_allclose(spnorm(self.b.astype(np.float64), 2),
  37. 7.348469228349534)
  38. # _multi_svd_norm is not implemented for sparse matrix
  39. assert_raises(NotImplementedError, spnorm, self.b, -2)
  40. def test_matrix_norm_axis(self):
  41. for m, axis in ((self.b, None), (self.b, (0, 1)), (self.b.T, (1, 0))):
  42. assert_allclose(spnorm(m, axis=axis), 7.745966692414834)
  43. assert_allclose(spnorm(m, 'fro', axis=axis), 7.745966692414834)
  44. assert_allclose(spnorm(m, np.inf, axis=axis), 9)
  45. assert_allclose(spnorm(m, -np.inf, axis=axis), 2)
  46. assert_allclose(spnorm(m, 1, axis=axis), 7)
  47. assert_allclose(spnorm(m, -1, axis=axis), 6)
  48. def test_vector_norm(self):
  49. v = [4.5825756949558398, 4.2426406871192848, 4.5825756949558398]
  50. for m, a in (self.b, 0), (self.b.T, 1):
  51. for axis in a, (a, ), a-2, (a-2, ):
  52. assert_allclose(spnorm(m, 1, axis=axis), [7, 6, 7])
  53. assert_allclose(spnorm(m, np.inf, axis=axis), [4, 3, 4])
  54. assert_allclose(spnorm(m, axis=axis), v)
  55. assert_allclose(spnorm(m, ord=2, axis=axis), v)
  56. assert_allclose(spnorm(m, ord=None, axis=axis), v)
  57. def test_norm_exceptions(self):
  58. m = self.b
  59. assert_raises(TypeError, spnorm, m, None, 1.5)
  60. assert_raises(TypeError, spnorm, m, None, [2])
  61. assert_raises(ValueError, spnorm, m, None, ())
  62. assert_raises(ValueError, spnorm, m, None, (0, 1, 2))
  63. assert_raises(ValueError, spnorm, m, None, (0, 0))
  64. assert_raises(ValueError, spnorm, m, None, (0, 2))
  65. assert_raises(ValueError, spnorm, m, None, (-3, 0))
  66. assert_raises(ValueError, spnorm, m, None, 2)
  67. assert_raises(ValueError, spnorm, m, None, -3)
  68. assert_raises(ValueError, spnorm, m, 'plate_of_shrimp', 0)
  69. assert_raises(ValueError, spnorm, m, 'plate_of_shrimp', (0, 1))
  70. class TestVsNumpyNorm:
  71. _sparse_types = (
  72. scipy.sparse.bsr_matrix,
  73. scipy.sparse.coo_matrix,
  74. scipy.sparse.csc_matrix,
  75. scipy.sparse.csr_matrix,
  76. scipy.sparse.dia_matrix,
  77. scipy.sparse.dok_matrix,
  78. scipy.sparse.lil_matrix,
  79. )
  80. _test_matrices = (
  81. (np.arange(9) - 4).reshape((3, 3)),
  82. [
  83. [1, 2, 3],
  84. [-1, 1, 4]],
  85. [
  86. [1, 0, 3],
  87. [-1, 1, 4j]],
  88. )
  89. def test_sparse_matrix_norms(self):
  90. for sparse_type in self._sparse_types:
  91. for M in self._test_matrices:
  92. S = sparse_type(M)
  93. assert_allclose(spnorm(S), npnorm(M))
  94. assert_allclose(spnorm(S, 'fro'), npnorm(M, 'fro'))
  95. assert_allclose(spnorm(S, np.inf), npnorm(M, np.inf))
  96. assert_allclose(spnorm(S, -np.inf), npnorm(M, -np.inf))
  97. assert_allclose(spnorm(S, 1), npnorm(M, 1))
  98. assert_allclose(spnorm(S, -1), npnorm(M, -1))
  99. def test_sparse_matrix_norms_with_axis(self):
  100. for sparse_type in self._sparse_types:
  101. for M in self._test_matrices:
  102. S = sparse_type(M)
  103. for axis in None, (0, 1), (1, 0):
  104. assert_allclose(spnorm(S, axis=axis), npnorm(M, axis=axis))
  105. for ord in 'fro', np.inf, -np.inf, 1, -1:
  106. assert_allclose(spnorm(S, ord, axis=axis),
  107. npnorm(M, ord, axis=axis))
  108. # Some numpy matrix norms are allergic to negative axes.
  109. for axis in (-2, -1), (-1, -2), (1, -2):
  110. assert_allclose(spnorm(S, axis=axis), npnorm(M, axis=axis))
  111. assert_allclose(spnorm(S, 'f', axis=axis),
  112. npnorm(M, 'f', axis=axis))
  113. assert_allclose(spnorm(S, 'fro', axis=axis),
  114. npnorm(M, 'fro', axis=axis))
  115. def test_sparse_vector_norms(self):
  116. for sparse_type in self._sparse_types:
  117. for M in self._test_matrices:
  118. S = sparse_type(M)
  119. for axis in (0, 1, -1, -2, (0, ), (1, ), (-1, ), (-2, )):
  120. assert_allclose(spnorm(S, axis=axis), npnorm(M, axis=axis))
  121. for ord in None, 2, np.inf, -np.inf, 1, 0.5, 0.42:
  122. assert_allclose(spnorm(S, ord, axis=axis),
  123. npnorm(M, ord, axis=axis))