2
votes

This is the correct graph of x^(1/3):

Normal graph of x^(1/3)

However, when trying to plot x**(1./3) on gnuplot, this is what I get:

Graph of x^(1/3) using gnuplot

How can I fix this?

Additionally, it is not the first time that gnuplot doesn't plot values around zero in other functions (when it is supposed to, of course: I'm not talking about asymptotes etc.). What can I do?

2
Can you provide your code? See How to Ask for more information. - ChristianYami
@ChristianYami Sure, this is the command I used: plot x**(1./3) As you can see, I included a dot after 1. If I don't do that, gnuplot won't perform the division. - Johann

2 Answers

5
votes

The reason why your graph is not drawn closer to zero is because there is a default sampling of 100, i.e. your function will be plotted with 100 points within your xrange. If you increase this number, this will get you closer to zero. Check help samples.

About the missing negative values, this seems to be a bit special in gnuplot. I guess x**b where b is a floating point number is special. You can test the examples:

print sqrt(4)
print 4**0.5
print sqrt(-4)
print (-4)**0.5
print 8**(1./3)
print (-8)**(1./3)

which will give:

2.0
2.0
{0.0, 2.0}
{1.22460635382238e-16, 2.0}   # rounding error {0.0, 2.0}
2.0
{1.0, 1.73205080756888}       # 1 out of 3 valid solutions, but not the expected -2

Values in {Re, Im} are imaginary numbers. First the real part then the imaginary part. In order to get your plot nevertheless you can try the following:

Code:

### cube root
reset session

set samples 500
set grid xtics, ytics

cuberoot(x) = sgn(x)*abs(x)**(1./3)

plot cuberoot(x) w l
### end of code

Result:

enter image description here

Addition:

I'll try to explain, but I'm not a mathematician. For the N-th root there are N solutions. Apparently, gnuplot takes one of them. Apparently, one with a positive real part, and if there are several, the one with the smallest positive imaginary part. I guess it is called "principal root". Check also this.

So, this will explain why

print (-8)**(1./3)
print (-8)**(1./9)  # 9th root

will return

{1.0, 1.73205}          # and not -2
{1.18393, 0.4309183}    # and not -1.25992

Code:

### roots
reset session

set size ratio -1
set xlabel "real part"
set xrange [-3:3]
set ylabel "imaginary part"
set yrange [-3:3]
set grid xtics, ytics

set angle degrees
NRootRe(x,N,i) = -sgn(x)*abs(x)**(1./N)*cos(360.*i/N - 180*sgn(x))
NRootIm(x,N,i) = -sgn(x)*abs(x)**(1./N)*sin(360.*i/N - 180*sgn(x))

x = -8
do for [N=3:9:2] {
    do for [i=1:N] {
        print sprintf('x=%g, N=%g, i=%g: {% 9g, % 9g}',x,N,i,NRootRe(x,N,i), NRootIm(x,N,i))
    }
    print ""
}

plot for [N=3:9:2] [i=1:N:1] '+' u (0):(0):(NRootRe(x,N,i)):(NRootIm(x,N,i)) w vec ti sprintf("x=%g, N=%g",x,N)
### end of code

Result:

x=-8, N=3, i=1: {        1,  -1.73205}
x=-8, N=3, i=2: {        1,   1.73205}
x=-8, N=3, i=3: {       -2,  7.34764e-16}

x=-8, N=5, i=1: {-0.468382,  -1.44153}
x=-8, N=5, i=2: {  1.22624, -0.890916}
x=-8, N=5, i=3: {  1.22624,  0.890916}
x=-8, N=5, i=4: {-0.468382,   1.44153}
x=-8, N=5, i=5: { -1.51572,  5.56847e-16}

x=-8, N=7, i=1: {-0.839155,  -1.05227}
x=-8, N=7, i=2: { 0.299491,  -1.31216}
x=-8, N=7, i=3: {  1.21261, -0.583964}
x=-8, N=7, i=4: {  1.21261,  0.583964}
x=-8, N=7, i=5: { 0.299491,   1.31216}
x=-8, N=7, i=6: {-0.839155,   1.05227}
x=-8, N=7, i=7: {  -1.3459,  4.94459e-16}

x=-8, N=9, i=1: {-0.965156, -0.809862}
x=-8, N=9, i=2: {-0.218783,  -1.24078}
x=-8, N=9, i=3: { 0.629961,  -1.09112}
x=-8, N=9, i=4: {  1.18394, -0.430918}
x=-8, N=9, i=5: {  1.18394,  0.430918}
x=-8, N=9, i=6: { 0.629961,   1.09112}
x=-8, N=9, i=7: {-0.218783,   1.24078}
x=-8, N=9, i=8: {-0.965156,  0.809862}
x=-8, N=9, i=9: { -1.25992,  4.62872e-16}

enter image description here

3
votes

The cube root of x for x < 0 is a surface of complex values. Gnuplot cannot easily plot that. The plot you show is presumably for

f(x) = sgn(x) * abs(x)**(1./3) 

which is the intersection of that complex surface with the plane Imag(z) = 0. (Edit: see supplementary figures).

An alternative plot that makes intuitive sense is to plot x as the cube of y.

plot [t=-2:2] (t**3):(t) with lines

enter image description here

Supplementary figures

Figure 1) The first figure shows why the 'simple' root that lies along the negative real axis is undesireable because it runs along a discontinuity in the imaginary component of the complex surface.

set title "Discontinuous imaginary component along negative real axis"
set yrange [-.1:.1]
set xrange [-10:10]
set xlabel "Real"
set ylabel "Imaginary"
set xyplane 0
set grid x y z vertical

f(x,y) = (x + I*y) ** (1./3)

splot real(f(x,y)), imag(f(x,y)), abs(f(x,y)), \
      [-10:10] '+' using (x):(0):(sgn(x)*abs(x)**(1./3)) with lines lt -1 lw 2 title "cuberoot(x)"

enter image description here

Figure 2 This figure shows the complex surface of solutions to the equation (Z)**(1/3). For each plane of constant Z the solutions lie on three curves. I stacked the curves generated for sequential samples along Z to generate the surface. The heavy black line is the 'simple' cuberoot(Z) limited to real values, i.e. the same line as in Figure 1 and requested in the original question. The green line is the complex value returned by gnuplot for Z**(1./3). For positive Z the two curves are the same. For negative Z they lie on different regions of the complex surface. I have confirmed that gnuplot's complex power function and the C library function cpow both return values from the same region of the surface. enter image description here