Why is minimize_scalar not minimizing correctly?












1















I am a new Python user, so bear with me if this question is obvious.



I am trying to find the value of lmbda that minimizes the following function, given a fixed vector Z and scalar sigma:



def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda;
minimum = np.minimum(z**2,lmbda**2);
return -sigma**2*np.sum(indicator) + np.sum(minimum);


When I pass in values of lmbda manually, I find that the function produces the correct value of sure_stf. However, when I try to use the following code to find the value of lmbda that minimizes sure_stf:



minimize_scalar(lambda lmbda: sure_sft(Z, lmbda, sigma))


it gives me an incorrect value for sure_stf (-8.6731 for lmbda = 0.4916). If I pass in 0.4916 manually to sure_sft, I obtain -7.99809 instead. What am I doing incorrectly? I would appreciate any advice!



EDIT: I've pasted my code below. The data is from: https://web.stanford.edu/~chadj/HallJones400.asc



import pandas as pd 
import numpy as np
from scipy.optimize import minimize_scalar

# FUNCTIONS

# Calculate orthogonal projection of g onto f
def proj(f, g):
return ( np.dot(f,g) / np.dot(f,f) ) * f

def gs(X):

# Copy of X -- will be used to store orthogonalization
F = np.copy(X)

# Orthogonalize design matrix
for i in range(1, X.shape[1]): # Iterate over columns of X
for j in range(i): # Iterate over columns less than current one
F[:,i] -= proj(F[:,j], X[:,i]) # Subtract projection of x_i onto f_j for all j<i from F_i

# normalize each column to have unit length
norm_F=( (F**2).mean(axis=0) ) ** 0.5 # Row vector with sqrt root of average of the squares of each column
W = F/norm_F # Normalize

return W

# SURE for soft-thresholding
def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda
minimum = np.minimum(z**2,lmbda**2)
return -sigma**2*np.sum(indicator) + np.sum(minimum)

# Import data.
data_raw = pd.read_csv("hall_jones1999.csv")

# Drop missing observations.
data = data_raw.dropna(subset=['logYL', 'Latitude'])

Y = data['logYL']
Y = np.array(Y)
N = Y.size

# Create design matrix.
design = np.empty([data['Latitude'].size,15])

design[:,0] = 1
for j in range(1, 15):
design[:,j] = data['Latitude']**j

K = design.shape[1]

# Use Gramm-Schmidt on design matrix.
W = gs(design)
Z = np.dot(W.T, Y)/N

# MLE
mu_mle = np.dot(W, Z)

# Soft-thresholding
# Use MLE residuals to calculate sigma for SURE calculation
sigma = np.sqrt(np.sum((Y - mu_mle)**2)/(N-K))

# Write SURE as a function of lmbda
sure = lambda lmbda: sure_sft(Z, lmbda, sigma)

# Find SURE-minimizing lmbda
lmbda = minimize_scalar(sure).x
min_sure = minimize_scalar(sure).fun #-8.673172212265738

# Compare to manually inputting minimized lambda into sure_sft
# I'm s
act_sure1 = sure_sft(Z, 0.49167598, sigma) #-7.998060514873529
act_sure2 = sure_sft(Z, 0.491675989, sigma) #-8.673172212306728









share|improve this question




















  • 1





    can you reproduce the error in code which we can run?

    – AidanGawronski
    Nov 16 '18 at 5:11











  • I believe you mean scipy.optimize.minimize_scalar right?

    – ZisIsNotZis
    Nov 16 '18 at 5:25











  • I imported at the very top of my code: from scipy.optimize import minimize_scalar

    – Jess
    Nov 16 '18 at 5:52


















1















I am a new Python user, so bear with me if this question is obvious.



I am trying to find the value of lmbda that minimizes the following function, given a fixed vector Z and scalar sigma:



def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda;
minimum = np.minimum(z**2,lmbda**2);
return -sigma**2*np.sum(indicator) + np.sum(minimum);


When I pass in values of lmbda manually, I find that the function produces the correct value of sure_stf. However, when I try to use the following code to find the value of lmbda that minimizes sure_stf:



minimize_scalar(lambda lmbda: sure_sft(Z, lmbda, sigma))


it gives me an incorrect value for sure_stf (-8.6731 for lmbda = 0.4916). If I pass in 0.4916 manually to sure_sft, I obtain -7.99809 instead. What am I doing incorrectly? I would appreciate any advice!



EDIT: I've pasted my code below. The data is from: https://web.stanford.edu/~chadj/HallJones400.asc



import pandas as pd 
import numpy as np
from scipy.optimize import minimize_scalar

