我需要将以下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的符号工具箱。
答案 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