(self)
| 1768 | assert_raises(ValueError, np.divide.reduce, a, axis=(0, 1)) |
| 1769 | |
| 1770 | def test_reduce_zero_axis(self): |
| 1771 | # If we have a n x m array and do a reduction with axis=1, then we are |
| 1772 | # doing n reductions, and each reduction takes an m-element array. For |
| 1773 | # a reduction operation without an identity, then: |
| 1774 | # n > 0, m > 0: fine |
| 1775 | # n = 0, m > 0: fine, doing 0 reductions of m-element arrays |
| 1776 | # n > 0, m = 0: can't reduce a 0-element array, ValueError |
| 1777 | # n = 0, m = 0: can't reduce a 0-element array, ValueError (for |
| 1778 | # consistency with the above case) |
| 1779 | # This test doesn't actually look at return values, it just checks to |
| 1780 | # make sure that error we get an error in exactly those cases where we |
| 1781 | # expect one, and assumes the calculations themselves are done |
| 1782 | # correctly. |
| 1783 | |
| 1784 | def ok(f, *args, **kwargs): |
| 1785 | f(*args, **kwargs) |
| 1786 | |
| 1787 | def err(f, *args, **kwargs): |
| 1788 | assert_raises(ValueError, f, *args, **kwargs) |
| 1789 | |
| 1790 | def t(expect, func, n, m): |
| 1791 | expect(func, np.zeros((n, m)), axis=1) |
| 1792 | expect(func, np.zeros((m, n)), axis=0) |
| 1793 | expect(func, np.zeros((n // 2, n // 2, m)), axis=2) |
| 1794 | expect(func, np.zeros((n // 2, m, n // 2)), axis=1) |
| 1795 | expect(func, np.zeros((n, m // 2, m // 2)), axis=(1, 2)) |
| 1796 | expect(func, np.zeros((m // 2, n, m // 2)), axis=(0, 2)) |
| 1797 | expect(func, np.zeros((m // 3, m // 3, m // 3, |
| 1798 | n // 2, n // 2)), |
| 1799 | axis=(0, 1, 2)) |
| 1800 | # Check what happens if the inner (resp. outer) dimensions are a |
| 1801 | # mix of zero and non-zero: |
| 1802 | expect(func, np.zeros((10, m, n)), axis=(0, 1)) |
| 1803 | expect(func, np.zeros((10, n, m)), axis=(0, 2)) |
| 1804 | expect(func, np.zeros((m, 10, n)), axis=0) |
| 1805 | expect(func, np.zeros((10, m, n)), axis=1) |
| 1806 | expect(func, np.zeros((10, n, m)), axis=2) |
| 1807 | |
| 1808 | # np.maximum is just an arbitrary ufunc with no reduction identity |
| 1809 | assert_equal(np.maximum.identity, None) |
| 1810 | t(ok, np.maximum.reduce, 30, 30) |
| 1811 | t(ok, np.maximum.reduce, 0, 30) |
| 1812 | t(err, np.maximum.reduce, 30, 0) |
| 1813 | t(err, np.maximum.reduce, 0, 0) |
| 1814 | err(np.maximum.reduce, []) |
| 1815 | np.maximum.reduce(np.zeros((0, 0)), axis=()) |
| 1816 | |
| 1817 | # all of the combinations are fine for a reduction that has an |
| 1818 | # identity |
| 1819 | t(ok, np.add.reduce, 30, 30) |
| 1820 | t(ok, np.add.reduce, 0, 30) |
| 1821 | t(ok, np.add.reduce, 30, 0) |
| 1822 | t(ok, np.add.reduce, 0, 0) |
| 1823 | np.add.reduce([]) |
| 1824 | np.add.reduce(np.zeros((0, 0)), axis=()) |
| 1825 | |
| 1826 | # OTOH, accumulate always makes sense for any combination of n and m, |
| 1827 | # because it maps an m-element array to an m-element array. These |
nothing calls this directly
no test coverage detected