I'd like to call some sage commands from within a c++ program and use the output. My plan is to call very simple 1-4 line sequences of sage commands, in order to make use of some of the number theoretic functions built into sage (for example, dealing with elliptic curves, number fields, modular forms).
I found a simple way to do so using popen, but this necessitates reading the sage output as strings and then parsing. If the sage output cuts across many lines, then the parsing becomes a bit more tricky. I also tried the instructions at: http://docs.python.org/extending/embedding.html but had trouble when I tried to PyRun_SimpleString a simple sage command (see example 2 below). Example 1 ---------------- Here is a simple proof of concept example.cc program which uses popen, (compile with g++ example.cc and run with ./a.out), to factor 2310 by calling sage. The result is stored as a string, but it would not be difficult to parse it further to get the actual factors as numbers if desired. #include <stdio.h> #include <iostream> #include <string> using namespace std; int main (int argc, char *argv[]) { FILE* sage_output; sage_output=popen("echo \"factor(2310)\" | sage", "r"); string factorization; // string for storing the result from sage int MAX_LEN=10000; //maximum length of lines in file char str_buf[MAX_LEN + 1]; // One extra byte needed // for the null character int line_count=0; while(fgets(str_buf, MAX_LEN + 1, sage_output) != NULL){ line_count++; //The first four lines look like: //---------------------------------------------------------------------- //| Sage Version 4.5.3, Release Date: 2010-09-04 | //| Type notebook() for the GUI, and license() for information. | //---------------------------------------------------------------------- if (line_count==5){ // the 5th line of the sage session has the output that we want factorization=str_buf; factorization=factorization.substr(6,strlen(str_buf)-7); // the 6 removes the `sage: ' from the output, i.e. starts after the 6th character // strlen(str_buf)-7 is the length of the output, i.e. without `sage: ' and without newline } } pclose(sage_output); cout << "sage returned:" << factorization << endl; return 0; } //============================= END OF EXAMPLE 1 ================================== Example 2 ---------------- Next thing I tried to do was to embed sage in a c program, by following http://docs.python.org/extending/embedding.html but that gave me errors at runtime. For example, the following embed.c progam produced the output/errors at the bottom of this post. Any ideas what's wrong? Any ideas of better ways to call sage from within c or c++? /* sage -sh gcc -I$SAGE_LOCAL/include/python2.6 $SAGE_LOCAL/lib/python/config/ libpython2.6.a embed.c -o embed; ./embed See http://docs.python.org/extending/embedding.html */ #include <Python.h> int main(int argc, char *argv[]) { Py_Initialize(); printf("1+1:\n"); PyRun_SimpleString("print 1+1"); printf("Load sage \n"); PyRun_SimpleString("from sage.all import *"); printf("Factor 2310:\n"); PyRun_SimpleString("print factor(2310)"); Py_Finalize(); return 0; } //================================ END EXAMPLE 2 ===================== What happens when I run example 2: mrubinst$ ./embed 1+1: 2 Loading the Sage library... Traceback (most recent call last): File "<string>", line 1, in <module> File "/Applications/sage/local/lib/python2.6/site-packages/sage/ all.py", line 64, in <module> from sage.misc.all import * # takes a while File "/Applications/sage/local/lib/python2.6/site-packages/sage/misc/ all.py", line 16, in <module> from sage_timeit_class import timeit File "sage_timeit_class.pyx", line 3, in init sage.misc.sage_timeit_class (sage/misc/sage_timeit_class.c:862) File "/Applications/sage/local/lib/python2.6/site-packages/sage/misc/ sage_timeit.py", line 12, in <module> import timeit as timeit_, time, math, preparser, interpreter File "/Applications/sage/local/lib/python2.6/site-packages/sage/misc/ interpreter.py", line 95, in <module> import IPython.ipapi File "/Applications/sage/local/lib/python2.6/site-packages/IPython/ __init__.py", line 58, in <module> __import__(name,glob,loc,[]) File "/Applications/sage/local/lib/python2.6/site-packages/IPython/ Shell.py", line 42, in <module> from IPython import ultraTB, ipapi File "/Applications/sage/local/lib/python2.6/site-packages/IPython/ ultraTB.py", line 99, in <module> from IPython import Debugger, PyColorize File "/Applications/sage/local/lib/python2.6/site-packages/IPython/ Debugger.py", line 48, in <module> if '-pydb' in sys.argv: AttributeError: 'module' object has no attribute 'argv' Factoring an integer: Traceback (most recent call last): File "<string>", line 1, in <module> NameError: name 'factor' is not defined But typing the python/sage commands into python directly works ok: mrubinst$ python Python 2.6.4 (r264:75706, Sep 9 2010, 12:46:47) [GCC 4.2.1 (Apple Inc. build 5664)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from sage.all import * >>> factor(2310) 2 * 3 * 5 * 7 * 11 -- To post to this group, send an email to sage-devel@googlegroups.com To unsubscribe from this group, send an email to sage-devel+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URL: http://www.sagemath.org