1"""
2Module of functions that are like ufuncs in acting on arrays and optionally
3storing results in an output array.
4
5"""
6__all__ = ['fix', 'isneginf', 'isposinf']
7
8import numpy.core.numeric as nx
9from numpy.core.overrides import (
10 array_function_dispatch, ARRAY_FUNCTION_ENABLED,
11)
12import warnings
13import functools
14
15
16def _deprecate_out_named_y(f):
17 """
18 Allow the out argument to be passed as the name `y` (deprecated)
19
20 In future, this decorator should be removed.
21 """
22 @functools.wraps(f)
23 def func(x, out=None, **kwargs):
24 if 'y' in kwargs:
25 if 'out' in kwargs:
26 raise TypeError(
27 "{} got multiple values for argument 'out'/'y'"
28 .format(f.__name__)
29 )
30 out = kwargs.pop('y')
31 # NumPy 1.13.0, 2017-04-26
32 warnings.warn(
33 "The name of the out argument to {} has changed from `y` to "
34 "`out`, to match other ufuncs.".format(f.__name__),
35 DeprecationWarning, stacklevel=3)
36 return f(x, out=out, **kwargs)
37
38 return func
39
40
41def _fix_out_named_y(f):
42 """
43 Allow the out argument to be passed as the name `y` (deprecated)
44
45 This decorator should only be used if _deprecate_out_named_y is used on
46 a corresponding dispatcher function.
47 """
48 @functools.wraps(f)
49 def func(x, out=None, **kwargs):
50 if 'y' in kwargs:
51 # we already did error checking in _deprecate_out_named_y
52 out = kwargs.pop('y')
53 return f(x, out=out, **kwargs)
54
55 return func
56
57
58def _fix_and_maybe_deprecate_out_named_y(f):
59 """
60 Use the appropriate decorator, depending upon if dispatching is being used.
61 """
62 if ARRAY_FUNCTION_ENABLED:
63 return _fix_out_named_y(f)
64 else:
65 return _deprecate_out_named_y(f)
66
67
68@_deprecate_out_named_y
69def _dispatcher(x, out=None):
70 return (x, out)
71
72
73@array_function_dispatch(_dispatcher, verify=False, module='numpy')
74@_fix_and_maybe_deprecate_out_named_y
75def fix(x, out=None):
76 """
77 Round to nearest integer towards zero.
78
79 Round an array of floats element-wise to nearest integer towards zero.
80 The rounded values are returned as floats.
81
82 Parameters
83 ----------
84 x : array_like
85 An array of floats to be rounded
86 out : ndarray, optional
87 A location into which the result is stored. If provided, it must have
88 a shape that the input broadcasts to. If not provided or None, a
89 freshly-allocated array is returned.
90
91 Returns
92 -------
93 out : ndarray of floats
94 A float array with the same dimensions as the input.
95 If second argument is not supplied then a float array is returned
96 with the rounded values.
97
98 If a second argument is supplied the result is stored there.
99 The return value `out` is then a reference to that array.
100
101 See Also
102 --------
103 rint, trunc, floor, ceil
104 around : Round to given number of decimals
105
106 Examples
107 --------
108 >>> np.fix(3.14)
109 3.0
110 >>> np.fix(3)
111 3.0
112 >>> np.fix([2.1, 2.9, -2.1, -2.9])
113 array([ 2., 2., -2., -2.])
114
115 """
116 # promote back to an array if flattened
117 res = nx.asanyarray(nx.ceil(x, out=out))
118 res = nx.floor(x, out=res, where=nx.greater_equal(x, 0))
119
120 # when no out argument is passed and no subclasses are involved, flatten
121 # scalars
122 if out is None and type(res) is nx.ndarray:
123 res = res[()]
124 return res
125
126
127@array_function_dispatch(_dispatcher, verify=False, module='numpy')
128@_fix_and_maybe_deprecate_out_named_y
129def isposinf(x, out=None):
130 """
131 Test element-wise for positive infinity, return result as bool array.
132
133 Parameters
134 ----------
135 x : array_like
136 The input array.
137 out : array_like, optional
138 A location into which the result is stored. If provided, it must have a
139 shape that the input broadcasts to. If not provided or None, a
140 freshly-allocated boolean array is returned.
141
142 Returns
143 -------
144 out : ndarray
145 A boolean array with the same dimensions as the input.
146 If second argument is not supplied then a boolean array is returned
147 with values True where the corresponding element of the input is
148 positive infinity and values False where the element of the input is
149 not positive infinity.
150
151 If a second argument is supplied the result is stored there. If the
152 type of that array is a numeric type the result is represented as zeros
153 and ones, if the type is boolean then as False and True.
154 The return value `out` is then a reference to that array.
155
156 See Also
157 --------
158 isinf, isneginf, isfinite, isnan
159
160 Notes
161 -----
162 NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
163 (IEEE 754).
164
165 Errors result if the second argument is also supplied when x is a scalar
166 input, if first and second arguments have different shapes, or if the
167 first argument has complex values
168
169 Examples
170 --------
171 >>> np.isposinf(np.PINF)
172 True
173 >>> np.isposinf(np.inf)
174 True
175 >>> np.isposinf(np.NINF)
176 False
177 >>> np.isposinf([-np.inf, 0., np.inf])
178 array([False, False, True])
179
180 >>> x = np.array([-np.inf, 0., np.inf])
181 >>> y = np.array([2, 2, 2])
182 >>> np.isposinf(x, y)
183 array([0, 0, 1])
184 >>> y
185 array([0, 0, 1])
186
187 """
188 is_inf = nx.isinf(x)
189 try:
190 signbit = ~nx.signbit(x)
191 except TypeError as e:
192 dtype = nx.asanyarray(x).dtype
193 raise TypeError(f'This operation is not supported for {dtype} values '
194 'because it would be ambiguous.') from e
195 else:
196 return nx.logical_and(is_inf, signbit, out)
197
198
199@array_function_dispatch(_dispatcher, verify=False, module='numpy')
200@_fix_and_maybe_deprecate_out_named_y
201def isneginf(x, out=None):
202 """
203 Test element-wise for negative infinity, return result as bool array.
204
205 Parameters
206 ----------
207 x : array_like
208 The input array.
209 out : array_like, optional
210 A location into which the result is stored. If provided, it must have a
211 shape that the input broadcasts to. If not provided or None, a
212 freshly-allocated boolean array is returned.
213
214 Returns
215 -------
216 out : ndarray
217 A boolean array with the same dimensions as the input.
218 If second argument is not supplied then a numpy boolean array is
219 returned with values True where the corresponding element of the
220 input is negative infinity and values False where the element of
221 the input is not negative infinity.
222
223 If a second argument is supplied the result is stored there. If the
224 type of that array is a numeric type the result is represented as
225 zeros and ones, if the type is boolean then as False and True. The
226 return value `out` is then a reference to that array.
227
228 See Also
229 --------
230 isinf, isposinf, isnan, isfinite
231
232 Notes
233 -----
234 NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
235 (IEEE 754).
236
237 Errors result if the second argument is also supplied when x is a scalar
238 input, if first and second arguments have different shapes, or if the
239 first argument has complex values.
240
241 Examples
242 --------
243 >>> np.isneginf(np.NINF)
244 True
245 >>> np.isneginf(np.inf)
246 False
247 >>> np.isneginf(np.PINF)
248 False
249 >>> np.isneginf([-np.inf, 0., np.inf])
250 array([ True, False, False])
251
252 >>> x = np.array([-np.inf, 0., np.inf])
253 >>> y = np.array([2, 2, 2])
254 >>> np.isneginf(x, y)
255 array([1, 0, 0])
256 >>> y
257 array([1, 0, 0])
258
259 """
260 is_inf = nx.isinf(x)
261 try:
262 signbit = nx.signbit(x)
263 except TypeError as e:
264 dtype = nx.asanyarray(x).dtype
265 raise TypeError(f'This operation is not supported for {dtype} values '
266 'because it would be ambiguous.') from e
267 else:
268 return nx.logical_and(is_inf, signbit, out)