Example #1
0
    def __call__(self, assumptions=None):
        """
        Run 'command' and collect output.

        INPUT:

        - ``assumptions`` - ignored, accepted for compatibility with
          other solvers (default: ``None``)

        TESTS:

        This class is not meant to be called directly::

            sage: from sage.sat.solvers.dimacs import DIMACS
            sage: fn = tmp_filename()
            sage: solver = DIMACS(filename=fn)
            sage: solver.add_clause( (1, -2 , 3) )
            sage: solver()
            Traceback (most recent call last):
            ...
            ValueError: No SAT solver command selected.
        """
        if assumptions is not None:
            raise NotImplementedError("Assumptions are not supported for DIMACS based solvers.")

        self.write()

        output_filename = None
        self._output = []

        command = self._command.strip()

        if not command:
            raise ValueError("No SAT solver command selected.")


        if "{output}" in command:
            output_filename = tmp_filename()
        command = command.format(input=self._headname, output=output_filename)

        args = shlex.split(command)

        try:
            process = subprocess.Popen(args, stdout=subprocess.PIPE)
        except OSError:
            raise OSError("Could run '%s', perhaps you need to add your SAT solver to $PATH?"%(" ".join(args)))

        try:
            while process.poll() is None:
                for line in iter(process.stdout.readline,''):
                    if get_verbose() or self._verbosity:
                        print line,
                        sys.stdout.flush()
                    self._output.append(line)
                sleep(0.1)
            if output_filename:
                self._output.extend(open(output_filename).readlines())
        except KeyboardInterrupt:
            process.kill()
            raise KeyboardInterrupt
Example #2
0
    def __call__(self, model, outfile='sage.png',
                 verbose=1, block=True, extra_opts=''):
        modelfile = tmp_filename() + '.dat'
        open(modelfile,'w').write(model)
        opts = ''
        ext = outfile[-4:].lower()
        if ext == '.png':
            opts += ' -format PNG '
        elif ext == '.tga':
            opts += ' -format TARGA '
        elif ext == '.bmp':
            opts += ' -format BMP '
        elif ext == '.ppm':
            opts += ' -format PPM '
        elif ext == '.rgb':
            opts += ' -format RGB '
        
        opts += ' -o %s '%outfile

        opts += ' ' + extra_opts + ' '
        
        if verbose >= 2:
            opts += ' +V '
        elif verbose == 0:
            opts += '  1>/dev/null'
            
        cmd = 'tachyon %s %s; rm -f "%s"'%(modelfile,opts, modelfile)

        if not block:
            cmd += ' &'

        if verbose:
            print cmd
        os.system(cmd)
    def __call__(self,
                 model,
                 outfile='sage.png',
                 verbose=1,
                 block=True,
                 extra_opts=''):
        """
        This executes the tachyon program, given a scene file input.
        The default is to return the result as a PNG file called 'sage.png'.

        TESTS::

            sage: from sage.interfaces.tachyon import TachyonRT
            sage: tgen = Tachyon()
            sage: tgen.texture('t1')
            sage: tgen.sphere((0,0,0),1,'t1')
            sage: tgen.str()[30:40]
            'resolution'
            sage: t = TachyonRT()
            sage: import os
            sage: t(tgen.str(), outfile = os.devnull)
            tachyon ...
            Tachyon Parallel/Multiprocessor Ray Tracer...
        """
        modelfile = tmp_filename(ext='.dat')
        open(modelfile, 'w').write(model)
        opts = ''
        ext = outfile[-4:].lower()
        if ext == '.png':
            opts += ' -format PNG '
        elif ext == '.tga':
            opts += ' -format TARGA '
        elif ext == '.bmp':
            opts += ' -format BMP '
        elif ext == '.ppm':
            opts += ' -format PPM '
        elif ext == '.rgb':
            opts += ' -format RGB '

        opts += ' -o %s ' % outfile

        opts += ' ' + extra_opts + ' '

        if verbose >= 2:
            opts += ' +V '
        elif verbose == 0:
            opts += '  1>/dev/null'

        cmd = 'tachyon %s %s; rm -f "%s"' % (modelfile, opts, modelfile)

        if not block:
            cmd = '( ' + cmd + ' ) &'

        if verbose:
            print cmd
        # One should always flush before system()
        sys.stdout.flush()
        sys.stderr.flush()
        os.system(cmd)
Example #4
0
    def __init__(self, command=None, filename=None, verbosity=0, **kwds):
        """
        Construct a new generic DIMACS solver.

        INPUT:

        - ``command`` - a named format string with the command to
          run. The string must contain {input} and may contain
          {output} if the solvers writes the solution to an output
          file. For example "sat-solver {input}" is a valid
          command. If ``None`` then the class variable ``command`` is
          used. (default: ``None``)

        - ``filename`` - a filename to write clauses to in DIMACS
          format, must be writable. If ``None`` a temporary filename
          is chosen automatically. (default: ``None``)

        - ``verbosity`` - a verbosity level, where zero means silent
          and anything else means verbose output. (default: ``0``)

        - ``**kwds`` - accepted for compatibility with other solves,
          ignored.

        TESTS::

            sage: from sage.sat.solvers.dimacs import DIMACS
            sage: DIMACS()
            DIMACS Solver: ''
        """
        if filename is None:
            filename = tmp_filename()

        self._headname = filename
        self._verbosity = verbosity

        if command is not None:
            self._command = command
        else:
            self._command = self.__class__.command

        self._tail = open(tmp_filename(), 'w')
        self._var = 0
        self._lit = 0