# FUNCTIONS

# Calculate orthogonal projection of g onto f
def proj(f, g):
return ( np.dot(f,g) / np.dot(f,f) ) * f

def gs(X):

# Copy of X -- will be used to store orthogonalization
F = np.copy(X)

# Orthogonalize design matrix
for i in range(1, X.shape[1]): # Iterate over columns of X
for j in range(i): # Iterate over columns less than current one
F[:,i] -= proj(F[:,j], X[:,i]) # Subtract projection of x_i onto f_j for all j<i from F_i

# normalize each column to have unit length
norm_F=( (F**2).mean(axis=0) ) ** 0.5 # Row vector with sqrt root of average of the squares of each column
W = F/norm_F # Normalize

return W

# SURE for soft-thresholding
def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda
minimum = np.minimum(z**2,lmbda**2)
return -sigma**2*np.sum(indicator) + np.sum(minimum)

# Import data.
data_raw = pd.read_csv("hall_jones1999.csv")

# Drop missing observations.
data = data_raw.dropna(subset=['logYL', 'Latitude'])

Y = data['logYL']
Y = np.array(Y)
N = Y.size

# Create design matrix.
design = np.empty([data['Latitude'].size,15])

design[:,0] = 1
for j in range(1, 15):
design[:,j] = data['Latitude']**j

K = design.shape[1]

# Use Gramm-Schmidt on design matrix.
W = gs(design)
Z = np.dot(W.T, Y)/N

# MLE
mu_mle = np.dot(W, Z)

# Soft-thresholding
# Use MLE residuals to calculate sigma for SURE calculation
sigma = np.sqrt(np.sum((Y - mu_mle)**2)/(N-K))

# Write SURE as a function of lmbda
sure = lambda lmbda: sure_sft(Z, lmbda, sigma)

# Find SURE-minimizing lmbda
lmbda = minimize_scalar(sure).x
min_sure = minimize_scalar(sure).fun #-8.673172212265738

# Compare to manually inputting minimized lambda into sure_sft
# I'm s
act_sure1 = sure_sft(Z, 0.49167598, sigma) #-7.998060514873529
act_sure2 = sure_sft(Z, 0.491675989, sigma) #-8.673172212306728









share|improve this question




















  • 1





    can you reproduce the error in code which we can run?

    – AidanGawronski
    Nov 16 '18 at 5:11











  • I believe you mean scipy.optimize.minimize_scalar right?

    – ZisIsNotZis
    Nov 16 '18 at 5:25











  • I imported at the very top of my code: from scipy.optimize import minimize_scalar

    – Jess
    Nov 16 '18 at 5:52
















1












1








1








I am a new Python user, so bear with me if this question is obvious.



I am trying to find the value of lmbda that minimizes the following function, given a fixed vector Z and scalar sigma:



def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda;
minimum = np.minimum(z**2,lmbda**2);
return -sigma**2*np.sum(indicator) + np.sum(minimum);


When I pass in values of lmbda manually, I find that the function produces the correct value of sure_stf. However, when I try to use the following code to find the value of lmbda that minimizes sure_stf:



minimize_scalar(lambda lmbda: sure_sft(Z, lmbda, sigma))


it gives me an incorrect value for sure_stf (-8.6731 for lmbda = 0.4916). If I pass in 0.4916 manually to sure_sft, I obtain -7.99809 instead. What am I doing incorrectly? I would appreciate any advice!



EDIT: I've pasted my code below. The data is from: https://web.stanford.edu/~chadj/HallJones400.asc



import pandas as pd 
import numpy as np
from scipy.optimize import minimize_scalar

# FUNCTIONS

# Calculate orthogonal projection of g onto f
def proj(f, g):
return ( np.dot(f,g) / np.dot(f,f) ) * f

def gs(X):

# Copy of X -- will be used to store orthogonalization
F = np.copy(X)

# Orthogonalize design matrix
for i in range(1, X.shape[1]): # Iterate over columns of X
for j in range(i): # Iterate over columns less than current one
F[:,i] -= proj(F[:,j], X[:,i]) # Subtract projection of x_i onto f_j for all j<i from F_i

# normalize each column to have unit length
norm_F=( (F**2).mean(axis=0) ) ** 0.5 # Row vector with sqrt root of average of the squares of each column
W = F/norm_F # Normalize

return W

# SURE for soft-thresholding
def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda
minimum = np.minimum(z**2,lmbda**2)
return -sigma**2*np.sum(indicator) + np.sum(minimum)

# Import data.
data_raw = pd.read_csv("hall_jones1999.csv")

