| version 1.1, 2018/09/08 05:35:35 |
version 1.3, 2019/03/29 02:17:00 |
|
|
| # $OpenXM$ |
# $OpenXM: OpenXM/src/sage/asir.py,v 1.2 2019/03/06 02:38:33 takayama Exp $ |
| from __future__ import print_function |
from __future__ import print_function |
| from __future__ import absolute_import |
from __future__ import absolute_import |
| |
|
| import os |
import os |
| from .expect import Expect, ExpectElement |
from sage.interfaces.expect import Expect, ExpectElement |
| from sage.misc.misc import verbose |
from sage.misc.misc import verbose |
| |
|
| |
##Ref: @s/2018/09/20180907-sage-asir-proj, Using External Libraries and Interfaces |
| |
##Ref: /usr/lib/python2.7/dist-packages/sage/interfaces |
| |
##Usage: load("asir.py"); |
| |
|
| class Asir(Expect): |
class Asir(Expect): |
| r""" |
r""" |
| Interface to the Asir interpreter. |
Interface to the Asir interpreter. |
| |
|
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: asir.eval("a = [ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]") # optional - asir |
sage: asir.evall("F=fctr(x^10-1)") # optional - asir |
| 'a =\n\n 1 1 2\n 3 5 8\n 13 21 33\n\n's |
|
| sage: asir.eval("b = [ 1; 3; 13]") # optional - asir |
|
| 'b =\n\n 1\n 3\n 13\n\n' |
|
| sage: asir.eval("c=a \\ b") # solves linear equation: a*c = b # optional - asir; random output |
|
| 'c =\n\n 1\n 7.21645e-16\n -7.21645e-16\n\n' |
|
| sage: asir.eval("c") # optional - asir; random output |
|
| 'c =\n\n 1\n 7.21645e-16\n -7.21645e-16\n\n' |
|
| """ |
""" |
| |
|
| def __init__(self, maxread=None, script_subdirectory=None, logfile=None, |
def __init__(self, maxread=None, script_subdirectory=None, logfile=None, |
| Line 39 class Asir(Expect): |
|
| Line 36 class Asir(Expect): |
|
| Expect.__init__(self, |
Expect.__init__(self, |
| name = 'asir', |
name = 'asir', |
| # We want the prompt sequence to be unique to avoid confusion with syntax error messages containing >>> |
# We want the prompt sequence to be unique to avoid confusion with syntax error messages containing >>> |
| # prompt = 'asir\:\d+> ', |
|
| prompt = 'asir>', |
prompt = 'asir>', |
| # prompt = '', |
|
| # We don't want any pagination of output |
# We don't want any pagination of output |
| # command = command + " --no-line-editing --silent --eval 'PS2(PS1());more off' --persist", |
|
| command = 'openxm ox_texmacs --view sage --quiet --noCopyright', |
command = 'openxm ox_texmacs --view sage --quiet --noCopyright', |
| # command = "openxm asir -quiet", |
|
| maxread = maxread, |
maxread = maxread, |
| server = server, |
server = server, |
| server_tmpdir = server_tmpdir, |
server_tmpdir = server_tmpdir, |
| Line 58 class Asir(Expect): |
|
| Line 51 class Asir(Expect): |
|
| |
|
| def set_seed(self, seed=None): |
def set_seed(self, seed=None): |
| """ |
""" |
| Sets the seed for the random number generator |
Not implemented. Sets the seed for the random number generator |
| for this asir interpreter. |
for this asir interpreter. |
| |
|
| EXAMPLES:: |
|
| |
|
| sage: o = Asir() # optional - asir |
|
| sage: o.set_seed(1) # optional - asir |
|
| 1 |
|
| sage: [o.rand() for i in range(5)] # optional - asir |
|
| [ 0.134364, 0.847434, 0.763775, 0.255069, 0.495435] |
|
| """ |
""" |
| if seed is None: |
return 0 |
| seed = self.rand_seed() |
|
| self.eval("rand('state',%d)" % seed) |
|
| self._seed = seed |
|
| return seed |
|
| |
|
| def __reduce__(self): |
def __reduce__(self): |
| """ |
""" |
| Line 90 class Asir(Expect): |
|
| Line 71 class Asir(Expect): |
|
| |
|
| sage: filename = tmp_filename() |
sage: filename = tmp_filename() |
| sage: asir._read_in_file_command(filename) |
sage: asir._read_in_file_command(filename) |
| 'source("...");' |
'load("...");' |
| """ |
""" |
| return 'source("%s");'%filename |
return 'load("%s");'%filename |
| |
|
| def _quit_string(self): |
def _quit_string(self): |
| """ |
""" |
| Line 113 class Asir(Expect): |
|
| Line 94 class Asir(Expect): |
|
| You must get ... |
You must get ... |
| """ |
""" |
| return """ |
return """ |
| You must get the program "asir" in order to use Asir |
You must get the program "asir" and "ox_texmacs" in order to use Asir |
| from Sage. You can read all about Asir at |
from Sage. You can read all about Asir at |
| http://www.gnu.org/software/asir/ |
http://www.openxm.org |
| |
The command openxm must be in the search path. |
| LINUX: |
|
| Do apt-get install asir as root on your machine (Ubuntu/Debian). |
|
| Other Linux systems have asir too. |
|
| |
|
| OS X: |
|
| * This website has details on OS X builds of Asir: |
|
| http://wiki.asir.org/Asir_for_MacOS_X |
|
| * Darwin ports and fink have Asir as well. |
|
| """ |
""" |
| |
def evall(self,cmd): |
| |
""" |
| |
evalutes the argument immediately. The argument of eval is buffered |
| |
and ; should be added. |
| |
EXAMPLES:: |
| |
sage: asir.eval('1+2;'); asir.evall('3+3') |
| |
""" |
| |
return self.eval(cmd+';;') |
| def _eval_line(self, line, reformat=True, allow_use_file=False, |
def _eval_line(self, line, reformat=True, allow_use_file=False, |
| wait_for_prompt=True, restart_if_needed=False): |
wait_for_prompt=True, restart_if_needed=False): |
| """ |
""" |
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: print(asir._eval_line('2+2')) #optional - asir |
sage: print(asir._eval_line('2+2')) #optional - asir |
| ans = 4 |
'4' |
| """ |
""" |
| from pexpect.exceptions import EOF |
from pexpect.exceptions import EOF |
| if not wait_for_prompt: |
if not wait_for_prompt: |
| Line 169 class Asir(Expect): |
|
| Line 149 class Asir(Expect): |
|
| return '' |
return '' |
| |
|
| def _keyboard_interrupt(self): |
def _keyboard_interrupt(self): |
| print("CntrlC: Interrupting %s..."%self) |
print("Ctrl-C: Interrupting %s..."%self) |
| if self._restart_on_ctrlc: |
if self._restart_on_ctrlc: |
| try: |
try: |
| self._expect.close(force=1) |
self._expect.close(force=1) |
| Line 252 class Asir(Expect): |
|
| Line 232 class Asir(Expect): |
|
| |
|
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: asir.set('x', '2') # optional - asir |
sage: asir.set('X', '2') # optional - asir |
| sage: asir.get('x') # optional - asir |
sage: asir.get('X') # optional - asir |
| ' 2' |
' 2' |
| """ |
""" |
| cmd = '%s=%s;'%(var,value) |
cmd = '%s=%s'%(var,value) |
| out = self.eval(cmd) |
out = self.evall(cmd) |
| if out.find("error") != -1 or out.find("Error") != -1: |
if out.find("error") != -1 or out.find("Error") != -1: |
| raise TypeError("Error executing code in Asir\nCODE:\n\t%s\nAsir ERROR:\n\t%s"%(cmd, out)) |
raise TypeError("Error executing code in Asir\nCODE:\n\t%s\nAsir ERROR:\n\t%s"%(cmd, out)) |
| |
|
| Line 267 class Asir(Expect): |
|
| Line 247 class Asir(Expect): |
|
| |
|
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: asir.set('x', '2') # optional - asir |
sage: asir.set('X', '2') # optional - asir |
| sage: asir.get('x') # optional - asir |
sage: asir.get('X') # optional - asir |
| ' 2' |
' 2' |
| """ |
""" |
| s = self.eval('%s;'%var) |
s = self.evall('%s;'%var) |
| i = s.find('=') |
i = s.find('=') |
| return s[i+1:] |
return s[i+1:] |
| |
|
| def clear(self, var): |
|
| """ |
|
| Clear the variable named var. |
|
| |
|
| EXAMPLES:: |
|
| |
|
| sage: asir.set('x', '2') # optional - asir |
|
| sage: asir.clear('x') # optional - asir |
|
| sage: asir.get('x') # optional - asir |
|
| "error: 'x' undefined near line ... column 1" |
|
| """ |
|
| self.eval('clear %s'%var) |
|
| |
|
| def console(self): |
def console(self): |
| """ |
""" |
| Spawn a new Asir command-line session. |
Spawn a new Asir command-line session. |
| Line 297 class Asir(Expect): |
|
| Line 264 class Asir(Expect): |
|
| |
|
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: asir_console() # not tested |
sage: asir_console() |
| GNU Asir, version 2.1.73 (i386-apple-darwin8.5.3). |
This is Risa/Asir, .... |
| Copyright (C) 2006 John W. Eaton. |
|
| ... |
... |
| asir:1> 2+3 |
[nnnn] 2+3; |
| ans = 5 |
5 |
| asir:2> [ctl-d] |
[nnnn] quit(); |
| |
|
| Pressing ctrl-d exits the asir console and returns you to Sage. |
quit(); exits the asir console and returns you to Sage. |
| asir, like Sage, remembers its history from one session to |
|
| another. |
|
| """ |
""" |
| asir_console() |
asir_console() |
| |
|
| def version(self): |
def version(self): |
| """ |
""" |
| Return the version of Asir. |
Return the version of Asir. |
| |
bug: it returns error because sage tries to set sage0=version(); |
| |
insread of Sage0=version(); |
| OUTPUT: string |
OUTPUT: string |
| |
|
| EXAMPLES:: |
EXAMPLES:: |
| Line 323 class Asir(Expect): |
|
| Line 288 class Asir(Expect): |
|
| sage: v # optional - asir; random |
sage: v # optional - asir; random |
| '2.13.7' |
'2.13.7' |
| |
|
| sage: import re |
|
| sage: assert re.match("\d+\.\d+\.\d+", v) is not None # optional - asir |
|
| """ |
""" |
| return str(self("version()")).strip() |
return str(self("version()")).strip() |
| |
|
| def solve_linear_system(self, A, b): |
|
| r""" |
|
| Use asir to compute a solution x to A\*x = b, as a list. |
|
| |
|
| INPUT: |
|
| |
|
| - ``A`` -- mxn matrix A with entries in `\QQ` or `\RR` |
|
| |
|
| - ``b`` -- m-vector b entries in `\QQ` or `\RR` (resp) |
|
| |
|
| OUTPUT: A list x (if it exists) which solves M\*x = b |
|
| |
|
| EXAMPLES:: |
|
| |
|
| sage: M33 = MatrixSpace(QQ,3,3) |
|
| sage: A = M33([1,2,3,4,5,6,7,8,0]) |
|
| sage: V3 = VectorSpace(QQ,3) |
|
| sage: b = V3([1,2,3]) |
|
| sage: asir.solve_linear_system(A,b) # optional - asir (and output is slightly random in low order bits) |
|
| [-0.33333299999999999, 0.66666700000000001, -3.5236600000000002e-18] |
|
| |
|
| AUTHORS: |
|
| |
|
| - David Joyner and William Stein |
|
| """ |
|
| m = A.nrows() |
|
| if m != len(b): |
|
| raise ValueError("dimensions of A and b must be compatible") |
|
| from sage.matrix.all import MatrixSpace |
|
| from sage.rings.all import QQ |
|
| MS = MatrixSpace(QQ,m,1) |
|
| b = MS(list(b)) # converted b to a "column vector" |
|
| sA = self.sage2asir_matrix_string(A) |
|
| sb = self.sage2asir_matrix_string(b) |
|
| self.eval("a = " + sA ) |
|
| self.eval("b = " + sb ) |
|
| soln = asir.eval("c = a \\ b") |
|
| soln = soln.replace("\n\n ","[") |
|
| soln = soln.replace("\n\n","]") |
|
| soln = soln.replace("\n",",") |
|
| sol = soln[3:] |
|
| return eval(sol) |
|
| |
|
| |
|
| def sage2asir_matrix_string(self, A): |
|
| """ |
|
| Return an asir matrix from a Sage matrix. |
|
| |
|
| INPUT: A Sage matrix with entries in the rationals or reals. |
|
| |
|
| OUTPUT: A string that evaluates to an Asir matrix. |
|
| |
|
| EXAMPLES:: |
|
| |
|
| sage: M33 = MatrixSpace(QQ,3,3) |
|
| sage: A = M33([1,2,3,4,5,6,7,8,0]) |
|
| sage: asir.sage2asir_matrix_string(A) # optional - asir |
|
| '[1, 2, 3; 4, 5, 6; 7, 8, 0]' |
|
| |
|
| AUTHORS: |
|
| |
|
| - David Joyner and William Stein |
|
| """ |
|
| return str(A.rows()).replace('), (', '; ').replace('(', '').replace(')','') |
|
| |
|
| def de_system_plot(self, f, ics, trange): |
|
| r""" |
|
| Plots (using asir's interface to gnuplot) the solution to a |
|
| `2\times 2` system of differential equations. |
|
| |
|
| INPUT: |
|
| |
|
| |
|
| - ``f`` - a pair of strings representing the |
|
| differential equations; The independent variable must be called x |
|
| and the dependent variable must be called y. |
|
| |
|
| - ``ics`` - a pair [x0,y0] such that x(t0) = x0, y(t0) |
|
| = y0 |
|
| |
|
| - ``trange`` - a pair [t0,t1] |
|
| |
|
| |
|
| OUTPUT: a gnuplot window appears |
|
| |
|
| EXAMPLES:: |
|
| |
|
| sage: asir.de_system_plot(['x+y','x-y'], [1,-1], [0,2]) # not tested -- does this actually work (on OS X it fails for me -- William Stein, 2007-10) |
|
| |
|
| This should yield the two plots `(t,x(t)), (t,y(t))` on the |
|
| same graph (the `t`-axis is the horizontal axis) of the |
|
| system of ODEs |
|
| |
|
| .. math:: |
|
| |
|
| x' = x+y, x(0) = 1;\qquad y' = x-y, y(0) = -1, \quad\text{for}\quad 0 < t < 2. |
|
| """ |
|
| eqn1 = f[0].replace('x','x(1)').replace('y','x(2)') |
|
| eqn2 = f[1].replace('x','x(1)').replace('y','x(2)') |
|
| fcn = "function xdot = f(x,t) xdot(1) = %s; xdot(2) = %s; endfunction"%(eqn1, eqn2) |
|
| self.eval(fcn) |
|
| x0_eqn = "x0 = [%s; %s]"%(ics[0], ics[1]) |
|
| self.eval(x0_eqn) |
|
| t_eqn = "t = linspace(%s, %s, 200)'"%(trange[0], trange[1]) |
|
| self.eval(t_eqn) |
|
| x_eqn = 'x = lsode("f",x0,t);' |
|
| self.eval(x_eqn) |
|
| self.eval("plot(t,x)") |
|
| |
|
| def _object_class(self): |
def _object_class(self): |
| """ |
""" |
| EXAMPLES:: |
EXAMPLES:: |
| Line 449 class Asir(Expect): |
|
| Line 303 class Asir(Expect): |
|
| |
|
| asir_functions = set() |
asir_functions = set() |
| |
|
| def to_complex(asir_string, R): |
#Todo, the following class has not yet been implemented. |
| r""" |
# These are sample interface with octave. |
| Helper function to convert asir complex number |
|
| |
|
| TESTS:: |
|
| |
|
| sage: from sage.interfaces.asir import to_complex |
|
| sage: to_complex('(0,1)', CDF) |
|
| 1.0*I |
|
| sage: to_complex('(1.3231,-0.2)', CDF) |
|
| 1.3231 - 0.2*I |
|
| """ |
|
| real, imag = asir_string.strip('() ').split(',') |
|
| return R(float(real), float(imag)) |
|
| |
|
| class AsirElement(ExpectElement): |
class AsirElement(ExpectElement): |
| def _get_sage_ring(self): |
def _get_sage_ring(self): |
| r""" |
r""" |
| Line 680 def asir_console(): |
|
| Line 521 def asir_console(): |
|
| EXAMPLES:: |
EXAMPLES:: |
| |
|
| sage: asir_console() # not tested |
sage: asir_console() # not tested |
| GNU Asir, version 2.1.73 (i386-apple-darwin8.5.3). |
This is Risa/Asir .... |
| Copyright (C) 2006 John W. Eaton. |
|
| ... |
... |
| asir:1> 2+3 |
[nnnn] 2+3; |
| ans = 5 |
5 |
| asir:2> [ctl-d] |
[nnnn] quit(); |
| |
|
| Pressing ctrl-d exits the asir console and returns you to Sage. |
quit(); exits the asir console and returns you to Sage. |
| asir, like Sage, remembers its history from one session to |
|
| another. |
|
| """ |
""" |
| from sage.repl.rich_output.display_manager import get_display_manager |
from sage.repl.rich_output.display_manager import get_display_manager |
| if not get_display_manager().is_in_terminal(): |
if not get_display_manager().is_in_terminal(): |
| raise RuntimeError('Can use the console only in the terminal. Try %%asir magics instead.') |
raise RuntimeError('Can use the console only in the terminal. Try %%asir magics instead.') |
| os.system('openxm asir') # with asir prompt |
os.system('openxm fep asir') # with asir prompt |
| # os.system('openxm asir -quiet') |
# os.system('openxm asir -quiet') |
| |
|
| |
|