Example #5
0
    def __init__(self, command=None, filename=None, verbosity=0, **kwds):
        """
        Construct a new generic DIMACS solver.

        INPUT:

        - ``command`` - a named format string with the command to
          run. The string must contain {input} and may contain
          {output} if the solvers writes the solution to an output
          file. For example "sat-solver {input}" is a valid
          command. If ``None`` then the class variable ``command`` is
          used. (default: ``None``)

        - ``filename`` - a filename to write clauses to in DIMACS
          format, must be writable. If ``None`` a temporary filename
          is chosen automatically. (default: ``None``)

        - ``verbosity`` - a verbosity level, where zero means silent
          and anything else means verbose output. (default: ``0``)

        - ``**kwds`` - accepted for compatibility with other solves,
          ignored.

        TESTS::

            sage: from sage.sat.solvers.dimacs import DIMACS
            sage: DIMACS()
            DIMACS Solver: ''
        """
        if filename is None:
            filename = tmp_filename()

        self._headname = filename
        self._verbosity = verbosity

        if command is not None:
            self._command = command
        else:
            self._command = self.__class__.command

        self._tail = open(tmp_filename(), "w")
        self._var = 0
        self._lit = 0
Example #6
0
    def __call__(self, model, outfile='sage.png',
                 verbose=1, block=True, extra_opts=''):
        """
        This executes the tachyon program, given a scene file input.
        The default is to return the result as a PNG file called 'sage.png'.
        
        TESTS::

            sage: from sage.interfaces.tachyon import TachyonRT
            sage: tgen = Tachyon()
            sage: tgen.texture('t1')
            sage: tgen.sphere((0,0,0),1,'t1')
            sage: tgen.str()[30:40]
            'resolution'
            sage: t = TachyonRT()
            sage: import os
            sage: t(tgen.str(), outfile = os.devnull)
            tachyon ...
            Tachyon Parallel/Multiprocessor Ray Tracer...
        """
        modelfile = tmp_filename(ext='.dat')
        open(modelfile,'w').write(model)
        opts = ''
        ext = outfile[-4:].lower()
        if ext == '.png':
            opts += ' -format PNG '
        elif ext == '.tga':
            opts += ' -format TARGA '
        elif ext == '.bmp':
            opts += ' -format BMP '
        elif ext == '.ppm':
            opts += ' -format PPM '
        elif ext == '.rgb':
            opts += ' -format RGB '
        
        opts += ' -o %s '%outfile

        opts += ' ' + extra_opts + ' '
        
        if verbose >= 2:
            opts += ' +V '
        elif verbose == 0:
            opts += '  1>/dev/null'
            
        cmd = 'tachyon %s %s; rm -f "%s"'%(modelfile,opts, modelfile)

        if not block:
            cmd = '( ' + cmd + ' ) &'

        if verbose:
            print cmd
        # One should always flush before system()
        sys.stdout.flush()
        sys.stderr.flush()
        os.system(cmd)
Example #7
0
def runsnake(command):
    """
    Graphical profiling with ``runsnake``

    INPUT:

    - ``command`` -- the command to be run as a string.

    EXAMPLES::

        sage: runsnake("list(SymmetricGroup(3))")        # optional - runsnake

    ``command`` is first preparsed (see :func:`preparse`)::

        sage: runsnake('for x in range(1,4): print x^2') # optional - runsnake
        1
        4
        9

    :func:`runsnake` requires the program ``runsnake``. Due to non
    trivial dependencies (python-wxgtk, ...), installing it within the
    Sage distribution is unpractical. Hence, we recommend installing
    it with the system wide Python. On Ubuntu 10.10, this can be done
    with::

        > sudo apt-get install python-profiler python-wxgtk2.8 python-setuptools
        > sudo easy_install RunSnakeRun

    See the ``runsnake`` website for instructions for other platforms.

    :func:`runsnake` further assumes that the system wide Python is
    installed in ``/usr/bin/python``.

    .. seealso::

        - `The runsnake website <http://www.vrplumber.com/programming/runsnakerun/>`_
        - ``%prun``
        - :class:`Profiler`

    """
    import cProfile, os
    from sage.misc.misc import tmp_filename, get_main_globals
    from sage.misc.preparser import preparse
    tmpfile = tmp_filename()
    cProfile.runctx(preparse(command.lstrip().rstrip()),
                    get_main_globals(),
                    locals(),
                    filename=tmpfile)
    os.system("/usr/bin/python -E `which runsnake` %s &" % tmpfile)
