Home > front end >  Why does my python loop give a different array every run, and how to make it produce the same result
Why does my python loop give a different array every run, and how to make it produce the same result

Time:05-11

You can see the loop below, which gives a different plot everytime, and approximately 1 out of 20 runs is the result that I want, which is a triangular Fourier series. How to make it so that the outcome is the same everytime?

L=1
N=1000

#Array for x
x=np.linspace(-3*L,3*L,N 1)
#Array for sum
s=np.empty(N 1) 
#While loop for sum
i=1
while(i<N 1):
    s=(1/((2*i-1)**2))*(np.cos((2*i-1)*np.pi*x/L)) s
    i=i 1

print(s)
#f(x)
y=(L/2)-(4*L/((np.pi)**2))*s

#Settings for plot
plt.plot(x,y)

CodePudding user response:

This line

s=np.empty(N 1) 

produces an array filled with undefined(arbitrary) value. You should be using a new array filled with zero instead:

s=np.zeros(N 1) 

CodePudding user response:

As pointed out the np.empty is giving you problems. Your loop with an initial print of s:

In [26]: L=1
    ...: N=10
    ...: 
    ...: #Array for x
    ...: x=np.linspace(-3*L,3*L,N 1)
    ...: #Array for sum
    ...: s=np.empty(N 1)
    ...: print(s)
    ...: i=1
    ...: while(i<N 1):
    ...:     s=(1/((2*i-1)**2))*(np.cos((2*i-1)*np.pi*x/L)) s
    ...:     i=i 1
    ...: 
[-3.  -2.4 -1.8 -1.2 -0.6  0.   0.6  1.2  1.8  2.4  3. ]
In [27]: s
Out[27]: 
array([-4.20872131, -2.15330145, -1.06005191, -1.93994809, -0.84669855,
        1.20872131,  0.35330145,  0.46005191,  2.53994809,  2.64669855,
        1.79127869])

Same thing but with np.zeros:

In [28]: L=1
    ...: N=10
    ...: 
    ...: #Array for x
    ...: x=np.linspace(-3*L,3*L,N 1)
    ...: #Array for sum
    ...: s=np.zeros(N 1)
    ...: print(s)
    ...: i=1
    ...: while(i<N 1):
    ...:     s=(1/((2*i-1)**2))*(np.cos((2*i-1)*np.pi*x/L)) s
    ...:     i=i 1
    ...: 
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
In [29]: s
Out[29]: 
array([-1.20872131,  0.24669855,  0.73994809, -0.73994809, -0.24669855,
        1.20872131, -0.24669855, -0.73994809,  0.73994809,  0.24669855,
       -1.20872131])

But you don't need to iterate. Instead create i range of values, and construct a 2d result (broadcasting the (11,1) x against the (10,) i:

In [30]: i = np.arange(1,N 1)
In [31]: S = (1/((2*i-1)**2))*(np.cos((2*i-1)*np.pi*x[:,None]/L))
In [32]: S.shape
Out[32]: (11, 10)
In [33]: s.shape
Out[33]: (11,)

Then sum across the i dimension:

In [34]: S.sum(axis=1)
Out[34]: 
array([-1.20872131,  0.24669855,  0.73994809, -0.73994809, -0.24669855,
        1.20872131, -0.24669855, -0.73994809,  0.73994809,  0.24669855,
       -1.20872131])
  • Related