Very small numbers python with a for cycle

I have to evaluate the function b=3x-2 in the interval [-10,10] with precision increments from 1, 0.1, 0.01, 0.001, 0.0001, 0.00001 and so on, my objective is to reach more than 8 zeros (0.000000001 more than this) I'm trying to do it with np.linspace() but it has the limit of 8 precision numbers (8 zeros 0.00000001) but I want to reach more than 8 zeros the ideal it would be reach 10 or 11 zeros (I know it'll take some hours or maybe days but the objective is reach more than 8 zeros) I wrote the next code and I explain each part of the code:

import numpy as np
import matplotlib.pyplot as plt
from decimal import *
from time import time

file = open("tiempos.txt", "w")
increment = 1
upper_bound = 10
lower_bound = -10

#I'm creating an array to save the values of the increments (1, 0.1, 0.01, 0.001, 0.0001, etc.)
v = []
#Creating an array to save the time that takes to calculate the function with each increment
t = []

for x in range(0, 9):
    #Start counting the time that takes each increment
    start_time = time()
    pts = int((upper_bound - lower_bound)/increment + 1)
    #Counting the precision increments
    a = np.linspace(lower_bound, upper_bound, pts)
    #Calculating the function
    b = 3 * a - 2
    #introduce the valor of the increment into the array
    v.append(increment)
    #Divide the increment to get a smaller number
    increment = increment/10
    #Stop counting the time and seve it
    elapsed_time = time() - start_time
    #Introduce the time into the array
    t.append(elapsed_time)
    #write the interval and time into a txt file
    file.write("Valor: %.10f    " % increment)
    file.write("Tiempo: %.10f segundos " % elapsed_time +'\n')

file.close()

print(v)
print(t)

#Graph the time that took each interval
plt.figure(1)
plt.plot(t,v,'*')
plt.show()

I have the problem in this part:

a = np.linspace(lower_bound, upper_bound, pts)

When I reach the 8 zeros (0.00000001) It says that I have reach the limit of np.linspace

So my question is how can I reach a smaller number?

Upvotes: 1

Views: 854

Answers (1)

blue note
blue note

Reputation: 29071

Your problem has nothing to do with np.linspace. Neither does np.linspace has specific precision. You can try

x = np.linspace(0, 10**(-10), num=10000)

and see that it works fine.

The problem is that you're running out of memory. Every time you divide the increment by 10, your array gets 10 times larger. There's nothing you can do about it.

The only approach would be, instead of generating the whole a array in advance, to generate its elements in a loop. eg

while increment > 10**(-12):
    # start_timing
    for a in range(start, end, increment):
        b = 3*a - 2
    # stop timing
   increment = increment / 10

Since built-in range seems to accept only integer step, and np.arange mentions that it does not work well with non-integer step, you could make your own range function. Take care that it must be a generator, otherwise you'll run out of memory

def my_range(start, stop, step):
    current = start
    while current < stop:
         current += step
         yield current

Upvotes: 3

Related Questions