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

Reply via email to