TheWaveLad
TheWaveLad

Reputation: 1026

Avoid copy method in Python

I wrote a function in python implementing the de Casteljau algorithm

from __future__ import division
import numpy as np
import copy

def decasteljau(P, t):
    N = len(P)
    for k in range(N-1):
        for r in range(N-1-k):
            P[r] = (1-t)*P[r] + t*P[r+1]
    return P[0]

And called the function with the following data

P = np.array([[1.,1.],[2.,3.],[3.,2.]], dtype=float)
M = 1000
for j in range(M):
    t = decasteljau(P, j/(M-1))

which lead to thousands of (wrong) results [3,2] for almost all values of t = j/(M-1). I changed the code to

def decasteljau(P, t):
    N = len(P)
    Q = copy.copy(P)
    for k in range(N-1):
        for r in range(N-1-k):
            Q[r] = (1-t)*Q[r] + t*Q[r+1]
    return Q[0]

so I copied the array P before changing it, and now the data is correct. I don't really understand why it works now and I was wondering if there is a solution without the copy method? Thank you!

Here is a data plot without copy method and a data plot with the copy method:

without copy method enter image description here

Obviously, the first plot isn't correct. The first plot has most of it's point in 3,2, which is not what I want.

Upvotes: 0

Views: 1069

Answers (1)

Zav
Zav

Reputation: 661

The problem is in python you pass link to a variable, not just value, so you modify base list. All mutable types transmitted as link. You can read more about it in data types section of python documentation.

If you want avoid copy function you can just write

Q = P[:]

And that is all you need :-)

Also there is good answer how to do right copy of list

Upvotes: 1

Related Questions