I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

View File

@ -0,0 +1,78 @@
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
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)))
a = ArrayComprehensionMap(lambda i, j: i+j, (i, 1, 5))
raises(ValueError, lambda: a.doit())

View File

@ -0,0 +1,52 @@
from sympy.core.symbol import symbols
from sympy.matrices.dense import Matrix
from sympy.matrices.expressions.matexpr import MatrixSymbol
from sympy.tensor.array.ndim_array import NDimArray
from sympy.matrices.matrixbase import MatrixBase
from sympy.tensor.array.array_derivatives import ArrayDerivative
x, y, z, t = symbols("x y z t")
m = Matrix([[x, y], [z, t]])
M = MatrixSymbol("M", 3, 2)
N = MatrixSymbol("N", 4, 3)
def test_array_derivative_construction():
d = ArrayDerivative(x, m, evaluate=False)
assert d.shape == (2, 2)
expr = d.doit()
assert isinstance(expr, MatrixBase)
assert expr.shape == (2, 2)
d = ArrayDerivative(m, m, evaluate=False)
assert d.shape == (2, 2, 2, 2)
expr = d.doit()
assert isinstance(expr, NDimArray)
assert expr.shape == (2, 2, 2, 2)
d = ArrayDerivative(m, x, evaluate=False)
assert d.shape == (2, 2)
expr = d.doit()
assert isinstance(expr, MatrixBase)
assert expr.shape == (2, 2)
d = ArrayDerivative(M, N, evaluate=False)
assert d.shape == (4, 3, 3, 2)
expr = d.doit()
assert isinstance(expr, ArrayDerivative)
assert expr.shape == (4, 3, 3, 2)
d = ArrayDerivative(M, (N, 2), evaluate=False)
assert d.shape == (4, 3, 4, 3, 3, 2)
expr = d.doit()
assert isinstance(expr, ArrayDerivative)
assert expr.shape == (4, 3, 4, 3, 3, 2)
d = ArrayDerivative(M.as_explicit(), (N.as_explicit(), 2), evaluate=False)
assert d.doit().shape == (4, 3, 4, 3, 3, 2)
expr = d.doit()
assert isinstance(expr, NDimArray)
assert expr.shape == (4, 3, 4, 3, 3, 2)

View File

