Home > Software design >  Why is the element inserted several times?
Why is the element inserted several times?

Time:11-09

I have the following code:

C = np.array([10 ** ((i-1)/(2-1)) for i in range(2)])
C = C *np.identity(2)
x = [1, 1]
J = (C.T   C) @ x
theta = 1e-5
alpha = 0.1

X = []
while np.sum(np.linalg.norm(alpha * J, ord=2)) >= theta:
    J = (C.T   C) @ x
    x -= alpha * J
    X.append(x)
    print("x = ", x)
    print("X[i] = ", np.array(X))

Like you see, I want to perform a basic gradient descent, but this doesn't matter right now.

The problem is the output (e.g):

x =  [0.98 0.8 ]
X[i] =  [[0.98 0.8 ]]
x =  [0.9604 0.64  ]
X[i] =  [[0.9604 0.64  ]
 [0.9604 0.64  ]]
x =  [0.941192 0.512   ]
X[i] =  [[0.941192 0.512   ]
 [0.941192 0.512   ]
 [0.941192 0.512   ]]
x =  [0.92236816 0.4096    ]
X[i] =  [[0.92236816 0.4096    ]
 [0.92236816 0.4096    ]
 [0.92236816 0.4096    ]
 [0.92236816 0.4096    ]]
x =  [0.9039208 0.32768  ]
X[i] =  [[0.9039208 0.32768  ]
 [0.9039208 0.32768  ]
 [0.9039208 0.32768  ]
 [0.9039208 0.32768  ]
 [0.9039208 0.32768  ]]
x =  [0.88584238 0.262144  ]
X[i] =  [[0.88584238 0.262144  ]
 [0.88584238 0.262144  ]
 [0.88584238 0.262144  ]
 [0.88584238 0.262144  ]
 [0.88584238 0.262144  ]
 [0.88584238 0.262144  ]]

There is something wrong with the append function and I can't find the reason, do you have an Idee?

CodePudding user response:

Python is not a value-based language, but rather a reference-based language. If I write l.append(x) then I add a reference to object x to the list l. If I then later modify x, this changes l. It often takes a while to run into this problem because a lot of objects a Python beginner interacts with are immutable. But not all!

>>> x = [1, 1]
>>> l = [x]
>>> l
[[1, 1]]
>>> x[0] = 2
>>> l
[[2, 1]]

Now confusingly, x -= alpha * J is not the same as x = x - alpha * J. The former modifies x in-place, whereas the latter creates a new object.

To prevent this issue entirely I'd suggest adding a copy of x to the list:

X.append(np.copy(x))
  • Related