Coverage for /usr/lib/python3/dist-packages/scipy/ndimage/_ni_support.py: 12%

68 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1# Copyright (C) 2003-2005 Peter J. Verveer 

2# 

3# Redistribution and use in source and binary forms, with or without 

4# modification, are permitted provided that the following conditions 

5# are met: 

6# 

7# 1. Redistributions of source code must retain the above copyright 

8# notice, this list of conditions and the following disclaimer. 

9# 

10# 2. Redistributions in binary form must reproduce the above 

11# copyright notice, this list of conditions and the following 

12# disclaimer in the documentation and/or other materials provided 

13# with the distribution. 

14# 

15# 3. The name of the author may not be used to endorse or promote 

16# products derived from this software without specific prior 

17# written permission. 

18# 

19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 

20# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 

21# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 

22# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 

23# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 

24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 

25# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 

26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 

27# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 

28# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 

29# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 

30 

31from collections.abc import Iterable 

32import operator 

33import warnings 

34import numpy 

35 

36 

37def _extend_mode_to_code(mode): 

38 """Convert an extension mode to the corresponding integer code. 

39 """ 

40 if mode == 'nearest': 

41 return 0 

42 elif mode == 'wrap': 

43 return 1 

44 elif mode in ['reflect', 'grid-mirror']: 

45 return 2 

46 elif mode == 'mirror': 

47 return 3 

48 elif mode == 'constant': 

49 return 4 

50 elif mode == 'grid-wrap': 

51 return 5 

52 elif mode == 'grid-constant': 

53 return 6 

54 else: 

55 raise RuntimeError('boundary mode not supported') 

56 

57 

58def _normalize_sequence(input, rank): 

59 """If input is a scalar, create a sequence of length equal to the 

60 rank by duplicating the input. If input is a sequence, 

61 check if its length is equal to the length of array. 

62 """ 

63 is_str = isinstance(input, str) 

64 if not is_str and isinstance(input, Iterable): 

65 normalized = list(input) 

66 if len(normalized) != rank: 

67 err = "sequence argument must have length equal to input rank" 

68 raise RuntimeError(err) 

69 else: 

70 normalized = [input] * rank 

71 return normalized 

72 

73 

74def _get_output(output, input, shape=None, complex_output=False): 

75 if shape is None: 

76 shape = input.shape 

77 if output is None: 

78 if not complex_output: 

79 output = numpy.zeros(shape, dtype=input.dtype.name) 

80 else: 

81 complex_type = numpy.promote_types(input.dtype, numpy.complex64) 

82 output = numpy.zeros(shape, dtype=complex_type) 

83 elif isinstance(output, (type, numpy.dtype)): 

84 # Classes (like `np.float32`) and dtypes are interpreted as dtype 

85 if complex_output and numpy.dtype(output).kind != 'c': 

86 warnings.warn("promoting specified output dtype to complex") 

87 output = numpy.promote_types(output, numpy.complex64) 

88 output = numpy.zeros(shape, dtype=output) 

89 elif isinstance(output, str): 

90 output = numpy.sctypeDict[output] 

91 if complex_output and numpy.dtype(output).kind != 'c': 

92 raise RuntimeError("output must have complex dtype") 

93 output = numpy.zeros(shape, dtype=output) 

94 elif output.shape != shape: 

95 raise RuntimeError("output shape not correct") 

96 elif complex_output and output.dtype.kind != 'c': 

97 raise RuntimeError("output must have complex dtype") 

98 return output 

99 

100 

101def _check_axes(axes, ndim): 

102 if axes is None: 

103 return tuple(range(ndim)) 

104 elif numpy.isscalar(axes): 

105 axes = (operator.index(axes),) 

106 elif isinstance(axes, Iterable): 

107 for ax in axes: 

108 axes = tuple(operator.index(ax) for ax in axes) 

109 if ax < -ndim or ax > ndim - 1: 

110 raise ValueError(f"specified axis: {ax} is out of range") 

111 axes = tuple(ax % ndim if ax < 0 else ax for ax in axes) 

112 else: 

113 message = "axes must be an integer, iterable of integers, or None" 

114 raise ValueError(message) 

115 if len(tuple(set(axes))) != len(axes): 

116 raise ValueError("axes must be unique") 

117 return axes