@ -0,0 +1,361 @@
import itertools
import random
from sympy.combinatorics import Permutation
from sympy.combinatorics.permutations import _af_invert
from sympy.testing.pytest import raises
from sympy.core.function import diff
from sympy.core.symbol import symbols
from sympy.functions.elementary.complexes import (adjoint, conjugate, transpose)
from sympy.functions.elementary.exponential import (exp, log)
from sympy.functions.elementary.trigonometric import (cos, sin)
from sympy.tensor.array import Array, ImmutableDenseNDimArray, ImmutableSparseNDimArray, MutableSparseNDimArray
from sympy.tensor.array.arrayop import tensorproduct, tensorcontraction, derive_by_array, permutedims, Flatten, \
tensordiagonal
def test_import_NDimArray():
from sympy.tensor.array import NDimArray
del NDimArray
def test_tensorproduct():
x,y,z,t = symbols('x y z t')
from sympy.abc import a,b,c,d
assert tensorproduct() == 1
assert tensorproduct([x]) == Array([x])
assert tensorproduct([x], [y]) == Array([[x*y]])
assert tensorproduct([x], [y], [z]) == Array([[[x*y*z]]])
assert tensorproduct([x], [y], [z], [t]) == Array([[[[x*y*z*t]]]])
assert tensorproduct(x) == x
assert tensorproduct(x, y) == x*y
assert tensorproduct(x, y, z) == x*y*z
assert tensorproduct(x, y, z, t) == x*y*z*t
for ArrayType in [ImmutableDenseNDimArray, ImmutableSparseNDimArray]:
A = ArrayType([x, y])
B = ArrayType([1, 2, 3])
C = ArrayType([a, b, c, d])
assert tensorproduct(A, B, C) == ArrayType([[[a*x, b*x, c*x, d*x], [2*a*x, 2*b*x, 2*c*x, 2*d*x], [3*a*x, 3*b*x, 3*c*x, 3*d*x]],
[[a*y, b*y, c*y, d*y], [2*a*y, 2*b*y, 2*c*y, 2*d*y], [3*a*y, 3*b*y, 3*c*y, 3*d*y]]])
assert tensorproduct([x, y], [1, 2, 3]) == tensorproduct(A, B)
assert tensorproduct(A, 2) == ArrayType([2*x, 2*y])
assert tensorproduct(A, [2]) == ArrayType([[2*x], [2*y]])
assert tensorproduct([2], A) == ArrayType([[2*x, 2*y]])
assert tensorproduct(a, A) == ArrayType([a*x, a*y])
assert tensorproduct(a, A, B) == ArrayType([[a*x, 2*a*x, 3*a*x], [a*y, 2*a*y, 3*a*y]])
assert tensorproduct(A, B, a) == ArrayType([[a*x, 2*a*x, 3*a*x], [a*y, 2*a*y, 3*a*y]])
assert tensorproduct(B, a, A) == ArrayType([[a*x, a*y], [2*a*x, 2*a*y], [3*a*x, 3*a*y]])
# tests for large scale sparse array
for SparseArrayType in [ImmutableSparseNDimArray, MutableSparseNDimArray]:
a = SparseArrayType({1:2, 3:4},(1000, 2000))
b = SparseArrayType({1:2, 3:4},(1000, 2000))
assert tensorproduct(a, b) == ImmutableSparseNDimArray({2000001: 4, 2000003: 8, 6000001: 8, 6000003: 16}, (1000, 2000, 1000, 2000))
def test_tensorcontraction():
from sympy.abc import a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x
B = Array(range(18), (2, 3, 3))
assert tensorcontraction(B, (1, 2)) == Array([12, 39])
C1 = Array([a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x], (2, 3, 2, 2))
assert tensorcontraction(C1, (0, 2)) == Array([[a + o, b + p], [e + s, f + t], [i + w, j + x]])
assert tensorcontraction(C1, (0, 2, 3)) == Array([a + p, e + t, i + x])
assert tensorcontraction(C1, (2, 3)) == Array([[a + d, e + h, i + l], [m + p, q + t, u + x]])
def test_derivative_by_array():
from sympy.abc import i, j, t, x, y, z
bexpr = x*y**2*exp(z)*log(t)
sexpr = sin(bexpr)
cexpr = cos(bexpr)
a = Array([sexpr])
assert derive_by_array(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t
assert derive_by_array(sexpr, [x, y, z]) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr])
assert derive_by_array(a, [x, y, z]) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]])
assert derive_by_array(sexpr, [[x, y], [z, t]]) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]])
assert derive_by_array(a, [[x, y], [z, t]]) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]])
assert derive_by_array([[x, y], [z, t]], [x, y]) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]])
assert derive_by_array([[x, y], [z, t]], [[x, y], [z, t]]) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]],
[[[0, 0], [1, 0]], [[0, 0], [0, 1]]]])
assert diff(sexpr, t) == x*y**2*exp(z)*cos(x*y**2*exp(z)*log(t))/t
assert diff(sexpr, Array([x, y, z])) == Array([bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr, bexpr*cexpr])
assert diff(a, Array([x, y, z])) == Array([[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr], [bexpr*cexpr]])
assert diff(sexpr, Array([[x, y], [z, t]])) == Array([[bexpr/x*cexpr, 2*y*bexpr/y**2*cexpr], [bexpr*cexpr, bexpr/log(t)/t*cexpr]])
assert diff(a, Array([[x, y], [z, t]])) == Array([[[bexpr/x*cexpr], [2*y*bexpr/y**2*cexpr]], [[bexpr*cexpr], [bexpr/log(t)/t*cexpr]]])
assert diff(Array([[x, y], [z, t]]), Array([x, y])) == Array([[[1, 0], [0, 0]], [[0, 1], [0, 0]]])
assert diff(Array([[x, y], [z, t]]), Array([[x, y], [z, t]])) == Array([[[[1, 0], [0, 0]], [[0, 1], [0, 0]]],
[[[0, 0], [1, 0]], [[0, 0], [0, 1]]]])
# test for large scale sparse array
for SparseArrayType in [ImmutableSparseNDimArray, MutableSparseNDimArray]:
b = MutableSparseNDimArray({0:i, 1:j}, (10000, 20000))
assert derive_by_array(b, i) == ImmutableSparseNDimArray({0: 1}, (10000, 20000))
assert derive_by_array(b, (i, j)) == ImmutableSparseNDimArray({0: 1, 200000001: 1}, (2, 10000, 20000))
#https://github.com/sympy/sympy/issues/20655
U = Array([x, y, z])
E = 2
assert derive_by_array(E, U) == ImmutableDenseNDimArray([0, 0, 0])
def test_issue_emerged_while_discussing_10972():
ua = Array([-1,0])
Fa = Array([[0, 1], [-1, 0]])
po = tensorproduct(Fa, ua, Fa, ua)
assert tensorcontraction(po, (1, 2), (4, 5)) == Array([[0, 0], [0, 1]])
sa = symbols('a0:144')
po = Array(sa, [2, 2, 3, 3, 2, 2])
assert tensorcontraction(po, (0, 1), (2, 3), (4, 5)) == sa[0] + sa[108] + sa[111] + sa[124] + sa[127] + sa[140] + sa[143] + sa[16] + sa[19] + sa[3] + sa[32] + sa[35]
assert tensorcontraction(po, (0, 1, 4, 5), (2, 3)) == sa[0] + sa[111] + sa[127] + sa[143] + sa[16] + sa[32]
assert tensorcontraction(po, (0, 1), (4, 5)) == Array([[sa[0] + sa[108] + sa[111] + sa[3], sa[112] + sa[115] + sa[4] + sa[7],
sa[11] + sa[116] + sa[119] + sa[8]], [sa[12] + sa[120] + sa[123] + sa[15],
sa[124] + sa[127] + sa[16] + sa[19], sa[128] + sa[131] + sa[20] + sa[23]],
[sa[132] + sa[135] + sa[24] + sa[27], sa[136] + sa[139] + sa[28] + sa[31],
sa[140] + sa[143] + sa[32] + sa[35]]])
assert tensorcontraction(po, (0, 1), (2, 3)) == Array([[sa[0] + sa[108] + sa[124] + sa[140] + sa[16] + sa[32], sa[1] + sa[109] + sa[125] + sa[141] + sa[17] + sa[33]],
[sa[110] + sa[126] + sa[142] + sa[18] + sa[2] + sa[34], sa[111] + sa[127] + sa[143] + sa[19] + sa[3] + sa[35]]])
def test_array_permutedims():
sa = symbols('a0:144')
for ArrayType in [ImmutableDenseNDimArray, ImmutableSparseNDimArray]:
m1 = ArrayType(sa[:6], (2, 3))
assert permutedims(m1, (1, 0)) == transpose(m1)
assert m1.tomatrix().T == permutedims(m1, (1, 0)).tomatrix()
assert m1.tomatrix().T == transpose(m1).tomatrix()
assert m1.tomatrix().C == conjugate(m1).tomatrix()
assert m1.tomatrix().H == adjoint(m1).tomatrix()
assert m1.tomatrix().T == m1.transpose().tomatrix()
assert m1.tomatrix().C == m1.conjugate().tomatrix()
assert m1.tomatrix().H == m1.adjoint().tomatrix()
raises(ValueError, lambda: permutedims(m1, (0,)))
raises(ValueError, lambda: permutedims(m1, (0, 0)))
raises(ValueError, lambda: permutedims(m1, (1, 2, 0)))
# Some tests with random arrays:
dims = 6
shape = [random.randint(1,5) for i in range(dims)]
elems = [random.random() for i in range(tensorproduct(*shape))]
ra = ArrayType(elems, shape)
perm = list(range(dims))
# Randomize the permutation:
random.shuffle(perm)
# Test inverse permutation:
assert permutedims(permutedims(ra, perm), _af_invert(perm)) == ra
# Test that permuted shape corresponds to action by `Permutation`:
assert permutedims(ra, perm).shape == tuple(Permutation(perm)(shape))
z = ArrayType.zeros(4,5,6,7)
assert permutedims(z, (2, 3, 1, 0)).shape == (6, 7, 5, 4)
assert permutedims(z, [2, 3, 1, 0]).shape == (6, 7, 5, 4)
assert permutedims(z, Permutation([2, 3, 1, 0])).shape == (6, 7, 5, 4)
po = ArrayType(sa, [2, 2, 3, 3, 2, 2])
raises(ValueError, lambda: permutedims(po, (1, 1)))
raises(ValueError, lambda: po.transpose())
raises(ValueError, lambda: po.adjoint())
assert permutedims(po, reversed(range(po.rank()))) == ArrayType(
[[[[[[sa[0], sa[72]], [sa[36], sa[108]]], [[sa[12], sa[84]], [sa[48], sa[120]]], [[sa[24],
sa[96]], [sa[60], sa[132]]]],
[[[sa[4], sa[76]], [sa[40], sa[112]]], [[sa[16],
sa[88]], [sa[52], sa[124]]],
[[sa[28], sa[100]], [sa[64], sa[136]]]],
[[[sa[8],
sa[80]], [sa[44], sa[116]]], [[sa[20], sa[92]], [sa[56], sa[128]]], [[sa[32],
sa[104]], [sa[68], sa[140]]]]],
[[[[sa[2], sa[74]], [sa[38], sa[110]]], [[sa[14],
sa[86]], [sa[50], sa[122]]], [[sa[26], sa[98]], [sa[62], sa[134]]]],
[[[sa[6],
sa[78]], [sa[42], sa[114]]], [[sa[18], sa[90]], [sa[54], sa[126]]], [[sa[30],
sa[102]], [sa[66], sa[138]]]],
[[[sa[10], sa[82]], [sa[46], sa[118]]], [[sa[22],
sa[94]], [sa[58], sa[130]]],
[[sa[34], sa[106]], [sa[70], sa[142]]]]]],
[[[[[sa[1],
sa[73]], [sa[37], sa[109]]], [[sa[13], sa[85]], [sa[49], sa[121]]], [[sa[25],
sa[97]], [sa[61], sa[133]]]],
[[[sa[5], sa[77]], [sa[41], sa[113]]], [[sa[17],
sa[89]], [sa[53], sa[125]]],
[[sa[29], sa[101]], [sa[65], sa[137]]]],
[[[sa[9],
sa[81]], [sa[45], sa[117]]], [[sa[21], sa[93]], [sa[57], sa[129]]], [[sa[33],
sa[105]], [sa[69], sa[141]]]]],
[[[[sa[3], sa[75]], [sa[39], sa[111]]], [[sa[15],
sa[87]], [sa[51], sa[123]]], [[sa[27], sa[99]], [sa[63], sa[135]]]],
[[[sa[7],
sa[79]], [sa[43], sa[115]]], [[sa[19], sa[91]], [sa[55], sa[127]]], [[sa[31],
sa[103]], [sa[67], sa[139]]]],
[[[sa[11], sa[83]], [sa[47], sa[119]]], [[sa[23],
sa[95]], [sa[59], sa[131]]],
[[sa[35], sa[107]], [sa[71], sa[143]]]]]]])
assert permutedims(po, (1, 0, 2, 3, 4, 5)) == ArrayType(
[[[[[[sa[0], sa[1]], [sa[2], sa[3]]], [[sa[4], sa[5]], [sa[6], sa[7]]], [[sa[8], sa[9]], [sa[10],
sa[11]]]],
[[[sa[12], sa[13]], [sa[14], sa[15]]], [[sa[16], sa[17]], [sa[18],
sa[19]]], [[sa[20], sa[21]], [sa[22], sa[23]]]],
[[[sa[24], sa[25]], [sa[26],
sa[27]]], [[sa[28], sa[29]], [sa[30], sa[31]]], [[sa[32], sa[33]], [sa[34],
sa[35]]]]],
[[[[sa[72], sa[73]], [sa[74], sa[75]]], [[sa[76], sa[77]], [sa[78],
sa[79]]], [[sa[80], sa[81]], [sa[82], sa[83]]]],
[[[sa[84], sa[85]], [sa[86],
sa[87]]], [[sa[88], sa[89]], [sa[90], sa[91]]], [[sa[92], sa[93]], [sa[94],
sa[95]]]],
[[[sa[96], sa[97]], [sa[98], sa[99]]], [[sa[100], sa[101]], [sa[102],
sa[103]]],
[[sa[104], sa[105]], [sa[106], sa[107]]]]]], [[[[[sa[36], sa[37]], [sa[38],
sa[39]]],
[[sa[40], sa[41]], [sa[42], sa[43]]],
[[sa[44], sa[45]], [sa[46],
sa[47]]]],
[[[sa[48], sa[49]], [sa[50], sa[51]]],
[[sa[52], sa[53]], [sa[54],
sa[55]]],
[[sa[56], sa[57]], [sa[58], sa[59]]]],
[[[sa[60], sa[61]], [sa[62],
sa[63]]],
[[sa[64], sa[65]], [sa[66], sa[67]]],
[[sa[68], sa[69]], [sa[70],
sa[71]]]]], [
[[[sa[108], sa[109]], [sa[110], sa[111]]],
[[sa[112], sa[113]], [sa[114],
sa[115]]],
[[sa[116], sa[117]], [sa[118], sa[119]]]],
[[[sa[120], sa[121]], [sa[122],
sa[123]]],
[[sa[124], sa[125]], [sa[126], sa[127]]],
[[sa[128], sa[129]], [sa[130],
sa[131]]]],
[[[sa[132], sa[133]], [sa[134], sa[135]]],
[[sa[136], sa[137]], [sa[138],
sa[139]]],
[[sa[140], sa[141]], [sa[142], sa[143]]]]]]])
assert permutedims(po, (0, 2, 1, 4, 3, 5)) == ArrayType(
[[[[[[sa[0], sa[1]], [sa[4], sa[5]], [sa[8], sa[9]]], [[sa[2], sa[3]], [sa[6], sa[7]], [sa[10],
sa[11]]]],
[[[sa[36], sa[37]], [sa[40], sa[41]], [sa[44], sa[45]]], [[sa[38],
sa[39]], [sa[42], sa[43]], [sa[46], sa[47]]]]],
[[[[sa[12], sa[13]], [sa[16],
sa[17]], [sa[20], sa[21]]], [[sa[14], sa[15]], [sa[18], sa[19]], [sa[22],
sa[23]]]],
[[[sa[48], sa[49]], [sa[52], sa[53]], [sa[56], sa[57]]], [[sa[50],
sa[51]], [sa[54], sa[55]], [sa[58], sa[59]]]]],
[[[[sa[24], sa[25]], [sa[28],
sa[29]], [sa[32], sa[33]]], [[sa[26], sa[27]], [sa[30], sa[31]], [sa[34],
sa[35]]]],
[[[sa[60], sa[61]], [sa[64], sa[65]], [sa[68], sa[69]]], [[sa[62],
sa[63]], [sa[66], sa[67]], [sa[70], sa[71]]]]]],
[[[[[sa[72], sa[73]], [sa[76],
sa[77]], [sa[80], sa[81]]], [[sa[74], sa[75]], [sa[78], sa[79]], [sa[82],
sa[83]]]],
[[[sa[108], sa[109]], [sa[112], sa[113]], [sa[116], sa[117]]], [[sa[110],
sa[111]], [sa[114], sa[115]],
[sa[118], sa[119]]]]],
[[[[sa[84], sa[85]], [sa[88],
sa[89]], [sa[92], sa[93]]], [[sa[86], sa[87]], [sa[90], sa[91]], [sa[94],
sa[95]]]],
[[[sa[120], sa[121]], [sa[124], sa[125]], [sa[128], sa[129]]], [[sa[122],
sa[123]], [sa[126], sa[127]],
[sa[130], sa[131]]]]],
[[[[sa[96], sa[97]], [sa[100],
sa[101]], [sa[104], sa[105]]], [[sa[98], sa[99]], [sa[102], sa[103]], [sa[106],
sa[107]]]],
[[[sa[132], sa[133]], [sa[136], sa[137]], [sa[140], sa[141]]], [[sa[134],
sa[135]], [sa[138], sa[139]],
[sa[142], sa[143]]]]]]])
po2 = po.reshape(4, 9, 2, 2)
assert po2 == ArrayType([[[[sa[0], sa[1]], [sa[2], sa[3]]], [[sa[4], sa[5]], [sa[6], sa[7]]], [[sa[8], sa[9]], [sa[10], sa[11]]], [[sa[12], sa[13]], [sa[14], sa[15]]], [[sa[16], sa[17]], [sa[18], sa[19]]], [[sa[20], sa[21]], [sa[22], sa[23]]], [[sa[24], sa[25]], [sa[26], sa[27]]], [[sa[28], sa[29]], [sa[30], sa[31]]], [[sa[32], sa[33]], [sa[34], sa[35]]]], [[[sa[36], sa[37]], [sa[38], sa[39]]], [[sa[40], sa[41]], [sa[42], sa[43]]], [[sa[44], sa[45]], [sa[46], sa[47]]], [[sa[48], sa[49]], [sa[50], sa[51]]], [[sa[52], sa[53]], [sa[54], sa[55]]], [[sa[56], sa[57]], [sa[58], sa[59]]], [[sa[60], sa[61]], [sa[62], sa[63]]], [[sa[64], sa[65]], [sa[66], sa[67]]], [[sa[68], sa[69]], [sa[70], sa[71]]]], [[[sa[72], sa[73]], [sa[74], sa[75]]], [[sa[76], sa[77]], [sa[78], sa[79]]], [[sa[80], sa[81]], [sa[82], sa[83]]], [[sa[84], sa[85]], [sa[86], sa[87]]], [[sa[88], sa[89]], [sa[90], sa[91]]], [[sa[92], sa[93]], [sa[94], sa[95]]], [[sa[96], sa[97]], [sa[98], sa[99]]], [[sa[100], sa[101]], [sa[102], sa[103]]], [[sa[104], sa[105]], [sa[106], sa[107]]]], [[[sa[108], sa[109]], [sa[110], sa[111]]], [[sa[112], sa[113]], [sa[114], sa[115]]], [[sa[116], sa[117]], [sa[118], sa[119]]], [[sa[120], sa[121]], [sa[122], sa[123]]], [[sa[124], sa[125]], [sa[126], sa[127]]], [[sa[128], sa[129]], [sa[130], sa[131]]], [[sa[132], sa[133]], [sa[134], sa[135]]], [[sa[136], sa[137]], [sa[138], sa[139]]], [[sa[140], sa[141]], [sa[142], sa[143]]]]])
assert permutedims(po2, (3, 2, 0, 1)) == ArrayType([[[[sa[0], sa[4], sa[8], sa[12], sa[16], sa[20], sa[24], sa[28], sa[32]], [sa[36], sa[40], sa[44], sa[48], sa[52], sa[56], sa[60], sa[64], sa[68]], [sa[72], sa[76], sa[80], sa[84], sa[88], sa[92], sa[96], sa[100], sa[104]], [sa[108], sa[112], sa[116], sa[120], sa[124], sa[128], sa[132], sa[136], sa[140]]], [[sa[2], sa[6], sa[10], sa[14], sa[18], sa[22], sa[26], sa[30], sa[34]], [sa[38], sa[42], sa[46], sa[50], sa[54], sa[58], sa[62], sa[66], sa[70]], [sa[74], sa[78], sa[82], sa[86], sa[90], sa[94], sa[98], sa[102], sa[106]], [sa[110], sa[114], sa[118], sa[122], sa[126], sa[130], sa[134], sa[138], sa[142]]]], [[[sa[1], sa[5], sa[9], sa[13], sa[17], sa[21], sa[25], sa[29], sa[33]], [sa[37], sa[41], sa[45], sa[49], sa[53], sa[57], sa[61], sa[65], sa[69]], [sa[73], sa[77], sa[81], sa[85], sa[89], sa[93], sa[97], sa[101], sa[105]], [sa[109], sa[113], sa[117], sa[121], sa[125], sa[129], sa[133], sa[137], sa[141]]], [[sa[3], sa[7], sa[11], sa[15], sa[19], sa[23], sa[27], sa[31], sa[35]], [sa[39], sa[43], sa[47], sa[51], sa[55], sa[59], sa[63], sa[67], sa[71]], [sa[75], sa[79], sa[83], sa[87], sa[91], sa[95], sa[99], sa[103], sa[107]], [sa[111], sa[115], sa[119], sa[123], sa[127], sa[131], sa[135], sa[139], sa[143]]]]])
# test for large scale sparse array
for SparseArrayType in [ImmutableSparseNDimArray, MutableSparseNDimArray]:
A = SparseArrayType({1:1, 10000:2}, (10000, 20000, 10000))
assert permutedims(A, (0, 1, 2)) == A
assert permutedims(A, (1, 0, 2)) == SparseArrayType({1: 1, 100000000: 2}, (20000, 10000, 10000))
B = SparseArrayType({1:1, 20000:2}, (10000, 20000))
assert B.transpose() == SparseArrayType({10000: 1, 1: 2}, (20000, 10000))
def test_permutedims_with_indices():
A = Array(range(32)).reshape(2, 2, 2, 2, 2)
indices_new = list("abcde")
indices_old = list("ebdac")
new_A = permutedims(A, index_order_new=indices_new, index_order_old=indices_old)
for a, b, c, d, e in itertools.product(range(2), range(2), range(2), range(2), range(2)):
assert new_A[a, b, c, d, e] == A[e, b, d, a, c]
indices_old = list("cabed")
new_A = permutedims(A, index_order_new=indices_new, index_order_old=indices_old)
for a, b, c, d, e in itertools.product(range(2), range(2), range(2), range(2), range(2)):
assert new_A[a, b, c, d, e] == A[c, a, b, e, d]
raises(ValueError, lambda: permutedims(A, index_order_old=list("aacde"), index_order_new=list("abcde")))
raises(ValueError, lambda: permutedims(A, index_order_old=list("abcde"), index_order_new=list("abcce")))
raises(ValueError, lambda: permutedims(A, index_order_old=list("abcde"), index_order_new=list("abce")))
raises(ValueError, lambda: permutedims(A, index_order_old=list("abce"), index_order_new=list("abce")))
raises(ValueError, lambda: permutedims(A, [2, 1, 0, 3, 4], index_order_old=list("abcde")))
raises(ValueError, lambda: permutedims(A, [2, 1, 0, 3, 4], index_order_new=list("abcde")))
def test_flatten():
from sympy.matrices.dense import Matrix
for ArrayType in [ImmutableDenseNDimArray, ImmutableSparseNDimArray, Matrix]:
A = ArrayType(range(24)).reshape(4, 6)
assert list(Flatten(A)) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
for i, v in enumerate(Flatten(A)):
assert i == v
def test_tensordiagonal():
from sympy.matrices.dense import eye
expr = Array(range(9)).reshape(3, 3)
raises(ValueError, lambda: tensordiagonal(expr, [0], [1]))
raises(ValueError, lambda: tensordiagonal(expr, [0, 0]))
assert tensordiagonal(eye(3), [0, 1]) == Array([1, 1, 1])
assert tensordiagonal(expr, [0, 1]) == Array([0, 4, 8])
x, y, z = symbols("x y z")
expr2 = tensorproduct([x, y, z], expr)
assert tensordiagonal(expr2, [1, 2]) == Array([[0, 4*x, 8*x], [0, 4*y, 8*y], [0, 4*z, 8*z]])
assert tensordiagonal(expr2, [0, 1]) == Array([[0, 3*y, 6*z], [x, 4*y, 7*z], [2*x, 5*y, 8*z]])
assert tensordiagonal(expr2, [0, 1, 2]) == Array([0, 4*y, 8*z])
# assert tensordiagonal(expr2, [0]) == permutedims(expr2, [1, 2, 0])
# assert tensordiagonal(expr2, [1]) == permutedims(expr2, [0, 2, 1])
# assert tensordiagonal(expr2, [2]) == expr2
# assert tensordiagonal(expr2, [1], [2]) == expr2
# assert tensordiagonal(expr2, [0], [1]) == permutedims(expr2, [2, 0, 1])
a, b, c, X, Y, Z = symbols("a b c X Y Z")
expr3 = tensorproduct([x, y, z], [1, 2, 3], [a, b, c], [X, Y, Z])
assert tensordiagonal(expr3, [0, 1, 2, 3]) == Array([x*a*X, 2*y*b*Y, 3*z*c*Z])
assert tensordiagonal(expr3, [0, 1], [2, 3]) == tensorproduct([x, 2*y, 3*z], [a*X, b*Y, c*Z])
# assert tensordiagonal(expr3, [0], [1, 2], [3]) == tensorproduct([x, y, z], [a, 2*b, 3*c], [X, Y, Z])
assert tensordiagonal(tensordiagonal(expr3, [2, 3]), [0, 1]) == tensorproduct([a*X, b*Y, c*Z], [x, 2*y, 3*z])
raises(ValueError, lambda: tensordiagonal([[1, 2, 3], [4, 5, 6]], [0, 1]))
raises(ValueError, lambda: tensordiagonal(expr3.reshape(3, 3, 9), [1, 2]))

