Reputation: 7
I am working on an implementation of power method to calculate the dominant eigen vector and eigen value of a given matrix. I have not posted the complete code, I rather have a specific question that I cannot understand.
In the following loop, I am updating x0
by assigning the calculated x
of each step to it. This works fine, however, I need to calculate the difference between x
and x0
in each step and save them in a variable called epsilon
.
As the x0
assignment comes in the line after epsilon
calculation, I expected this to work, but what I get as epsilon
after the first round of loop is 0
and the reason is that x0
and x
are identical in each step.
I have been thinking about this but I would appreciate some hint on what I am doing wrong.
for k in range(10):
y = matprod.matvec(m, x0)
normy = normvec.normvec(y)
for i in range(len(y)):
x[i] = y[i] / normy
epsilon[i] = x[i] - x0[i]
x0 = x
print k, x, x0, normy, epsilon
Upvotes: 0
Views: 242
Reputation: 23877
This is a result of one of the common errors in Python. When we have a list b
and set a=b
, we aren't setting every value of a
to equal every value of b
. Rather we are setting them to be the same thing They are the same positions in memory. Any change to one of them changes the other. Any time you have two lists (or any python object) that seem to always be the same, or one object seems to change when you aren't expecting you should always check whether you've done this.
x0 = x[:]
will do what you're after if it's a list and
x0 = x.copy()
if it's numpy.
Assuming these are numpy arrays, you'll also be able to improve your code by setting
x = y/normy
epsilon = x-x0
rather than doing it in a loop. It will be much faster because numpy is optimized to do this.
Upvotes: 2
Reputation: 1201
Since x
and x0
are arrays, get an error. The line x0 = x
does not copy the data, but rather makes both x
and x0
point to the same data. After the first time it is done, they will stay the same.
If you want to copy the data from x
to x0
you should use x0 = x[:]
. The slice syntax ([:]
) creates a copy of the data, so that should work.
Upvotes: 2