2
$\begingroup$

I found the following example online (which works fine) for sending commands from Java:

ml.putFunction("EvaluatePacket", 1);
ml.putFunction("Plus", 2);
ml.put(3);
ml.put(3);
ml.endPacket();

I need to follow the same tactic to update through a loop, the items of some Matrix. For example, the Mathematica expression I want to evaluate would be:

MyMatrix[[1]] = {3, 4};

What is the equivalent Java code for this action? The following does not seem to update MyMatrix because the last print shows it like it was originally.

ml.putFunction("EvaluatePacket", 1);
ml.putFunction("Set", 2);
ml.putFunction("Part", 2);
ml.put("MyMatrix");
ml.put(1);
ml.putFunction("List", 2);
ml.put(3.);
ml.put(4.);
ml.endPacket();
ml.discardAnswer();

System.out.println(ml.evaluateToOutputForm("MyMatrix", 0));

On the contrary, this works:

ml.evaluateToOutputForm("MyMatrix[[1]] = {3.0, 4.0};", 0);
System.out.println(ml.evaluateToOutputForm("MyMatrix", 0));

Here is a full example showing the problem:

import com.wolfram.jlink.*;

public class Mathematica {

public static void main(String[] args) {

    KernelLink ml = null;
    String jLinkDir = "C:\\Program Files\\Wolfram Research\\Mathematica\\12.0\\SystemFiles\\Links\\JLink";
    System.setProperty("com.wolfram.jlink.libdir", jLinkDir);

    try {
        ml = MathLinkFactory.createKernelLink("-linkmode launch -linkname 'C:\\Program Files\\Wolfram Research\\Mathematica\\12.0\\MathKernel.exe'");
        // Get rid of the initial InputNamePacket the kernel will send when it is launched.
        ml.discardAnswer();

        ml.evaluate("MyMatrix = {{1,2},{3,4}}");
        ml.discardAnswer();
        System.out.println(ml.evaluateToOutputForm("MyMatrix", 0));

        ml.putFunction("EvaluatePacket", 1);
        ml.putFunction("Set", 2);
        ml.putFunction("Part", 2);
        ml.put("MyMatrix");
        ml.put(1);
        ml.putFunction("List", 2);
        ml.put(5.);
        ml.put(6.);
        ml.endPacket();
        ml.discardAnswer();

        System.out.println(ml.evaluateToOutputForm("MyMatrix", 0));

        ml.evaluate("MyMatrix[[1]]={5.,6.};");
        ml.discardAnswer();
        System.out.println(ml.evaluateToOutputForm("MyMatrix", 0));

    } catch (MathLinkException e) {
        System.out.println("Fatal error opening link: " +
                e.getMessage());
    }
}
}
$\endgroup$
5
  • $\begingroup$ In your example you are sending the expression Plus[3,3], which is the full form of 3+3. For your matrix case, look at the full form via FullForm[Unevaluated[MyMatrix[[1]] = {3, 4}]] $\endgroup$
    – Jason B.
    Oct 25, 2020 at 16:05
  • $\begingroup$ It could be related to evaluation order, with Part evaluating before Set has a chance to see MyMatrix. $\endgroup$
    – Jason B.
    Oct 25, 2020 at 19:29
  • $\begingroup$ Any ideas for a workaround and hopefully avoid the use of "evaluateToOutputForm". The reason why I want to avoid it is that I will be doing many times this update and so I was searching for the fastest way possible. $\endgroup$
    – Gouz
    Oct 25, 2020 at 20:56
  • $\begingroup$ It's hard without a complete working example, something I can copy/paste and run. $\endgroup$
    – Jason B.
    Oct 26, 2020 at 1:44
  • $\begingroup$ I added a minimal example $\endgroup$
    – Gouz
    Oct 26, 2020 at 12:49

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.