# Drop missing observations.
data = data_raw.dropna(subset=['logYL', 'Latitude'])

Y = data['logYL']
Y = np.array(Y)
N = Y.size

# Create design matrix.
design = np.empty([data['Latitude'].size,15])

design[:,0] = 1
for j in range(1, 15):
design[:,j] = data['Latitude']**j

K = design.shape[1]

# Use Gramm-Schmidt on design matrix.
W = gs(design)
Z = np.dot(W.T, Y)/N

# MLE
mu_mle = np.dot(W, Z)

# Soft-thresholding
# Use MLE residuals to calculate sigma for SURE calculation
sigma = np.sqrt(np.sum((Y - mu_mle)**2)/(N-K))

# Write SURE as a function of lmbda
sure = lambda lmbda: sure_sft(Z, lmbda, sigma)

# Find SURE-minimizing lmbda
lmbda = minimize_scalar(sure).x
min_sure = minimize_scalar(sure).fun #-8.673172212265738

# Compare to manually inputting minimized lambda into sure_sft
# I'm s
act_sure1 = sure_sft(Z, 0.49167598, sigma) #-7.998060514873529
act_sure2 = sure_sft(Z, 0.491675989, sigma) #-8.673172212306728









share|improve this question
















I am a new Python user, so bear with me if this question is obvious.



I am trying to find the value of lmbda that minimizes the following function, given a fixed vector Z and scalar sigma:



def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda;
minimum = np.minimum(z**2,lmbda**2);
return -sigma**2*np.sum(indicator) + np.sum(minimum);


When I pass in values of lmbda manually, I find that the function produces the correct value of sure_stf. However, when I try to use the following code to find the value of lmbda that minimizes sure_stf:



minimize_scalar(lambda lmbda: sure_sft(Z, lmbda, sigma))


it gives me an incorrect value for sure_stf (-8.6731 for lmbda = 0.4916). If I pass in 0.4916 manually to sure_sft, I obtain -7.99809 instead. What am I doing incorrectly? I would appreciate any advice!



EDIT: I've pasted my code below. The data is from: https://web.stanford.edu/~chadj/HallJones400.asc



import pandas as pd 
import numpy as np
from scipy.optimize import minimize_scalar

# FUNCTIONS

# Calculate orthogonal projection of g onto f
def proj(f, g):
return ( np.dot(f,g) / np.dot(f,f) ) * f

def gs(X):

# Copy of X -- will be used to store orthogonalization
F = np.copy(X)

# Orthogonalize design matrix
for i in range(1, X.shape[1]): # Iterate over columns of X
for j in range(i): # Iterate over columns less than current one
F[:,i] -= proj(F[:,j], X[:,i]) # Subtract projection of x_i onto f_j for all j<i from F_i

# normalize each column to have unit length
norm_F=( (F**2).mean(axis=0) ) ** 0.5 # Row vector with sqrt root of average of the squares of each column
W = F/norm_F # Normalize

return W

# SURE for soft-thresholding
def sure_sft(z,lmbda, sigma):
indicator = np.abs(z) <= lmbda
minimum = np.minimum(z**2,lmbda**2)
return -sigma**2*np.sum(indicator) + np.sum(minimum)

# Import data.
data_raw = pd.read_csv("hall_jones1999.csv")

# Drop missing observations.
data = data_raw.dropna(subset=['logYL', 'Latitude'])

Y = data['logYL']
Y = np.array(Y)
N = Y.size

# Create design matrix.
design = np.empty([data['Latitude'].size,15])

design[:,0] = 1
for j in range(1, 15):
design[:,j] = data['Latitude']**j

K = design.shape[1]

# Use Gramm-Schmidt on design matrix.
W = gs(design)
Z = np.dot(W.T, Y)/N

# MLE
mu_mle = np.dot(W, Z)

# Soft-thresholding
# Use MLE residuals to calculate sigma for SURE calculation
sigma = np.sqrt(np.sum((Y - mu_mle)**2)/(N-K))

# Write SURE as a function of lmbda
sure = lambda lmbda: sure_sft(Z, lmbda, sigma)

# Find SURE-minimizing lmbda
lmbda = minimize_scalar(sure).x
min_sure = minimize_scalar(sure).fun #-8.673172212265738

# Compare to manually inputting minimized lambda into sure_sft
# I'm s
act_sure1 = sure_sft(Z, 0.49167598, sigma) #-7.998060514873529
act_sure2 = sure_sft(Z, 0.491675989, sigma) #-8.673172212306728






python numpy optimization scipy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 5:56







