You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

array_ops.py 34 kB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ============================================================================
  15. """array operations, the function docs are adapted from Numpy API."""
  16. from copy import copy as py_copy
  17. import numpy as onp
  18. import mindspore
  19. from mindspore import Tensor
  20. from mindspore.ops import operations as P
  21. from mindspore.ops import functional as F
  22. from mindspore.ops.primitive import constexpr
  23. from .utils import _check_shape, _check_shape_compile, _check_dtype, _check_is_int, \
  24. _check_axes_range, _check_start_normalize, _check_shape_contain_zero, _check_is_tensor, \
  25. _check_input_for_asarray
  26. DEFAULT_FLOAT_DTYPE = mindspore.float32
  27. DEFAULT_INT_DTYPE = mindspore.int32
  28. def array(obj, dtype=None, copy=True, ndmin=0):
  29. """
  30. Create a tensor.
  31. This function creat tensors from an array-like object.
  32. Args:
  33. obj (Union[int, float, bool, list, tuple, numpy.ndarray]): Input data, in
  34. any form that can be converted to an array. This includes lists, lists of
  35. tuples, tuples, tuples of tuples, tuples of lists and ndarrays.
  36. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  37. be in format of np.int32, or `int32`. If dtype is None, the data type
  38. of the new tensor will be inferred from obj. Default is None.
  39. copy (bool): If true, then the object is copied. Otherwise, a copy will
  40. only be made if necessary. Default: True.
  41. ndmin (int): Specifies the minimum number of dimensions that the resulting
  42. array should have. Ones will be pre-pended to the shape as needed to
  43. meet this requirement. Default: 0
  44. Returns:
  45. Tensor, generated tensor with the specified dtype.
  46. Supported Platforms:
  47. ``Ascend`` ``GPU`` ``CPU``
  48. Examples:
  49. >>> import mindspore.numpy as np
  50. >>> print(np.array([1,2,3]))
  51. [1 2 3]
  52. """
  53. if ndmin > 0:
  54. # Fall back to original numpy creation.
  55. if isinstance(obj, Tensor):
  56. obj = obj.asnumpy()
  57. return asarray(onp.array(obj, dtype, copy=copy, ndmin=ndmin))
  58. if not copy:
  59. return asarray(obj, dtype=dtype)
  60. obj = py_copy(obj)
  61. return asarray(obj, dtype=dtype)
  62. def asarray(a, dtype=None):
  63. """
  64. Convert the input to tensor.
  65. This function convert tensors from an array-like object.
  66. Args:
  67. a (Union[int, float, bool, list, tuple, numpy.ndarray]): Input data, in
  68. any form that can be converted to an array. This includes lists, lists of
  69. tuples, tuples, tuples of tuples, tuples of lists and ndarrays.
  70. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  71. be in format of np.int32, or `int32`. If dtype is None, the data type
  72. of the new tensor will be inferred from a. Default is None.
  73. Returns:
  74. Tensor, generated tensor with the specified dtype.
  75. Supported Platforms:
  76. ``Ascend`` ``GPU`` ``CPU``
  77. Examples:
  78. >>> import mindspore.numpy as np
  79. >>> print(np.asarray([1,2,3]))
  80. [1 2 3]
  81. """
  82. if dtype is not None:
  83. dtype = _check_dtype(dtype)
  84. _ = _check_input_for_asarray(a)
  85. if isinstance(a, float) and (dtype is None):
  86. dtype = DEFAULT_FLOAT_DTYPE
  87. if isinstance(a, int) and not isinstance(a, bool) and (dtype is None):
  88. dtype = DEFAULT_INT_DTYPE
  89. if isinstance(a, bool) and (dtype is None):
  90. dtype = mindspore.bool_
  91. if isinstance(a, (list, tuple)):
  92. a = onp.asarray(a)
  93. # If dtype is not specified, we keep consistent with numpy decision
  94. # only exceptions are: we use int/float32
  95. if dtype is None:
  96. if a.dtype is onp.dtype('int64'):
  97. dtype = DEFAULT_INT_DTYPE
  98. elif a.dtype is onp.dtype('float64'):
  99. dtype = DEFAULT_FLOAT_DTYPE
  100. if isinstance(a, onp.ndarray) and dtype is None:
  101. if a.dtype is onp.dtype('bool'):
  102. dtype = mindspore.bool_
  103. elif a.dtype is onp.dtype('int'):
  104. dtype = DEFAULT_INT_DTYPE
  105. elif a.dtype is onp.dtype('float'):
  106. dtype = DEFAULT_FLOAT_DTYPE
  107. a = Tensor.from_numpy(a)
  108. # If a is already an tensor and we don't need to cast dtype, return a
  109. if isinstance(a, Tensor):
  110. if dtype is None:
  111. return a
  112. dtype = _check_dtype(dtype)
  113. if dtype == a.dtype:
  114. return a
  115. return Tensor(a, dtype=dtype)
  116. def asfarray(a, dtype=DEFAULT_FLOAT_DTYPE):
  117. """
  118. Similar to asarray, convert the input to an float array.
  119. If non-float dtype is defined, this function will return a float32 Tensor instead.
  120. Args:
  121. a (Union[int, float, bool, list, tuple, numpy.ndarray]): Input data, in
  122. any form that can be converted to an array. This includes lists, lists of
  123. tuples, tuples, tuples of tuples, tuples of lists and ndarrays.
  124. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  125. be in format of np.float32, or `float32`. Default is mindspore.float32.
  126. Returns:
  127. Tensor, generated tensor with the specified float dtype.
  128. Supported Platforms:
  129. ``Ascend`` ``GPU`` ``CPU``
  130. Examples:
  131. >>> import mindspore.numpy as np
  132. >>> print(np.asfarray([1,2,3]))
  133. [1. 2. 3.]
  134. """
  135. dtype = _check_dtype(dtype)
  136. _ = _check_input_for_asarray(a)
  137. if dtype not in (mindspore.float16, mindspore.float32, mindspore.float64):
  138. dtype = DEFAULT_FLOAT_DTYPE
  139. if isinstance(a, (list, tuple)):
  140. a = onp.asarray(a)
  141. if isinstance(a, onp.ndarray):
  142. a = Tensor.from_numpy(a)
  143. return Tensor(a, dtype)
  144. def copy_(a):
  145. """
  146. Return an tensor copy of the given object.
  147. Args:
  148. a (Tensor): Input tensor.
  149. Returns:
  150. Tensor, has the same data as `a`.
  151. Supported Platforms:
  152. ``Ascend`` ``GPU`` ``CPU``
  153. Examples:
  154. >>> import mindspore.numpy as np
  155. >>> print(np.copy([1,2,3]))
  156. [1. 2. 3.]
  157. """
  158. return py_copy(a)
  159. def ones(shape, dtype=DEFAULT_FLOAT_DTYPE):
  160. """
  161. Return a new array of given shape and type, filled with ones.
  162. Args:
  163. shape (Union[int, tuple, list]): the shape of the new array.
  164. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  165. be in format of np.float32, or `float32`. Default is mindspore.float32.
  166. Returns:
  167. Tensor, with the designated shape and dtype, filled with ones.
  168. Supported Platforms:
  169. ``Ascend`` ``GPU`` ``CPU``
  170. Examples:
  171. >>> import mindspore.numpy as np
  172. >>> print(np.ones((2,2)))
  173. [[1. 1.]
  174. [1. 1.]]
  175. """
  176. if _check_shape_contain_zero(shape):
  177. return asarray(onp.ones(shape), dtype=dtype)
  178. shape = _check_shape(shape)
  179. dtype = _check_dtype(dtype)
  180. fill = P.Fill()
  181. output = fill(dtype, shape, 1)
  182. return Tensor(output, dtype=dtype)
  183. def zeros(shape, dtype=DEFAULT_FLOAT_DTYPE):
  184. """
  185. Return a new array of given shape and type, filled with zeros.
  186. Args:
  187. shape (Union[int, tuple, list]): the shape of the new array.
  188. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  189. be in format of np.float32, or `float32`. Default is mindspore.float32.
  190. Returns:
  191. Tensor, with the designated shape and dtype, filled with zeros.
  192. Supported Platforms:
  193. ``Ascend`` ``GPU`` ``CPU``
  194. Examples:
  195. >>> import mindspore.numpy as np
  196. >>> print(np.zeros((2,2)))
  197. [[0. 0.]
  198. [0. 0.]]
  199. """
  200. if _check_shape_contain_zero(shape):
  201. return asarray(onp.zeros(shape), dtype=dtype)
  202. shape = _check_shape(shape)
  203. dtype = _check_dtype(dtype)
  204. fill = P.Fill()
  205. output = fill(dtype, shape, 0)
  206. return Tensor(output, dtype=dtype)
  207. def full(shape, fill_value, dtype=None):
  208. """
  209. Return a new array of given shape and type, filled with fill_value.
  210. Args:
  211. shape (Union[int, tuple(int), list(int)]): Shape of the new array, e.g.,
  212. (2, 3) or 2.
  213. fill_value (Union[int, float, bool, list, tuple]): scalar or array_like
  214. fill value.
  215. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  216. be in format of np.float32, or `float32`, if dtype is None, the data type
  217. of the new tensor will be inferred from fill_value. Default is None.
  218. Supported Platforms:
  219. ``Ascend`` ``GPU`` ``CPU``
  220. Returns:
  221. Tensor, with the designated shape and dtype, filled with `fill_value`.
  222. Examples:
  223. >>> import mindspore.numpy as np
  224. >>> print(np.full((2,2), True))
  225. [[True True]
  226. [True True]]
  227. """
  228. if dtype is None:
  229. dtype = array(fill_value).dtype
  230. shape = _check_shape(shape)
  231. _ = _check_input_for_asarray(fill_value)
  232. dtype = _check_dtype(dtype)
  233. if isinstance(fill_value, (int, float, bool)) and not _check_shape_contain_zero(shape):
  234. return P.Fill()(dtype, shape, fill_value)
  235. # if fill_value is array_like or shape contains zero. fall back to original
  236. # numpy creation
  237. return Tensor(onp.full(shape, fill_value, mindspore.dtype_to_nptype(dtype)))
  238. def arange(*args, **kwargs):
  239. """
  240. Return evenly spaced values within a given interval.
  241. Returns `num` evenly spaced samples, calculated over the interval [`start`, `stop`].
  242. The endpoint of the interval can optionally be excluded.
  243. The current implementation is a direct wrapper on top of numpy.arange, except
  244. the default dtype is float32 and int32, compare to float64 and int64 for numpy
  245. implementation.
  246. Args:
  247. start(Union[int, float], optional): Start of interval. The interval includes
  248. this value. Default is 0.
  249. stop(Union[int, float], optional): End of interval. The interval does not
  250. include this value, except in some cases where step is not an integer
  251. and floating point round-off affects the length of out.
  252. step(Union[int, float], optional): Spacing between values. For any output
  253. out, this is the distance between two adjacent values, out[i+1] - out[i].
  254. The default step size is 1. If step is specified as a position argument,
  255. start must also be given.
  256. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  257. be in format of np.float32, or `float32`. If dtype is None, the data type
  258. of the new tensor will be inferred from start, stop and step. Default is None.
  259. Returns:
  260. arangend Tensor, array of evenly spaced values.
  261. Supported Platforms:
  262. ``Ascend`` ``GPU`` ``CPU``
  263. Examples:
  264. >>> import mindspore.numpy as np
  265. >>> print(np.arange(0, 5, 1))
  266. [0 1 2 3 4]
  267. """
  268. # infer the dtype, if either of start, end, step is float, default dtype is
  269. # float32, else int32.
  270. int_flag = True
  271. final_dtype = None
  272. if args:
  273. for item in args:
  274. if isinstance(item, float):
  275. int_flag = False
  276. if kwargs:
  277. if ('start' in kwargs and isinstance(kwargs['start'], float)) or \
  278. ('stop' in kwargs and isinstance(kwargs['stop'], float)) or \
  279. ('step' in kwargs and isinstance(kwargs['step'], float)):
  280. int_flag = False
  281. if int_flag:
  282. final_dtype = onp.int32
  283. else:
  284. final_dtype = onp.float32
  285. if 'dtype' in kwargs and kwargs['dtype'] is not None:
  286. final_dtype = _check_dtype(kwargs['dtype'])
  287. final_dtype = mindspore.dtype_to_nptype(final_dtype)
  288. kwargs['dtype'] = final_dtype
  289. out = onp.arange(*args, **kwargs)
  290. out = Tensor.from_numpy(out)
  291. return Tensor(out)
  292. def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0):
  293. """
  294. Return evenly spaced values within a given interval.
  295. The current implementation is a direct wrapper on top of numpy.linspace, except
  296. the default dtype is float32, compare to float64 for numpy,
  297. Args:
  298. start (Union[int, list(int), tuple(int),tensor]):The starting value of the sequence.
  299. stop (Union[int, list(int), tuple(int),tensor]):The end value of the sequence,
  300. unless `endpoint` is set to False. In that case, the sequence consists
  301. of all but the last of ``num + 1` evenly spaced samples, so that `stop`
  302. is excluded. Note that the step size changes when `endpoint` is False.
  303. num (int, optional): Number of samples to generate. Default is 50.
  304. endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is
  305. not included. Default is True.
  306. retstep (bool, optional): If True, return (`samples`, `step`), where `step` is
  307. the spacing between samples.
  308. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  309. be in format of np.float32, or `float32`.If `dtype` is None, infer the data
  310. type from other input arguments. Default is None.
  311. axis (int, optional): The axis in the result to store the samples. Relevant
  312. only if start or stop are array-like. By default (0), the samples will
  313. be along a new axis inserted at the beginning. Use -1 to get an axis at the end.
  314. Default is 0.
  315. Returns:
  316. samples (Tensor): There are `num` equally spaced samples in the closed interval
  317. ``[start, stop]`` or the half-open interval ``[start, stop)``
  318. (depending on whether `endpoint` is True or False).
  319. step (float, optional): Only returned if `retstep` is True.
  320. Size of spacing between samples.
  321. Supported Platforms:
  322. ``Ascend`` ``GPU`` ``CPU``
  323. Examples:
  324. >>> import mindspore.numpy as np
  325. >>> print(np.linspace(0, 5, 6))
  326. [0. 1. 2. 3. 4. 5.]
  327. """
  328. if isinstance(start, Tensor):
  329. start = start.asnumpy()
  330. if isinstance(stop, Tensor):
  331. stop = stop.asnumpy()
  332. final_dtype = None
  333. if dtype is not None:
  334. final_dtype = _check_dtype(dtype)
  335. final_dtype = mindspore.dtype_to_nptype(final_dtype)
  336. else:
  337. final_dtype = onp.float32
  338. dtype = final_dtype
  339. out = onp.linspace(start, stop, num, endpoint, retstep, dtype, axis)
  340. if retstep:
  341. array_out, step_out = out[0], out[1]
  342. tensor_out = Tensor.from_numpy(array_out)
  343. return tensor_out, step_out
  344. tensor_out = Tensor.from_numpy(out)
  345. return tensor_out
  346. def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0):
  347. """
  348. Return numbers spaced evenly on a log scale.
  349. In linear space, the sequence starts at base ** start (base to the power of
  350. start) and ends with base ** stop (see endpoint below).
  351. The current implementation is a direct wrapper on top of numpy.logspace, except
  352. the default dtype is float32, compare to float64 for numpy,
  353. Args:
  354. start (Union[int, list(int), tuple(int), tensor]):The starting value of the sequence.
  355. stop (Union[int, list(int), tuple(int), tensor]):The end value of the sequence,
  356. unless `endpoint` is set to False. In that case, the sequence consists
  357. of all but the last of ``num + 1` evenly spaced samples, so that `stop`
  358. is excluded. Note that the step size changes when `endpoint` is False.
  359. num (int, optional): Number of samples to generate. Default is 50.
  360. endpoint (bool, optional): If True, `stop` is the last sample. Otherwise, it is
  361. not included. Default is True.
  362. base (Union[int, float], optional): The base of the log space. The step size
  363. between the elements in ln(samples) / ln(base) (or log_base(samples))
  364. is uniform. Default is 10.0.
  365. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  366. be in format of np.float32, or `float32`.If `dtype` is None, infer the data
  367. type from other input arguments. Default is None.
  368. axis (int, optional): The axis in the result to store the samples. Relevant
  369. only if start or stop are array-like. By default (0), the samples will
  370. be along a new axis inserted at the beginning. Use -1 to get an axis at the end.
  371. Default is 0.
  372. Returns:
  373. samples (Tensor): num samples, equally spaced on a log scale.
  374. Supported Platforms:
  375. ``Ascend`` ``GPU`` ``CPU``
  376. Examples:
  377. >>> import mindspore.numpy as np
  378. >>> print(np.logspace(0, 5, 6, base=2.0))
  379. [ 1. 2. 4. 8. 16. 32.]
  380. """
  381. if isinstance(start, Tensor):
  382. start = start.asnumpy()
  383. if isinstance(stop, Tensor):
  384. stop = stop.asnumpy()
  385. final_dtype = None
  386. if dtype is not None:
  387. final_dtype = _check_dtype(dtype)
  388. final_dtype = mindspore.dtype_to_nptype(final_dtype)
  389. else:
  390. final_dtype = onp.float32
  391. dtype = final_dtype
  392. out = onp.logspace(start, stop, num, endpoint, base, dtype, axis)
  393. tensor_out = Tensor.from_numpy(out)
  394. return tensor_out
  395. def eye(N, M=None, k=0, dtype=DEFAULT_FLOAT_DTYPE):
  396. """
  397. Return a 2-D array with ones on the diagnoal and zeros elsewhere.
  398. Args:
  399. N (int): Number of rows in the output, must be larger than 0.
  400. M (int, optional): Number of columns in the output. If None, defaults to N,
  401. if defined, must be larger than 0. Deault is None.
  402. k (int, optional): Index of the diagonal: 0 (the default) refers to the main
  403. diagonal, a positive value refers to an upper diagonal, and a negative value
  404. to a lower diagonal. Default is 0.
  405. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  406. be in format of np.float32, or `float32`. Default is mindspore.float32.
  407. Returns:
  408. result (Tensor): A tensor array of shape (N,M). An array where all elements
  409. are equal to zero, except for the k-th diagonal, whose values are equal to one.
  410. Supported Platforms:
  411. ``Ascend`` ``GPU`` ``CPU``
  412. Examples:
  413. >>> import mindspore.numpy as np
  414. >>> print(np.eye(2, 2))
  415. [[1. 0.]
  416. [0. 1.]]
  417. """
  418. dtype = _check_dtype(dtype)
  419. make_eye = P.Eye()
  420. if M is None:
  421. M = N
  422. M = int(M)
  423. N = int(N)
  424. k = int(k)
  425. out = None
  426. if k != 0 or N == 0 or M == 0:
  427. # Fall back to original numpy creation method
  428. out = onp.eye(N, M, k)
  429. else:
  430. out = make_eye(N, M, dtype)
  431. return asarray(out, dtype=dtype)
  432. def identity(n, dtype=DEFAULT_FLOAT_DTYPE):
  433. """
  434. Return the identity array.
  435. Args:
  436. n (int): Number of rows and columns in the output, must be larger than 0.
  437. dtype (Union[mindspore.dtype, str], optional): Designated array dtype, can
  438. be in format of np.float32, or `float32`. Default is mindspore.float32.
  439. Returns:
  440. result (Tensor): A tensor array of shape (n,n). An array where all elements
  441. are equal to zero, except for the diagonal, whose values are equal to one.
  442. Supported Platforms:
  443. ``Ascend`` ``GPU`` ``CPU``
  444. Examples:
  445. >>> import mindspore.numpy as np
  446. >>> print(np.identity(2))
  447. [[1. 0.]
  448. [0. 1.]]
  449. """
  450. dtype = _check_dtype(dtype)
  451. return eye(n, dtype=dtype)
  452. @constexpr
  453. def _prepare_shape_for_expand_dims(shape, axes):
  454. """
  455. Creat the expanded new shape based on the shape and given axes
  456. Args:
  457. shape (tuple): the shape of the tensor
  458. axes Union(int, tuple(int), list(int)): the axes with dimensions expanded.
  459. Returns:
  460. new_shape(tuple): the shape with dimensions expanded.
  461. """
  462. new_shape = []
  463. shape_idx = 0
  464. new_shape_length = len(shape)
  465. # Convert to set
  466. if isinstance(axes, int):
  467. new_shape_length += 1
  468. if axes >= new_shape_length or axes < -new_shape_length:
  469. raise ValueError(
  470. f"axis {axes} is out of bounds for array of dimension {new_shape_length}")
  471. axes = {axes}
  472. elif isinstance(axes, (list, tuple)):
  473. new_shape_length += len(axes)
  474. for axis in axes:
  475. if axis >= new_shape_length or axis < -new_shape_length:
  476. raise ValueError(
  477. f"axis {axis} is out of bounds for array of dimension {new_shape_length}")
  478. axes = set(axes)
  479. else:
  480. raise TypeError(
  481. f"only int, tuple and list are allowed for axes, but got {type(axes)}")
  482. for new_shape_idx in range(new_shape_length):
  483. if new_shape_idx in axes or new_shape_idx - new_shape_length in axes:
  484. new_shape.append(1)
  485. else:
  486. new_shape.append(shape[shape_idx])
  487. shape_idx += 1
  488. return tuple(new_shape)
  489. def expand_dims(a, axis):
  490. """
  491. Expand the shape of an array.
  492. Insert a new axis that will appear at the axis position in the expanded array shape.
  493. Args:
  494. a (Tensor): Input tensor array.
  495. axis Union[int, list(int), tuple(int)]: Position in the expanded axes where
  496. the new axis is placed,
  497. Returns:
  498. Tensor, view of a tensor with the number of dimensions increased.
  499. Supported Platforms:
  500. ``Ascend`` ``GPU`` ``CPU``
  501. Examples:
  502. >>> import mindspore.numpy as np
  503. >>> x = np.ones((2,2))
  504. >>> x = np.expand_dims(x,0)
  505. >>> print(x,shape)
  506. (2,2,1)
  507. """
  508. shape = F.shape(a)
  509. # yield expanded shape based on the axes
  510. new_shape = _prepare_shape_for_expand_dims(shape, axis)
  511. return P.Reshape()(a, new_shape)
  512. @constexpr
  513. def _prepare_shape_for_squeeze(shape, axes):
  514. """
  515. Creat the squeezed new shape based on the tensor and given axes.
  516. Args:
  517. shape (tuple): the shape of the tensor
  518. axes Union(None, int, tuple(int), list(int)): the axes with dimensions squeezed.
  519. Returns:
  520. new_shape(tuple): the shape with dimensions squeezed.
  521. """
  522. new_shape = []
  523. ndim = len(shape)
  524. # Convert to set
  525. if isinstance(axes, int):
  526. if axes >= ndim or axes < -ndim:
  527. raise ValueError(
  528. f"axis {axes} is out of bounds for array of dimension {ndim}")
  529. axes = {axes}
  530. elif isinstance(axes, (list, tuple)):
  531. for axis in axes:
  532. if axis >= ndim or axis < -ndim:
  533. raise ValueError(
  534. f"axis {axis} is out of bounds for array of dimension {ndim}")
  535. axes = set(axes)
  536. elif axes is not None:
  537. raise TypeError(
  538. f"only int, tuple and list are allowed for axes, but got {type(axes)}")
  539. if axes is None:
  540. new_shape = [s for s in shape if s != 1]
  541. else:
  542. for idx, s in enumerate(shape):
  543. if s != 1 or (idx not in axes) and (idx - ndim not in axes):
  544. new_shape.append(s)
  545. # if an axis is selected with shape entry greater than one, an error is raised.
  546. if s != 1 and ((idx in axes) or (idx - ndim in axes)):
  547. raise ValueError(
  548. f"axis {axes} has shape entry {s} > 1, cannot be squeezed.")
  549. return tuple(new_shape)
  550. def squeeze(a, axis=None):
  551. """
  552. Remove single-dimensional entries from the shape of an array.
  553. This is a temporary solution to support CPU backend. Will be changed
  554. once CPU backend supports P.Squeeze().
  555. Args:
  556. a (Tensor): Input tensor array.
  557. axis: Union[None, int, list(int), tuple(list)]. Default is None.
  558. Returns:
  559. Tensor, with all or a subset of the dimensions of length 1 removed.
  560. Supported Platforms:
  561. ``Ascend`` ``GPU`` ``CPU``
  562. Examples:
  563. >>> import mindspore.numpy as np
  564. >>> x = np.ones((1,2,2,1))
  565. >>> x = np.squeeze(x)
  566. >>> print(x,shape)
  567. (2,2)
  568. """
  569. shape = F.shape(a)
  570. # yield squeezed shape based on the axes
  571. new_shape = _prepare_shape_for_squeeze(shape, axis)
  572. return P.Reshape()(a, new_shape)
  573. def transpose(a, axes=None):
  574. """
  575. Reverse or permute the axes of an array; returns the modified array.
  576. Args:
  577. a (Tensor): a tensor to be transposed
  578. axes Union[None, tuple, list]: the axes order, if axes is None, transpose
  579. the entire tensor. Default is None.
  580. Returns:
  581. Tensor, the transposed tensor array.
  582. Supported Platforms:
  583. ``Ascend`` ``GPU`` ``CPU``
  584. Examples:
  585. >>> import mindspore.numpy as np
  586. >>> x = np.ones((1,2,3))
  587. >>> x = np.transpose(x)
  588. >>> print(x,shape)
  589. (3,2,1)
  590. """
  591. if axes is None:
  592. shape = F.shape(a)
  593. length = F.tuple_len(shape)
  594. perm = F.make_range(0, length)
  595. new_order = F.tuple_reversed(perm)
  596. return P.Transpose()(a, new_order)
  597. axes = _check_shape_compile(axes)
  598. return P.Transpose()(a, axes)
  599. def rollaxis(x, axis, start=0):
  600. """
  601. Roll the specified axis backwards, until it lies in the given position.
  602. The positions of the other axes do not change relative to one another.
  603. Args:
  604. x (Tensor): A Tensor to be transposed.
  605. axis (int): The axis to be rolled.
  606. start (int):
  607. - When start >= 0:
  608. - When start <= axis: the axis is rolled back until it lies in this position (start).
  609. - When start > axis: the axis is rolled until it lies before this position (start).
  610. - When start < 0: the start will be normalized as follows:
  611. start ........... Normalized start
  612. -(x.ndim+1) raise ValueError
  613. -x.ndim 0
  614. ... ...
  615. -1 x.ndim-1
  616. 0 0
  617. ... ...
  618. x.ndim x.ndim
  619. x.ndim+1 raise ValueError
  620. Returns:
  621. Transposed Tensor. Has the same data type as the original tensor x.
  622. Supported Platforms:
  623. ``Ascend`` ``GPU`` ``CPU``
  624. Raises:
  625. TypeError: If axis or start is not integer.
  626. ValueError: If axis is not in the range from -ndim to ndim-1 or
  627. start is not in the range from -ndim to ndim.
  628. Examples:
  629. >>> import mindspore
  630. >>> import mindspore.numpy as mnp
  631. >>> from mindspore import Tensor
  632. >>> import numpy as onp
  633. >>> input_x = Tensor(onp.ones((2,3,4)), mindspore.float32)
  634. >>> output = mnp.rollaxis(x, 0, 2)
  635. >>> print(output.shape)
  636. (3,2,4)
  637. """
  638. _check_is_int(axis)
  639. _check_is_int(start)
  640. shape = F.shape(x)
  641. ndim = F.tuple_len(shape)
  642. axis = _check_axes_range(axis, ndim)
  643. start = _check_start_normalize(start, ndim)
  644. if start - axis >= 0 and start - axis <= 1:
  645. return x
  646. perm = F.make_range(0, ndim)
  647. new_perm = None
  648. if start < axis:
  649. if axis + 1 < ndim:
  650. new_perm = perm[0:start] + perm[axis:axis+1] + \
  651. perm[start:axis] + perm[axis+1:]
  652. else:
  653. new_perm = perm[0:start] + perm[axis:axis+1] + perm[start:axis]
  654. if start > axis:
  655. if start < ndim:
  656. new_perm = perm[0:axis] + perm[axis+1:start] + \
  657. perm[axis:axis+1] + perm[start:]
  658. else:
  659. new_perm = perm[0:axis] + perm[axis+1:start] + \
  660. perm[axis:axis+1]
  661. return P.Transpose()(x, new_perm)
  662. def swapaxes(x, axis1, axis2):
  663. """
  664. Interchange two axes of a tensor.
  665. Args:
  666. x (Tensor): A Tensor to be transposed.
  667. axis1 (int): First axis.
  668. axis2 (int): Second axis.
  669. Returns:
  670. Transposed Tensor. Has the same data type as the original tensor x.
  671. Raises:
  672. TypeError: If axis1 or axis2 is not integer.
  673. ValueError: If axis1 or axis2 is not in the range from -ndim to ndim-1.
  674. Supported Platforms:
  675. ``Ascend`` ``GPU`` ``CPU``
  676. Examples:
  677. >>> import mindspore
  678. >>> import mindspore.numpy as mnp
  679. >>> from mindspore import Tensor
  680. >>> import numpy as onp
  681. >>> input_x = Tensor(onp.ones((2,3,4)), mindspore.float32)
  682. >>> output = mnp.swapaxes(x, 0, 2)
  683. >>> print(output.shape)
  684. (4,3,2)
  685. """
  686. _check_is_int(axis1)
  687. _check_is_int(axis2)
  688. shape = F.shape(x)
  689. ndim = F.tuple_len(shape)
  690. axes = _check_axes_range((axis1, axis2), ndim)
  691. axis1, axis2 = axes[0], axes[1]
  692. if axis1 == axis2:
  693. return x
  694. if axis1 > axis2:
  695. axis1, axis2 = axis2, axis1
  696. perm = F.make_range(0, ndim)
  697. new_perm = None
  698. if axis2 + 1 < ndim:
  699. new_perm = perm[0:axis1] + perm[axis2:axis2+1] + \
  700. perm[axis1+1:axis2] + perm[axis1:axis1+1] + perm[axis2+1:]
  701. else:
  702. new_perm = perm[0:axis1] + perm[axis2:axis2+1] + \
  703. perm[axis1+1:axis2] + perm[axis1:axis1+1]
  704. return P.Transpose()(x, new_perm)
  705. def reshape(x, new_shape):
  706. """
  707. Reshape a tensor without changing its data.
  708. Args:
  709. x (Tensor): A Tensor to be reshaped.
  710. new_shape (Union[int, list(int), tuple(int)]): The new shape should be
  711. compatible with the original shape. If the tuple has only one element,
  712. the result will be a 1-D tensor of that length. One shape dimension
  713. can be -1. In this case, the value is inferred from the length of
  714. the tensor and remaining dimensions.
  715. Returns:
  716. Reshaped Tensor. Has the same data type as the original tensor x.
  717. Raises:
  718. TypeError: If new_shape is not integer, list or tuple.
  719. ValueError: If new_shape does not compatible with the original shape.
  720. Supported Platforms:
  721. ``Ascend`` ``GPU`` ``CPU``
  722. Examples:
  723. >>> x = Tensor(np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]]), mindspore.float32)
  724. >>> reshape = mindspore.numpy.reshape()
  725. >>> output = reshape(x, (3, 2))
  726. >>> print(output)
  727. [[-0.1 0.3]
  728. [ 3.6 0.4]
  729. [ 0.5 -3.2]]
  730. >>> output = reshape(x, (3, -1))
  731. >>> print(output)
  732. [[-0.1 0.3]
  733. [ 3.6 0.4]
  734. [ 0.5 -3.2]]
  735. >>> output = reshape(x, (6, ))
  736. >>> print(output)
  737. [-0.1 0.3 3.6 0.4 0.5 -3.2]
  738. """
  739. new_shape = _check_shape_compile(new_shape)
  740. return P.Reshape()(x, new_shape)
  741. def ravel(x):
  742. """
  743. Return a contiguous flattened tensor.
  744. A 1-D tensor, containing the elements of the input, is returned.
  745. Args:
  746. x (Tensor): A tensor to be flattened.
  747. Returns:
  748. Flattened Tensor. Has the same data type as the original tensor x.
  749. Supported Platforms:
  750. ``Ascend`` ``GPU`` ``CPU``
  751. Examples:
  752. >>> import mindspore
  753. >>> import mindspore.numpy as mnp
  754. >>> from mindspore import Tensor
  755. >>> import numpy as onp
  756. >>> input_x = Tensor(onp.ones((2,3,4)), mindspore.float32)
  757. >>> output = mnp.ravel(x)
  758. >>> print(output.shape)
  759. (24,)
  760. """
  761. return reshape(x, (-1,))
  762. @constexpr
  763. def _move_axes_for_concatenate(arr_shape, axis):
  764. """
  765. move axis 0 to the disiganated position, while keep other axes' relative
  766. positions unchanged, only used if a single array is concatenated.
  767. """
  768. original_axes = tuple(range(len(arr_shape)))
  769. new_axes = original_axes[1:axis+1] + (0,) + original_axes[axis+1:]
  770. new_shape = arr_shape[1:axis+1] + (arr_shape[0] * arr_shape[axis+1],) + \
  771. arr_shape[axis+2:]
  772. return new_axes, new_shape
  773. def concatenate(arrays, axis=0):
  774. """
  775. Join a sequence of arrays along an existing axis.
  776. Args:
  777. arrays: Union[Tensor, tuple(Tensor), list(Tensor)], a Tensor or a list
  778. of Tensor to be concatenated.
  779. axis (int, optional): The axis along which the arrays will be joined,
  780. if axis is None, arrays are flattened before use. Default is 0.
  781. Returns:
  782. Tensor, a Tensor concatenated from a Tensor or a list of Tensors.
  783. Supported Platforms:
  784. ``Ascend`` ``GPU`` ``CPU``
  785. Examples:
  786. >>> import mindspore.numpy as np
  787. >>> x1 = np.ones((1,2,3))
  788. >>> x2 = np.ones((1,2,1))
  789. >>> x = np.concatenate((x1, x2), axis=-1)
  790. >>> print(x,shape)
  791. (1,2,4)
  792. """
  793. array_type = F.typeof(arrays)
  794. if _check_is_tensor(array_type):
  795. # if the input is a single tensor
  796. # if only one tensor is provided, it is treated as a tuple along the
  797. # first dimension. For example, a tensor of shape (3,4,5) will be treated
  798. # as: tuple(tensor_1(4,5), tensor_2(4,5), tensor_3(4,5))
  799. if axis is None:
  800. return ravel(arrays)
  801. arr_shape = F.shape(arrays)
  802. _check_axes_range((axis,), len(arr_shape))
  803. # move axis 0 to the disiganated position, while keep other axes' relative
  804. # positions unchanged
  805. new_axes, new_shape = _move_axes_for_concatenate(arr_shape, axis)
  806. arrays = transpose(arrays, new_axes)
  807. arrays = reshape(arrays, new_shape)
  808. return arrays
  809. flattened_arrays = ()
  810. if axis is None:
  811. for arr in arrays:
  812. flattened_arrays += (ravel(arr),)
  813. axis = -1
  814. return P.Concat(axis)(flattened_arrays)
  815. arr_shape = F.shape(arrays[0])
  816. _check_axes_range((axis,), len(arr_shape))
  817. # if only one tensor in the tuple/list, return the tensor itself
  818. if len(arrays) == 1:
  819. return arrays[0]
  820. return P.Concat(axis)(arrays)