#include <cassert>
#include <jni.h>
#include "IpTNLP.hpp"
#include "IpIpoptApplication.hpp"
#include "org_coinor_Ipopt.h"
using namespace std;
using namespace Ipopt;
#ifdef IPOPT_SINGLE
typedef jfloat jnumber;
typedef jfloatArray jnumberArray;
#define NewNumberArray NewFloatArray
#define GetNumberArrayRegion GetFloatArrayRegion
#define SetNumberArrayRegion SetFloatArrayRegion
#else
typedef jdouble jnumber;
typedef jdoubleArray jnumberArray;
#define NewNumberArray NewDoubleArray
#define GetNumberArrayRegion GetDoubleArrayRegion
#define SetNumberArrayRegion SetDoubleArrayRegion
#endif
class Jipopt: public TNLP
{
public:
Jipopt(
JNIEnv* env,
jobject solver,
jint n,
jint m,
jint nele_jac,
jint nele_hess,
jint index_style
);
virtual ~Jipopt()
{
}
virtual bool get_nlp_info(
Index& n,
Index& m,
Index& nnz_jac_g,
Index& nnz_h_lag,
IndexStyleEnum& index_style
);
virtual bool get_bounds_info(
Index n,
Number* x_l,
Number* x_u,
Index m,
Number* g_l,
Number* g_u
);
virtual bool get_starting_point(
Index n,
bool init_x,
Number* x,
bool init_z,
Number* z_L,
Number* z_U,
Index m,
bool init_lambda,
Number* lambda
);
virtual bool eval_f(
Index n,
const Number* x,
bool new_x,
Number& obj_value
);
virtual bool eval_grad_f(
Index n,
const Number* x,
bool new_x,
Number* grad_f
);
virtual bool eval_g(
Index n,
const Number* x,
bool new_x,
Index m,
Number* g
);
virtual bool eval_jac_g(
Index n,
const Number* x,
bool new_x,
Index m,
Index nele_jac,
Index* iRow,
Index* jCol,
Number* values
);
virtual bool eval_h(
Index n,
const Number* x,
bool new_x,
Number obj_factor,
Index m,
const Number* lambda,
bool new_lambda,
Index nele_hess,
Index* iRow,
Index* jCol,
Number* values
);
virtual void finalize_solution(
SolverReturn status,
Index n,
const Number* x,
const Number* z_L,
const Number* z_U,
Index m,
const Number* g,
const Number* lambda,
Number obj_value,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
);
virtual bool intermediate_callback(
AlgorithmMode mode,
Index iter,
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,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
);
virtual bool get_scaling_parameters(
Number& obj_scaling,
bool& use_x_scaling,
Index n,
Number* x_scaling,
bool& use_g_scaling,
Index m,
Number* g_scaling
);
virtual Index get_number_of_nonlinear_variables();
virtual bool get_list_of_nonlinear_variables(
Index num_nonlin_vars,
Index* pos_nonlin_vars
);
public:
JNIEnv* env;
jobject solver;
jint n;
jint m;
jint nele_jac;
jint nele_hess;
jint index_style;
jnumberArray mult_gj;
jnumberArray mult_x_Lj;
jnumberArray mult_x_Uj;
jnumberArray xj;
jnumberArray fj;
jnumberArray grad_fj;
jnumberArray gj;
jnumberArray jac_gj;
jnumberArray hessj;
jboolean using_scaling_parameters;
jboolean using_LBFGS;
SmartPtr<IpoptApplication> application;
jmethodID get_bounds_info_;
jmethodID get_starting_point_;
jmethodID eval_f_;
jmethodID eval_grad_f_;
jmethodID eval_g_;
jmethodID eval_jac_g_;
jmethodID eval_h_;
jmethodID intermediate_callback_;
jmethodID get_scaling_parameters_;
jmethodID get_number_of_nonlinear_variables_;
jmethodID get_list_of_nonlinear_variables_;
private:
Jipopt(const Jipopt&);
Jipopt& operator=(const Jipopt&);
};
Jipopt::Jipopt(
JNIEnv* env_,
jobject solver_,
jint n_,
jint m_,
jint nele_jac_,
jint nele_hess_,
jint index_style_
)
: env(env_), solver(solver_), n(n_), m(m_), nele_jac(nele_jac_), nele_hess(nele_hess_), index_style(index_style_),
mult_gj(NULL), mult_x_Lj(NULL), mult_x_Uj(NULL), xj(NULL), fj(NULL), grad_fj(NULL),
gj(NULL), jac_gj(NULL), hessj(NULL),
using_scaling_parameters(false), using_LBFGS(false),
application(new IpoptApplication())
{
application->RethrowNonIpoptException(false);
jclass solverCls = env->GetObjectClass(solver);
#ifndef IPOPT_SINGLE
get_bounds_info_ = env->GetMethodID(solverCls, "get_bounds_info", "(I[D[DI[D[D)Z");
get_starting_point_ = env->GetMethodID(solverCls, "get_starting_point", "(IZ[DZ[D[DIZ[D)Z");
eval_f_ = env->GetMethodID(solverCls, "eval_f", "(I[DZ[D)Z");
eval_grad_f_ = env->GetMethodID(solverCls, "eval_grad_f", "(I[DZ[D)Z");
eval_g_ = env->GetMethodID(solverCls, "eval_g", "(I[DZI[D)Z");
eval_jac_g_ = env->GetMethodID(solverCls, "eval_jac_g", "(I[DZII[I[I[D)Z");
eval_h_ = env->GetMethodID(solverCls, "eval_h", "(I[DZDI[DZI[I[I[D)Z");
get_scaling_parameters_ = env->GetMethodID(solverCls, "get_scaling_parameters", "([DI[DI[D[Z)Z");
intermediate_callback_ = env->GetMethodID(solverCls, "intermediate_callback", "(IIDDDDDDDDIJJ)Z");
#else
get_bounds_info_ = env->GetMethodID(solverCls, "get_bounds_info", "(I[F[FI[F[F)Z");
get_starting_point_ = env->GetMethodID(solverCls, "get_starting_point", "(IZ[FZ[F[FIZ[F)Z");
eval_f_ = env->GetMethodID(solverCls, "eval_f", "(I[FZ[F)Z");
eval_grad_f_ = env->GetMethodID(solverCls, "eval_grad_f", "(I[FZ[F)Z");
eval_g_ = env->GetMethodID(solverCls, "eval_g", "(I[FZI[F)Z");
eval_jac_g_ = env->GetMethodID(solverCls, "eval_jac_g", "(I[FZII[I[I[F)Z");
eval_h_ = env->GetMethodID(solverCls, "eval_h", "(I[FZFI[FZI[I[I[F)Z");
get_scaling_parameters_ = env->GetMethodID(solverCls, "get_scaling_parameters", "([FI[FI[F[Z)Z");
intermediate_callback_ = env->GetMethodID(solverCls, "intermediate_callback", "(IIFFFFFFFFIJJ)Z");
#endif
get_number_of_nonlinear_variables_ = env->GetMethodID(solverCls, "get_number_of_nonlinear_variables", "()I");
get_list_of_nonlinear_variables_ = env->GetMethodID(solverCls, "get_list_of_nonlinear_variables", "(I[I)Z");
if( get_bounds_info_ == 0 || get_starting_point_ == 0 || eval_f_ == 0
|| eval_grad_f_ == 0 || eval_g_ == 0 || eval_jac_g_ == 0 || eval_h_ == 0
|| get_scaling_parameters_ == 0 || get_number_of_nonlinear_variables_ == 0
|| get_list_of_nonlinear_variables_ == 0 )
{
std::cerr << "Expected callback methods missing on JIpopt.java" << std::endl;
}
assert(get_bounds_info_ != 0);
assert(get_starting_point_ != 0);
assert(eval_f_ != 0);
assert(eval_grad_f_ != 0);
assert(eval_g_ != 0);
assert(eval_jac_g_ != 0);
assert(eval_h_ != 0);
assert(get_scaling_parameters_ != 0);
assert(get_number_of_nonlinear_variables_ != 0);
assert(get_list_of_nonlinear_variables_ != 0);
}
bool Jipopt::get_nlp_info(
Index& n,
Index& m,
Index& nnz_jac_g,
Index& nnz_h_lag,
IndexStyleEnum& index_style)
{
n = this->n;
m = this->m;
nnz_jac_g = this->nele_jac;
nnz_h_lag = this->nele_hess;
index_style = (IndexStyleEnum) this->index_style;
return true;
}
bool Jipopt::get_bounds_info(
Index n,
Number* x_l,
Number* x_u,
Index m,
Number* g_l,
Number* g_u)
{
jnumberArray x_lj = NULL;
jnumberArray x_uj = NULL;
jnumberArray g_lj = NULL;
jnumberArray g_uj = NULL;
assert(x_l != NULL);
assert(x_u != NULL);
assert(g_l != NULL);
assert(g_u != NULL);
x_lj = env->NewNumberArray(n);
x_uj = env->NewNumberArray(n);
g_lj = env->NewNumberArray(m);
g_uj = env->NewNumberArray(m);
if( !env->CallBooleanMethod(solver, get_bounds_info_, n, x_lj, x_uj, m, g_lj, g_uj) )
{
return false;
}
env->GetNumberArrayRegion(x_lj, 0, n, x_l);
env->GetNumberArrayRegion(x_uj, 0, n, x_u);
env->GetNumberArrayRegion(g_lj, 0, m, g_l);
env->GetNumberArrayRegion(g_uj, 0, m, g_u);
return true;
}
bool Jipopt::get_starting_point(
Index n,
bool init_x,
Number* x,
bool init_z,
Number* z_L,
Number* z_U,
Index m,
bool init_lambda,
Number* lambda)
{
jnumberArray xj = this->xj;
jnumberArray z_lj = this->mult_x_Lj;
jnumberArray z_uj = this->mult_x_Uj;
jnumberArray lambdaj = this->mult_gj;
if( !env->CallBooleanMethod(solver, get_starting_point_, n, init_x, xj, init_z, z_lj, z_uj, m, init_lambda, lambdaj) )
{
return false;
}
if( init_x )
{
env->GetNumberArrayRegion(xj, 0, n, x);
}
if( init_z )
{
env->GetNumberArrayRegion(z_lj, 0, n, z_L);
env->GetNumberArrayRegion(z_uj, 0, n, z_U);
}
if( init_lambda )
{
env->GetNumberArrayRegion(lambdaj, 0, m, lambda);
}
return true;
}
bool Jipopt::eval_f(
Index n,
const Number* x,
bool new_x,
Number& obj_value)
{
if( new_x )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
jboolean new_xj = new_x;
if( !env->CallBooleanMethod(solver, eval_f_, n, xj, new_xj, fj) )
{
return false;
}
env->GetNumberArrayRegion(fj, 0, 1, &obj_value);
return true;
}
bool Jipopt::eval_grad_f(
Index n,
const Number* x,
bool new_x,
Number* grad_f)
{
if( new_x )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
jboolean new_xj = new_x;
if( !env->CallBooleanMethod(solver, eval_grad_f_, n, xj, new_xj, grad_fj) )
{
return false;
}
env->GetNumberArrayRegion(grad_fj, 0, n, grad_f);
return true;
}
bool Jipopt::eval_g(
Index n,
const Number* x,
bool new_x,
Index m,
Number* g)
{
if( new_x )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
jboolean new_xj = new_x;
if( !env->CallBooleanMethod(solver, eval_g_, n, xj, new_xj, m, gj) )
{
return false;
}
env->GetNumberArrayRegion(gj, 0, m, g);
return true;
}
bool Jipopt::eval_jac_g(
Index n,
const Number* x,
bool new_x,
Index m,
Index nele_jac,
Index* iRow,
Index* jCol,
Number* jac_g)
{
if( new_x && x != NULL )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
jintArray iRowj = NULL;
jintArray jColj = NULL;
if( iRow != NULL && jCol != NULL )
{
iRowj = env->NewIntArray(nele_jac);
jColj = env->NewIntArray(nele_jac);
}
jboolean new_xj = new_x;
if( !env->CallBooleanMethod(solver, eval_jac_g_, n, xj, new_xj, m, nele_jac, iRowj, jColj, jac_g == NULL ? NULL : jac_gj) )
{
return false;
}
if( jac_g != NULL )
{
env->GetNumberArrayRegion(jac_gj, 0, nele_jac, jac_g);
}
if( iRow != NULL && jCol != NULL )
{
if( sizeof(jint) == sizeof(Index) )
{
env->GetIntArrayRegion(iRowj, 0, nele_jac, reinterpret_cast<jint*>(iRow));
env->GetIntArrayRegion(jColj, 0, nele_jac, reinterpret_cast<jint*>(jCol));
}
else
{
jint* tmp = new jint[nele_jac];
env->GetIntArrayRegion(iRowj, 0, nele_jac, tmp);
for( Index i = 0; i < nele_jac; ++i )
{
iRow[i] = (Index) tmp[i];
}
env->GetIntArrayRegion(jColj, 0, nele_jac, tmp);
for( Index i = 0; i < nele_jac; ++i )
{
jCol[i] = (Index) tmp[i];
}
delete[] tmp;
}
}
return true;
}
bool Jipopt::eval_h(
Index n,
const Number* x,
bool new_x,
Number obj_factor,
Index m,
const Number* lambda,
bool new_lambda,
Index nele_hess,
Index* iRow,
Index* jCol,
Number* hess)
{
if( new_x && x != NULL )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
if( new_lambda && lambda != NULL )
{
env->SetNumberArrayRegion(mult_gj, 0, m, const_cast<Number*>(lambda));
}
jintArray iRowj = NULL;
jintArray jColj = NULL;
if( iRow != NULL && jCol != NULL )
{
iRowj = env->NewIntArray(nele_hess);
jColj = env->NewIntArray(nele_hess);
}
jboolean new_xj = new_x;
jboolean new_lambdaj = new_lambda;
if( !env->CallBooleanMethod(solver, eval_h_, n, xj, new_xj, obj_factor, m, mult_gj, new_lambdaj, nele_hess, iRowj, jColj, hess == NULL ? NULL : hessj) )
{
return false;
}
if( hess != NULL )
{
env->GetNumberArrayRegion(hessj, 0, nele_hess, hess);
}
if( iRow != NULL && jCol != NULL )
{
if( sizeof(jint) == sizeof(Index) )
{
env->GetIntArrayRegion(iRowj, 0, nele_hess, reinterpret_cast<jint*>(iRow));
env->GetIntArrayRegion(jColj, 0, nele_hess, reinterpret_cast<jint*>(jCol));
}
else
{
jint* tmp = new jint[nele_hess];
env->GetIntArrayRegion(iRowj, 0, nele_hess, tmp);
for( Index i = 0; i < nele_hess; ++i )
{
iRow[i] = (Index) tmp[i];
}
env->GetIntArrayRegion(jColj, 0, nele_hess, tmp);
for( Index i = 0; i < nele_hess; ++i )
{
jCol[i] = (Index) tmp[i];
}
delete[] tmp;
}
}
return true;
}
void Jipopt::finalize_solution(
SolverReturn ,
Index n,
const Number* x,
const Number* z_L,
const Number* z_U,
Index m,
const Number* g,
const Number* lambda,
Number obj_value,
const IpoptData* ,
IpoptCalculatedQuantities*
)
{
if( x != NULL )
{
env->SetNumberArrayRegion(xj, 0, n, const_cast<Number*>(x));
}
if( z_L != NULL )
{
env->SetNumberArrayRegion(mult_x_Lj, 0, n, const_cast<Number*>(z_L));
}
if( z_U != NULL )
{
env->SetNumberArrayRegion(mult_x_Uj, 0, n, const_cast<Number*>(z_U));
}
if( g != NULL )
{
env->SetNumberArrayRegion(gj, 0, m, const_cast<Number*>(g));
}
if( lambda != NULL )
{
env->SetNumberArrayRegion(mult_gj, 0, m, const_cast<Number*>(lambda));
}
env->GetNumberArrayRegion(fj, 0, 1, &obj_value);
}
bool Jipopt::intermediate_callback(
AlgorithmMode mode,
Index iter,
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,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
)
{
return env->CallBooleanMethod(solver, intermediate_callback_, (int)mode, iter, obj_value, inf_pr, inf_du, mu, d_norm, regularization_size, alpha_du, alpha_pr, ls_trials, ip_data, ip_cq);
}
bool Jipopt::get_scaling_parameters(
Number& obj_scaling,
bool& use_x_scaling,
Index n,
Number* x_scaling,
bool& use_g_scaling,
Index m,
Number* g_scaling)
{
if( !using_scaling_parameters )
{
return false;
}
jnumberArray obj_scaling_j = env->NewNumberArray(1);
jnumberArray x_scaling_j = env->NewNumberArray(n);
jnumberArray g_scaling_j = env->NewNumberArray(m);
jbooleanArray use_x_g_scaling_j = env->NewBooleanArray(2);
env->CallBooleanMethod(solver, get_scaling_parameters_, obj_scaling_j, n, x_scaling_j, m, g_scaling_j, use_x_g_scaling_j);
jboolean* use_x_g_scaling = env->GetBooleanArrayElements(use_x_g_scaling_j, 0);
env->GetNumberArrayRegion(obj_scaling_j, 0, 1, &obj_scaling);
if( use_x_g_scaling[0] )
{
env->GetNumberArrayRegion(x_scaling_j, 0, n, x_scaling);
use_x_scaling = true;
}
else
{
use_x_scaling = false;
}
if( use_x_g_scaling[1] )
{
env->GetNumberArrayRegion(g_scaling_j, 0, n, g_scaling);
use_g_scaling = true;
}
else
{
use_g_scaling = false;
}
env->ReleaseBooleanArrayElements(use_x_g_scaling_j, use_x_g_scaling, 0);
return true;
}
Index Jipopt::get_number_of_nonlinear_variables()
{
if( using_LBFGS )
{
return env->CallIntMethod(solver, get_number_of_nonlinear_variables_);
}
return -1;
}
bool Jipopt::get_list_of_nonlinear_variables(
Index num_nonlin_vars,
Index* pos_nonlin_vars)
{
if( !using_LBFGS )
{
return false;
}
jintArray pos_nonlin_vars_j = env->NewIntArray(num_nonlin_vars);
if( !env->CallBooleanMethod(solver, get_list_of_nonlinear_variables_, num_nonlin_vars, pos_nonlin_vars_j) )
{
return false;
}
if( pos_nonlin_vars != NULL )
{
if( sizeof(jint) == sizeof(Index) )
{
env->GetIntArrayRegion(pos_nonlin_vars_j, 0, num_nonlin_vars, reinterpret_cast<jint*>(pos_nonlin_vars));
}
else
{
jint* tmp = new jint[num_nonlin_vars];
env->GetIntArrayRegion(pos_nonlin_vars_j, 0, num_nonlin_vars, tmp);
for( Index i = 0; i < num_nonlin_vars; ++i )
{
pos_nonlin_vars[i] = (Index) tmp[i];
}
delete[] tmp;
}
}
return true;
}
extern "C"
{
JNIEXPORT jlong JNICALL Java_org_coinor_Ipopt_CreateIpoptProblem(
JNIEnv* env,
jobject obj_this,
jint n,
jint m,
jint nele_jac,
jint nele_hess,
jint index_style)
{
SmartPtr<Jipopt>* pproblem = new SmartPtr<Jipopt>;
*pproblem = new Jipopt(env, obj_this, n, m, nele_jac, nele_hess, index_style);
return (jlong) pproblem;
}
JNIEXPORT jint JNICALL Java_org_coinor_Ipopt_OptimizeTNLP(
JNIEnv* env,
jobject obj_this,
jlong pipopt,
jnumberArray xj,
jnumberArray gj,
jnumberArray obj_valj,
jnumberArray mult_gj,
jnumberArray mult_x_Lj,
jnumberArray mult_x_Uj,
jnumberArray callback_grad_f,
jnumberArray callback_jac_g,
jnumberArray callback_hess)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
problem->env = env;
problem->solver = obj_this;
problem->xj = xj;
problem->gj = gj;
problem->fj = obj_valj;
problem->mult_gj = mult_gj;
problem->mult_x_Lj = mult_x_Lj;
problem->mult_x_Uj = mult_x_Uj;
problem->grad_fj = callback_grad_f;
problem->jac_gj = callback_jac_g;
problem->hessj = callback_hess;
ApplicationReturnStatus status;
status = problem->application->Initialize();
if( status != Solve_Succeeded )
{
printf("\n\n*** Error during initialization!\n");
return (int) status;
}
status = problem->application->OptimizeTNLP(problem);
return (jint) status;
}
JNIEXPORT jboolean JNICALL Java_org_coinor_Ipopt_GetCurrIterate(
JNIEnv* env,
jobject ,
jlong pipopt,
jlong jip_data,
jlong jip_cq,
jboolean jscaled,
jint jn,
jnumberArray jx,
jnumberArray jz_L,
jnumberArray jz_U,
jint jm,
jnumberArray jg,
jnumberArray jlambda)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
IpoptData* ip_data = (IpoptData*)jip_data;
IpoptCalculatedQuantities* ip_cq = (IpoptCalculatedQuantities*)jip_cq;
Index n = jn;
Index m = jm;
Number* x = NULL;
Number* z_L = NULL;
Number* z_U = NULL;
Number* g = NULL;
Number* lambda = NULL;
if( jx != NULL )
{
x = new Number[n];
}
if( jz_L != NULL )
{
z_L = new Number[n];
}
if( jz_U != NULL )
{
z_U = new Number[n];
}
if( jg != NULL )
{
g = new Number[m];
}
if( jlambda != NULL )
{
lambda = new Number[m];
}
bool ok = problem->get_curr_iterate(ip_data, ip_cq, jscaled, n, x, z_L, z_U, m, g, lambda);
if( ok )
{
if( jx != NULL )
{
env->SetNumberArrayRegion(jx, 0, n, const_cast<Number*>(x));
}
if( jz_L != NULL )
{
env->SetNumberArrayRegion(jz_L, 0, n, const_cast<Number*>(z_L));
}
if( jz_U != NULL )
{
env->SetNumberArrayRegion(jz_U, 0, n, const_cast<Number*>(z_U));
}
if( jg != NULL )
{
env->SetNumberArrayRegion(jg, 0, m, const_cast<Number*>(g));
}
if( jlambda != NULL )
{
env->SetNumberArrayRegion(jlambda, 0, m, const_cast<Number*>(lambda));
}
}
delete[] lambda;
delete[] g;
delete[] z_U;
delete[] z_L;
delete[] x;
return ok;
}
JNIEXPORT jboolean JNICALL Java_org_coinor_Ipopt_GetCurrViolations(
JNIEnv* env,
jobject ,
jlong pipopt,
jlong jip_data,
jlong jip_cq,
jboolean jscaled,
jint jn,
jnumberArray jx_L_violation,
jnumberArray jx_U_violation,
jnumberArray jcompl_x_L,
jnumberArray jcompl_x_U,
jnumberArray jgrad_lag_x,
jint jm,
jnumberArray jnlp_constraint_violation,
jnumberArray jcompl_g)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
IpoptData* ip_data = (IpoptData*)jip_data;
IpoptCalculatedQuantities* ip_cq = (IpoptCalculatedQuantities*)jip_cq;
Index n = jn;
Index m = jm;
Number* x_L_violation = NULL;
Number* x_U_violation = NULL;
Number* compl_x_L = NULL;
Number* compl_x_U = NULL;
Number* grad_lag_x = NULL;
Number* nlp_constraint_violation = NULL;
Number* compl_g = NULL;
if( jx_L_violation != NULL )
{
x_L_violation = new Number[n];
}
if( jx_U_violation != NULL )
{
x_U_violation = new Number[n];
}
if( jcompl_x_L != NULL )
{
compl_x_L = new Number[n];
}
if( jcompl_x_U != NULL )
{
compl_x_U = new Number[n];
}
if( jgrad_lag_x != NULL )
{
grad_lag_x = new Number[n];
}
if( jnlp_constraint_violation != NULL )
{
nlp_constraint_violation = new Number[m];
}
if( jcompl_g != NULL )
{
compl_g = new Number[m];
}
bool ok = problem->get_curr_violations(ip_data, ip_cq, jscaled, n, x_L_violation, x_U_violation, compl_x_L, compl_x_U, grad_lag_x, m, nlp_constraint_violation, compl_g);
if( ok )
{
if( jx_L_violation != NULL )
{
env->SetNumberArrayRegion(jx_L_violation, 0, n, const_cast<Number*>(x_L_violation));
}
if( jx_U_violation != NULL )
{
env->SetNumberArrayRegion(jx_U_violation, 0, n, const_cast<Number*>(x_U_violation));
}
if( jcompl_x_L != NULL )
{
env->SetNumberArrayRegion(jcompl_x_L, 0, n, const_cast<Number*>(compl_x_L));
}
if( jcompl_x_U != NULL )
{
env->SetNumberArrayRegion(jcompl_x_U, 0, n, const_cast<Number*>(compl_x_U));
}
if( jgrad_lag_x != NULL )
{
env->SetNumberArrayRegion(jgrad_lag_x, 0, n, const_cast<Number*>(grad_lag_x));
}
if( jnlp_constraint_violation != NULL )
{
env->SetNumberArrayRegion(jnlp_constraint_violation, 0, m, const_cast<Number*>(nlp_constraint_violation));
}
if( jcompl_g != NULL )
{
env->SetNumberArrayRegion(jcompl_g, 0, m, const_cast<Number*>(compl_g));
}
}
delete[] compl_g;
delete[] nlp_constraint_violation;
delete[] grad_lag_x;
delete[] compl_x_U;
delete[] compl_x_L;
delete[] x_U_violation;
delete[] x_L_violation;
return ok;
}
JNIEXPORT void JNICALL Java_org_coinor_Ipopt_FreeIpoptProblem(
JNIEnv* ,
jobject ,
jlong pipopt
)
{
SmartPtr<Jipopt>* pproblem = (SmartPtr<Jipopt>*)pipopt;
if( pproblem != NULL && IsValid(*pproblem) )
{
(*pproblem)->application = NULL;
*pproblem = NULL;
}
}
JNIEXPORT jboolean JNICALL Java_org_coinor_Ipopt_AddIpoptIntOption(
JNIEnv* env,
jobject ,
jlong pipopt,
jstring jparname,
jint jparvalue
)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
const char* pparameterName = env->GetStringUTFChars(jparname, 0);
string parameterName = pparameterName;
jboolean ret = problem->application->Options()->SetIntegerValue(parameterName, jparvalue);
env->ReleaseStringUTFChars(jparname, pparameterName);
return ret;
}
JNIEXPORT jboolean JNICALL Java_org_coinor_Ipopt_AddIpoptNumOption(
JNIEnv* env,
jobject ,
jlong pipopt,
jstring jparname,
jnumber jparvalue
)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
const char* pparameterName = env->GetStringUTFChars(jparname, 0);
string parameterName = pparameterName;
jboolean ret = problem->application->Options()->SetNumericValue(parameterName, jparvalue);
env->ReleaseStringUTFChars(jparname, pparameterName);
return ret;
}
JNIEXPORT jboolean JNICALL Java_org_coinor_Ipopt_AddIpoptStrOption(
JNIEnv* env,
jobject ,
jlong pipopt,
jstring jparname,
jstring jparvalue
)
{
Jipopt* problem = GetRawPtr(*(SmartPtr<Jipopt>*) pipopt);
const char* pparameterName = env->GetStringUTFChars(jparname, NULL);
string parameterName = pparameterName;
const char* pparameterValue = env->GetStringUTFChars(jparvalue, NULL);
string parameterValue = pparameterValue;
if( parameterName == "hessian_approximation" && parameterValue == "limited-memory" )
{
problem->using_LBFGS = true;
}
else if( parameterName == "nlp_scaling_method" && parameterValue == "user-scaling" )
{
problem->using_scaling_parameters = true;
}
jboolean ret = problem->application->Options()->SetStringValue(parameterName, parameterValue);
env->ReleaseStringUTFChars(jparname, pparameterName);
env->ReleaseStringUTFChars(jparname, pparameterValue);
return ret;
}
}