0

This is a part of my code

import numpy as np 

import matplotlib.pyplot as plt

plt.style.use('ggplot')

import statistics as st



N = 2000 #tamaño de la señal

a = 1 #valor de la cte del proceso


time1 = np.arange(0.0, 0.2, 0.0005)

time2 = np.arange(0.2, 0.4, 0.0005)

time3 = np.arange(0.4, 0.6, 0.0005)

time4 = np.arange(0.6, 0.8, 0.0005)

print(len(time4))

And it prints 401

if i change it to

time4 = np.arange(0.4+2, 0.6+0.2, 0.0005)

it prints 400 as expected

Not sure why in the first code it prints 401

Dani3850
  • 9
  • 2
  • 1
    On `time4 = np.arange(0.4+2, 0.6+0.2, 0.0005)` you are actually adding 2 instead of 0.2 on the first parameter. – kengru Jul 28 '21 at 03:15
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Julien Jul 28 '21 at 03:17
  • 1
    `np.arange(0.6, 0.8, 0.0005)[-1] == 0.799999999999978` – Julien Jul 28 '21 at 03:18
  • So I suggest using `np.linspace` to get a fixed length array (eg `np.linspace(start, end, num=400)`) – Xixiaxixi Jul 28 '21 at 03:27
  • 1
    Most of your code isn't needed to demonstrate the problem and should be removed. Then you could add your second example to demonstrate the difference. In fact `np.arange(0.4+2, 0.6+0.2, 0.0005)` is an empty array which would be seen on an working example. – tdelaney Jul 28 '21 at 03:30
  • You missed the warning in the docs. With float steps, getting the end point right is tricky. – hpaulj Jul 28 '21 at 03:53

1 Answers1

0

Notice numpy.arange() is using ceil to count the numbers, for example,

a = np.arange(.1,.3,.1)
print(len(a)) # 2 
print(a)      # [0.1 0.2]

a = np.arange(.1,.4,.1)
print(len(a)) # 4
print(a)      # [0.1 0.2 0.3 0.4]

The result is not as simple as (stop - start)/step, due to ceilling, which adds up 1.

We can use numpy.linespace() if we know how many numbers we want, as below

a = np.linspace(.1,.4,3,endpoint=False) # do not include 0.4
print(len(a)) # 4
print(a) 

Now let us try time4,

time4 = np.linspace(0.6, 0.8, 400,endpoint = False)
print(len(time4))
print(time4)

We can use parameter retstep to see the real step, as below,

time4 = np.linspace(0.6, 0.8, 400,endpoint = False, retstep=False)
print(time4[1]) # 0.0005000000000000001

Now we get real understanding of ceilling, and we rewrite the assignment,

time4 = np.arange(0.6, 0.8, 0.0005000000000000001)
print(len(time4)) # 401 again, no wonder

time4 = np.arange(0.6, 0.8 - 0.0005000000000000001, 0.0005000000000000001)
print(len(time4)) # 400 now, as expected
print(time4)

What time4 = np.arange(0.4+0.2, 0.6+0.2, 0.0005) does is the same, it puts the ceilling to 400, thus woks fine. Anyway, python is not pure math, it is just representing math :(

LinconFive
  • 1,718
  • 1
  • 19
  • 24