from sympy.tensor.array.array_comprehension import ArrayComprehension, ArrayComprehensionMap from sympy.tensor.array import ImmutableDenseNDimArray from sympy.abc import i, j, k, l from sympy.testing.pytest import raises, warns from sympy.utilities.exceptions import SymPyDeprecationWarning from sympy.matrices import Matrix def test_array_comprehension(): a = ArrayComprehension(i*j, (i, 1, 3), (j, 2, 4)) b = ArrayComprehension(i, (i, 1, j+1)) c = ArrayComprehension(i+j+k+l, (i, 1, 2), (j, 1, 3), (k, 1, 4), (l, 1, 5)) d = ArrayComprehension(k, (i, 1, 5)) e = ArrayComprehension(i, (j, k+1, k+5)) assert a.doit().tolist() == [[2, 3, 4], [4, 6, 8], [6, 9, 12]] assert a.shape == (3, 3) assert a.is_shape_numeric == True assert a.tolist() == [[2, 3, 4], [4, 6, 8], [6, 9, 12]] assert a.tomatrix() == Matrix([ [2, 3, 4], [4, 6, 8], [6, 9, 12]]) assert len(a) == 9 assert isinstance(b.doit(), ArrayComprehension) assert isinstance(a.doit(), ImmutableDenseNDimArray) assert b.subs(j, 3) == ArrayComprehension(i, (i, 1, 4)) assert b.free_symbols == {j} assert b.shape == (j + 1,) assert b.rank() == 1 assert b.is_shape_numeric == False assert c.free_symbols == set() assert c.function == i + j + k + l assert c.limits == ((i, 1, 2), (j, 1, 3), (k, 1, 4), (l, 1, 5)) assert c.doit().tolist() == [[[[4, 5, 6, 7, 8], [5, 6, 7, 8, 9], [6, 7, 8, 9, 10], [7, 8, 9, 10, 11]], [[5, 6, 7, 8, 9], [6, 7, 8, 9, 10], [7, 8, 9, 10, 11], [8, 9, 10, 11, 12]], [[6, 7, 8, 9, 10], [7, 8, 9, 10, 11], [8, 9, 10, 11, 12], [9, 10, 11, 12, 13]]], [[[5, 6, 7, 8, 9], [6, 7, 8, 9, 10], [7, 8, 9, 10, 11], [8, 9, 10, 11, 12]], [[6, 7, 8, 9, 10], [7, 8, 9, 10, 11], [8, 9, 10, 11, 12], [9, 10, 11, 12, 13]], [[7, 8, 9, 10, 11], [8, 9, 10, 11, 12], [9, 10, 11, 12, 13], [10, 11, 12, 13, 14]]]] assert c.free_symbols == set() assert c.variables == [i, j, k, l] assert c.bound_symbols == [i, j, k, l] assert d.doit().tolist() == [k, k, k, k, k] assert len(e) == 5 raises(TypeError, lambda: ArrayComprehension(i*j, (i, 1, 3), (j, 2, [1, 3, 2]))) raises(ValueError, lambda: ArrayComprehension(i*j, (i, 1, 3), (j, 2, 1))) raises(ValueError, lambda: ArrayComprehension(i*j, (i, 1, 3), (j, 2, j+1))) raises(ValueError, lambda: len(ArrayComprehension(i*j, (i, 1, 3), (j, 2, j+4)))) raises(TypeError, lambda: ArrayComprehension(i*j, (i, 0, i + 1.5), (j, 0, 2))) raises(ValueError, lambda: b.tolist()) raises(ValueError, lambda: b.tomatrix()) raises(ValueError, lambda: c.tomatrix()) def test_arraycomprehensionmap(): a = ArrayComprehensionMap(lambda i: i+1, (i, 1, 5)) assert a.doit().tolist() == [2, 3, 4, 5, 6] assert a.shape == (5,) assert a.is_shape_numeric assert a.tolist() == [2, 3, 4, 5, 6] assert len(a) == 5 assert isinstance(a.doit(), ImmutableDenseNDimArray) expr = ArrayComprehensionMap(lambda i: i+1, (i, 1, k)) assert expr.doit() == expr assert expr.subs(k, 4) == ArrayComprehensionMap(lambda i: i+1, (i, 1, 4)) assert expr.subs(k, 4).doit() == ImmutableDenseNDimArray([2, 3, 4, 5]) b = ArrayComprehensionMap(lambda i: i+1, (i, 1, 2), (i, 1, 3), (i, 1, 4), (i, 1, 5)) assert b.doit().tolist() == [[[[2, 3, 4, 5, 6], [3, 5, 7, 9, 11], [4, 7, 10, 13, 16], [5, 9, 13, 17, 21]], [[3, 5, 7, 9, 11], [5, 9, 13, 17, 21], [7, 13, 19, 25, 31], [9, 17, 25, 33, 41]], [[4, 7, 10, 13, 16], [7, 13, 19, 25, 31], [10, 19, 28, 37, 46], [13, 25, 37, 49, 61]]], [[[3, 5, 7, 9, 11], [5, 9, 13, 17, 21], [7, 13, 19, 25, 31], [9, 17, 25, 33, 41]], [[5, 9, 13, 17, 21], [9, 17, 25, 33, 41], [13, 25, 37, 49, 61], [17, 33, 49, 65, 81]], [[7, 13, 19, 25, 31], [13, 25, 37, 49, 61], [19, 37, 55, 73, 91], [25, 49, 73, 97, 121]]]] # tests about lambda expression assert ArrayComprehensionMap(lambda: 3, (i, 1, 5)).doit().tolist() == [3, 3, 3, 3, 3] assert ArrayComprehensionMap(lambda i: i+1, (i, 1, 5)).doit().tolist() == [2, 3, 4, 5, 6] raises(ValueError, lambda: ArrayComprehensionMap(i*j, (i, 1, 3), (j, 2, 4))) # The use of a function here triggers a deprecation warning from sympify() with warns(SymPyDeprecationWarning, test_stacklevel=False): a = ArrayComprehensionMap(lambda i, j: i+j, (i, 1, 5)) raises(ValueError, lambda: a.doit())