def dump_to_tmpfile(s):
    """
    Utility function to dump a string to a temporary file.

    EXAMPLE:
        sage: from spherical import *
        sage: file_loc = dump_to_tmpfile("boo")
        sage: os.remove(file_loc)
    """

    file_loc = tmp_filename()
    f = open(file_loc,"w")
    f.write(s)
    f.close()
    return file_loc
Example #9
0
def dump_to_tmpfile(s):
    """
    Utility function to dump a string to a temporary file.

    EXAMPLE::

        sage: from sage.combinat.designs import ext_rep
        sage: file_loc = ext_rep.dump_to_tmpfile("boo")
        sage: os.remove(file_loc)
    """

    file_loc = tmp_filename()
    f = open(file_loc, "w")
    f.write(v2_b2_k2_icgsa)
    f.close()
    return file_loc
Example #10
0
def dump_to_tmpfile(s):
    """
    Utility function to dump a string to a temporary file.

    EXAMPLE::

        sage: from sage.combinat.designs import ext_rep
        sage: file_loc = ext_rep.dump_to_tmpfile("boo")
        sage: os.remove(file_loc)
    """

    file_loc = tmp_filename()
    f = open(file_loc,"w")
    f.write(v2_b2_k2_icgsa)
    f.close()
    return file_loc
Example #11
0
def runsnake(command):
    """
    Graphical profiling with ``runsnake``

    INPUT:

    - ``command`` -- the command to be run as a string.

    EXAMPLES::

        sage: runsnake("list(SymmetricGroup(3))")        # optional - runsnake

    ``command`` is first preparsed (see :func:`preparse`)::

        sage: runsnake('for x in range(1,4): print x^2') # optional - runsnake
        1
        4
        9

    :func:`runsnake` requires the program ``runsnake``. Due to non
    trivial dependencies (python-wxgtk, ...), installing it within the
    Sage distribution is unpractical. Hence, we recommend installing
    it with the system wide Python. On Ubuntu 10.10, this can be done
    with::

        > sudo apt-get install python-profiler python-wxgtk2.8 python-setuptools
        > sudo easy_install RunSnakeRun

    See the ``runsnake`` website for instructions for other platforms.

    :func:`runsnake` further assumes that the system wide Python is
    installed in ``/usr/bin/python``.

    .. seealso::

        - `The runsnake website <http://www.vrplumber.com/programming/runsnakerun/>`_
        - ``%prun``
        - :class:`Profiler`

    """
    import cProfile, os
    from sage.misc.misc import tmp_filename, get_main_globals
    from sage.misc.preparser import preparse
    tmpfile = tmp_filename()
    cProfile.runctx(preparse(command.lstrip().rstrip()), get_main_globals(), locals(), filename=tmpfile)
    os.system("/usr/bin/python -E `which runsnake` %s &"%tmpfile)
Example #12
0
 def __call__(self, n, watch=False):
     n = Integer(n)
     self._validate(n)
     cmd = 'echo "%s" | %s'%(n, self.__cmd)
     if watch:
         t = tmp_filename()
         os.system('%s | tee %s'%(cmd, t))
         ou = open(t).read()
         os.unlink(t)
     else:
         i,o,e = os.popen3(cmd)
         i.close()
         ou = e.read() + '\n' + o.read()
     if 'command not found' in ou:
         err = ou + '\n' + 'You must install GMP-ECM.\n'
         err += sage.misc.package.package_mesg('ecm-6.1.3')
         raise RuntimeError, err
     return ou
Example #13
0
 def __call__(self, n, watch=False):
     n = Integer(n)
     self._validate(n)
     cmd = 'echo "%s" | %s' % (n, self.__cmd)
     if watch:
         t = tmp_filename()
         os.system("%s | tee %s" % (cmd, t))
         ou = open(t).read()
         os.unlink(t)
     else:
         i, o, e = os.popen3(cmd)
         i.close()
         ou = e.read() + "\n" + o.read()
     if "command not found" in ou:
         err = ou + "\n" + "You must install GMP-ECM.\n"
         err += sage.misc.package.package_mesg("ecm-6.1.3")
         raise RuntimeError, err
     return ou
