Lucia Palomarez
Lucia Palomarez

Reputation: 7

Updating a variable in a for loop Python

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

Answers (2)

Joel
Joel

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

tmr232
tmr232

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

Related Questions