Mathews24 Mathews24 - 3 months ago 8x
Python Question

Numpy linspace unexpected output

I am running the code below to build a one-dimensional array for each z and t. At the present moment, I am trying to make their sizes equivalent so that they each have a length of 501.

import numpy as np

#constants & parameters
omega = 1.
eps = 1.
c = 3.*(10.**8.)
hbar = 1.
eta = 0.01
nn = 10.**7.
n = eta*nn

lambdaOH = c/(1612.*10.**(6.))
gamma = 1.282*(10.**(-11.))
Tsp = 1./gamma
TR = 604800.
L = (Tsp/TR)*(np.pi)/((3.*(lambdaOH**2.))*n)

Ngridt = 500.
tmax = 1.
dt = tmax/Ngridt
intervalt = tmax/dt + 1
t = np.linspace(0.01,tmax,intervalt)

#z space
Ngridz = 500.
zmax = L
dz = zmax/Ngridz
intervalz = zmax/dz + 1
z = np.linspace(0.01,zmax,intervalz)

When running the code, both intervalt and intervalz equal 501.0, but when checking the length of both z and t, len(z) = 500 while len(t) = 501. I have played around with the code above to yield len(z) = 501 by modifying certain parts. For example, if I insert the code

zmax = int(zmax)

then len(z) = 501. But I am wondering why the initial code, exactly as written, does not yield an array z with length 501?

(I am using Python 2.7.)


It is a problem of rounding. If you try to subtract 501 from intervalz you will find a very small negative number, -5.68e-14; linspace just takes the integer part of it, that is 500, and provides a 500-long list.

Notice two other problems with your code:

  1. dt does not provide the correct spacing because you don't remove the initial t (same for dz)
  2. Ngridt and Ngridz are conceptually integers, while you initialize them as floats. Just remove the dot at the end.

I think that your code could be simplified by writing (notice that Ngridt and Ngridz are initialized to 501)

Ngridt = 501
tmax = 1. 
t, dt = np.linspace(0.01,tmax,Ngridt,retstep=True)

#z space
Ngridz = 501
zmax = L
z, dz = np.linspace(0.01,zmax,Ngridz,retstep=True)