索引对象#

Module that defines indexed objects.

班级 IndexedBaseIndexedIdx 表示矩阵元素 M[i, j] 如下图所示:

1) The Indexed class represents the entire indexed object.
           |
        ___|___
       '       '
        M[i, j]
       /   \__\______
       |             |
       |             |
       |     2) The Idx class represents indices; each Idx can
       |        optionally contain information about its range.
       |
 3) IndexedBase represents the 'stem' of an indexed object, here `M`.
    The stem used by itself is usually taken to represent the entire
    array.

索引对象上可以有任意数量的索引。这些基本对象中没有实现转换属性,但支持隐式压缩重复索引。

请注意,对复杂(即非原子)整数表达式作为索引的支持是有限的。(这应该在以后的版本中得到改进。)

实例#

为了表示上述矩阵元素示例,您可以写下:

>>> from sympy import symbols, IndexedBase, Idx
>>> M = IndexedBase('M')
>>> i, j = symbols('i j', cls=Idx)
>>> M[i, j]
M[i, j]

乘积中的重复索引意味着求和,因此要用索引对象表示矩阵向量积:

>>> x = IndexedBase('x')
>>> M[i, j]*x[j]
M[i, j]*x[j]

如果索引对象将转换为基于组件的数组,例如使用代码打印机或自动换行框架,则还需要提供(符号或数字)维度。这可以通过在构造时将可选形状参数传递给IndexedBase来完成:

>>> dim1, dim2 = symbols('dim1 dim2', integer=True)
>>> A = IndexedBase('A', shape=(dim1, 2*dim1, dim2))
>>> A.shape
(dim1, 2*dim1, dim2)
>>> A[i, j, 3].shape
(dim1, 2*dim1, dim2)

如果IndexedBase对象没有形状信息,则假定数组与其索引的范围一样大:

>>> n, m = symbols('n m', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', n)
>>> M[i, j].shape
(m, n)
>>> M[i, j].ranges
[(0, m - 1), (0, n - 1)]

以上可与以下内容进行比较:

>>> A[i, 2, j].shape
(dim1, 2*dim1, dim2)
>>> A[i, 2, j].ranges
[(0, m - 1), None, (0, n - 1)]

要分析索引表达式的结构,可以使用get_indexes()和get_constructure()方法:

>>> from sympy.tensor import get_indices, get_contraction_structure
>>> get_indices(A[i, j, j])
({i}, {})
>>> get_contraction_structure(A[i, j, j])
{(j,): {A[i, j, j]}}

有关输出的详细说明,请参阅相应的docstrings。

class sympy.tensor.indexed.Idx(label, range=None, **kw_args)[源代码]#

将整数索引表示为 Integer 或整数表达式。

有多种方法可以创建 Idx 对象。构造函数接受两个参数:

label

标记索引的整数或符号。

range

也可以将范围指定为

  • Symbol 或整数:这被解释为一个维度。下限和上限设置为 0range - 1 ,分别。

  • tuple :这两个元素分别解释为范围的下限和上限。

注意:范围的边界被假定为整数或无穷大(oo和-oo允许指定一个无界范围)。如果 n 是作为一个约束 n.is_integer 不能返回false。

为了方便起见,如果标签以字符串形式给出,则会自动转换为整数符号。(注意:对于范围或维度参数,不进行此转换。)

实例

>>> from sympy import Idx, symbols, oo
>>> n, i, L, U = symbols('n i L U', integer=True)

如果为标签指定字符串,则为整数 Symbol 和边界都是 None

>>> idx = Idx('qwerty'); idx
qwerty
>>> idx.lower, idx.upper
(None, None)

可以指定上限和下限:

>>> idx = Idx(i, (L, U)); idx
i
>>> idx.lower, idx.upper
(L, U)

当只给定一个边界时,它被解释为维度,下限默认为0:

>>> idx = Idx(i, n); idx.lower, idx.upper
(0, n - 1)
>>> idx = Idx(i, 4); idx.lower, idx.upper
(0, 3)
>>> idx = Idx(i, oo); idx.lower, idx.upper
(0, oo)
property label#

返回Idx对象的标签(整数或整数表达式)。

实例

>>> from sympy import Idx, Symbol
>>> x = Symbol('x', integer=True)
>>> Idx(x).label
x
>>> j = Symbol('j', integer=True)
>>> Idx(j).label
j
>>> Idx(j + 1).label
j + 1
property lower#

返回 Idx .

实例

>>> from sympy import Idx
>>> Idx('j', 2).lower
0
>>> Idx('j', 5).lower
0
>>> Idx('j').lower is None
True
property upper#

返回 Idx .

实例

>>> from sympy import Idx
>>> Idx('j', 2).upper
1
>>> Idx('j', 5).upper
4
>>> Idx('j').upper is None
True
class sympy.tensor.indexed.Indexed(base, *args, **kw_args)[源代码]#

表示具有索引的数学对象。

>>> from sympy import Indexed, IndexedBase, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j)
A[i, j]

建议 Indexed 通过索引创建对象 IndexedBaseIndexedBase('A')[i, j] 而不是 Indexed(IndexedBase('A'), i, j) .

>>> A = IndexedBase('A')
>>> a_ij = A[i, j]           # Prefer this,
>>> b_ij = Indexed(A, i, j)  # over this.
>>> a_ij == b_ij
True
property base#

返回 IndexedBaseIndexed 对象。

实例

>>> from sympy import Indexed, IndexedBase, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j).base
A
>>> B = IndexedBase('B')
>>> B == B[i, j].base
True
property indices#

