sympy's plot_parametric говорит, что TypeError: не может преобразовать сложное в float - PullRequest
0 голосов
/ 30 сентября 2018

Я хочу построить кривую, которая на самом деле имеет форму S:

  1. Нарисуйте круг
  2. Переместите нижнюю часть полукруга на расстояние полного диаметра

но код гласит TypeError: can't convert complex to float.Где комплексное число?как это исправить?Спасибо

import sympy as sp
from sympy.plotting import *

u = sp.Symbol('u', real=True)
R0 = 2
boundLower = 0
boundUpper = 2 * sp.pi

x_u = sp.Piecewise(
    (R0*sp.cos(u)+R0, sp.And(boundLower <= u, u <= boundUpper/2)),
    (R0*sp.cos(u)+3*R0, sp.And(boundUpper/2 < u, u <= boundUpper)),
)

y_u = sp.Piecewise(
    (R0*sp.sin(u), sp.And(boundLower <= u,  u <= boundUpper/2)),
    (R0*sp.sin(u), sp.And(boundUpper/2 < u, u <= boundUpper)),
)

plot_parametric(x_u, y_u, (u, boundLower, boundUpper))

1 Ответ

0 голосов
/ 30 сентября 2018

SymPy plot включает в себя некоторые подверженные ошибкам манипуляции, предназначенные для повышения производительности графиков;они включают complex тип данных, который иногда приводит к ошибкам при наличии неравенства.Уменьшение числа неравенств помогает в этом случае:

x_u = sp.Piecewise(
    (R0*sp.cos(u)+R0, u <= boundUpper/2),
    (R0*sp.cos(u)+3*R0, u <= boundUpper),
)

y_u = sp.Piecewise(
    (R0*sp.sin(u), u <= boundUpper/2),
    (R0*sp.sin(u), u <= boundUpper),
)

plot_parametric(x_u, y_u, (u, boundLower, boundUpper))

Выше показано, как Piecewise обычно представлен в SymPy: условия оцениваются в указанном порядке, и первое из них должно быть True, что приводит к оценкесоответствующее выражение.(Кстати, u <= boundUpper можно заменить на True.) Результат:

piecewise

Это все еще не идеально.Горизонтальной линии от 0 до 4, конечно, быть не должно - это артефакт построения.Кроме того, этот код отображает

UserWarning: Оценка выражения является проблематичной.Мы пробуем метод восстановления, который все еще может работать.Пожалуйста, сообщите об этом как об ошибке.

Я предлагаю избегать Кусочек при построении.Вместо этого объедините график из кусочков, используя extend, как показано ниже.

x_u1 = R0*sp.cos(u)+R0
x_u2 = R0*sp.cos(u)+3*R0

y_u1 = R0*sp.sin(u)
y_u2 = R0*sp.sin(u)

p = plot_parametric(x_u1, y_u1, (u, boundLower, boundUpper/2), show=False)
p.extend(plot_parametric(x_u2, y_u2, (u, boundUpper/2, boundUpper), show=False))
p.show()

Вывод (без предупреждений и артефактов).

better

...