From 52b10d7cf26ccac52799d824406c5527f75fa743 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:21:26 -0500 Subject: [PATCH 1/9] Remove apply_new --- src/callback.c | 81 +---------------------------------------- src/hook.h | 1 - src/pyipoptcoremodule.c | 22 +---------- 3 files changed, 4 insertions(+), 100 deletions(-) diff --git a/src/callback.c b/src/callback.c index 3d0ad23..c85fde9 100644 --- a/src/callback.c +++ b/src/callback.c @@ -135,27 +135,10 @@ eval_f(Index n, Number * x, Bool new_x, Number * obj_value, UserDataPtr data) // import_array (); import_array1(FALSE); - PyObject *arrayx = - PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, (char *)x); + PyObject *arrayx = PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, (char *)x); if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1; - arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) { arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -218,21 +201,6 @@ eval_grad_f(Index n, Number * x, Bool new_x, Number * grad_f, UserDataPtr data) if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -296,21 +264,6 @@ eval_g(Index n, Number * x, Bool new_x, Index m, Number * g, UserDataPtr data) if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -420,27 +373,11 @@ eval_jac_g(Index n, Number * x, Bool new_x, Py_CLEAR(arglist); //logger("[Callback:R] eval_jac_g(1)"); } else { - PyObject *arrayx = - PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, - (char *)x); + PyObject *arrayx = PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE,(char *)x); if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = - PyObject_CallObject(myowndata->apply_new_python, - arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OOO)", @@ -586,20 +523,6 @@ eval_h(Index n, Number * x, Bool new_x, Number obj_factor, if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } dims2[0] = m; PyObject *lagrangex = PyArray_SimpleNewFromData( 1, dims2, PyArray_DOUBLE, (char *)lambda); diff --git a/src/hook.h b/src/hook.h index 54058e4..c7e8d8f 100644 --- a/src/hook.h +++ b/src/hook.h @@ -44,7 +44,6 @@ typedef struct { PyObject *eval_g_python; PyObject *eval_jac_g_python; PyObject *eval_h_python; - PyObject *apply_new_python; PyObject *eval_intermediate_callback_python; PyObject *userdata; } DispatchData; diff --git a/src/pyipoptcoremodule.c b/src/pyipoptcoremodule.c index 1895310..2160969 100644 --- a/src/pyipoptcoremodule.c +++ b/src/pyipoptcoremodule.c @@ -293,7 +293,6 @@ static PyObject *create(PyObject * obj, PyObject * args) PyObject *g = NULL; PyObject *jacg = NULL; PyObject *h = NULL; - PyObject *applynew = NULL; DispatchData myowndata; @@ -333,18 +332,17 @@ static PyObject *create(PyObject * obj, PyObject * args) myowndata.eval_g_python = NULL; myowndata.eval_jac_g_python = NULL; myowndata.eval_h_python = NULL; - myowndata.apply_new_python = NULL; myowndata.userdata = NULL; /* "O!", &PyArray_Type &a_x */ - if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|OO:pyipoptcreate", + if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|O:pyipoptcreate", &n, &PyArray_Type, &xL, &PyArray_Type, &xU, &m, &PyArray_Type, &gL, &PyArray_Type, &gU, &nele_jac, &nele_hess, - &f, &gradf, &g, &jacg, &h, &applynew)) { + &f, &gradf, &g, &jacg, &h)) { retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); @@ -386,20 +384,6 @@ static PyObject *create(PyObject * obj, PyObject * args) logger("[PyIPOPT] Ipopt will use Hessian approximation.\n"); } - if (applynew != NULL) { - if (PyCallable_Check(applynew)) { - myowndata.apply_new_python = applynew; - } else { - PyErr_SetString(PyExc_TypeError, - "Need a callable object for function applynew."); - retval = NULL; - SAFE_FREE(x_L); - SAFE_FREE(x_U); - SAFE_FREE(g_L); - SAFE_FREE(g_U); - return retval; - } - } if (m < 0 || n < 0) { PyErr_SetString(PyExc_TypeError, "m or n can't be negative"); retval = NULL; @@ -445,7 +429,6 @@ static PyObject *create(PyObject * obj, PyObject * args) Py_XINCREF(g); Py_XINCREF(jacg); Py_XINCREF(h); - Py_XINCREF(applynew); /* create the Ipopt Problem */ @@ -708,7 +691,6 @@ PyObject *close_model(PyObject * self, PyObject * args) Py_XDECREF(dp->eval_g_python); Py_XDECREF(dp->eval_jac_g_python); Py_XDECREF(dp->eval_h_python); - Py_XDECREF(dp->apply_new_python); FreeIpoptProblem(obj->nlp); obj->nlp = NULL; From 65bbd147ec924e3442a2495dd64585e1ab8f25a2 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:23:05 -0500 Subject: [PATCH 2/9] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3eb9c0b..4b861d6 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The file "hs071.py" contains a toy optimization problem. If everything is OK, py Pyipopt is a legitimate Python module, you can inspect it by using standard Python commands like "dir" or "help". All functions in pyipopt are well documented. -Since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function as well as the "apply_new" callback function, Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). +Since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). Contributing ------------ From a24c556ce1c740be8202e001b22c4ffc6d6565bd Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:33:29 -0500 Subject: [PATCH 3/9] fix readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cf1a41..3caf146 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The file "hs071.py" contains a toy optimization problem. If everything is OK, py Pyipopt is a legitimate Python module, you can inspect it by using standard Python commands like "dir" or "help". All functions in pyipopt are documented in details. -**Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function as well as the "apply_new" callback function, Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). +**Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). Contributing ------------ From 341852ba5160cc27d69503dd1ce6f5a09a82f067 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Mon, 23 Apr 2018 22:24:52 -0500 Subject: [PATCH 4/9] removed annoying pydebug message --- src/callback.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/callback.c b/src/callback.c index 3d0ad23..378663b 100644 --- a/src/callback.c +++ b/src/callback.c @@ -634,7 +634,6 @@ eval_h(Index n, Number * x, Bool new_x, Number obj_factor, double *tempdata = (double *)result->data; for (i = 0; i < nele_hess; i++) { values[i] = tempdata[i]; - logger("PyDebug %lf", values[i]); } Py_CLEAR(arrayx); Py_CLEAR(lagrangex); From b023cbbcb982f8a7fe9d5dee71fabb467aca6f13 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:21:26 -0500 Subject: [PATCH 5/9] Remove apply_new --- src/callback.c | 81 +---------------------------------------- src/hook.h | 1 - src/pyipoptcoremodule.c | 22 +---------- 3 files changed, 4 insertions(+), 100 deletions(-) diff --git a/src/callback.c b/src/callback.c index 378663b..eef2ec8 100644 --- a/src/callback.c +++ b/src/callback.c @@ -135,27 +135,10 @@ eval_f(Index n, Number * x, Bool new_x, Number * obj_value, UserDataPtr data) // import_array (); import_array1(FALSE); - PyObject *arrayx = - PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, (char *)x); + PyObject *arrayx = PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, (char *)x); if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1; - arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) { arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -218,21 +201,6 @@ eval_grad_f(Index n, Number * x, Bool new_x, Number * grad_f, UserDataPtr data) if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -296,21 +264,6 @@ eval_g(Index n, Number * x, Bool new_x, Index m, Number * g, UserDataPtr data) if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } - PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OO)", arrayx, (PyObject *) user_data); @@ -420,27 +373,11 @@ eval_jac_g(Index n, Number * x, Bool new_x, Py_CLEAR(arglist); //logger("[Callback:R] eval_jac_g(1)"); } else { - PyObject *arrayx = - PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE, - (char *)x); + PyObject *arrayx = PyArray_SimpleNewFromData(1, dims, PyArray_DOUBLE,(char *)x); if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = - PyObject_CallObject(myowndata->apply_new_python, - arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } PyObject *arglist; if (user_data != NULL) arglist = Py_BuildValue("(OOO)", @@ -586,20 +523,6 @@ eval_h(Index n, Number * x, Bool new_x, Number obj_factor, if (!arrayx) return FALSE; - if (new_x && myowndata->apply_new_python) { - /* Call the python function to applynew */ - PyObject *arg1 = Py_BuildValue("(O)", arrayx); - PyObject *tempresult = PyObject_CallObject( - myowndata->apply_new_python, arg1); - if (tempresult == NULL) { - logger("[Error] Python function apply_new returns NULL"); - PyErr_Print(); - Py_DECREF(arg1); - return FALSE; - } - Py_DECREF(arg1); - Py_DECREF(tempresult); - } dims2[0] = m; PyObject *lagrangex = PyArray_SimpleNewFromData( 1, dims2, PyArray_DOUBLE, (char *)lambda); diff --git a/src/hook.h b/src/hook.h index 54058e4..c7e8d8f 100644 --- a/src/hook.h +++ b/src/hook.h @@ -44,7 +44,6 @@ typedef struct { PyObject *eval_g_python; PyObject *eval_jac_g_python; PyObject *eval_h_python; - PyObject *apply_new_python; PyObject *eval_intermediate_callback_python; PyObject *userdata; } DispatchData; diff --git a/src/pyipoptcoremodule.c b/src/pyipoptcoremodule.c index 1895310..2160969 100644 --- a/src/pyipoptcoremodule.c +++ b/src/pyipoptcoremodule.c @@ -293,7 +293,6 @@ static PyObject *create(PyObject * obj, PyObject * args) PyObject *g = NULL; PyObject *jacg = NULL; PyObject *h = NULL; - PyObject *applynew = NULL; DispatchData myowndata; @@ -333,18 +332,17 @@ static PyObject *create(PyObject * obj, PyObject * args) myowndata.eval_g_python = NULL; myowndata.eval_jac_g_python = NULL; myowndata.eval_h_python = NULL; - myowndata.apply_new_python = NULL; myowndata.userdata = NULL; /* "O!", &PyArray_Type &a_x */ - if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|OO:pyipoptcreate", + if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|O:pyipoptcreate", &n, &PyArray_Type, &xL, &PyArray_Type, &xU, &m, &PyArray_Type, &gL, &PyArray_Type, &gU, &nele_jac, &nele_hess, - &f, &gradf, &g, &jacg, &h, &applynew)) { + &f, &gradf, &g, &jacg, &h)) { retval = NULL; SAFE_FREE(x_L); SAFE_FREE(x_U); @@ -386,20 +384,6 @@ static PyObject *create(PyObject * obj, PyObject * args) logger("[PyIPOPT] Ipopt will use Hessian approximation.\n"); } - if (applynew != NULL) { - if (PyCallable_Check(applynew)) { - myowndata.apply_new_python = applynew; - } else { - PyErr_SetString(PyExc_TypeError, - "Need a callable object for function applynew."); - retval = NULL; - SAFE_FREE(x_L); - SAFE_FREE(x_U); - SAFE_FREE(g_L); - SAFE_FREE(g_U); - return retval; - } - } if (m < 0 || n < 0) { PyErr_SetString(PyExc_TypeError, "m or n can't be negative"); retval = NULL; @@ -445,7 +429,6 @@ static PyObject *create(PyObject * obj, PyObject * args) Py_XINCREF(g); Py_XINCREF(jacg); Py_XINCREF(h); - Py_XINCREF(applynew); /* create the Ipopt Problem */ @@ -708,7 +691,6 @@ PyObject *close_model(PyObject * self, PyObject * args) Py_XDECREF(dp->eval_g_python); Py_XDECREF(dp->eval_jac_g_python); Py_XDECREF(dp->eval_h_python); - Py_XDECREF(dp->apply_new_python); FreeIpoptProblem(obj->nlp); obj->nlp = NULL; From fbab665090ddc7724cebb0df4872832a60c90624 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:23:05 -0500 Subject: [PATCH 6/9] fix readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4cf1a41..162ddf9 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,11 @@ The file "hs071.py" contains a toy optimization problem. If everything is OK, py Pyipopt is a legitimate Python module, you can inspect it by using standard Python commands like "dir" or "help". All functions in pyipopt are documented in details. +<<<<<<< HEAD **Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function as well as the "apply_new" callback function, Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). +======= +Since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). +>>>>>>> 65bbd14... fix readme Contributing ------------ From 595223090f590b30148ae6214e6e161d7d3c7670 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Thu, 19 Apr 2018 20:33:29 -0500 Subject: [PATCH 7/9] fix readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 162ddf9..4a1c500 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,15 @@ The file "hs071.py" contains a toy optimization problem. If everything is OK, py Pyipopt is a legitimate Python module, you can inspect it by using standard Python commands like "dir" or "help". All functions in pyipopt are documented in details. +<<<<<<< HEAD <<<<<<< HEAD **Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function as well as the "apply_new" callback function, Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). ======= Since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). >>>>>>> 65bbd14... fix readme +======= +**Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). +>>>>>>> a24c556... fix readme Contributing ------------ From a978da3841fea1c74cdb76e86045f49407fb7c3d Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Mon, 23 Apr 2018 22:24:52 -0500 Subject: [PATCH 8/9] removed annoying pydebug message From f0aa6af96f5e56cea47f8c7cf65b28428152ecb4 Mon Sep 17 00:00:00 2001 From: nanthony21 Date: Fri, 29 Jun 2018 18:05:00 -0500 Subject: [PATCH 9/9] one more readme fix --- README.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4a1c500..4f5f4b7 100644 --- a/README.md +++ b/README.md @@ -60,15 +60,9 @@ The file "hs071.py" contains a toy optimization problem. If everything is OK, py Pyipopt is a legitimate Python module, you can inspect it by using standard Python commands like "dir" or "help". All functions in pyipopt are documented in details. -<<<<<<< HEAD -<<<<<<< HEAD -**Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function as well as the "apply_new" callback function, Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). -======= -Since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). ->>>>>>> 65bbd14... fix readme -======= + **Hessian Estimation**: since Hessian estimation is usually tedious, Ipopt can solve problems without Hessian estimation. Pyipopt also supports this feature. The file "hs071.py" demonstrates the idea. If you provide the pyipopt.create function with an "eval_h" callback function Ipopt will delegate the Hessian matrix calculation to your function (otherwise Ipopt will approximate Hessian for you). ->>>>>>> a24c556... fix readme + Contributing ------------