Reputation: 1110
I'm running the following code in python:
w= np.random.rand(3)
w_old=np.zeros((3,))
while (np.linalg.norm(w - w_old)) / np.linalg.norm(w) > 1e-5:
w_old=w
print w
print w_old
w[0]-=eta*dE1i
w[1]-=eta*dE2i
w[2]-=eta*dE3i
print w
print w_old
The results for the prints are :
[ 0.22877423 0.59402658 0.16657174]
[ 0.22877423 0.59402658 0.16657174]
and
[ 0.21625852 0.5573612 0.123111 ]
[ 0.21625852 0.5573612 0.123111 ]
I'm wondering why the value of w_old
has been changed? Shouldn't it be updated after going back to the beginning of the while loop? How can I fix this?
Upvotes: 1
Views: 154
Reputation: 1110
Just to conclude the answers above, according to python documentation
Assignment statements in Python do not copy objects, they create bindings between a target and an object.
So, the solution is
For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.
So using copy()
we can rewrite the code as
import numpy as np
w= np.random.rand(3)
w_old=np.zeros((3,))
while (np.linalg.norm(w - w_old)) / np.linalg.norm(w) > 1e-5:
w_old=w.copy()
print(w)
print(w_old)
w[0]-=0.01
w[1]-=0.01
w[2]-=0.01
print(w)
print(w_old)
and get
[0.79666571 0.82305671 0.41167625]
[0.79666571 0.82305671 0.41167625]
and
[0.78666571 0.81305671 0.40167625]
[0.79666571 0.82305671 0.41167625]
Upvotes: 0
Reputation: 69
Just to clear things up, variables are independent so:
a=5
b=a
will work just fine if you change either a
or b
. But lists and dictionaries cannot be copied the same way, so:
a=[1,2]
b=a
a[0]=100
print(b[0])
will give you 100 because now a
and b
are the same thing with two names. So as suggested before use
w_old = w.copy()
instead so w_old
is a new list and not just another name for the old one.
Upvotes: 1
Reputation: 152795
Just using
w_old = w
doesn't copy w
, using =
just tells python that you want another name for whatever is stored in w
. So every in-place change to w
will also change w_old
. There is a really nice blog post about it in case you want more details Ned Batchelder: "Facts and myths about Python names and values"
You can explicitly copy a numpy array, for example, using the copy
method:
w_old = w.copy()
Upvotes: 2