next | previous | forward | backward | up | top | index | toc | Macaulay2 website
RunExternalM2 :: suggestions for using RunExternalM2

suggestions for using RunExternalM2 -- suggestions for using RunExternalM2

A suggested way of writing programs using this package is to write your program in a file, perhaps named "somefilename.m2", with the following structure:

needsPackage "RunExternalM2"

...
(ring definitions, etc., here)
...


mycalc = (...) -> (
        ...
        (do a calculation)
        ...
);

if isExternalM2Parent() then (
        ...
        h=runExternalM2("somefilename.m2",mycalc,...);
        ...
);

and then execute your program in Macaulay2 by running:

i1 : load "somefilename.m2"

This has a few advantages. It ensures that ring definitions are always the same in the parent and child Macaulay2 processes, even if you are frequently editing the file and running the calculation again. If the file containing the function has syntax errors, then they should appear directly in the console rather than inside a temporary file containing the program's output. If a particular try at execution does not work, then you can immediately call the function directly for quick debugging.

For instance, the following code calculates an ideal of minors:

needsPackage "RunExternalM2"

m=4;
n=3;
R=QQ[x_(1,1)..x_(m,n)];

idealOfMinors = (i) -> (
        M:=genericMatrix(R,m,n);
        return trim minors(i,M);
);

if isExternalM2Parent() then (
        h=runExternalM2("example1.m2",idealOfMinors,2);
        if (h#"exit code"===0) then (
                stdio<<"The code ran successfully and the answer was:"<<endl;
                stdio<<toExternalString(h#value)<<endl;
        ) else (
                stderr<<"There was a problem."<<endl;
        );
);

When using random numbers, it may be useful for the parent to provide the random number seed to the child, so that the output of the child is reproducible. For instance, the following code searches for a random integer matrix with a large determinant:

needsPackage "RunExternalM2"

getRandomMat = (seed,size,height) -> (
        setRandomSeed(seed);
        blankMat:=mutableMatrix(ZZ,size,size);
        return matrix fillMatrix(blankMat,Height=>height);
);

if isExternalM2Parent() then (
        seed:=0;
        while (true) do (
                seed=random(0,2^32);
                h:=runExternalM2("z1.m2",getRandomMat,(seed,5,5));
                if (h#"exit code"===0) then (
                        d:=det(h#value);
                        stdio<<"Starting with seed "<<seed<<" gives this matrix (with det="<<d<<"):"<<endl;
                        stdio<<"  "<<h#value<<endl;

                        if (d>100) then (
                                break;
                        );
                ) else (
                        stderr<<"There was a problem; aborting."<<endl;
                        break;
                );
        );

        stdio<<"Using the seed "<<seed<<" again gives the same matrix:"<<endl;
        stdio<<"  "<<getRandomMat(seed,5,5)<<endl;
);

See also