返回 Indexed 对象。

实例

>>> from sympy import Indexed, Idx, symbols
>>> i, j = symbols('i j', cls=Idx)
>>> Indexed('A', i, j).indices
(i, j)
property ranges#

返回包含每个索引的下限和上限的元组列表。

如果索引没有定义上下数据成员,则列表中相应的槽包含 None 而不是元组。

实例

>>> from sympy import Indexed,Idx, symbols
>>> Indexed('A', Idx('i', 2), Idx('j', 4), Idx('k', 8)).ranges
[(0, 1), (0, 3), (0, 7)]
>>> Indexed('A', Idx('i', 3), Idx('j', 3), Idx('k', 3)).ranges
[(0, 2), (0, 2), (0, 2)]
>>> x, y, z = symbols('x y z', integer=True)
>>> Indexed('A', x, y, z).ranges
[None, None, None]
property rank#

返回 Indexed 对象。

实例

>>> from sympy import Indexed, Idx, symbols
>>> i, j, k, l, m = symbols('i:m', cls=Idx)
>>> Indexed('A', i, j).rank
2
>>> q = Indexed('A', i, j, k, l, m)
>>> q.rank
5
>>> q.rank == len(q.indices)
True
property shape#

返回包含每个索引的维度的列表。

维度是数组的属性,而不是索引的属性。不过,如果 IndexedBase 假定数组的形状不对应于数组的形状。

>>> from sympy import IndexedBase, Idx, symbols
>>> n, m = symbols('n m', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', m)
>>> A = IndexedBase('A', shape=(n, n))
>>> B = IndexedBase('B')
>>> A[i, j].shape
(n, n)
>>> B[i, j].shape
(m, m)
class sympy.tensor.indexed.IndexedBase(label, shape=None, *, offset=0, strides=None, **kw_args)[源代码]#

表示索引对象的基部或茎

IndexedBase类表示包含元素的数组。此类的主要用途是允许方便地创建索引类的对象。这个 __getitem__ 方法返回IndexedBase的实例。单独使用IndexedBase类,如果没有索引,就可以用作矩阵方程的表示法,类似于Symbol类的用法。但是,IndexedBase类添加了符号实例不可用的功能:

  • IndexedBase对象可以选择存储形状信息。可以使用numpy来检查数组和条件的一致性。(待办事项)

  • IndexedBase对象实现了语法糖,它允许使用重复索引的隐式求和来轻松地符号表示数组操作。

  • IndexedBase对象表示与数组等效的数学结构,在代码生成、自动编译和包装时也被认为是这样。

>>> from sympy.tensor import IndexedBase, Idx
>>> from sympy import symbols
>>> A = IndexedBase('A'); A
A
>>> type(A)
<class 'sympy.tensor.indexed.IndexedBase'>

当IndexedBase对象接收到索引时,它将返回一个带有命名轴的数组,该数组由索引对象表示:

>>> i, j = symbols('i j', integer=True)
>>> A[i, j, 2]
A[i, j, 2]
>>> type(A[i, j, 2])
<class 'sympy.tensor.indexed.Indexed'>

IndexedBase构造函数采用可选的形状参数。如果给定,它将覆盖索引中的任何形状信息。(但不是索引范围!)

>>> m, n, o, p = symbols('m n o p', integer=True)
>>> i = Idx('i', m)
>>> j = Idx('j', n)
>>> A[i, j].shape
(m, n)
>>> B = IndexedBase('B', shape=(o, p))
>>> B[i, j].shape
(o, p)

可以使用关键字参数指定假设,方法与Symbol相同:

>>> A_real = IndexedBase('A', real=True)
>>> A_real.is_real
True
>>> A != A_real
True

如果使用符号初始化IndexedBase,也可以继承假设:

>>> I = symbols('I', integer=True)
>>> C_inherit = IndexedBase(I)
>>> C_explicit = IndexedBase('I', integer=True)
>>> C_inherit == C_explicit
True
property label#

返回 IndexedBase 对象。

实例

>>> from sympy import IndexedBase
>>> from sympy.abc import x, y
>>> IndexedBase('A', shape=(x, y)).label
A
property offset#

返回 IndexedBase 对象。

这是当二维索引对象展开为1D形式时添加到结果索引中的值。用于代码生成。

实例

>>> from sympy.printing import ccode
>>> from sympy.tensor import IndexedBase, Idx
>>> from sympy import symbols
>>> l, m, n, o = symbols('l m n o', integer=True)
>>> A = IndexedBase('A', strides=(l, m, n), offset=o)
>>> i, j, k = map(Idx, 'ijk')
>>> ccode(A[i, j, k])
'A[l*i + m*j + n*k + o]'
property shape#

返回 IndexedBase 对象。

实例

>>> from sympy import IndexedBase, Idx
>>> from sympy.abc import x, y
>>> IndexedBase('A', shape=(x, y)).shape
(x, y)

注:如果是 IndexedBase 指定时,它将覆盖索引给定的任何形状信息。

>>> A = IndexedBase('A', shape=(x, y))
>>> B = IndexedBase('B')
>>> i = Idx('i', 2)
>>> j = Idx('j', 1)
>>> A[i, j].shape
(x, y)
>>> B[i, j].shape
(2, 1)
property strides#

返回 IndexedBase 对象。

通常,这是一个元组,表示遍历数组时在相应维度中要执行的步骤数。为了生成代码,还可以使用stripes='C'和stripes='F'。

streads='C'表示代码打印机将按行主顺序展开,“F”表示按列主要顺序展开。