This page will point out interesting or odd behaviors of Sage and areas where it is either helpful or causes issues.
Return Type of integral and integrate
Depending on the value of the integral of a symbolic expression the return type will differ.
For example lets say we had the function and we call the integral function on it.
The Sage code would look like this:
f = x^2 + 1 result = integral( f )
The result is obviously
We can check the type of result by using the type function:
type( result )
If you input it into Sage you will see that the type is sage.calculus.calculus.SymbolicArithmetic.
Now let's look at another example where
Here the integral is
Sage code would look like this:
f = 1 / x result = integral( f ) type( result )
Here the type of result is sage.calculus.calculus.SymbolicComposition which differs from our previous example.
Why this is a problem
Sage's Maxima interface provides a variety of pattern matching functions, one of which is called freeof. freeof takes a pattern and an expression and returns true if the pattern is not found in the expression.
Sage code could look something like this:
f = x^2 + 1 maxima.freeof( x^3, integral( f ) )
Since the integral( f ) = maxima returns false like you would expect.
Now let's try it with our other example
f = 1 / x maxima.freeof( x^3, integral( f ) )
Since integral( f ) is it should return true, instead it appears the freeof function doesn't understand SymbollicComposition variables and Sage hangs requiring you to quit the worksheet before you can perform anymore calculations.
Parameter Passing and Graphics Objects
In Python parameter passing of objects is done by reference. So if you pass a mutable object to a function and modify that object then the original is modified. This only applies to mutable objects such as a list or dictionary. Strings and tuples are immutable and therefore any modification made to them in the function must make a copy since the original does not allow change.
Example: A function that appends an item to a list
def addItem( ls, item ): ls += item myList = [1,2] addItem(myList, ) print myList #Output: [1,2,3]
Example 2: A function that appends to a string
def appendString( s, addition ) s += addition myString = 'hello ' appendString( myString, ' joe') print myString #Output: hello
Even though the += operator is thought of as modifying the original since strings in Python are immutable += is actually creating a new string object containing the string referenced by lhs concatenated with the string referenced by rhs and assigning the reference of the string newly created string to the lhs.
The Graphics Object
Here is Sage's description of the Graphics Object:
The Graphics object is an empty list of graphics objects It is useful to use this object when initializing a for loop where different graphics object will be added to the empty object.
Based on this description you would think that a Graphics object was mutable since they encourage use of the += operator and with enough objects contained in a graphics object repeated copying could become an expensive process.
However after testing the behavior it appears that Graphics objects are immutable and += is actually making a copy.
def addLine( g ): g += line( [ (0,0),(1,1) ] ) g = Graphics() addLine( g ) print g #output Graphics object consisting of 0 graphics primitives
As you can see passing a graphics object to a function and using the += operator did not modify the original. This means that for a function to modify a Graphics object it must return back the copy created.
def addLine( g ): g += line( [ (0,0),(1,1) ] ) return g g = Graphics() g = addLine( g ) print g #output Graphics object consisting of 1 graphics primitive