3

I'm trying to minimize a function that has arguments S1, S2, S3 and n1, n2, and n3. There are also weights: w1, w2, and w3.

This is the function:

f = (w1**2 * n1**2 + w2**2 * n2**2 + w3**2 * n3**2) / (w1**2 * S1**2 + w2**2 * S2**2 + w3**2 * S3**2 + 2*w1*S1*w2*S2 * 2*w1*S1*w2*S2 + 2*w2*S2*w3*S3)

I want to know given S1, S2, S3, n1, n2, and n3, what w1, w2, and w3 will minimize f?

Here's my code so far:

def opt(S1, S2, S3, n1, n2, n3):
    xo = np.array([0,1,.01])
    from scipy.optimize import minimize
    signoise = lambda w1,w2,w3: (w1**2 * n1**2 + w2**2 * n2**2 + w3**2 * n3**2) / (w1**2 * S1**2 + w2**2 * S2**2 + w3**2 * S3**2 + 2*w1*S1*w2*S2 * 2*w1*S1*w2*S2 + 2*w2*S2*w3*S3)
    w1min, w2min, w3min = scipy.optimize.minimize(signoise, (.4, .2, .4))
    return w1min, w2min, w3min

scipy.optimize.minimize takes two arguments, the function and an initial guess. I don't know if it works for multivariable functions, because I'm getting the

error : <lambda>() takes exactly 3 arguments (1 given)

Okay, I followed CodyKramer's suggestion. When I tested it with arbitrary values for S1, S2, S3, n1, n2, n3, I got all of this as an answer : status: 0 success: True njev: 1 nfev: 5 hess_inv: array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) fun: 5.1874999894628917e-18 x: array([ 0.4, 0.2, 0.4]) message: 'Optimization terminated successfully.' jac: array([ -1.81249989e-17, -4.62499946e-17, 1.53125002e-17]) Is that last line the 'jac' the three numbers I was looking for?

1
  • The answer is the array x in your output. jac is the Jacobian matrix which is the (basically) first derivative of x, and hess is the Hessian matrix which is (basically) the second derivative of x Commented Jul 25, 2015 at 13:42

1 Answer 1

3

The problem is that as written your lambda takes 3 arguments, not 1 argument (that happens to be a sequence with 3 elements). I would pull out your objective function into a standalone function

def signoise(w):
    w1, w2, w3 = w  # unpack your tuple into each variable
    # populate your S and n coefficients
    return w1**2 * n1**2 + w2**2 * n2**2 + w3**2 * n3**2) / (w1**2 * S1**2 + w2**2 * S2**2 + w3**2 * S3**2 + 2*w1*S1*w2*S2 * 2*w1*S1*w2*S2 + 2*w2*S2*w3*S3

Then you can modify your function to

def opt(S1, S2, S3, n1, n2, n3):
    xo = np.array([0,1,.01])
    from scipy.optimize import minimize
    return scipy.optimize.minimize(signoise, (.4, .2, .4))
Sign up to request clarification or add additional context in comments.

2 Comments

Okay, I followed your suggestion. When I tested it with arbitrary values for S1, S2, S3, n1, n2, n3, I got all of this as an answer : status: 0 success: True njev: 1 nfev: 5 hess_inv: array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) fun: 5.1874999894628917e-18 x: array([ 0.4, 0.2, 0.4]) message: 'Optimization terminated successfully.' jac: array([ -1.81249989e-17, -4.62499946e-17, 1.53125002e-17]) Is that last line the 'jac' the three numbers I was looking for?
Can you please edit your question to include that? Unfortunately all formatting is lost in the comment section so it's hard to parse that output visually

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.