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,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]

View File

@ -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])}}

View File

@ -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]

View File

@ -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)"

File diff suppressed because it is too large Load Diff

View File

@ -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, :]

View File

@ -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() == 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() == 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() == 0
scalar_expression = PartialDerivative(base_expr2, tau)._perform_derivative()
assert scalar_expression == 2*tau