Using local variables in ExternalEvaluate Python
If you are willing to setup and use WolframClientForPython you could do:
With Mathematica
linearMap = 1. {{1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 1/4, 0, 0, 0},
{0, 0, 0, 0, 1/2, 0, 0}, {0, 0, 0, 0, 0, 1/2, 0},
{0, 0, 0, 0, 0, 0, 1/4}};
Export[FileNameJoin[{"C:", "temp", "linearMap.wxf"}], "WXF"]
then in Python
import numpy as np
import os
from wolframclient.evaluation import WolframLanguageSession
from wolframclient.serializers import export
math_kernel = r'C:\Program Files\Wolfram Research\Mathematica\11.3\MathKernel.exe'
output_path = r'C:\temp'
session = WolframLanguageSession(math_kernel)
session.start()
linear_map = session.evaluate('Import[FileNameJoin[{"C:", "temp", "linearMap.wxf"}]]')
linear_map = np.array(linear_map)
out = np.linalg.eigvalsh(linear_map)
export(out, os.path.join(output_path, 'out.wxf'), target_format='wxf')
session.terminate()
finally back in Mathematica
Import[FileNameJoin[{"C:", "temp", "out.wxf"}]] // Normal
(* {0.25, 0.25, 0.5, 0.5, 1., 1., 1.} *)
You may use the Association
syntax for ExternalEvaluate
.
If numpy
is installed in your Python instance then you should have a "Python-NumPy"
external evaluator. Check by evaluating FindExternalEvaluators[]
.
Initialise the connection with
ExternalEvaluate["Python-NumPy", "1+1"]
2
Then
ExternalEvaluate["Python-NumPy",
<|
"Command" -> "numpy.linalg.eigvalsh",
"Arguments" -> {linearMap}
|>
]
{0.25, 0.25, 0.5, 0.5, 1., 1., 1.}
If you need to use this often then create a function
numpyEigvalsh[m_?MatrixQ] :=
ExternalEvaluate["Python-NumPy",
<|
"Command" -> "numpy.linalg.eigvalsh",
"Arguments" -> {m}
|>
]
Then
numpyEigvalsh@linearMap
{0.25, 0.25, 0.5, 0.5, 1., 1., 1.}
Why it may be slower
Note that when using Rationals
that Mathematica will take longer as it works to preserve the infinite precision of rationals.
Eigenvalues@linearMap
{1, 1, 1, 1/2, 1/2, 1/4, 1/4}
You can speed things up by using Reals
. All you need to do is multiply by 1.
Eigenvalues[1. linearMap]
{1., 1., 1., 0.5, 0.5, 0.25, 0.25}
Note that the output is now with reals instead of rationals
Hope this helps.