График функции, DomainError. Возведение в степень, дающее сложный результат, требует сложного аргумента - PullRequest
0 голосов
/ 16 мая 2019

Фон

Я прочитал здесь , что метод Ньютона не работает в функции x^(1/3), когда его начальный шаг равен 1. Я пытаюсь проверить его в Джулии ЮпитерЗаписная книжка.

  1. Я хочу напечатать график функции x^(1/3)

  2. , затем я хочу запустить код

f = x->x^(1/3)
D(f) = x->ForwardDiff.derivative(f, float(x))
x = find_zero((f, D(f)),1, Roots.Newton(),verbose=true)

Проблема: Как распечатать диаграмму функции x^(1/3) в диапазоне, например. (-1,1)

Я пытался

f = x->x^(1/3)
plot(f,-1,1)

Я получил

enter image description here

Я изменил код на

f = x->(x+0im)^(1/3)
plot(f,-1,1)

Я получил

enter image description here

Я хочу, чтобы мой график выглядел как график x^(1/3) в Google enter image description here

Однако я могупечатать не более половины

enter image description here

Ответы [ 3 ]

1 голос
/ 16 мая 2019

Это потому, что x^(1/3) не всегда возвращает реальный (как в числах) результат или реальный корень куба x. Для отрицательных чисел функция возведения в степень с некоторыми степенями, такими как (1/3 или 1.254, и я предполагаю, что все нецелые числа) вернет Complex. Для требований стабильности типа в Юлии, эта операция, примененная к отрицательному Real, дает DomainError. Это поведение также отмечено в разделе Часто задаваемые вопросы руководства Юлии.

julia> (-1)^(1/3)
ERROR: DomainError with -1.0:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.

julia> Complex(-1)^(1/3)
0.5 + 0.8660254037844386im

Обратите внимание, что поведение возврата комплексного числа для возведения в степень отрицательных значений в действительности не отличается от, скажем, поведения MATLAB

>>> (-1)^(1/3)

ans =

0.5000 + 0.8660i

Однако вы хотите построить настоящий куб root.

Вы можете пойти с

plot(x -> x < 0 ? -(-x)^(1//3) : x^(1//3), -1, 1)

для принудительного применения реального корня куба или использования для этого встроенной функции cbrt.

plot(cbrt, -1, 1)

У него также есть псевдоним .

plot(∛, -1, 1)
1 голос
/ 16 мая 2019

F (x) - это нечетная функция , вы просто используете [0 1] в качестве входной переменной.

Сюжет на [-1 0] вычитается следующим образом enter image description here

код ниже

import numpy as np

import matplotlib.pyplot as plt

# Function f 
f = lambda x: x**(1/3)


fig, ax = plt.subplots()

x1 = np.linspace(0, 1, num = 100)
x2 = np.linspace(-1, 0, num = 100)
ax.plot(x1, f(x1))
ax.plot(x2, -f(x1[::-1]))


ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
plt.show()

Участок

enter image description here

1 голос
/ 16 мая 2019

Этот сюжет Google не имеет смысла для меня.Для x > 0 это нормально, но для отрицательных значений x правильный результат сложный, и на графике Google отображается отрицательное значение абсолютного значения , что странно.

Ниже вы можете увидеть вывод Matlab, который менее суетлив относительно типов, чем Джулия.Как вы можете видеть, это не соответствует вашему графику.

Plot of x^(1/3)

Из графика видно, что положительные значения x дают действительные значенияответ, в то время как отрицательный x дает комплексный ответ.Причина, по которой Джулия допускает отрицательные входные данные, заключается в том, что они очень заинтересованы в стабильности типов.Наличие выходного типа функции зависит от входного значения , что приведет к нестабильности типа, что вредит производительности.Это менее важно для Matlab или Python и т. Д.

Если вы хотите построить график, аналогичный приведенному выше в Julia, вы можете определить свою функцию следующим образом:

f = x -> sign(x) * abs(complex(x)^(1/3))

Редактировать: На самом деле, лучшая и более быстрая версия -

f = x -> sign(x) * abs(x)^(1/3)

Да, это выглядит неловко, но это потому, что вам нужен действительно странный сюжет, который не имеет смысла для функции x^(1/3).

...