Ticket #7377: trac_7377-split_and_refactor.patch
File trac_7377-split_and_refactor.patch, 167.1 KB (added by , 11 years ago) |
---|
-
sage/interfaces/expect.py
# HG changeset patch # User Jean-Pierre Flori <flori@enst.fr> # Date 1297688775 -3600 # Node ID b766df9c34391b224035c0f8e4a54524c59b0dfd # Parent a928dca2950bd0506e978caee270e9c1c059a560 Split Expect interface. diff -r a928dca2950b -r b766df9c3439 sage/interfaces/expect.py
a b 42 42 import time 43 43 import gc 44 44 import operator 45 import quit 46 import cleaner 45 47 from random import randrange 46 48 47 49 ######################################################## … … 51 53 ######################################################## 52 54 import pexpect 53 55 from pexpect import ExceptionPexpect 54 56 from sage.interfaces.interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement, AsciiArtString 55 57 56 58 from sage.structure.sage_object import SageObject 57 59 from sage.structure.parent_base import ParentWithBase 58 import sage.structure.element60 from sage.structure.element import RingElement 59 61 60 62 import sage.misc.sage_eval 61 62 import quit63 64 import cleaner65 66 import os67 68 63 from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE, LOCAL_IDENTIFIER 69 from sage.structure.element import RingElement70 71 64 from sage.misc.object_multiplexer import Multiplex 72 65 73 66 BAD_SESSION = -2 … … 142 135 gc.enable() 143 136 return False 144 137 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): 138 class Expect(Interface): 154 139 """ 155 140 Expect interface object. 156 141 """ … … 161 146 logfile = None, eval_using_file_cutoff=0, 162 147 do_cleaner = True, remote_cleaner = False, path=None): 163 148 149 Interface.__init__(self, name) 164 150 self.__is_remote = False 165 151 self.__remote_cleaner = remote_cleaner 166 152 if command == None: … … 188 174 self.__maxread = maxread 189 175 self._eval_using_file_cutoff = eval_using_file_cutoff 190 176 self.__script_subdirectory = script_subdirectory 191 self.__name = name192 self.__coerce_name = '_' + name.lower() + '_'193 177 self.__command = command 194 178 self._prompt = prompt 195 179 self._restart_on_ctrlc = restart_on_ctrlc … … 199 183 elif script_subdirectory is None: 200 184 self.__path = '.' 201 185 else: 202 self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT, self.__name,186 self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT,name, 203 187 self.__script_subdirectory) 204 188 self.__initialized = False 205 189 self.__seq = -1 … … 212 196 if isinstance(logfile, basestring): 213 197 logfile = open(logfile,'w') 214 198 self.__logfile = logfile 215 216 199 217 200 quit.expect_objects.append(weakref.ref(self)) 218 201 self._available_vars = [] 219 ParentWithBase.__init__(self, self)220 202 221 203 def _get(self, wait=0.1, alternate_prompt=None): 222 204 if self._expect is None: … … 286 268 def user_dir(self): 287 269 return self.__path 288 270 289 def _repr_(self):290 return self.__name.capitalize()291 292 271 def _change_prompt(self, prompt): 293 272 self._prompt = prompt 294 273 … … 299 278 # os.makedirs(T) 300 279 # return T + str(x) 301 280 302 def name(self, new_name=None):303 return self.__name304 305 281 def path(self): 306 282 return self.__path 307 283 … … 461 437 except (ExceptionPexpect, pexpect.EOF, IndexError): 462 438 self._expect = None 463 439 self._session_number = BAD_SESSION 464 failed_to_start.append( self.__name)440 failed_to_start.append(name()) 465 441 raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%( 466 self.__name, cmd, self._install_hints())442 name(), cmd, self._install_hints()) 467 443 468 444 os.chdir(current_path) 469 445 self._expect.timeout = self.__max_startup_time … … 476 452 except (pexpect.TIMEOUT, pexpect.EOF), msg: 477 453 self._expect = None 478 454 self._session_number = BAD_SESSION 479 failed_to_start.append( self.__name)480 raise RuntimeError, "Unable to start %s"% self.__name455 failed_to_start.append(name()) 456 raise RuntimeError, "Unable to start %s"%name() 481 457 self._expect.timeout = None 482 458 with gc_disabled(): 483 459 if block_during_init: … … 1056 1032 except TypeError, s: 1057 1033 raise TypeError, 'error evaluating "%s":\n%s'%(code,s) 1058 1034 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 _assign_symbol(self):1176 return "="1177 1178 def _equality_symbol(self):1179 raise NotImplementedError1180 1181 # For efficiency purposes, you should definitely override these1182 # in your derived class.1183 def _true_symbol(self):1184 try:1185 return self.__true_symbol1186 except AttributeError:1187 self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol())1188 1189 def _false_symbol(self):1190 try:1191 return self.__false_symbol1192 except AttributeError:1193 self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol())1194 1195 def _lessthan_symbol(self):1196 return '<'1197 1198 def _greaterthan_symbol(self):1199 return '>'1200 1201 def _inequality_symbol(self):1202 return '!='1203 1204 def _relation_symbols(self):1205 """1206 Returns a dictionary with operators as the keys and their1207 string representation as the values.1208 1209 EXAMPLES::1210 1211 sage: import operator1212 sage: symbols = mathematica._relation_symbols()1213 sage: symbols[operator.eq]1214 '=='1215 """1216 return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()),1217 (operator.lt, self._lessthan_symbol()), (operator.le, "<="),1218 (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")])1219 1220 def _exponent_symbol(self):1221 """1222 Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e61223 1224 EXAMPLES::1225 1226 sage: from sage.interfaces.expect import Expect1227 sage: Expect('nonexistent_interface', 'fake')._exponent_symbol()1228 'e'1229 """1230 return 'e'1231 1232 1035 ############################################################ 1233 1036 # Functions for working with variables. 1234 1037 # The first three must be overloaded by derived classes, … … 1236 1039 # the functionality one gets from this is very nice. 1237 1040 ############################################################ 1238 1041 1239 def set(self, var, value):1240 """1241 Set the variable var to the given value.1242 """1243 cmd = '%s%s%s;'%(var,self._assign_symbol(), value)1244 self.eval(cmd)1245 1246 def get(self, var):1247 """1248 Get the value of the variable var.1249 """1250 return self.eval(var)1251 1252 def get_using_file(self, var):1253 r"""1254 Return the string representation of the variable var in self,1255 possibly using a file. Use this if var has a huge string1256 representation, since it may be way faster.1257 1258 .. warning::1259 1260 In fact unless a special derived class implements this, it1261 will *not* be any faster. This is the case for this class1262 if you're reading it through introspection and seeing this.1263 """1264 return self.get(var)1265 1266 def clear(self, var):1267 """1268 Clear the variable named var.1269 """1270 self._available_vars.append(var)1271 1272 def _next_var_name(self):1273 if len(self._available_vars) != 0:1274 v = self._available_vars[0]1275 del self._available_vars[0]1276 return v1277 self.__seq += 11278 return "sage%s"%self.__seq1279 1280 def _create(self, value, name=None):1281 name = self._next_var_name() if name is None else name1282 self.set(name, value)1283 return name1284 1285 1042 def _object_class(self): 1286 1043 """ 1287 1044 EXAMPLES:: … … 1311 1068 <class 'sage.interfaces.expect.FunctionElement'> 1312 1069 """ 1313 1070 return FunctionElement 1071 1314 1072 1315 def _convert_args_kwds(self, args=None, kwds=None): 1316 """ 1317 Converts all of the args and kwds to be elements of this 1318 interface. 1319 1320 EXAMPLES:: 1321 1322 sage: args = [5] 1323 sage: kwds = {'x': 6} 1324 sage: args, kwds = gap._convert_args_kwds(args, kwds) 1325 sage: args 1326 [5] 1327 sage: map(type, args) 1328 [<class 'sage.interfaces.gap.GapElement'>] 1329 sage: type(kwds['x']) 1330 <class 'sage.interfaces.gap.GapElement'> 1331 """ 1332 args = [] if args is None else args 1333 kwds = {} if kwds is None else kwds 1334 if not isinstance(args, list): 1335 args = [args] 1336 for i, arg in enumerate(args): 1337 if not isinstance(arg, ExpectElement) or arg.parent() is not self: 1338 args[i] = self(arg) 1339 for key, value in kwds.iteritems(): 1340 if not isinstance(value, ExpectElement) or value.parent() is not self: 1341 kwds[key] = self(value) 1342 1343 return args, kwds 1344 1345 def _check_valid_function_name(self, function): 1346 """ 1347 Checks to see if function is a valid function name in this 1348 interface. If it is not, an exception is raised. Otherwise, nothing 1349 is done. 1350 1351 EXAMPLES:: 1352 1353 sage: gap._check_valid_function_name('SymmetricGroup') 1354 sage: gap._check_valid_function_name('') 1355 Traceback (most recent call last): 1356 ... 1357 ValueError: function name must be nonempty 1358 sage: gap._check_valid_function_name('__foo') 1359 Traceback (most recent call last): 1360 ... 1361 AttributeError 1362 """ 1363 if function == '': 1364 raise ValueError, "function name must be nonempty" 1365 if function[:2] == "__": 1366 raise AttributeError 1367 1368 def function_call(self, function, args=None, kwds=None): 1369 """ 1370 EXAMPLES:: 1371 1372 sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) 1373 [0.5,5.5511151231257...e-15,21,0] 1374 sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) 1375 [0.5,5.5511151231257...e-15,21,0] 1376 """ 1377 args, kwds = self._convert_args_kwds(args, kwds) 1378 self._check_valid_function_name(function) 1379 s = self._function_call_string(function, 1380 [s.name() for s in args], 1381 ['%s=%s'%(key,value.name()) for key, value in kwds.items()]) 1382 return self.new(s) 1383 1384 def _function_call_string(self, function, args, kwds): 1385 """ 1386 Returns the string used to make function calls. 1387 1388 EXAMPLES:: 1389 1390 sage: maxima._function_call_string('diff', ['f(x)', 'x'], []) 1391 'diff(f(x),x)' 1392 """ 1393 return "%s(%s)"%(function, ",".join(list(args) + list(kwds))) 1394 1395 def call(self, function_name, *args, **kwds): 1396 return self.function_call(function_name, args, kwds) 1397 1398 def _contains(self, v1, v2): 1399 raise NotImplementedError 1400 1401 def __getattr__(self, attrname): 1402 """ 1403 TESTS:: 1404 1405 sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_') 1406 <built-in method _coerce_map_from_ of Singular object at ...> 1407 """ 1408 try: 1409 return ParentWithBase.__getattribute__(self, attrname) 1410 except AttributeError: 1411 if attrname[:1] == "_": 1412 raise AttributeError 1413 return self._function_class()(self, attrname) 1414 1415 def __cmp__(self, other): 1416 """ 1417 Compare two pseudo-tty interfaces. Two interfaces compare 1418 equal if and only if they are identical objects (this is a 1419 critical constraint so that caching of representations of 1420 objects in interfaces works correctly). Otherwise they are 1421 never equal. 1422 1423 EXAMPLES:: 1424 1425 sage: Maxima() == maxima 1426 False 1427 sage: maxima == maxima 1428 True 1429 """ 1430 if self is other: 1431 return 0 1432 c = cmp(type(self), type(other)) 1433 if c: 1434 return c 1435 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. 1436 1437 def console(self): 1438 raise NotImplementedError 1439 1440 def help(self, s): 1441 return AsciiArtString('No help on %s available'%s) 1442 1443 1444 class ExpectFunction(SageObject): 1073 class ExpectFunction(InterfaceFunction): 1445 1074 """ 1446 1075 Expect function. 1447 1076 """ 1448 def __init__(self, parent, name): 1449 self._parent = parent 1450 self._name = name 1451 1452 def __repr__(self): 1453 return "%s"%self._name 1454 1455 def __call__(self, *args, **kwds): 1456 return self._parent.function_call(self._name, list(args), kwds) 1457 1458 def _sage_doc_(self): 1459 """ 1460 EXAMPLES:: 1461 1462 sage: gp.gcd._sage_doc_() 1463 'gcd(x,{y}): greatest common divisor of x and y.' 1464 """ 1465 M = self._parent 1466 return M.help(self._name) 1467 1077 pass 1468 1078 1469 1079 1470 1471 class FunctionElement(SageObject): 1080 class FunctionElement(InterfaceFunctionElement): 1472 1081 """ 1473 1082 Expect function element. 1474 1083 """ 1475 def __init__(self, obj, name): 1476 self._obj = obj 1477 self._name = name 1084 pass 1478 1085 1479 def __repr__(self):1480 return "%s"%self._name1481 1482 def __call__(self, *args, **kwds):1483 return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds)1484 1485 def help(self):1486 print self._sage_doc_()1487 1488 def _sage_doc_(self):1489 """1490 EXAMPLES::1491 1492 sage: gp(2).gcd._sage_doc_()1493 'gcd(x,{y}): greatest common divisor of x and y.'1494 """1495 M = self._obj.parent()1496 return M.help(self._name)1497 1086 1498 1087 1499 1088 def is_ExpectElement(x): 1500 1089 return isinstance(x, ExpectElement) 1501 1090 1502 1503 1504 class ExpectElement(RingElement): 1091 class ExpectElement(InterfaceElement): 1505 1092 """ 1506 1093 Expect element. 1507 1094 """ … … 1526 1113 raise TypeError, x 1527 1114 self._session_number = parent._session_number 1528 1115 1529 def _latex_(self):1530 # return "\\begin{verbatim}%s\\end{verbatim}"%self1531 string = str(self)1532 if not '|' in string:1533 delim = '|'1534 elif not '#' in string:1535 delim = '#'1536 elif not '@' in string:1537 delim = '@'1538 elif not '~' in string:1539 delim = '~'1540 return "\\verb%s%s%s"%(delim, string, delim)1541 1542 def __iter__(self):1543 for i in range(1, len(self)+1):1544 yield self[i]1545 1546 def __len__(self):1547 """1548 Call self.sage() and return the length of that sage object.1549 1550 This approach is inefficient - each interface should override1551 this method with one that calls the external program's length1552 function.1553 1554 EXAMPLES::1555 1556 sage: len(gp([1,2,3]))1557 31558 1559 AUTHORS:1560 1561 - Felix Lawrence (2009-08-21)1562 """1563 return len(self.sage())1564 1565 def __reduce__(self):1566 return reduce_load, (self.parent(), self._reduce())1567 1568 def _reduce(self):1569 return repr(self)1570 1571 def __call__(self, *args):1572 self._check_valid()1573 P = self.parent()1574 return getattr(P, self.name())(*args)1575 1576 def __contains__(self, x):1577 P = self._check_valid()1578 if not isinstance(x, ExpectElement) or x.parent() is not self.parent():1579 x = P.new(x)1580 return P._contains(x.name(), self.name())1581 1582 1583 def _sage_doc_(self):1584 """1585 EXAMPLES::1586 1587 sage: gp(2)._sage_doc_()1588 '2'1589 """1590 return str(self)1591 1592 1116 def __hash__(self): 1593 1117 """ 1594 1118 Returns the hash of self. This is a default implementation of hash … … 1596 1120 """ 1597 1121 return hash('%s%s'%(self, self._session_number)) 1598 1122 1599 def __cmp__(self, other):1600 P = self.parent()1601 if P.eval("%s %s %s"%(self.name(), P._equality_symbol(),1602 other.name())) == P._true_symbol():1603 return 01604 elif P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol():1605 return -11606 elif P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol():1607 return 11608 1609 # everything is supposed to be comparable in Python, so we define1610 # the comparison thus when no comparison is available in interfaced system.1611 if (hash(self) < hash(other)):1612 return -11613 else:1614 return 11615 1616 def _matrix_(self, R):1617 raise NotImplementedError1618 1619 def _vector_(self, R):1620 raise NotImplementedError1621 1123 1622 1124 def _check_valid(self): 1623 1125 """ … … 1650 1152 #print msg 1651 1153 pass 1652 1154 1653 def _sage_repr(self): 1654 """ 1655 Return a sage-friendly string representation of the object. 1656 1657 Some programs use different notation to Sage, e.g. Mathematica 1658 writes lists with {} instead of []. This method calls repr(self) 1659 then converts the foreign notation into Sage's notation. 1660 1661 OUTPUT: 1662 1663 A string representation of the object that is ready for 1664 sage_eval(). 1665 1666 EXAMPLES:: 1667 1668 sage: repr(mathematica([1,2,3])) # optional - mathematica 1669 '{1, 2, 3}' 1670 sage: mathematica([1,2,3])._sage_repr() # optional - mathematica 1671 '[1, 2, 3]' 1672 1673 :: 1674 1675 sage: gp(10.^80)._sage_repr() 1676 '1.0000000000000000000000000000000000000e80' # 64-bit 1677 '1.000000000000000000000000000e80' # 32-bit 1678 sage: mathematica('10.^80')._sage_repr() # optional - mathematica 1679 '1.e80' 1680 1681 AUTHORS: 1682 1683 - Felix Lawrence (2009-08-21) 1684 """ 1685 #TO DO: this could use file transfers when self.is_remote() 1686 1687 string = repr(self).replace('\n',' ').replace('\r', '') 1688 # Translate the external program's list formatting to Sage's 1689 lld = self.parent()._left_list_delim() 1690 if '[' != lld: string = string.replace(lld, '[') 1691 rld = self.parent()._right_list_delim() 1692 if ']' != rld: string = string.replace(rld, ']') 1693 # Translate the external program's exponent formatting 1694 expl = self.parent()._exponent_symbol() 1695 if 'e' != expl: string = string.replace(expl, 'e') 1696 return string 1155 # def _sage_repr(self): 1156 #TO DO: this could use file transfers when self.is_remote() 1697 1157 1698 def _sage_(self):1699 """1700 Attempt to return a Sage version of this object.1701 This is a generic routine that just tries to evaluate1702 the repr(self).1703 1704 EXAMPLES::1705 1706 sage: gp(1/2)._sage_()1707 1/21708 sage: _.parent()1709 Rational Field1710 1711 AUTHORS:1712 1713 - William Stein1714 1715 - Felix Lawrence (2009-08-21)1716 """1717 try:1718 return sage.misc.sage_eval.sage_eval(self._sage_repr())1719 except:1720 raise NotImplementedError1721 1722 1723 def sage(self):1724 """1725 Attempt to return a Sage version of this object.1726 1727 EXAMPLES::1728 1729 sage: gp(1/2).sage()1730 1/21731 sage: _.parent()1732 Rational Field1733 """1734 return self._sage_()1735 1158 1736 1159 def __repr__(self): 1737 1160 self._check_valid() … … 1745 1168 s = s.replace(self._name, self.__dict__['__custom_name']) 1746 1169 return s 1747 1170 1748 def __getattr__(self, attrname):1749 P = self._check_valid()1750 if attrname[:1] == "_":1751 raise AttributeError1752 return P._function_element_class()(self, attrname)1753 1754 1171 def get_using_file(self): 1755 1172 """ 1756 1173 Return this element's string representation using a file. Use this … … 1767 1184 except ValueError: 1768 1185 return '(invalid object -- defined in terms of closed session)' 1769 1186 return self.parent().get_using_file(self._name) 1770 1771 def hasattr(self, attrname):1772 """1773 Returns whether the given attribute is already defined by this1774 object, and in particular is not dynamically generated.1775 1776 EXAMPLES::1777 1778 sage: m = maxima('2')1779 sage: m.hasattr('integral')1780 True1781 sage: m.hasattr('gcd')1782 False1783 """1784 return not isinstance(getattr(self, attrname), FunctionElement)1785 1786 def attribute(self, attrname):1787 """1788 If this wraps the object x in the system, this returns the object1789 x.attrname. This is useful for some systems that have object1790 oriented attribute access notation.1791 1792 EXAMPLES::1793 1794 sage: g = gap('SO(1,4,7)')1795 sage: k = g.InvariantQuadraticForm()1796 sage: k.attribute('matrix')1797 [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ],1798 [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ]1799 1800 ::1801 1802 sage: e = gp('ellinit([0,-1,1,-10,-20])')1803 sage: e.attribute('j')1804 -122023936/1610511805 """1806 P = self._check_valid()1807 return P('%s.%s'%(self.name(), attrname))1808 1809 def __getitem__(self, n):1810 P = self._check_valid()1811 if not isinstance(n, tuple):1812 return P.new('%s[%s]'%(self._name, n))1813 else:1814 return P.new('%s[%s]'%(self._name, str(n)[1:-1]))1815 1187 1816 def __int__(self):1817 """1818 EXAMPLES::1819 1820 sage: int(maxima('1'))1821 11822 sage: type(_)1823 <type 'int'>1824 """1825 return int(repr(self))1826 1827 def bool(self):1828 P = self.parent()1829 t = P._true_symbol()1830 cmd = '%s %s %s'%(self._name, P._equality_symbol(), t)1831 return P.eval(cmd) == t1832 1833 def __nonzero__(self):1834 """1835 EXAMPLES::1836 1837 sage: bool(maxima(0))1838 False1839 sage: bool(maxima(1))1840 True1841 """1842 return self.bool()1843 1844 def __long__(self):1845 """1846 EXAMPLES::1847 1848 sage: m = maxima('1')1849 sage: long(m)1850 1L1851 """1852 return long(repr(self))1853 1854 def __float__(self):1855 """1856 EXAMPLES::1857 1858 sage: m = maxima('1/2')1859 sage: m.__float__()1860 0.51861 sage: float(m)1862 0.51863 """1864 return float(repr(self))1865 1866 def _integer_(self, ZZ=None):1867 """1868 EXAMPLES::1869 1870 sage: m = maxima('1')1871 sage: m._integer_()1872 11873 sage: _.parent()1874 Integer Ring1875 sage: QQ(m)1876 11877 """1878 import sage.rings.all1879 return sage.rings.all.Integer(repr(self))1880 1881 def _rational_(self):1882 """1883 EXAMPLES::1884 1885 sage: m = maxima('1/2')1886 sage: m._rational_()1887 1/21888 sage: _.parent()1889 Rational Field1890 sage: QQ(m)1891 1/21892 """1893 import sage.rings.all1894 return sage.rings.all.Rational(repr(self))1895 1896 def name(self, new_name=None):1897 """1898 Returns the name of self. If new_name is passed in, then this1899 function returns a new object identical to self whose name is1900 new_name.1901 1902 Note that this can overwrite existing variables in the system.1903 1904 EXAMPLES::1905 1906 sage: x = r([1,2,3]); x1907 [1] 1 2 31908 sage: x.name()1909 'sage3'1910 sage: x = r([1,2,3]).name('x'); x1911 [1] 1 2 31912 sage: x.name()1913 'x'1914 1915 ::1916 1917 sage: s5 = gap.SymmetricGroup(5).name('s5')1918 sage: s51919 SymmetricGroup( [ 1 .. 5 ] )1920 sage: s5.name()1921 's5'1922 """1923 if new_name is not None:1924 if not isinstance(new_name, str):1925 raise TypeError, "new_name must be a string"1926 p = self.parent()1927 p.set(new_name, self._name)1928 return p._object_class()(p, new_name, is_name=True)1929 1930 return self._name1931 1932 def gen(self, n):1933 P = self._check_valid()1934 return P.new('%s.%s'%(self._name, int(n)))1935 1936 def _operation(self, operation, right):1937 P = self._check_valid()1938 try:1939 return P.new('%s %s %s'%(self._name, operation, right._name))1940 except Exception, msg:1941 raise TypeError, msg1942 1943 def _add_(self, right):1944 """1945 EXAMPLES::1946 1947 sage: f = maxima.cos(x)1948 sage: g = maxima.sin(x)1949 sage: f + g1950 sin(x)+cos(x)1951 sage: f + 21952 cos(x)+21953 sage: 2 + f1954 cos(x)+21955 """1956 return self._operation("+", right)1957 1958 def _sub_(self, right):1959 """1960 EXAMPLES::1961 1962 sage: f = maxima.cos(x)1963 sage: g = maxima.sin(x)1964 sage: f - g1965 cos(x)-sin(x)1966 sage: f - 21967 cos(x)-21968 sage: 2 - f1969 2-cos(x)1970 """1971 return self._operation('-', right)1972 1973 def _mul_(self, right):1974 """1975 EXAMPLES::1976 1977 sage: f = maxima.cos(x)1978 sage: g = maxima.sin(x)1979 sage: f*g1980 cos(x)*sin(x)1981 sage: 2*f1982 2*cos(x)1983 """1984 return self._operation('*', right)1985 1986 def _div_(self, right):1987 """1988 EXAMPLES::1989 1990 sage: f = maxima.cos(x)1991 sage: g = maxima.sin(x)1992 sage: f/g1993 cos(x)/sin(x)1994 sage: f/21995 cos(x)/21996 """1997 return self._operation("/", right)1998 1999 def __pow__(self, n):2000 """2001 EXAMPLES::2002 2003 sage: a = maxima('2')2004 sage: a^(3/4)2005 2^(3/4)2006 """2007 P = self._check_valid()2008 if not hasattr(n, 'parent') or P is not n.parent():2009 n = P(n)2010 return self._operation("^", n)2011 2012 1188 2013 1189 class StdOutContext: 2014 1190 """ … … 2034 1210 sage: with StdOutContext(gp): 2035 1211 ... gp('1+1') 2036 1212 ... 2037 sage [...1213 sage=... 2038 1214 """ 2039 1215 self.interface = interface 2040 1216 self.silent = silent … … 2076 1252 self.stdout.write("\n") 2077 1253 self.interface._expect.logfile = self._logfile_backup 2078 1254 2079 def reduce_load(parent, x):2080 return parent(x)2081 2082 1255 import os 2083 1256 def console(cmd): 2084 1257 os.system(cmd) -
sage/interfaces/gap.py
diff -r a928dca2950b -r b766df9c3439 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 a928dca2950b -r b766df9c3439 sage/interfaces/interface.py
- + 1 """ 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 from sage.misc.sage_eval import 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 61 self.__name = name 62 self.__coerce_name = '_' + name.lower() + '_' 63 self.__seq = -1 64 self._available_vars = [] 65 ParentWithBase.__init__(self, self) 66 67 def _repr_(self): 68 return self.__name.capitalize() 69 70 def name(self, new_name=None): 71 return self.__name 72 73 def interact(self): 74 r""" 75 This allows you to interactively interact with the child 76 interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and 77 return to Sage. 78 79 .. note:: 80 81 This is completely different than the console() member 82 function. The console function opens a new copy of the 83 child interpreter, whereas the interact function gives you 84 interactive access to the interpreter that is being used by 85 Sage. Use sage(xxx) or interpretername(xxx) to pull objects 86 in from sage to the interpreter. 87 """ 88 import sage.misc.preparser_ipython 89 sage.misc.preparser_ipython.switch_interface_general(self) 90 91 def _pre_interact(self): 92 pass 93 94 def _post_interact(self): 95 pass 96 97 def __del__(self): 98 pass 99 100 def read(self, filename): 101 r""" 102 EXAMPLES:: 103 104 sage: filename = tmp_filename() 105 sage: f = open(filename, 'w') 106 sage: f.write('x = 2\n') 107 sage: f.close() 108 sage: octave.read(filename) #optional -- requires Octave 109 sage: octave.get('x') #optional 110 ' 2' 111 sage: import os 112 sage: os.unlink(filename) 113 """ 114 self.eval(self._read_in_file_command(filename)) 115 116 def _read_in_file_command(self, filename): 117 raise NotImplementedError 118 119 def eval(self, code, locals=None, **kwds): 120 """ 121 INPUT: 122 123 124 - ``code`` - text to evaluate 125 126 - ``locals`` - None (ignored); this is used for compatibility with the 127 Sage notebook's generic system interface. 128 129 - ``**kwds`` - All other arguments are passed onto 130 the _eval_line method. An often useful example is 131 reformat=False. 132 """ 133 134 if not isinstance(code, basestring): 135 raise TypeError, 'input code must be a string.' 136 137 #Remove extra whitespace 138 code = code.strip() 139 140 try: 141 pass 142 except KeyboardInterrupt: 143 # DO NOT CATCH KeyboardInterrupt, as it is being caught 144 # by _eval_line 145 # In particular, do NOT call self._keyboard_interrupt() 146 raise 147 except TypeError, s: 148 raise TypeError, 'error evaluating "%s":\n%s'%(code,s) 149 150 def execute(self, *args, **kwds): 151 return self.eval(*args, **kwds) 152 153 def __call__(self, x, name=None): 154 155 r""" 156 Create a new object in self from x. 157 158 The object X returned can be used like any Sage object, and 159 wraps an object in self. The standard arithmetic operators 160 work. Moreover if foo is a function then 161 X.foo(y,z,...) 162 calls foo(X, y, z, ...) and returns the corresponding object. 163 164 EXAMPLES:: 165 166 sage: gp(2) 167 2 168 sage: gp('2') 169 2 170 sage: a = gp(2); gp(a) is a 171 True 172 173 """ 174 cls = self._object_class() 175 176 #Handle the case when x is an object 177 #in some interface. 178 if isinstance(x, InterfaceElement): 179 if x.parent() is self: 180 return x 181 182 #We convert x into an object in this 183 #interface by first going through Sage. 184 try: 185 return self(x._sage_()) 186 except (NotImplementedError, TypeError): 187 pass 188 189 if isinstance(x, basestring): 190 return cls(self, x, name=name) 191 try: 192 return self._coerce_from_special_method(x) 193 except TypeError: 194 raise 195 except AttributeError, msg: 196 pass 197 try: 198 return self._coerce_impl(x, use_special=False) 199 except TypeError, msg: 200 try: 201 return cls(self, str(x), name=name) 202 except TypeError, msg2: 203 raise TypeError, msg 204 205 def _coerce_from_special_method(self, x): 206 """ 207 Tries to coerce to self by calling a special underscore method. 208 209 If no such method is defined, raises an AttributeError instead of a 210 TypeError. 211 """ 212 s = '_%s_'%self.name() 213 if s == '_pari_': 214 s = '_gp_' 215 try: 216 return (x.__getattribute__(s))(self) 217 except AttributeError: 218 return self(x._interface_init_()) 219 220 def _coerce_impl(self, x, use_special=True): 221 if isinstance(x, (int, long)): 222 import sage.rings.all 223 return self(sage.rings.all.Integer(x)) 224 elif isinstance(x, float): 225 import sage.rings.all 226 return self(sage.rings.all.RDF(x)) 227 if use_special: 228 try: 229 return self._coerce_from_special_method(x) 230 except AttributeError, msg: 231 pass 232 233 if isinstance(x, (list, tuple)): 234 A = [] 235 z = [] 236 cls = self._object_class() 237 for v in x: 238 if isinstance(v, cls): 239 A.append(v.name()) 240 z.append(v) 241 else: 242 w = self(v) 243 A.append(w.name()) 244 z.append(w) 245 X = ','.join(A) 246 r = self.new('%s%s%s'%(self._left_list_delim(), X, self._right_list_delim())) 247 r.__sage_list = z # do this to avoid having the entries of the list be garbage collected 248 return r 249 250 raise TypeError, "unable to coerce element into %s"%self.name() 251 252 def new(self, code): 253 return self(code) 254 255 ################################################################### 256 # these should all be appropriately overloaded by the derived class 257 ################################################################### 258 259 def _left_list_delim(self): 260 return "[" 261 262 def _right_list_delim(self): 263 return "]" 264 265 def _assign_symbol(self): 266 return "=" 267 268 def _equality_symbol(self): 269 raise NotImplementedError 270 271 # For efficiency purposes, you should definitely override these 272 # in your derived class. 273 def _true_symbol(self): 274 try: 275 return self.__true_symbol 276 except AttributeError: 277 self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol()) 278 279 def _false_symbol(self): 280 try: 281 return self.__false_symbol 282 except AttributeError: 283 self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol()) 284 285 def _lessthan_symbol(self): 286 return '<' 287 288 def _greaterthan_symbol(self): 289 return '>' 290 291 def _inequality_symbol(self): 292 return '!=' 293 294 def _relation_symbols(self): 295 """ 296 Returns a dictionary with operators as the keys and their 297 string representation as the values. 298 299 EXAMPLES:: 300 301 sage: import operator 302 sage: symbols = mathematica._relation_symbols() 303 sage: symbols[operator.eq] 304 '==' 305 """ 306 return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()), 307 (operator.lt, self._lessthan_symbol()), (operator.le, "<="), 308 (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")]) 309 310 def _exponent_symbol(self): 311 """ 312 Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e6 313 314 EXAMPLES:: 315 316 sage: from sage.interfaces.expect import Expect 317 sage: Expect('nonexistent_interface', 'fake')._exponent_symbol() 318 'e' 319 """ 320 return 'e' 321 322 ############################################################ 323 # Functions for working with variables. 324 # The first three must be overloaded by derived classes, 325 # and the definition depends a lot on the class. But 326 # the functionality one gets from this is very nice. 327 ############################################################ 328 329 def set(self, var, value): 330 """ 331 Set the variable var to the given value. 332 """ 333 cmd = '%s%s%s;'%(var,self._assign_symbol(), value) 334 self.eval(cmd) 335 336 def get(self, var): 337 """ 338 Get the value of the variable var. 339 """ 340 return self.eval(var) 341 342 def get_using_file(self, var): 343 r""" 344 Return the string representation of the variable var in self, 345 possibly using a file. Use this if var has a huge string 346 representation, since it may be way faster. 347 348 .. warning:: 349 350 In fact unless a special derived class implements this, it 351 will *not* be any faster. This is the case for this class 352 if you're reading it through introspection and seeing this. 353 """ 354 return self.get(var) 355 356 def clear(self, var): 357 """ 358 Clear the variable named var. 359 """ 360 self._available_vars.append(var) 361 362 def _next_var_name(self): 363 if len(self._available_vars) != 0: 364 v = self._available_vars[0] 365 del self._available_vars[0] 366 return v 367 self.__seq += 1 368 return "sage%s"%self.__seq 369 370 def _create(self, value, name=None): 371 name = self._next_var_name() if name is None else name 372 self.set(name, value) 373 return name 374 375 def _object_class(self): 376 """ 377 EXAMPLES:: 378 379 sage: from sage.interfaces.expect import Expect 380 sage: Expect._object_class(maxima) 381 <class 'sage.interfaces.expect.ExpectElement'> 382 """ 383 return InterfaceElement 384 385 def _function_class(self): 386 """ 387 EXAMPLES:: 388 389 sage: from sage.interfaces.interface import Interface 390 sage: Interface._function_class(maxima) 391 <class 'sage.interfaces.interface.InterfaceFunction'> 392 """ 393 return InterfaceFunction 394 395 def _function_element_class(self): 396 """ 397 EXAMPLES:: 398 399 sage: from sage.interfaces.interface import Interface 400 sage: Interface._function_element_class(maxima) 401 <class 'sage.interfaces.interface.InterfaceFunctionElement'> 402 """ 403 return InterfaceFunctionElement 404 405 def _convert_args_kwds(self, args=None, kwds=None): 406 """ 407 Converts all of the args and kwds to be elements of this 408 interface. 409 410 EXAMPLES:: 411 412 sage: args = [5] 413 sage: kwds = {'x': 6} 414 sage: args, kwds = gap._convert_args_kwds(args, kwds) 415 sage: args 416 [5] 417 sage: map(type, args) 418 [<class 'sage.interfaces.gap.GapElement'>] 419 sage: type(kwds['x']) 420 <class 'sage.interfaces.gap.GapElement'> 421 """ 422 args = [] if args is None else args 423 kwds = {} if kwds is None else kwds 424 if not isinstance(args, list): 425 args = [args] 426 for i, arg in enumerate(args): 427 if not isinstance(arg, InterfaceElement) or arg.parent() is not self: 428 args[i] = self(arg) 429 for key, value in kwds.iteritems(): 430 if not isinstance(value, InterfaceElement) or value.parent() is not self: 431 kwds[key] = self(value) 432 433 return args, kwds 434 435 def _check_valid_function_name(self, function): 436 """ 437 Checks to see if function is a valid function name in this 438 interface. If it is not, an exception is raised. Otherwise, nothing 439 is done. 440 441 EXAMPLES:: 442 443 sage: gap._check_valid_function_name('SymmetricGroup') 444 sage: gap._check_valid_function_name('') 445 Traceback (most recent call last): 446 ... 447 ValueError: function name must be nonempty 448 sage: gap._check_valid_function_name('__foo') 449 Traceback (most recent call last): 450 ... 451 AttributeError 452 """ 453 if function == '': 454 raise ValueError, "function name must be nonempty" 455 if function[:2] == "__": 456 raise AttributeError 457 458 def function_call(self, function, args=None, kwds=None): 459 """ 460 EXAMPLES:: 461 462 sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) 463 [0.5,5.5511151231257...e-15,21,0] 464 sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) 465 [0.5,5.5511151231257...e-15,21,0] 466 """ 467 args, kwds = self._convert_args_kwds(args, kwds) 468 self._check_valid_function_name(function) 469 s = self._function_call_string(function, 470 [s.name() for s in args], 471 ['%s=%s'%(key,value.name()) for key, value in kwds.items()]) 472 return self.new(s) 473 474 def _function_call_string(self, function, args, kwds): 475 """ 476 Returns the string used to make function calls. 477 478 EXAMPLES:: 479 480 sage: maxima._function_call_string('diff', ['f(x)', 'x'], []) 481 'diff(f(x),x)' 482 """ 483 return "%s(%s)"%(function, ",".join(list(args) + list(kwds))) 484 485 def call(self, function_name, *args, **kwds): 486 return self.function_call(function_name, args, kwds) 487 488 def _contains(self, v1, v2): 489 raise NotImplementedError 490 491 def __getattr__(self, attrname): 492 """ 493 TESTS:: 494 495 sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_') 496 <built-in method _coerce_map_from_ of Singular object at ...> 497 """ 498 try: 499 return ParentWithBase.__getattribute__(self, attrname) 500 except AttributeError: 501 if attrname[:1] == "_": 502 raise AttributeError 503 return self._function_class()(self, attrname) 504 505 def __cmp__(self, other): 506 """ 507 Compare two pseudo-tty interfaces. Two interfaces compare 508 equal if and only if they are identical objects (this is a 509 critical constraint so that caching of representations of 510 objects in interfaces works correctly). Otherwise they are 511 never equal. 512 513 EXAMPLES:: 514 515 sage: Maxima() == maxima 516 False 517 sage: maxima == maxima 518 True 519 """ 520 if self is other: 521 return 0 522 c = cmp(type(self), type(other)) 523 if c: 524 return c 525 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. 526 527 def console(self): 528 raise NotImplementedError 529 530 def help(self, s): 531 return AsciiArtString('No help on %s available'%s) 532 533 534 class InterfaceFunction(SageObject): 535 """ 536 Interface function. 537 """ 538 def __init__(self, parent, name): 539 self._parent = parent 540 self._name = name 541 542 def __repr__(self): 543 return "%s"%self._name 544 545 def __call__(self, *args, **kwds): 546 return self._parent.function_call(self._name, list(args), kwds) 547 548 def _sage_doc_(self): 549 """ 550 EXAMPLES:: 551 552 sage: gp.gcd._sage_doc_() 553 'gcd(x,{y}): greatest common divisor of x and y.' 554 """ 555 M = self._parent 556 return M.help(self._name) 557 558 559 class InterfaceFunctionElement(SageObject): 560 """ 561 Interface function element. 562 """ 563 def __init__(self, obj, name): 564 self._obj = obj 565 self._name = name 566 567 def __repr__(self): 568 return "%s"%self._name 569 570 def __call__(self, *args, **kwds): 571 return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds) 572 573 def help(self): 574 print self._sage_doc_() 575 576 def _sage_doc_(self): 577 """ 578 EXAMPLES:: 579 580 sage: gp(2).gcd._sage_doc_() 581 'gcd(x,{y}): greatest common divisor of x and y.' 582 """ 583 M = self._obj.parent() 584 return M.help(self._name) 585 586 587 588 def is_InterfaceElement(x): 589 return isinstance(x, InterfaceElement) 590 591 class InterfaceElement(RingElement): 592 """ 593 Interface element. 594 """ 595 def __init__(self, parent, value, is_name=False, name=None): 596 RingElement.__init__(self, parent) 597 self._create = value 598 if parent is None: return # means "invalid element" 599 # idea: Joe Wetherell -- try to find out if the output 600 # is too long and if so get it using file, otherwise 601 # don't. 602 603 if is_name: 604 self._name = value 605 else: 606 try: 607 self._name = parent._create(value, name=name) 608 except (TypeError, KeyboardInterrupt, RuntimeError, ValueError), x: 609 raise TypeError, x 610 611 def _latex_(self): 612 # return "\\begin{verbatim}%s\\end{verbatim}"%self 613 string = str(self) 614 if not '|' in string: 615 delim = '|' 616 elif not '#' in string: 617 delim = '#' 618 elif not '@' in string: 619 delim = '@' 620 elif not '~' in string: 621 delim = '~' 622 return "\\verb%s%s%s"%(delim, string, delim) 623 624 def __iter__(self): 625 for i in range(1, len(self)+1): 626 yield self[i] 627 628 def __len__(self): 629 """ 630 Call self.sage() and return the length of that sage object. 631 632 This approach is inefficient - each interface should override 633 this method with one that calls the external program's length 634 function. 635 636 EXAMPLES:: 637 638 sage: len(gp([1,2,3])) 639 3 640 641 AUTHORS: 642 643 - Felix Lawrence (2009-08-21) 644 """ 645 return len(self.sage()) 646 647 def __reduce__(self): 648 return reduce_load, (self.parent(), self._reduce()) 649 650 def _reduce(self): 651 return repr(self) 652 653 def __call__(self, *args): 654 self._check_valid() 655 P = self.parent() 656 return getattr(P, self.name())(*args) 657 658 def __contains__(self, x): 659 P = self._check_valid() 660 if not isinstance(x, InterfaceElement) or x.parent() is not self.parent(): 661 x = P.new(x) 662 return P._contains(x.name(), self.name()) 663 664 665 def _sage_doc_(self): 666 """ 667 EXAMPLES:: 668 669 sage: gp(2)._sage_doc_() 670 '2' 671 """ 672 return str(self) 673 674 def __hash__(self): 675 """ 676 Returns the hash of self. This is a default implementation of hash 677 which just takes the hash of the string of self. 678 """ 679 return hash('%s'%(self)) 680 681 def __cmp__(self, other): 682 P = self.parent() 683 if P.eval("%s %s %s"%(self.name(), P._equality_symbol(), 684 other.name())) == P._true_symbol(): 685 return 0 686 elif P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): 687 return -1 688 elif P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): 689 return 1 690 691 # everything is supposed to be comparable in Python, so we define 692 # the comparison thus when no comparison is available in interfaced system. 693 if (hash(self) < hash(other)): 694 return -1 695 else: 696 return 1 697 698 def _matrix_(self, R): 699 raise NotImplementedError 700 701 def _vector_(self, R): 702 raise NotImplementedError 703 704 def _check_valid(self): 705 """ 706 Check that this object is valid, i.e., the session in which this 707 object is defined is still running. This is relevant for 708 interpreters that can't be interrupted via ctrl-C, hence get 709 restarted. 710 """ 711 try: 712 P = self.parent() 713 if P is None: 714 raise ValueError, "The %s session in which this object was defined is no longer running."%P.name() 715 except AttributeError: 716 raise ValueError, "The session in which this object was defined is no longer running." 717 return P 718 719 def __del__(self): 720 try: 721 self._check_valid() 722 except ValueError: 723 return 724 if hasattr(self,'_name'): 725 P = self.parent() 726 if not (P is None): 727 P.clear(self._name) 728 729 def _sage_repr(self): 730 """ 731 Return a sage-friendly string representation of the object. 732 733 Some programs use different notation to Sage, e.g. Mathematica 734 writes lists with {} instead of []. This method calls repr(self) 735 then converts the foreign notation into Sage's notation. 736 737 OUTPUT: 738 739 A string representation of the object that is ready for 740 sage_eval(). 741 742 EXAMPLES:: 743 744 sage: repr(mathematica([1,2,3])) # optional - mathematica 745 '{1, 2, 3}' 746 sage: mathematica([1,2,3])._sage_repr() # optional - mathematica 747 '[1, 2, 3]' 748 749 :: 750 751 sage: gp(10.^80)._sage_repr() 752 '1.0000000000000000000000000000000000000e80' # 64-bit 753 '1.000000000000000000000000000e80' # 32-bit 754 sage: mathematica('10.^80')._sage_repr() # optional - mathematica 755 '1.e80' 756 757 AUTHORS: 758 759 - Felix Lawrence (2009-08-21) 760 """ 761 #TO DO: this could use file transfers when self.is_remote() 762 763 string = repr(self).replace('\n',' ').replace('\r', '') 764 # Translate the external program's list formatting to Sage's 765 lld = self.parent()._left_list_delim() 766 if '[' != lld: string = string.replace(lld, '[') 767 rld = self.parent()._right_list_delim() 768 if ']' != rld: string = string.replace(rld, ']') 769 # Translate the external program's exponent formatting 770 expl = self.parent()._exponent_symbol() 771 if 'e' != expl: string = string.replace(expl, 'e') 772 return string 773 774 def _sage_(self): 775 """ 776 Attempt to return a Sage version of this object. 777 This is a generic routine that just tries to evaluate 778 the repr(self). 779 780 EXAMPLES:: 781 782 sage: gp(1/2)._sage_() 783 1/2 784 sage: _.parent() 785 Rational Field 786 787 AUTHORS: 788 789 - William Stein 790 791 - Felix Lawrence (2009-08-21) 792 """ 793 try: 794 return sage_eval(self._sage_repr()) 795 except: 796 raise NotImplementedError 797 798 799 def sage(self): 800 """ 801 Attempt to return a Sage version of this object. 802 803 EXAMPLES:: 804 805 sage: gp(1/2).sage() 806 1/2 807 sage: _.parent() 808 Rational Field 809 """ 810 return self._sage_() 811 812 def __repr__(self): 813 self._check_valid() 814 try: 815 if self._get_using_file: 816 s = self.parent().get_using_file(self._name) 817 except AttributeError: 818 s = self.parent().get(self._name) 819 if s.__contains__(self._name): 820 if hasattr(self, '__custom_name'): 821 s = s.replace(self._name, self.__dict__['__custom_name']) 822 return s 823 824 def __getattr__(self, attrname): 825 P = self._check_valid() 826 if attrname[:1] == "_": 827 raise AttributeError 828 return P._function_element_class()(self, attrname) 829 830 def get_using_file(self): 831 """ 832 Return this element's string representation using a file. Use this 833 if self has a huge string representation. It'll be way faster. 834 835 EXAMPLES:: 836 837 sage: a = maxima(str(2^1000)) 838 sage: a.get_using_file() 839 '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376' 840 """ 841 try: 842 self._check_valid() 843 except ValueError: 844 return '(invalid object -- defined in terms of closed session)' 845 return self.parent().get_using_file(self._name) 846 847 def hasattr(self, attrname): 848 """ 849 Returns whether the given attribute is already defined by this 850 object, and in particular is not dynamically generated. 851 852 EXAMPLES:: 853 854 sage: m = maxima('2') 855 sage: m.hasattr('integral') 856 True 857 sage: m.hasattr('gcd') 858 False 859 """ 860 return not isinstance(getattr(self, attrname), InterfaceFunctionElement) 861 862 def attribute(self, attrname): 863 """ 864 If this wraps the object x in the system, this returns the object 865 x.attrname. This is useful for some systems that have object 866 oriented attribute access notation. 867 868 EXAMPLES:: 869 870 sage: g = gap('SO(1,4,7)') 871 sage: k = g.InvariantQuadraticForm() 872 sage: k.attribute('matrix') 873 [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ], 874 [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ] 875 876 :: 877 878 sage: e = gp('ellinit([0,-1,1,-10,-20])') 879 sage: e.attribute('j') 880 -122023936/161051 881 """ 882 P = self._check_valid() 883 return P('%s.%s'%(self.name(), attrname)) 884 885 def __getitem__(self, n): 886 P = self._check_valid() 887 if not isinstance(n, tuple): 888 return P.new('%s[%s]'%(self._name, n)) 889 else: 890 return P.new('%s[%s]'%(self._name, str(n)[1:-1])) 891 892 def __int__(self): 893 """ 894 EXAMPLES:: 895 896 sage: int(maxima('1')) 897 1 898 sage: type(_) 899 <type 'int'> 900 """ 901 return int(repr(self)) 902 903 def bool(self): 904 P = self.parent() 905 t = P._true_symbol() 906 cmd = '%s %s %s'%(self._name, P._equality_symbol(), t) 907 return P.eval(cmd) == t 908 909 def __nonzero__(self): 910 """ 911 EXAMPLES:: 912 913 sage: bool(maxima(0)) 914 False 915 sage: bool(maxima(1)) 916 True 917 """ 918 return self.bool() 919 920 def __long__(self): 921 """ 922 EXAMPLES:: 923 924 sage: m = maxima('1') 925 sage: long(m) 926 1L 927 """ 928 return long(repr(self)) 929 930 def __float__(self): 931 """ 932 EXAMPLES:: 933 934 sage: m = maxima('1/2') 935 sage: m.__float__() 936 0.5 937 sage: float(m) 938 0.5 939 """ 940 return float(repr(self)) 941 942 def _integer_(self, ZZ=None): 943 """ 944 EXAMPLES:: 945 946 sage: m = maxima('1') 947 sage: m._integer_() 948 1 949 sage: _.parent() 950 Integer Ring 951 sage: QQ(m) 952 1 953 """ 954 import sage.rings.all 955 return sage.rings.all.Integer(repr(self)) 956 957 def _rational_(self): 958 """ 959 EXAMPLES:: 960 961 sage: m = maxima('1/2') 962 sage: m._rational_() 963 1/2 964 sage: _.parent() 965 Rational Field 966 sage: QQ(m) 967 1/2 968 """ 969 import sage.rings.all 970 return sage.rings.all.Rational(repr(self)) 971 972 def name(self, new_name=None): 973 """ 974 Returns the name of self. If new_name is passed in, then this 975 function returns a new object identical to self whose name is 976 new_name. 977 978 Note that this can overwrite existing variables in the system. 979 980 EXAMPLES:: 981 982 sage: x = r([1,2,3]); x 983 [1] 1 2 3 984 sage: x.name() 985 'sage3' 986 sage: x = r([1,2,3]).name('x'); x 987 [1] 1 2 3 988 sage: x.name() 989 'x' 990 991 :: 992 993 sage: s5 = gap.SymmetricGroup(5).name('s5') 994 sage: s5 995 SymmetricGroup( [ 1 .. 5 ] ) 996 sage: s5.name() 997 's5' 998 """ 999 if new_name is not None: 1000 if not isinstance(new_name, str): 1001 raise TypeError, "new_name must be a string" 1002 p = self.parent() 1003 p.set(new_name, self._name) 1004 return p._object_class()(p, new_name, is_name=True) 1005 1006 return self._name 1007 1008 def gen(self, n): 1009 P = self._check_valid() 1010 return P.new('%s.%s'%(self._name, int(n))) 1011 1012 def _operation(self, operation, right): 1013 P = self._check_valid() 1014 try: 1015 return P.new('%s %s %s'%(self._name, operation, right._name)) 1016 except Exception, msg: 1017 raise TypeError, msg 1018 1019 def _add_(self, right): 1020 """ 1021 EXAMPLES:: 1022 1023 sage: f = maxima.cos(x) 1024 sage: g = maxima.sin(x) 1025 sage: f + g 1026 sin(x)+cos(x) 1027 sage: f + 2 1028 cos(x)+2 1029 sage: 2 + f 1030 cos(x)+2 1031 """ 1032 return self._operation("+", right) 1033 1034 def _sub_(self, right): 1035 """ 1036 EXAMPLES:: 1037 1038 sage: f = maxima.cos(x) 1039 sage: g = maxima.sin(x) 1040 sage: f - g 1041 cos(x)-sin(x) 1042 sage: f - 2 1043 cos(x)-2 1044 sage: 2 - f 1045 2-cos(x) 1046 """ 1047 return self._operation('-', right) 1048 1049 def _mul_(self, right): 1050 """ 1051 EXAMPLES:: 1052 1053 sage: f = maxima.cos(x) 1054 sage: g = maxima.sin(x) 1055 sage: f*g 1056 cos(x)*sin(x) 1057 sage: 2*f 1058 2*cos(x) 1059 """ 1060 return self._operation('*', right) 1061 1062 def _div_(self, right): 1063 """ 1064 EXAMPLES:: 1065 1066 sage: f = maxima.cos(x) 1067 sage: g = maxima.sin(x) 1068 sage: f/g 1069 cos(x)/sin(x) 1070 sage: f/2 1071 cos(x)/2 1072 """ 1073 return self._operation("/", right) 1074 1075 def __pow__(self, n): 1076 """ 1077 EXAMPLES:: 1078 1079 sage: a = maxima('2') 1080 sage: a^(3/4) 1081 2^(3/4) 1082 """ 1083 P = self._check_valid() 1084 if not hasattr(n, 'parent') or P is not n.parent(): 1085 n = P(n) 1086 return self._operation("^", n) 1087 1088 def reduce_load(parent, x): 1089 return parent(x) -
sage/interfaces/maxima_lib.py
diff -r a928dca2950b -r b766df9c3439 sage/interfaces/maxima_lib.py
a b 624 624 self.__eval_using_file_cutoff = 10**9 625 625 self._available_vars = [] 626 626 self._Expect__seq = 0 627 self._Interface__seq = 0 627 628 self._session_number = 1 628 629 self._Expect__name = "maxima" 630 self._Interface__name = "maxima" 629 631 630 632 if True: 631 633 # display2d -- no ascii art output -
sage/symbolic/integration/integral.py
diff -r a928dca2950b -r b766df9c3439 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: -
sage/calculus/calculus.py
# HG changeset patch # User Jean-Pierre Flori <flori@enst.fr> # Date 1297870719 -3600 # Node ID fba59ed64da68b2a44e625ba60be03d053407484 # Parent b766df9c34391b224035c0f8e4a54524c59b0dfd Refactor Maxima's interfaces. diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 sage/interfaces/expect.py
a b 489 489 except Exception, msg: 490 490 pass 491 491 492 def cputime(self):493 """494 CPU time since this process started running.495 """496 raise NotImplementedError497 498 492 def quit(self, verbose=False, timeout=0.25): 499 493 """ 500 494 EXAMPLES:: … … 1084 1078 pass 1085 1079 1086 1080 1087 1088 1081 def is_ExpectElement(x): 1089 1082 return isinstance(x, ExpectElement) 1090 1083 … … 1155 1148 # def _sage_repr(self): 1156 1149 #TO DO: this could use file transfers when self.is_remote() 1157 1150 1158 1159 def __repr__(self):1160 self._check_valid()1161 try:1162 if self._get_using_file:1163 s = self.parent().get_using_file(self._name)1164 except AttributeError:1165 s = self.parent().get(self._name)1166 if s.__contains__(self._name):1167 if hasattr(self, '__custom_name'):1168 s = s.replace(self._name, self.__dict__['__custom_name'])1169 return s1170 1171 def get_using_file(self):1172 """1173 Return this element's string representation using a file. Use this1174 if self has a huge string representation. It'll be way faster.1175 1176 EXAMPLES::1177 1178 sage: a = maxima(str(2^1000))1179 sage: a.get_using_file()1180 '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376'1181 """1182 try:1183 self._check_valid()1184 except ValueError:1185 return '(invalid object -- defined in terms of closed session)'1186 return self.parent().get_using_file(self._name)1187 1188 1151 1189 1152 class StdOutContext: 1190 1153 """ -
sage/interfaces/interface.py
diff -r b766df9c3439 -r fba59ed64da6 sage/interfaces/interface.py
a b 57 57 Interface interface object. 58 58 """ 59 59 def __init__(self, name): 60 61 60 self.__name = name 62 61 self.__coerce_name = '_' + name.lower() + '_' 63 62 self.__seq = -1 … … 97 96 def __del__(self): 98 97 pass 99 98 99 def cputime(self): 100 """ 101 CPU time since this process started running. 102 """ 103 raise NotImplementedError 104 100 105 def read(self, filename): 101 106 r""" 102 107 EXAMPLES:: … … 147 152 except TypeError, s: 148 153 raise TypeError, 'error evaluating "%s":\n%s'%(code,s) 149 154 155 _eval_line = eval 156 150 157 def execute(self, *args, **kwds): 151 158 return self.eval(*args, **kwds) 152 159 … … 210 217 TypeError. 211 218 """ 212 219 s = '_%s_'%self.name() 220 # if s == '_maxima_lib_': 221 # s = '_maxima_' 213 222 if s == '_pari_': 214 223 s = '_gp_' 215 224 try: -
sage/interfaces/maxima.py
diff -r b766df9c3439 -r fba59ed64da6 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_version1090 sage: maxima_version()1091 '5.23.2'1092 """1093 return os.popen('maxima --version').read().split()[-1]1094 1095 1056 def __doctest_cleanup(): 1096 1057 import sage.interfaces.quit 1097 1058 sage.interfaces.quit.expect_quitall() -
sage/interfaces/maxima_abstract.py
diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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*) 72 (error 73 (concatenate 'string "Maxima asks: " 74 (string-trim '(#\Newline) (with-output-to-string (*standard-output*) 501 75 (terpri) 502 76 (cond ((not print?) 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 (mterpri)))))))77 (setq print? t) 78 (princ *prompt-prefix*) 79 (princ *prompt-suffix*)) 80 ((null msg) 81 (princ *prompt-prefix*) 82 (princ *prompt-suffix*)) 83 ((atom msg) 84 (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*) 85 (mterpri)) 86 ((eq flag t) 87 (princ *prompt-prefix*) 88 (mapc #'princ (cdr msg)) 89 (princ *prompt-suffix*) 90 (mterpri)) 91 (t 92 (princ *prompt-prefix*) 93 (displa msg) 94 (princ *prompt-suffix*) 95 (mterpri)))))))) 522 96 """) 523 97 524 98 ecl_eval('(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))') 525 99 ecl_eval('(defun principal nil (error "Divergent Integral"))') 526 527 100 ecl_eval("(setf $errormsg nil)") 528 101 102 #ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))") 103 104 #ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))') 105 #ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))') 106 #ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))') 107 #ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))') 108 #ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))') 109 #ecl_eval('(defun asksign (x)(error "Maxima asks a question"))') 110 #ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))') 111 #ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))') 112 #ecl_eval('(defun askinver (a)(error "Maxima asks a question"))') 113 #ecl_eval('(defun npask (exp)(error "Maxima asks a question"))') 114 115 ecl_eval("(setf original-standard-output *standard-output*)") 116 ecl_eval("(setf *standard-output* *dev-null*)") 117 #ecl_eval("(setf *error-output* *dev-null*)") 118 119 # display2d -- no ascii art output 120 # keepfloat -- don't automatically convert floats to rationals 121 init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'] 122 # Turn off the prompt labels, since computing them *very 123 # dramatically* slows down the maxima interpret after a while. 124 # See the function makelabel in suprv1.lisp. 125 # Many thanks to andrej.vodopivec@gmail.com and also 126 # Robert Dodier for figuring this out! 127 # See trac # 6818. 128 init_code.append('nolabels : true') 129 for l in init_code: 130 ecl_eval("#$%s$"%l) 131 ## To get more debug information uncomment the next line 132 ## should allow to do this through a method 133 #ecl_eval("(setf *standard-output* original-standard-output)") 134 135 # This returns an EclObject 529 136 maxima_eval=ecl_eval(""" 530 137 (defun maxima-eval( form ) 531 138 (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form))))) … … 554 161 ) 555 162 """) 556 163 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 164 maxima_lib_instances = 0 574 165 575 maxprint=EclObject("$STRING") 166 # The Maxima string function can change the structure of its input 167 #maxprint=EclObject("$STRING") 168 maxprint=EclObject("(defun mstring-for-sage (form) (coerce (mstring form) 'string))").eval() 576 169 meval=EclObject("MEVAL") 577 170 msetq=EclObject("MSETQ") 578 171 mlist=EclObject("MLIST") … … 590 183 max_use_grobner=EclObject("$USE_GROBNER") 591 184 max_to_poly_solve=EclObject("$TO_POLY_SOLVE") 592 185 186 def stdout_to_string(s): 187 return ecl_eval("(with-output-to-string (*standard-output*) (maxima-eval #$%s$))"%s).python()[1:-1] 188 593 189 def max_to_string(s): 594 return m eval(EclObject([[maxprint],s])).python()[1:-1]190 return maxprint(s).python()[1:-1] 595 191 596 class Maxima(maxima_abstract.Maxima): 192 my_mread=ecl_eval(""" 193 (defun my-mread (cmd) 194 (caddr (mread (make-string-input-stream cmd)))) 195 """) 196 197 def parse_max_string(l): 198 return my_mread('"%s;"'%l) 199 200 class MaximaLib(MaximaAbstract): 597 201 """ 598 Interface to the Maxima interpreter.202 Interface to Maxima as a Library. 599 203 """ 600 def __init__(self, script_subdirectory=None, logfile=None, server=None, 601 init_code = None): 204 def __init__(self): 602 205 """ 603 206 Create an instance of the Maxima interpreter. 604 207 605 208 TESTS:: 606 607 sage: maxima == loads(dumps(maxima)) 209 210 sage: from sage.interfaces.maxima_lib import maxima_lib 211 sage: maxima_lib == loads(dumps(maxima_lib)) 608 212 True 609 213 610 214 We make sure labels are turned off (see trac 6816):: 611 215 612 sage: 'nolabels :true' in maxima._Expect__init_code216 sage: 'nolabels : true' in maxima_lib._MaximaLib__init_code 613 217 True 614 218 """ 615 219 global maxima_lib_instances 616 220 if maxima_lib_instances > 0: 617 221 raise RuntimeError, "Maxima interface in library mode can only be instantiated once" 618 222 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._Interface__seq = 0628 self._session_number = 1629 self._Expect__name = "maxima"630 self._Interface__name = "maxima"631 223 632 if True: 633 # display2d -- no ascii art output 634 # keepfloat -- don't automatically convert floats to rationals 635 init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'] 636 637 # Turn off the prompt labels, since computing them *very 638 # dramatically* slows down the maxima interpret after a while. 639 # See the function makelabel in suprv1.lisp. 640 # Many thanks to andrej.vodopivec@gmail.com and also 641 # Robert Dodier for figuring this out! 642 # See trac # 6818. 643 init_code.append('nolabels : true') 644 ecl_eval("(setf original-standard-output *standard-output*)") 645 ecl_eval("(setf *standard-output* *dev-null*)") 646 for l in init_code: 647 ecl_eval("#$%s$"%l) 648 ecl_eval("(setf *standard-output* original-standard-output)") 224 global init_code 225 self.__init_code = init_code 226 227 ## The name should definitely be changed to maxima_lib, however much more changes are then needed elsewhere 228 ## 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) 229 MaximaAbstract.__init__(self,"maxima") 230 self.__seq = 0 649 231 650 232 def _coerce_from_special_method(self, x): 651 233 if isinstance(x, EclObject): 652 return Maxima Element(self,self._create(x))234 return MaximaLibElement(self,self._create(x)) 653 235 else: 654 return maxima_abstract.Maxima._coerce_from_special_method(self,x) 655 656 657 def _function_class(self): 658 """ 659 EXAMPLES:: 660 661 sage: maxima._function_class() 662 <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'> 663 """ 664 return MaximaExpectFunction 665 666 def _start(self): 667 """ 668 Starts the Maxima interpreter. 669 670 EXAMPLES:: 671 672 sage: m = Maxima() 673 sage: m.is_running() 674 False 675 sage: m._start() 676 sage: m.is_running() 677 True 678 """ 679 # ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))") 680 pass 236 return MaximaAbstract._coerce_from_special_method(self,x) 681 237 682 238 def __reduce__(self): 683 239 """ 684 240 EXAMPLES:: 685 241 686 sage: maxima.__reduce__() 687 (<function reduce_load_Maxima at 0x...>, ()) 242 sage: from sage.interfaces.maxima_lib import maxima_lib 243 sage: maxima_lib.__reduce__() 244 (<function reduce_load_MaximaLib at 0x...>, ()) 688 245 """ 689 return reduce_load_Maxima , tuple([])246 return reduce_load_MaximaLib, tuple([]) 690 247 691 def _sendline(self, str): 692 self._sendstr(str) 693 os.write(self._expect.child_fd, os.linesep) 694 695 def _expect_expr(self, expr=None, timeout=None): 696 """ 697 EXAMPLES: 698 sage: a,b=var('a,b') 699 sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 700 Traceback (most recent call last): 701 ... 702 RuntimeError: ECL says: Maxima asks:... 703 sage: assume(a>0) 704 sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x) 705 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) 706 sage: var('x, n') 707 (x, n) 708 sage: integral(x^n,x) 709 Traceback (most recent call last): 710 ... 711 RuntimeError: ECL says: Maxima asks:... 712 sage: assume(n+1>0) 713 sage: integral(x^n,x) 714 x^(n + 1)/(n + 1) 715 sage: forget() 716 """ 717 if expr is None: 718 expr = self._prompt_wait 719 if self._expect is None: 720 self._start() 721 try: 722 if timeout: 723 i = self._expect.expect(expr,timeout=timeout) 724 else: 725 i = self._expect.expect(expr) 726 if i > 0: 727 v = self._expect.before 728 729 #We check to see if there is a "serious" error in Maxima. 730 #Note that this depends on the order of self._prompt_wait 731 if expr is self._prompt_wait and i > len(self._ask): 732 self.quit() 733 raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v 734 735 j = v.find('Is ') 736 v = v[j:] 737 k = v.find(' ',4) 738 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] 739 self._sendline(";") 740 self._expect_expr() 741 raise ValueError, msg 742 except KeyboardInterrupt, msg: 743 #print self._expect.before 744 i = 0 745 while True: 746 try: 747 print "Control-C pressed. Interrupting Maxima. Please wait a few seconds..." 748 self._sendstr('quit;\n'+chr(3)) 749 self._sendstr('quit;\n'+chr(3)) 750 self.interrupt() 751 self.interrupt() 752 except KeyboardInterrupt: 753 i += 1 754 if i > 10: 755 break 756 pass 757 else: 758 break 759 raise KeyboardInterrupt, msg 760 761 def _eval_line(self, line, allow_use_file=False, 762 wait_for_prompt=True, reformat=True, error_check=True): 248 # This outputs a string 249 def eval(self, line, locals=None, reformat=True, **kwds): 763 250 result = '' 764 251 while line: 765 252 ind_dollar=line.find("$") … … 771 258 else: 772 259 statement = line[:ind_semi] 773 260 line = line[ind_semi+1:] 774 if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement))261 if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement)) 775 262 else: 776 263 statement = line[:ind_dollar] 777 264 line = line[ind_dollar+1:] 778 if statement: _ = max_to_string(maxima_eval("#$%s$"%statement)) 779 return result 265 if statement: _ = maxima_eval("#$%s$"%statement) 266 if not reformat: 267 return result 268 return ''.join([x.strip() for x in result.split()]) 780 269 781 def _synchronize(self): 782 """ 783 Synchronize pexpect interface. 784 785 This put a random integer (plus one!) into the output stream, then 786 waits for it, thus resynchronizing the stream. If the random 787 integer doesn't appear within 1 second, maxima is sent interrupt 788 signals. 789 790 This way, even if you somehow left maxima in a busy state 791 computing, calling _synchronize gets everything fixed. 792 793 EXAMPLES: This makes Maxima start a calculation:: 794 795 sage: maxima._sendstr('1/1'*500) 796 797 When you type this command, this synchronize command is implicitly 798 called, and the above running calculation is interrupted:: 799 800 sage: maxima('2+2') 801 4 802 """ 803 marker = '__SAGE_SYNCHRO_MARKER_' 804 if self._expect is None: return 805 r = randrange(2147483647) 806 s = marker + str(r+1) 807 808 # The 0; *is* necessary... it comes up in certain rare cases 809 # that are revealed by extensive testing. Don't delete it. -- william stein 810 cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r) 811 self._sendstr(cmd) 812 try: 813 self._expect_expr(timeout=0.5) 814 if not s in self._before(): 815 self._expect_expr(s,timeout=0.5) 816 self._expect_expr(timeout=0.5) 817 except pexpect.TIMEOUT, msg: 818 self._interrupt() 819 except pexpect.EOF: 820 self._crash_msg() 821 self.quit() 270 _eval_line = eval 822 271 823 272 ########################################### 824 273 # Direct access to underlying lisp interpreter. … … 833 282 834 283 EXAMPLES:: 835 284 836 sage: maxima.lisp("(+ 2 17)") # random formatted output 837 :lisp (+ 2 17) 838 19 839 ( 285 sage: from sage.interfaces.maxima_lib import maxima_lib 286 sage: maxima_lib.lisp("(+ 2 17)") 287 <ECL: 19> 840 288 """ 841 self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False, wait_for_prompt=False, reformat=False, error_check=False) 842 self._expect_expr('(%i)') 843 return self._before() 844 845 ########################################### 846 # Interactive help 847 ########################################### 848 def _command_runner(self, command, s, redirect=True): 849 """ 850 Run ``command`` in a new Maxima session and return its 851 output as an ``AsciiArtString``. 852 853 If redirect is set to False, then the output of the command is not 854 returned as a string. Instead, it behaves like os.system. This is 855 used for interactive things like Maxima's demos. See maxima.demo? 856 857 EXAMPLES:: 858 859 sage: maxima._command_runner('describe', 'gcd') 860 -- Function: gcd (<p_1>, <p_2>, <x_1>, ...) 861 ... 862 """ 863 cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s) 864 if sage.server.support.EMBEDDED_MODE: 865 cmd += '< /dev/null' 866 867 if redirect: 868 p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, 869 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 870 res = p.stdout.read() 871 # ecl-10.2 : 3 lines 872 # ecl-10.4 : 5 lines 873 # ecl-11.1 : 4 lines fancy a tango? 874 # We now get 4 lines of commented verbosity 875 # every time Maxima starts, so we need to get rid of them 876 for _ in range(4): 877 res = res[res.find('\n')+1:] 878 return AsciiArtString(res) 879 else: 880 subprocess.Popen(cmd, shell=True) 881 882 def _object_class(self): 883 """ 884 Return the Python class of Maxima elements. 885 886 EXAMPLES:: 887 888 sage: maxima._object_class() 889 <class 'sage.interfaces.maxima_abstract.MaximaElement'> 890 """ 891 return MaximaElement 892 893 def _function_element_class(self): 894 """ 895 EXAMPLES:: 896 897 sage: maxima._function_element_class() 898 <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'> 899 """ 900 return MaximaFunctionElement 901 902 def function(self, args, defn, rep=None, latex=None): 903 """ 904 Return the Maxima function with given arguments and definition. 905 906 INPUT: 907 908 909 - ``args`` - a string with variable names separated by 910 commas 911 912 - ``defn`` - a string (or Maxima expression) that 913 defines a function of the arguments in Maxima. 914 915 - ``rep`` - an optional string; if given, this is how 916 the function will print. 917 918 919 EXAMPLES:: 920 921 sage: f = maxima.function('x', 'sin(x)') 922 sage: f(3.2) 923 -.058374143427580... 924 sage: f = maxima.function('x,y', 'sin(x)+cos(y)') 925 sage: f(2,3.5) 926 sin(2)-.9364566872907963 927 sage: f 928 sin(x)+cos(y) 929 930 :: 931 932 sage: g = f.integrate('z') 933 sage: g 934 (cos(y)+sin(x))*z 935 sage: g(1,2,3) 936 3*(cos(2)+sin(1)) 937 938 The function definition can be a maxima object:: 939 940 sage: an_expr = maxima('sin(x)*gamma(x)') 941 sage: t = maxima.function('x', an_expr) 942 sage: t 943 gamma(x)*sin(x) 944 sage: t(2) 945 sin(2) 946 sage: float(t(2)) 947 0.90929742682568171 948 sage: loads(t.dumps()) 949 gamma(x)*sin(x) 950 """ 951 name = self._next_var_name() 952 if isinstance(defn, MaximaElement): 953 defn = defn.str() 954 elif not isinstance(defn, str): 955 defn = str(defn) 956 if isinstance(args, MaximaElement): 957 args = args.str() 958 elif not isinstance(args, str): 959 args = str(args) 960 cmd = '%s(%s) := %s'%(name, args, defn) 961 maxima._eval_line(cmd) 962 if rep is None: 963 rep = defn 964 f = MaximaFunction(self, name, rep, args, latex) 965 return f 289 return ecl_eval(cmd) 966 290 967 291 def set(self, var, value): 968 292 """ … … 978 302 979 303 EXAMPLES:: 980 304 981 sage: maxima.set('xxxxx', '2') 982 sage: maxima.get('xxxxx') 305 sage: from sage.interfaces.maxima_lib import maxima_lib 306 sage: maxima_lib.set('xxxxx', '2') 307 sage: maxima_lib.get('xxxxx') 983 308 '2' 984 309 """ 985 310 if not isinstance(value, str): 986 311 raise TypeError 987 312 cmd = '%s : %s$'%(var, value.rstrip(';')) 988 if len(cmd) > self.__eval_using_file_cutoff: 989 self._batch(cmd, batchload=True) 990 else: 991 self._eval_line(cmd) 992 #self._sendline(cmd) 993 #self._expect_expr() 994 #out = self._before() 995 #self._error_check(cmd, out) 313 self.eval(cmd) 996 314 997 315 def clear(self, var): 998 316 """ … … 1000 318 1001 319 EXAMPLES:: 1002 320 1003 sage: maxima.set('xxxxx', '2') 1004 sage: maxima.get('xxxxx') 321 sage: from sage.interfaces.maxima_lib import maxima_lib 322 sage: maxima_lib.set('xxxxx', '2') 323 sage: maxima_lib.get('xxxxx') 1005 324 '2' 1006 sage: maxima .clear('xxxxx')1007 sage: maxima .get('xxxxx')325 sage: maxima_lib.clear('xxxxx') 326 sage: maxima_lib.get('xxxxx') 1008 327 'xxxxx' 1009 328 """ 1010 329 try: 1011 self. _expect.send('kill(%s)$'%var)330 self.eval('kill(%s)$'%var) 1012 331 except (TypeError, AttributeError): 1013 332 pass 1014 333 1015 334 def get(self, var): 1016 335 """ … … 1018 337 1019 338 EXAMPLES:: 1020 339 1021 sage: maxima.set('xxxxx', '2') 1022 sage: maxima.get('xxxxx') 340 sage: from sage.interfaces.maxima_lib import maxima_lib 341 sage: maxima_lib.set('xxxxx', '2') 342 sage: maxima_lib.get('xxxxx') 1023 343 '2' 1024 344 """ 1025 s = self. _eval_line('%s;'%var)345 s = self.eval('%s;'%var) 1026 346 return s 1027 347 1028 348 def _create(self, value, name=None): … … 1032 352 else: 1033 353 self.set(name, value) 1034 354 return name 1035 1036 def version(self):355 356 def _function_class(self): 1037 357 """ 1038 Return the version of Maxima that Sage includes. 358 EXAMPLES:: 359 360 sage: from sage.interfaces.maxima_lib import maxima_lib 361 sage: maxima_lib._function_class() 362 <class 'sage.interfaces.maxima_lib.MaximaLibFunction'> 363 """ 364 return MaximaLibFunction 365 366 def _object_class(self): 367 """ 368 Return the Python class of Maxima elements. 1039 369 1040 370 EXAMPLES:: 1041 371 1042 sage: maxima.version() 1043 '5.23.2' 372 sage: from sage.interfaces.maxima_lib import maxima_lib 373 sage: maxima_lib._object_class() 374 <class 'sage.interfaces.maxima_lib.MaximaLibElement'> 1044 375 """ 1045 return maxima_version()376 return MaximaLibElement 1046 377 1047 ##some helper functions to wrap tha calculus use of the maxima interface. 1048 ##these routines expect arguments living in the symbolic ring and return something 1049 ##that is hopefully coercible into the symbolic ring again. 378 def _function_element_class(self): 379 """ 380 EXAMPLES:: 381 382 sage: from sage.interfaces.maxima_lib import maxima_lib 383 sage: maxima_lib._function_element_class() 384 <class 'sage.interfaces.maxima_lib.MaximaLibFunctionElement'> 385 """ 386 return MaximaLibFunctionElement 387 388 def _object_function_class(self): 389 """ 390 EXAMPLES:: 391 392 sage: from sage.interfaces.maxima_lib import maxima_lib 393 sage: maxima_lib._object_function_class() 394 <class 'sage.interfaces.maxima_lib.MaximaLibElementFunction'> 395 """ 396 return MaximaLibElementFunction 397 398 ##some helper functions to wrap the calculus use of the maxima interface. 399 ##these routines expect arguments living in the symbolic ring and return something 400 ##that is hopefully coercible into the symbolic ring again. 1050 401 1051 402 def sr_integral(self,*args): 1052 403 try: … … 1084 435 L.append(max_minus) 1085 436 return max_to_sr(maxima_eval(([max_tlimit],L))) 1086 437 1087 ## def display2d(self, flag=True):1088 ## """1089 ## Set the flag that determines whether Maxima objects are1090 ## printed using their 2-d ASCII art representation. When the1091 ## maxima interface starts the default is that objects are not1092 ## represented in 2-d.1093 438 1094 ## INPUT: 1095 ## flag -- bool (default: True) 439 def is_MaximaLibElement(x): 440 """ 441 Returns True if x is of type MaximaLibElement. 442 443 EXAMPLES:: 444 445 sage: from sage.interfaces.maxima_lib import maxima_lib, is_MaximaLibElement 446 sage: m = maxima_lib(1) 447 sage: is_MaximaLibElement(m) 448 True 449 sage: is_MaximaLibElement(1) 450 False 451 """ 452 return isinstance(x, MaximaLibElement) 1096 453 1097 ## EXAMPLES 1098 ## sage: maxima('1/2') 1099 ## 1/2 1100 ## sage: maxima.display2d(True) 1101 ## sage: maxima('1/2') 1102 ## 1 1103 ## - 1104 ## 2 1105 ## sage: maxima.display2d(False) 1106 ## """ 1107 ## self._display2d = bool(flag) 1108 1109 class MaximaElement(maxima_abstract.MaximaElement): 454 class MaximaLibElement(MaximaAbstractElement): 1110 455 """ 1111 456 """ 1112 457 def ecl(self): … … 1124 469 cmd=EclObject([[max_to_poly_solve], self.ecl(), sr_to_max(vars)]) 1125 470 return self.parent()(maxima_eval(cmd)) 1126 471 1127 def is_MaximaElement(x): 1128 """ 1129 Returns True if x is of type MaximaElement. 1130 1131 EXAMPLES:: 1132 1133 sage: from sage.interfaces.maxima import is_MaximaElement 1134 sage: m = maxima(1) 1135 sage: is_MaximaElement(m) 1136 True 1137 sage: is_MaximaElement(1) 1138 False 1139 """ 1140 return isinstance(x, MaximaElement) 472 def display2d(self, onscreen=True): 473 """ 474 EXAMPLES:: 475 476 sage: from sage.interfaces.maxima_lib import maxima_lib 477 sage: F = maxima_lib('x^5 - y^5').factor() 478 sage: F.display2d () 479 4 3 2 2 3 4 480 - (y - x) (y + x y + x y + x y + x ) 481 """ 482 self._check_valid() 483 P = self.parent() 484 P._eval_line('display2d : true$') 485 s = stdout_to_string('disp(%s)'%self.name()) 486 #s = P._eval_line('disp(%s)$'%self.name()) 487 P._eval_line('display2d : false$') 488 s = s.strip('\r\n') 1141 489 1142 # An instance 1143 maxima = Maxima() 490 # if ever want to dedent, see 491 # http://mail.python.org/pipermail/python-list/2006-December/420033.html 492 if onscreen: 493 print s 494 else: 495 return s 1144 496 1145 def reduce_load_Maxima(): 497 498 class MaximaLibFunctionElement(MaximaAbstractFunctionElement): 499 pass 500 501 502 class MaximaLibFunction(MaximaAbstractFunction): 503 pass 504 505 506 class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction): 507 pass 508 509 510 # The (unique) instance 511 maxima_lib = MaximaLib() 512 maxima = maxima_lib 513 514 515 def reduce_load_MaximaLib(): 1146 516 """ 1147 517 EXAMPLES:: 1148 518 1149 sage: from sage.interfaces.maxima import reduce_load_Maxima1150 sage: reduce_load_Maxima ()519 sage: from sage.interfaces.maxima_lib import reduce_load_MaximaLib 520 sage: reduce_load_MaximaLib() 1151 521 Maxima 1152 522 """ 1153 return maxima 523 return maxima_lib 1154 524 1155 1156 def maxima_version(): 1157 """ 1158 EXAMPLES:: 1159 1160 sage: from sage.interfaces.maxima import maxima_version 1161 sage: maxima_version() 1162 '5.23.2' 1163 """ 1164 return os.popen('maxima --version').read().split()[-1] 1165 1166 def __doctest_cleanup(): 1167 import sage.interfaces.quit 1168 sage.interfaces.quit.expect_quitall() 1169 1170 1171 import sage.symbolic.expression 1172 from sage.symbolic.ring import SR 525 #********************************** 526 # ??? 1173 527 1174 528 import sage.symbolic.expression 1175 529 import sage.functions.trig 1176 530 import sage.functions.log 1177 531 import sage.functions.other 1178 532 import sage.symbolic.integration.integral 533 from sage.symbolic.operators import FDerivativeOperator 1179 534 1180 535 car=EclObject("car") 1181 536 cdr=EclObject("cdr") … … 1189 544 NIL=EclObject("NIL") 1190 545 ratdisrep=EclObject("ratdisrep") 1191 546 1192 sage_op_dict={}1193 1194 547 sage_op_dict = { 1195 548 sage.symbolic.expression.operator.abs : "MABS", 1196 549 sage.symbolic.expression.operator.add : "MPLUS", … … 1225 578 sage.functions.other.erf : "%ERF", 1226 579 sage.functions.other.gamma_inc : "%GAMMA_INCOMPLETE" 1227 580 } 1228 1229 581 #we compile the dictionary 1230 582 sage_op_dict = dict([(k,EclObject(sage_op_dict[k])) for k in sage_op_dict]) 1231 583 max_op_dict = dict([(sage_op_dict[k],k) for k in sage_op_dict]) 584 1232 585 def add_vararg(*args): 1233 586 S=0 1234 587 for a in args: … … 1246 599 1247 600 mplus=EclObject("MPLUS") 1248 601 mtimes=EclObject("MTIMES") 602 mdiff=EclObject("%DERIVATIVE") 1249 603 rat=EclObject("RAT") 1250 604 max_i=EclObject("$%I") 1251 605 max_op_dict[mplus]=add_vararg … … 1292 646 else: 1293 647 return sage.symbolic.integration.integral.indefinite_integral(*args, hold=True) 1294 648 649 def mdiff_to_sage(expr): 650 return max_to_sr(expr.cadr()).diff(*[max_to_sr(e) for e in expr.cddr()]) 651 1295 652 special_max_to_sage={ 1296 653 EclObject("MRAT") : mrat_to_sage, 1297 EclObject("MQAPPLY") : mqapply_to_sage, 1298 EclObject("%INTEGRATE") : dummy_integrate 654 mqapply : mqapply_to_sage, 655 EclObject("%INTEGRATE") : dummy_integrate, 656 mdiff : mdiff_to_sage 1299 657 } 1300 658 1301 659 special_sage_to_max={ … … 1314 672 elif isinstance(obj,sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic) and obj.parent().defining_polynomial().list() == [1,0,1]: 1315 673 re, im = obj.list() 1316 674 return EclObject([[mplus], pyobject_to_max(re), [[mtimes], pyobject_to_max(im), max_i]]) 1317 1318 675 return EclObject(obj) 1319 676 677 # This goes from SR to EclObject 1320 678 def sr_to_max(expr): 1321 679 r""" 1322 680 """ … … 1326 684 return EclObject(([mlist],[sr_to_max(e) for e in expr])) 1327 685 op = expr.operator() 1328 686 if op: 1329 if (op in special_sage_to_max): 687 # Stolen from sage.symbolic.expression_conversion 688 # Should be defined in a function and then put in special_sage_to_max 689 # For that, we should change the API of the functions there (we need to have access to op, not only to expr.operands() 690 if isinstance(op, FDerivativeOperator): 691 from sage.symbolic.ring import is_SymbolicVariable 692 args = expr.operands() 693 if (not all(is_SymbolicVariable(v) for v in args) or 694 len(args) != len(set(args))): 695 raise NotImplementedError, "arguments must be distinct variables" 696 f = sr_to_max(op.function()(*args)) 697 params = op.parameter_set() 698 deriv_max = [] 699 [deriv_max.extend([sr_to_max(args[i]), EclObject(params.count(i))]) for i in set(params)] 700 l = [mdiff,f] 701 l.extend(deriv_max) 702 return EclObject(l) 703 elif (op in special_sage_to_max): 1330 704 return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()])) 1331 705 elif not (op in sage_op_dict): 1332 op_max=caar(maxima(expr).ecl()) 706 # Maxima does some simplifications automatically by default 707 # so calling maxima(expr) can change the structure of expr 708 #op_max=caar(maxima(expr).ecl()) 709 # This should be safe if we treated all special operators above 710 op_max=maxima(op).ecl() 1333 711 sage_op_dict[op]=op_max 1334 712 max_op_dict[op_max]=op 1335 713 return EclObject(([sage_op_dict[op]], … … 1346 724 except TypeError: 1347 725 return maxima(expr).ecl() 1348 726 727 # This goes from EclObject to SR 1349 728 def max_to_sr(expr): 1350 729 if expr.consp(): 1351 730 op_max=caar(expr) 1352 731 if op_max in special_max_to_sage: 1353 732 return special_max_to_sage[op_max](expr) 1354 733 if not(op_max in max_op_dict): 734 # This could be unsafe if the conversion to SR chenges the structure of expr 1355 735 sage_expr=SR(maxima(expr)) 1356 736 max_op_dict[op_max]=sage_expr.operator() 1357 737 sage_op_dict[sage_expr.operator()]=op_max 1358 738 op=max_op_dict[op_max] 1359 739 max_args=cdr(expr) 1360 args=[ 740 args=[max_to_sr(a) for a in max_args] 1361 741 return op(*args) 1362 742 elif expr.symbolp(): 1363 743 if not(expr in max_sym_dict): -
sage/structure/sage_object.pyx
diff -r b766df9c3439 -r fba59ed64da6 sage/structure/sage_object.pyx
a b 518 518 def _maxima_init_(self): 519 519 import sage.interfaces.maxima 520 520 I = sage.interfaces.maxima.maxima 521 return self._interface_init_(I) 522 523 def _maxima_lib_(self, G=None): 524 if G is None: 525 import sage.interfaces.maxima_lib 526 G = sage.interfaces.maxima_lib.maxima_lib 527 return self._interface_(G) 528 529 def _maxima_lib_init_(self): 530 import sage.interfaces.maxima_lib 531 I = sage.interfaces.maxima_lib.maxima_lib 521 532 return self._interface_init_(I) 522 533 523 534 def _magma_init_(self, magma): -
sage/symbolic/expression.pyx
diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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 """