cmdscale - это функция, включенная в пакет статистики, который по умолчанию включен в среду R (то же самое относится и к базовому пакету Renjin). Я могу выполнить функцию cmdscale (матрица, k = 1) в Renjin без проблем. Однако при использовании параметра add = TRUE - как в cmdscale (matrix, k = 1, add = TRUE) - Renjin создает исключение org.renjin.eval.EvalException. Оба прогона R и Renjin проиллюстрированы ниже:
Прогон Renjin (версия выпуска):
public class RenjinInstanceTest {
private RenjinInstance renjinInstance;
public RenjinInstanceTest() throws Exception {
renjinInstance= RenjinInstance.getInstance();
}
@Test
public void cmdScaleTest() throws Exception {
double[][] testMatrix= new double[4][4];
testMatrix[0][0] = 1.37680589686909;
testMatrix[0][1] = 1.36770559031242;
testMatrix[0][2] = 1.38561245483721;
testMatrix[0][3] = 1.40217631836104;
testMatrix[1][0] = 1.36770559031242;
testMatrix[1][1] = 1.36429765734584;
testMatrix[1][2] = 1.37562481815626;
testMatrix[1][3] = 1.38860967955558;
testMatrix[2][0] = 1.38561245483721;
testMatrix[2][1] = 1.37562481815626;
testMatrix[2][2] = 1.37680589686909;
testMatrix[2][3] = 1.40422475998389;
testMatrix[3][0] = 1.40217631836104;
testMatrix[3][1] = 1.38860967955558;
testMatrix[3][2] = 1.40422475998389;
testMatrix[3][3] = 1.41266993454097;
renjinInstance.runCmdScaleFromMatrix(testMatrix);
}
}
public class RenjinInstance {
private static RenjinInstance renjinInstance = null;
ScriptEngine engine;
// singleton
public static RenjinInstance getInstance() throws Exception {
if (renjinInstance == null) {
renjinInstance = new RenjinInstance ();
}
return renjinInstance ;
}
private InstanciaRenjin() throws Exception {
RenjinScriptEngineFactory factory = new RenjinScriptEngineFactory();
// create a Renjin engine:
engine = factory.getScriptEngine();
}
public double[] runCmdScaleFromMatrix(double[][] testMatrix) throws Exception {
loadMatrixInREnvironment("testMatrix", testMatrix);
engine.eval("output <- cmdscale(testMatrix, k=1, add=TRUE)");
double[] output = ((DoubleVector)
engine.eval("output")).toDoubleArray();
return output;
}
public void loadMatrixInREnvironment(String rVariable, double[][] matrix) throws ScriptException {
engine.put("tempVector", linearizeMatrix(matrix));
engine.eval(rVariable+ " <- matrix(tempVector, nrow = " + matrix.length + ", ncol = " +
matrix[0].length + ")");
}
private double[] linearizeMatrix(double[][] matrix) {
double[] array = new double[matrix.length * matrix[0].length];
for (int i=0; i< matrix.length; i++) {
for (int j=0; j < matrix[0].length; j++) {
array[(i*matrix[0].length) + j] = matrix[i][j];
}
}
return array;
}
}
Этот код работает отлично, если опция add = TRUE опущена , Однако, когда он включен, отображается следующая ошибка:
org.renjin.eval.EvalException
at org.renjin.invoke.reflection.FunctionBinding$Overload.invoke(FunctionBinding.java:125)
at org.renjin.invoke.reflection.FunctionBinding.invoke(FunctionBinding.java:172)
at org.renjin.invoke.reflection.FunctionBinding.invoke(FunctionBinding.java:165)
at org.renjin.primitives.Native.delegateToJavaMethod(Native.java:502)
at org.renjin.primitives.Native.redotCall(Native.java:353)
at org.renjin.primitives.R$primitive$$Call.applyPromised(R$primitive$$Call.java:65)
at org.renjin.sexp.BuiltinFunction.apply(BuiltinFunction.java:100)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.IfFunction.apply(IfFunction.java:40)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.AssignLeftFunction.assignLeft(AssignLeftFunction.java:58)
at org.renjin.primitives.special.AssignLeftFunction.apply(AssignLeftFunction.java:42)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.BeginFunction.apply(BeginFunction.java:39)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.IfFunction.apply(IfFunction.java:44)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.BeginFunction.apply(BeginFunction.java:39)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.IfFunction.apply(IfFunction.java:40)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.BeginFunction.apply(BeginFunction.java:39)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.sexp.Closure.applyPromised(Closure.java:200)
at org.renjin.sexp.Closure.apply(Closure.java:133)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.eval.Context.evaluate(Context.java:280)
at org.renjin.primitives.special.DollarFunction.apply(DollarFunction.java:46)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.AssignLeftFunction.assignLeft(AssignLeftFunction.java:58)
at org.renjin.primitives.special.AssignLeftFunction.apply(AssignLeftFunction.java:42)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.BeginFunction.apply(BeginFunction.java:39)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.IfFunction.apply(IfFunction.java:40)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.BeginFunction.apply(BeginFunction.java:39)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.sexp.Closure.applyPromised(Closure.java:200)
at org.renjin.sexp.Closure.apply(Closure.java:133)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.primitives.special.AssignLeftFunction.assignLeft(AssignLeftFunction.java:58)
at org.renjin.primitives.special.AssignLeftFunction.apply(AssignLeftFunction.java:42)
at org.renjin.sexp.FunctionCall.eval(FunctionCall.java:80)
at org.renjin.sexp.ExpressionVector.eval(ExpressionVector.java:85)
at org.renjin.eval.Context.evaluate(Context.java:280)
at org.renjin.script.RenjinScriptEngine.eval(RenjinScriptEngine.java:174)
at org.renjin.script.RenjinScriptEngine.eval(RenjinScriptEngine.java:133)
Caused by: java.lang.NullPointerException
at java.util.Arrays.copyOfRange(Arrays.java:3737)
at org.renjin.base.Lapack.rg(Lapack.java:863)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.renjin.invoke.reflection.FunctionBinding$Overload.invoke(FunctionBinding.java:117)
R run:
x <- c(1.37680589686909,1.36770559031242,1.38561245483721,1.40217631836104,1.36770559031242,1.36429765734584,1.37562481815626,1.38860967955558,1.38561245483721,1.37562481815626,1.39062924330846,1.40422475998389,1.40217631836104,1.38860967955558,1.40422475998389,1.41266993454097)
m <- matrix(x, nrow = 4, ncol = 4)
output <- cmdscale(m, k=1, add=TRUE)
Код работает нормально и генерирует желаемый вывод