Отсутствие abs
не просто для того, чтобы "все было просто". Как написал ведущий разработчик SymPy ,
SymPy не возвращает log(abs(x))
для integrate(1/x)
, поскольку оно недопустимо для комплексных чисел. Вместо этого ответ является правильным вплоть до константы интегрирования (которая может быть сложной). Все операции SymPy предполагают, что переменные являются сложными по умолчанию.
Остальная часть связанной проблемы также относится к вашему вопросу. С определенной точки зрения, log(cos(x) - 1)
: так же действителен, как и log(1 - cos(x))
в результате интегрирования: разница между этими двумя выражениями равна I*pi
, которая поглощается константой интегрирования. Кроме того, cos(x)
может быть больше 1 для комплексного x, например cos(I) = 1.54...
Тем не менее, следующий способ заставить постоянный член в логах быть неотрицательным.
def fix_logs(expr):
replacements = {}
for a in expr.atoms(log):
if a.args[0].as_coeff_add()[0].is_negative:
replacements[a] = log(-a.args[0]) + log(-1)
return expr.xreplace(replacements)
Вот как это работает:
rv = integrate(cos(x)**2/sin(x), x)
rv2 = fix_logs(rv)
rv3 = Add(*fix_logs(rv2).as_coeff_add(x)[1])
Здесь rv, rv2 и rv3:
log(cos(x) - 1)/2 - log(cos(x) + 1)/2 + cos(x)
log(-cos(x) + 1)/2 - log(cos(x) + 1)/2 + cos(x) + I*pi/2
log(-cos(x) + 1)/2 - log(cos(x) + 1)/2 + cos(x)
Функция fix_logs
не удаляет часть журнала (-1), поскольку это может быть важно: x*log(x-1)
становится x*(log(1-x) + I*pi/2)
, где константа не может быть просто отброшена. Но при желании аддитивную константу можно удалить, как показано в расчете rv3
.
Ссылка для as_coeff_add
метода