Example #14
0
 def __call__(self, n, watch=False):
     n = Integer(n)
     self._validate(n)
     cmd = 'echo "%s" | %s'%(n, self.__cmd)
     if watch:
         t = tmp_filename()
         os.system('%s | tee %s'%(cmd, t))
         ou = open(t).read()
         os.unlink(t)
     else:
         from subprocess import Popen, PIPE
         x = Popen(cmd, shell=True,
         stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
         x.stdin.close()
         ou = x.stderr.read() + '\n' + x.stdout.read()
     if 'command not found' in ou:
         err = ou + '\n' + 'You must install GMP-ECM.\n'
         err += sage.misc.package.package_mesg('ecm-6.1.3')
         raise RuntimeError, err
     return ou
Example #15
0
 def __call__(self, n, watch=False):
     n = Integer(n)
     self._validate(n)
     cmd = 'echo "%s" | %s'%(n, self.__cmd)
     if watch:
         t = tmp_filename()
         os.system('%s | tee %s'%(cmd, t))
         ou = open(t).read()
         os.unlink(t)
     else:
         from subprocess import Popen, PIPE
         x = Popen(cmd, shell=True,
         stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
         x.stdin.close()
         ou = x.stderr.read() + '\n' + x.stdout.read()
     if 'command not found' in ou:
         err = ou + '\n' + 'You must install GMP-ECM.\n'
         err += sage.misc.package.package_mesg('ecm-6.1.3')
         raise RuntimeError, err
     return ou
Example #16
0
def compile_and_load(code):
    r"""
    INPUT:

    - ``code`` -- string containing code that could be in a .pyx file
      that is attached or put in a %cython block in the notebook.

    OUTPUT: a module, which results from compiling the given code and
    importing it

    EXAMPLES::

        sage: module = sage.misc.cython.compile_and_load("def f(int n):\n    return n*n")
        sage: module.f(10)
        100
    """
    from sage.misc.misc import tmp_filename
    file = tmp_filename() + ".pyx"
    open(file, 'w').write(code)
    from sage.server.support import cython_import
    return cython_import(file, create_local_c_file=False)
Example #17
0
def tmp_filename():
    """
    Return a temporary file.

    OUTPUT:

    String. The absolute filename of the temporary file.

    EXAMPLES::

        sage: from sage.dev.misc import tmp_filename
        sage: tmp_filename().startswith(str(SAGE_TMP))
        True
    """
    try:
        from sage.misc.misc import tmp_filename
        return tmp_filename()
    except ImportError:
        from tempfile import NamedTemporaryFile
        f = NamedTemporaryFile(dir=get_sage_tmp())
        f.close()
        return f.name
Example #18
0
    def __call__(self,
                 model,
                 outfile='sage.png',
                 verbose=1,
                 block=True,
                 extra_opts=''):
        modelfile = tmp_filename() + '.dat'
        open(modelfile, 'w').write(model)
        opts = ''
        ext = outfile[-4:].lower()
        if ext == '.png':
            opts += ' -format PNG '
        elif ext == '.tga':
            opts += ' -format TARGA '
        elif ext == '.bmp':
            opts += ' -format BMP '
        elif ext == '.ppm':
            opts += ' -format PPM '
        elif ext == '.rgb':
            opts += ' -format RGB '

        opts += ' -o %s ' % outfile

        opts += ' ' + extra_opts + ' '

        if verbose >= 2:
            opts += ' +V '
        elif verbose == 0:
            opts += '  1>/dev/null'

        cmd = 'tachyon %s %s; rm -f "%s"' % (modelfile, opts, modelfile)

        if not block:
            cmd += ' &'

        if verbose:
            print cmd
        os.system(cmd)
Example #19
0
def compile_and_load(code):
    r"""
    INPUT:

    - ``code`` -- string containing code that could be in a .pyx file
      that is attached or put in a %cython block in the notebook.

    OUTPUT: a module, which results from compiling the given code and
    importing it

    EXAMPLES::

        sage: module = sage.misc.cython.compile_and_load("def f(int n):\n    return n*n")
        sage: module.f(10)
        100
    """
    from sage.misc.misc import tmp_filename

    file = tmp_filename() + ".pyx"
    open(file, "w").write(code)
    from sage.server.support import cython_import

    return cython_import(file, create_local_c_file=False)
Example #20
0
File: chomp.py Project: chos9/sage
    def __call__(self, program, complex, subcomplex=None, **kwds):
        """
        Call a CHomP program to compute the homology of a chain
        complex, simplicial complex, or cubical complex.

        See :class:`CHomP` for full documentation.

        EXAMPLES::

        sage: from sage.interfaces.chomp import CHomP
        sage: T = cubical_complexes.Torus()
        sage: CHomP()('homcubes', T) # indirect doctest, optional - CHomP
        {0: 0, 1: Z x Z, 2: Z}
        """
        from sage.misc.misc import tmp_filename
        from sage.homology.all import CubicalComplex, cubical_complexes
        from sage.homology.all import SimplicialComplex, Simplex
        from sage.homology.cubical_complex import Cube
        from sage.homology.chain_complex import HomologyGroup, ChainComplex
        from subprocess import Popen, PIPE
        from sage.rings.all import QQ, ZZ
        from sage.modules.all import VectorSpace, vector
        from sage.combinat.free_module import CombinatorialFreeModule

        if not have_chomp(program):
            raise OSError, "Program %s not found" % program

        verbose = kwds.get('verbose', False)
        generators = kwds.get('generators', False)
        extra_opts = kwds.get('extra_opts', '')
        base_ring = kwds.get('base_ring', ZZ)

        if extra_opts:
            extra_opts = extra_opts.split()
        else:
            extra_opts = []

        # type of complex:
        cubical = False
        simplicial = False
        chain = False
        # CHomP seems to have problems with cubical complexes if the
        # first interval in the first cube defining the complex is
        # degenerate.  So replace the complex X with [0,1] x X.
        if isinstance(complex, CubicalComplex):
            cubical = True
            edge = cubical_complexes.Cube(1)
            original_complex = complex
            complex = edge.product(complex)
            if verbose:
                print "Cubical complex"
        elif isinstance(complex, SimplicialComplex):
            simplicial = True
            if verbose:
                print "Simplicial complex"
        else:
            chain = True
            base_ring = kwds.get('base_ring', complex.base_ring())
            if verbose:
                print "Chain complex over %s" % base_ring

        if base_ring == QQ:
            raise ValueError, "CHomP doesn't compute over the rationals, only over Z or F_p."
        if base_ring.is_prime_field():
            p = base_ring.characteristic()
            extra_opts.append('-p%s' % p)
            mod_p = True
        else:
            mod_p = False

        #
        #    complex
        #
        try:
            data = complex._chomp_repr_()
        except AttributeError:
            raise AttributeError, "Complex can not be converted to use with CHomP."

        datafile = tmp_filename()
        f = open(datafile, 'w')
        f.write(data)
        f.close()

        #
        #    subcomplex
        #
        if subcomplex is None:
            if cubical:
                subcomplex = CubicalComplex([complex.n_cells(0)[0]])
            elif simplicial:
                m = re.search(r'\(([^,]*),', data)
                v = int(m.group(1))
                subcomplex = SimplicialComplex([[v]])
        else:
            # replace subcomplex with [0,1] x subcomplex.
            if cubical:
                subcomplex = edge.product(subcomplex)
        #
        #    generators
        #
        if generators:
            genfile = tmp_filename()
            extra_opts.append('-g%s' % genfile)

        #
        #    call program
        #
        if subcomplex is not None:
            try:
                sub = subcomplex._chomp_repr_()
            except AttributeError:
                raise AttributeError, "Subcomplex can not be converted to use with CHomP."
            subfile = tmp_filename()
            f = open(subfile, 'w')
            f.write(sub)
            f.close()
        else:
            subfile = ''
        if verbose:
            print "Popen called with arguments",
            print [program, datafile, subfile] + extra_opts
            print
            print "CHomP output:"
            print
        # output = Popen([program, datafile, subfile, extra_opts],
        cmd = [program, datafile]
        if subfile:
            cmd.append(subfile)
        if extra_opts:
            cmd.extend(extra_opts)
        output = Popen(cmd, stdout=PIPE).communicate()[0]
        if verbose:
            print output
            print "End of CHomP output"
            print
        if generators:
            gens = open(genfile, 'r').read()
            if verbose:
                print "Generators:"
                print gens

        #
        #    process output
        #
        # output contains substrings of one of the forms
        # "H_1 = Z", "H_1 = Z_2 + Z", "H_1 = Z_2 + Z^2",
        # "H_1 = Z + Z_2 + Z"
        if output.find('trivial') != -1:
            if mod_p:
                return {0: VectorSpace(base_ring, 0)}
            else:
                return {0: HomologyGroup(0)}
        d = {}
        h = re.compile("^H_([0-9]*) = (.*)$", re.M)
        tors = re.compile("Z_([0-9]*)")
        #
        #    homology groups
        #
        for m in h.finditer(output):
            if verbose:
                print m.groups()
            # dim is the dimension of the homology group
            dim = int(m.group(1))
            # hom_str is the right side of the equation "H_n = Z^r + Z_k + ..."
            hom_str = m.group(2)
            # need to read off number of summands and their invariants
            if hom_str.find("0") == 0:
                if mod_p:
                    hom = VectorSpace(base_ring, 0)
                else:
                    hom = HomologyGroup(0)
            else:
                rk = 0
                if hom_str.find("^") != -1:
                    rk_srch = re.search(r'\^([0-9]*)\s?', hom_str)
                    rk = int(rk_srch.group(1))
                rk += len(re.findall("(Z$)|(Z\s)", hom_str))
                if mod_p:
                    rk = rk if rk != 0 else 1
                    if verbose:
                        print "dimension = %s, rank of homology = %s" % (dim, rk)
                    hom = VectorSpace(base_ring, rk)
                else:
                    n = rk
                    invts = []
                    for t in tors.finditer(hom_str):
                        n += 1
                        invts.append(int(t.group(1)))
                    for i in range(rk):
                        invts.append(0)
                    if verbose:
                        print "dimension = %s, number of factors = %s, invariants = %s" %(dim, n, invts)
                    hom = HomologyGroup(n, invts)

            #
            #    generators
            #
            if generators:
                if cubical:
                    g = process_generators_cubical(gens, dim)
                    if verbose:
                        print "raw generators: %s" % g
                    if g:
                        module = CombinatorialFreeModule(base_ring,
                                                         original_complex.n_cells(dim),
                                                         prefix="",
                                                         bracket=True)
                        basis = module.basis()
                        output = []
                        for x in g:
                            v = module(0)
                            for term in x:
                                v += term[0] * basis[term[1]]
                            output.append(v)
                        g = output
                elif simplicial:
                    g = process_generators_simplicial(gens, dim, complex)
                    if verbose:
                        print "raw generators: %s" % gens
                    if g:
                        module = CombinatorialFreeModule(base_ring,
                                                         complex.n_cells(dim),
                                                         prefix="",
                                                         bracket=False)
                        basis = module.basis()
                        output = []
                        for x in g:
                            v = module(0)
                            for term in x:
                                if complex._numeric:
                                    v += term[0] * basis[term[1]]
                                else:
                                    # if not numeric: have to
                                    # translate vertices from numbers
                                    # to their original form.
                                    translate = dict([(b,a) for (a,b) in complex._numeric_translation])
                                    simplex = Simplex([translate[a] for a in tuple(term[1])])
                                    v += term[0] * basis[simplex]
                            output.append(v)
                        g = output
                elif chain:
                    g = process_generators_chain(gens, dim, base_ring)
                    if verbose:
                        print "raw generators: %s" % gens
                if g:
                    d[dim] = (hom, g)
                else:
                    d[dim] = hom
            else:
                d[dim] = hom

        if chain:
            new_d = {}
            bottom = min(complex.differential())
            top = max(complex.differential())
            for dim in d:
                if complex._degree == -1:  # chain complex
                    new_dim = bottom + dim
                else: # cochain complex
                    new_dim = top - dim
                if isinstance(d[dim], tuple):
                    # generators included.
                    group = d[dim][0]
                    gens = d[dim][1]
                    new_gens = []
                    dimension = complex.differential(new_dim).ncols()
                    # make sure that each vector is embedded in the
                    # correct ambient space: pad with a zero if
                    # necessary.
                    for v in gens:
                        v_dict = v.dict()
                        if dimension - 1 not in v.dict():
                            v_dict[dimension - 1] = 0
                            new_gens.append(vector(base_ring, v_dict))
                        else:
                            new_gens.append(v)
                    new_d[new_dim] = (group, new_gens)
                else:
                    new_d[new_dim] = d[dim]
            d = new_d
        return d
Example #21
0
    def eval(self,x,globals=None, locals=None):
        """
        EXAMPLES::
        
            sage: from sage.misc.inline_fortran import InlineFortran, _example
            sage: test_fortran = InlineFortran(globals())   # optional -- fortran
            sage: test_fortran(_example)                    # optional -- fortran
            sage: import numpy
            sage: n = numpy.array(range(10),dtype=float)
            sage: fib(n,int(10))                            # optional -- fortran
            sage: n                                         # optional -- fortran
            array([  0.,   1.,   1.,   2.,   3.,   5.,   8.,  13.,  21.,  34.])
        """
        if len(x.splitlines()) == 1 and os.path.exists(x):
            filename = x
            x = open(x).read()
            if filename.lower().endswith('.f90'):
                x = '!f90\n' + x
        global count
        # On linux g77_shared should be a script that runs sage_fortran -shared
        # On OS X it should be a script that runs gfortran -bundle -undefined dynamic_lookup
        path = os.environ['SAGE_LOCAL']+'/bin/sage-g77_shared'
        from numpy import f2py
        old_import_path=os.sys.path
        cwd=os.getcwd()
        os.sys.path.append(cwd)

        #name = tmp_dir() + '/fortran_module_%d'%count
        name = 'fortran_module_%d'%count
        if os.path.exists(name):
            os.unlink(name)
        s_lib_path=""
        s_lib=""
        for s in self.library_paths:
            s_lib_path=s_lib_path+"-L"+s+" "

        for s in self.libraries:
            s_lib=s_lib +"-l"+s + " "

        # if the first line has !f90 as a comment gfortran will treat it as
        # fortran 90 code
        if x.startswith('!f90'):        
            fname = os.path.join(tmp_filename() +'.f90')
        else:
            fname = os.path.join(tmp_filename() +'.f')

        log = tmp_filename()
        extra_args = '--quiet --f77exec=%s --f90exec=%s %s %s  1>&2 >"%s"'%(
                    path, path, s_lib_path, s_lib, log)

        f2py.compile(x, name, extra_args = extra_args, source_fn=fname)

        log_string = open(log).read()

        os.unlink(log)
        os.unlink(fname)

        if self.verbose:
            print log_string
        
        count += 1
        try:
            m=__builtin__.__import__(name)
        except ImportError:
            if not self.verbose:
                print log_string
            return
        finally:
            os.sys.path=old_import_path
            os.unlink(name + '.so')
        
        for k, x in m.__dict__.iteritems():
            if k[0] != '_':
                self.globals[k] = x
Example #22
0
    def __call__(self, program, complex, subcomplex=None, **kwds):
        """
        Call a CHomP program to compute the homology of a chain
        complex, simplicial complex, or cubical complex.

        See :class:`CHomP` for full documentation.

        EXAMPLES::

        sage: from sage.interfaces.chomp import CHomP
        sage: T = cubical_complexes.Torus()
        sage: CHomP()('homcubes', T) # indirect doctest, optional - CHomP
        {0: 0, 1: Z x Z, 2: Z}
        """
        from sage.misc.misc import tmp_filename
        from sage.homology.all import CubicalComplex, cubical_complexes
        from sage.homology.all import SimplicialComplex, Simplex
        from sage.homology.cubical_complex import Cube
        from sage.homology.chain_complex import HomologyGroup, ChainComplex
        from subprocess import Popen, PIPE
        from sage.rings.all import QQ, ZZ
        from sage.modules.all import VectorSpace, vector
        from sage.combinat.free_module import CombinatorialFreeModule

        if not have_chomp(program):
            raise OSError("Program %s not found" % program)

        verbose = kwds.get('verbose', False)
        generators = kwds.get('generators', False)
        extra_opts = kwds.get('extra_opts', '')
        base_ring = kwds.get('base_ring', ZZ)

        if extra_opts:
            extra_opts = extra_opts.split()
        else:
            extra_opts = []

        # type of complex:
        cubical = False
        simplicial = False
        chain = False
        # CHomP seems to have problems with cubical complexes if the
        # first interval in the first cube defining the complex is
        # degenerate.  So replace the complex X with [0,1] x X.
        if isinstance(complex, CubicalComplex):
            cubical = True
            edge = cubical_complexes.Cube(1)
            original_complex = complex
            complex = edge.product(complex)
            if verbose:
                print "Cubical complex"
        elif isinstance(complex, SimplicialComplex):
            simplicial = True
            if verbose:
                print "Simplicial complex"
        else:
            chain = True
            base_ring = kwds.get('base_ring', complex.base_ring())
            if verbose:
                print "Chain complex over %s" % base_ring

        if base_ring == QQ:
            raise ValueError(
                "CHomP doesn't compute over the rationals, only over Z or F_p."
            )
        if base_ring.is_prime_field():
            p = base_ring.characteristic()
            extra_opts.append('-p%s' % p)
            mod_p = True
        else:
            mod_p = False

        #
        #    complex
        #
        try:
            data = complex._chomp_repr_()
        except AttributeError:
            raise AttributeError(
                "Complex can not be converted to use with CHomP.")

        datafile = tmp_filename()
        f = open(datafile, 'w')
        f.write(data)
        f.close()

        #
        #    subcomplex
        #
        if subcomplex is None:
            if cubical:
                subcomplex = CubicalComplex([complex.n_cells(0)[0]])
            elif simplicial:
                m = re.search(r'\(([^,]*),', data)
                v = int(m.group(1))
                subcomplex = SimplicialComplex([[v]])
        else:
            # replace subcomplex with [0,1] x subcomplex.
            if cubical:
                subcomplex = edge.product(subcomplex)
        #
        #    generators
        #
        if generators:
            genfile = tmp_filename()
            extra_opts.append('-g%s' % genfile)

        #
        #    call program
        #
        if subcomplex is not None:
            try:
                sub = subcomplex._chomp_repr_()
            except AttributeError:
                raise AttributeError(
                    "Subcomplex can not be converted to use with CHomP.")
            subfile = tmp_filename()
            f = open(subfile, 'w')
            f.write(sub)
            f.close()
        else:
            subfile = ''
        if verbose:
            print "Popen called with arguments",
            print[program, datafile, subfile] + extra_opts
            print
            print "CHomP output:"
            print
        # output = Popen([program, datafile, subfile, extra_opts],
        cmd = [program, datafile]
        if subfile:
            cmd.append(subfile)
        if extra_opts:
            cmd.extend(extra_opts)
        output = Popen(cmd, stdout=PIPE).communicate()[0]
        if verbose:
            print output
            print "End of CHomP output"
            print
        if generators:
            gens = open(genfile, 'r').read()
            if verbose:
                print "Generators:"
                print gens

        #
        #    process output
        #
        # output contains substrings of one of the forms
        # "H_1 = Z", "H_1 = Z_2 + Z", "H_1 = Z_2 + Z^2",
        # "H_1 = Z + Z_2 + Z"
        if output.find('trivial') != -1:
            if mod_p:
                return {0: VectorSpace(base_ring, 0)}
            else:
                return {0: HomologyGroup(0, ZZ)}
        d = {}
        h = re.compile("^H_([0-9]*) = (.*)$", re.M)
        tors = re.compile("Z_([0-9]*)")
        #
        #    homology groups
        #
        for m in h.finditer(output):
            if verbose:
                print m.groups()
            # dim is the dimension of the homology group
            dim = int(m.group(1))
            # hom_str is the right side of the equation "H_n = Z^r + Z_k + ..."
            hom_str = m.group(2)
            # need to read off number of summands and their invariants
            if hom_str.find("0") == 0:
                if mod_p:
                    hom = VectorSpace(base_ring, 0)
                else:
                    hom = HomologyGroup(0, ZZ)
            else:
                rk = 0
                if hom_str.find("^") != -1:
                    rk_srch = re.search(r'\^([0-9]*)\s?', hom_str)
                    rk = int(rk_srch.group(1))
                rk += len(re.findall("(Z$)|(Z\s)", hom_str))
                if mod_p:
                    rk = rk if rk != 0 else 1
                    if verbose:
                        print "dimension = %s, rank of homology = %s" % (dim,
                                                                         rk)
                    hom = VectorSpace(base_ring, rk)
                else:
                    n = rk
                    invts = []
                    for t in tors.finditer(hom_str):
                        n += 1
                        invts.append(int(t.group(1)))
                    for i in range(rk):
                        invts.append(0)
                    if verbose:
                        print "dimension = %s, number of factors = %s, invariants = %s" % (
                            dim, n, invts)
                    hom = HomologyGroup(n, ZZ, invts)

            #
            #    generators
            #
            if generators:
                if cubical:
                    g = process_generators_cubical(gens, dim)
                    if verbose:
                        print "raw generators: %s" % g
                    if g:
                        module = CombinatorialFreeModule(
                            base_ring,
                            original_complex.n_cells(dim),
                            prefix="",
                            bracket=True)
                        basis = module.basis()
                        output = []
                        for x in g:
                            v = module(0)
                            for term in x:
                                v += term[0] * basis[term[1]]
                            output.append(v)
                        g = output
                elif simplicial:
                    g = process_generators_simplicial(gens, dim, complex)
                    if verbose:
                        print "raw generators: %s" % gens
                    if g:
                        module = CombinatorialFreeModule(base_ring,
                                                         complex.n_cells(dim),
                                                         prefix="",
                                                         bracket=False)
                        basis = module.basis()
                        output = []
                        for x in g:
                            v = module(0)
                            for term in x:
                                if complex._is_numeric():
                                    v += term[0] * basis[term[1]]
                                else:
                                    translate = complex._translation_from_numeric(
                                    )
                                    simplex = Simplex(
                                        [translate[a] for a in term[1]])
                                    v += term[0] * basis[simplex]
                            output.append(v)
                        g = output
                elif chain:
                    g = process_generators_chain(gens, dim, base_ring)
                    if verbose:
                        print "raw generators: %s" % gens
                if g:
                    if not mod_p:
                        # sort generators to match up with corresponding invariant
                        g = [
                            _[1]
                            for _ in sorted(zip(invts, g), key=lambda x: x[0])
                        ]
                    d[dim] = (hom, g)
                else:
                    d[dim] = hom
            else:
                d[dim] = hom

        if chain:
            new_d = {}
            diff = complex.differential()
            if len(diff) == 0:
                return {}
            bottom = min(diff)
            top = max(diff)
            for dim in d:
                if complex._degree_of_differential == -1:  # chain complex
                    new_dim = bottom + dim
                else:  # cochain complex
                    new_dim = top - dim
                if isinstance(d[dim], tuple):
                    # generators included.
                    group = d[dim][0]
                    gens = d[dim][1]
                    new_gens = []
                    dimension = complex.differential(new_dim).ncols()
                    # make sure that each vector is embedded in the
                    # correct ambient space: pad with a zero if
                    # necessary.
                    for v in gens:
                        v_dict = v.dict()
                        if dimension - 1 not in v.dict():
                            v_dict[dimension - 1] = 0
                            new_gens.append(vector(base_ring, v_dict))
                        else:
                            new_gens.append(v)
                    new_d[new_dim] = (group, new_gens)
                else:
                    new_d[new_dim] = d[dim]
            d = new_d
        return d
Example #23
0
    def __call__(self, assumptions=None):
        """
        Run 'command' and collect output.

        INPUT:

        - ``assumptions`` - ignored, accepted for compatibility with
          other solvers (default: ``None``)

        TESTS:

        This class is not meant to be called directly::

            sage: from sage.sat.solvers.dimacs import DIMACS
            sage: fn = tmp_filename()
            sage: solver = DIMACS(filename=fn)
            sage: solver.add_clause( (1, -2 , 3) )
            sage: solver()
            Traceback (most recent call last):
            ...
            ValueError: No SAT solver command selected.
        """
        if assumptions is not None:
            raise NotImplementedError(
                "Assumptions are not supported for DIMACS based solvers.")

        self.write()

        output_filename = None
        self._output = []

        command = self._command.strip()

        if not command:
            raise ValueError("No SAT solver command selected.")

        if "{output}" in command:
            output_filename = tmp_filename()
        command = command.format(input=self._headname, output=output_filename)

        args = shlex.split(command)

        try:
            process = subprocess.Popen(args, stdout=subprocess.PIPE)
        except OSError:
            raise OSError(
                "Could run '%s', perhaps you need to add your SAT solver to $PATH?"
                % (" ".join(args)))

        try:
            while process.poll() is None:
                for line in iter(process.stdout.readline, ''):
                    if get_verbose() or self._verbosity:
                        print line,
                        sys.stdout.flush()
                    self._output.append(line)
                sleep(0.1)
            if output_filename:
                self._output.extend(open(output_filename).readlines())
        except KeyboardInterrupt:
            process.kill()
            raise KeyboardInterrupt