Jess

















asked Nov 16 '18 at 5:02









JessJess

175310




175310








  • 1





    can you reproduce the error in code which we can run?

    – AidanGawronski
    Nov 16 '18 at 5:11











  • I believe you mean scipy.optimize.minimize_scalar right?

    – ZisIsNotZis
    Nov 16 '18 at 5:25











  • I imported at the very top of my code: from scipy.optimize import minimize_scalar

    – Jess
    Nov 16 '18 at 5:52
















  • 1





    can you reproduce the error in code which we can run?

    – AidanGawronski
    Nov 16 '18 at 5:11











  • I believe you mean scipy.optimize.minimize_scalar right?

    – ZisIsNotZis
    Nov 16 '18 at 5:25











  • I imported at the very top of my code: from scipy.optimize import minimize_scalar

    – Jess
    Nov 16 '18 at 5:52










1




1





can you reproduce the error in code which we can run?

– AidanGawronski
Nov 16 '18 at 5:11





can you reproduce the error in code which we can run?

– AidanGawronski
Nov 16 '18 at 5:11













I believe you mean scipy.optimize.minimize_scalar right?

– ZisIsNotZis
Nov 16 '18 at 5:25





I believe you mean scipy.optimize.minimize_scalar right?

– ZisIsNotZis
Nov 16 '18 at 5:25













I imported at the very top of my code: from scipy.optimize import minimize_scalar

– Jess
Nov 16 '18 at 5:52







I imported at the very top of my code: from scipy.optimize import minimize_scalar

– Jess
Nov 16 '18 at 5:52














1 Answer
1






active

oldest

votes


















0














You're actually not doing anything wrong. I just tested out the code and confirmed that lmbda has a value of 0.4916759890416824 at the end of the script. You can confirm this for yourself by adding the following lines to the bottom of your script:



print(lmbda)
print(sure_sft(Z, lmbda, sigma))


when you run your script you should then see:



0.4916759890416824
-8.673158394698172


The only thing I can figure is that somehow the routine you were using to print out lmbda was set up to only print a fixed number of digits of floating point numbers, or somehow the printout was otherwise truncated.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53331732%2fwhy-is-minimize-scalar-not-minimizing-correctly%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You're actually not doing anything wrong. I just tested out the code and confirmed that lmbda has a value of 0.4916759890416824 at the end of the script. You can confirm this for yourself by adding the following lines to the bottom of your script:



    print(lmbda)
    print(sure_sft(Z, lmbda, sigma))


    when you run your script you should then see:



    0.4916759890416824
    -8.673158394698172


    The only thing I can figure is that somehow the routine you were using to print out lmbda was set up to only print a fixed number of digits of floating point numbers, or somehow the printout was otherwise truncated.






    share|improve this answer




























      0














      You're actually not doing anything wrong. I just tested out the code and confirmed that lmbda has a value of 0.4916759890416824 at the end of the script. You can confirm this for yourself by adding the following lines to the bottom of your script:



      print(lmbda)
      print(sure_sft(Z, lmbda, sigma))


      when you run your script you should then see:



      0.4916759890416824
      -8.673158394698172


      The only thing I can figure is that somehow the routine you were using to print out lmbda was set up to only print a fixed number of digits of floating point numbers, or somehow the printout was otherwise truncated.






      share|improve this answer


























        0












        0








        0







        You're actually not doing anything wrong. I just tested out the code and confirmed that lmbda has a value of 0.4916759890416824 at the end of the script. You can confirm this for yourself by adding the following lines to the bottom of your script:



        print(lmbda)
        print(sure_sft(Z, lmbda, sigma))


        when you run your script you should then see:



        0.4916759890416824
        -8.673158394698172


        The only thing I can figure is that somehow the routine you were using to print out lmbda was set up to only print a fixed number of digits of floating point numbers, or somehow the printout was otherwise truncated.






        share|improve this answer













        You're actually not doing anything wrong. I just tested out the code and confirmed that lmbda has a value of 0.4916759890416824 at the end of the script. You can confirm this for yourself by adding the following lines to the bottom of your script:



        print(lmbda)
        print(sure_sft(Z, lmbda, sigma))


        when you run your script you should then see:



        0.4916759890416824
        -8.673158394698172


        The only thing I can figure is that somehow the routine you were using to print out lmbda was set up to only print a fixed number of digits of floating point numbers, or somehow the printout was otherwise truncated.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 7:45









        teltel

        7,44621431




        7,44621431
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53331732%2fwhy-is-minimize-scalar-not-minimizing-correctly%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python