SymPy中是否有类似于np.ix_的函数?

时间:2019-08-26 14:25:36

标签: sympy

我需要将以下MATLAB代码转换为SymPy,但我找不到简单直接的答案:

syms E A L P

long = [L;  L/2;  L/3];

LaG = [1 3
       2 3
       3 4];

k = E.*A./long;

K = sym(zeros(4));
for e = 1:3       
   idx = LaG(e,:);
   K(idx,idx) = K(idx,idx) + k(e)*[1 -1; -1 1]; 
end;

但是,我在SymPy中找不到像NumPy的np.ix_()这样的命令。没有这个,我的代码看起来会太复杂,而且由于我的许多代码都依赖于ix_()函数,因此我在整个课程中都不得不使用MATLAB的符号工具箱。

2 个答案:

答案 0 :(得分:0)

尽管在示例中未显示使用ix_,但np doc page建议使用SymPy extract矩阵方法来做到这一点:

    >>> m
    Matrix([
    [0,  1,  2],
    [3,  4,  5],
    [6,  7,  8],
    [9, 10, 11]])
    >>> e = [0, 1, 3], [0, 1]
    >>> m.extract(*e)
    Matrix([
    [0,  1],
    [3,  4],
    [9, 10]])

如果要将结果放入矩阵的连续子区域中,则可以

>>> m[:2, :2] = eye(2)

我不知道将另一个矩阵放入不连续区域的方法,但是可以定义这样的例程:

>>> m = Matrix(4,3,range(12))
>>> def assign(self, m, a, b):
...   assert len(a)*len(b) == len(m)
...   k = 0
...   for i in a:
...     for j in b:
...       self[i, j] = m[k]
...       k += 1
...
>>> n=eye(4)
>>> assign(n, m.extract(*e), *e); n
Matrix([
[0,  1, 0, 0],
[3,  4, 0, 0],
[0,  0, 1, 0],
[9, 10, 0, 1]])

答案 1 :(得分:0)

由于没有sympy.ix_()(或等效功能),我可以使用以下代码解决问题:

import numpy as np
import sympy as sp

def ensamblar(K, idx, Ke):
    ''' Ensambla la matriz de rigidez local Ke en la matriz de rigidez global K

    Uso:
    ensamblar(K, idx, Ke)

    Parametros de entrada:
    K   -> matriz de rigidez global
    idx -> grados de libertad donde debe proceder el ensamblaje
    Ke  -> matriz de rigidez local
    '''

    # se verifican las dimensiones de las matrices
    nfil, ncol = K.shape
    assert nfil == ncol, "La matriz de rigidez K debe ser cuadrada"

    nfil, ncol = Ke.shape
    assert nfil == ncol == len(idx),\
            "Ke debe ser cuadrada y debe tener el mismo número de filas que idx"

    # se procede con el ensamblaje
    for i in range(nfil):
        for j in range(ncol):
            K[idx[i], idx[j]] += Ke[i,j]

# %% defino las variables
E, A, L, P = sp.symbols('E A L P')         # define las variables simbolicas

long = [L,  L,  L/2]                       # longitud de la barra

# LaG: local a global: matriz que relaciona nodos locales y globales
# (se lee la barra x va del nodo i al nodo j)
LaG = np.array([[1, 3],         # fila = barra
                [2, 3],         # col1 = nodo global asociado a nodo local 1
                [3, 4]]) - 1    # col2 = nodo global asociado a nodo local 2

k = [E*A/longitud for longitud in long]    # (k minuscula) rigidez de cada barra

# %% ensamblo la matriz de rigidez global (K mayuscula)
K = sp.zeros(4)       # separa memoria para matriz de rigidez global K
for e in range(3):    # para cada una de las barras e = 1, 2 y 3
   idx = LaG[e,:]     # extrae indices de los nodos globales de la barra e
   Ke  = k[e]*np.array([[1, -1],[-1, 1]])  # matriz de rigidez local
   ensamblar(K, idx, Ke)                   # ensamblaje matricial