add read me
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
from sympy.tensor.functions import TensorProduct
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.matrices.expressions.matexpr import MatrixSymbol
|
||||
from sympy.tensor.array import Array
|
||||
from sympy.abc import x, y, z
|
||||
from sympy.abc import i, j, k, l
|
||||
|
||||
|
||||
A = MatrixSymbol("A", 3, 3)
|
||||
B = MatrixSymbol("B", 3, 3)
|
||||
C = MatrixSymbol("C", 3, 3)
|
||||
|
||||
|
||||
def test_TensorProduct_construction():
|
||||
assert TensorProduct(3, 4) == 12
|
||||
assert isinstance(TensorProduct(A, A), TensorProduct)
|
||||
|
||||
expr = TensorProduct(TensorProduct(x, y), z)
|
||||
assert expr == x*y*z
|
||||
|
||||
expr = TensorProduct(TensorProduct(A, B), C)
|
||||
assert expr == TensorProduct(A, B, C)
|
||||
|
||||
expr = TensorProduct(Matrix.eye(2), Array([[0, -1], [1, 0]]))
|
||||
assert expr == Array([
|
||||
[
|
||||
[[0, -1], [1, 0]],
|
||||
[[0, 0], [0, 0]]
|
||||
],
|
||||
[
|
||||
[[0, 0], [0, 0]],
|
||||
[[0, -1], [1, 0]]
|
||||
]
|
||||
])
|
||||
|
||||
|
||||
def test_TensorProduct_shape():
|
||||
|
||||
expr = TensorProduct(3, 4, evaluate=False)
|
||||
assert expr.shape == ()
|
||||
assert expr.rank() == 0
|
||||
|
||||
expr = TensorProduct(Array([1, 2]), Array([x, y]), evaluate=False)
|
||||
assert expr.shape == (2, 2)
|
||||
assert expr.rank() == 2
|
||||
expr = TensorProduct(expr, expr, evaluate=False)
|
||||
assert expr.shape == (2, 2, 2, 2)
|
||||
assert expr.rank() == 4
|
||||
|
||||
expr = TensorProduct(Matrix.eye(2), Array([[0, -1], [1, 0]]), evaluate=False)
|
||||
assert expr.shape == (2, 2, 2, 2)
|
||||
assert expr.rank() == 4
|
||||
|
||||
|
||||
def test_TensorProduct_getitem():
|
||||
expr = TensorProduct(A, B)
|
||||
assert expr[i, j, k, l] == A[i, j]*B[k, l]
|
||||
@@ -0,0 +1,227 @@
|
||||
from sympy.core import symbols, S, Pow, Function
|
||||
from sympy.functions import exp
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.tensor.indexed import Idx, IndexedBase
|
||||
from sympy.tensor.index_methods import IndexConformanceException
|
||||
|
||||
from sympy.tensor.index_methods import (get_contraction_structure, get_indices)
|
||||
|
||||
|
||||
def test_trivial_indices():
|
||||
x, y = symbols('x y')
|
||||
assert get_indices(x) == (set(), {})
|
||||
assert get_indices(x*y) == (set(), {})
|
||||
assert get_indices(x + y) == (set(), {})
|
||||
assert get_indices(x**y) == (set(), {})
|
||||
|
||||
|
||||
def test_get_indices_Indexed():
|
||||
x = IndexedBase('x')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
assert get_indices(x[i, j]) == ({i, j}, {})
|
||||
assert get_indices(x[j, i]) == ({j, i}, {})
|
||||
|
||||
|
||||
def test_get_indices_Idx():
|
||||
f = Function('f')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
assert get_indices(f(i)*j) == ({i, j}, {})
|
||||
assert get_indices(f(j, i)) == ({j, i}, {})
|
||||
assert get_indices(f(i)*i) == (set(), {})
|
||||
|
||||
|
||||
def test_get_indices_mul():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
assert get_indices(x[j]*y[i]) == ({i, j}, {})
|
||||
assert get_indices(x[i]*y[j]) == ({i, j}, {})
|
||||
|
||||
|
||||
def test_get_indices_exceptions():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
raises(IndexConformanceException, lambda: get_indices(x[i] + y[j]))
|
||||
|
||||
|
||||
def test_scalar_broadcast():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
assert get_indices(x[i] + y[i, i]) == ({i}, {})
|
||||
assert get_indices(x[i] + y[j, j]) == ({i}, {})
|
||||
|
||||
|
||||
def test_get_indices_add():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
A = IndexedBase('A')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
assert get_indices(x[i] + 2*y[i]) == ({i}, {})
|
||||
assert get_indices(y[i] + 2*A[i, j]*x[j]) == ({i}, {})
|
||||
assert get_indices(y[i] + 2*(x[i] + A[i, j]*x[j])) == ({i}, {})
|
||||
assert get_indices(y[i] + x[i]*(A[j, j] + 1)) == ({i}, {})
|
||||
assert get_indices(
|
||||
y[i] + x[i]*x[j]*(y[j] + A[j, k]*x[k])) == ({i}, {})
|
||||
|
||||
|
||||
def test_get_indices_Pow():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
A = IndexedBase('A')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
assert get_indices(Pow(x[i], y[j])) == ({i, j}, {})
|
||||
assert get_indices(Pow(x[i, k], y[j, k])) == ({i, j, k}, {})
|
||||
assert get_indices(Pow(A[i, k], y[k] + A[k, j]*x[j])) == ({i, k}, {})
|
||||
assert get_indices(Pow(2, x[i])) == get_indices(exp(x[i]))
|
||||
|
||||
# test of a design decision, this may change:
|
||||
assert get_indices(Pow(x[i], 2)) == ({i}, {})
|
||||
|
||||
|
||||
def test_get_contraction_structure_basic():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
assert get_contraction_structure(x[i]*y[j]) == {None: {x[i]*y[j]}}
|
||||
assert get_contraction_structure(x[i] + y[j]) == {None: {x[i], y[j]}}
|
||||
assert get_contraction_structure(x[i]*y[i]) == {(i,): {x[i]*y[i]}}
|
||||
assert get_contraction_structure(
|
||||
1 + x[i]*y[i]) == {None: {S.One}, (i,): {x[i]*y[i]}}
|
||||
assert get_contraction_structure(x[i]**y[i]) == {None: {x[i]**y[i]}}
|
||||
|
||||
|
||||
def test_get_contraction_structure_complex():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
A = IndexedBase('A')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
expr1 = y[i] + A[i, j]*x[j]
|
||||
d1 = {None: {y[i]}, (j,): {A[i, j]*x[j]}}
|
||||
assert get_contraction_structure(expr1) == d1
|
||||
expr2 = expr1*A[k, i] + x[k]
|
||||
d2 = {None: {x[k]}, (i,): {expr1*A[k, i]}, expr1*A[k, i]: [d1]}
|
||||
assert get_contraction_structure(expr2) == d2
|
||||
|
||||
|
||||
def test_contraction_structure_simple_Pow():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
ii_jj = x[i, i]**y[j, j]
|
||||
assert get_contraction_structure(ii_jj) == {
|
||||
None: {ii_jj},
|
||||
ii_jj: [
|
||||
{(i,): {x[i, i]}},
|
||||
{(j,): {y[j, j]}}
|
||||
]
|
||||
}
|
||||
|
||||
ii_jk = x[i, i]**y[j, k]
|
||||
assert get_contraction_structure(ii_jk) == {
|
||||
None: {x[i, i]**y[j, k]},
|
||||
x[i, i]**y[j, k]: [
|
||||
{(i,): {x[i, i]}}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_contraction_structure_Mul_and_Pow():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
|
||||
i_ji = x[i]**(y[j]*x[i])
|
||||
assert get_contraction_structure(i_ji) == {None: {i_ji}}
|
||||
ij_i = (x[i]*y[j])**(y[i])
|
||||
assert get_contraction_structure(ij_i) == {None: {ij_i}}
|
||||
j_ij_i = x[j]*(x[i]*y[j])**(y[i])
|
||||
assert get_contraction_structure(j_ij_i) == {(j,): {j_ij_i}}
|
||||
j_i_ji = x[j]*x[i]**(y[j]*x[i])
|
||||
assert get_contraction_structure(j_i_ji) == {(j,): {j_i_ji}}
|
||||
ij_exp_kki = x[i]*y[j]*exp(y[i]*y[k, k])
|
||||
result = get_contraction_structure(ij_exp_kki)
|
||||
expected = {
|
||||
(i,): {ij_exp_kki},
|
||||
ij_exp_kki: [{
|
||||
None: {exp(y[i]*y[k, k])},
|
||||
exp(y[i]*y[k, k]): [{
|
||||
None: {y[i]*y[k, k]},
|
||||
y[i]*y[k, k]: [{(k,): {y[k, k]}}]
|
||||
}]}
|
||||
]
|
||||
}
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_contraction_structure_Add_in_Pow():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
s_ii_jj_s = (1 + x[i, i])**(1 + y[j, j])
|
||||
expected = {
|
||||
None: {s_ii_jj_s},
|
||||
s_ii_jj_s: [
|
||||
{None: {S.One}, (i,): {x[i, i]}},
|
||||
{None: {S.One}, (j,): {y[j, j]}}
|
||||
]
|
||||
}
|
||||
result = get_contraction_structure(s_ii_jj_s)
|
||||
assert result == expected
|
||||
|
||||
s_ii_jk_s = (1 + x[i, i]) ** (1 + y[j, k])
|
||||
expected_2 = {
|
||||
None: {(x[i, i] + 1)**(y[j, k] + 1)},
|
||||
s_ii_jk_s: [
|
||||
{None: {S.One}, (i,): {x[i, i]}}
|
||||
]
|
||||
}
|
||||
result_2 = get_contraction_structure(s_ii_jk_s)
|
||||
assert result_2 == expected_2
|
||||
|
||||
|
||||
def test_contraction_structure_Pow_in_Pow():
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
z = IndexedBase('z')
|
||||
i, j, k = Idx('i'), Idx('j'), Idx('k')
|
||||
ii_jj_kk = x[i, i]**y[j, j]**z[k, k]
|
||||
expected = {
|
||||
None: {ii_jj_kk},
|
||||
ii_jj_kk: [
|
||||
{(i,): {x[i, i]}},
|
||||
{
|
||||
None: {y[j, j]**z[k, k]},
|
||||
y[j, j]**z[k, k]: [
|
||||
{(j,): {y[j, j]}},
|
||||
{(k,): {z[k, k]}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
assert get_contraction_structure(ii_jj_kk) == expected
|
||||
|
||||
|
||||
def test_ufunc_support():
|
||||
f = Function('f')
|
||||
g = Function('g')
|
||||
x = IndexedBase('x')
|
||||
y = IndexedBase('y')
|
||||
i, j = Idx('i'), Idx('j')
|
||||
a = symbols('a')
|
||||
|
||||
assert get_indices(f(x[i])) == ({i}, {})
|
||||
assert get_indices(f(x[i], y[j])) == ({i, j}, {})
|
||||
assert get_indices(f(y[i])*g(x[i])) == (set(), {})
|
||||
assert get_indices(f(a, x[i])) == ({i}, {})
|
||||
assert get_indices(f(a, y[i], x[j])*g(x[i])) == ({j}, {})
|
||||
assert get_indices(g(f(x[i]))) == ({i}, {})
|
||||
|
||||
assert get_contraction_structure(f(x[i])) == {None: {f(x[i])}}
|
||||
assert get_contraction_structure(
|
||||
f(y[i])*g(x[i])) == {(i,): {f(y[i])*g(x[i])}}
|
||||
assert get_contraction_structure(
|
||||
f(y[i])*g(f(x[i]))) == {(i,): {f(y[i])*g(f(x[i]))}}
|
||||
assert get_contraction_structure(
|
||||
f(x[j], y[i])*g(x[i])) == {(i,): {f(x[j], y[i])*g(x[i])}}
|
||||
@@ -0,0 +1,511 @@
|
||||
from sympy.core import symbols, Symbol, Tuple, oo, Dummy
|
||||
from sympy.tensor.indexed import IndexException
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.utilities.iterables import iterable
|
||||
|
||||
# import test:
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.function import Function, Subs, Derivative
|
||||
from sympy.core.relational import (StrictLessThan, GreaterThan,
|
||||
StrictGreaterThan, LessThan)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.functions.elementary.exponential import exp, log
|
||||
from sympy.functions.elementary.trigonometric import cos, sin
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
from sympy.series.order import Order
|
||||
from sympy.sets.fancysets import Range
|
||||
from sympy.tensor.indexed import IndexedBase, Idx, Indexed
|
||||
|
||||
|
||||
def test_Idx_construction():
|
||||
i, a, b = symbols('i a b', integer=True)
|
||||
assert Idx(i) != Idx(i, 1)
|
||||
assert Idx(i, a) == Idx(i, (0, a - 1))
|
||||
assert Idx(i, oo) == Idx(i, (0, oo))
|
||||
|
||||
x = symbols('x', integer=False)
|
||||
raises(TypeError, lambda: Idx(x))
|
||||
raises(TypeError, lambda: Idx(0.5))
|
||||
raises(TypeError, lambda: Idx(i, x))
|
||||
raises(TypeError, lambda: Idx(i, 0.5))
|
||||
raises(TypeError, lambda: Idx(i, (x, 5)))
|
||||
raises(TypeError, lambda: Idx(i, (2, x)))
|
||||
raises(TypeError, lambda: Idx(i, (2, 3.5)))
|
||||
|
||||
|
||||
def test_Idx_properties():
|
||||
i, a, b = symbols('i a b', integer=True)
|
||||
assert Idx(i).is_integer
|
||||
assert Idx(i).name == 'i'
|
||||
assert Idx(i + 2).name == 'i + 2'
|
||||
assert Idx('foo').name == 'foo'
|
||||
|
||||
|
||||
def test_Idx_bounds():
|
||||
i, a, b = symbols('i a b', integer=True)
|
||||
assert Idx(i).lower is None
|
||||
assert Idx(i).upper is None
|
||||
assert Idx(i, a).lower == 0
|
||||
assert Idx(i, a).upper == a - 1
|
||||
assert Idx(i, 5).lower == 0
|
||||
assert Idx(i, 5).upper == 4
|
||||
assert Idx(i, oo).lower == 0
|
||||
assert Idx(i, oo).upper is oo
|
||||
assert Idx(i, (a, b)).lower == a
|
||||
assert Idx(i, (a, b)).upper == b
|
||||
assert Idx(i, (1, 5)).lower == 1
|
||||
assert Idx(i, (1, 5)).upper == 5
|
||||
assert Idx(i, (-oo, oo)).lower is -oo
|
||||
assert Idx(i, (-oo, oo)).upper is oo
|
||||
|
||||
|
||||
def test_Idx_fixed_bounds():
|
||||
i, a, b, x = symbols('i a b x', integer=True)
|
||||
assert Idx(x).lower is None
|
||||
assert Idx(x).upper is None
|
||||
assert Idx(x, a).lower == 0
|
||||
assert Idx(x, a).upper == a - 1
|
||||
assert Idx(x, 5).lower == 0
|
||||
assert Idx(x, 5).upper == 4
|
||||
assert Idx(x, oo).lower == 0
|
||||
assert Idx(x, oo).upper is oo
|
||||
assert Idx(x, (a, b)).lower == a
|
||||
assert Idx(x, (a, b)).upper == b
|
||||
assert Idx(x, (1, 5)).lower == 1
|
||||
assert Idx(x, (1, 5)).upper == 5
|
||||
assert Idx(x, (-oo, oo)).lower is -oo
|
||||
assert Idx(x, (-oo, oo)).upper is oo
|
||||
|
||||
|
||||
def test_Idx_inequalities():
|
||||
i14 = Idx("i14", (1, 4))
|
||||
i79 = Idx("i79", (7, 9))
|
||||
i46 = Idx("i46", (4, 6))
|
||||
i35 = Idx("i35", (3, 5))
|
||||
|
||||
assert i14 <= 5
|
||||
assert i14 < 5
|
||||
assert not (i14 >= 5)
|
||||
assert not (i14 > 5)
|
||||
|
||||
assert 5 >= i14
|
||||
assert 5 > i14
|
||||
assert not (5 <= i14)
|
||||
assert not (5 < i14)
|
||||
|
||||
assert LessThan(i14, 5)
|
||||
assert StrictLessThan(i14, 5)
|
||||
assert not GreaterThan(i14, 5)
|
||||
assert not StrictGreaterThan(i14, 5)
|
||||
|
||||
assert i14 <= 4
|
||||
assert isinstance(i14 < 4, StrictLessThan)
|
||||
assert isinstance(i14 >= 4, GreaterThan)
|
||||
assert not (i14 > 4)
|
||||
|
||||
assert isinstance(i14 <= 1, LessThan)
|
||||
assert not (i14 < 1)
|
||||
assert i14 >= 1
|
||||
assert isinstance(i14 > 1, StrictGreaterThan)
|
||||
|
||||
assert not (i14 <= 0)
|
||||
assert not (i14 < 0)
|
||||
assert i14 >= 0
|
||||
assert i14 > 0
|
||||
|
||||
from sympy.abc import x
|
||||
|
||||
assert isinstance(i14 < x, StrictLessThan)
|
||||
assert isinstance(i14 > x, StrictGreaterThan)
|
||||
assert isinstance(i14 <= x, LessThan)
|
||||
assert isinstance(i14 >= x, GreaterThan)
|
||||
|
||||
assert i14 < i79
|
||||
assert i14 <= i79
|
||||
assert not (i14 > i79)
|
||||
assert not (i14 >= i79)
|
||||
|
||||
assert i14 <= i46
|
||||
assert isinstance(i14 < i46, StrictLessThan)
|
||||
assert isinstance(i14 >= i46, GreaterThan)
|
||||
assert not (i14 > i46)
|
||||
|
||||
assert isinstance(i14 < i35, StrictLessThan)
|
||||
assert isinstance(i14 > i35, StrictGreaterThan)
|
||||
assert isinstance(i14 <= i35, LessThan)
|
||||
assert isinstance(i14 >= i35, GreaterThan)
|
||||
|
||||
iNone1 = Idx("iNone1")
|
||||
iNone2 = Idx("iNone2")
|
||||
|
||||
assert isinstance(iNone1 < iNone2, StrictLessThan)
|
||||
assert isinstance(iNone1 > iNone2, StrictGreaterThan)
|
||||
assert isinstance(iNone1 <= iNone2, LessThan)
|
||||
assert isinstance(iNone1 >= iNone2, GreaterThan)
|
||||
|
||||
|
||||
def test_Idx_inequalities_current_fails():
|
||||
i14 = Idx("i14", (1, 4))
|
||||
|
||||
assert S(5) >= i14
|
||||
assert S(5) > i14
|
||||
assert not (S(5) <= i14)
|
||||
assert not (S(5) < i14)
|
||||
|
||||
|
||||
def test_Idx_func_args():
|
||||
i, a, b = symbols('i a b', integer=True)
|
||||
ii = Idx(i)
|
||||
assert ii.func(*ii.args) == ii
|
||||
ii = Idx(i, a)
|
||||
assert ii.func(*ii.args) == ii
|
||||
ii = Idx(i, (a, b))
|
||||
assert ii.func(*ii.args) == ii
|
||||
|
||||
|
||||
def test_Idx_subs():
|
||||
i, a, b = symbols('i a b', integer=True)
|
||||
assert Idx(i, a).subs(a, b) == Idx(i, b)
|
||||
assert Idx(i, a).subs(i, b) == Idx(b, a)
|
||||
|
||||
assert Idx(i).subs(i, 2) == Idx(2)
|
||||
assert Idx(i, a).subs(a, 2) == Idx(i, 2)
|
||||
assert Idx(i, (a, b)).subs(i, 2) == Idx(2, (a, b))
|
||||
|
||||
|
||||
def test_IndexedBase_sugar():
|
||||
i, j = symbols('i j', integer=True)
|
||||
a = symbols('a')
|
||||
A1 = Indexed(a, i, j)
|
||||
A2 = IndexedBase(a)
|
||||
assert A1 == A2[i, j]
|
||||
assert A1 == A2[(i, j)]
|
||||
assert A1 == A2[[i, j]]
|
||||
assert A1 == A2[Tuple(i, j)]
|
||||
assert all(a.is_Integer for a in A2[1, 0].args[1:])
|
||||
|
||||
|
||||
def test_IndexedBase_subs():
|
||||
i = symbols('i', integer=True)
|
||||
a, b = symbols('a b')
|
||||
A = IndexedBase(a)
|
||||
B = IndexedBase(b)
|
||||
assert A[i] == B[i].subs(b, a)
|
||||
C = {1: 2}
|
||||
assert C[1] == A[1].subs(A, C)
|
||||
|
||||
|
||||
def test_IndexedBase_shape():
|
||||
i, j, m, n = symbols('i j m n', integer=True)
|
||||
a = IndexedBase('a', shape=(m, m))
|
||||
b = IndexedBase('a', shape=(m, n))
|
||||
assert b.shape == Tuple(m, n)
|
||||
assert a[i, j] != b[i, j]
|
||||
assert a[i, j] == b[i, j].subs(n, m)
|
||||
assert b.func(*b.args) == b
|
||||
assert b[i, j].func(*b[i, j].args) == b[i, j]
|
||||
raises(IndexException, lambda: b[i])
|
||||
raises(IndexException, lambda: b[i, i, j])
|
||||
F = IndexedBase("F", shape=m)
|
||||
assert F.shape == Tuple(m)
|
||||
assert F[i].subs(i, j) == F[j]
|
||||
raises(IndexException, lambda: F[i, j])
|
||||
|
||||
|
||||
def test_IndexedBase_assumptions():
|
||||
i = Symbol('i', integer=True)
|
||||
a = Symbol('a')
|
||||
A = IndexedBase(a, positive=True)
|
||||
for c in (A, A[i]):
|
||||
assert c.is_real
|
||||
assert c.is_complex
|
||||
assert not c.is_imaginary
|
||||
assert c.is_nonnegative
|
||||
assert c.is_nonzero
|
||||
assert c.is_commutative
|
||||
assert log(exp(c)) == c
|
||||
|
||||
assert A != IndexedBase(a)
|
||||
assert A == IndexedBase(a, positive=True, real=True)
|
||||
assert A[i] != Indexed(a, i)
|
||||
|
||||
|
||||
def test_IndexedBase_assumptions_inheritance():
|
||||
I = Symbol('I', integer=True)
|
||||
I_inherit = IndexedBase(I)
|
||||
I_explicit = IndexedBase('I', integer=True)
|
||||
|
||||
assert I_inherit.is_integer
|
||||
assert I_explicit.is_integer
|
||||
assert I_inherit.label.is_integer
|
||||
assert I_explicit.label.is_integer
|
||||
assert I_inherit == I_explicit
|
||||
|
||||
|
||||
def test_issue_17652():
|
||||
"""Regression test issue #17652.
|
||||
|
||||
IndexedBase.label should not upcast subclasses of Symbol
|
||||
"""
|
||||
class SubClass(Symbol):
|
||||
pass
|
||||
|
||||
x = SubClass('X')
|
||||
assert type(x) == SubClass
|
||||
base = IndexedBase(x)
|
||||
assert type(x) == SubClass
|
||||
assert type(base.label) == SubClass
|
||||
|
||||
|
||||
def test_Indexed_constructor():
|
||||
i, j = symbols('i j', integer=True)
|
||||
A = Indexed('A', i, j)
|
||||
assert A == Indexed(Symbol('A'), i, j)
|
||||
assert A == Indexed(IndexedBase('A'), i, j)
|
||||
raises(TypeError, lambda: Indexed(A, i, j))
|
||||
raises(IndexException, lambda: Indexed("A"))
|
||||
assert A.free_symbols == {A, A.base.label, i, j}
|
||||
|
||||
|
||||
def test_Indexed_func_args():
|
||||
i, j = symbols('i j', integer=True)
|
||||
a = symbols('a')
|
||||
A = Indexed(a, i, j)
|
||||
assert A == A.func(*A.args)
|
||||
|
||||
|
||||
def test_Indexed_subs():
|
||||
i, j, k = symbols('i j k', integer=True)
|
||||
a, b = symbols('a b')
|
||||
A = IndexedBase(a)
|
||||
B = IndexedBase(b)
|
||||
assert A[i, j] == B[i, j].subs(b, a)
|
||||
assert A[i, j] == A[i, k].subs(k, j)
|
||||
|
||||
|
||||
def test_Indexed_properties():
|
||||
i, j = symbols('i j', integer=True)
|
||||
A = Indexed('A', i, j)
|
||||
assert A.name == 'A[i, j]'
|
||||
assert A.rank == 2
|
||||
assert A.indices == (i, j)
|
||||
assert A.base == IndexedBase('A')
|
||||
assert A.ranges == [None, None]
|
||||
raises(IndexException, lambda: A.shape)
|
||||
|
||||
n, m = symbols('n m', integer=True)
|
||||
assert Indexed('A', Idx(
|
||||
i, m), Idx(j, n)).ranges == [Tuple(0, m - 1), Tuple(0, n - 1)]
|
||||
assert Indexed('A', Idx(i, m), Idx(j, n)).shape == Tuple(m, n)
|
||||
raises(IndexException, lambda: Indexed("A", Idx(i, m), Idx(j)).shape)
|
||||
|
||||
|
||||
def test_Indexed_shape_precedence():
|
||||
i, j = symbols('i j', integer=True)
|
||||
o, p = symbols('o p', integer=True)
|
||||
n, m = symbols('n m', integer=True)
|
||||
a = IndexedBase('a', shape=(o, p))
|
||||
assert a.shape == Tuple(o, p)
|
||||
assert Indexed(
|
||||
a, Idx(i, m), Idx(j, n)).ranges == [Tuple(0, m - 1), Tuple(0, n - 1)]
|
||||
assert Indexed(a, Idx(i, m), Idx(j, n)).shape == Tuple(o, p)
|
||||
assert Indexed(
|
||||
a, Idx(i, m), Idx(j)).ranges == [Tuple(0, m - 1), (None, None)]
|
||||
assert Indexed(a, Idx(i, m), Idx(j)).shape == Tuple(o, p)
|
||||
|
||||
|
||||
def test_complex_indices():
|
||||
i, j = symbols('i j', integer=True)
|
||||
A = Indexed('A', i, i + j)
|
||||
assert A.rank == 2
|
||||
assert A.indices == (i, i + j)
|
||||
|
||||
|
||||
def test_not_interable():
|
||||
i, j = symbols('i j', integer=True)
|
||||
A = Indexed('A', i, i + j)
|
||||
assert not iterable(A)
|
||||
|
||||
|
||||
def test_Indexed_coeff():
|
||||
N = Symbol('N', integer=True)
|
||||
len_y = N
|
||||
i = Idx('i', len_y-1)
|
||||
y = IndexedBase('y', shape=(len_y,))
|
||||
a = (1/y[i+1]*y[i]).coeff(y[i])
|
||||
b = (y[i]/y[i+1]).coeff(y[i])
|
||||
assert a == b
|
||||
|
||||
|
||||
def test_differentiation():
|
||||
from sympy.functions.special.tensor_functions import KroneckerDelta
|
||||
i, j, k, l = symbols('i j k l', cls=Idx)
|
||||
a = symbols('a')
|
||||
m, n = symbols("m, n", integer=True, finite=True)
|
||||
assert m.is_real
|
||||
h, L = symbols('h L', cls=IndexedBase)
|
||||
hi, hj = h[i], h[j]
|
||||
|
||||
expr = hi
|
||||
assert expr.diff(hj) == KroneckerDelta(i, j)
|
||||
assert expr.diff(hi) == KroneckerDelta(i, i)
|
||||
|
||||
expr = S(2) * hi
|
||||
assert expr.diff(hj) == S(2) * KroneckerDelta(i, j)
|
||||
assert expr.diff(hi) == S(2) * KroneckerDelta(i, i)
|
||||
assert expr.diff(a) is S.Zero
|
||||
|
||||
assert Sum(expr, (i, -oo, oo)).diff(hj) == Sum(2*KroneckerDelta(i, j), (i, -oo, oo))
|
||||
assert Sum(expr.diff(hj), (i, -oo, oo)) == Sum(2*KroneckerDelta(i, j), (i, -oo, oo))
|
||||
assert Sum(expr, (i, -oo, oo)).diff(hj).doit() == 2
|
||||
|
||||
assert Sum(expr.diff(hi), (i, -oo, oo)).doit() == Sum(2, (i, -oo, oo)).doit()
|
||||
assert Sum(expr, (i, -oo, oo)).diff(hi).doit() is oo
|
||||
|
||||
expr = a * hj * hj / S(2)
|
||||
assert expr.diff(hi) == a * h[j] * KroneckerDelta(i, j)
|
||||
assert expr.diff(a) == hj * hj / S(2)
|
||||
assert expr.diff(a, 2) is S.Zero
|
||||
|
||||
assert Sum(expr, (i, -oo, oo)).diff(hi) == Sum(a*KroneckerDelta(i, j)*h[j], (i, -oo, oo))
|
||||
assert Sum(expr.diff(hi), (i, -oo, oo)) == Sum(a*KroneckerDelta(i, j)*h[j], (i, -oo, oo))
|
||||
assert Sum(expr, (i, -oo, oo)).diff(hi).doit() == a*h[j]
|
||||
|
||||
assert Sum(expr, (j, -oo, oo)).diff(hi) == Sum(a*KroneckerDelta(i, j)*h[j], (j, -oo, oo))
|
||||
assert Sum(expr.diff(hi), (j, -oo, oo)) == Sum(a*KroneckerDelta(i, j)*h[j], (j, -oo, oo))
|
||||
assert Sum(expr, (j, -oo, oo)).diff(hi).doit() == a*h[i]
|
||||
|
||||
expr = a * sin(hj * hj)
|
||||
assert expr.diff(hi) == 2*a*cos(hj * hj) * hj * KroneckerDelta(i, j)
|
||||
assert expr.diff(hj) == 2*a*cos(hj * hj) * hj
|
||||
|
||||
expr = a * L[i, j] * h[j]
|
||||
assert expr.diff(hi) == a*L[i, j]*KroneckerDelta(i, j)
|
||||
assert expr.diff(hj) == a*L[i, j]
|
||||
assert expr.diff(L[i, j]) == a*h[j]
|
||||
assert expr.diff(L[k, l]) == a*KroneckerDelta(i, k)*KroneckerDelta(j, l)*h[j]
|
||||
assert expr.diff(L[i, l]) == a*KroneckerDelta(j, l)*h[j]
|
||||
|
||||
assert Sum(expr, (j, -oo, oo)).diff(L[k, l]) == Sum(a * KroneckerDelta(i, k) * KroneckerDelta(j, l) * h[j], (j, -oo, oo))
|
||||
assert Sum(expr, (j, -oo, oo)).diff(L[k, l]).doit() == a * KroneckerDelta(i, k) * h[l]
|
||||
|
||||
assert h[m].diff(h[m]) == 1
|
||||
assert h[m].diff(h[n]) == KroneckerDelta(m, n)
|
||||
assert Sum(a*h[m], (m, -oo, oo)).diff(h[n]) == Sum(a*KroneckerDelta(m, n), (m, -oo, oo))
|
||||
assert Sum(a*h[m], (m, -oo, oo)).diff(h[n]).doit() == a
|
||||
assert Sum(a*h[m], (n, -oo, oo)).diff(h[n]) == Sum(a*KroneckerDelta(m, n), (n, -oo, oo))
|
||||
assert Sum(a*h[m], (m, -oo, oo)).diff(h[m]).doit() == oo*a
|
||||
|
||||
|
||||
def test_indexed_series():
|
||||
A = IndexedBase("A")
|
||||
i = symbols("i", integer=True)
|
||||
assert sin(A[i]).series(A[i]) == A[i] - A[i]**3/6 + A[i]**5/120 + Order(A[i]**6, A[i])
|
||||
|
||||
|
||||
def test_indexed_is_constant():
|
||||
A = IndexedBase("A")
|
||||
i, j, k = symbols("i,j,k")
|
||||
assert not A[i].is_constant()
|
||||
assert A[i].is_constant(j)
|
||||
assert not A[1+2*i, k].is_constant()
|
||||
assert not A[1+2*i, k].is_constant(i)
|
||||
assert A[1+2*i, k].is_constant(j)
|
||||
assert not A[1+2*i, k].is_constant(k)
|
||||
|
||||
|
||||
def test_issue_12533():
|
||||
d = IndexedBase('d')
|
||||
assert IndexedBase(range(5)) == Range(0, 5, 1)
|
||||
assert d[0].subs(Symbol("d"), range(5)) == 0
|
||||
assert d[0].subs(d, range(5)) == 0
|
||||
assert d[1].subs(d, range(5)) == 1
|
||||
assert Indexed(Range(5), 2) == 2
|
||||
|
||||
|
||||
def test_issue_12780():
|
||||
n = symbols("n")
|
||||
i = Idx("i", (0, n))
|
||||
raises(TypeError, lambda: i.subs(n, 1.5))
|
||||
|
||||
|
||||
def test_issue_18604():
|
||||
m = symbols("m")
|
||||
assert Idx("i", m).name == 'i'
|
||||
assert Idx("i", m).lower == 0
|
||||
assert Idx("i", m).upper == m - 1
|
||||
m = symbols("m", real=False)
|
||||
raises(TypeError, lambda: Idx("i", m))
|
||||
|
||||
def test_Subs_with_Indexed():
|
||||
A = IndexedBase("A")
|
||||
i, j, k = symbols("i,j,k")
|
||||
x, y, z = symbols("x,y,z")
|
||||
f = Function("f")
|
||||
|
||||
assert Subs(A[i], A[i], A[j]).diff(A[j]) == 1
|
||||
assert Subs(A[i], A[i], x).diff(A[i]) == 0
|
||||
assert Subs(A[i], A[i], x).diff(A[j]) == 0
|
||||
assert Subs(A[i], A[i], x).diff(x) == 1
|
||||
assert Subs(A[i], A[i], x).diff(y) == 0
|
||||
assert Subs(A[i], A[i], A[j]).diff(A[k]) == KroneckerDelta(j, k)
|
||||
assert Subs(x, x, A[i]).diff(A[j]) == KroneckerDelta(i, j)
|
||||
assert Subs(f(A[i]), A[i], x).diff(A[j]) == 0
|
||||
assert Subs(f(A[i]), A[i], A[k]).diff(A[j]) == Derivative(f(A[k]), A[k])*KroneckerDelta(j, k)
|
||||
assert Subs(x, x, A[i]**2).diff(A[j]) == 2*KroneckerDelta(i, j)*A[i]
|
||||
assert Subs(A[i], A[i], A[j]**2).diff(A[k]) == 2*KroneckerDelta(j, k)*A[j]
|
||||
|
||||
assert Subs(A[i]*x, x, A[i]).diff(A[i]) == 2*A[i]
|
||||
assert Subs(A[i]*x, x, A[i]).diff(A[j]) == 2*A[i]*KroneckerDelta(i, j)
|
||||
assert Subs(A[i]*x, x, A[j]).diff(A[i]) == A[j] + A[i]*KroneckerDelta(i, j)
|
||||
assert Subs(A[i]*x, x, A[j]).diff(A[j]) == A[i] + A[j]*KroneckerDelta(i, j)
|
||||
assert Subs(A[i]*x, x, A[i]).diff(A[k]) == 2*A[i]*KroneckerDelta(i, k)
|
||||
assert Subs(A[i]*x, x, A[j]).diff(A[k]) == KroneckerDelta(i, k)*A[j] + KroneckerDelta(j, k)*A[i]
|
||||
|
||||
assert Subs(A[i]*x, A[i], x).diff(A[i]) == 0
|
||||
assert Subs(A[i]*x, A[i], x).diff(A[j]) == 0
|
||||
assert Subs(A[i]*x, A[j], x).diff(A[i]) == x
|
||||
assert Subs(A[i]*x, A[j], x).diff(A[j]) == x*KroneckerDelta(i, j)
|
||||
assert Subs(A[i]*x, A[i], x).diff(A[k]) == 0
|
||||
assert Subs(A[i]*x, A[j], x).diff(A[k]) == x*KroneckerDelta(i, k)
|
||||
|
||||
|
||||
def test_complicated_derivative_with_Indexed():
|
||||
x, y = symbols("x,y", cls=IndexedBase)
|
||||
sigma = symbols("sigma")
|
||||
i, j, k = symbols("i,j,k")
|
||||
m0,m1,m2,m3,m4,m5 = symbols("m0:6")
|
||||
f = Function("f")
|
||||
|
||||
expr = f((x[i] - y[i])**2/sigma)
|
||||
_xi_1 = symbols("xi_1", cls=Dummy)
|
||||
assert expr.diff(x[m0]).dummy_eq(
|
||||
(x[i] - y[i])*KroneckerDelta(i, m0)*\
|
||||
2*Subs(
|
||||
Derivative(f(_xi_1), _xi_1),
|
||||
(_xi_1,),
|
||||
((x[i] - y[i])**2/sigma,)
|
||||
)/sigma
|
||||
)
|
||||
assert expr.diff(x[m0]).diff(x[m1]).dummy_eq(
|
||||
2*KroneckerDelta(i, m0)*\
|
||||
KroneckerDelta(i, m1)*Subs(
|
||||
Derivative(f(_xi_1), _xi_1),
|
||||
(_xi_1,),
|
||||
((x[i] - y[i])**2/sigma,)
|
||||
)/sigma + \
|
||||
4*(x[i] - y[i])**2*KroneckerDelta(i, m0)*KroneckerDelta(i, m1)*\
|
||||
Subs(
|
||||
Derivative(f(_xi_1), _xi_1, _xi_1),
|
||||
(_xi_1,),
|
||||
((x[i] - y[i])**2/sigma,)
|
||||
)/sigma**2
|
||||
)
|
||||
|
||||
|
||||
def test_IndexedBase_commutative():
|
||||
t = IndexedBase('t', commutative=False)
|
||||
u = IndexedBase('u', commutative=False)
|
||||
v = IndexedBase('v')
|
||||
assert t[0]*v[0] == v[0]*t[0]
|
||||
assert t[0]*u[0] != u[0]*t[0]
|
||||
@@ -0,0 +1,13 @@
|
||||
from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead
|
||||
from sympy import I
|
||||
|
||||
def test_printing_TensMul():
|
||||
R3 = TensorIndexType('R3', dim=3)
|
||||
p, q = tensor_indices("p q", R3)
|
||||
K = TensorHead("K", [R3])
|
||||
|
||||
assert repr(2*K(p)) == "2*K(p)"
|
||||
assert repr(-K(p)) == "-K(p)"
|
||||
assert repr(-2*K(p)*K(q)) == "-2*K(p)*K(q)"
|
||||
assert repr(-I*K(p)) == "-I*K(p)"
|
||||
assert repr(I*K(p)) == "I*K(p)"
|
||||
2218
venv/lib/python3.12/site-packages/sympy/tensor/tests/test_tensor.py
Normal file
2218
venv/lib/python3.12/site-packages/sympy/tensor/tests/test_tensor.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
from sympy.tensor.tensor import (Tensor, TensorIndexType, TensorSymmetry,
|
||||
tensor_indices, TensorHead, TensorElement)
|
||||
from sympy.tensor import Array
|
||||
from sympy.core.symbol import Symbol
|
||||
|
||||
|
||||
def test_tensor_element():
|
||||
L = TensorIndexType("L")
|
||||
i, j, k, l, m, n = tensor_indices("i j k l m n", L)
|
||||
|
||||
A = TensorHead("A", [L, L], TensorSymmetry.no_symmetry(2))
|
||||
|
||||
a = A(i, j)
|
||||
|
||||
assert isinstance(TensorElement(a, {}), Tensor)
|
||||
assert isinstance(TensorElement(a, {k: 1}), Tensor)
|
||||
|
||||
te1 = TensorElement(a, {Symbol("i"): 1})
|
||||
assert te1.free == [(j, 0)]
|
||||
assert te1.get_free_indices() == [j]
|
||||
assert te1.dum == []
|
||||
|
||||
te2 = TensorElement(a, {i: 1})
|
||||
assert te2.free == [(j, 0)]
|
||||
assert te2.get_free_indices() == [j]
|
||||
assert te2.dum == []
|
||||
|
||||
assert te1 == te2
|
||||
|
||||
array = Array([[1, 2], [3, 4]])
|
||||
assert te1.replace_with_arrays({A(i, j): array}, [j]) == array[1, :]
|
||||
@@ -0,0 +1,464 @@
|
||||
from sympy import sin, cos
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.tensor.toperators import PartialDerivative
|
||||
from sympy.tensor.tensor import (TensorIndexType,
|
||||
tensor_indices,
|
||||
TensorHead, tensor_heads)
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.matrices.dense import diag
|
||||
from sympy.tensor.array import Array
|
||||
|
||||
from sympy.core.random import randint
|
||||
|
||||
|
||||
L = TensorIndexType("L")
|
||||
i, j, k, m, m1, m2, m3, m4 = tensor_indices("i j k m m1 m2 m3 m4", L)
|
||||
i0 = tensor_indices("i0", L)
|
||||
L_0, L_1 = tensor_indices("L_0 L_1", L)
|
||||
|
||||
A, B, C, D = tensor_heads("A B C D", [L])
|
||||
|
||||
H = TensorHead("H", [L, L])
|
||||
|
||||
|
||||
def test_invalid_partial_derivative_valence():
|
||||
raises(ValueError, lambda: PartialDerivative(C(j), D(-j)))
|
||||
raises(ValueError, lambda: PartialDerivative(C(-j), D(j)))
|
||||
|
||||
|
||||
def test_tensor_partial_deriv():
|
||||
# Test flatten:
|
||||
expr = PartialDerivative(PartialDerivative(A(i), A(j)), A(k))
|
||||
assert expr == PartialDerivative(A(i), A(j), A(k))
|
||||
assert expr.expr == A(i)
|
||||
assert expr.variables == (A(j), A(k))
|
||||
assert expr.get_indices() == [i, -j, -k]
|
||||
assert expr.get_free_indices() == [i, -j, -k]
|
||||
|
||||
expr = PartialDerivative(PartialDerivative(A(i), A(j)), A(i))
|
||||
assert expr.expr == A(L_0)
|
||||
assert expr.variables == (A(j), A(L_0))
|
||||
|
||||
expr1 = PartialDerivative(A(i), A(j))
|
||||
assert expr1.expr == A(i)
|
||||
assert expr1.variables == (A(j),)
|
||||
|
||||
expr2 = A(i)*PartialDerivative(H(k, -i), A(j))
|
||||
assert expr2.get_indices() == [L_0, k, -L_0, -j]
|
||||
|
||||
expr2b = A(i)*PartialDerivative(H(k, -i), A(-j))
|
||||
assert expr2b.get_indices() == [L_0, k, -L_0, j]
|
||||
|
||||
expr3 = A(i)*PartialDerivative(B(k)*C(-i) + 3*H(k, -i), A(j))
|
||||
assert expr3.get_indices() == [L_0, k, -L_0, -j]
|
||||
|
||||
expr4 = (A(i) + B(i))*PartialDerivative(C(j), D(j))
|
||||
assert expr4.get_indices() == [i, L_0, -L_0]
|
||||
|
||||
expr4b = (A(i) + B(i))*PartialDerivative(C(-j), D(-j))
|
||||
assert expr4b.get_indices() == [i, -L_0, L_0]
|
||||
|
||||
expr5 = (A(i) + B(i))*PartialDerivative(C(-i), D(j))
|
||||
assert expr5.get_indices() == [L_0, -L_0, -j]
|
||||
|
||||
|
||||
def test_replace_arrays_partial_derivative():
|
||||
|
||||
x, y, z, t = symbols("x y z t")
|
||||
|
||||
expr = PartialDerivative(A(i), B(j))
|
||||
repl = expr.replace_with_arrays({A(i): [sin(x)*cos(y), x**3*y**2], B(i): [x, y]})
|
||||
assert repl == Array([[cos(x)*cos(y), -sin(x)*sin(y)], [3*x**2*y**2, 2*x**3*y]])
|
||||
repl = expr.replace_with_arrays({A(i): [sin(x)*cos(y), x**3*y**2], B(i): [x, y]}, [-j, i])
|
||||
assert repl == Array([[cos(x)*cos(y), 3*x**2*y**2], [-sin(x)*sin(y), 2*x**3*y]])
|
||||
|
||||
# d(A^i)/d(A_j) = d(g^ik A_k)/d(A_j) = g^ik delta_jk
|
||||
expr = PartialDerivative(A(i), A(-j))
|
||||
assert expr.get_free_indices() == [i, j]
|
||||
assert expr.get_indices() == [i, j]
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, 1)}, [i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, -1)}, [i, j]) == Array([[1, 0], [0, -1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, 1)}, [i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, -1)}, [i, j]) == Array([[1, 0], [0, -1]])
|
||||
|
||||
expr = PartialDerivative(A(i), A(j))
|
||||
assert expr.get_free_indices() == [i, -j]
|
||||
assert expr.get_indices() == [i, -j]
|
||||
assert expr.replace_with_arrays({A(i): [x, y]}, [i, -j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, 1)}, [i, -j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, -1)}, [i, -j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, 1)}, [i, -j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, -1)}, [i, -j]) == Array([[1, 0], [0, 1]])
|
||||
|
||||
expr = PartialDerivative(A(-i), A(-j))
|
||||
assert expr.get_free_indices() == [-i, j]
|
||||
assert expr.get_indices() == [-i, j]
|
||||
assert expr.replace_with_arrays({A(-i): [x, y]}, [-i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, 1)}, [-i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(-i): [x, y], L: diag(1, -1)}, [-i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, 1)}, [-i, j]) == Array([[1, 0], [0, 1]])
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, -1)}, [-i, j]) == Array([[1, 0], [0, 1]])
|
||||
|
||||
expr = PartialDerivative(A(i), A(i))
|
||||
assert expr.get_free_indices() == []
|
||||
assert expr.get_indices() == [L_0, -L_0]
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, 1)}, []) == 2
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, -1)}, []) == 2
|
||||
|
||||
expr = PartialDerivative(A(-i), A(-i))
|
||||
assert expr.get_free_indices() == []
|
||||
assert expr.get_indices() == [-L_0, L_0]
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, 1)}, []) == 2
|
||||
assert expr.replace_with_arrays({A(i): [x, y], L: diag(1, -1)}, []) == 2
|
||||
|
||||
expr = PartialDerivative(H(i, j) + H(j, i), A(i))
|
||||
assert expr.get_indices() == [L_0, j, -L_0]
|
||||
assert expr.get_free_indices() == [j]
|
||||
|
||||
expr = PartialDerivative(H(i, j) + H(j, i), A(k))*B(-i)
|
||||
assert expr.get_indices() == [L_0, j, -k, -L_0]
|
||||
assert expr.get_free_indices() == [j, -k]
|
||||
|
||||
expr = PartialDerivative(A(i)*(H(-i, j) + H(j, -i)), A(j))
|
||||
assert expr.get_indices() == [L_0, -L_0, L_1, -L_1]
|
||||
assert expr.get_free_indices() == []
|
||||
|
||||
expr = A(j)*A(-j) + expr
|
||||
assert expr.get_indices() == [L_0, -L_0, L_1, -L_1]
|
||||
assert expr.get_free_indices() == []
|
||||
|
||||
expr = A(i)*(B(j)*PartialDerivative(C(-j), D(i)) + C(j)*PartialDerivative(D(-j), B(i)))
|
||||
assert expr.get_indices() == [L_0, L_1, -L_1, -L_0]
|
||||
assert expr.get_free_indices() == []
|
||||
|
||||
expr = A(i)*PartialDerivative(C(-j), D(i))
|
||||
assert expr.get_indices() == [L_0, -j, -L_0]
|
||||
assert expr.get_free_indices() == [-j]
|
||||
|
||||
|
||||
def test_expand_partial_derivative_sum_rule():
|
||||
tau = symbols("tau")
|
||||
|
||||
# check sum rule for D(tensor, symbol)
|
||||
expr1aa = PartialDerivative(A(i), tau)
|
||||
|
||||
assert expr1aa._expand_partial_derivative() == PartialDerivative(A(i), tau)
|
||||
|
||||
expr1ab = PartialDerivative(A(i) + B(i), tau)
|
||||
|
||||
assert (expr1ab._expand_partial_derivative() ==
|
||||
PartialDerivative(A(i), tau) +
|
||||
PartialDerivative(B(i), tau))
|
||||
|
||||
expr1ac = PartialDerivative(A(i) + B(i) + C(i), tau)
|
||||
|
||||
assert (expr1ac._expand_partial_derivative() ==
|
||||
PartialDerivative(A(i), tau) +
|
||||
PartialDerivative(B(i), tau) +
|
||||
PartialDerivative(C(i), tau))
|
||||
|
||||
# check sum rule for D(tensor, D(j))
|
||||
expr1ba = PartialDerivative(A(i), D(j))
|
||||
|
||||
assert expr1ba._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), D(j))
|
||||
expr1bb = PartialDerivative(A(i) + B(i), D(j))
|
||||
|
||||
assert (expr1bb._expand_partial_derivative() ==
|
||||
PartialDerivative(A(i), D(j)) +
|
||||
PartialDerivative(B(i), D(j)))
|
||||
|
||||
expr1bc = PartialDerivative(A(i) + B(i) + C(i), D(j))
|
||||
assert expr1bc._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), D(j))\
|
||||
+ PartialDerivative(B(i), D(j))\
|
||||
+ PartialDerivative(C(i), D(j))
|
||||
|
||||
# check sum rule for D(tensor, H(j, k))
|
||||
expr1ca = PartialDerivative(A(i), H(j, k))
|
||||
assert expr1ca._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), H(j, k))
|
||||
expr1cb = PartialDerivative(A(i) + B(i), H(j, k))
|
||||
assert (expr1cb._expand_partial_derivative() ==
|
||||
PartialDerivative(A(i), H(j, k))
|
||||
+ PartialDerivative(B(i), H(j, k)))
|
||||
expr1cc = PartialDerivative(A(i) + B(i) + C(i), H(j, k))
|
||||
assert (expr1cc._expand_partial_derivative() ==
|
||||
PartialDerivative(A(i), H(j, k))
|
||||
+ PartialDerivative(B(i), H(j, k))
|
||||
+ PartialDerivative(C(i), H(j, k)))
|
||||
|
||||
# check sum rule for D(D(tensor, D(j)), H(k, m))
|
||||
expr1da = PartialDerivative(A(i), (D(j), H(k, m)))
|
||||
assert expr1da._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), (D(j), H(k, m)))
|
||||
expr1db = PartialDerivative(A(i) + B(i), (D(j), H(k, m)))
|
||||
assert expr1db._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), (D(j), H(k, m)))\
|
||||
+ PartialDerivative(B(i), (D(j), H(k, m)))
|
||||
expr1dc = PartialDerivative(A(i) + B(i) + C(i), (D(j), H(k, m)))
|
||||
assert expr1dc._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), (D(j), H(k, m)))\
|
||||
+ PartialDerivative(B(i), (D(j), H(k, m)))\
|
||||
+ PartialDerivative(C(i), (D(j), H(k, m)))
|
||||
|
||||
|
||||
def test_expand_partial_derivative_constant_factor_rule():
|
||||
nneg = randint(0, 1000)
|
||||
pos = randint(1, 1000)
|
||||
neg = -randint(1, 1000)
|
||||
|
||||
c1 = Rational(nneg, pos)
|
||||
c2 = Rational(neg, pos)
|
||||
c3 = Rational(nneg, neg)
|
||||
|
||||
expr2a = PartialDerivative(nneg*A(i), D(j))
|
||||
assert expr2a._expand_partial_derivative() ==\
|
||||
nneg*PartialDerivative(A(i), D(j))
|
||||
|
||||
expr2b = PartialDerivative(neg*A(i), D(j))
|
||||
assert expr2b._expand_partial_derivative() ==\
|
||||
neg*PartialDerivative(A(i), D(j))
|
||||
|
||||
expr2ca = PartialDerivative(c1*A(i), D(j))
|
||||
assert expr2ca._expand_partial_derivative() ==\
|
||||
c1*PartialDerivative(A(i), D(j))
|
||||
|
||||
expr2cb = PartialDerivative(c2*A(i), D(j))
|
||||
assert expr2cb._expand_partial_derivative() ==\
|
||||
c2*PartialDerivative(A(i), D(j))
|
||||
|
||||
expr2cc = PartialDerivative(c3*A(i), D(j))
|
||||
assert expr2cc._expand_partial_derivative() ==\
|
||||
c3*PartialDerivative(A(i), D(j))
|
||||
|
||||
|
||||
def test_expand_partial_derivative_full_linearity():
|
||||
nneg = randint(0, 1000)
|
||||
pos = randint(1, 1000)
|
||||
neg = -randint(1, 1000)
|
||||
|
||||
c1 = Rational(nneg, pos)
|
||||
c2 = Rational(neg, pos)
|
||||
c3 = Rational(nneg, neg)
|
||||
|
||||
# check full linearity
|
||||
p = PartialDerivative(42, D(j))
|
||||
assert p and not p._expand_partial_derivative()
|
||||
|
||||
expr3a = PartialDerivative(nneg*A(i) + pos*B(i), D(j))
|
||||
assert expr3a._expand_partial_derivative() ==\
|
||||
nneg*PartialDerivative(A(i), D(j))\
|
||||
+ pos*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3b = PartialDerivative(nneg*A(i) + neg*B(i), D(j))
|
||||
assert expr3b._expand_partial_derivative() ==\
|
||||
nneg*PartialDerivative(A(i), D(j))\
|
||||
+ neg*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3c = PartialDerivative(neg*A(i) + pos*B(i), D(j))
|
||||
assert expr3c._expand_partial_derivative() ==\
|
||||
neg*PartialDerivative(A(i), D(j))\
|
||||
+ pos*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3d = PartialDerivative(c1*A(i) + c2*B(i), D(j))
|
||||
assert expr3d._expand_partial_derivative() ==\
|
||||
c1*PartialDerivative(A(i), D(j))\
|
||||
+ c2*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3e = PartialDerivative(c2*A(i) + c1*B(i), D(j))
|
||||
assert expr3e._expand_partial_derivative() ==\
|
||||
c2*PartialDerivative(A(i), D(j))\
|
||||
+ c1*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3f = PartialDerivative(c2*A(i) + c3*B(i), D(j))
|
||||
assert expr3f._expand_partial_derivative() ==\
|
||||
c2*PartialDerivative(A(i), D(j))\
|
||||
+ c3*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3g = PartialDerivative(c3*A(i) + c2*B(i), D(j))
|
||||
assert expr3g._expand_partial_derivative() ==\
|
||||
c3*PartialDerivative(A(i), D(j))\
|
||||
+ c2*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3h = PartialDerivative(c3*A(i) + c1*B(i), D(j))
|
||||
assert expr3h._expand_partial_derivative() ==\
|
||||
c3*PartialDerivative(A(i), D(j))\
|
||||
+ c1*PartialDerivative(B(i), D(j))
|
||||
|
||||
expr3i = PartialDerivative(c1*A(i) + c3*B(i), D(j))
|
||||
assert expr3i._expand_partial_derivative() ==\
|
||||
c1*PartialDerivative(A(i), D(j))\
|
||||
+ c3*PartialDerivative(B(i), D(j))
|
||||
|
||||
|
||||
def test_expand_partial_derivative_product_rule():
|
||||
# check product rule
|
||||
expr4a = PartialDerivative(A(i)*B(j), D(k))
|
||||
|
||||
assert expr4a._expand_partial_derivative() == \
|
||||
PartialDerivative(A(i), D(k))*B(j)\
|
||||
+ A(i)*PartialDerivative(B(j), D(k))
|
||||
|
||||
expr4b = PartialDerivative(A(i)*B(j)*C(k), D(m))
|
||||
assert expr4b._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), D(m))*B(j)*C(k)\
|
||||
+ A(i)*PartialDerivative(B(j), D(m))*C(k)\
|
||||
+ A(i)*B(j)*PartialDerivative(C(k), D(m))
|
||||
|
||||
expr4c = PartialDerivative(A(i)*B(j), C(k), D(m))
|
||||
assert expr4c._expand_partial_derivative() ==\
|
||||
PartialDerivative(A(i), C(k), D(m))*B(j) \
|
||||
+ PartialDerivative(A(i), C(k))*PartialDerivative(B(j), D(m))\
|
||||
+ PartialDerivative(A(i), D(m))*PartialDerivative(B(j), C(k))\
|
||||
+ A(i)*PartialDerivative(B(j), C(k), D(m))
|
||||
|
||||
|
||||
def test_eval_partial_derivative_expr_by_symbol():
|
||||
|
||||
tau, alpha = symbols("tau alpha")
|
||||
|
||||
expr1 = PartialDerivative(tau**alpha, tau)
|
||||
assert expr1._perform_derivative() == alpha * 1 / tau * tau ** alpha
|
||||
|
||||
expr2 = PartialDerivative(2*tau + 3*tau**4, tau)
|
||||
assert expr2._perform_derivative() == 2 + 12 * tau ** 3
|
||||
|
||||
expr3 = PartialDerivative(2*tau + 3*tau**4, alpha)
|
||||
assert expr3._perform_derivative() == 0
|
||||
|
||||
|
||||
def test_eval_partial_derivative_single_tensors_by_scalar():
|
||||
|
||||
tau, mu = symbols("tau mu")
|
||||
|
||||
expr = PartialDerivative(tau**mu, tau)
|
||||
assert expr._perform_derivative() == mu*tau**mu/tau
|
||||
|
||||
expr1a = PartialDerivative(A(i), tau)
|
||||
assert expr1a._perform_derivative() == 0
|
||||
|
||||
expr1b = PartialDerivative(A(-i), tau)
|
||||
assert expr1b._perform_derivative() == 0
|
||||
|
||||
expr2a = PartialDerivative(H(i, j), tau)
|
||||
assert expr2a._perform_derivative() == 0
|
||||
|
||||
expr2b = PartialDerivative(H(i, -j), tau)
|
||||
assert expr2b._perform_derivative() == 0
|
||||
|
||||
expr2c = PartialDerivative(H(-i, j), tau)
|
||||
assert expr2c._perform_derivative() == 0
|
||||
|
||||
expr2d = PartialDerivative(H(-i, -j), tau)
|
||||
assert expr2d._perform_derivative() == 0
|
||||
|
||||
|
||||
def test_eval_partial_derivative_single_1st_rank_tensors_by_tensor():
|
||||
|
||||
expr1 = PartialDerivative(A(i), A(j))
|
||||
assert expr1._perform_derivative() - L.delta(i, -j) == 0
|
||||
|
||||
expr2 = PartialDerivative(A(i), A(-j))
|
||||
assert expr2._perform_derivative() - L.metric(i, L_0) * L.delta(-L_0, j) == 0
|
||||
|
||||
expr3 = PartialDerivative(A(-i), A(-j))
|
||||
assert expr3._perform_derivative() - L.delta(-i, j) == 0
|
||||
|
||||
expr4 = PartialDerivative(A(-i), A(j))
|
||||
assert expr4._perform_derivative() - L.metric(-i, -L_0) * L.delta(L_0, -j) == 0
|
||||
|
||||
expr5 = PartialDerivative(A(i), B(j))
|
||||
expr6 = PartialDerivative(A(i), C(j))
|
||||
expr7 = PartialDerivative(A(i), D(j))
|
||||
expr8 = PartialDerivative(A(i), H(j, k))
|
||||
assert expr5._perform_derivative() == 0
|
||||
assert expr6._perform_derivative() == 0
|
||||
assert expr7._perform_derivative() == 0
|
||||
assert expr8._perform_derivative() == 0
|
||||
|
||||
expr9 = PartialDerivative(A(i), A(i))
|
||||
assert expr9._perform_derivative() - L.delta(L_0, -L_0) == 0
|
||||
|
||||
expr10 = PartialDerivative(A(-i), A(-i))
|
||||
assert expr10._perform_derivative() - L.delta(-L_0, L_0) == 0
|
||||
|
||||
|
||||
def test_eval_partial_derivative_single_2nd_rank_tensors_by_tensor():
|
||||
|
||||
expr1 = PartialDerivative(H(i, j), H(m, m1))
|
||||
assert expr1._perform_derivative() - L.delta(i, -m) * L.delta(j, -m1) == 0
|
||||
|
||||
expr2 = PartialDerivative(H(i, j), H(-m, m1))
|
||||
assert expr2._perform_derivative() - L.metric(i, L_0) * L.delta(-L_0, m) * L.delta(j, -m1) == 0
|
||||
|
||||
expr3 = PartialDerivative(H(i, j), H(m, -m1))
|
||||
assert expr3._perform_derivative() - L.delta(i, -m) * L.metric(j, L_0) * L.delta(-L_0, m1) == 0
|
||||
|
||||
expr4 = PartialDerivative(H(i, j), H(-m, -m1))
|
||||
assert expr4._perform_derivative() - L.metric(i, L_0) * L.delta(-L_0, m) * L.metric(j, L_1) * L.delta(-L_1, m1) == 0
|
||||
|
||||
def test_eval_partial_derivative_divergence_type():
|
||||
expr1a = PartialDerivative(A(i), A(i))
|
||||
expr1b = PartialDerivative(A(i), A(k))
|
||||
expr1c = PartialDerivative(L.delta(-i, k) * A(i), A(k))
|
||||
|
||||
assert (expr1a._perform_derivative()
|
||||
- (L.delta(-i, k) * expr1b._perform_derivative())).contract_delta(L.delta) == 0
|
||||
|
||||
assert (expr1a._perform_derivative()
|
||||
- expr1c._perform_derivative()).contract_delta(L.delta) == 0
|
||||
|
||||
expr2a = PartialDerivative(H(i, j), H(i, j))
|
||||
expr2b = PartialDerivative(H(i, j), H(k, m))
|
||||
expr2c = PartialDerivative(L.delta(-i, k) * L.delta(-j, m) * H(i, j), H(k, m))
|
||||
|
||||
assert (expr2a._perform_derivative()
|
||||
- (L.delta(-i, k) * L.delta(-j, m) * expr2b._perform_derivative())).contract_delta(L.delta) == 0
|
||||
|
||||
assert (expr2a._perform_derivative()
|
||||
- expr2c._perform_derivative()).contract_delta(L.delta) == 0
|
||||
|
||||
|
||||
def test_eval_partial_derivative_expr1():
|
||||
|
||||
tau, alpha = symbols("tau alpha")
|
||||
|
||||
# this is only some special expression
|
||||
# tested: vector derivative
|
||||
# tested: scalar derivative
|
||||
# tested: tensor derivative
|
||||
base_expr1 = A(i)*H(-i, j) + A(i)*A(-i)*A(j) + tau**alpha*A(j)
|
||||
|
||||
tensor_derivative = PartialDerivative(base_expr1, H(k, m))._perform_derivative()
|
||||
vector_derivative = PartialDerivative(base_expr1, A(k))._perform_derivative()
|
||||
scalar_derivative = PartialDerivative(base_expr1, tau)._perform_derivative()
|
||||
|
||||
assert (tensor_derivative - A(L_0)*L.metric(-L_0, -L_1)*L.delta(L_1, -k)*L.delta(j, -m)) == 0
|
||||
|
||||
assert (vector_derivative - (tau**alpha*L.delta(j, -k) +
|
||||
L.delta(L_0, -k)*A(-L_0)*A(j) +
|
||||
A(L_0)*L.metric(-L_0, -L_1)*L.delta(L_1, -k)*A(j) +
|
||||
A(L_0)*A(-L_0)*L.delta(j, -k) +
|
||||
L.delta(L_0, -k)*H(-L_0, j))).expand().doit() == 0
|
||||
|
||||
assert (vector_derivative.contract_metric(L.metric).contract_delta(L.delta) -
|
||||
(tau**alpha*L.delta(j, -k) + A(L_0)*A(-L_0)*L.delta(j, -k) + H(-k, j) + 2*A(j)*A(-k))).expand().doit() == 0
|
||||
|
||||
assert scalar_derivative - alpha*1/tau*tau**alpha*A(j) == 0
|
||||
|
||||
|
||||
def test_eval_partial_derivative_mixed_scalar_tensor_expr2():
|
||||
|
||||
tau, alpha = symbols("tau alpha")
|
||||
|
||||
base_expr2 = A(i)*A(-i) + tau**2
|
||||
|
||||
vector_expression = PartialDerivative(base_expr2, A(k))._perform_derivative()
|
||||
assert (vector_expression -
|
||||
(L.delta(L_0, -k)*A(-L_0) + A(L_0)*L.metric(-L_0, -L_1)*L.delta(L_1, -k))).expand().doit() == 0
|
||||
|
||||
scalar_expression = PartialDerivative(base_expr2, tau)._perform_derivative()
|
||||
assert scalar_expression == 2*tau
|
||||
Reference in New Issue
Block a user