#include "GlobalOptimization.h" #include #include #include #include #include /* Nasty global variables to store pointers to Java environment and methods so that we can use them in different parts of this C code. */ JNIEnv *globalJavaEnv; jobject globaljavaobject; jmethodID globalObjfunID; jmethodID globalMonitID; /* This routine has the interface required by NAG routine e05jbf for argument objfun. It makes calls back to the Java version of objfun */ void objfunFun(int *n, double x[], double *f, int *nstate, int iuser[], double ruser[], int *inform) { int i; /* First create Java arrays to pass to objfun */ jdoubleArray jx = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n); jintArray jiuser = (*globalJavaEnv)->NewIntArray(globalJavaEnv, 1); jdoubleArray jruser = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, 1); /* Copy input array x to Java array jx */ double *jxpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jx, 0); int *jiuserpt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jiuser, 0); double *jruserpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jruser, 0); for (i = 0; i < *n; i++) jxpt[i] = x[i]; for (i = 0; i < 1; i++) jiuserpt[i] = iuser[i]; for (i = 0; i < 1; i++) jruserpt[i] = ruser[i]; /* Release array elements back to Java (this puts the values into jx, jiuser, jruser) */ (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jx, jxpt, 0); (*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jiuser, jiuserpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jruser, jruserpt, 0); /* We need to set inform to a non-negative value */ *inform = 0; /* Call Java objfun which returns objf */ *f = (*globalJavaEnv)->CallDoubleMethod(globalJavaEnv, globaljavaobject, globalObjfunID, (jint) (*n), jx, (jdouble) (*f), (jint) (*nstate), jiuser, jruser, (jint) (*inform)); } /* This routine has the interface required by NAG routine e05jbf for argument monit. It makes calls back to the Java version of monit */ void monitFun(int *n, int *ncall, double xbest[], int icount[], int *ninit, double list[], int numpts[], int initpt[], int *nbaskt, double xbaskt[], double boxl[], double boxu[], int *nstate, int iuser[], double ruser[], int *inform) { int i,j; int *jicountpt, *jnumptspt, *jinitptpt, *jiuserpt; double *jxbestpt, *jlistpt, *jxbasktpt, *jboxlpt, *jboxupt, *jruserpt; /* First create some Java arrays to pass to monit */ jintArray jicount = (*globalJavaEnv)->NewIntArray(globalJavaEnv, 6); jintArray jnumpts = (*globalJavaEnv)->NewIntArray(globalJavaEnv, *n); jintArray jinitpt = (*globalJavaEnv)->NewIntArray(globalJavaEnv, *n); jintArray jiuser = (*globalJavaEnv)->NewIntArray(globalJavaEnv, 1); jdoubleArray jxbest = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n); jdoubleArray jlist = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, ((*n)*(*ninit))); jdoubleArray jxbaskt = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, ((*n)*(*nbaskt))); jdoubleArray jboxl = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n); jdoubleArray jboxu = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n); jdoubleArray jruser = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, 1); /* Copy input arguments to Java arrays*/ jicountpt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jicount, 0); jnumptspt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jnumpts, 0); jinitptpt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jinitpt, 0); jiuserpt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jiuser, 0); jxbestpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jxbest, 0); jlistpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jlist, 0); jxbasktpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jxbaskt, 0); jboxlpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jboxl, 0); jboxupt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jboxu, 0); jruserpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jruser, 0); for (i = 0; i < 6; i++) jicountpt[i] = icount[i]; for (i = 0; i < *n; i++) jnumptspt[i] = numpts[i]; for (i = 0; i < *n; i++) jinitptpt[i] = initpt[i]; for (i = 0; i < *n; i++) jxbestpt[i] = xbest[i]; for (i = 0; i < *n; i++) { for (j = 0; j < *ninit; j++) jlistpt[j*(*n) + i] = list[j*(*n) + i]; } for (i = 0; i < *n; i++) { for (j = 0; j < *nbaskt; j++) jxbasktpt[j*(*n) + i] = xbaskt[j*(*n) + i]; } for (i = 0; i < *n; i++) jboxlpt[i] = boxl[i]; for (i = 0; i < *n; i++) jboxupt[i] = boxu[i]; for (i = 0; i < 1; i++) jiuserpt[i] = iuser[i]; for (i = 0; i < 1; i++) jruserpt[i] = ruser[i]; /* Release array elements back to Java (this puts the values back into Java arrays) */ (*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jicount, jicountpt, 0); (*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jnumpts, jnumptspt, 0); (*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jinitpt, jinitptpt, 0); (*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jiuser, jiuserpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jxbest, jxbestpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jlist, jlistpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jxbaskt, jxbasktpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jboxl, jboxlpt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jboxu, jboxupt, 0); (*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jruser, jruserpt, 0); /* Call the Java method via its method ID */ *inform = (*globalJavaEnv)->CallIntMethod(globalJavaEnv, globaljavaobject, globalMonitID, (jint)(*n), (jint) (*ncall), jxbest, jicount, (jint)(*ninit), jlist, jnumpts, jinitpt, (jint)(*nbaskt), jxbaskt, jboxl, jboxu, (jint)(*nstate), jiuser, jruser, (jint) (*inform)); } JNIEXPORT jint JNICALL Java_GlobalOptimization_e05jbf ( JNIEnv *env, jobject object, jint n, jstring objfun, jint ibound, jint iinit, jdoubleArray bl, jdoubleArray bu, jint sdlist, jdoubleArray list, jintArray numpts, jintArray initpt, jstring monit, jdoubleArray x, jdoubleArray obj, jdoubleArray comm, jint lcomm, jintArray iuser, jdoubleArray ruser ) { /* Local variables and arrays */ int ifail; jclass cls; const char *objfunction; const char *monitrt; jdouble *bl_pt, *bu_pt, *list_pt, *x_pt, *obj_pt, *comm_pt, *ruser_pt; jint *numpts_pt, *initpt_pt, *iuser_pt; /* Copy the Java env pointers to global space so that monitFun and objfunFun can access them. */ globalJavaEnv = env; globaljavaobject = object; /* Get hold of the name of the user's Java evaluation functions. */ objfunction = (*env)->GetStringUTFChars(env, objfun, 0); monitrt = (*env)->GetStringUTFChars(env, monit, 0); /* Now we have the Java evaluation function names we can use them to get hold of handles (method IDs) to the functions. Once more, the method IDs are stored globally so that objfunFun and monitFun can use them. Note that the Java function signatures must be correct. You can find out the signatures after compiling the Java program GlobalOptimization.java by using the command % javap -private -s GlobalOptimization */ cls = (*env)->GetObjectClass(env, object); globalObjfunID = (*env)->GetMethodID(env, cls, objfunction, "(I[DDI[I[DI)D"); globalMonitID = (*env)->GetMethodID(env, cls, monitrt, "(II[D[II[D[I[II[D[D[DI[I[DI)I"); /* Free up the Java string argument so we don't leak memory. */ (*env)->ReleaseStringUTFChars(env, objfun, objfunction); (*env)->ReleaseStringUTFChars(env, monit, monitrt); if (globalObjfunID == 0) { printf("Cannot find objfun method \"%s\" with signature \"(I[DDI[I[DI)D\"\n", objfunction); return -1; } if (globalMonitID == 0) { printf("Cannot find monit method \"%s\" with signature \"(II[D[II[D[I[II[D[D[DI[I[DI)I\"\n", monitrt); return -1; } /* Extract the arrays from Java */ bl_pt = (*env)->GetDoubleArrayElements(env, bl, 0); bu_pt = (*env)->GetDoubleArrayElements(env, bu, 0); list_pt = (*env)->GetDoubleArrayElements(env, list, 0); x_pt = (*env)->GetDoubleArrayElements(env, x, 0); obj_pt = (*env)->GetDoubleArrayElements(env, obj, 0); comm_pt = (*env)->GetDoubleArrayElements(env, comm, 0); ruser_pt = (*env)->GetDoubleArrayElements(env, ruser, 0); numpts_pt = (*env)->GetIntArrayElements(env, numpts, 0); initpt_pt = (*env)->GetIntArrayElements(env, initpt, 0); iuser_pt = (*env)->GetIntArrayElements(env, iuser, 0); /* Call to main NAG Library routine e05jbf */ ifail = -1; #ifdef WINDOWS E05JBF #else e05jbf_ #endif (&n, objfunFun, &ibound, &iinit, bl_pt, bu_pt, &sdlist, list_pt, numpts_pt, initpt_pt, monitFun, x_pt, obj_pt, comm_pt, &lcomm, iuser_pt, ruser_pt, &ifail); /* Release the array elements back to Java and free memory. */ (*env)->ReleaseDoubleArrayElements(env, bl, bl_pt, 0); (*env)->ReleaseDoubleArrayElements(env, bu, bu_pt, 0); (*env)->ReleaseDoubleArrayElements(env, list, list_pt, 0); (*env)->ReleaseDoubleArrayElements(env, x, x_pt, 0); (*env)->ReleaseDoubleArrayElements(env, obj, obj_pt, 0); (*env)->ReleaseDoubleArrayElements(env, comm, comm_pt, 0); (*env)->ReleaseDoubleArrayElements(env, ruser, ruser_pt, 0); (*env)->ReleaseIntArrayElements(env, numpts, numpts_pt, 0); (*env)->ReleaseIntArrayElements(env, initpt, initpt_pt, 0); (*env)->ReleaseIntArrayElements(env, iuser, iuser_pt, 0); return ifail; } // Interface to initialization routine e05jaf JNIEXPORT jint JNICALL Java_GlobalOptimization_e05jaf (JNIEnv *env, jobject object, jint n, jdoubleArray comm, jint lcomm) { jdouble *comm_pt; int ifail; /* Extract the array from Java */ comm_pt = (*env)->GetDoubleArrayElements(env, comm, 0); ifail = -1; /* Call the initialization routine */ #ifdef WINDOWS E05JAF(&n,comm_pt,&lcomm,&ifail); #else e05jaf_(&n,comm_pt,&lcomm,&ifail); #endif /* Release the array elements back to Java and free memory. */ (*env)->ReleaseDoubleArrayElements(env, comm, comm_pt, 0); return ifail; }