0

I'm running fmincon function in python via this interface: https://github.com/byuflowlab/pyfmincon

If I specify upper and lower bounds as

ub = np.array([1.0, 30.0])
lb = np.array([0, 0])

it results in the following error:

Unable to resolve the name 'py.self.neg_log_likelihood'.
Error in my_optimize/fupdate (line 45)
        eval(['output = py.', funcname, '(x);'])  % output is a cell array with {J, cin}
Error in my_optimize/obj (line 63)
        [J, cin, gJ, gcin] = fupdate(x);
Error in fmincon (line 577)
      [initVals.f,initVals.g] = feval(funfcn{3},X,varargin{:});
Error in my_optimize (line 28)
    [xopt, fopt, exitflag, output] = fmincon(@obj, x0, A, b, Aeq, beq, lb, ub, @con, options);
Caused by:
    Failure in initial objective function evaluation. FMINCON cannot continue.

However, if I switch upper and lower bounds the function runs without errors and prints out this message:

Exiting due to infeasibility: at least one lower bound exceeds the corresponding upper bound.

I don't understand how it can run with incorrect bounds. Also, unfortunately people who developed the package are not supporting it anymore, so I can't ask on Github.

my objective function is:

def neg_log_likelihood(self, params):
        """Compute the negative log likelihood of the parameters.
        The data consist of a sequence of (cue,action,reward) observations.
        """
    df = self.df
    if self.model in ('sample_average', 'constant_step_size'):
        alpha, beta = params
    elif (self.model == 'policy') or (self.model == 'policy_daw'):
        if self.param_value['alpha'] == None:
            alpha, params = params[0], params[1:]
        else:
            alpha = self.param_value['alpha']
        if self.param_value['beta'] == None:
            beta, params = params[0], params[1:]
        else:
            beta = self.param_value['beta']
        if self.param_value['r_bar'] == None:
            r_bar, params = params[0], params[1:]
        else:
            r_bar = self.param_value['r_bar']

    df = self.df[self.df['cue'].isin(self.cues)]
    actions, rewards = df['action'].values, df['reward'].values
    cues = df['cue'].values
    prob_log = 0.0
    Q = dict([[cue, np.zeros(self.n_actions)] for cue in self.cues])
    k = 1
    for action, reward, cue in zip(actions, rewards, cues):
        if action == 'blue':
            action = 1
        else:
            action = 0
        if self.model == 'sample_average':
            Q[cue][action] += alpha * (reward - Q[cue][action]) / k
            k += 1
        elif self.model == 'constant_step_size':
            Q[cue][action] = Q[cue][action] + alpha * (reward - Q[cue][action])
            #Q[cue] = Q[cue].at[action].set((Q[cue][action] + alpha * (reward - Q[cue][action])))
        elif self.model == 'policy':
            # We are reusing Q, but the right name should be pi
            probs = softmax(Q[cue], beta)
            for a in (0,1):  # (0, 1) should be something like self.actions
                indicator = 1 if a == action else 0
                Q[cue][a] += alpha * (reward - r_bar) * (indicator - probs[a])
        elif self.model == 'policy_daw': # Daw simplified rule
            # We are reusing Q, but the right name should be pi
            Q[cue][action] += alpha * (reward - r_bar)
        else:
            print('Something bad happen :(')
        prob_log += np.log(softmax_jnp(Q[cue], beta)[action])
        
    return -prob_log
stasia_l
  • 47
  • 6
  • Now when I'm testing it more, I think it's also not running with the incorrect bounds, I think it's just skipping the function altogether. Maybe the problem is in linking python and Matlab? – stasia_l May 28 '22 at 12:46
  • I don't know what you mean by "runs without errors and prints out this message" - the message it prints out is (basically) an error message. Moreover, it is a reasonable error message ("lower bound exceeds the upper bound"). It looks like the heart of your problem is at "`Failure in initial objective function evaluation`". Basically, it looks like fmincon fails both times, but in two different ways (as expected). I think you need to investigate the objective function more. And you will probably have to supply more information about it - can you supply (brief) examples of `obj,x0,a,b` etc? – magnesium May 28 '22 at 12:50
  • I've added the objective function. x0 = [0.5, 5] a = [] b = [] – stasia_l May 28 '22 at 13:00
  • I also don't know which error message is more important: 'Unable to resolve the name 'py.self.neg_log_likelihood'." or "Failure in initial objective function evaluation. FMINCON cannot continue." – stasia_l May 28 '22 at 13:05
  • Please remove the matlab tag if this isn't a matlab question. – Chuck May 28 '22 at 13:19
  • I'm using matlab engine to run matlab function in python, so I feel like it's a matlab related question as well – stasia_l May 28 '22 at 13:26

0 Answers0