Using Sage in C++

421 views
Skip to first unread message

Grzegorz Kwasniewski

unread,
Nov 16, 2015, 10:57:52 PM11/16/15
to sage-support
   Hello,

How to execute Sage commands from C++? I could only find answers to do the other way around.
Please excuse me if this question was answered before, but after some search I couldn't find the answer. I've found the related discussion here : http://ask.sagemath.org/question/9133/using-features-of-sage-in-c/ , but does it mean that the answer to my question is: "you cannot do that"?

I would like to use it as for example Matlab allows:

      Engine *ep;
    if (!(ep = engOpen(NULL))) {
        exit(-1);
    }
    mxArray *res1 = NULL;
    engEvalString(ep,"res = 2+2");
    res1 = engGetVariable(ep,"res");
    string result = mxArrayToString(res1);
    engClose(ep);


So far I found only the very rough workaround:

         FILE* sage_output;
    string solveString = "2+2";
    std::stringstream ss;
    ss << "echo \"" << solveString << "\" | sage";
    sage_output = popen(ss.str(), "r");
    int line_count = 0;
    while (fgets(str_buf, MAX_LEN + 1, sage_output) != NULL) {
        line_count++;
        if (line_count == 6) {
            result = str_buf;
            result = result.substr(6, strlen(str_buf) - 7);
        }
    }
    pclose(sage_output);


Which works for a simple input, but it starts a new Sage process each time (so I cannot store variables). And it requires parsing the large output to find the result.

Thank you

Nils Bruin

unread,
Nov 17, 2015, 12:14:16 AM11/17/15
to sage-support
On Monday, November 16, 2015 at 7:57:52 PM UTC-8, Grzegorz Kwasniewski wrote:
   Hello,

How to execute Sage commands from C++? I could only find answers to do the other way around.
Please excuse me if this question was answered before, but after some search I couldn't find the answer. I've found the related discussion here : http://ask.sagemath.org/question/9133/using-features-of-sage-in-c/ , but does it mean that the answer to my question is: "you cannot do that"?

Your question is really "can I embed python in my C++ program" and the answer is, in principle, yes:

https://docs.python.org/2/extending/embedding.html

Note however, that it's generally advised against, so you should probably only do so if you really have to. The initialization of sage is really that of a (rather complicated) python program so in principle, once you have python embedded you should be able to get sage embedded too. Be aware that sage normally tries to take control over things like signal handlers. So your embedding program might have to take care to accommodate such things.

You can compile C++ into python modules. So you could just take your C++ program, compile it as a dynamically linked library, and make a thin cython wrapper that allows you to invoke your "main" procedure. Technically, you would be calling C++ from sage, but once your program is running, it would be more or less indistinguishable from working the other way around. Unless your C++ program has a lot other dependencies that are hard to satisfy from within sage, this is almost certainly the easier way to go.


Which works for a simple input, but it starts a new Sage process each time (so I cannot store variables). And it requires parsing the large output to find the result.


That's just because you've set up sage to terminate after executing one command. It's very easy to write a sage program that's listening on one pipe for input (in whatever format you require--you can make it binary if you want) and write output on another, i.e. just a little server. There must be standard python libraries that can do that for you. Then state can be preserved in exactly the way you want. That's the IPC that the answer you linked to already mentioned. If the sharing of data between your C++ program and sage isn't excessive, that's probably the easiest way to go about it. If you do need to share a lot of data, you could still do so by setting up some pages of shared memory between the processes. Is there a particular reason why you prefer your C++ program to be in the same process as the sage process(es)?

Jeroen Demeyer

unread,
Nov 17, 2015, 10:34:01 AM11/17/15
to sage-s...@googlegroups.com
On 2015-11-17 06:14, Nils Bruin wrote:
> It's very easy to write a sage program that's listening on one
> pipe for input (in whatever format you require--you can make it binary
> if you want) and write output on another, i.e. just a little server.

You could try to use 0MQ for this. It has bindings for many languages,
including C++ and Python. Sage already includes it.

But I agree with Nils that you should certainly also consider the
reverse: using your C++ program within Sage.
Reply all
Reply to author
Forward
0 new messages