Ticket #7377: trac_7377-split_and_refactor-p3.patch
File trac_7377-split_and_refactor-p3.patch, 168.1 KB (added by , 10 years ago) |
---|
-
sage/calculus/calculus.py
# HG changeset patch # User Jean-Pierre Flori <flori@enst.fr> # Date 1297688775 -3600 # Node ID 1d93d2e35ef6534eb448728e64c39a1b0cbb67b7 # Parent df3ffca8158810ee8dc20ab1476ebfc7ba04c323 Split Expect interface. diff -r df3ffca81588 -r 1d93d2e35ef6 sage/calculus/calculus.py
a b 364 364 from sage.rings.real_mpfr import create_RealNumber 365 365 366 366 from sage.misc.latex import latex, latex_variable_name 367 from sage.interfaces.maxima import Maxima368 367 from sage.misc.parser import Parser 369 368 370 369 from sage.symbolic.ring import var, SR, is_SymbolicVariable … … 374 373 from sage.symbolic.integration.integral import indefinite_integral, \ 375 374 definite_integral 376 375 import sage.symbolic.pynac 377 import sage.interfaces.maxima_lib378 376 379 377 """ 380 378 Check if maxima has redundant variables defined after initialization #9538:: 381 379 382 sage: maxima = sage.interfaces.maxima _lib.maxima380 sage: maxima = sage.interfaces.maxima.maxima 383 381 sage: maxima('f1') 384 382 f1 385 383 sage: sage.calculus.calculus.maxima('f1') 386 384 f1 387 385 """ 388 maxima = sage.interfaces.maxima_lib.maxima 389 #maxima = Maxima(init_code = ['display2d:false', 'domain: complex', 390 # 'keepfloat: true', 'load(to_poly_solver)', 'load(simplify_sum)'], 386 import sage.interfaces.maxima_lib 387 maxima = sage.interfaces.maxima_lib.maxima_lib 388 # This is not the same instance of Maxima as the general purpose one 389 #from sage.interfaces.maxima import Maxima 390 #maxima = Maxima(init_code = ['display2d : false', 'domain : complex', 391 # 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'], 391 392 # script_subdirectory=None) 392 393 393 394 ######################################################## -
sage/interfaces/all.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/all.py
a b 17 17 from magma_free import magma_free 18 18 from macaulay2 import macaulay2, macaulay2_console, Macaulay2 19 19 from maple import maple, maple_console, Maple 20 from maxima import maxima, maxima_console, is_MaximaElement, Maxima 20 from maxima_abstract import maxima_console 21 from maxima import maxima, is_MaximaElement, Maxima 22 # import problems 23 #from maxima_lib import maxima_lib 21 24 from mathematica import mathematica, mathematica_console, Mathematica 22 25 from matlab import matlab, matlab_console, matlab_version, Matlab 23 26 from mupad import mupad, mupad_console, Mupad # NOT functional yet -
sage/interfaces/expect.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/expect.py
a b 1 1 """ 2 Common Interface Functionality 2 Common Interface Functionality through Pexpect 3 3 4 4 See the examples in the other sections for how to use specific 5 5 interfaces. The interface classes all derive from the generic … … 17 17 - Simon King (2010-09-25): Expect._local_tmpfile() depends on 18 18 Expect.pid() and is cached; Expect.quit() clears that cache, 19 19 which is important for forking. 20 21 - Jean-Pierre Flori (2010,2011): Split non Pexpect stuff into a parent class. 20 22 """ 21 23 22 24 #***************************************************************************** … … 42 44 import time 43 45 import gc 44 46 import operator 47 import quit 48 import cleaner 45 49 from random import randrange 46 50 47 51 ######################################################## … … 51 55 ######################################################## 52 56 import pexpect 53 57 from pexpect import ExceptionPexpect 54 58 from sage.interfaces.interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement, AsciiArtString 55 59 56 60 from sage.structure.sage_object import SageObject 57 61 from sage.structure.parent_base import ParentWithBase 58 import sage.structure.element62 from sage.structure.element import RingElement 59 63 60 64 import sage.misc.sage_eval 61 62 import quit63 64 import cleaner65 66 import os67 68 65 from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE, LOCAL_IDENTIFIER 69 from sage.structure.element import RingElement70 71 66 from sage.misc.object_multiplexer import Multiplex 72 67 73 68 BAD_SESSION = -2 … … 142 137 gc.enable() 143 138 return False 144 139 145 class AsciiArtString(str): 146 def __repr__(self): 147 return str(self) 148 149 class PropTypeError(Exception): 150 pass 151 152 153 class Expect(ParentWithBase): 140 class Expect(Interface): 154 141 """ 155 142 Expect interface object. 156 143 """ … … 161 148 logfile = None, eval_using_file_cutoff=0, 162 149 do_cleaner = True, remote_cleaner = False, path=None): 163 150 151 Interface.__init__(self, name) 164 152 self.__is_remote = False 165 153 self.__remote_cleaner = remote_cleaner 166 154 if command == None: … … 188 176 self.__maxread = maxread 189 177 self._eval_using_file_cutoff = eval_using_file_cutoff 190 178 self.__script_subdirectory = script_subdirectory 191 self.__name = name192 self.__coerce_name = '_' + name.lower() + '_'193 179 self.__command = command 194 180 self._prompt = prompt 195 181 self._restart_on_ctrlc = restart_on_ctrlc … … 199 185 elif script_subdirectory is None: 200 186 self.__path = '.' 201 187 else: 202 self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT, self.__name,188 self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT,name, 203 189 self.__script_subdirectory) 204 190 self.__initialized = False 205 191 self.__seq = -1 … … 212 198 if isinstance(logfile, basestring): 213 199 logfile = open(logfile,'w') 214 200 self.__logfile = logfile 215 216 201 217 202 quit.expect_objects.append(weakref.ref(self)) 218 203 self._available_vars = [] 219 ParentWithBase.__init__(self, self)220 204 221 205 def _get(self, wait=0.1, alternate_prompt=None): 222 206 if self._expect is None: … … 286 270 def user_dir(self): 287 271 return self.__path 288 272 289 def _repr_(self):290 return self.__name.capitalize()291 292 273 def _change_prompt(self, prompt): 293 274 self._prompt = prompt 294 275 … … 299 280 # os.makedirs(T) 300 281 # return T + str(x) 301 282 302 def name(self, new_name=None):303 return self.__name304 305 283 def path(self): 306 284 return self.__path 307 285 … … 461 439 except (ExceptionPexpect, pexpect.EOF, IndexError): 462 440 self._expect = None 463 441 self._session_number = BAD_SESSION 464 failed_to_start.append(self. __name)442 failed_to_start.append(self.name()) 465 443 raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%( 466 self. __name, cmd, self._install_hints())444 self.name(), cmd, self._install_hints()) 467 445 468 446 os.chdir(current_path) 469 447 self._expect.timeout = self.__max_startup_time … … 476 454 except (pexpect.TIMEOUT, pexpect.EOF), msg: 477 455 self._expect = None 478 456 self._session_number = BAD_SESSION 479 failed_to_start.append(self. __name)480 raise RuntimeError, "Unable to start %s"%self. __name457 failed_to_start.append(self.name()) 458 raise RuntimeError, "Unable to start %s"%self.name() 481 459 self._expect.timeout = None 482 460 with gc_disabled(): 483 461 if block_during_init: … … 513 491 except Exception, msg: 514 492 pass 515 493 516 def cputime(self):517 """518 CPU time since this process started running.519 """520 raise NotImplementedError521 522 494 def quit(self, verbose=False, timeout=0.25): 523 495 """ 524 496 EXAMPLES:: … … 1056 1028 except TypeError, s: 1057 1029 raise TypeError, 'error evaluating "%s":\n%s'%(code,s) 1058 1030 1059 def execute(self, *args, **kwds):1060 return self.eval(*args, **kwds)1061 1062 def __call__(self, x, name=None):1063 1064 r"""1065 Create a new object in self from x.1066 1067 The object X returned can be used like any Sage object, and1068 wraps an object in self. The standard arithmetic operators1069 work. Moreover if foo is a function then1070 X.foo(y,z,...)1071 calls foo(X, y, z, ...) and returns the corresponding object.1072 1073 EXAMPLES::1074 1075 sage: gp(2)1076 21077 sage: gp('2')1078 21079 sage: a = gp(2); gp(a) is a1080 True1081 1082 """1083 cls = self._object_class()1084 1085 #Handle the case when x is an object1086 #in some interface.1087 if isinstance(x, ExpectElement):1088 if x.parent() is self:1089 return x1090 1091 #We convert x into an object in this1092 #interface by first going through Sage.1093 try:1094 return self(x._sage_())1095 except (NotImplementedError, TypeError):1096 pass1097 1098 if isinstance(x, basestring):1099 return cls(self, x, name=name)1100 try:1101 return self._coerce_from_special_method(x)1102 except TypeError:1103 raise1104 except AttributeError, msg:1105 pass1106 try:1107 return self._coerce_impl(x, use_special=False)1108 except TypeError, msg:1109 try:1110 return cls(self, str(x), name=name)1111 except TypeError, msg2:1112 raise TypeError, msg1113 1114 def _coerce_from_special_method(self, x):1115 """1116 Tries to coerce to self by calling a special underscore method.1117 1118 If no such method is defined, raises an AttributeError instead of a1119 TypeError.1120 """1121 s = '_%s_'%self.name()1122 if s == '_pari_':1123 s = '_gp_'1124 try:1125 return (x.__getattribute__(s))(self)1126 except AttributeError:1127 return self(x._interface_init_())1128 1129 def _coerce_impl(self, x, use_special=True):1130 if isinstance(x, (int, long)):1131 import sage.rings.all1132 return self(sage.rings.all.Integer(x))1133 elif isinstance(x, float):1134 import sage.rings.all1135 return self(sage.rings.all.RDF(x))1136 if use_special:1137 try:1138 return self._coerce_from_special_method(x)1139 except AttributeError, msg:1140 pass1141 1142 if isinstance(x, (list, tuple)):1143 A = []1144 z = []1145 cls = self._object_class()1146 for v in x:1147 if isinstance(v, cls):1148 A.append(v.name())1149 z.append(v)1150 else:1151 w = self(v)1152 A.append(w.name())1153 z.append(w)1154 X = ','.join(A)1155 r = self.new('%s%s%s'%(self._left_list_delim(), X, self._right_list_delim()))1156 r.__sage_list = z # do this to avoid having the entries of the list be garbage collected1157 return r1158 1159 1160 raise TypeError, "unable to coerce element into %s"%self.name()1161 1162 def new(self, code):1163 return self(code)1164 1165 ###################################################################1166 # these should all be appropriately overloaded by the derived class1167 ###################################################################1168 1169 def _left_list_delim(self):1170 return "["1171 1172 def _right_list_delim(self):1173 return "]"1174 1175 def _left_func_delim(self):1176 return "("1177 1178 def _right_func_delim(self):1179 return ")"1180 1181 def _assign_symbol(self):1182 return "="1183 1184 def _equality_symbol(self):1185 raise NotImplementedError1186 1187 # For efficiency purposes, you should definitely override these1188 # in your derived class.1189 def _true_symbol(self):1190 try:1191 return self.__true_symbol1192 except AttributeError:1193 self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol())1194 1195 def _false_symbol(self):1196 try:1197 return self.__false_symbol1198 except AttributeError:1199 self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol())1200 1201 def _lessthan_symbol(self):1202 return '<'1203 1204 def _greaterthan_symbol(self):1205 return '>'1206 1207 def _inequality_symbol(self):1208 return '!='1209 1210 def _relation_symbols(self):1211 """1212 Returns a dictionary with operators as the keys and their1213 string representation as the values.1214 1215 EXAMPLES::1216 1217 sage: import operator1218 sage: symbols = mathematica._relation_symbols()1219 sage: symbols[operator.eq]1220 '=='1221 """1222 return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()),1223 (operator.lt, self._lessthan_symbol()), (operator.le, "<="),1224 (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")])1225 1226 def _exponent_symbol(self):1227 """1228 Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e61229 1230 EXAMPLES::1231 1232 sage: from sage.interfaces.expect import Expect1233 sage: Expect('nonexistent_interface', 'fake')._exponent_symbol()1234 'e'1235 """1236 return 'e'1237 1238 1031 ############################################################ 1239 1032 # Functions for working with variables. 1240 1033 # The first three must be overloaded by derived classes, … … 1242 1035 # the functionality one gets from this is very nice. 1243 1036 ############################################################ 1244 1037 1245 def set(self, var, value):1246 """1247 Set the variable var to the given value.1248 """1249 cmd = '%s%s%s;'%(var,self._assign_symbol(), value)1250 self.eval(cmd)1251 1252 def get(self, var):1253 """1254 Get the value of the variable var.1255 """1256 return self.eval(var)1257 1258 def get_using_file(self, var):1259 r"""1260 Return the string representation of the variable var in self,1261 possibly using a file. Use this if var has a huge string1262 representation, since it may be way faster.1263 1264 .. warning::1265 1266 In fact unless a special derived class implements this, it1267 will *not* be any faster. This is the case for this class1268 if you're reading it through introspection and seeing this.1269 """1270 return self.get(var)1271 1272 def clear(self, var):1273 """1274 Clear the variable named var.1275 """1276 self._available_vars.append(var)1277 1278 def _next_var_name(self):1279 if len(self._available_vars) != 0:1280 v = self._available_vars[0]1281 del self._available_vars[0]1282 return v1283 self.__seq += 11284 return "sage%s"%self.__seq1285 1286 def _create(self, value, name=None):1287 name = self._next_var_name() if name is None else name1288 self.set(name, value)1289 return name1290 1291 1038 def _object_class(self): 1292 1039 """ 1293 1040 EXAMPLES:: … … 1317 1064 <class 'sage.interfaces.expect.FunctionElement'> 1318 1065 """ 1319 1066 return FunctionElement 1067 1320 1068 1321 def _convert_args_kwds(self, args=None, kwds=None): 1322 """ 1323 Converts all of the args and kwds to be elements of this 1324 interface. 1325 1326 EXAMPLES:: 1327 1328 sage: args = [5] 1329 sage: kwds = {'x': 6} 1330 sage: args, kwds = gap._convert_args_kwds(args, kwds) 1331 sage: args 1332 [5] 1333 sage: map(type, args) 1334 [<class 'sage.interfaces.gap.GapElement'>] 1335 sage: type(kwds['x']) 1336 <class 'sage.interfaces.gap.GapElement'> 1337 """ 1338 args = [] if args is None else args 1339 kwds = {} if kwds is None else kwds 1340 if not isinstance(args, list): 1341 args = [args] 1342 for i, arg in enumerate(args): 1343 if not isinstance(arg, ExpectElement) or arg.parent() is not self: 1344 args[i] = self(arg) 1345 for key, value in kwds.iteritems(): 1346 if not isinstance(value, ExpectElement) or value.parent() is not self: 1347 kwds[key] = self(value) 1348 1349 return args, kwds 1350 1351 def _check_valid_function_name(self, function): 1352 """ 1353 Checks to see if function is a valid function name in this 1354 interface. If it is not, an exception is raised. Otherwise, nothing 1355 is done. 1356 1357 EXAMPLES:: 1358 1359 sage: gap._check_valid_function_name('SymmetricGroup') 1360 sage: gap._check_valid_function_name('') 1361 Traceback (most recent call last): 1362 ... 1363 ValueError: function name must be nonempty 1364 sage: gap._check_valid_function_name('__foo') 1365 Traceback (most recent call last): 1366 ... 1367 AttributeError 1368 """ 1369 if function == '': 1370 raise ValueError, "function name must be nonempty" 1371 if function[:2] == "__": 1372 raise AttributeError 1373 1374 def function_call(self, function, args=None, kwds=None): 1375 """ 1376 EXAMPLES:: 1377 1378 sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) 1379 [0.5,5.5511151231257...e-15,21,0] 1380 sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) 1381 [0.5,5.5511151231257...e-15,21,0] 1382 """ 1383 args, kwds = self._convert_args_kwds(args, kwds) 1384 self._check_valid_function_name(function) 1385 s = self._function_call_string(function, 1386 [s.name() for s in args], 1387 ['%s=%s'%(key,value.name()) for key, value in kwds.items()]) 1388 return self.new(s) 1389 1390 def _function_call_string(self, function, args, kwds): 1391 """ 1392 Returns the string used to make function calls. 1393 1394 EXAMPLES:: 1395 1396 sage: maxima._function_call_string('diff', ['f(x)', 'x'], []) 1397 'diff(f(x),x)' 1398 """ 1399 return "%s(%s)"%(function, ",".join(list(args) + list(kwds))) 1400 1401 def call(self, function_name, *args, **kwds): 1402 return self.function_call(function_name, args, kwds) 1403 1404 def _contains(self, v1, v2): 1405 raise NotImplementedError 1406 1407 def __getattr__(self, attrname): 1408 """ 1409 TESTS:: 1410 1411 sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_') 1412 <built-in method _coerce_map_from_ of Singular object at ...> 1413 """ 1414 try: 1415 return ParentWithBase.__getattribute__(self, attrname) 1416 except AttributeError: 1417 if attrname[:1] == "_": 1418 raise AttributeError 1419 return self._function_class()(self, attrname) 1420 1421 def __cmp__(self, other): 1422 """ 1423 Compare two pseudo-tty interfaces. Two interfaces compare 1424 equal if and only if they are identical objects (this is a 1425 critical constraint so that caching of representations of 1426 objects in interfaces works correctly). Otherwise they are 1427 never equal. 1428 1429 EXAMPLES:: 1430 1431 sage: Maxima() == maxima 1432 False 1433 sage: maxima == maxima 1434 True 1435 """ 1436 if self is other: 1437 return 0 1438 c = cmp(type(self), type(other)) 1439 if c: 1440 return c 1441 return -1 # sucky, but I can't think of anything better; it is important that different interfaces to the same system still compare differently; unfortunately there is nothing to distinguish them. 1442 1443 def console(self): 1444 raise NotImplementedError 1445 1446 def help(self, s): 1447 return AsciiArtString('No help on %s available'%s) 1448 1449 1450 class ExpectFunction(SageObject): 1069 class ExpectFunction(InterfaceFunction): 1451 1070 """ 1452 1071 Expect function. 1453 1072 """ 1454 def __init__(self, parent, name): 1455 self._parent = parent 1456 self._name = name 1457 1458 def __repr__(self): 1459 return "%s"%self._name 1460 1461 def __call__(self, *args, **kwds): 1462 return self._parent.function_call(self._name, list(args), kwds) 1463 1464 def _sage_doc_(self): 1465 """ 1466 EXAMPLES:: 1467 1468 sage: gp.gcd._sage_doc_() 1469 'gcd(x,{y}): greatest common divisor of x and y.' 1470 """ 1471 M = self._parent 1472 return M.help(self._name) 1473 1073 pass 1474 1074 1475 1075 1476 1477 class FunctionElement(SageObject): 1076 class FunctionElement(InterfaceFunctionElement): 1478 1077 """ 1479 1078 Expect function element. 1480 1079 """ 1481 def __init__(self, obj, name): 1482 self._obj = obj 1483 self._name = name 1484 1485 def __repr__(self): 1486 return "%s"%self._name 1487 1488 def __call__(self, *args, **kwds): 1489 return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds) 1490 1491 def help(self): 1492 print self._sage_doc_() 1493 1494 def _sage_doc_(self): 1495 """ 1496 EXAMPLES:: 1497 1498 sage: gp(2).gcd._sage_doc_() 1499 'gcd(x,{y}): greatest common divisor of x and y.' 1500 """ 1501 M = self._obj.parent() 1502 return M.help(self._name) 1080 pass 1503 1081 1504 1082 1505 1083 def is_ExpectElement(x): 1506 1084 return isinstance(x, ExpectElement) 1507 1085 1508 1509 1510 class ExpectElement(RingElement): 1086 class ExpectElement(InterfaceElement): 1511 1087 """ 1512 1088 Expect element. 1513 1089 """ … … 1532 1108 raise TypeError, x 1533 1109 self._session_number = parent._session_number 1534 1110 1535 def _latex_(self):1536 # return "\\begin{verbatim}%s\\end{verbatim}"%self1537 string = str(self)1538 if not '|' in string:1539 delim = '|'1540 elif not '#' in string:1541 delim = '#'1542 elif not '@' in string:1543 delim = '@'1544 elif not '~' in string:1545 delim = '~'1546 return "\\verb%s%s%s"%(delim, string, delim)1547 1548 def __iter__(self):1549 for i in range(1, len(self)+1):1550 yield self[i]1551 1552 def __len__(self):1553 """1554 Call self.sage() and return the length of that sage object.1555 1556 This approach is inefficient - each interface should override1557 this method with one that calls the external program's length1558 function.1559 1560 EXAMPLES::1561 1562 sage: len(gp([1,2,3]))1563 31564 1565 AUTHORS:1566 1567 - Felix Lawrence (2009-08-21)1568 """1569 return len(self.sage())1570 1571 def __reduce__(self):1572 return reduce_load, (self.parent(), self._reduce())1573 1574 def _reduce(self):1575 return repr(self)1576 1577 def __call__(self, *args):1578 self._check_valid()1579 P = self.parent()1580 return getattr(P, self.name())(*args)1581 1582 def __contains__(self, x):1583 P = self._check_valid()1584 if not isinstance(x, ExpectElement) or x.parent() is not self.parent():1585 x = P.new(x)1586 return P._contains(x.name(), self.name())1587 1588 1589 def _sage_doc_(self):1590 """1591 EXAMPLES::1592 1593 sage: gp(2)._sage_doc_()1594 '2'1595 """1596 return str(self)1597 1598 1111 def __hash__(self): 1599 1112 """ 1600 1113 Returns the hash of self. This is a default implementation of hash … … 1602 1115 """ 1603 1116 return hash('%s%s'%(self, self._session_number)) 1604 1117 1605 def __cmp__(self, other):1606 """1607 Comparison is done by GAP.1608 1609 GAP may raise an error when comparing objects. We catch these1610 errors. Moreover, GAP does not recognise certain objects as1611 equal even if there definitions are identical.1612 1613 TESTS:1614 1615 Here are examples in which GAP succeeds with a comparison::1616 1617 sage: gap('SymmetricGroup(8)')==gap('SymmetricGroup(8)')1618 True1619 sage: gap('SymmetricGroup(8)')>gap('AlternatingGroup(8)')1620 False1621 sage: gap('SymmetricGroup(8)')<gap('AlternatingGroup(8)')1622 True1623 1624 Here, GAP fails to compare, and so ``False`` is returned.1625 In previous Sage versions, this example actually resulted1626 in an error; compare #5962.1627 ::1628 1629 sage: gap('DihedralGroup(8)')==gap('DihedralGroup(8)')1630 False1631 1632 """1633 P = self.parent()1634 try:1635 if P.eval("%s %s %s"%(self.name(), P._equality_symbol(),1636 other.name())) == P._true_symbol():1637 return 01638 except RuntimeError:1639 pass1640 try:1641 if P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol():1642 return -11643 except RuntimeError:1644 pass1645 try:1646 if P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol():1647 return 11648 except:1649 pass1650 1651 # everything is supposed to be comparable in Python, so we define1652 # the comparison thus when no comparison is available in interfaced system.1653 if (hash(self) < hash(other)):1654 return -11655 else:1656 return 11657 1658 def _matrix_(self, R):1659 raise NotImplementedError1660 1661 def _vector_(self, R):1662 raise NotImplementedError1663 1118 1664 1119 def _check_valid(self): 1665 1120 """ … … 1692 1147 #print msg 1693 1148 pass 1694 1149 1695 def _sage_repr(self): 1696 """ 1697 Return a sage-friendly string representation of the object. 1698 1699 Some programs use different notation to Sage, e.g. Mathematica 1700 writes lists with {} instead of []. This method calls repr(self) 1701 then converts the foreign notation into Sage's notation. 1702 1703 OUTPUT: 1704 1705 A string representation of the object that is ready for 1706 sage_eval(). 1707 1708 EXAMPLES:: 1709 1710 sage: repr(mathematica([1,2,3])) # optional - mathematica 1711 '{1, 2, 3}' 1712 sage: mathematica([1,2,3])._sage_repr() # optional - mathematica 1713 '[1, 2, 3]' 1714 1715 :: 1716 1717 sage: gp(10.^80)._sage_repr() 1718 '1.0000000000000000000000000000000000000e80' # 64-bit 1719 '1.000000000000000000000000000e80' # 32-bit 1720 sage: mathematica('10.^80')._sage_repr() # optional - mathematica 1721 '1.e80' 1722 1723 AUTHORS: 1724 1725 - Felix Lawrence (2009-08-21) 1726 """ 1727 #TO DO: this could use file transfers when self.is_remote() 1728 1729 string = repr(self).replace('\n',' ').replace('\r', '') 1730 # Translate the external program's function notation to Sage's 1731 lfd = self.parent()._left_func_delim() 1732 if '(' != lfd: string = string.replace(lfd, '(') 1733 rfd = self.parent()._right_func_delim() 1734 if ')' != rfd: string = string.replace(rfd, ')') 1735 # Translate the external program's list formatting to Sage's 1736 lld = self.parent()._left_list_delim() 1737 if '[' != lld: string = string.replace(lld, '[') 1738 rld = self.parent()._right_list_delim() 1739 if ']' != rld: string = string.replace(rld, ']') 1740 # Translate the external program's exponent formatting 1741 expl = self.parent()._exponent_symbol() 1742 if 'e' != expl: string = string.replace(expl, 'e') 1743 return string 1744 1745 def _sage_(self): 1746 """ 1747 Attempt to return a Sage version of this object. 1748 This is a generic routine that just tries to evaluate 1749 the repr(self). 1750 1751 EXAMPLES:: 1752 1753 sage: gp(1/2)._sage_() 1754 1/2 1755 sage: _.parent() 1756 Rational Field 1757 1758 AUTHORS: 1759 1760 - William Stein 1761 1762 - Felix Lawrence (2009-08-21) 1763 """ 1764 string = self._sage_repr() 1765 try: 1766 return sage.misc.sage_eval.sage_eval(string) 1767 except: 1768 raise NotImplementedError, "Unable to parse output: %s" % string 1769 1770 1771 def sage(self): 1772 """ 1773 Attempt to return a Sage version of this object. 1774 1775 EXAMPLES:: 1776 1777 sage: gp(1/2).sage() 1778 1/2 1779 sage: _.parent() 1780 Rational Field 1781 """ 1782 return self._sage_() 1783 1784 def __repr__(self): 1785 self._check_valid() 1786 try: 1787 if self._get_using_file: 1788 s = self.parent().get_using_file(self._name) 1789 except AttributeError: 1790 s = self.parent().get(self._name) 1791 if s.__contains__(self._name): 1792 if hasattr(self, '__custom_name'): 1793 s = s.replace(self._name, self.__dict__['__custom_name']) 1794 return s 1795 1796 def __getattr__(self, attrname): 1797 P = self._check_valid() 1798 if attrname[:1] == "_": 1799 raise AttributeError 1800 return P._function_element_class()(self, attrname) 1801 1802 def get_using_file(self): 1803 """ 1804 Return this element's string representation using a file. Use this 1805 if self has a huge string representation. It'll be way faster. 1806 1807 EXAMPLES:: 1808 1809 sage: a = maxima(str(2^1000)) 1810 sage: a.get_using_file() 1811 '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376' 1812 """ 1813 try: 1814 self._check_valid() 1815 except ValueError: 1816 return '(invalid object -- defined in terms of closed session)' 1817 return self.parent().get_using_file(self._name) 1818 1819 def hasattr(self, attrname): 1820 """ 1821 Returns whether the given attribute is already defined by this 1822 object, and in particular is not dynamically generated. 1823 1824 EXAMPLES:: 1825 1826 sage: m = maxima('2') 1827 sage: m.hasattr('integral') 1828 True 1829 sage: m.hasattr('gcd') 1830 False 1831 """ 1832 return not isinstance(getattr(self, attrname), FunctionElement) 1833 1834 def attribute(self, attrname): 1835 """ 1836 If this wraps the object x in the system, this returns the object 1837 x.attrname. This is useful for some systems that have object 1838 oriented attribute access notation. 1839 1840 EXAMPLES:: 1841 1842 sage: g = gap('SO(1,4,7)') 1843 sage: k = g.InvariantQuadraticForm() 1844 sage: k.attribute('matrix') 1845 [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ], 1846 [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ] 1847 1848 :: 1849 1850 sage: e = gp('ellinit([0,-1,1,-10,-20])') 1851 sage: e.attribute('j') 1852 -122023936/161051 1853 """ 1854 P = self._check_valid() 1855 return P('%s.%s'%(self.name(), attrname)) 1856 1857 def __getitem__(self, n): 1858 P = self._check_valid() 1859 if not isinstance(n, tuple): 1860 return P.new('%s[%s]'%(self._name, n)) 1861 else: 1862 return P.new('%s[%s]'%(self._name, str(n)[1:-1])) 1863 1864 def __int__(self): 1865 """ 1866 EXAMPLES:: 1867 1868 sage: int(maxima('1')) 1869 1 1870 sage: type(_) 1871 <type 'int'> 1872 """ 1873 return int(repr(self)) 1874 1875 def bool(self): 1876 P = self.parent() 1877 t = P._true_symbol() 1878 cmd = '%s %s %s'%(self._name, P._equality_symbol(), t) 1879 return P.eval(cmd) == t 1880 1881 def __nonzero__(self): 1882 """ 1883 EXAMPLES:: 1884 1885 sage: bool(maxima(0)) 1886 False 1887 sage: bool(maxima(1)) 1888 True 1889 """ 1890 return self.bool() 1891 1892 def __long__(self): 1893 """ 1894 EXAMPLES:: 1895 1896 sage: m = maxima('1') 1897 sage: long(m) 1898 1L 1899 """ 1900 return long(repr(self)) 1901 1902 def __float__(self): 1903 """ 1904 EXAMPLES:: 1905 1906 sage: m = maxima('1/2') 1907 sage: m.__float__() 1908 0.5 1909 sage: float(m) 1910 0.5 1911 """ 1912 return float(repr(self)) 1913 1914 def _integer_(self, ZZ=None): 1915 """ 1916 EXAMPLES:: 1917 1918 sage: m = maxima('1') 1919 sage: m._integer_() 1920 1 1921 sage: _.parent() 1922 Integer Ring 1923 sage: QQ(m) 1924 1 1925 """ 1926 import sage.rings.all 1927 return sage.rings.all.Integer(repr(self)) 1928 1929 def _rational_(self): 1930 """ 1931 EXAMPLES:: 1932 1933 sage: m = maxima('1/2') 1934 sage: m._rational_() 1935 1/2 1936 sage: _.parent() 1937 Rational Field 1938 sage: QQ(m) 1939 1/2 1940 """ 1941 import sage.rings.all 1942 return sage.rings.all.Rational(repr(self)) 1943 1944 def name(self, new_name=None): 1945 """ 1946 Returns the name of self. If new_name is passed in, then this 1947 function returns a new object identical to self whose name is 1948 new_name. 1949 1950 Note that this can overwrite existing variables in the system. 1951 1952 EXAMPLES:: 1953 1954 sage: x = r([1,2,3]); x 1955 [1] 1 2 3 1956 sage: x.name() 1957 'sage3' 1958 sage: x = r([1,2,3]).name('x'); x 1959 [1] 1 2 3 1960 sage: x.name() 1961 'x' 1962 1963 :: 1964 1965 sage: s5 = gap.SymmetricGroup(5).name('s5') 1966 sage: s5 1967 SymmetricGroup( [ 1 .. 5 ] ) 1968 sage: s5.name() 1969 's5' 1970 """ 1971 if new_name is not None: 1972 if not isinstance(new_name, str): 1973 raise TypeError, "new_name must be a string" 1974 p = self.parent() 1975 p.set(new_name, self._name) 1976 return p._object_class()(p, new_name, is_name=True) 1977 1978 return self._name 1979 1980 def gen(self, n): 1981 P = self._check_valid() 1982 return P.new('%s.%s'%(self._name, int(n))) 1983 1984 def _operation(self, operation, right): 1985 P = self._check_valid() 1986 try: 1987 return P.new('%s %s %s'%(self._name, operation, right._name)) 1988 except Exception, msg: 1989 raise TypeError, msg 1990 1991 def _add_(self, right): 1992 """ 1993 EXAMPLES:: 1994 1995 sage: f = maxima.cos(x) 1996 sage: g = maxima.sin(x) 1997 sage: f + g 1998 sin(x)+cos(x) 1999 sage: f + 2 2000 cos(x)+2 2001 sage: 2 + f 2002 cos(x)+2 2003 """ 2004 return self._operation("+", right) 2005 2006 def _sub_(self, right): 2007 """ 2008 EXAMPLES:: 2009 2010 sage: f = maxima.cos(x) 2011 sage: g = maxima.sin(x) 2012 sage: f - g 2013 cos(x)-sin(x) 2014 sage: f - 2 2015 cos(x)-2 2016 sage: 2 - f 2017 2-cos(x) 2018 """ 2019 return self._operation('-', right) 2020 2021 def _mul_(self, right): 2022 """ 2023 EXAMPLES:: 2024 2025 sage: f = maxima.cos(x) 2026 sage: g = maxima.sin(x) 2027 sage: f*g 2028 cos(x)*sin(x) 2029 sage: 2*f 2030 2*cos(x) 2031 """ 2032 return self._operation('*', right) 2033 2034 def _div_(self, right): 2035 """ 2036 EXAMPLES:: 2037 2038 sage: f = maxima.cos(x) 2039 sage: g = maxima.sin(x) 2040 sage: f/g 2041 cos(x)/sin(x) 2042 sage: f/2 2043 cos(x)/2 2044 """ 2045 return self._operation("/", right) 2046 2047 def __pow__(self, n): 2048 """ 2049 EXAMPLES:: 2050 2051 sage: a = maxima('2') 2052 sage: a^(3/4) 2053 2^(3/4) 2054 """ 2055 P = self._check_valid() 2056 if not hasattr(n, 'parent') or P is not n.parent(): 2057 n = P(n) 2058 return self._operation("^", n) 1150 # def _sage_repr(self): 1151 #TO DO: this could use file transfers when self.is_remote() 2059 1152 2060 1153 2061 1154 class StdOutContext: … … 2082 1175 sage: with StdOutContext(gp): 2083 1176 ... gp('1+1') 2084 1177 ... 2085 sage [...1178 sage=... 2086 1179 """ 2087 1180 self.interface = interface 2088 1181 self.silent = silent … … 2124 1217 self.stdout.write("\n") 2125 1218 self.interface._expect.logfile = self._logfile_backup 2126 1219 2127 def reduce_load(parent, x):2128 return parent(x)2129 2130 1220 import os 2131 1221 def console(cmd): 2132 1222 os.system(cmd) -
sage/interfaces/gap.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/gap.py
a b 599 599 600 600 sage: s = gap.function_call('Display', [gap.SymmetricGroup(5).CharacterTable()]) 601 601 sage: type(s) 602 <class 'sage.interfaces. expect.AsciiArtString'>602 <class 'sage.interfaces.interface.AsciiArtString'> 603 603 sage: s.startswith('CT') 604 604 True 605 605 """ -
new file sage/interfaces/interface.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/interface.py
- + 1 r""" 2 Common Interface Functionality 3 4 See the examples in the other sections for how to use specific 5 interfaces. The interface classes all derive from the generic 6 interface that is described in this section. 7 8 AUTHORS: 9 10 - William Stein (2005): initial version 11 12 - William Stein (2006-03-01): got rid of infinite loop on startup if 13 client system missing 14 15 - Felix Lawrence (2009-08-21): edited ._sage_() to support lists and float exponents in foreign notation. 16 17 - Simon King (2010-09-25): Expect._local_tmpfile() depends on 18 Expect.pid() and is cached; Expect.quit() clears that cache, 19 which is important for forking. 20 """ 21 22 #***************************************************************************** 23 # Copyright (C) 2005 William Stein <wstein@gmail.com> 24 # 25 # Distributed under the terms of the GNU General Public License (GPL) 26 # 27 # This code is distributed in the hope that it will be useful, 28 # but WITHOUT ANY WARRANTY; without even the implied warranty of 29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 # General Public License for more details. 31 # 32 # The full text of the GPL is available at: 33 # 34 # http://www.gnu.org/licenses/ 35 #***************************************************************************** 36 37 import operator 38 39 from sage.structure.sage_object import SageObject 40 from sage.structure.parent_base import ParentWithBase 41 from sage.structure.element import RingElement 42 43 import sage.misc.sage_eval 44 45 from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE, LOCAL_IDENTIFIER 46 47 class AsciiArtString(str): 48 def __repr__(self): 49 return str(self) 50 51 class PropTypeError(Exception): 52 pass 53 54 55 class Interface(ParentWithBase): 56 """ 57 Interface interface object. 58 """ 59 def __init__(self, name): 60 self.__name = name 61 self.__coerce_name = '_' + name.lower() + '_' 62 self.__seq = -1 63 self._available_vars = [] 64 ParentWithBase.__init__(self, self) 65 66 def _repr_(self): 67 return self.__name.capitalize() 68 69 def name(self, new_name=None): 70 return self.__name 71 72 def interact(self): 73 r""" 74 This allows you to interactively interact with the child 75 interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and 76 return to Sage. 77 78 .. note:: 79 80 This is completely different than the console() member 81 function. The console function opens a new copy of the 82 child interpreter, whereas the interact function gives you 83 interactive access to the interpreter that is being used by 84 Sage. Use sage(xxx) or interpretername(xxx) to pull objects 85 in from sage to the interpreter. 86 """ 87 import sage.misc.preparser_ipython 88 sage.misc.preparser_ipython.switch_interface_general(self) 89 90 def _pre_interact(self): 91 pass 92 93 def _post_interact(self): 94 pass 95 96 def __del__(self): 97 pass 98 99 def cputime(self): 100 """ 101 CPU time since this process started running. 102 """ 103 raise NotImplementedError 104 105 def read(self, filename): 106 r""" 107 EXAMPLES:: 108 109 sage: filename = tmp_filename() 110 sage: f = open(filename, 'w') 111 sage: f.write('x = 2\n') 112 sage: f.close() 113 sage: octave.read(filename) #optional -- requires Octave 114 sage: octave.get('x') #optional 115 ' 2' 116 sage: import os 117 sage: os.unlink(filename) 118 """ 119 self.eval(self._read_in_file_command(filename)) 120 121 def _read_in_file_command(self, filename): 122 raise NotImplementedError 123 124 def eval(self, code, locals=None, **kwds): 125 """ 126 INPUT: 127 128 129 - ``code`` - text to evaluate 130 131 - ``locals`` - None (ignored); this is used for compatibility with the 132 Sage notebook's generic system interface. 133 134 - ``**kwds`` - All other arguments are passed onto 135 the _eval_line method. An often useful example is 136 reformat=False. 137 """ 138 139 if not isinstance(code, basestring): 140 raise TypeError, 'input code must be a string.' 141 142 #Remove extra whitespace 143 code = code.strip() 144 145 try: 146 pass 147 except KeyboardInterrupt: 148 # DO NOT CATCH KeyboardInterrupt, as it is being caught 149 # by _eval_line 150 # In particular, do NOT call self._keyboard_interrupt() 151 raise 152 except TypeError, s: 153 raise TypeError, 'error evaluating "%s":\n%s'%(code,s) 154 155 _eval_line = eval 156 157 def execute(self, *args, **kwds): 158 return self.eval(*args, **kwds) 159 160 def __call__(self, x, name=None): 161 162 r""" 163 Create a new object in self from x. 164 165 The object X returned can be used like any Sage object, and 166 wraps an object in self. The standard arithmetic operators 167 work. Moreover if foo is a function then 168 X.foo(y,z,...) 169 calls foo(X, y, z, ...) and returns the corresponding object. 170 171 EXAMPLES:: 172 173 sage: gp(2) 174 2 175 sage: gp('2') 176 2 177 sage: a = gp(2); gp(a) is a 178 True 179 180 """ 181 cls = self._object_class() 182 183 #Handle the case when x is an object 184 #in some interface. 185 if isinstance(x, InterfaceElement): 186 if x.parent() is self: 187 return x 188 189 #We convert x into an object in this 190 #interface by first going through Sage. 191 try: 192 return self(x._sage_()) 193 except (NotImplementedError, TypeError): 194 pass 195 196 if isinstance(x, basestring): 197 return cls(self, x, name=name) 198 try: 199 return self._coerce_from_special_method(x) 200 except TypeError: 201 raise 202 except AttributeError, msg: 203 pass 204 try: 205 return self._coerce_impl(x, use_special=False) 206 except TypeError, msg: 207 try: 208 return cls(self, str(x), name=name) 209 except TypeError, msg2: 210 raise TypeError, msg 211 212 def _coerce_from_special_method(self, x): 213 """ 214 Tries to coerce to self by calling a special underscore method. 215 216 If no such method is defined, raises an AttributeError instead of a 217 TypeError. 218 """ 219 s = '_%s_'%self.name() 220 if s == '_maxima_lib_': 221 s = '_maxima_' 222 if s == '_pari_': 223 s = '_gp_' 224 try: 225 return (x.__getattribute__(s))(self) 226 except AttributeError: 227 return self(x._interface_init_()) 228 229 def _coerce_impl(self, x, use_special=True): 230 if isinstance(x, (int, long)): 231 import sage.rings.all 232 return self(sage.rings.all.Integer(x)) 233 elif isinstance(x, float): 234 import sage.rings.all 235 return self(sage.rings.all.RDF(x)) 236 if use_special: 237 try: 238 return self._coerce_from_special_method(x) 239 except AttributeError, msg: 240 pass 241 242 if isinstance(x, (list, tuple)): 243 A = [] 244 z = [] 245 cls = self._object_class() 246 for v in x: 247 if isinstance(v, cls): 248 A.append(v.name()) 249 z.append(v) 250 else: 251 w = self(v) 252 A.append(w.name()) 253 z.append(w) 254 X = ','.join(A) 255 r = self.new('%s%s%s'%(self._left_list_delim(), X, self._right_list_delim())) 256 r.__sage_list = z # do this to avoid having the entries of the list be garbage collected 257 return r 258 259 raise TypeError, "unable to coerce element into %s"%self.name() 260 261 def new(self, code): 262 return self(code) 263 264 ################################################################### 265 # these should all be appropriately overloaded by the derived class 266 ################################################################### 267 268 def _left_list_delim(self): 269 return "[" 270 271 def _right_list_delim(self): 272 return "]" 273 274 def _left_func_delim(self): 275 return "(" 276 277 def _right_func_delim(self): 278 return ")" 279 280 def _assign_symbol(self): 281 return "=" 282 283 def _equality_symbol(self): 284 raise NotImplementedError 285 286 # For efficiency purposes, you should definitely override these 287 # in your derived class. 288 def _true_symbol(self): 289 try: 290 return self.__true_symbol 291 except AttributeError: 292 self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol()) 293 294 def _false_symbol(self): 295 try: 296 return self.__false_symbol 297 except AttributeError: 298 self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol()) 299 300 def _lessthan_symbol(self): 301 return '<' 302 303 def _greaterthan_symbol(self): 304 return '>' 305 306 def _inequality_symbol(self): 307 return '!=' 308 309 def _relation_symbols(self): 310 """ 311 Returns a dictionary with operators as the keys and their 312 string representation as the values. 313 314 EXAMPLES:: 315 316 sage: import operator 317 sage: symbols = mathematica._relation_symbols() 318 sage: symbols[operator.eq] 319 '==' 320 """ 321 return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()), 322 (operator.lt, self._lessthan_symbol()), (operator.le, "<="), 323 (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")]) 324 325 def _exponent_symbol(self): 326 """ 327 Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e6 328 329 EXAMPLES:: 330 331 sage: from sage.interfaces.expect import Expect 332 sage: Expect('nonexistent_interface', 'fake')._exponent_symbol() 333 'e' 334 """ 335 return 'e' 336 337 ############################################################ 338 # Functions for working with variables. 339 # The first three must be overloaded by derived classes, 340 # and the definition depends a lot on the class. But 341 # the functionality one gets from this is very nice. 342 ############################################################ 343 344 def set(self, var, value): 345 """ 346 Set the variable var to the given value. 347 """ 348 cmd = '%s%s%s;'%(var,self._assign_symbol(), value) 349 self.eval(cmd) 350 351 def get(self, var): 352 """ 353 Get the value of the variable var. 354 """ 355 return self.eval(var) 356 357 def get_using_file(self, var): 358 r""" 359 Return the string representation of the variable var in self, 360 possibly using a file. Use this if var has a huge string 361 representation, since it may be way faster. 362 363 .. warning:: 364 365 In fact unless a special derived class implements this, it 366 will *not* be any faster. This is the case for this class 367 if you're reading it through introspection and seeing this. 368 """ 369 return self.get(var) 370 371 def clear(self, var): 372 """ 373 Clear the variable named var. 374 """ 375 self._available_vars.append(var) 376 377 def _next_var_name(self): 378 if len(self._available_vars) != 0: 379 v = self._available_vars[0] 380 del self._available_vars[0] 381 return v 382 self.__seq += 1 383 return "sage%s"%self.__seq 384 385 def _create(self, value, name=None): 386 name = self._next_var_name() if name is None else name 387 self.set(name, value) 388 return name 389 390 def _object_class(self): 391 """ 392 EXAMPLES:: 393 394 sage: from sage.interfaces.expect import Expect 395 sage: Expect._object_class(maxima) 396 <class 'sage.interfaces.expect.ExpectElement'> 397 """ 398 return InterfaceElement 399 400 def _function_class(self): 401 """ 402 EXAMPLES:: 403 404 sage: from sage.interfaces.interface import Interface 405 sage: Interface._function_class(maxima) 406 <class 'sage.interfaces.interface.InterfaceFunction'> 407 """ 408 return InterfaceFunction 409 410 def _function_element_class(self): 411 """ 412 EXAMPLES:: 413 414 sage: from sage.interfaces.interface import Interface 415 sage: Interface._function_element_class(maxima) 416 <class 'sage.interfaces.interface.InterfaceFunctionElement'> 417 """ 418 return InterfaceFunctionElement 419 420 def _convert_args_kwds(self, args=None, kwds=None): 421 """ 422 Converts all of the args and kwds to be elements of this 423 interface. 424 425 EXAMPLES:: 426 427 sage: args = [5] 428 sage: kwds = {'x': 6} 429 sage: args, kwds = gap._convert_args_kwds(args, kwds) 430 sage: args 431 [5] 432 sage: map(type, args) 433 [<class 'sage.interfaces.gap.GapElement'>] 434 sage: type(kwds['x']) 435 <class 'sage.interfaces.gap.GapElement'> 436 """ 437 args = [] if args is None else args 438 kwds = {} if kwds is None else kwds 439 if not isinstance(args, list): 440 args = [args] 441 for i, arg in enumerate(args): 442 if not isinstance(arg, InterfaceElement) or arg.parent() is not self: 443 args[i] = self(arg) 444 for key, value in kwds.iteritems(): 445 if not isinstance(value, InterfaceElement) or value.parent() is not self: 446 kwds[key] = self(value) 447 448 return args, kwds 449 450 def _check_valid_function_name(self, function): 451 """ 452 Checks to see if function is a valid function name in this 453 interface. If it is not, an exception is raised. Otherwise, nothing 454 is done. 455 456 EXAMPLES:: 457 458 sage: gap._check_valid_function_name('SymmetricGroup') 459 sage: gap._check_valid_function_name('') 460 Traceback (most recent call last): 461 ... 462 ValueError: function name must be nonempty 463 sage: gap._check_valid_function_name('__foo') 464 Traceback (most recent call last): 465 ... 466 AttributeError 467 """ 468 if function == '': 469 raise ValueError, "function name must be nonempty" 470 if function[:2] == "__": 471 raise AttributeError 472 473 def function_call(self, function, args=None, kwds=None): 474 """ 475 EXAMPLES:: 476 477 sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) 478 [0.5,5.5511151231257...e-15,21,0] 479 sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) 480 [0.5,5.5511151231257...e-15,21,0] 481 """ 482 args, kwds = self._convert_args_kwds(args, kwds) 483 self._check_valid_function_name(function) 484 s = self._function_call_string(function, 485 [s.name() for s in args], 486 ['%s=%s'%(key,value.name()) for key, value in kwds.items()]) 487 return self.new(s) 488 489 def _function_call_string(self, function, args, kwds): 490 """ 491 Returns the string used to make function calls. 492 493 EXAMPLES:: 494 495 sage: maxima._function_call_string('diff', ['f(x)', 'x'], []) 496 'diff(f(x),x)' 497 """ 498 return "%s(%s)"%(function, ",".join(list(args) + list(kwds))) 499 500 def call(self, function_name, *args, **kwds): 501 return self.function_call(function_name, args, kwds) 502 503 def _contains(self, v1, v2): 504 raise NotImplementedError 505 506 def __getattr__(self, attrname): 507 """ 508 TESTS:: 509 510 sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_') 511 <built-in method _coerce_map_from_ of Singular object at ...> 512 """ 513 try: 514 return ParentWithBase.__getattribute__(self, attrname) 515 except AttributeError: 516 if attrname[:1] == "_": 517 raise AttributeError 518 return self._function_class()(self, attrname) 519 520 def __cmp__(self, other): 521 """ 522 Compare two pseudo-tty interfaces. Two interfaces compare 523 equal if and only if they are identical objects (this is a 524 critical constraint so that caching of representations of 525 objects in interfaces works correctly). Otherwise they are 526 never equal. 527 528 EXAMPLES:: 529 530 sage: Maxima() == maxima 531 False 532 sage: maxima == maxima 533 True 534 """ 535 if self is other: 536 return 0 537 c = cmp(type(self), type(other)) 538 if c: 539 return c 540 return -1 # sucky, but I can't think of anything better; it is important that different interfaces to the same system still compare differently; unfortunately there is nothing to distinguish them. 541 542 def console(self): 543 raise NotImplementedError 544 545 def help(self, s): 546 return AsciiArtString('No help on %s available'%s) 547 548 549 class InterfaceFunction(SageObject): 550 """ 551 Interface function. 552 """ 553 def __init__(self, parent, name): 554 self._parent = parent 555 self._name = name 556 557 def __repr__(self): 558 return "%s"%self._name 559 560 def __call__(self, *args, **kwds): 561 return self._parent.function_call(self._name, list(args), kwds) 562 563 def _sage_doc_(self): 564 """ 565 EXAMPLES:: 566 567 sage: gp.gcd._sage_doc_() 568 'gcd(x,{y}): greatest common divisor of x and y.' 569 """ 570 M = self._parent 571 return M.help(self._name) 572 573 574 class InterfaceFunctionElement(SageObject): 575 """ 576 Interface function element. 577 """ 578 def __init__(self, obj, name): 579 self._obj = obj 580 self._name = name 581 582 def __repr__(self): 583 return "%s"%self._name 584 585 def __call__(self, *args, **kwds): 586 return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds) 587 588 def help(self): 589 print self._sage_doc_() 590 591 def _sage_doc_(self): 592 """ 593 EXAMPLES:: 594 595 sage: gp(2).gcd._sage_doc_() 596 'gcd(x,{y}): greatest common divisor of x and y.' 597 """ 598 M = self._obj.parent() 599 return M.help(self._name) 600 601 602 603 def is_InterfaceElement(x): 604 return isinstance(x, InterfaceElement) 605 606 class InterfaceElement(RingElement): 607 """ 608 Interface element. 609 """ 610 def __init__(self, parent, value, is_name=False, name=None): 611 RingElement.__init__(self, parent) 612 self._create = value 613 if parent is None: return # means "invalid element" 614 # idea: Joe Wetherell -- try to find out if the output 615 # is too long and if so get it using file, otherwise 616 # don't. 617 618 if is_name: 619 self._name = value 620 else: 621 try: 622 self._name = parent._create(value, name=name) 623 except (TypeError, KeyboardInterrupt, RuntimeError, ValueError), x: 624 raise TypeError, x 625 626 def _latex_(self): 627 # return "\\begin{verbatim}%s\\end{verbatim}"%self 628 string = str(self) 629 if not '|' in string: 630 delim = '|' 631 elif not '#' in string: 632 delim = '#' 633 elif not '@' in string: 634 delim = '@' 635 elif not '~' in string: 636 delim = '~' 637 return "\\verb%s%s%s"%(delim, string, delim) 638 639 def __iter__(self): 640 for i in range(1, len(self)+1): 641 yield self[i] 642 643 def __len__(self): 644 """ 645 Call self.sage() and return the length of that sage object. 646 647 This approach is inefficient - each interface should override 648 this method with one that calls the external program's length 649 function. 650 651 EXAMPLES:: 652 653 sage: len(gp([1,2,3])) 654 3 655 656 AUTHORS: 657 658 - Felix Lawrence (2009-08-21) 659 """ 660 return len(self.sage()) 661 662 def __reduce__(self): 663 return reduce_load, (self.parent(), self._reduce()) 664 665 def _reduce(self): 666 return repr(self) 667 668 def __call__(self, *args): 669 self._check_valid() 670 P = self.parent() 671 return getattr(P, self.name())(*args) 672 673 def __contains__(self, x): 674 P = self._check_valid() 675 if not isinstance(x, InterfaceElement) or x.parent() is not self.parent(): 676 x = P.new(x) 677 return P._contains(x.name(), self.name()) 678 679 680 def _sage_doc_(self): 681 """ 682 EXAMPLES:: 683 684 sage: gp(2)._sage_doc_() 685 '2' 686 """ 687 return str(self) 688 689 def __hash__(self): 690 """ 691 Returns the hash of self. This is a default implementation of hash 692 which just takes the hash of the string of self. 693 """ 694 return hash('%s'%(self)) 695 696 def __cmp__(self, other): 697 """ 698 Comparison is done by GAP. 699 700 GAP may raise an error when comparing objects. We catch these 701 errors. Moreover, GAP does not recognise certain objects as 702 equal even if there definitions are identical. 703 704 TESTS: 705 706 Here are examples in which GAP succeeds with a comparison:: 707 708 sage: gap('SymmetricGroup(8)')==gap('SymmetricGroup(8)') 709 True 710 sage: gap('SymmetricGroup(8)')>gap('AlternatingGroup(8)') 711 False 712 sage: gap('SymmetricGroup(8)')<gap('AlternatingGroup(8)') 713 True 714 715 Here, GAP fails to compare, and so ``False`` is returned. 716 In previous Sage versions, this example actually resulted 717 in an error; compare #5962. 718 :: 719 720 sage: gap('DihedralGroup(8)')==gap('DihedralGroup(8)') 721 False 722 723 """ 724 P = self.parent() 725 try: 726 if P.eval("%s %s %s"%(self.name(), P._equality_symbol(), 727 other.name())) == P._true_symbol(): 728 return 0 729 except RuntimeError: 730 pass 731 try: 732 if P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): 733 return -1 734 except RuntimeError: 735 pass 736 try: 737 if P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): 738 return 1 739 except: 740 pass 741 742 # everything is supposed to be comparable in Python, so we define 743 # the comparison thus when no comparison is available in interfaced system. 744 if (hash(self) < hash(other)): 745 return -1 746 else: 747 return 1 748 749 def _matrix_(self, R): 750 raise NotImplementedError 751 752 def _vector_(self, R): 753 raise NotImplementedError 754 755 def _check_valid(self): 756 """ 757 Check that this object is valid, i.e., the session in which this 758 object is defined is still running. This is relevant for 759 interpreters that can't be interrupted via ctrl-C, hence get 760 restarted. 761 """ 762 try: 763 P = self.parent() 764 if P is None: 765 raise ValueError, "The %s session in which this object was defined is no longer running."%P.name() 766 except AttributeError: 767 raise ValueError, "The session in which this object was defined is no longer running." 768 return P 769 770 def __del__(self): 771 try: 772 self._check_valid() 773 except ValueError: 774 return 775 if hasattr(self,'_name'): 776 P = self.parent() 777 if not (P is None): 778 P.clear(self._name) 779 780 def _sage_repr(self): 781 """ 782 Return a sage-friendly string representation of the object. 783 784 Some programs use different notation to Sage, e.g. Mathematica 785 writes lists with {} instead of []. This method calls repr(self) 786 then converts the foreign notation into Sage's notation. 787 788 OUTPUT: 789 790 A string representation of the object that is ready for 791 sage_eval(). 792 793 EXAMPLES:: 794 795 sage: repr(mathematica([1,2,3])) # optional - mathematica 796 '{1, 2, 3}' 797 sage: mathematica([1,2,3])._sage_repr() # optional - mathematica 798 '[1, 2, 3]' 799 800 :: 801 802 sage: gp(10.^80)._sage_repr() 803 '1.0000000000000000000000000000000000000e80' # 64-bit 804 '1.000000000000000000000000000e80' # 32-bit 805 sage: mathematica('10.^80')._sage_repr() # optional - mathematica 806 '1.e80' 807 808 AUTHORS: 809 810 - Felix Lawrence (2009-08-21) 811 """ 812 #TO DO: this could use file transfers when self.is_remote() 813 814 string = repr(self).replace('\n',' ').replace('\r', '') 815 # Translate the external program's function notation to Sage's 816 lfd = self.parent()._left_func_delim() 817 if '(' != lfd: string = string.replace(lfd, '(') 818 rfd = self.parent()._right_func_delim() 819 if ')' != rfd: string = string.replace(rfd, ')') 820 # Translate the external program's list formatting to Sage's 821 lld = self.parent()._left_list_delim() 822 if '[' != lld: string = string.replace(lld, '[') 823 rld = self.parent()._right_list_delim() 824 if ']' != rld: string = string.replace(rld, ']') 825 # Translate the external program's exponent formatting 826 expl = self.parent()._exponent_symbol() 827 if 'e' != expl: string = string.replace(expl, 'e') 828 return string 829 830 def _sage_(self): 831 """ 832 Attempt to return a Sage version of this object. 833 This is a generic routine that just tries to evaluate 834 the repr(self). 835 836 EXAMPLES:: 837 838 sage: gp(1/2)._sage_() 839 1/2 840 sage: _.parent() 841 Rational Field 842 843 AUTHORS: 844 845 - William Stein 846 847 - Felix Lawrence (2009-08-21) 848 """ 849 string = self._sage_repr() 850 try: 851 return sage.misc.sage_eval.sage_eval(string) 852 except: 853 raise NotImplementedError, "Unable to parse output: %s" % string 854 855 856 def sage(self): 857 """ 858 Attempt to return a Sage version of this object. 859 860 EXAMPLES:: 861 862 sage: gp(1/2).sage() 863 1/2 864 sage: _.parent() 865 Rational Field 866 """ 867 return self._sage_() 868 869 def __repr__(self): 870 self._check_valid() 871 try: 872 if self._get_using_file: 873 s = self.parent().get_using_file(self._name) 874 except AttributeError: 875 s = self.parent().get(self._name) 876 if s.__contains__(self._name): 877 if hasattr(self, '__custom_name'): 878 s = s.replace(self._name, self.__dict__['__custom_name']) 879 return s 880 881 def __getattr__(self, attrname): 882 P = self._check_valid() 883 if attrname[:1] == "_": 884 raise AttributeError 885 return P._function_element_class()(self, attrname) 886 887 def get_using_file(self): 888 """ 889 Return this element's string representation using a file. Use this 890 if self has a huge string representation. It'll be way faster. 891 892 EXAMPLES:: 893 894 sage: a = maxima(str(2^1000)) 895 sage: a.get_using_file() 896 '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376' 897 """ 898 try: 899 self._check_valid() 900 except ValueError: 901 return '(invalid object -- defined in terms of closed session)' 902 return self.parent().get_using_file(self._name) 903 904 def hasattr(self, attrname): 905 """ 906 Returns whether the given attribute is already defined by this 907 object, and in particular is not dynamically generated. 908 909 EXAMPLES:: 910 911 sage: m = maxima('2') 912 sage: m.hasattr('integral') 913 True 914 sage: m.hasattr('gcd') 915 False 916 """ 917 return not isinstance(getattr(self, attrname), InterfaceFunctionElement) 918 919 def attribute(self, attrname): 920 """ 921 If this wraps the object x in the system, this returns the object 922 x.attrname. This is useful for some systems that have object 923 oriented attribute access notation. 924 925 EXAMPLES:: 926 927 sage: g = gap('SO(1,4,7)') 928 sage: k = g.InvariantQuadraticForm() 929 sage: k.attribute('matrix') 930 [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ], 931 [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ] 932 933 :: 934 935 sage: e = gp('ellinit([0,-1,1,-10,-20])') 936 sage: e.attribute('j') 937 -122023936/161051 938 """ 939 P = self._check_valid() 940 return P('%s.%s'%(self.name(), attrname)) 941 942 def __getitem__(self, n): 943 P = self._check_valid() 944 if not isinstance(n, tuple): 945 return P.new('%s[%s]'%(self._name, n)) 946 else: 947 return P.new('%s[%s]'%(self._name, str(n)[1:-1])) 948 949 def __int__(self): 950 """ 951 EXAMPLES:: 952 953 sage: int(maxima('1')) 954 1 955 sage: type(_) 956 <type 'int'> 957 """ 958 return int(repr(self)) 959 960 def bool(self): 961 P = self.parent() 962 t = P._true_symbol() 963 cmd = '%s %s %s'%(self._name, P._equality_symbol(), t) 964 return P.eval(cmd) == t 965 966 def __nonzero__(self): 967 """ 968 EXAMPLES:: 969 970 sage: bool(maxima(0)) 971 False 972 sage: bool(maxima(1)) 973 True 974 """ 975 return self.bool() 976 977 def __long__(self): 978 """ 979 EXAMPLES:: 980 981 sage: m = maxima('1') 982 sage: long(m) 983 1L 984 """ 985 return long(repr(self)) 986 987 def __float__(self): 988 """ 989 EXAMPLES:: 990 991 sage: m = maxima('1/2') 992 sage: m.__float__() 993 0.5 994 sage: float(m) 995 0.5 996 """ 997 return float(repr(self)) 998 999 def _integer_(self, ZZ=None): 1000 """ 1001 EXAMPLES:: 1002 1003 sage: m = maxima('1') 1004 sage: m._integer_() 1005 1 1006 sage: _.parent() 1007 Integer Ring 1008 sage: QQ(m) 1009 1 1010 """ 1011 import sage.rings.all 1012 return sage.rings.all.Integer(repr(self)) 1013 1014 def _rational_(self): 1015 """ 1016 EXAMPLES:: 1017 1018 sage: m = maxima('1/2') 1019 sage: m._rational_() 1020 1/2 1021 sage: _.parent() 1022 Rational Field 1023 sage: QQ(m) 1024 1/2 1025 """ 1026 import sage.rings.all 1027 return sage.rings.all.Rational(repr(self)) 1028 1029 def name(self, new_name=None): 1030 """ 1031 Returns the name of self. If new_name is passed in, then this 1032 function returns a new object identical to self whose name is 1033 new_name. 1034 1035 Note that this can overwrite existing variables in the system. 1036 1037 EXAMPLES:: 1038 1039 sage: x = r([1,2,3]); x 1040 [1] 1 2 3 1041 sage: x.name() 1042 'sage3' 1043 sage: x = r([1,2,3]).name('x'); x 1044 [1] 1 2 3 1045 sage: x.name() 1046 'x' 1047 1048 :: 1049 1050 sage: s5 = gap.SymmetricGroup(5).name('s5') 1051 sage: s5 1052 SymmetricGroup( [ 1 .. 5 ] ) 1053 sage: s5.name() 1054 's5' 1055 """ 1056 if new_name is not None: 1057 if not isinstance(new_name, str): 1058 raise TypeError, "new_name must be a string" 1059 p = self.parent() 1060 p.set(new_name, self._name) 1061 return p._object_class()(p, new_name, is_name=True) 1062 1063 return self._name 1064 1065 def gen(self, n): 1066 P = self._check_valid() 1067 return P.new('%s.%s'%(self._name, int(n))) 1068 1069 def _operation(self, operation, right): 1070 P = self._check_valid() 1071 try: 1072 return P.new('%s %s %s'%(self._name, operation, right._name)) 1073 except Exception, msg: 1074 raise TypeError, msg 1075 1076 def _add_(self, right): 1077 """ 1078 EXAMPLES:: 1079 1080 sage: f = maxima.cos(x) 1081 sage: g = maxima.sin(x) 1082 sage: f + g 1083 sin(x)+cos(x) 1084 sage: f + 2 1085 cos(x)+2 1086 sage: 2 + f 1087 cos(x)+2 1088 """ 1089 return self._operation("+", right) 1090 1091 def _sub_(self, right): 1092 """ 1093 EXAMPLES:: 1094 1095 sage: f = maxima.cos(x) 1096 sage: g = maxima.sin(x) 1097 sage: f - g 1098 cos(x)-sin(x) 1099 sage: f - 2 1100 cos(x)-2 1101 sage: 2 - f 1102 2-cos(x) 1103 """ 1104 return self._operation('-', right) 1105 1106 def _mul_(self, right): 1107 """ 1108 EXAMPLES:: 1109 1110 sage: f = maxima.cos(x) 1111 sage: g = maxima.sin(x) 1112 sage: f*g 1113 cos(x)*sin(x) 1114 sage: 2*f 1115 2*cos(x) 1116 """ 1117 return self._operation('*', right) 1118 1119 def _div_(self, right): 1120 """ 1121 EXAMPLES:: 1122 1123 sage: f = maxima.cos(x) 1124 sage: g = maxima.sin(x) 1125 sage: f/g 1126 cos(x)/sin(x) 1127 sage: f/2 1128 cos(x)/2 1129 """ 1130 return self._operation("/", right) 1131 1132 def __pow__(self, n): 1133 """ 1134 EXAMPLES:: 1135 1136 sage: a = maxima('2') 1137 sage: a^(3/4) 1138 2^(3/4) 1139 """ 1140 P = self._check_valid() 1141 if not hasattr(n, 'parent') or P is not n.parent(): 1142 n = P(n) 1143 return self._operation("^", n) 1144 1145 def reduce_load(parent, x): 1146 return parent(x) -
sage/interfaces/maxima.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/maxima.py
a b 45 45 sage: F 46 46 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4) 47 47 sage: type(F) 48 <class 'sage.interfaces.maxima _abstract.MaximaElement'>48 <class 'sage.interfaces.maxima.MaximaElement'> 49 49 50 50 Note that Maxima objects can also be displayed using "ASCII art"; 51 51 to see a normal linear representation of any Maxima object x. Just … … 451 451 452 452 import os, re, sys, subprocess 453 453 import pexpect 454 cygwin = os.uname()[0][:6]=="CYGWIN" 455 456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString 457 from pexpect import EOF 454 #cygwin = os.uname()[0][:6]=="CYGWIN" 458 455 459 456 from random import randrange 460 457 458 from sage.misc.misc import DOT_SAGE, SAGE_ROOT 459 461 460 ##import sage.rings.all 462 461 import sage.rings.complex_number 463 462 464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT463 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString 465 464 466 from sage.misc.multireplace import multiple_replace465 from maxima_abstract import MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction 467 466 468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE 469 470 import sage.server.support 471 472 import maxima_abstract 473 from maxima_abstract import MaximaFunctionElement, MaximaExpectFunction, MaximaElement, MaximaFunction, maxima_console 474 475 # The Maxima "apropos" command, e.g., apropos(det) gives a list 476 # of all identifiers that begin in a certain way. This could 477 # maybe be useful somehow... (?) Also maxima has a lot for getting 478 # documentation from the system -- this could also be useful. 479 480 class Maxima(maxima_abstract.Maxima): 467 # Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected 468 class Maxima(MaximaAbstract, Expect): 481 469 """ 482 470 Interface to the Maxima interpreter. 483 471 """ … … 493 481 494 482 We make sure labels are turned off (see trac 6816):: 495 483 496 sage: 'nolabels :true' in maxima._Expect__init_code484 sage: 'nolabels : true' in maxima._Expect__init_code 497 485 True 498 486 """ 499 487 # TODO: Input and output prompts in maxima can be changed by … … 509 497 # this interface to preload commands, put them in 510 498 # $DOT_SAGE/maxima/maxima-init.mac 511 499 # (we use the "--userdir" option in maxima for this) 512 import sage.misc.misc 513 SAGE_MAXIMA_DIR = os.path.join(sage.misc.misc.DOT_SAGE,"maxima") 500 SAGE_MAXIMA_DIR = os.path.join(DOT_SAGE,"maxima") 514 501 515 502 if not os.path.exists(STARTUP): 516 503 raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp' … … 525 512 # Many thanks to andrej.vodopivec@gmail.com and also 526 513 # Robert Dodier for figuring this out! 527 514 # See trac # 6818. 528 init_code.append('nolabels:true') 529 530 531 515 init_code.append('nolabels : true') 516 517 MaximaAbstract.__init__(self,"maxima") 532 518 Expect.__init__(self, 533 519 name = 'maxima', 534 520 prompt = '\(\%i[0-9]+\)', … … 552 538 553 539 554 540 555 def _function_class(self):556 """557 EXAMPLES::558 559 sage: maxima._function_class()560 <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'>561 """562 return MaximaExpectFunction563 564 541 def _start(self): 565 542 """ 566 543 Starts the Maxima interpreter. … … 751 728 o = out[m.end()+1:-2] 752 729 o = ''.join([x.strip() for x in o.split()]) 753 730 return o 754 755 731 756 732 def _synchronize(self): 757 733 """ … … 795 771 self._crash_msg() 796 772 self.quit() 797 773 774 def _batch(self, s, batchload=True): 775 filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647)) 776 F = open(filename, 'w') 777 F.write(s) 778 F.close() 779 if self.is_remote(): 780 self._send_tmpfile_to_server(local_file=filename) 781 tmp_to_use = self._remote_tmpfile() 782 tmp_to_use = filename 783 784 if batchload: 785 cmd = 'batchload("%s");'%tmp_to_use 786 else: 787 cmd = 'batch("%s");'%tmp_to_use 788 789 r = randrange(2147483647) 790 s = str(r+1) 791 cmd = "%s1+%s;\n"%(cmd,r) 792 793 self._sendline(cmd) 794 self._expect_expr(s) 795 out = self._before() 796 self._error_check(str, out) 797 os.unlink(filename) 798 return out 799 800 def _quit_string(self): 801 """ 802 EXAMPLES:: 803 804 sage: maxima._quit_string() 805 'quit();' 806 """ 807 return 'quit();' 808 809 def _crash_msg(self): 810 """ 811 EXAMPLES:: 812 813 sage: maxima._crash_msg() 814 Maxima crashed -- automatically restarting. 815 """ 816 print "Maxima crashed -- automatically restarting." 817 818 def _error_check(self, str, out): 819 r = self._error_re 820 m = r.search(out) 821 if not m is None: 822 self._error_msg(str, out) 823 824 def _error_msg(self, str, out): 825 raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(str, out.replace('-- an error. To debug this try debugmode(true);','')) 826 798 827 ########################################### 799 828 # Direct access to underlying lisp interpreter. 800 829 ########################################### … … 817 846 self._expect_expr('(%i)') 818 847 return self._before() 819 848 820 ########################################### 821 # Interactive help 822 ########################################### 823 def _command_runner(self, command, s, redirect=True): 824 """ 825 Run ``command`` in a new Maxima session and return its 826 output as an ``AsciiArtString``. 827 828 If redirect is set to False, then the output of the command is not 829 returned as a string. Instead, it behaves like os.system. This is 830 used for interactive things like Maxima's demos. See maxima.demo? 831 832 EXAMPLES:: 833 834 sage: maxima._command_runner('describe', 'gcd') 835 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...) 836 ... 837 """ 838 cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s) 839 if sage.server.support.EMBEDDED_MODE: 840 cmd += '< /dev/null' 841 842 if redirect: 843 p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, 844 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 845 res = p.stdout.read() 846 # ecl-10.2 : 3 lines 847 # ecl-10.4 : 5 lines 848 # ecl-11.1 : 4 lines fancy a tango? 849 # We now get 4 lines of commented verbosity 850 # every time Maxima starts, so we need to get rid of them 851 for _ in range(4): 852 res = res[res.find('\n')+1:] 853 return AsciiArtString(res) 854 else: 855 subprocess.Popen(cmd, shell=True) 856 857 def _object_class(self): 858 """ 859 Return the Python class of Maxima elements. 860 861 EXAMPLES:: 862 863 sage: maxima._object_class() 864 <class 'sage.interfaces.maxima_abstract.MaximaElement'> 865 """ 866 return MaximaElement 867 868 def _function_element_class(self): 869 """ 870 EXAMPLES:: 871 872 sage: maxima._function_element_class() 873 <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'> 874 """ 875 return MaximaFunctionElement 876 877 def function(self, args, defn, rep=None, latex=None): 878 """ 879 Return the Maxima function with given arguments and definition. 880 881 INPUT: 882 883 884 - ``args`` - a string with variable names separated by 885 commas 886 887 - ``defn`` - a string (or Maxima expression) that 888 defines a function of the arguments in Maxima. 889 890 - ``rep`` - an optional string; if given, this is how 891 the function will print. 892 893 894 EXAMPLES:: 895 896 sage: f = maxima.function('x', 'sin(x)') 897 sage: f(3.2) 898 -.058374143427580... 899 sage: f = maxima.function('x,y', 'sin(x)+cos(y)') 900 sage: f(2,3.5) 901 sin(2)-.9364566872907963 902 sage: f 903 sin(x)+cos(y) 904 905 :: 906 907 sage: g = f.integrate('z') 908 sage: g 909 (cos(y)+sin(x))*z 910 sage: g(1,2,3) 911 3*(cos(2)+sin(1)) 912 913 The function definition can be a maxima object:: 914 915 sage: an_expr = maxima('sin(x)*gamma(x)') 916 sage: t = maxima.function('x', an_expr) 917 sage: t 918 gamma(x)*sin(x) 919 sage: t(2) 920 sin(2) 921 sage: float(t(2)) 922 0.90929742682568171 923 sage: loads(t.dumps()) 924 gamma(x)*sin(x) 925 """ 926 name = self._next_var_name() 927 if isinstance(defn, MaximaElement): 928 defn = defn.str() 929 elif not isinstance(defn, str): 930 defn = str(defn) 931 if isinstance(args, MaximaElement): 932 args = args.str() 933 elif not isinstance(args, str): 934 args = str(args) 935 cmd = '%s(%s) := %s'%(name, args, defn) 936 maxima._eval_line(cmd) 937 if rep is None: 938 rep = defn 939 f = MaximaFunction(self, name, rep, args, latex) 940 return f 849 ##### 850 # 851 ##### 941 852 942 853 def set(self, var, value): 943 854 """ … … 999 910 """ 1000 911 s = self._eval_line('%s;'%var) 1001 912 return s 1002 1003 def version(self):913 914 def _function_class(self): 1004 915 """ 1005 Return the version of Maxima that Sage includes. 916 EXAMPLES:: 917 918 sage: maxima._function_class() 919 <class 'sage.interfaces.maxima.MaximaFunction'> 920 """ 921 return MaximaFunction 922 923 def _object_class(self): 924 """ 925 Return the Python class of Maxima elements. 1006 926 1007 927 EXAMPLES:: 1008 928 1009 sage: maxima. version()1010 '5.23.2'929 sage: maxima._object_class() 930 <class 'sage.interfaces.maxima.MaximaElement'> 1011 931 """ 1012 return maxima_version()932 return MaximaElement 1013 933 1014 ##some helper functions to wrap tha calculus use of the maxima interface. 1015 ##these routines expect arguments living in the symbolic ring and return something 1016 ##that is hopefully coercible into the symbolic ring again. 934 def _function_element_class(self): 935 """ 936 EXAMPLES:: 937 938 sage: maxima._function_element_class() 939 <class 'sage.interfaces.maxima.MaximaFunctionElement'> 940 """ 941 return MaximaFunctionElement 942 943 def _object_function_class(self): 944 """ 945 EXAMPLES:: 946 947 sage: maxima._object_function_class() 948 <class 'sage.interfaces.maxima.MaximaElementFunction'> 949 """ 950 return MaximaElementFunction 951 952 ##some helper functions to wrap tha calculus use of the maxima interface. 953 ##these routines expect arguments living in the symbolic ring and return something 954 ##that is hopefully coercible into the symbolic ring again. 1017 955 1018 956 def sr_integral(self,*args): 1019 957 return args[0]._maxima_().integrate(*args[1:]) … … 1029 967 1030 968 def sr_tlimit(self,ex,*args): 1031 969 return ex._maxima_().tlimit(*args) 1032 1033 ## def display2d(self, flag=True):1034 ## """1035 ## Set the flag that determines whether Maxima objects are1036 ## printed using their 2-d ASCII art representation. When the1037 ## maxima interface starts the default is that objects are not1038 ## represented in 2-d.1039 970 1040 ## INPUT:1041 ## flag -- bool (default: True)1042 1043 ## EXAMPLES1044 ## sage: maxima('1/2')1045 ## 1/21046 ## sage: maxima.display2d(True)1047 ## sage: maxima('1/2')1048 ## 11049 ## -1050 ## 21051 ## sage: maxima.display2d(False)1052 ## """1053 ## self._display2d = bool(flag)1054 971 1055 972 def is_MaximaElement(x): 1056 973 """ … … 1067 984 """ 1068 985 return isinstance(x, MaximaElement) 1069 986 987 # Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected 988 class MaximaElement(MaximaAbstractElement, ExpectElement): 989 def __init__(self, parent, value, is_name=False, name=None): 990 ExpectElement.__init__(self, parent, value, is_name=False, name=None) 991 992 def display2d(self, onscreen=True): 993 """ 994 EXAMPLES:: 995 996 sage: F = maxima('x^5 - y^5').factor() 997 sage: F.display2d () 998 4 3 2 2 3 4 999 - (y - x) (y + x y + x y + x y + x ) 1000 """ 1001 self._check_valid() 1002 P = self.parent() 1003 with gc_disabled(): 1004 P._eval_line('display2d : true$') 1005 s = P._eval_line('disp(%s)$'%self.name(), reformat=False) 1006 P._eval_line('display2d : false$') 1007 1008 s = s.strip('\r\n') 1009 1010 # if ever want to dedent, see 1011 # http://mail.python.org/pipermail/python-list/2006-December/420033.html 1012 if onscreen: 1013 print s 1014 else: 1015 return s 1016 1017 1018 # Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected 1019 class MaximaFunctionElement(MaximaAbstractFunctionElement, FunctionElement): 1020 pass 1021 # def __init__(self, obj, name): 1022 # MaximaAbstractFunctionElement.__init__(self, obj, name) 1023 # FunctionElement.__init__(self, obj, name) 1024 1025 1026 # Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected 1027 class MaximaFunction(MaximaAbstractFunction, ExpectFunction): 1028 pass 1029 # def __init__(self, parent, name): 1030 # MaximaAbstractFunction.__init__(self, parent, name) 1031 # ExpectFunction.__init__(self, parent, name) 1032 1033 1034 # Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected 1035 class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction): 1036 def __init__(self, parent, name, defn, args, latex): 1037 MaximaElement.__init__(self, parent, name, is_name=True) 1038 MaximaAbstractElementFunction.__init__(self, parent, name, defn, args, latex) 1039 1040 1070 1041 # An instance 1071 maxima = Maxima(init_code = ['display2d :false; domain: complex; keepfloat: true'],1042 maxima = Maxima(init_code = ['display2d : false; domain : complex; keepfloat : true'], 1072 1043 script_subdirectory=None) 1073 1044 1045 1074 1046 def reduce_load_Maxima(): 1075 1047 """ 1076 1048 EXAMPLES:: … … 1081 1053 """ 1082 1054 return maxima 1083 1055 1084 1085 def maxima_version(): 1086 """ 1087 EXAMPLES:: 1088 1089 sage: from sage.interfaces.maxima import maxima_version 1090 sage: maxima_version() 1091 '5.23.2' 1092 """ 1093 return os.popen('maxima --version').read().split()[-1] 1056 def reduce_load_Maxima_function(parent, defn, args, latex): 1057 return parent.function(args, defn, defn, latex) 1094 1058 1095 1059 def __doctest_cleanup(): 1096 1060 import sage.interfaces.quit -
sage/interfaces/maxima_abstract.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/maxima_abstract.py
a b 28 28 29 29 If the string "error" (case insensitive) occurs in the output of 30 30 anything from Maxima, a RuntimeError exception is raised. 31 32 EXAMPLES: We evaluate a very simple expression in Maxima.33 34 ::35 36 sage: maxima('3 * 5')37 1538 39 We factor `x^5 - y^5` in Maxima in several different ways.40 The first way yields a Maxima object.41 42 ::43 44 sage: F = maxima.factor('x^5 - y^5')45 sage: F46 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)47 sage: type(F)48 <class 'sage.interfaces.maxima_abstract.MaximaElement'>49 50 Note that Maxima objects can also be displayed using "ASCII art";51 to see a normal linear representation of any Maxima object x. Just52 use the print command: use ``str(x)``.53 54 ::55 56 sage: print F57 4 3 2 2 3 458 - (y - x) (y + x y + x y + x y + x )59 60 You can always use ``repr(x)`` to obtain the linear61 representation of an object. This can be useful for moving maxima62 data to other systems.63 64 ::65 66 sage: repr(F)67 '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'68 sage: F.str()69 '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'70 71 The ``maxima.eval`` command evaluates an expression in72 maxima and returns the result as a *string* not a maxima object.73 74 ::75 76 sage: print maxima.eval('factor(x^5 - y^5)')77 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)78 79 We can create the polynomial `f` as a Maxima polynomial,80 then call the factor method on it. Notice that the notation81 ``f.factor()`` is consistent with how the rest of Sage82 works.83 84 ::85 86 sage: f = maxima('x^5 - y^5')87 sage: f^288 (x^5-y^5)^289 sage: f.factor()90 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)91 92 Control-C interruption works well with the maxima interface,93 because of the excellent implementation of maxima. For example, try94 the following sum but with a much bigger range, and hit control-C.95 96 ::97 98 sage: maxima('sum(1/x^2, x, 1, 10)')99 1968329/1270080100 101 Tutorial102 --------103 104 We follow the tutorial at105 http://maxima.sourceforge.net/docs/intromax/.106 107 ::108 109 sage: maxima('1/100 + 1/101')110 201/10100111 112 ::113 114 sage: a = maxima('(1 + sqrt(2))^5'); a115 (sqrt(2)+1)^5116 sage: a.expand()117 3*2^(7/2)+5*sqrt(2)+41118 119 ::120 121 sage: a = maxima('(1 + sqrt(2))^5')122 sage: float(a)123 82.012193308819747124 sage: a.numer()125 82.01219330881975126 127 ::128 129 sage: maxima.eval('fpprec : 100')130 '100'131 sage: a.bfloat()132 8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1133 134 ::135 136 sage: maxima('100!')137 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000138 139 ::140 141 sage: f = maxima('(x + 3*y + x^2*y)^3')142 sage: f.expand()143 x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3144 sage: f.subst('x=5/z')145 (5/z+25*y/z^2+3*y)^3146 sage: g = f.subst('x=5/z')147 sage: h = g.ratsimp(); h148 (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6149 sage: h.factor()150 (3*y*z^2+5*z+25*y)^3/z^6151 152 ::153 154 sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])155 sage: s = eqn.solve('[a,b,c]'); s156 [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]157 158 Here is an example of solving an algebraic equation::159 160 sage: maxima('x^2+y^2=1').solve('y')161 [y=-sqrt(1-x^2),y=sqrt(1-x^2)]162 sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')163 [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]164 165 You can even nicely typeset the solution in latex::166 167 sage: latex(s)168 \left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} , b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1 }\over{10}} \right] , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\, \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} , c=-{{\sqrt{79}\,i-1}\over{10}} \right] \right]169 170 To have the above appear onscreen via ``xdvi``, type171 ``view(s)``. (TODO: For OS X should create pdf output172 and use preview instead?)173 174 ::175 176 sage: e = maxima('sin(u + v) * cos(u)^3'); e177 cos(u)^3*sin(v+u)178 sage: f = e.trigexpand(); f179 cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))180 sage: f.trigreduce()181 (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8182 sage: w = maxima('3 + k*%i')183 sage: f = w^2 + maxima('%e')^w184 sage: f.realpart()185 %e^3*cos(k)-k^2+9186 187 ::188 189 sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f190 x^3*%e^(k*x)*sin(w*x)191 sage: f.diff('x')192 k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)193 sage: f.integrate('x')194 (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)195 196 ::197 198 sage: f = maxima('1/x^2')199 sage: f.integrate('x', 1, 'inf')200 1201 sage: g = maxima('f/sinh(k*x)^4')202 sage: g.taylor('x', 0, 3)203 f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945204 205 ::206 207 sage: maxima.taylor('asin(x)','x',0, 10)208 x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152209 210 Examples involving matrices211 ---------------------------212 213 We illustrate computing with the matrix whose `i,j` entry214 is `i/j`, for `i,j=1,\ldots,4`.215 216 ::217 218 sage: f = maxima.eval('f[i,j] := i/j')219 sage: A = maxima('genmatrix(f,4,4)'); A220 matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])221 sage: A.determinant()222 0223 sage: A.echelon()224 matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])225 sage: A.eigenvalues()226 [[0,4],[3,1]]227 sage: A.eigenvectors()228 [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]229 230 We can also compute the echelon form in Sage::231 232 sage: B = matrix(QQ, A)233 sage: B.echelon_form()234 [ 1 1/2 1/3 1/4]235 [ 0 0 0 0]236 [ 0 0 0 0]237 [ 0 0 0 0]238 sage: B.charpoly('x').factor()239 (x - 4) * x^3240 241 Laplace Transforms242 ------------------243 244 We illustrate Laplace transforms::245 246 sage: _ = maxima.eval("f(t) := t*sin(t)")247 sage: maxima("laplace(f(t),t,s)")248 2*s/(s^2+1)^2249 250 ::251 252 sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function253 %e^-(3*s)254 255 ::256 257 sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")258 sage: maxima("laplace(f(t),t,s)")259 1/(s^2-2*s+2)260 261 ::262 263 sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")264 sage: maxima("laplace(f(t),t,s)")265 360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6266 sage: print maxima("laplace(f(t),t,s)")267 3 5268 360 (2 s - 2) 480 (2 s - 2) 120 (2 s - 2)269 --------------- - --------------- + ---------------270 2 4 2 5 2 6271 (s - 2 s + 2) (s - 2 s + 2) (s - 2 s + 2)272 273 ::274 275 sage: maxima("laplace(diff(x(t),t),t,s)")276 s*'laplace(x(t),t,s)-x(0)277 278 ::279 280 sage: maxima("laplace(diff(x(t),t,2),t,s)")281 -?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s282 283 It is difficult to read some of these without the 2d284 representation::285 286 sage: print maxima("laplace(diff(x(t),t,2),t,s)")287 !288 d ! 2289 - -- (x(t))! + s laplace(x(t), t, s) - x(0) s290 dt !291 !t = 0292 293 Even better, use294 ``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see295 a typeset version.296 297 Continued Fractions298 -------------------299 300 A continued fraction `a + 1/(b + 1/(c + \cdots))` is301 represented in maxima by the list `[a, b, c, \ldots]`.302 303 ::304 305 sage: maxima("cf((1 + sqrt(5))/2)")306 [1,1,1,1,2]307 sage: maxima("cf ((1 + sqrt(341))/2)")308 [9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]309 310 Special examples311 ----------------312 313 In this section we illustrate calculations that would be awkward to314 do (as far as I know) in non-symbolic computer algebra systems like315 MAGMA or GAP.316 317 We compute the gcd of `2x^{n+4} - x^{n+2}` and318 `4x^{n+1} + 3x^n` for arbitrary `n`.319 320 ::321 322 sage: f = maxima('2*x^(n+4) - x^(n+2)')323 sage: g = maxima('4*x^(n+1) + 3*x^n')324 sage: f.gcd(g)325 x^n326 327 You can plot 3d graphs (via gnuplot)::328 329 sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])') # not tested330 [displays a 3 dimensional graph]331 332 You can formally evaluate sums (note the ``nusum``333 command)::334 335 sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')336 sage: print S337 2/n + 3 2/n + 1338 %e %e339 ----------------------- - -----------------------340 1/n 1/n 1/n 1/n341 (%e - 1) (%e + 1) (%e - 1) (%e + 1)342 343 We formally compute the limit as `n\to\infty` of344 `2S/n` as follows::345 346 sage: T = S*maxima('2/n')347 sage: T.tlimit('n','inf')348 %e^3-%e349 350 Miscellaneous351 -------------352 353 Obtaining digits of `\pi`::354 355 sage: maxima.eval('fpprec : 100')356 '100'357 sage: maxima(pi).bfloat()358 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0359 360 Defining functions in maxima::361 362 sage: maxima.eval('fun[a] := a^2')363 'fun[a]:=a^2'364 sage: maxima('fun[10]')365 100366 367 Interactivity368 -------------369 370 Unfortunately maxima doesn't seem to have a non-interactive mode,371 which is needed for the Sage interface. If any Sage call leads to372 maxima interactively answering questions, then the questions can't be373 answered and the maxima session may hang. See the discussion at374 http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some375 ideas about how to fix this problem. An example that illustrates this376 problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.377 378 Latex Output379 ------------380 381 To TeX a maxima object do this::382 383 sage: latex(maxima('sin(u) + sinh(v^2)'))384 \sinh v^2+\sin u385 386 Here's another example::387 388 sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')389 sage: latex(g)390 -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c391 392 Long Input393 ----------394 395 The MAXIMA interface reads in even very long input (using files) in396 a robust manner, as long as you are creating a new object.397 398 .. note::399 400 Using ``maxima.eval`` for long input is much less robust, and is401 not recommended.402 403 ::404 405 sage: t = '"%s"'%10^10000 # ten thousand character string.406 sage: a = maxima(t)407 408 TESTS: This working tests that a subtle bug has been fixed::409 410 sage: f = maxima.function('x','gamma(x)')411 sage: g = f(1/7)412 sage: g413 gamma(1/7)414 sage: del f415 sage: maxima(sin(x))416 sin(x)417 418 This tests to make sure we handle the case where Maxima asks if an419 expression is positive or zero.420 421 ::422 423 sage: var('Ax,Bx,By')424 (Ax, Bx, By)425 sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))426 sage: t.limit(Ax=0, dir='+')427 0428 429 A long complicated input expression::430 431 sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')432 '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'433 31 """ 434 32 435 33 #***************************************************************************** … … 447 45 # http://www.gnu.org/licenses/ 448 46 #***************************************************************************** 449 47 450 from __future__ import with_statement 48 import os, re, sys, subprocess 451 49 452 import os, re, sys, subprocess 453 import pexpect 454 cygwin = os.uname()[0][:6]=="CYGWIN" 50 from sage.misc.misc import DOT_SAGE 51 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE 455 52 456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString 457 from pexpect import EOF 53 from sage.misc.multireplace import multiple_replace 458 54 459 from random import randrange 55 import sage.server.support 460 56 461 57 ##import sage.rings.all 462 58 import sage.rings.complex_number 463 59 464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT 465 466 from sage.misc.multireplace import multiple_replace 467 468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE 469 470 import sage.server.support 60 from interface import Interface, InterfaceElement, InterfaceFunctionElement, InterfaceFunction, AsciiArtString 471 61 472 62 # The Maxima "apropos" command, e.g., apropos(det) gives a list 473 63 # of all identifiers that begin in a certain way. This could 474 64 # maybe be useful somehow... (?) Also maxima has a lot for getting 475 65 # documentation from the system -- this could also be useful. 476 66 477 class Maxima (Expect):67 class MaximaAbstract(Interface): 478 68 """ 479 69 Interface to the Maxima interpreter. 480 70 """ 481 def __init__(self, script_subdirectory=None, logfile=None, server=None, 482 init_code = None): 71 def __init__(self, name): 483 72 """ 484 Create an instance of the Maxima interpreter. 485 486 TESTS:: 487 488 sage: maxima == loads(dumps(maxima)) 489 True 490 491 We make sure labels are turned off (see trac 6816):: 492 493 sage: 'nolabels:true' in maxima._Expect__init_code 494 True 73 Create an instance of an abstract interface to Maxima. 495 74 """ 496 # TODO: Input and output prompts in maxima can be changed by 497 # setting inchar and outchar.. 498 eval_using_file_cutoff = 256 499 self.__eval_using_file_cutoff = eval_using_file_cutoff 500 STARTUP = '%s/local/bin/sage-maxima.lisp'%SAGE_ROOT 501 502 # We set maxima's configuration directory to $DOT_SAGE/maxima 503 # This avoids that sage's maxima inadvertently loads 504 # ~/.maxima/maxima-init.mac 505 # If you absolutely want maxima instances that are started by 506 # this interface to preload commands, put them in 507 # $DOT_SAGE/maxima/maxima-init.mac 508 # (we use the "--userdir" option in maxima for this) 509 import sage.misc.misc 510 SAGE_MAXIMA_DIR = os.path.join(sage.misc.misc.DOT_SAGE,"maxima") 511 512 if not os.path.exists(STARTUP): 513 raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp' 514 if init_code is None: 515 # display2d -- no ascii art output 516 # keepfloat -- don't automatically convert floats to rationals 517 init_code = ['display2d : false', 'keepfloat : true'] 518 519 # Turn off the prompt labels, since computing them *very 520 # dramatically* slows down the maxima interpret after a while. 521 # See the function makelabel in suprv1.lisp. 522 # Many thanks to andrej.vodopivec@gmail.com and also 523 # Robert Dodier for figuring this out! 524 # See trac # 6818. 525 init_code.append('nolabels:true') 526 527 Expect.__init__(self, 528 name = 'maxima', 529 prompt = '\(\%i[0-9]+\)', 530 command = 'maxima-noreadline --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP), 531 maxread = 10000, 532 script_subdirectory = script_subdirectory, 533 restart_on_ctrlc = False, 534 verbose_start = False, 535 init_code = init_code, 536 logfile = logfile, 537 eval_using_file_cutoff=eval_using_file_cutoff) 538 self._display_prompt = '<sage-display>' # must match what is in the file local/bin/sage-maxima.lisp!! 539 self._output_prompt_re = re.compile('\(\%o[0-9]+\)') 540 self._ask = ['zero or nonzero?', 'an integer?', 'positive, negative, or zero?', 541 'positive or negative?', 'positive or zero?'] 542 self._prompt_wait = [self._prompt] + [re.compile(x) for x in self._ask] + \ 543 ['Break [0-9]+'] #note that you might need to change _expect_expr if you 544 #change this 545 self._error_re = re.compile('(Principal Value|debugmode|incorrect syntax|Maxima encountered a Lisp error)') 546 self._display2d = False 547 548 def _quit_string(self): 549 """ 550 EXAMPLES:: 551 552 sage: maxima._quit_string() 553 'quit();' 554 """ 555 return 'quit();' 556 557 def _crash_msg(self): 558 """ 559 EXAMPLES:: 560 561 sage: maxima._crash_msg() 562 Maxima crashed -- automatically restarting. 563 """ 564 print "Maxima crashed -- automatically restarting." 565 566 567 def _batch(self, s, batchload=True): 568 filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647)) 569 F = open(filename, 'w') 570 F.write(s) 571 F.close() 572 if self.is_remote(): 573 self._send_tmpfile_to_server(local_file=filename) 574 tmp_to_use = self._remote_tmpfile() 575 tmp_to_use = filename 576 577 if batchload: 578 cmd = 'batchload("%s");'%tmp_to_use 579 else: 580 cmd = 'batch("%s");'%tmp_to_use 581 582 r = randrange(2147483647) 583 s = str(r+1) 584 cmd = "%s1+%s;\n"%(cmd,r) 585 586 self._sendline(cmd) 587 self._expect_expr(s) 588 out = self._before() 589 self._error_check(str, out) 590 os.unlink(filename) 591 return out 592 593 def _error_check(self, str, out): 594 r = self._error_re 595 m = r.search(out) 596 if not m is None: 597 self._error_msg(str, out) 598 599 def _error_msg(self, str, out): 600 raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(str, out.replace('-- an error. To debug this try debugmode(true);','')) 601 75 Interface.__init__(self,name) 602 76 603 77 ########################################### 604 78 # System -- change directory, etc … … 616 90 ########################################### 617 91 # Interactive help 618 92 ########################################### 93 def _command_runner(self, command, s, redirect=True): 94 """ 95 Run ``command`` in a new Maxima session and return its 96 output as an ``AsciiArtString``. 97 98 If redirect is set to False, then the output of the command is not 99 returned as a string. Instead, it behaves like os.system. This is 100 used for interactive things like Maxima's demos. See maxima.demo? 101 102 EXAMPLES:: 103 104 sage: maxima._command_runner('describe', 'gcd') 105 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...) 106 ... 107 """ 108 cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s) 109 if sage.server.support.EMBEDDED_MODE: 110 cmd += '< /dev/null' 619 111 112 if redirect: 113 p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, 114 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 115 res = p.stdout.read() 116 # ecl-10.2 : 3 lines 117 # ecl-10.4 : 5 lines 118 # ecl-11.1 : 4 lines fancy a tango? 119 # We now get 4 lines of commented verbosity 120 # every time Maxima starts, so we need to get rid of them 121 for _ in range(4): 122 res = res[res.find('\n')+1:] 123 return AsciiArtString(res) 124 else: 125 subprocess.Popen(cmd, shell=True) 620 126 621 127 def help(self, s): 622 128 """ … … 736 242 sage.misc.persist.save(v, COMMANDS_CACHE) 737 243 return v 738 244 245 def console(self): 246 r""" 247 Start the interactive Maxima console. This is a completely separate 248 maxima session from this interface. To interact with this session, 249 you should instead use ``maxima.interact()``. 250 251 EXAMPLES:: 252 253 sage: maxima.console() # not tested (since we can't) 254 Maxima 5.13.0 http://maxima.sourceforge.net 255 Using Lisp CLISP 2.41 (2006-10-13) 256 Distributed under the GNU Public License. See the file COPYING. 257 Dedicated to the memory of William Schelter. 258 This is a development version of Maxima. The function bug_report() 259 provides bug reporting information. 260 (%i1) 261 262 :: 263 264 sage: maxima.interact() # this is not tested either 265 --> Switching to Maxima <-- 266 maxima: 2+2 267 4 268 maxima: 269 --> Exiting back to Sage <-- 270 """ 271 maxima_console() 272 273 def cputime(self, t=None): 274 r""" 275 Returns the amount of CPU time that this Maxima session has used. 276 If \var{t} is not None, then it returns the difference between 277 the current CPU time and \var{t}. 278 279 EXAMPLES: 280 sage: t = maxima.cputime() 281 sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1]) 282 sage: maxima.cputime(t) # output random 283 0.568913 284 """ 285 if t: 286 return float(self.eval('elapsed_run_time()')) - t 287 else: 288 return float(self.eval('elapsed_run_time()')) 289 290 def version(self): 291 """ 292 Return the version of Maxima that Sage includes. 293 294 EXAMPLES:: 295 296 sage: maxima.version() 297 '5.23.2' 298 """ 299 return maxima_version() 300 301 #### 302 # Overriding default values 303 ### 304 305 def _assign_symbol(self): 306 return ":" 307 739 308 def _true_symbol(self): 740 309 """ 741 310 Return the true symbol in Maxima. … … 786 355 """ 787 356 return '#' 788 357 789 def console(self): 790 r""" 791 Start the interactive Maxima console. This is a completely separate 792 maxima session from this interface. To interact with this session, 793 you should instead use ``maxima.interact()``. 358 def _function_class(self): 359 """ 360 EXAMPLES:: 361 362 sage: maxima._function_class() 363 <class 'sage.interfaces.maxima.MaximaFunction'> 364 """ 365 return MaximaAbstractFunction 366 367 def _object_class(self): 368 """ 369 Return the Python class of Maxima elements. 794 370 795 371 EXAMPLES:: 796 372 797 sage: maxima.console() # not tested (since we can't) 798 Maxima 5.13.0 http://maxima.sourceforge.net 799 Using Lisp CLISP 2.41 (2006-10-13) 800 Distributed under the GNU Public License. See the file COPYING. 801 Dedicated to the memory of William Schelter. 802 This is a development version of Maxima. The function bug_report() 803 provides bug reporting information. 804 (%i1) 373 sage: maxima._object_class() 374 <class 'sage.interfaces.maxima.MaximaElement'> 375 """ 376 return MaximaAbstractElement 377 378 def _function_element_class(self): 379 """ 380 EXAMPLES:: 381 382 sage: maxima._function_element_class() 383 <class 'sage.interfaces.maxima.MaximaFunctionElement'> 384 """ 385 return MaximaAbstractFunctionElement 386 387 def _object_function_class(self): 388 """ 389 EXAMPLES:: 390 391 sage: maxima._object_function_class() 392 <class 'sage.interfaces.maxima.MaximaElementFunction'> 393 """ 394 return MaximaAbstractElementFunction 395 396 #### 397 # 398 #### 399 400 def function(self, args, defn, rep=None, latex=None): 401 """ 402 Return the Maxima function with given arguments and definition. 403 404 INPUT: 405 406 407 - ``args`` - a string with variable names separated by 408 commas 409 410 - ``defn`` - a string (or Maxima expression) that 411 defines a function of the arguments in Maxima. 412 413 - ``rep`` - an optional string; if given, this is how 414 the function will print. 415 416 417 EXAMPLES:: 418 419 sage: f = maxima.function('x', 'sin(x)') 420 sage: f(3.2) 421 -.058374143427580... 422 sage: f = maxima.function('x,y', 'sin(x)+cos(y)') 423 sage: f(2,3.5) 424 sin(2)-.9364566872907963 425 sage: f 426 sin(x)+cos(y) 805 427 806 428 :: 807 429 808 sage: maxima.interact() # this is not tested either 809 --> Switching to Maxima <-- 810 maxima: 2+2 811 4 812 maxima: 813 --> Exiting back to Sage <-- 430 sage: g = f.integrate('z') 431 sage: g 432 (cos(y)+sin(x))*z 433 sage: g(1,2,3) 434 3*(cos(2)+sin(1)) 435 436 The function definition can be a maxima object:: 437 438 sage: an_expr = maxima('sin(x)*gamma(x)') 439 sage: t = maxima.function('x', an_expr) 440 sage: t 441 gamma(x)*sin(x) 442 sage: t(2) 443 sin(2) 444 sage: float(t(2)) 445 0.90929742682568171 446 sage: loads(t.dumps()) 447 gamma(x)*sin(x) 814 448 """ 815 maxima_console() 449 name = self._next_var_name() 450 if isinstance(defn, MaximaAbstractElement): 451 defn = defn.str() 452 elif not isinstance(defn, str): 453 defn = str(defn) 454 if isinstance(args, MaximaAbstractElement): 455 args = args.str() 456 elif not isinstance(args, str): 457 args = str(args) 458 cmd = '%s(%s) := %s'%(name, args, defn) 459 self._eval_line(cmd) 460 if rep is None: 461 rep = defn 462 f = self._object_function_class()(self, name, rep, args, latex) 463 return f 816 464 817 def cputime(self, t=None): 818 r""" 819 Returns the amount of CPU time that this Maxima session has used. 820 If \var{t} is not None, then it returns the difference between 821 the current CPU time and \var{t}. 822 823 EXAMPLES: 824 sage: t = maxima.cputime() 825 sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1]) 826 sage: maxima.cputime(t) # output random 827 0.568913 828 """ 829 if t: 830 return float(self.eval('elapsed_run_time()')) - t 831 else: 832 return float(self.eval('elapsed_run_time()')) 833 834 465 ##### 466 # Maxima functions 467 ##### 468 835 469 ## def display2d(self, flag=True): 836 470 ## """ 837 471 ## Set the flag that determines whether Maxima objects are … … 1248 882 self('plot2d('+cmd+','+options+')') 1249 883 1250 884 1251 class Maxima Element(ExpectElement):885 class MaximaAbstractElement(InterfaceElement): 1252 886 def __str__(self): 1253 887 """ 1254 888 Printing an object explicitly gives ASCII art: … … 1469 1103 sage: a = maxima('sqrt(2)').numer(); a 1470 1104 1.41421356237309... 1471 1105 sage: type(a) 1472 <class 'sage.interfaces.maxima _abstract.MaximaElement'>1106 <class 'sage.interfaces.maxima.MaximaElement'> 1473 1107 """ 1474 1108 return self.comma('numer') 1475 1109 … … 1503 1137 self.__repr = r 1504 1138 return r 1505 1139 1506 def display2d(self, onscreen=True):1507 """1508 EXAMPLES::1509 1510 sage: F = maxima('x^5 - y^5').factor()1511 sage: F.display2d ()1512 4 3 2 2 3 41513 - (y - x) (y + x y + x y + x y + x )1514 """1515 self._check_valid()1516 P = self.parent()1517 with gc_disabled():1518 P._eval_line('display2d : true$')1519 s = P._eval_line('disp(%s)$'%self.name(), reformat=False)1520 P._eval_line('display2d: false$')1521 1522 s = s.strip('\r\n')1523 1524 # if ever want to dedent, see1525 # http://mail.python.org/pipermail/python-list/2006-December/420033.html1526 if onscreen:1527 print s1528 else:1529 return s1530 1531 1140 def diff(self, var='x', n=1): 1532 1141 """ 1533 1142 Return the n-th derivative of self. … … 1562 1171 sage: f.diff('y') 1563 1172 34*y 1564 1173 """ 1565 return ExpectElement.__getattr__(self, 'diff')(var, n)1174 return InterfaceElement.__getattr__(self, 'diff')(var, n) 1566 1175 1567 1176 derivative = diff 1568 1177 … … 1675 1284 sage: f.numer() 1676 1285 1.46265174590718... 1677 1286 """ 1678 I = ExpectElement.__getattr__(self, 'integrate')1287 I = InterfaceElement.__getattr__(self, 'integrate') 1679 1288 if min is None: 1680 1289 return I(var) 1681 1290 else: … … 1757 1366 if n < 0 or n >= len(self): 1758 1367 raise IndexError, "n = (%s) must be between %s and %s"%(n, 0, len(self)-1) 1759 1368 # If you change the n+1 to n below, better change __iter__ as well. 1760 return ExpectElement.__getitem__(self, n+1)1369 return InterfaceElement.__getitem__(self, n+1) 1761 1370 1762 1371 def __iter__(self): 1763 1372 """ … … 1940 1549 """ 1941 1550 P = self._check_valid() 1942 1551 1943 if isinstance(right, MaximaFunction):1552 if isinstance(right, P._object_function_class()): 1944 1553 fself = P.function('', repr(self)) 1945 1554 return fself._operation(operation, right) 1946 1555 … … 1950 1559 raise TypeError, msg 1951 1560 1952 1561 1953 1954 class MaximaFunctionElement(FunctionElement): 1955 def _sage_doc_(self): 1956 """ 1957 EXAMPLES:: 1958 1959 sage: m = maxima(4) 1960 sage: m.gcd._sage_doc_() 1961 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...) 1962 ... 1963 """ 1964 return self._obj.parent().help(self._name) 1562 class MaximaAbstractFunctionElement(InterfaceFunctionElement): 1563 pass 1965 1564 1966 class MaximaExpectFunction(ExpectFunction):1967 def _sage_doc_(self):1968 """1969 EXAMPLES::1970 1971 sage: maxima.gcd._sage_doc_()1972 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)1973 ...1974 """1975 M = self._parent1976 return M.help(self._name)1977 1565 1566 class MaximaAbstractFunction(InterfaceFunction): 1567 pass 1978 1568 1979 class MaximaFunction(MaximaElement): 1569 1570 class MaximaAbstractElementFunction(MaximaAbstractElement): 1980 1571 def __init__(self, parent, name, defn, args, latex): 1981 1572 """ 1982 1573 EXAMPLES:: … … 1985 1576 sage: f == loads(dumps(f)) 1986 1577 True 1987 1578 """ 1988 Maxima Element.__init__(self, parent, name, is_name=True)1579 MaximaAbstractElement.__init__(self, parent, name, is_name=True) 1989 1580 self.__defn = defn 1990 1581 self.__args = args 1991 1582 self.__latex = latex … … 1996 1587 1997 1588 sage: f = maxima.function('x,y','sin(x+y)') 1998 1589 sage: f.__reduce__() 1999 (<function reduce_load_Maxima _function at 0x...>,1590 (<function reduce_load_MaximaAbstract_function at 0x...>, 2000 1591 (Maxima, 'sin(x+y)', 'x,y', None)) 2001 1592 """ 2002 return reduce_load_Maxima _function, (self.parent(), self.__defn, self.__args, self.__latex)1593 return reduce_load_MaximaAbstract_function, (self.parent(), self.__defn, self.__args, self.__latex) 2003 1594 2004 1595 def __call__(self, *x): 2005 1596 """ … … 2127 1718 1/sin(y+x) 2128 1719 """ 2129 1720 P = self._check_valid() 2130 if isinstance(f, MaximaFunction):1721 if isinstance(f, P._object_function_class()): 2131 1722 tmp = list(sorted(set(self.arguments() + f.arguments()))) 2132 1723 args = ','.join(tmp) 2133 1724 defn = "(%s)%s(%s)"%(self.definition(), operation, f.definition()) … … 2298 1889 return self._operation("^", f) 2299 1890 2300 1891 2301 def reduce_load_Maxima _function(parent, defn, args, latex):1892 def reduce_load_MaximaAbstract_function(parent, defn, args, latex): 2302 1893 return parent.function(args, defn, defn, latex) 2303 1894 1895 def maxima_version(): 1896 """ 1897 EXAMPLES:: 1898 1899 sage: from sage.interfaces.maxima_abstract import maxima_version 1900 sage: maxima_version() 1901 '5.23.2' 1902 """ 1903 return os.popen('maxima --version').read().split()[-1] 2304 1904 2305 import os2306 1905 def maxima_console(): 2307 1906 """ 2308 1907 Spawn a new Maxima command-line session. 2309 1908 2310 1909 EXAMPLES:: 2311 1910 2312 sage: from sage.interfaces.maxima import maxima_console1911 sage: from sage.interfaces.maxima_abstract import maxima_console 2313 1912 sage: maxima_console() # not tested 2314 1913 Maxima 5.23.2 http://maxima.sourceforge.net 2315 1914 ... -
sage/interfaces/maxima_lib.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/interfaces/maxima_lib.py
a b 28 28 29 29 If the string "error" (case insensitive) occurs in the output of 30 30 anything from Maxima, a RuntimeError exception is raised. 31 32 EXAMPLES: We evaluate a very simple expression in Maxima.33 34 ::35 36 sage: maxima('3 * 5')37 1538 39 We factor `x^5 - y^5` in Maxima in several different ways.40 The first way yields a Maxima object.41 42 ::43 44 sage: F = maxima.factor('x^5 - y^5')45 sage: F46 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)47 sage: type(F)48 <class 'sage.interfaces.maxima_abstract.MaximaElement'>49 50 Note that Maxima objects can also be displayed using "ASCII art";51 to see a normal linear representation of any Maxima object x. Just52 use the print command: use ``str(x)``.53 54 ::55 56 sage: print F57 4 3 2 2 3 458 - (y - x) (y + x y + x y + x y + x )59 60 You can always use ``repr(x)`` to obtain the linear61 representation of an object. This can be useful for moving maxima62 data to other systems.63 64 ::65 66 sage: repr(F)67 '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'68 sage: F.str()69 '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'70 71 The ``maxima.eval`` command evaluates an expression in72 maxima and returns the result as a *string* not a maxima object.73 74 ::75 76 sage: print maxima.eval('factor(x^5 - y^5)')77 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)78 79 We can create the polynomial `f` as a Maxima polynomial,80 then call the factor method on it. Notice that the notation81 ``f.factor()`` is consistent with how the rest of Sage82 works.83 84 ::85 86 sage: f = maxima('x^5 - y^5')87 sage: f^288 (x^5-y^5)^289 sage: f.factor()90 -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)91 92 Control-C interruption works well with the maxima interface,93 because of the excellent implementation of maxima. For example, try94 the following sum but with a much bigger range, and hit control-C.95 96 ::97 98 sage: maxima('sum(1/x^2, x, 1, 10)')99 1968329/1270080100 101 Tutorial102 --------103 104 We follow the tutorial at105 http://maxima.sourceforge.net/docs/intromax/.106 107 ::108 109 sage: maxima('1/100 + 1/101')110 201/10100111 112 ::113 114 sage: a = maxima('(1 + sqrt(2))^5'); a115 (sqrt(2)+1)^5116 sage: a.expand()117 3*2^(7/2)+5*sqrt(2)+41118 119 ::120 121 sage: a = maxima('(1 + sqrt(2))^5')122 sage: float(a)123 82.012193308819747124 sage: a.numer()125 82.01219330881975126 127 ::128 129 sage: maxima.eval('fpprec : 100')130 '100'131 sage: a.bfloat()132 8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1133 134 ::135 136 sage: maxima('100!')137 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000138 139 ::140 141 sage: f = maxima('(x + 3*y + x^2*y)^3')142 sage: f.expand()143 x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3144 sage: f.subst('x=5/z')145 (5/z+25*y/z^2+3*y)^3146 sage: g = f.subst('x=5/z')147 sage: h = g.ratsimp(); h148 (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6149 sage: h.factor()150 (3*y*z^2+5*z+25*y)^3/z^6151 152 ::153 154 sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])155 sage: s = eqn.solve('[a,b,c]'); s156 [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]157 158 Here is an example of solving an algebraic equation::159 160 sage: maxima('x^2+y^2=1').solve('y')161 [y=-sqrt(1-x^2),y=sqrt(1-x^2)]162 sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')163 [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]164 165 You can even nicely typeset the solution in latex::166 167 sage: latex(s)168 \left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} , b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1 }\over{10}} \right] , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\, \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} , c=-{{\sqrt{79}\,i-1}\over{10}} \right] \right]169 170 To have the above appear onscreen via ``xdvi``, type171 ``view(s)``. (TODO: For OS X should create pdf output172 and use preview instead?)173 174 ::175 176 sage: e = maxima('sin(u + v) * cos(u)^3'); e177 cos(u)^3*sin(v+u)178 sage: f = e.trigexpand(); f179 cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))180 sage: f.trigreduce()181 (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8182 sage: w = maxima('3 + k*%i')183 sage: f = w^2 + maxima('%e')^w184 sage: f.realpart()185 %e^3*cos(k)-k^2+9186 187 ::188 189 sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f190 x^3*%e^(k*x)*sin(w*x)191 sage: f.diff('x')192 k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)193 sage: f.integrate('x')194 (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)195 196 ::197 198 sage: f = maxima('1/x^2')199 sage: f.integrate('x', 1, 'inf')200 1201 sage: g = maxima('f/sinh(k*x)^4')202 sage: g.taylor('x', 0, 3)203 f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945204 205 ::206 207 sage: maxima.taylor('asin(x)','x',0, 10)208 x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152209 210 Examples involving matrices211 ---------------------------212 213 We illustrate computing with the matrix whose `i,j` entry214 is `i/j`, for `i,j=1,\ldots,4`.215 216 ::217 218 sage: f = maxima.eval('f[i,j] := i/j')219 sage: A = maxima('genmatrix(f,4,4)'); A220 matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])221 sage: A.determinant()222 0223 sage: A.echelon()224 matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])225 sage: A.eigenvalues()226 [[0,4],[3,1]]227 sage: A.eigenvectors()228 [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]229 230 We can also compute the echelon form in Sage::231 232 sage: B = matrix(QQ, A)233 sage: B.echelon_form()234 [ 1 1/2 1/3 1/4]235 [ 0 0 0 0]236 [ 0 0 0 0]237 [ 0 0 0 0]238 sage: B.charpoly('x').factor()239 (x - 4) * x^3240 241 Laplace Transforms242 ------------------243 244 We illustrate Laplace transforms::245 246 sage: _ = maxima.eval("f(t) := t*sin(t)")247 sage: maxima("laplace(f(t),t,s)")248 2*s/(s^2+1)^2249 250 ::251 252 sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function253 %e^-(3*s)254 255 ::256 257 sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")258 sage: maxima("laplace(f(t),t,s)")259 1/(s^2-2*s+2)260 261 ::262 263 sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")264 sage: maxima("laplace(f(t),t,s)")265 360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6266 sage: print maxima("laplace(f(t),t,s)")267 3 5268 360 (2 s - 2) 480 (2 s - 2) 120 (2 s - 2)269 --------------- - --------------- + ---------------270 2 4 2 5 2 6271 (s - 2 s + 2) (s - 2 s + 2) (s - 2 s + 2)272 273 ::274 275 sage: maxima("laplace(diff(x(t),t),t,s)")276 s*'laplace(x(t),t,s)-x(0)277 278 ::279 280 sage: maxima("laplace(diff(x(t),t,2),t,s)")281 -?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s282 283 It is difficult to read some of these without the 2d284 representation::285 286 sage: print maxima("laplace(diff(x(t),t,2),t,s)")287 !288 d ! 2289 - -- (x(t))! + s laplace(x(t), t, s) - x(0) s290 dt !291 !t = 0292 293 Even better, use294 ``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see295 a typeset version.296 297 Continued Fractions298 -------------------299 300 A continued fraction `a + 1/(b + 1/(c + \cdots))` is301 represented in maxima by the list `[a, b, c, \ldots]`.302 303 ::304 305 sage: maxima("cf((1 + sqrt(5))/2)")306 [1,1,1,1,2]307 sage: maxima("cf ((1 + sqrt(341))/2)")308 [9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]309 310 Special examples311 ----------------312 313 In this section we illustrate calculations that would be awkward to314 do (as far as I know) in non-symbolic computer algebra systems like315 MAGMA or GAP.316 317 We compute the gcd of `2x^{n+4} - x^{n+2}` and318 `4x^{n+1} + 3x^n` for arbitrary `n`.319 320 ::321 322 sage: f = maxima('2*x^(n+4) - x^(n+2)')323 sage: g = maxima('4*x^(n+1) + 3*x^n')324 sage: f.gcd(g)325 x^n326 327 You can plot 3d graphs (via gnuplot)::328 329 sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])') # not tested330 [displays a 3 dimensional graph]331 332 You can formally evaluate sums (note the ``nusum``333 command)::334 335 sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')336 sage: print S337 2/n + 3 2/n + 1338 %e %e339 ----------------------- - -----------------------340 1/n 1/n 1/n 1/n341 (%e - 1) (%e + 1) (%e - 1) (%e + 1)342 343 We formally compute the limit as `n\to\infty` of344 `2S/n` as follows::345 346 sage: T = S*maxima('2/n')347 sage: T.tlimit('n','inf')348 %e^3-%e349 350 Miscellaneous351 -------------352 353 Obtaining digits of `\pi`::354 355 sage: maxima.eval('fpprec : 100')356 '100'357 sage: maxima(pi).bfloat()358 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0359 360 Defining functions in maxima::361 362 sage: maxima.eval('fun[a] := a^2')363 'fun[a]:=a^2'364 sage: maxima('fun[10]')365 100366 367 Interactivity368 -------------369 370 Unfortunately maxima doesn't seem to have a non-interactive mode,371 which is needed for the Sage interface. If any Sage call leads to372 maxima interactively answering questions, then the questions can't be373 answered and the maxima session may hang. See the discussion at374 http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some375 ideas about how to fix this problem. An example that illustrates this376 problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.377 378 Latex Output379 ------------380 381 To TeX a maxima object do this::382 383 sage: latex(maxima('sin(u) + sinh(v^2)'))384 \sinh v^2+\sin u385 386 Here's another example::387 388 sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')389 sage: latex(g)390 -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c391 392 Long Input393 ----------394 395 The MAXIMA interface reads in even very long input (using files) in396 a robust manner, as long as you are creating a new object.397 398 .. note::399 400 Using ``maxima.eval`` for long input is much less robust, and is401 not recommended.402 403 ::404 405 sage: t = '"%s"'%10^10000 # ten thousand character string.406 sage: a = maxima(t)407 408 TESTS: This working tests that a subtle bug has been fixed::409 410 sage: f = maxima.function('x','gamma(x)')411 sage: g = f(1/7)412 sage: g413 gamma(1/7)414 sage: del f415 sage: maxima(sin(x))416 sin(x)417 418 This tests to make sure we handle the case where Maxima asks if an419 expression is positive or zero.420 421 ::422 423 sage: var('Ax,Bx,By')424 (Ax, Bx, By)425 sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))426 sage: t.limit(Ax=0,dir='+')427 0428 429 A long complicated input expression::430 431 sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')432 '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'433 31 """ 434 32 435 33 #***************************************************************************** … … 447 45 # http://www.gnu.org/licenses/ 448 46 #***************************************************************************** 449 47 450 from __future__ import with_statement48 from sage.symbolic.ring import SR 451 49 452 import os, re, sys, subprocess 453 import pexpect 454 cygwin = os.uname()[0][:6]=="CYGWIN" 50 from sage.libs.ecl import * 455 51 456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString 457 from pexpect import EOF 52 from maxima_abstract import MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction 458 53 459 from random import randrange 460 461 ##import sage.rings.all 462 import sage.rings.complex_number 463 464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT 465 466 from sage.misc.multireplace import multiple_replace 467 468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE 469 470 import sage.server.support 471 472 import maxima_abstract 473 from maxima_abstract import MaximaFunctionElement, MaximaExpectFunction, MaximaFunction, maxima_console 474 475 # The Maxima "apropos" command, e.g., apropos(det) gives a list 476 # of all identifiers that begin in a certain way. This could 477 # maybe be useful somehow... (?) Also maxima has a lot for getting 478 # documentation from the system -- this could also be useful. 479 480 #################################################################### 481 ## We begin here by initializing maxima in library more 482 from sage.libs.ecl import * 54 ## We begin here by initializing maxima in library mode 483 55 ecl_eval("(setf *load-verbose* NIL)") 484 56 ecl_eval("(require 'maxima)") 485 57 ecl_eval("(in-package :maxima)") … … 497 69 (defun retrieve (msg flag &aux (print? nil)) 498 70 (declare (special msg flag print?)) 499 71 (or (eq flag 'noprint) (setq print? t)) 500 (error (concatenate 'string "Maxima asks:" (with-output-to-string (*standard-output*) 501 (terpri) 72 (error 73 (concatenate 'string "Maxima asks: " 74 (string-trim '(#\Newline) 75 (with-output-to-string (*standard-output*) 502 76 (cond ((not print?) 503 (setq print? t) 504 (princ *prompt-prefix*) 505 (princ *prompt-suffix*)) 506 ((null msg) 507 (princ *prompt-prefix*) 508 (princ *prompt-suffix*)) 509 ((atom msg) 510 (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*) 511 (mterpri)) 512 ((eq flag t) 513 (princ *prompt-prefix*) 514 (mapc #'princ (cdr msg)) 515 (princ *prompt-suffix*) 516 (mterpri)) 517 (t 518 (princ *prompt-prefix*) 519 (displa msg) 520 (princ *prompt-suffix*) 521 (mterpri))))))) 77 (setq print? t) 78 (princ *prompt-prefix*) 79 (princ *prompt-suffix*) 80 ) 81 ((null msg) 82 (princ *prompt-prefix*) 83 (princ *prompt-suffix*) 84 ) 85 ((atom msg) 86 (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*) 87 ) 88 ((eq flag t) 89 (princ *prompt-prefix*) 90 (mapc #'princ (cdr msg)) 91 (princ *prompt-suffix*) 92 ) 93 (t 94 (princ *prompt-prefix*) 95 (displa msg) 96 (princ *prompt-suffix*) 97 ) 98 )))) 99 ) 100 ) 522 101 """) 523 102 524 103 ecl_eval('(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))') 525 104 ecl_eval('(defun principal nil (error "Divergent Integral"))') 526 527 105 ecl_eval("(setf $errormsg nil)") 528 106 107 #ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))") 108 109 #ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))') 110 #ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))') 111 #ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))') 112 #ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))') 113 #ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))') 114 #ecl_eval('(defun asksign (x)(error "Maxima asks a question"))') 115 #ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))') 116 #ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))') 117 #ecl_eval('(defun askinver (a)(error "Maxima asks a question"))') 118 #ecl_eval('(defun npask (exp)(error "Maxima asks a question"))') 119 120 ecl_eval("(setf original-standard-output *standard-output*)") 121 ecl_eval("(setf *standard-output* *dev-null*)") 122 #ecl_eval("(setf *error-output* *dev-null*)") 123 124 # display2d -- no ascii art output 125 # keepfloat -- don't automatically convert floats to rationals 126 init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'] 127 # Turn off the prompt labels, since computing them *very 128 # dramatically* slows down the maxima interpret after a while. 129 # See the function makelabel in suprv1.lisp. 130 # Many thanks to andrej.vodopivec@gmail.com and also 131 # Robert Dodier for figuring this out! 132 # See trac # 6818. 133 init_code.append('nolabels : true') 134 for l in init_code: 135 ecl_eval("#$%s$"%l) 136 ## To get more debug information uncomment the next line 137 ## should allow to do this through a method 138 #ecl_eval("(setf *standard-output* original-standard-output)") 139 140 # This returns an EclObject 529 141 maxima_eval=ecl_eval(""" 530 142 (defun maxima-eval( form ) 531 143 (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form))))) … … 554 166 ) 555 167 """) 556 168 557 #ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))')558 #ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))')559 #ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))')560 #ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))')561 #ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))')562 #ecl_eval('(defun asksign (x)(error "Maxima asks a question"))')563 #ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))')564 #ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))')565 #ecl_eval('(defun askinver (a)(error "Maxima asks a question"))')566 #ecl_eval('(defun npask (exp)(error "Maxima asks a question"))')567 568 569 import sage.symbolic.expression570 from sage.symbolic.ring import is_SymbolicVariable571 from sage.symbolic.ring import SR572 573 169 maxima_lib_instances = 0 574 170 575 maxprint=EclObject("$STRING") 171 # The Maxima string function can change the structure of its input 172 #maxprint=EclObject("$STRING") 173 maxprint=EclObject("(defun mstring-for-sage (form) (coerce (mstring form) 'string))").eval() 576 174 meval=EclObject("MEVAL") 577 175 msetq=EclObject("MSETQ") 578 176 mlist=EclObject("MLIST") … … 590 188 max_use_grobner=EclObject("$USE_GROBNER") 591 189 max_to_poly_solve=EclObject("$TO_POLY_SOLVE") 592 190 191 def stdout_to_string(s): 192 return ecl_eval("(with-output-to-string (*standard-output*) (maxima-eval #$%s$))"%s).python()[1:-1] 193 593 194 def max_to_string(s): 594 return m eval(EclObject([[maxprint],s])).python()[1:-1]195 return maxprint(s).python()[1:-1] 595 196 596 class Maxima(maxima_abstract.Maxima): 197 my_mread=ecl_eval(""" 198 (defun my-mread (cmd) 199 (caddr (mread (make-string-input-stream cmd)))) 200 """) 201 202 def parse_max_string(l): 203 return my_mread('"%s;"'%l) 204 205 class MaximaLib(MaximaAbstract): 597 206 """ 598 Interface to the Maxima interpreter.207 Interface to Maxima as a Library. 599 208 """ 600 def __init__(self, script_subdirectory=None, logfile=None, server=None, 601 init_code = None): 209 def __init__(self): 602 210 """ 603 211 Create an instance of the Maxima interpreter. 604 212 605 213 TESTS:: 606 607 sage: maxima == loads(dumps(maxima)) 214 215 sage: from sage.interfaces.maxima_lib import maxima_lib 216 sage: maxima_lib == loads(dumps(maxima_lib)) 608 217 True 609 218 610 219 We make sure labels are turned off (see trac 6816):: 611 220 612 sage: 'nolabels :true' in maxima._Expect__init_code221 sage: 'nolabels : true' in maxima_lib._MaximaLib__init_code 613 222 True 614 223 """ 615 224 global maxima_lib_instances 616 225 if maxima_lib_instances > 0: 617 226 raise RuntimeError, "Maxima interface in library mode can only be instantiated once" 618 227 maxima_lib_instances += 1 619 620 #the single one gets defined in the Expect interface621 self._eval_using_file_cutoff = 10**9622 #the double underscore one seems to by private to the Maxima interface623 #this must have started as a typo by someone624 self.__eval_using_file_cutoff = 10**9625 self._available_vars = []626 self._Expect__seq = 0627 self._session_number = 1628 self._Expect__name = "maxima"629 228 630 if True: 631 # display2d -- no ascii art output 632 # keepfloat -- don't automatically convert floats to rationals 633 init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'] 634 635 # Turn off the prompt labels, since computing them *very 636 # dramatically* slows down the maxima interpret after a while. 637 # See the function makelabel in suprv1.lisp. 638 # Many thanks to andrej.vodopivec@gmail.com and also 639 # Robert Dodier for figuring this out! 640 # See trac # 6818. 641 init_code.append('nolabels : true') 642 ecl_eval("(setf original-standard-output *standard-output*)") 643 ecl_eval("(setf *standard-output* *dev-null*)") 644 for l in init_code: 645 ecl_eval("#$%s$"%l) 646 ecl_eval("(setf *standard-output* original-standard-output)") 229 global init_code 230 self.__init_code = init_code 231 232 ## The name should definitely be changed to maxima_lib, however much more changes are then needed elsewhere 233 ## With maxima, more things are fine, but for example _maxima_init_ gets called in calculus.calculus and the classic interface gets initialized (not started, it is already initialized by default, so that is not really a big deal) 234 MaximaAbstract.__init__(self,"maxima_lib") 235 self.__seq = 0 647 236 648 237 def _coerce_from_special_method(self, x): 649 238 if isinstance(x, EclObject): 650 return Maxima Element(self,self._create(x))239 return MaximaLibElement(self,self._create(x)) 651 240 else: 652 return maxima_abstract.Maxima._coerce_from_special_method(self,x) 653 654 655 def _function_class(self): 656 """ 657 EXAMPLES:: 658 659 sage: maxima._function_class() 660 <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'> 661 """ 662 return MaximaExpectFunction 663 664 def _start(self): 665 """ 666 Starts the Maxima interpreter. 667 668 EXAMPLES:: 669 670 sage: m = Maxima() 671 sage: m.is_running() 672 False 673 sage: m._start() 674 sage: m.is_running() 675 True 676 """ 677 # ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))") 678 pass 241 return MaximaAbstract._coerce_from_special_method(self,x) 679 242 680 243 def __reduce__(self): 681 244 """ 682 245 EXAMPLES:: 683 246 684 sage: maxima.__reduce__() 685 (<function reduce_load_Maxima at 0x...>, ()) 247 sage: from sage.interfaces.maxima_lib import maxima_lib 248 sage: maxima_lib.__reduce__() 249 (<function reduce_load_MaximaLib at 0x...>, ()) 686 250 """ 687 return reduce_load_Maxima , tuple([])251 return reduce_load_MaximaLib, tuple([]) 688 252 689 def _sendline(self, str): 690 self._sendstr(str) 691 os.write(self._expect.child_fd, os.linesep) 692 693 def _expect_expr(self, expr=None, timeout=None): 694 """ 695 EXAMPLES: 696 sage: a,b=var('a,b') 697 sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 698 Traceback (most recent call last): 699 ... 700 RuntimeError: ECL says: Maxima asks:... 701 sage: assume(a>0) 702 sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 703 2/9*sqrt(3)*b^2*arctan(1/3*(2*(b*x + a)^(1/3) + a^(1/3))*sqrt(3)/a^(1/3))/a^(7/3) + 2/9*b^2*log((b*x + a)^(1/3) - a^(1/3))/a^(7/3) - 1/9*b^2*log((b*x + a)^(2/3) + (b*x + a)^(1/3)*a^(1/3) + a^(2/3))/a^(7/3) + 1/6*(4*(b*x + a)^(5/3)*b^2 - 7*(b*x + a)^(2/3)*a*b^2)/((b*x + a)^2*a^2 - 2*(b*x + a)*a^3 + a^4) 704 sage: var('x, n') 705 (x, n) 706 sage: integral(x^n,x) 707 Traceback (most recent call last): 708 ... 709 RuntimeError: ECL says: Maxima asks:... 710 sage: assume(n+1>0) 711 sage: integral(x^n,x) 712 x^(n + 1)/(n + 1) 713 sage: forget() 714 """ 715 if expr is None: 716 expr = self._prompt_wait 717 if self._expect is None: 718 self._start() 719 try: 720 if timeout: 721 i = self._expect.expect(expr,timeout=timeout) 722 else: 723 i = self._expect.expect(expr) 724 if i > 0: 725 v = self._expect.before 726 727 #We check to see if there is a "serious" error in Maxima. 728 #Note that this depends on the order of self._prompt_wait 729 if expr is self._prompt_wait and i > len(self._ask): 730 self.quit() 731 raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v 732 733 j = v.find('Is ') 734 v = v[j:] 735 k = v.find(' ',4) 736 msg = "Computation failed since Maxima requested additional constraints (try the command 'assume(" + v[4:k] +">0)' before integral or limit evaluation, for example):\n" + v + self._ask[i-1] 737 self._sendline(";") 738 self._expect_expr() 739 raise ValueError, msg 740 except KeyboardInterrupt, msg: 741 #print self._expect.before 742 i = 0 743 while True: 744 try: 745 print "Control-C pressed. Interrupting Maxima. Please wait a few seconds..." 746 self._sendstr('quit;\n'+chr(3)) 747 self._sendstr('quit;\n'+chr(3)) 748 self.interrupt() 749 self.interrupt() 750 except KeyboardInterrupt: 751 i += 1 752 if i > 10: 753 break 754 pass 755 else: 756 break 757 raise KeyboardInterrupt, msg 758 759 def _eval_line(self, line, allow_use_file=False, 760 wait_for_prompt=True, reformat=True, error_check=True): 253 # This outputs a string 254 def eval(self, line, locals=None, reformat=True, **kwds): 761 255 result = '' 762 256 while line: 763 257 ind_dollar=line.find("$") … … 769 263 else: 770 264 statement = line[:ind_semi] 771 265 line = line[ind_semi+1:] 772 if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement))266 if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement)) 773 267 else: 774 268 statement = line[:ind_dollar] 775 269 line = line[ind_dollar+1:] 776 if statement: _ = max_to_string(maxima_eval("#$%s$"%statement)) 777 return result 270 if statement: _ = maxima_eval("#$%s$"%statement) 271 if not reformat: 272 return result 273 return ''.join([x.strip() for x in result.split()]) 778 274 779 def _synchronize(self): 780 """ 781 Synchronize pexpect interface. 782 783 This put a random integer (plus one!) into the output stream, then 784 waits for it, thus resynchronizing the stream. If the random 785 integer doesn't appear within 1 second, maxima is sent interrupt 786 signals. 787 788 This way, even if you somehow left maxima in a busy state 789 computing, calling _synchronize gets everything fixed. 790 791 EXAMPLES: This makes Maxima start a calculation:: 792 793 sage: maxima._sendstr('1/1'*500) 794 795 When you type this command, this synchronize command is implicitly 796 called, and the above running calculation is interrupted:: 797 798 sage: maxima('2+2') 799 4 800 """ 801 marker = '__SAGE_SYNCHRO_MARKER_' 802 if self._expect is None: return 803 r = randrange(2147483647) 804 s = marker + str(r+1) 805 806 # The 0; *is* necessary... it comes up in certain rare cases 807 # that are revealed by extensive testing. Don't delete it. -- william stein 808 cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r) 809 self._sendstr(cmd) 810 try: 811 self._expect_expr(timeout=0.5) 812 if not s in self._before(): 813 self._expect_expr(s,timeout=0.5) 814 self._expect_expr(timeout=0.5) 815 except pexpect.TIMEOUT, msg: 816 self._interrupt() 817 except pexpect.EOF: 818 self._crash_msg() 819 self.quit() 275 _eval_line = eval 820 276 821 277 ########################################### 822 278 # Direct access to underlying lisp interpreter. … … 831 287 832 288 EXAMPLES:: 833 289 834 sage: maxima.lisp("(+ 2 17)") # random formatted output 835 :lisp (+ 2 17) 836 19 837 ( 290 sage: from sage.interfaces.maxima_lib import maxima_lib 291 sage: maxima_lib.lisp("(+ 2 17)") 292 <ECL: 19> 838 293 """ 839 self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False, wait_for_prompt=False, reformat=False, error_check=False) 840 self._expect_expr('(%i)') 841 return self._before() 842 843 ########################################### 844 # Interactive help 845 ########################################### 846 def _command_runner(self, command, s, redirect=True): 847 """ 848 Run ``command`` in a new Maxima session and return its 849 output as an ``AsciiArtString``. 850 851 If redirect is set to False, then the output of the command is not 852 returned as a string. Instead, it behaves like os.system. This is 853 used for interactive things like Maxima's demos. See maxima.demo? 854 855 EXAMPLES:: 856 857 sage: maxima._command_runner('describe', 'gcd') 858 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...) 859 ... 860 """ 861 cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s) 862 if sage.server.support.EMBEDDED_MODE: 863 cmd += '< /dev/null' 864 865 if redirect: 866 p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, 867 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 868 res = p.stdout.read() 869 # ecl-10.2 : 3 lines 870 # ecl-10.4 : 5 lines 871 # ecl-11.1 : 4 lines fancy a tango? 872 # We now get 4 lines of commented verbosity 873 # every time Maxima starts, so we need to get rid of them 874 for _ in range(4): 875 res = res[res.find('\n')+1:] 876 return AsciiArtString(res) 877 else: 878 subprocess.Popen(cmd, shell=True) 879 880 def _object_class(self): 881 """ 882 Return the Python class of Maxima elements. 883 884 EXAMPLES:: 885 886 sage: maxima._object_class() 887 <class 'sage.interfaces.maxima_abstract.MaximaElement'> 888 """ 889 return MaximaElement 890 891 def _function_element_class(self): 892 """ 893 EXAMPLES:: 894 895 sage: maxima._function_element_class() 896 <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'> 897 """ 898 return MaximaFunctionElement 899 900 def function(self, args, defn, rep=None, latex=None): 901 """ 902 Return the Maxima function with given arguments and definition. 903 904 INPUT: 905 906 907 - ``args`` - a string with variable names separated by 908 commas 909 910 - ``defn`` - a string (or Maxima expression) that 911 defines a function of the arguments in Maxima. 912 913 - ``rep`` - an optional string; if given, this is how 914 the function will print. 915 916 917 EXAMPLES:: 918 919 sage: f = maxima.function('x', 'sin(x)') 920 sage: f(3.2) 921 -.058374143427580... 922 sage: f = maxima.function('x,y', 'sin(x)+cos(y)') 923 sage: f(2,3.5) 924 sin(2)-.9364566872907963 925 sage: f 926 sin(x)+cos(y) 927 928 :: 929 930 sage: g = f.integrate('z') 931 sage: g 932 (cos(y)+sin(x))*z 933 sage: g(1,2,3) 934 3*(cos(2)+sin(1)) 935 936 The function definition can be a maxima object:: 937 938 sage: an_expr = maxima('sin(x)*gamma(x)') 939 sage: t = maxima.function('x', an_expr) 940 sage: t 941 gamma(x)*sin(x) 942 sage: t(2) 943 sin(2) 944 sage: float(t(2)) 945 0.90929742682568171 946 sage: loads(t.dumps()) 947 gamma(x)*sin(x) 948 """ 949 name = self._next_var_name() 950 if isinstance(defn, MaximaElement): 951 defn = defn.str() 952 elif not isinstance(defn, str): 953 defn = str(defn) 954 if isinstance(args, MaximaElement): 955 args = args.str() 956 elif not isinstance(args, str): 957 args = str(args) 958 cmd = '%s(%s) := %s'%(name, args, defn) 959 maxima._eval_line(cmd) 960 if rep is None: 961 rep = defn 962 f = MaximaFunction(self, name, rep, args, latex) 963 return f 294 return ecl_eval(cmd) 964 295 965 296 def set(self, var, value): 966 297 """ … … 976 307 977 308 EXAMPLES:: 978 309 979 sage: maxima.set('xxxxx', '2') 980 sage: maxima.get('xxxxx') 310 sage: from sage.interfaces.maxima_lib import maxima_lib 311 sage: maxima_lib.set('xxxxx', '2') 312 sage: maxima_lib.get('xxxxx') 981 313 '2' 982 314 """ 983 315 if not isinstance(value, str): 984 316 raise TypeError 985 317 cmd = '%s : %s$'%(var, value.rstrip(';')) 986 if len(cmd) > self.__eval_using_file_cutoff: 987 self._batch(cmd, batchload=True) 988 else: 989 self._eval_line(cmd) 990 #self._sendline(cmd) 991 #self._expect_expr() 992 #out = self._before() 993 #self._error_check(cmd, out) 318 self.eval(cmd) 994 319 995 320 def clear(self, var): 996 321 """ … … 998 323 999 324 EXAMPLES:: 1000 325 1001 sage: maxima.set('xxxxx', '2') 1002 sage: maxima.get('xxxxx') 326 sage: from sage.interfaces.maxima_lib import maxima_lib 327 sage: maxima_lib.set('xxxxx', '2') 328 sage: maxima_lib.get('xxxxx') 1003 329 '2' 1004 sage: maxima .clear('xxxxx')1005 sage: maxima .get('xxxxx')330 sage: maxima_lib.clear('xxxxx') 331 sage: maxima_lib.get('xxxxx') 1006 332 'xxxxx' 1007 333 """ 1008 334 try: 1009 self. _expect.send('kill(%s)$'%var)335 self.eval('kill(%s)$'%var) 1010 336 except (TypeError, AttributeError): 1011 337 pass 1012 338 1013 339 def get(self, var): 1014 340 """ … … 1016 342 1017 343 EXAMPLES:: 1018 344 1019 sage: maxima.set('xxxxx', '2') 1020 sage: maxima.get('xxxxx') 345 sage: from sage.interfaces.maxima_lib import maxima_lib 346 sage: maxima_lib.set('xxxxx', '2') 347 sage: maxima_lib.get('xxxxx') 1021 348 '2' 1022 349 """ 1023 s = self. _eval_line('%s;'%var)350 s = self.eval('%s;'%var) 1024 351 return s 1025 352 1026 353 def _create(self, value, name=None): … … 1030 357 else: 1031 358 self.set(name, value) 1032 359 return name 1033 1034 def version(self):360 361 def _function_class(self): 1035 362 """ 1036 Return the version of Maxima that Sage includes. 363 EXAMPLES:: 364 365 sage: from sage.interfaces.maxima_lib import maxima_lib 366 sage: maxima_lib._function_class() 367 <class 'sage.interfaces.maxima_lib.MaximaLibFunction'> 368 """ 369 return MaximaLibFunction 370 371 def _object_class(self): 372 """ 373 Return the Python class of Maxima elements. 1037 374 1038 375 EXAMPLES:: 1039 376 1040 sage: maxima.version() 1041 '5.23.2' 377 sage: from sage.interfaces.maxima_lib import maxima_lib 378 sage: maxima_lib._object_class() 379 <class 'sage.interfaces.maxima_lib.MaximaLibElement'> 1042 380 """ 1043 return maxima_version()381 return MaximaLibElement 1044 382 1045 ##some helper functions to wrap tha calculus use of the maxima interface. 1046 ##these routines expect arguments living in the symbolic ring and return something 1047 ##that is hopefully coercible into the symbolic ring again. 383 def _function_element_class(self): 384 """ 385 EXAMPLES:: 386 387 sage: from sage.interfaces.maxima_lib import maxima_lib 388 sage: maxima_lib._function_element_class() 389 <class 'sage.interfaces.maxima_lib.MaximaLibFunctionElement'> 390 """ 391 return MaximaLibFunctionElement 392 393 def _object_function_class(self): 394 """ 395 EXAMPLES:: 396 397 sage: from sage.interfaces.maxima_lib import maxima_lib 398 sage: maxima_lib._object_function_class() 399 <class 'sage.interfaces.maxima_lib.MaximaLibElementFunction'> 400 """ 401 return MaximaLibElementFunction 402 403 ##some helper functions to wrap the calculus use of the maxima interface. 404 ##these routines expect arguments living in the symbolic ring and return something 405 ##that is hopefully coercible into the symbolic ring again. 1048 406 1049 407 def sr_integral(self,*args): 1050 408 try: … … 1082 440 L.append(max_minus) 1083 441 return max_to_sr(maxima_eval(([max_tlimit],L))) 1084 442 1085 ## def display2d(self, flag=True):1086 ## """1087 ## Set the flag that determines whether Maxima objects are1088 ## printed using their 2-d ASCII art representation. When the1089 ## maxima interface starts the default is that objects are not1090 ## represented in 2-d.1091 443 1092 ## INPUT: 1093 ## flag -- bool (default: True) 444 def is_MaximaLibElement(x): 445 """ 446 Returns True if x is of type MaximaLibElement. 447 448 EXAMPLES:: 449 450 sage: from sage.interfaces.maxima_lib import maxima_lib, is_MaximaLibElement 451 sage: m = maxima_lib(1) 452 sage: is_MaximaLibElement(m) 453 True 454 sage: is_MaximaLibElement(1) 455 False 456 """ 457 return isinstance(x, MaximaLibElement) 1094 458 1095 ## EXAMPLES 1096 ## sage: maxima('1/2') 1097 ## 1/2 1098 ## sage: maxima.display2d(True) 1099 ## sage: maxima('1/2') 1100 ## 1 1101 ## - 1102 ## 2 1103 ## sage: maxima.display2d(False) 1104 ## """ 1105 ## self._display2d = bool(flag) 1106 1107 class MaximaElement(maxima_abstract.MaximaElement): 459 class MaximaLibElement(MaximaAbstractElement): 1108 460 """ 1109 461 """ 1110 462 def ecl(self): … … 1122 474 cmd=EclObject([[max_to_poly_solve], self.ecl(), sr_to_max(vars)]) 1123 475 return self.parent()(maxima_eval(cmd)) 1124 476 1125 def is_MaximaElement(x): 1126 """ 1127 Returns True if x is of type MaximaElement. 1128 1129 EXAMPLES:: 1130 1131 sage: from sage.interfaces.maxima import is_MaximaElement 1132 sage: m = maxima(1) 1133 sage: is_MaximaElement(m) 1134 True 1135 sage: is_MaximaElement(1) 1136 False 1137 """ 1138 return isinstance(x, MaximaElement) 477 def display2d(self, onscreen=True): 478 """ 479 EXAMPLES:: 480 481 sage: from sage.interfaces.maxima_lib import maxima_lib 482 sage: F = maxima_lib('x^5 - y^5').factor() 483 sage: F.display2d () 484 4 3 2 2 3 4 485 - (y - x) (y + x y + x y + x y + x ) 486 """ 487 self._check_valid() 488 P = self.parent() 489 P._eval_line('display2d : true$') 490 s = stdout_to_string('disp(%s)'%self.name()) 491 #s = P._eval_line('disp(%s)$'%self.name()) 492 P._eval_line('display2d : false$') 493 s = s.strip('\r\n') 1139 494 1140 # An instance 1141 maxima = Maxima() 495 # if ever want to dedent, see 496 # http://mail.python.org/pipermail/python-list/2006-December/420033.html 497 if onscreen: 498 print s 499 else: 500 return s 1142 501 1143 def reduce_load_Maxima(): 502 503 class MaximaLibFunctionElement(MaximaAbstractFunctionElement): 504 pass 505 506 507 class MaximaLibFunction(MaximaAbstractFunction): 508 pass 509 510 511 class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction): 512 pass 513 514 515 # The (unique) instance 516 maxima_lib = MaximaLib() 517 maxima = maxima_lib 518 519 520 def reduce_load_MaximaLib(): 1144 521 """ 1145 522 EXAMPLES:: 1146 523 1147 sage: from sage.interfaces.maxima import reduce_load_Maxima1148 sage: reduce_load_Maxima ()1149 Maxima 524 sage: from sage.interfaces.maxima_lib import reduce_load_MaximaLib 525 sage: reduce_load_MaximaLib() 526 Maxima_lib 1150 527 """ 1151 return maxima 528 return maxima_lib 1152 529 1153 1154 def maxima_version(): 1155 """ 1156 EXAMPLES:: 1157 1158 sage: from sage.interfaces.maxima import maxima_version 1159 sage: maxima_version() 1160 '5.23.2' 1161 """ 1162 return os.popen('maxima --version').read().split()[-1] 1163 1164 def __doctest_cleanup(): 1165 import sage.interfaces.quit 1166 sage.interfaces.quit.expect_quitall() 1167 1168 1169 import sage.symbolic.expression 1170 from sage.symbolic.ring import SR 530 #********************************** 531 # ??? 1171 532 1172 533 import sage.symbolic.expression 1173 534 import sage.functions.trig 1174 535 import sage.functions.log 1175 536 import sage.functions.other 1176 537 import sage.symbolic.integration.integral 538 from sage.symbolic.operators import FDerivativeOperator 1177 539 1178 540 car=EclObject("car") 1179 541 cdr=EclObject("cdr") … … 1187 549 NIL=EclObject("NIL") 1188 550 ratdisrep=EclObject("ratdisrep") 1189 551 1190 sage_op_dict={}1191 1192 552 sage_op_dict = { 1193 553 sage.symbolic.expression.operator.abs : "MABS", 1194 554 sage.symbolic.expression.operator.add : "MPLUS", … … 1223 583 sage.functions.other.erf : "%ERF", 1224 584 sage.functions.other.gamma_inc : "%GAMMA_INCOMPLETE" 1225 585 } 1226 1227 586 #we compile the dictionary 1228 587 sage_op_dict = dict([(k,EclObject(sage_op_dict[k])) for k in sage_op_dict]) 1229 588 max_op_dict = dict([(sage_op_dict[k],k) for k in sage_op_dict]) 589 1230 590 def add_vararg(*args): 1231 591 S=0 1232 592 for a in args: … … 1244 604 1245 605 mplus=EclObject("MPLUS") 1246 606 mtimes=EclObject("MTIMES") 607 mdiff=EclObject("%DERIVATIVE") 1247 608 rat=EclObject("RAT") 1248 609 max_i=EclObject("$%I") 1249 610 max_op_dict[mplus]=add_vararg … … 1290 651 else: 1291 652 return sage.symbolic.integration.integral.indefinite_integral(*args, hold=True) 1292 653 654 def mdiff_to_sage(expr): 655 return max_to_sr(expr.cadr()).diff(*[max_to_sr(e) for e in expr.cddr()]) 656 1293 657 special_max_to_sage={ 1294 658 EclObject("MRAT") : mrat_to_sage, 1295 EclObject("MQAPPLY") : mqapply_to_sage, 1296 EclObject("%INTEGRATE") : dummy_integrate 659 mqapply : mqapply_to_sage, 660 EclObject("%INTEGRATE") : dummy_integrate, 661 mdiff : mdiff_to_sage 1297 662 } 1298 663 1299 664 special_sage_to_max={ … … 1312 677 elif isinstance(obj,sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic) and obj.parent().defining_polynomial().list() == [1,0,1]: 1313 678 re, im = obj.list() 1314 679 return EclObject([[mplus], pyobject_to_max(re), [[mtimes], pyobject_to_max(im), max_i]]) 1315 1316 680 return EclObject(obj) 1317 681 682 # This goes from SR to EclObject 1318 683 def sr_to_max(expr): 1319 684 r""" 1320 685 """ … … 1324 689 return EclObject(([mlist],[sr_to_max(e) for e in expr])) 1325 690 op = expr.operator() 1326 691 if op: 1327 if (op in special_sage_to_max): 692 # Stolen from sage.symbolic.expression_conversion 693 # Should be defined in a function and then put in special_sage_to_max 694 # For that, we should change the API of the functions there (we need to have access to op, not only to expr.operands() 695 if isinstance(op, FDerivativeOperator): 696 from sage.symbolic.ring import is_SymbolicVariable 697 args = expr.operands() 698 if (not all(is_SymbolicVariable(v) for v in args) or 699 len(args) != len(set(args))): 700 raise NotImplementedError, "arguments must be distinct variables" 701 f = sr_to_max(op.function()(*args)) 702 params = op.parameter_set() 703 deriv_max = [] 704 [deriv_max.extend([sr_to_max(args[i]), EclObject(params.count(i))]) for i in set(params)] 705 l = [mdiff,f] 706 l.extend(deriv_max) 707 return EclObject(l) 708 elif (op in special_sage_to_max): 1328 709 return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()])) 1329 710 elif not (op in sage_op_dict): 1330 op_max=caar(maxima(expr).ecl()) 711 # Maxima does some simplifications automatically by default 712 # so calling maxima(expr) can change the structure of expr 713 #op_max=caar(maxima(expr).ecl()) 714 # This should be safe if we treated all special operators above 715 op_max=maxima(op).ecl() 1331 716 sage_op_dict[op]=op_max 1332 717 max_op_dict[op_max]=op 1333 718 return EclObject(([sage_op_dict[op]], … … 1344 729 except TypeError: 1345 730 return maxima(expr).ecl() 1346 731 732 # This goes from EclObject to SR 1347 733 def max_to_sr(expr): 1348 734 if expr.consp(): 1349 735 op_max=caar(expr) 1350 736 if op_max in special_max_to_sage: 1351 737 return special_max_to_sage[op_max](expr) 1352 738 if not(op_max in max_op_dict): 739 # This could be unsafe if the conversion to SR chenges the structure of expr 1353 740 sage_expr=SR(maxima(expr)) 1354 741 max_op_dict[op_max]=sage_expr.operator() 1355 742 sage_op_dict[sage_expr.operator()]=op_max 1356 743 op=max_op_dict[op_max] 1357 744 max_args=cdr(expr) 1358 args=[ 745 args=[max_to_sr(a) for a in max_args] 1359 746 return op(*args) 1360 747 elif expr.symbolp(): 1361 748 if not(expr in max_sym_dict): -
sage/structure/sage_object.pyx
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/structure/sage_object.pyx
a b 519 519 import sage.interfaces.maxima 520 520 I = sage.interfaces.maxima.maxima 521 521 return self._interface_init_(I) 522 523 def _maxima_lib_(self, G=None): 524 from sage.interfaces.maxima_lib import maxima_lib 525 return self._interface_(maxima_lib) 522 526 527 def _maxima_lib_init_(self): 528 return self._maxima_init_() 529 523 530 def _magma_init_(self, magma): 524 531 """ 525 532 Given a Magma interpreter M, return a string that evaluates in -
sage/symbolic/expression.pyx
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/symbolic/expression.pyx
a b 444 444 True 445 445 """ 446 446 if session is None: 447 # This chooses the Maxima interface used by calculus 448 # Maybe not such a great idea because the "default" interface is another one 447 449 from sage.calculus.calculus import maxima 448 450 return super(Expression, self)._interface_(maxima) 449 451 else: -
sage/symbolic/integration/external.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/symbolic/integration/external.py
a b 26 26 raise ValueError, "Integral is divergent." 27 27 else: 28 28 raise 29 return result 29 return result._sage_() 30 30 31 31 def sympy_integrator(expression, v, a=None, b=None): 32 32 """ -
sage/symbolic/integration/integral.py
diff -r df3ffca81588 -r 1d93d2e35ef6 sage/symbolic/integration/integral.py
a b 596 596 raise ValueError, "Unknown algorithm: %s" % algorithm 597 597 return integrator(expression, v, a, b) 598 598 599 600 599 if a is None: 601 600 return indefinite_integral(expression, v) 602 601 else: