<commit_before>from libc.string cimport memcpy
from libc.stdlib cimport free

cimport numpy as npc
import numpy as np


npc.import_array()


cdef extern from "coin/IpStdCInterface.h":
    cdef struct IpoptProblemInfo:
        pass

    cdef enum ApplicationReturnStatus:
        Solve_Succeeded, Solved_To_Acceptable_Level,
        Infeasible_Problem_Detected, Search_Direction_Becomes_Too_Small,
        Diverging_Iterates, User_Requested_Stop, Feasible_Point_Found,
        Maximum_Iterations_Exceeded, Restoration_Failed,
        Error_In_Step_Computation, Maximum_CpuTime_Exceeded,
        Not_Enough_Degrees_Of_Freedom, Invalid_Problem_Definition,
        Invalid_Option, Invalid_Number_Detected, Unrecoverable_Exception,
        NonIpopt_Exception_Thrown, Insufficient_Memory, Internal_Error
    
    ctypedef double Number
    ctypedef int Index
    ctypedef int Int
    ctypedef int Bool
    ctypedef void *UserDataPtr
    ctypedef IpoptProblemInfo* IpoptProblem
    
    ctypedef Bool (*Eval_F_CB)(Index n, Number* x, Bool new_x,
                               Number* obj_value,
                               UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_Grad_F_CB)(Index n, Number* x, Bool new_x,
                                    Number* grad_f,
                                    UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_G_CB)(Index n, Number* x, Bool new_x,
                               Index m, Number* g,
                               UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_Jac_G_CB)(Index n, Number *x, Bool new_x,
                                   Index m, Index nele_jac,
                                   Index *iRow, Index *jCol, Number *values,
                                   UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_H_CB)(Index n, Number *x, Bool new_x,Number obj_factor,
                               Index m, Number *lmult, Bool new_lmult,
                               Index nele_hess, Index *iRow, Index *jCol,
                               Number *values, UserDataPtr user_data) except? 0
    ctypedef Bool (*Intermediate_CB)(Index alg_mod,
                                     Index iter_count, Number obj_value,
                                     Number inf_pr, Number inf_du,
                                     Number mu, Number d_norm,
                                     Number regularization_size,
                                     Number alpha_du, Number alpha_pr,
                                     Index ls_trials,
                                     UserDataPtr user_data) except? 0
    
    cdef IpoptProblem CreateIpoptProblem(
        Index n, Number* x_L, Number* x_U, Index m, Number* g_L, Number* g_U,
        Index nele_jac, Index nele_hess, Index index_style, Eval_F_CB eval_f,
        Eval_G_CB eval_g, Eval_Grad_F_CB eval_grad_f, Eval_Jac_G_CB eval_jac_g,
        Eval_H_CB eval_h)

    cdef ApplicationReturnStatus IpoptSolve(
        IpoptProblem ipopt_problem, Number* x, Number* g, Number* obj_val,
        Number* mult_g, Number* mult_x_L, Number* mult_x_U,
        UserDataPtr user_data)


cdef class Problem:
    cdef IpoptProblem ipopt_problem
    cdef readonly object obj, constr, obj_grad, constr_jac, hess
    cdef readonly object constr_jac_inds, hess_inds
    cdef readonly int m, n
    
    def __init__(self, x_bounds, constr_bounds, constr_jac_inds, hess_inds,
                 obj, constr, obj_grad, constr_jac, hess=None):
        #Convert input to numpy arrays
        x_L = np.require(x_bounds[0], np.double, 'AC')
        x_U = np.require(x_bounds[1], np.double, 'AC')
        constr_L = np.require(constr_bounds[0], np.double, 'AC')
        constr_U = np.require(constr_bounds[1], np.double, 'AC')
        
        if x_L.size != x_U.size or constr_L.size != constr_U.size:
            raise ValueError, 'Upper and lower bounds are of different sizes.'
        
        hess_inds = (np.ravel(hess_inds[0]), np.ravel(hess_inds[1]))
        constr_jac_inds = (np.ravel(constr_jac_inds[0]),
                           np.ravel(constr_jac_inds[1]))

        if (hess_inds[0].size != hess_inds[1].size or
            constr_jac_inds[0].size != constr_jac_inds[1].size):
            raise ValueError, 'Hessian column and row inds of different sizes.'
        
        self.n = x_L.size
        self.m = constr_L.size
        nele_hess = hess_inds[0].size
        nele_jac = constr_jac_inds[0].size
        
        self.obj = obj
        self.constr = constr
        self.obj_grad = obj_grad
        self.constr_jac = constr_jac
        self.constr_jac_inds = constr_jac_inds
        self.hess = hess
        self.hess_inds = hess_inds
        
        self.ipopt_problem = CreateIpoptProblem(
            self.n, <double*> npc.PyArray_DATA(x_L),
            <double*> npc.PyArray_DATA(x_U), self.m,
            <double*> npc.PyArray_DATA(constr_L),
            <double*> npc.PyArray_DATA(constr_U), nele_jac, nele_hess, 0,
            eval_f, eval_g, eval_grad_f, eval_jac_g, eval_h)

    def __dealloc__(self):
        if self.ipopt_problem is not NULL:
            free(self.ipopt_problem)
    
    def solve(self, start_x):
        x = np.array(start_x, np.double).ravel()
        if x.size != self.n:
            raise ValueError, 'Start point of invalid size.'
        
        cdef double obj_val
        cdef npc.npy_intp* constr_dims = [self.m]
        cdef npc.npy_intp* x_dims = [self.n]
        
        x_mult_L = npc.PyArray_SimpleNew(1, x_dims, npc.NPY_DOUBLE)
        x_mult_U = npc.PyArray_SimpleNew(1, x_dims, npc.NPY_DOUBLE)
        constr = npc.PyArray_SimpleNew(1, constr_dims, npc.NPY_DOUBLE)<commit_msg>Added options to problem class.<commit_after>from libc.string cimport memcpy

