r"""
Interface to Scilab
Scilab is a scientific software package for numerical computations
providing a powerful open computing environment for engineering and
scientific applications. Scilab includes hundreds of mathematical
functions with the possibility to add interactively programs from
various languages (C, C++, Fortran...). It has sophisticated data
structures (including lists, polynomials, rational functions, linear
systems...), an interpreter and a high level programming language.
The commands in this section only work if you have the "scilab"
interpreter installed and available in your PATH. It's not necessary
to install any special Sage packages.
EXAMPLES::
sage: scilab.eval('2+2') # optional - scilab
'ans =\n \n 4.'
sage: scilab('2+2') # optional - scilab
4.
sage: a = scilab(10) # optional - scilab
sage: a**10 # optional - scilab
1.000D+10
Tutorial based the MATLAB interface tutorial:
EXAMPLES::
sage: scilab('4+10') # optional - scilab
14.
sage: scilab('date') # optional - scilab; random output
15-Feb-2010
sage: scilab('5*10 + 6') # optional - scilab
56.
sage: scilab('(6+6)/3') # optional - scilab
4.
sage: scilab('9')^2 # optional - scilab
81.
sage: a = scilab(10); b = scilab(20); c = scilab(30) # optional - scilab
sage: avg = (a+b+c)/3 # optional - scilab
sage: avg # optional - scilab
20.
sage: parent(avg) # optional - scilab
Scilab
sage: my_scalar = scilab('3.1415') # optional - scilab
sage: my_scalar # optional - scilab
3.1415
sage: my_vector1 = scilab('[1,5,7]') # optional - scilab
sage: my_vector1 # optional - scilab
1. 5. 7.
sage: my_vector2 = scilab('[1;5;7]') # optional - scilab
sage: my_vector2 # optional - scilab
1.
5.
7.
sage: my_vector1 * my_vector2 # optional - scilab
75.
sage: row_vector1 = scilab('[1 2 3]') # optional - scilab
sage: row_vector2 = scilab('[3 2 1]') # optional - scilab
sage: matrix_from_row_vec = scilab('[%s; %s]'%(row_vector1.name(), row_vector2.name())) # optional - scilab
sage: matrix_from_row_vec # optional - scilab
1. 2. 3.
3. 2. 1.
sage: column_vector1 = scilab('[1;3]') # optional - scilab
sage: column_vector2 = scilab('[2;8]') # optional - scilab
sage: matrix_from_col_vec = scilab('[%s %s]'%(column_vector1.name(), column_vector2.name())) # optional - scilab
sage: matrix_from_col_vec # optional - scilab
1. 2.
3. 8.
sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') # optional - scilab
sage: my_matrix # optional - scilab
8. 12. 19.
7. 3. 2.
12. 4. 23.
8. 1. 1.
sage: combined_matrix = scilab('[%s, %s]'%(my_matrix.name(), my_matrix.name())) # optional - scilab
sage: combined_matrix # optional - scilab
8. 12. 19. 8. 12. 19.
7. 3. 2. 7. 3. 2.
12. 4. 23. 12. 4. 23.
8. 1. 1. 8. 1. 1.
sage: tm = scilab('0.5:2:10') # optional - scilab
sage: tm # optional - scilab
0.5 2.5 4.5 6.5 8.5
sage: my_vector1 = scilab('[1,5,7]') # optional - scilab
sage: my_vector1(1) # optional - scilab
1.
sage: my_vector1(2) # optional - scilab
5.
sage: my_vector1(3) # optional - scilab
7.
Matrix indexing works as follows::
sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') # optional - scilab
sage: my_matrix(3,2) # optional - scilab
4.
One can also use square brackets::
sage: my_matrix[3,2] # optional - scilab
4.
Setting using parenthesis cannot work (because of how the Python
language works). Use square brackets or the set function::
sage: my_matrix = scilab('[8, 12, 19; 7, 3, 2; 12, 4, 23; 8, 1, 1]') # optional - scilab
sage: my_matrix.set(2,3, 1999) # optional - scilab
sage: my_matrix # optional - scilab
8. 12. 19.
7. 3. 1999.
12. 4. 23.
8. 1. 1.
sage: my_matrix[2,3] = -126 # optional - scilab
sage: my_matrix # optional - scilab
8. 12. 19.
7. 3. - 126.
12. 4. 23.
8. 1. 1.
TESTS::
sage: M = scilab(x) # optional - scilab
Traceback (most recent call last):
...
TypeError: _interface_init_() takes exactly one argument (0 given)
sage: M = scilab(matrix(3,range(9))); M # optional - scilab
0. 1. 2.
3. 4. 5.
6. 7. 8.
sage: M(10) # optional - scilab
Traceback (most recent call last):
...
TypeError: Error executing code in Scilab
...
Invalid index.
sage: M[10] # optional - scilab
Traceback (most recent call last):
...
TypeError: Error executing code in Scilab
...
Invalid index.
sage: M(4,2) # optional - scilab
Traceback (most recent call last):
...
TypeError: Error executing code in Scilab
...
Invalid index.
sage: M[2,4] # optional - scilab
Traceback (most recent call last):
...
TypeError: Error executing code in Scilab
...
Invalid index.
sage: M(9) = x # optional - scilab
Traceback (most recent call last):
...
SyntaxError: can't assign to function call (..., line 1)
AUTHORS:
-- Ronan Paixao (2008-11-26), based on the MATLAB tutorial by
William Stein (2006-10-11)
"""
import os
from expect import Expect, ExpectElement
class Scilab(Expect):
"""
Interface to the Scilab interpreter.
EXAMPLES:
sage: a = scilab('[ 1, 1, 2; 3, 5, 8; 13, 21, 33 ]') # optional - scilab
sage: b = scilab('[ 1; 3; 13]') # optional - scilab
sage: c = a * b # optional - scilab
sage: print c # optional - scilab
30.
122.
505.
"""
def __init__(self, maxread=100, script_subdirectory="",
logfile=None, server=None,server_tmpdir=None):
"""
Initializes the Scilab class.
EXAMPLES:
sage: from sage.interfaces.scilab import Scilab
sage: sci_obj = Scilab(script_subdirectory='user') # optional - scilab
sage: del sci_obj # optional - scilab
"""
Expect.__init__(self,
name = 'scilab',
prompt = '-->',
command = "scilab -nogui",
maxread = maxread,
server = server,
server_tmpdir = server_tmpdir,
script_subdirectory = script_subdirectory,
restart_on_ctrlc = False,
verbose_start = False,
logfile = logfile,
eval_using_file_cutoff=100)
def _quit_string(self):
"""
Returns the string used to quit the pexpect interface.
EXAMPLES:
sage: scilab._quit_string() # optional - scilab
'quit;'
"""
return 'quit;'
def _install_hints(self):
"""
Hints for installing Scilab.
EXAMPLES:
sage: print scilab._install_hints() # optional - scilab
You must ...
"""
return """
You must obtain the Scilab program in order to use Scilab
from Sage. You can read all about Scilab at
http://www.scilab.org/
The executable must be accessible system-wide.
"""
def _start(self):
"""
Starts Scilab and sets some options.
EXAMPLES:
sage: scilab._start() # optional - scilab
"""
Expect._start(self)
self.eval("mode(0)")
def eval(self, command, *args, **kwds):
"""
Evaluates commands.
EXAMPLES:
sage: scilab.eval("5") # optional - scilab
'ans =\n \n 5.'
sage: scilab.eval("d=44") # optional - scilab
'd =\n \n 44.'
"""
s = Expect.eval(self, command, **kwds).replace("\x1b[?1l\x1b>","").strip()
return s
def whos(self, name=None, typ=None):
"""
Returns information about current objects.
Arguments:
nam: first characters of selected names
typ: name of selected Scilab variable type
EXAMPLES:
sage: scilab.whos("core") # optional - scilab
'Name Type Size Bytes...'
sage: scilab.whos(typ='function') # optional - scilab
'Name Type Size Bytes...'
"""
parameters = ""
if name:
parameters += " -name %s" % (str(name))
if typ:
parameters += " -type %s" % (str(typ))
return self.eval('whos' + parameters)
def set(self, var, value):
"""
Set the variable var to the given value.
EXAMPLES:
sage: scilab.set('a', 123) # optional - scilab
sage: scilab.get('a') # optional - scilab
'\n \n 123.'
"""
cmd = '%s=%s;'%(var,value)
out = self.eval(cmd)
if out.find("error") != -1:
raise TypeError, "Error executing code in Scilab\nCODE:\n\t%s\nScilab ERROR:\n\t%s"%(cmd, out)
def get(self, var):
"""
Get the value of the variable var.
EXAMPLES:
sage: scilab.eval('b=124;') # optional - scilab
''
sage: scilab.get('b') # optional - scilab
'\n \n 124.'
"""
s = self.eval('%s'%var)
i = s.find('=')
return s[i+1:]
def console(self):
"""
Starts Scilab console.
EXAMPLES:
sage: scilab.console() # optional - scilab and not tested
"""
scilab_console()
def version(self):
"""
Returns the version of the Scilab software used.
EXAMPLES:
sage: scilab.version() # optional - scilab
'scilab-...'
"""
return scilab_version()
def sage2scilab_matrix_string(self, A):
"""
Return a Scilab matrix from a Sage matrix.
INPUT:
A Sage matrix with entries in the rationals or reals.
OUTPUT:
A string that evaluates to an Scilab matrix.
EXAMPLES:
sage: M33 = MatrixSpace(QQ,3,3) # optional - scilab
sage: A = M33([1,2,3,4,5,6,7,8,0]) # optional - scilab
sage: scilab.sage2scilab_matrix_string(A) # optional - scilab
'[1, 2, 3; 4, 5, 6; 7, 8, 0]'
"""
return str(A.rows()).replace('), (', '; ').replace('(', '').replace(')','')
def _object_class(self):
"""
Returns the class of the object.
EXAMPLES:
sage: scilab._object_class() # optional - scilab
<class 'sage.interfaces.scilab.ScilabElement'>
sage: type(scilab(2)) # optional - scilab
<class 'sage.interfaces.scilab.ScilabElement'>
"""
return ScilabElement
class ScilabElement(ExpectElement):
def __getitem__(self, n):
"""
Use parenthesis for Scilab matrices instead.
EXAMPLES:
sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab
sage: M[1] # optional - scilab
1.
sage: M[7] # optional - scilab
3.
sage: M[3,2] # optional - scilab
8.
"""
if isinstance(n, tuple):
index = str(n)[1:-1]
else:
index = str(n)
return self.parent()('%s(%s)' % (self._name, index))
def __setitem__(self, n, value):
"""
Sets an element of a matrix.
EXAMPLES:
sage: M = scilab('[1,2,3;4,5,6;7,8,9]') # optional - scilab
sage: M[6] = 0 # optional - scilab
sage: M # optional - scilab
1. 2. 3.
4. 5. 6.
7. 0. 9.
sage: M[3,2] = 10 # optional - scilab
sage: M # optional - scilab
1. 2. 3.
4. 5. 6.
7. 10. 9.
"""
if isinstance(n, tuple):
index = str(n)[1:-1]
else:
index = str(n)
self.parent().eval('%s(%s) = %s' % (self._name, index, value))
def _matrix_(self, R):
r"""
Return \sage matrix from this scilab element.
EXAMPLES:
sage: A = scilab('[1,2;3,4]') # optional - scilab
sage: matrix(ZZ, A) # optional - scilab
[1 2]
[3 4]
sage: A = scilab('[1,2;3,4.5]') # optional - scilab
sage: matrix(RR, A) # optional - scilab
[1.00000000000000 2.00000000000000]
[3.00000000000000 4.50000000000000]
"""
from sage.matrix.all import MatrixSpace
from sage.rings.all import ZZ
s = str(self).strip()
v = s.split('\n ')
nrows = len(v)
if nrows == 0:
return MatrixSpace(R,0,0)(0)
ncols = len(v[0].split())
M = MatrixSpace(R, nrows, ncols)
v = sum([[x.rstrip('.') for x in w.split()] for w in v], [])
return M(v)
def set(self, i, j, x):
"""
Set the variable var to the given value.
EXAMPLES:
sage: scilab.set('c', 125) # optional - scilab
sage: scilab.get('c') # optional - scilab
'\n \n 125.'
"""
P = self._check_valid()
z = P(x)
P.eval('%s(%s,%s) = %s'%(self.name(), i, j, z.name()))
scilab = Scilab(script_subdirectory='user')
import os
def scilab_console():
"""
This requires that the optional Scilab program be installed and in
your PATH, but no optional Sage packages need to be installed.
EXAMPLES:
sage: from sage.interfaces.scilab import scilab_console # optional - scilab
sage: scilab_console() # optional - scilab and not tested
___________________________________________
scilab-5.0.3
Consortium Scilab (DIGITEO)
Copyright (c) 1989-2008 (INRIA)
Copyright (c) 1989-2007 (ENPC)
___________________________________________
Startup execution:
loading initial environment
-->2+3
ans =
5.
-->quit
Typing quit exits the Scilab console and returns you to Sage.
Scilab, like Sage, remembers its history from one session to
another.
"""
os.system('scilab -nogui')
def scilab_version():
"""
Return the version of Scilab installed.
EXAMPLES:
sage: from sage.interfaces.scilab import scilab_version # optional - scilab
sage: scilab_version() # optional - scilab
'scilab-...'
"""
return str(scilab('getversion()')).strip()