Ошибка Renjin org.renjin.eval.EvalException при вызове cmdscale с add = TRUE - PullRequest
0 голосов
/ 05 февраля 2020

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)

Код работает нормально и генерирует желаемый вывод

...