проблема с неявными графиками с абсолютными функциями - PullRequest
1 голос
/ 11 января 2020

Я транскрибирую код с Mathematica на Python (я использую spyder). Однако при построении графика я не могу получить график, похожий на этот:

desired plot

Код выдает:

plot from the code

import numpy as np
import sympy as sym


nc=1.772
c=3e10
L=0.3
R=3.0
lbd=775e-7
d = sym.Symbol ('d')
rep = sym.Symbol ('rep')

M1=np.array([[1,(L/2)],[0,1]]) #espessura_cristal

M2=np.array([[1,0],[0,(1/nc)]]) #ar_cristal 

M3=sym.Matrix ([[1,(d/2)-L/2],[0,1]]) #dis_cristal_esp
#print M3
M4=np.array([[1,0],[(-2/R),1]]) #espelho 

M5= sym.Matrix ([[1,(c/rep)-d],[0,1]]) #comp_cavidade
#print M5
M6=np.array([[1,0],[0,nc]]) #cristal_ar 


M = sym.Matrix(M1*M2*M3*M4*M5*M4*M3*M6*M1)

est = sym.Eq(((M[0,0]+M[1,1])**2),4.0)

sol=sym.solve(est)
print sol

sym.plot_implicit(est,(rep,0.1,1),(d,1,10))

Что я делаю не так?

1 Ответ

1 голос
/ 13 января 2020

Во-первых, numpy и sympy не очень хорошо сочетаются. Sympy не знает о функциях numpy, а numpy не понимает символов sympy. Итак, лучше всего выполнить все вычисления Symboli c в Sympy. И, наконец, lambdify может преобразовать выражения sympy в numpy функции.

Вы можете немного помочь sympy, указав больше информации о переменных, например, зная, что positive=True может помочь упростить квадратные корни .

Что касается черчения, то есть некоторые дополнения к sympy для быстрого показа сюжета. Но они довольно ограничены в возможностях, особенно если вы хотите 3D-графики. Для трехмерных графиков matplotlib - это пакет goto, а numpy - предпочтительный способ представления функций и данных. Тем более, что у ваших функций огромный диапазон чисел.

Обратите внимание, что solve(est) без дополнительных уточнений решает для d как функцию rep. Назовите его как solve(est, rep), если вам нужно rep как функция d.

В приведенном ниже коде все функции numpy во время пути symboli c изменены на функции sympy. Затем lambdify используется для создания трехмерного графика поверхности с помощью matplotlib. Обратите внимание, что lambdify не может обрабатывать уравнение напрямую, но его нужно переписать как left-hand-side - right-hand-side.

(в этом коде используется Python 3. Единственное отличие состоит в том, что для печати нужны скобки. Если нет важных причина использования Python 2, так как с 2020 года очень рекомендуется перейти на Python 3.)

import sympy as sym

nc = 1.772
c = 3e10
L = 0.3
R = 3.0
lbd = 775e-7
d = sym.Symbol('d', real=True, positive=True, nonzero=True)
rep = sym.Symbol('rep', real=True, positive=True, nonzero=True)

M1 = sym.Matrix([[1, (L / 2)], [0, 1]])  # espessura_cristal
M2 = sym.Matrix([[1, 0], [0, (1 / nc)]])  # ar_cristal
M3 = sym.Matrix([[1, (d / 2) - L / 2], [0, 1]])  # dis_cristal_esp
M4 = sym.Matrix([[1, 0], [(-2 / R), 1]])  # espelho
M5 = sym.Matrix([[1, (c / rep) - d], [0, 1]])  # comp_cavidade
M6 = sym.Matrix([[1, 0], [0, nc]])  # cristal_ar

M = sym.Matrix(M1 * M2 * M3 * M4 * M5 * M4 * M3 * M6 * M1)

est = sym.Eq(((M[0, 0] + M[1, 1]) ** 2), 4.0 )

sol = sym.solve(est, rep)
print("sol:", sol)
print("est:", est)

# sym.plot_implicit(est, (rep, 0.1, 1), (d, 1, 10))

est_np = sym.lambdify((rep, d), (est.lhs - est.rhs).simplify(), "numpy")

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits import mplot3d

rep_np, d_np = np.meshgrid(np.linspace(0.1, 1, 200), np.linspace(1, 10, 200))

fig = plt.figure()
ax = plt.axes(projection='3d')
Z = est_np(rep_np, d_np)
ax.plot_surface(rep_np, d_np, Z, rstride=1, cstride=1, cmap='plasma', edgecolor='none')
ax.set_xlabel('rep')
ax.set_ylabel('d')
ax.set_zlabel('est')
plt.show()

resulting plot

Во время пребывания в Однако вы можете построить 4 решения следующим образом (после вызова sol = sym.solve(est, d)):

plots = []
for i, s in enumerate(sol):
    plots.append(sym.plot(s, xlim=(.001, 1), xlabel='rep', ylabel='d', title='solution '+ str(i+1), show=False))
sym.plotting.PlotGrid(2, len(sol)//2, *plots)

the four solutions

Первые два решения выглядят как очень похоже на sym.plot_implicit вопроса. Последние два решения получают огромные значения для d. Может быть, это не реальные решения, но из-за проблем с округлением?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...