View File

@ -0,0 +1,452 @@
from copy import copy
from sympy.tensor.array.dense_ndim_array import ImmutableDenseNDimArray
from sympy.core.containers import Dict
from sympy.core.function import diff
from sympy.core.numbers import Rational
from sympy.core.singleton import S
from sympy.core.symbol import (Symbol, symbols)
from sympy.matrices import SparseMatrix
from sympy.tensor.indexed import (Indexed, IndexedBase)
from sympy.matrices import Matrix
from sympy.tensor.array.sparse_ndim_array import ImmutableSparseNDimArray
from sympy.testing.pytest import raises
def test_ndim_array_initiation():
arr_with_no_elements = ImmutableDenseNDimArray([], shape=(0,))
assert len(arr_with_no_elements) == 0
assert arr_with_no_elements.rank() == 1
raises(ValueError, lambda: ImmutableDenseNDimArray([0], shape=(0,)))
raises(ValueError, lambda: ImmutableDenseNDimArray([1, 2, 3], shape=(0,)))
raises(ValueError, lambda: ImmutableDenseNDimArray([], shape=()))
raises(ValueError, lambda: ImmutableSparseNDimArray([0], shape=(0,)))
raises(ValueError, lambda: ImmutableSparseNDimArray([1, 2, 3], shape=(0,)))
raises(ValueError, lambda: ImmutableSparseNDimArray([], shape=()))
arr_with_one_element = ImmutableDenseNDimArray([23])
assert len(arr_with_one_element) == 1
assert arr_with_one_element[0] == 23
assert arr_with_one_element[:] == ImmutableDenseNDimArray([23])
assert arr_with_one_element.rank() == 1
arr_with_symbol_element = ImmutableDenseNDimArray([Symbol('x')])
assert len(arr_with_symbol_element) == 1
assert arr_with_symbol_element[0] == Symbol('x')
assert arr_with_symbol_element[:] == ImmutableDenseNDimArray([Symbol('x')])
assert arr_with_symbol_element.rank() == 1
number5 = 5
vector = ImmutableDenseNDimArray.zeros(number5)
assert len(vector) == number5
assert vector.shape == (number5,)
assert vector.rank() == 1
vector = ImmutableSparseNDimArray.zeros(number5)
assert len(vector) == number5
assert vector.shape == (number5,)
assert vector._sparse_array == Dict()
assert vector.rank() == 1
n_dim_array = ImmutableDenseNDimArray(range(3**4), (3, 3, 3, 3,))
assert len(n_dim_array) == 3 * 3 * 3 * 3
assert n_dim_array.shape == (3, 3, 3, 3)
assert n_dim_array.rank() == 4
array_shape = (3, 3, 3, 3)
sparse_array = ImmutableSparseNDimArray.zeros(*array_shape)
assert len(sparse_array._sparse_array) == 0
assert len(sparse_array) == 3 * 3 * 3 * 3
assert n_dim_array.shape == array_shape
assert n_dim_array.rank() == 4
one_dim_array = ImmutableDenseNDimArray([2, 3, 1])
assert len(one_dim_array) == 3
assert one_dim_array.shape == (3,)
assert one_dim_array.rank() == 1
assert one_dim_array.tolist() == [2, 3, 1]
shape = (3, 3)
array_with_many_args = ImmutableSparseNDimArray.zeros(*shape)
assert len(array_with_many_args) == 3 * 3
assert array_with_many_args.shape == shape
assert array_with_many_args[0, 0] == 0
assert array_with_many_args.rank() == 2
shape = (int(3), int(3))
array_with_long_shape = ImmutableSparseNDimArray.zeros(*shape)
assert len(array_with_long_shape) == 3 * 3
assert array_with_long_shape.shape == shape
assert array_with_long_shape[int(0), int(0)] == 0
assert array_with_long_shape.rank() == 2
vector_with_long_shape = ImmutableDenseNDimArray(range(5), int(5))
assert len(vector_with_long_shape) == 5
assert vector_with_long_shape.shape == (int(5),)
assert vector_with_long_shape.rank() == 1
raises(ValueError, lambda: vector_with_long_shape[int(5)])
from sympy.abc import x
for ArrayType in [ImmutableDenseNDimArray, ImmutableSparseNDimArray]:
rank_zero_array = ArrayType(x)
assert len(rank_zero_array) == 1
assert rank_zero_array.shape == ()
assert rank_zero_array.rank() == 0
assert rank_zero_array[()] == x
raises(ValueError, lambda: rank_zero_array[0])
def test_reshape():
array = ImmutableDenseNDimArray(range(50), 50)
assert array.shape == (50,)
assert array.rank() == 1
array = array.reshape(5, 5, 2)
assert array.shape == (5, 5, 2)
assert array.rank() == 3
assert len(array) == 50
def test_getitem():
for ArrayType in [ImmutableDenseNDimArray, ImmutableSparseNDimArray]:
array = ArrayType(range(24)).reshape(2, 3, 4)
assert array.tolist() == [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
assert array[0] == ArrayType([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])
assert array[0, 0] == ArrayType([0, 1, 2, 3])
value = 0
for i in range(2):
for j in range(3):
for k in range(4):
assert array[i, j, k] == value
value += 1
raises(ValueError, lambda: array[3, 4, 5])
raises(ValueError, lambda: array[3, 4, 5, 6])
raises(ValueError, lambda: array[3, 4, 5, 3:4])
def test_iterator():
array = ImmutableDenseNDimArray(range(4), (2, 2))
assert array[0] == ImmutableDenseNDimArray([0, 1])
assert array[1] == ImmutableDenseNDimArray([2, 3])
array = array.reshape(4)
j = 0
for i in array:
assert i == j
j += 1
def test_sparse():
sparse_array = ImmutableSparseNDimArray([0, 0, 0, 1], (2, 2))
assert len(sparse_array) == 2 * 2
# dictionary where all data is, only non-zero entries are actually stored:
assert len(sparse_array._sparse_array) == 1
assert sparse_array.tolist() == [[0, 0], [0, 1]]
for i, j in zip(sparse_array, [[0, 0], [0, 1]]):
assert i == ImmutableSparseNDimArray(j)
def sparse_assignment():
sparse_array[0, 0] = 123
assert len(sparse_array._sparse_array) == 1
raises(TypeError, sparse_assignment)
assert len(sparse_array._sparse_array) == 1
assert sparse_array[0, 0] == 0
assert sparse_array/0 == ImmutableSparseNDimArray([[S.NaN, S.NaN], [S.NaN, S.ComplexInfinity]], (2, 2))
# test for large scale sparse array
# equality test
assert ImmutableSparseNDimArray.zeros(100000, 200000) == ImmutableSparseNDimArray.zeros(100000, 200000)
# __mul__ and __rmul__
a = ImmutableSparseNDimArray({200001: 1}, (100000, 200000))
assert a * 3 == ImmutableSparseNDimArray({200001: 3}, (100000, 200000))
assert 3 * a == ImmutableSparseNDimArray({200001: 3}, (100000, 200000))
assert a * 0 == ImmutableSparseNDimArray({}, (100000, 200000))
assert 0 * a == ImmutableSparseNDimArray({}, (100000, 200000))
# __truediv__
assert a/3 == ImmutableSparseNDimArray({200001: Rational(1, 3)}, (100000, 200000))
# __neg__
assert -a == ImmutableSparseNDimArray({200001: -1}, (100000, 200000))
def test_calculation():
a = ImmutableDenseNDimArray([1]*9, (3, 3))
b = ImmutableDenseNDimArray([9]*9, (3, 3))
c = a + b
for i in c:
assert i == ImmutableDenseNDimArray([10, 10, 10])
assert c == ImmutableDenseNDimArray([10]*9, (3, 3))
assert c == ImmutableSparseNDimArray([10]*9, (3, 3))
c = b - a
for i in c:
assert i == ImmutableDenseNDimArray([8, 8, 8])
assert c == ImmutableDenseNDimArray([8]*9, (3, 3))
assert c == ImmutableSparseNDimArray([8]*9, (3, 3))
def test_ndim_array_converting():
dense_array = ImmutableDenseNDimArray([1, 2, 3, 4], (2, 2))
alist = dense_array.tolist()
assert alist == [[1, 2], [3, 4]]
matrix = dense_array.tomatrix()
assert (isinstance(matrix, Matrix))
for i in range(len(dense_array)):
assert dense_array[dense_array._get_tuple_index(i)] == matrix[i]
assert matrix.shape == dense_array.shape
assert ImmutableDenseNDimArray(matrix) == dense_array
assert ImmutableDenseNDimArray(matrix.as_immutable()) == dense_array
assert ImmutableDenseNDimArray(matrix.as_mutable()) == dense_array
sparse_array = ImmutableSparseNDimArray([1, 2, 3, 4], (2, 2))
alist = sparse_array.tolist()
assert alist == [[1, 2], [3, 4]]
matrix = sparse_array.tomatrix()
assert(isinstance(matrix, SparseMatrix))
for i in range(len(sparse_array)):
assert sparse_array[sparse_array._get_tuple_index(i)] == matrix[i]
assert matrix.shape == sparse_array.shape
assert ImmutableSparseNDimArray(matrix) == sparse_array
assert ImmutableSparseNDimArray(matrix.as_immutable()) == sparse_array
assert ImmutableSparseNDimArray(matrix.as_mutable()) == sparse_array
def test_converting_functions():
arr_list = [1, 2, 3, 4]
arr_matrix = Matrix(((1, 2), (3, 4)))
# list
arr_ndim_array = ImmutableDenseNDimArray(arr_list, (2, 2))
assert (isinstance(arr_ndim_array, ImmutableDenseNDimArray))
assert arr_matrix.tolist() == arr_ndim_array.tolist()
# Matrix
arr_ndim_array = ImmutableDenseNDimArray(arr_matrix)
assert (isinstance(arr_ndim_array, ImmutableDenseNDimArray))
assert arr_matrix.tolist() == arr_ndim_array.tolist()
assert arr_matrix.shape == arr_ndim_array.shape
def test_equality():
first_list = [1, 2, 3, 4]
second_list = [1, 2, 3, 4]
third_list = [4, 3, 2, 1]
assert first_list == second_list
assert first_list != third_list
first_ndim_array = ImmutableDenseNDimArray(first_list, (2, 2))
second_ndim_array = ImmutableDenseNDimArray(second_list, (2, 2))
fourth_ndim_array = ImmutableDenseNDimArray(first_list, (2, 2))
assert first_ndim_array == second_ndim_array
def assignment_attempt(a):
a[0, 0] = 0
raises(TypeError, lambda: assignment_attempt(second_ndim_array))
assert first_ndim_array == second_ndim_array
assert first_ndim_array == fourth_ndim_array
def test_arithmetic():
a = ImmutableDenseNDimArray([3 for i in range(9)], (3, 3))
b = ImmutableDenseNDimArray([7 for i in range(9)], (3, 3))
c1 = a + b
c2 = b + a
assert c1 == c2
d1 = a - b
d2 = b - a
assert d1 == d2 * (-1)
e1 = a * 5
e2 = 5 * a
e3 = copy(a)
e3 *= 5
assert e1 == e2 == e3
f1 = a / 5
f2 = copy(a)
f2 /= 5
assert f1 == f2
assert f1[0, 0] == f1[0, 1] == f1[0, 2] == f1[1, 0] == f1[1, 1] == \
f1[1, 2] == f1[2, 0] == f1[2, 1] == f1[2, 2] == Rational(3, 5)
assert type(a) == type(b) == type(c1) == type(c2) == type(d1) == type(d2) \
== type(e1) == type(e2) == type(e3) == type(f1)
z0 = -a
assert z0 == ImmutableDenseNDimArray([-3 for i in range(9)], (3, 3))
def test_higher_dimenions():
m3 = ImmutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert m3.tolist() == [[[10, 11, 12, 13],
[14, 15, 16, 17],
[18, 19, 20, 21]],
[[22, 23, 24, 25],
[26, 27, 28, 29],
[30, 31, 32, 33]]]
assert m3._get_tuple_index(0) == (0, 0, 0)
assert m3._get_tuple_index(1) == (0, 0, 1)
assert m3._get_tuple_index(4) == (0, 1, 0)
assert m3._get_tuple_index(12) == (1, 0, 0)
assert str(m3) == '[[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]]'
m3_rebuilt = ImmutableDenseNDimArray([[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]])
assert m3 == m3_rebuilt
m3_other = ImmutableDenseNDimArray([[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]], (2, 3, 4))
assert m3 == m3_other
def test_rebuild_immutable_arrays():
sparr = ImmutableSparseNDimArray(range(10, 34), (2, 3, 4))
densarr = ImmutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert sparr == sparr.func(*sparr.args)
assert densarr == densarr.func(*densarr.args)
def test_slices():
md = ImmutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert md[:] == ImmutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert md[:, :, 0].tomatrix() == Matrix([[10, 14, 18], [22, 26, 30]])
assert md[0, 1:2, :].tomatrix() == Matrix([[14, 15, 16, 17]])
assert md[0, 1:3, :].tomatrix() == Matrix([[14, 15, 16, 17], [18, 19, 20, 21]])
assert md[:, :, :] == md
sd = ImmutableSparseNDimArray(range(10, 34), (2, 3, 4))
assert sd == ImmutableSparseNDimArray(md)
assert sd[:] == ImmutableSparseNDimArray(range(10, 34), (2, 3, 4))
assert sd[:, :, 0].tomatrix() == Matrix([[10, 14, 18], [22, 26, 30]])
assert sd[0, 1:2, :].tomatrix() == Matrix([[14, 15, 16, 17]])
assert sd[0, 1:3, :].tomatrix() == Matrix([[14, 15, 16, 17], [18, 19, 20, 21]])
assert sd[:, :, :] == sd
def test_diff_and_applyfunc():
from sympy.abc import x, y, z
md = ImmutableDenseNDimArray([[x, y], [x*z, x*y*z]])
assert md.diff(x) == ImmutableDenseNDimArray([[1, 0], [z, y*z]])
assert diff(md, x) == ImmutableDenseNDimArray([[1, 0], [z, y*z]])
sd = ImmutableSparseNDimArray(md)
assert sd == ImmutableSparseNDimArray([x, y, x*z, x*y*z], (2, 2))
assert sd.diff(x) == ImmutableSparseNDimArray([[1, 0], [z, y*z]])
assert diff(sd, x) == ImmutableSparseNDimArray([[1, 0], [z, y*z]])
mdn = md.applyfunc(lambda x: x*3)
assert mdn == ImmutableDenseNDimArray([[3*x, 3*y], [3*x*z, 3*x*y*z]])
assert md != mdn
sdn = sd.applyfunc(lambda x: x/2)
assert sdn == ImmutableSparseNDimArray([[x/2, y/2], [x*z/2, x*y*z/2]])
assert sd != sdn
sdp = sd.applyfunc(lambda x: x+1)
assert sdp == ImmutableSparseNDimArray([[x + 1, y + 1], [x*z + 1, x*y*z + 1]])
assert sd != sdp
def test_op_priority():
from sympy.abc import x
md = ImmutableDenseNDimArray([1, 2, 3])
e1 = (1+x)*md
e2 = md*(1+x)
assert e1 == ImmutableDenseNDimArray([1+x, 2+2*x, 3+3*x])
assert e1 == e2
sd = ImmutableSparseNDimArray([1, 2, 3])
e3 = (1+x)*sd
e4 = sd*(1+x)
assert e3 == ImmutableDenseNDimArray([1+x, 2+2*x, 3+3*x])
assert e3 == e4
def test_symbolic_indexing():
x, y, z, w = symbols("x y z w")
M = ImmutableDenseNDimArray([[x, y], [z, w]])
i, j = symbols("i, j")
Mij = M[i, j]
assert isinstance(Mij, Indexed)
Ms = ImmutableSparseNDimArray([[2, 3*x], [4, 5]])
msij = Ms[i, j]
assert isinstance(msij, Indexed)
for oi, oj in [(0, 0), (0, 1), (1, 0), (1, 1)]:
assert Mij.subs({i: oi, j: oj}) == M[oi, oj]
assert msij.subs({i: oi, j: oj}) == Ms[oi, oj]
A = IndexedBase("A", (0, 2))
assert A[0, 0].subs(A, M) == x
assert A[i, j].subs(A, M) == M[i, j]
assert M[i, j].subs(M, A) == A[i, j]
assert isinstance(M[3 * i - 2, j], Indexed)
assert M[3 * i - 2, j].subs({i: 1, j: 0}) == M[1, 0]
assert isinstance(M[i, 0], Indexed)
assert M[i, 0].subs(i, 0) == M[0, 0]
assert M[0, i].subs(i, 1) == M[0, 1]
assert M[i, j].diff(x) == ImmutableDenseNDimArray([[1, 0], [0, 0]])[i, j]
assert Ms[i, j].diff(x) == ImmutableSparseNDimArray([[0, 3], [0, 0]])[i, j]
Mo = ImmutableDenseNDimArray([1, 2, 3])
assert Mo[i].subs(i, 1) == 2
Mos = ImmutableSparseNDimArray([1, 2, 3])
assert Mos[i].subs(i, 1) == 2
raises(ValueError, lambda: M[i, 2])
raises(ValueError, lambda: M[i, -1])
raises(ValueError, lambda: M[2, i])
raises(ValueError, lambda: M[-1, i])
raises(ValueError, lambda: Ms[i, 2])
raises(ValueError, lambda: Ms[i, -1])
raises(ValueError, lambda: Ms[2, i])
raises(ValueError, lambda: Ms[-1, i])
def test_issue_12665():
# Testing Python 3 hash of immutable arrays:
arr = ImmutableDenseNDimArray([1, 2, 3])
# This should NOT raise an exception:
hash(arr)
def test_zeros_without_shape():
arr = ImmutableDenseNDimArray.zeros()
assert arr == ImmutableDenseNDimArray(0)
def test_issue_21870():
a0 = ImmutableDenseNDimArray(0)
assert a0.rank() == 0
a1 = ImmutableDenseNDimArray(a0)
assert a1.rank() == 0

View File

@ -0,0 +1,374 @@
from copy import copy
from sympy.tensor.array.dense_ndim_array import MutableDenseNDimArray
from sympy.core.function import diff
from sympy.core.numbers import Rational
from sympy.core.singleton import S
from sympy.core.symbol import Symbol
from sympy.core.sympify import sympify
from sympy.matrices import SparseMatrix
from sympy.matrices import Matrix
from sympy.tensor.array.sparse_ndim_array import MutableSparseNDimArray
from sympy.testing.pytest import raises
def test_ndim_array_initiation():
arr_with_one_element = MutableDenseNDimArray([23])
assert len(arr_with_one_element) == 1
assert arr_with_one_element[0] == 23
assert arr_with_one_element.rank() == 1
raises(ValueError, lambda: arr_with_one_element[1])
arr_with_symbol_element = MutableDenseNDimArray([Symbol('x')])
assert len(arr_with_symbol_element) == 1
assert arr_with_symbol_element[0] == Symbol('x')
assert arr_with_symbol_element.rank() == 1
number5 = 5
vector = MutableDenseNDimArray.zeros(number5)
assert len(vector) == number5
assert vector.shape == (number5,)
assert vector.rank() == 1
raises(ValueError, lambda: arr_with_one_element[5])
vector = MutableSparseNDimArray.zeros(number5)
assert len(vector) == number5
assert vector.shape == (number5,)
assert vector._sparse_array == {}
assert vector.rank() == 1
n_dim_array = MutableDenseNDimArray(range(3**4), (3, 3, 3, 3,))
assert len(n_dim_array) == 3 * 3 * 3 * 3
assert n_dim_array.shape == (3, 3, 3, 3)
assert n_dim_array.rank() == 4
raises(ValueError, lambda: n_dim_array[0, 0, 0, 3])
raises(ValueError, lambda: n_dim_array[3, 0, 0, 0])
raises(ValueError, lambda: n_dim_array[3**4])
array_shape = (3, 3, 3, 3)
sparse_array = MutableSparseNDimArray.zeros(*array_shape)
assert len(sparse_array._sparse_array) == 0
assert len(sparse_array) == 3 * 3 * 3 * 3
assert n_dim_array.shape == array_shape
assert n_dim_array.rank() == 4
one_dim_array = MutableDenseNDimArray([2, 3, 1])
assert len(one_dim_array) == 3
assert one_dim_array.shape == (3,)
assert one_dim_array.rank() == 1
assert one_dim_array.tolist() == [2, 3, 1]
shape = (3, 3)
array_with_many_args = MutableSparseNDimArray.zeros(*shape)
assert len(array_with_many_args) == 3 * 3
assert array_with_many_args.shape == shape
assert array_with_many_args[0, 0] == 0
assert array_with_many_args.rank() == 2
shape = (int(3), int(3))
array_with_long_shape = MutableSparseNDimArray.zeros(*shape)
assert len(array_with_long_shape) == 3 * 3
assert array_with_long_shape.shape == shape
assert array_with_long_shape[int(0), int(0)] == 0
assert array_with_long_shape.rank() == 2
vector_with_long_shape = MutableDenseNDimArray(range(5), int(5))
assert len(vector_with_long_shape) == 5
assert vector_with_long_shape.shape == (int(5),)
assert vector_with_long_shape.rank() == 1
raises(ValueError, lambda: vector_with_long_shape[int(5)])
from sympy.abc import x
for ArrayType in [MutableDenseNDimArray, MutableSparseNDimArray]:
rank_zero_array = ArrayType(x)
assert len(rank_zero_array) == 1
assert rank_zero_array.shape == ()
assert rank_zero_array.rank() == 0
assert rank_zero_array[()] == x
raises(ValueError, lambda: rank_zero_array[0])
def test_sympify():
from sympy.abc import x, y, z, t
arr = MutableDenseNDimArray([[x, y], [1, z*t]])
arr_other = sympify(arr)
assert arr_other.shape == (2, 2)
assert arr_other == arr
def test_reshape():
array = MutableDenseNDimArray(range(50), 50)
assert array.shape == (50,)
assert array.rank() == 1
array = array.reshape(5, 5, 2)
assert array.shape == (5, 5, 2)
assert array.rank() == 3
assert len(array) == 50
def test_iterator():
array = MutableDenseNDimArray(range(4), (2, 2))
assert array[0] == MutableDenseNDimArray([0, 1])
assert array[1] == MutableDenseNDimArray([2, 3])
array = array.reshape(4)
j = 0
for i in array:
assert i == j
j += 1
def test_getitem():
for ArrayType in [MutableDenseNDimArray, MutableSparseNDimArray]:
array = ArrayType(range(24)).reshape(2, 3, 4)
assert array.tolist() == [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]
assert array[0] == ArrayType([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]])
assert array[0, 0] == ArrayType([0, 1, 2, 3])
value = 0
for i in range(2):
for j in range(3):
for k in range(4):
assert array[i, j, k] == value
value += 1
raises(ValueError, lambda: array[3, 4, 5])
raises(ValueError, lambda: array[3, 4, 5, 6])
raises(ValueError, lambda: array[3, 4, 5, 3:4])
def test_sparse():
sparse_array = MutableSparseNDimArray([0, 0, 0, 1], (2, 2))
assert len(sparse_array) == 2 * 2
# dictionary where all data is, only non-zero entries are actually stored:
assert len(sparse_array._sparse_array) == 1
assert sparse_array.tolist() == [[0, 0], [0, 1]]
for i, j in zip(sparse_array, [[0, 0], [0, 1]]):
assert i == MutableSparseNDimArray(j)
sparse_array[0, 0] = 123
assert len(sparse_array._sparse_array) == 2
assert sparse_array[0, 0] == 123
assert sparse_array/0 == MutableSparseNDimArray([[S.ComplexInfinity, S.NaN], [S.NaN, S.ComplexInfinity]], (2, 2))
# when element in sparse array become zero it will disappear from
# dictionary
sparse_array[0, 0] = 0
assert len(sparse_array._sparse_array) == 1
sparse_array[1, 1] = 0
assert len(sparse_array._sparse_array) == 0
assert sparse_array[0, 0] == 0
# test for large scale sparse array
# equality test
a = MutableSparseNDimArray.zeros(100000, 200000)
b = MutableSparseNDimArray.zeros(100000, 200000)
assert a == b
a[1, 1] = 1
b[1, 1] = 2
assert a != b
# __mul__ and __rmul__
assert a * 3 == MutableSparseNDimArray({200001: 3}, (100000, 200000))
assert 3 * a == MutableSparseNDimArray({200001: 3}, (100000, 200000))
assert a * 0 == MutableSparseNDimArray({}, (100000, 200000))
assert 0 * a == MutableSparseNDimArray({}, (100000, 200000))
# __truediv__
assert a/3 == MutableSparseNDimArray({200001: Rational(1, 3)}, (100000, 200000))
# __neg__
assert -a == MutableSparseNDimArray({200001: -1}, (100000, 200000))
def test_calculation():
a = MutableDenseNDimArray([1]*9, (3, 3))
b = MutableDenseNDimArray([9]*9, (3, 3))
c = a + b
for i in c:
assert i == MutableDenseNDimArray([10, 10, 10])
assert c == MutableDenseNDimArray([10]*9, (3, 3))
assert c == MutableSparseNDimArray([10]*9, (3, 3))
c = b - a
for i in c:
assert i == MutableSparseNDimArray([8, 8, 8])
assert c == MutableDenseNDimArray([8]*9, (3, 3))
assert c == MutableSparseNDimArray([8]*9, (3, 3))
def test_ndim_array_converting():
dense_array = MutableDenseNDimArray([1, 2, 3, 4], (2, 2))
alist = dense_array.tolist()
assert alist == [[1, 2], [3, 4]]
matrix = dense_array.tomatrix()
assert (isinstance(matrix, Matrix))
for i in range(len(dense_array)):
assert dense_array[dense_array._get_tuple_index(i)] == matrix[i]
assert matrix.shape == dense_array.shape
assert MutableDenseNDimArray(matrix) == dense_array
assert MutableDenseNDimArray(matrix.as_immutable()) == dense_array
assert MutableDenseNDimArray(matrix.as_mutable()) == dense_array
sparse_array = MutableSparseNDimArray([1, 2, 3, 4], (2, 2))
alist = sparse_array.tolist()
assert alist == [[1, 2], [3, 4]]
matrix = sparse_array.tomatrix()
assert(isinstance(matrix, SparseMatrix))
for i in range(len(sparse_array)):
assert sparse_array[sparse_array._get_tuple_index(i)] == matrix[i]
assert matrix.shape == sparse_array.shape
assert MutableSparseNDimArray(matrix) == sparse_array
assert MutableSparseNDimArray(matrix.as_immutable()) == sparse_array
assert MutableSparseNDimArray(matrix.as_mutable()) == sparse_array
def test_converting_functions():
arr_list = [1, 2, 3, 4]
arr_matrix = Matrix(((1, 2), (3, 4)))
# list
arr_ndim_array = MutableDenseNDimArray(arr_list, (2, 2))
assert (isinstance(arr_ndim_array, MutableDenseNDimArray))
assert arr_matrix.tolist() == arr_ndim_array.tolist()
# Matrix
arr_ndim_array = MutableDenseNDimArray(arr_matrix)
assert (isinstance(arr_ndim_array, MutableDenseNDimArray))
assert arr_matrix.tolist() == arr_ndim_array.tolist()
assert arr_matrix.shape == arr_ndim_array.shape
def test_equality():
first_list = [1, 2, 3, 4]
second_list = [1, 2, 3, 4]
third_list = [4, 3, 2, 1]
assert first_list == second_list
assert first_list != third_list
first_ndim_array = MutableDenseNDimArray(first_list, (2, 2))
second_ndim_array = MutableDenseNDimArray(second_list, (2, 2))
third_ndim_array = MutableDenseNDimArray(third_list, (2, 2))
fourth_ndim_array = MutableDenseNDimArray(first_list, (2, 2))
assert first_ndim_array == second_ndim_array
second_ndim_array[0, 0] = 0
assert first_ndim_array != second_ndim_array
assert first_ndim_array != third_ndim_array
assert first_ndim_array == fourth_ndim_array
def test_arithmetic():
a = MutableDenseNDimArray([3 for i in range(9)], (3, 3))
b = MutableDenseNDimArray([7 for i in range(9)], (3, 3))
c1 = a + b
c2 = b + a
assert c1 == c2
d1 = a - b
d2 = b - a
assert d1 == d2 * (-1)
e1 = a * 5
e2 = 5 * a
e3 = copy(a)
e3 *= 5
assert e1 == e2 == e3
f1 = a / 5
f2 = copy(a)
f2 /= 5
assert f1 == f2
assert f1[0, 0] == f1[0, 1] == f1[0, 2] == f1[1, 0] == f1[1, 1] == \
f1[1, 2] == f1[2, 0] == f1[2, 1] == f1[2, 2] == Rational(3, 5)
assert type(a) == type(b) == type(c1) == type(c2) == type(d1) == type(d2) \
== type(e1) == type(e2) == type(e3) == type(f1)
z0 = -a
assert z0 == MutableDenseNDimArray([-3 for i in range(9)], (3, 3))
def test_higher_dimenions():
m3 = MutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert m3.tolist() == [[[10, 11, 12, 13],
[14, 15, 16, 17],
[18, 19, 20, 21]],
[[22, 23, 24, 25],
[26, 27, 28, 29],
[30, 31, 32, 33]]]
assert m3._get_tuple_index(0) == (0, 0, 0)
assert m3._get_tuple_index(1) == (0, 0, 1)
assert m3._get_tuple_index(4) == (0, 1, 0)
assert m3._get_tuple_index(12) == (1, 0, 0)
assert str(m3) == '[[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]]'
m3_rebuilt = MutableDenseNDimArray([[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]])
assert m3 == m3_rebuilt
m3_other = MutableDenseNDimArray([[[10, 11, 12, 13], [14, 15, 16, 17], [18, 19, 20, 21]], [[22, 23, 24, 25], [26, 27, 28, 29], [30, 31, 32, 33]]], (2, 3, 4))
assert m3 == m3_other
def test_slices():
md = MutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert md[:] == MutableDenseNDimArray(range(10, 34), (2, 3, 4))
assert md[:, :, 0].tomatrix() == Matrix([[10, 14, 18], [22, 26, 30]])
assert md[0, 1:2, :].tomatrix() == Matrix([[14, 15, 16, 17]])
assert md[0, 1:3, :].tomatrix() == Matrix([[14, 15, 16, 17], [18, 19, 20, 21]])
assert md[:, :, :] == md
sd = MutableSparseNDimArray(range(10, 34), (2, 3, 4))
assert sd == MutableSparseNDimArray(md)
assert sd[:] == MutableSparseNDimArray(range(10, 34), (2, 3, 4))
assert sd[:, :, 0].tomatrix() == Matrix([[10, 14, 18], [22, 26, 30]])
assert sd[0, 1:2, :].tomatrix() == Matrix([[14, 15, 16, 17]])
assert sd[0, 1:3, :].tomatrix() == Matrix([[14, 15, 16, 17], [18, 19, 20, 21]])
assert sd[:, :, :] == sd
def test_slices_assign():
a = MutableDenseNDimArray(range(12), shape=(4, 3))
b = MutableSparseNDimArray(range(12), shape=(4, 3))
for i in [a, b]:
assert i.tolist() == [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
i[0, :] = [2, 2, 2]
assert i.tolist() == [[2, 2, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
i[0, 1:] = [8, 8]
assert i.tolist() == [[2, 8, 8], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
i[1:3, 1] = [20, 44]
assert i.tolist() == [[2, 8, 8], [3, 20, 5], [6, 44, 8], [9, 10, 11]]
def test_diff():
from sympy.abc import x, y, z
md = MutableDenseNDimArray([[x, y], [x*z, x*y*z]])
assert md.diff(x) == MutableDenseNDimArray([[1, 0], [z, y*z]])
assert diff(md, x) == MutableDenseNDimArray([[1, 0], [z, y*z]])
sd = MutableSparseNDimArray(md)
assert sd == MutableSparseNDimArray([x, y, x*z, x*y*z], (2, 2))
assert sd.diff(x) == MutableSparseNDimArray([[1, 0], [z, y*z]])
assert diff(sd, x) == MutableSparseNDimArray([[1, 0], [z, y*z]])

View File

@ -0,0 +1,73 @@
from sympy.testing.pytest import raises
from sympy.functions.elementary.trigonometric import sin, cos
from sympy.matrices.dense import Matrix
from sympy.simplify import simplify
from sympy.tensor.array import Array
from sympy.tensor.array.dense_ndim_array import (
ImmutableDenseNDimArray, MutableDenseNDimArray)
from sympy.tensor.array.sparse_ndim_array import (
ImmutableSparseNDimArray, MutableSparseNDimArray)
from sympy.abc import x, y
mutable_array_types = [
MutableDenseNDimArray,
MutableSparseNDimArray
]
array_types = [
ImmutableDenseNDimArray,
ImmutableSparseNDimArray,
MutableDenseNDimArray,
MutableSparseNDimArray
]
def test_array_negative_indices():
for ArrayType in array_types:
test_array = ArrayType([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
assert test_array[:, -1] == Array([5, 10])
assert test_array[:, -2] == Array([4, 9])
assert test_array[:, -3] == Array([3, 8])
assert test_array[:, -4] == Array([2, 7])
assert test_array[:, -5] == Array([1, 6])
assert test_array[:, 0] == Array([1, 6])
assert test_array[:, 1] == Array([2, 7])
assert test_array[:, 2] == Array([3, 8])
assert test_array[:, 3] == Array([4, 9])
assert test_array[:, 4] == Array([5, 10])
raises(ValueError, lambda: test_array[:, -6])
raises(ValueError, lambda: test_array[-3, :])
assert test_array[-1, -1] == 10
def test_issue_18361():
A = Array([sin(2 * x) - 2 * sin(x) * cos(x)])
B = Array([sin(x)**2 + cos(x)**2, 0])
C = Array([(x + x**2)/(x*sin(y)**2 + x*cos(y)**2), 2*sin(x)*cos(x)])
assert simplify(A) == Array([0])
assert simplify(B) == Array([1, 0])
assert simplify(C) == Array([x + 1, sin(2*x)])
def test_issue_20222():
A = Array([[1, 2], [3, 4]])
B = Matrix([[1,2],[3,4]])
raises(TypeError, lambda: A - B)
def test_issue_17851():
for array_type in array_types:
A = array_type([])
assert isinstance(A, array_type)
assert A.shape == (0,)
assert list(A) == []
def test_issue_and_18715():
for array_type in mutable_array_types:
A = array_type([0, 1, 2])
A[0] += 5
assert A[0] == 5

View File

@ -0,0 +1,22 @@
from sympy.tensor.array import (ImmutableDenseNDimArray,
ImmutableSparseNDimArray, MutableDenseNDimArray, MutableSparseNDimArray)
from sympy.abc import x, y, z
def test_NDim_array_conv():
MD = MutableDenseNDimArray([x, y, z])
MS = MutableSparseNDimArray([x, y, z])
ID = ImmutableDenseNDimArray([x, y, z])
IS = ImmutableSparseNDimArray([x, y, z])
assert MD.as_immutable() == ID
assert MD.as_mutable() == MD
assert MS.as_immutable() == IS
assert MS.as_mutable() == MS
assert ID.as_immutable() == ID
assert ID.as_mutable() == MD
assert IS.as_immutable() == IS
assert IS.as_mutable() == MS