1

I am trying to create two list with numpy.arange via two input parameters and the I want to pass them in an array which is initialized via np.zeros as a 3x3 matrix. The problem is that the pass only works for 0.1 and I don't see what I am doing wrong. My code:

import numpy as np
from time import sleep

def Stabilizer(px,pz):
    ss = 0.05
    #initialize an array for data aquisition: 1st row is for countrate, 2nd and 3rd row for x and z values in V
    values_x = np.zeros((3,3), dtype=float)
    values_z = np.zeros((3,3), dtype=float)
    sleep(5)
    values_x[2] = pz
    values_z[1] = px
    x_range = np.arange(px-ss, px+ss,ss)
    z_range = np.arange(pz-ss, pz+ss,ss)
    print(x_range)
    print(z_range)
    values_x[1] = x_range
    values_z[2] = z_range
    for i,x_value in enumerate(x_range):
        #change_pos(x_channel, x_value)
        sleep(1)
        start = 1000
        stop = 1+i
        countrate = stop - start
        values_x[0,i] = countrate
        print(x_value)
    print(values_x)

Stabilizer(0.1,0.2)

which creates this output on console:

Traceback (most recent call last):
  File "C:/Users/x/PycharmProjects/NV_centre/test.py", line 46, in <module>
    Stabilizer(0.1,0.2)
  File "C:/Users/x/PycharmProjects/NV_centre/test.py", line 35, in Stabilizer
    values_z[2] = z_range
ValueError: could not broadcast input array from shape (2) into shape (3)
[0.05 0.1  0.15]
[0.15 0.2 ]

In theory the function np.arange(px-ss, px+ss,ss) creates a list with the output [0.05 0.1]. When I use np.arange(px-ss, px+2*ss,ss) in theory the output would be [0.05 0.1 0.15] but it is [0.05 0.1 0.15 0.2 ]. And for z_range = np.arange(pz-ss, pz+2*ss,ss) the output is [0.15 0.2 0.25] which is correct. I don't understand why the difference occurs since both list are created in the same way.

Machzx
  • 49
  • 7
  • At the end, your issue is resumed with this line `x_range = np.arange(0.05, 0.2, 0.05)` (your example can be highly reduced). – Jona Jul 28 '20 at 09:53

3 Answers3

2

The results for numpy.arange are not consistent when using a non integer step ( you have used 0.05). Using numpy.linspace instead would give more consistent results.

ref: https://numpy.org/doc/stable/reference/generated/numpy.arange.html

Ameya Rane
  • 286
  • 1
  • 7
2

np.arange() does not works good for floating point numbers because floating-point operations have rounding error. Refer this for more details.

It's better to use np.linspace() in such cases. So change the following lines to :

x_range = np.linspace(px-ss, px+ss,3)
z_range = np.linspace(pz-ss, pz+ss,3)

This will work fine.

Rahul Vishwakarma
  • 1,446
  • 2
  • 7
  • 22
0

This is the best solution I can think of :

x_range = [round(i, 2) for i in np.arange(px-ss, px+2*ss,ss) if i<px+2*ss]
Jona
  • 1,218
  • 1
  • 10
  • 20