7
$\begingroup$

Mathematica has a way of integrating with Julia, and automatically convert Julia outputs into Mathematica objects (Julia seems to have nice support for low-rank approximation). What is the best way to use Mathematica matrices as Julia inputs?

For instance I can get get trace of Cholesky factor as follows

FindExternalEvaluators["Julia"]
jj[cmd_] := ExternalEvaluate["Julia", cmd];
jj["using LinearAlgebra;A=[2 1;1 2];tr(cholesky(A).U)"]

But a more useful scenario would be to try it on a A like below:

d = 4000;
A = RandomReal[{-1, 1}, {d, d}];
A = A + Transpose[A] + 2. Sqrt[d] IdentityMatrix[d];
Tr@CholeskyDecomposition@A
$\endgroup$

2 Answers 2

10
$\begingroup$

Fortunately, the Wolfram team had done the hard part for us. We don't have to build interface to call julia (in most cases).

First, start a session:

session = StartExternalSession["Julia"]

Load your libraries:

ExternalEvaluate[session, "using LinearAlgebra;"]

Build your function in Julia:

juliaFn1 = ExternalFunction[session, "f(x)=tr(cholesky(x).U)"]

Use it as a normal function in Mathematica:

juliaFn1[A]

Note in this simple example with d = 4000, Mathematica was orders of magnitude faster and the performance of Julia will diminish because of sending/receiving large arrays.

$\endgroup$
1
  • 1
    $\begingroup$ Thanks for the tip! It looks like it takes 20 seconds to get a 64MB array into Julia this way. This is orders of magnitudes slower than what's possible (ie, what Ray does with Arrow docs.ray.io/en/releases-1.11.1/ray-core/serialization.html )....I would guess there's an inefficient single thread serialization/deserialization process somewhere $\endgroup$ Commented Aug 3, 2022 at 14:16
3
$\begingroup$

@Ben's answer above is obviously very convenient. I just wanted to mention that, had that capability not been available already, you could parse and reformat the matrix yourself, and then use e.g. StringTemplate to generate the line of Julia code:

Here is a simple helper function that really just encapsulates the appropriate choices of delimiters for StringRiffle, which does all the reformatting in one go:

ClearAll[juliaMat]
juliaMat[a_?MatrixQ] := StringRiffle[a, {"[", "; ", "]"}, " "]

a = BlockRandom[SeedRandom[1]; RandomInteger[10, {4, 3}]];
juliaMat[a]

(* Out: "[1 4 0; 7 0 0; 8 6 0; 4 1 8]" *)

You can then insert that result where you need it in your command line either using StringJoin, or using a template expression as follows:

StringTemplate["using LinearAlgebra;A=<*juliaMat[#1]*>;tr(cholesky(A).U)"][a]

(* Out: 
  "using LinearAlgebra;A=[1 4 0; 7 0 0; 8 6 0; 4 1 8];tr(cholesky(A).U)"
*)
$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.