cimport numpy as npc
import numpy as np


npc.import_array()


cdef extern from "coin/IpStdCInterface.h":
    cdef struct IpoptProblemInfo:
        pass

    cdef enum ApplicationReturnStatus:
        Solve_Succeeded, Solved_To_Acceptable_Level,
        Infeasible_Problem_Detected, Search_Direction_Becomes_Too_Small,
        Diverging_Iterates, User_Requested_Stop, Feasible_Point_Found,
        Maximum_Iterations_Exceeded, Restoration_Failed,
        Error_In_Step_Computation, Maximum_CpuTime_Exceeded,
        Not_Enough_Degrees_Of_Freedom, Invalid_Problem_Definition,
        Invalid_Option, Invalid_Number_Detected, Unrecoverable_Exception,
        NonIpopt_Exception_Thrown, Insufficient_Memory, Internal_Error
    
    ctypedef double Number
    ctypedef int Index
    ctypedef int Int
    ctypedef int Bool
    ctypedef void *UserDataPtr
    ctypedef IpoptProblemInfo* IpoptProblem
    
    ctypedef Bool (*Eval_F_CB)(Index n, Number* x, Bool new_x,
                               Number* obj_value,
                               UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_Grad_F_CB)(Index n, Number* x, Bool new_x,
                                    Number* grad_f,
                                    UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_G_CB)(Index n, Number* x, Bool new_x,
                               Index m, Number* g,
                               UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_Jac_G_CB)(Index n, Number *x, Bool new_x,
                                   Index m, Index nele_jac,
                                   Index *iRow, Index *jCol, Number *values,
                                   UserDataPtr user_data) except? 0
    ctypedef Bool (*Eval_H_CB)(Index n, Number *x, Bool new_x,Number obj_factor,
                               Index m, Number *lmult, Bool new_lmult,
                               Index nele_hess, Index *iRow, Index *jCol,
                               Number *values, UserDataPtr user_data) except? 0
    ctypedef Bool (*Intermediate_CB)(Index alg_mod,
                                     Index iter_count, Number obj_value,
                                     Number inf_pr, Number inf_du,
                                     Number mu, Number d_norm,
                                     Number regularization_size,
                                     Number alpha_du, Number alpha_pr,
                                     Index ls_trials,
                                     UserDataPtr user_data) except? 0
    
    cdef IpoptProblem CreateIpoptProblem(
        Index n, Number* x_L, Number* x_U, Index m, Number* g_L, Number* g_U,
        Index nele_jac, Index nele_hess, Index index_style, Eval_F_CB eval_f,
        Eval_G_CB eval_g, Eval_Grad_F_CB eval_grad_f, Eval_Jac_G_CB eval_jac_g,
        Eval_H_CB eval_h)
    cdef ApplicationReturnStatus IpoptSolve(
        IpoptProblem ipopt_problem, Number* x, Number* g, Number* obj_val,
        Number* mult_g, Number* mult_x_L, Number* mult_x_U,
        UserDataPtr user_data)
    cdef void FreeIpoptProblem(IpoptProblem prob)
    cdef Bool AddIpoptStrOption(IpoptProblem prob, char* keyword, char* val)
    cdef Bool AddIpoptNumOption(IpoptProblem prob, char* keyword, Number val)
    cdef Bool AddIpoptIntOption(IpoptProblem prob, char* keyword, Int val)
    cdef Bool OpenIpoptOutputFile(IpoptProblem prob, char* file_name,
                                  Int print_level)
    cdef Bool SetIpoptProblemScaling(IpoptProblem prob, Number obj_scaling,
                                     Number* x_scaling, Number* g_scaling)
    cdef Bool SetIntermediateCallback(IpoptProblem ipopt_problem,
                                      Intermediate_CB intermediate_cb)


