函数图,DomainError。产生复数结果的求幂需要复数参数

Plot of function, DomainError. Exponentiation yielding a complex result requires a complex argument

背景

我读到 here 当初始步骤为 1 时,牛顿方法在函数 x^(1/3) 上失败。我想在 julia jupyter notebook 中测试它。

  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)

我得到了

我将代码更改为

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

我得到了

我希望我的情节看起来像 google 中 x^(1/3) 的情节

However I can not print more than a half of it

那个Google情节对我来说毫无意义。对于 x > 0 没问题,但对于 x 的负值,正确的结果很复杂,Google 图似乎显示了 绝对值的负数 ,这很奇怪。

下面你可以看到 Matlab 的输出,它对类型没有 Julia 那么挑剔。如您所见,它与您的情节不符。

从图中可以看出,正 x 值给出 real-valued 答案,而负 x 给出 complex-valued 答案。 Julia 错误输入负数的原因是他们非常关注类型稳定性。让函数的输出类型取决于输入 value 会导致类型不稳定,从而损害性能。这对 Matlab 或 Python 等来说不太重要

如果你想在 Julia 中绘制类似上面的图,你可以这样定义你的函数:

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

编辑:实际上,更好更快的版本是

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

是的,它看起来很尴尬,但那是因为你想要一个非常奇怪的情节,恕我直言,这对函数 x^(1/3).

毫无意义

那是因为 x^(1/3) 并不总是 return 一个真实的(如数字)结果或 x 的真实立方根。对于负数,具有某些幂(1/3 或 1.254,我想所有 non-integers)的幂函数将 return 和 Complex。对于 Julia 中的 type-stability 要求,此操作应用于负数 Real 会得到 DomainError。在 Julia 手册的 Frequently Asked Questions 部分中也记录了此行为。

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

请注意,return对负值求幂的复数的行为与 MATLAB 的行为

并没有什么不同
>>> (-1)^(1/3)

ans =

0.5000 + 0.8660i

然而,您想要的是绘制真正的立方体根。

你可以选择

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

强制执行真正的立方根或使用 built-in cbrt 函数代替。

plot(cbrt, -1, 1)

它还有一个别名

plot(∛, -1, 1)

F(x) 是一个奇函数,你只需使用[0 1] 作为输入变量。

[-1 0]剧情推演如下

代码如下

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()

情节