Kyle
Kyle

Reputation: 21

Trouble with least squares in Python

I am working on a project analyzing data and am trying to use a least squares method (built-in) to do so. I found a tutorial that provided code as an example and it works fine:

x = arange(0, 6e-2, 6e-2/30)
A, k, theta = 10, 1.0/3e-2, pi/6
y_true = A*sin(2*pi*k*x+theta)
y_meas = y_true+2*random.randn(len(x))

def residuals(p, y, x):
    A, k, theta = p
    print "A type" + str(type(A))
    print "k type" + str(type(k))
    print "theta type" + str(type(theta))
    print "x type" + str(type(x))
    err = y - A*sin(2*pi*k*x+theta)
    return err

def peval(x, p):
    return p[0]*sin(2*pi*p[1]*x+p[2])

p0 = [8,1/2.3e-2,pi/3]

plsq = leastsq(residuals, p0, args=(y_meas, x))
print(plsq[0])

However, when I try transferring this to my own code, it keeps throwing errors. I have been working on this for a while and have managed to eliminate, I think, all of the type mismatch issues which plagued me early on. As far as I can tell, currently the two pieces of code are nearly identical but I am getting the error 'unsupported operand type(s)' and can't figure out what to do next. Here is the section of my code that pertains to this question my code:

if (ls is not None):
        from scipy.optimize import leastsq
        p0 = [8, 1/2.3e-2,pi/3]
        def residuals(p, y, x):
            A,k,theta = p
            if (type(x) is list):
                x = asarray(x)
            err = y - A*sin(2*pi*k*x+theta) #Point of error
            return err
        def peval(x, p):
            return p[0]*sin(2*pi*p[1]*x+p[2])
        plsq = leastsq(residuals, p0, args=(listRelativeCount, listTime))
        plsq_0 = peval(listTime, plsq[0])

Where listTime is the x-values of the data found in listRelativeCount. I have marked the line where the code is currently failing. Any help would be appreciated as I have been stuck on this problem for over a month.

Upvotes: 2

Views: 343

Answers (1)

Frank M
Frank M

Reputation: 1570

Three things are happening in the line you called #Point of error: You are multiplying values, adding values and applying the sin() function. "Unsupported operand type" means something is wrong in one of these operations. It means you need to verify the types of the operands, and also make sure you know what function is being applied.

  • Are you sure you know the types (and dtypes, for ndarrays) of all the operands, including pi, x, theta and A?
  • Are you sure which sin function you are using? math.sin is not the same as np.sin, and they accept different operands.
  • Mulitplying a list by a scalar (if your listTime variable is really a list) does something completely different from multiplying scalar and ndarray.

If it's unclear which operation is causing the error, try breaking up the expression:

err1 = 2*pi*k
err2 = err1*x
err3 = err2 +  theta
err4 = sin(err3)
err5 = A*err4
err = y - err5

This ought to clarify what operation throws the exception.

This is an example of why it's often a better idea to use explicit package names, like np.sin() rather than sin().

Upvotes: 2

Related Questions