cdef class Problem:
    cdef IpoptProblem ipopt_problem
    cdef readonly object obj, constr, obj_grad, constr_jac, hess
    cdef readonly object constr_jac_inds, hess_inds
    cdef readonly int m, n
    
    def __init__(self, x_bounds, constr_bounds, constr_jac_inds, hess_inds,
                 obj, constr, obj_grad, constr_jac, hess=None):
        #Convert input to numpy arrays
        x_L = np.require(x_bounds[0], np.double, 'AC')
        x_U = np.require(x_bounds[1], np.double, 'AC')
        constr_L = np.require(constr_bounds[0], np.double, 'AC')
        constr_U = np.require(constr_bounds[1], np.double, 'AC')
        
        if x_L.size != x_U.size or constr_L.size != constr_U.size:
            raise ValueError, 'Upper and lower bounds are of different sizes.'
        
        hess_inds = (np.ravel(hess_inds[0]), np.ravel(hess_inds[1]))
        constr_jac_inds = (np.ravel(constr_jac_inds[0]),
                           np.ravel(constr_jac_inds[1]))
        
        if (hess_inds[0].size != hess_inds[1].size or
            constr_jac_inds[0].size != constr_jac_inds[1].size):
            raise ValueError, 'Hessian column and row inds of different sizes.'
        
        self.n = x_L.size
        self.m = constr_L.size
        nele_hess = hess_inds[0].size
        nele_jac = constr_jac_inds[0].size
        
        self.obj = obj
        self.constr = constr
        self.obj_grad = obj_grad
        self.constr_jac = constr_jac
        self.constr_jac_inds = constr_jac_inds
        self.hess = hess
        self.hess_inds = hess_inds
        
        self.ipopt_problem = CreateIpoptProblem(
            self.n, <double*> npc.PyArray_DATA(x_L),
            <double*> npc.PyArray_DATA(x_U), self.m,
            <double*> npc.PyArray_DATA(constr_L),
            <double*> npc.PyArray_DATA(constr_U), nele_jac, nele_hess, 0,
            eval_f, eval_g, eval_grad_f, eval_jac_g, eval_h)

        if nele_hess == 0 or hess is None:
            self.str_option('hessian_approximation', 'limited-memory')
    
    def __dealloc__(self):
        if self.ipopt_problem is not NULL:
            FreeIpoptProblem(self.ipopt_problem)

    def str_option(self, option, value):
        return bool(AddIpoptStrOption(self.ipopt_problem, option, value))
    
    def num_option(self, option, value):
        return bool(AddIpoptNumOption(self.ipopt_problem, option, value))

    def int_option(self, option, value):
        return bool(AddIpoptIntOption(self.ipopt_problem, option, value))

    def solve(self, start_x):
        if self.ipopt_problem is NULL:
            raise RuntimeError, 'Problem not initialized.'
        
        x = np.array(start_x, np.double).ravel()
        if x.size != self.n:
            raise ValueError, 'Start point of invalid size.'
        
        cdef double obj_val
        cdef npc.npy_intp* constr_dims = [self.m]
        cdef npc.npy_intp* x_dims = [self.n]
        
        x_mult_L = npc.PyArray_SimpleNew(1, x_dims, npc.NPY_DOUBLE)
        x_mult_U = npc.PyArray_SimpleNew(1, x_dims, npc.NPY_DOUBLE)
        constr = npc.PyArray_SimpleNew(1, constr_dims, npc.NPY_DOUBLE)
{'fraction_non_alphanumeric': 0.07432325470951401, 'fraction_numerical': 0.0038784233022004116, 'mean_word_length': 2.0697278911564627, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 27, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3662415', 'n_tokens_mistral': 4192, 'n_tokens_neox': 3988, 'n_words': 931}