Sage Sums
25 Feb 2021 - Tags: sage
Today I learned that sage can automatically
simplify lots of sums for us by interfacing with maxima.
I also learned recently that the init.sage
file exists, which let me fix some
minor gripes with my sage. Notably, I was able to add commands aa
and nn
which automatically get ascii art or a numeric answer for the most recent
expression! This is going to be a short post just to highlight how these things
work, since I had to figure them out for myself.
I was reading Concrete Mathematics the other night when I came across the section on Gosper’s Algorithm. This promises to solve a large class of sums (the hypergeometric ones) algorithmicaly, which is extremely alluring. I periodically find myself trying to simplify tricky sums (either for mse questions or for some problem I’m thinking about) and it would be nice to offload that thinking to a computer.
Unfortunately, googling around for “gosper’s method sage” and similar didn’t
actually give anything useful (at least not quickly). In hindsight, it turns
out there’s actually a gosper_sum
built in
(see the docs),
but for some reason I didn’t find it at the time. After some searching I instead
found a github repo that coded
up gosper’s algorithm, as well as a bunch of other algorithms from a book.
This was how I found my way to Petkovsek, Wilf, and Zeilberger’s
A=B, which has lots of similar
algorithms for algorithmically simplifying sums. It’s an extremely interesting
read, both mathematically and historically, and I’ve been enjoying it so far.
Before I learned it was built-in after all, I was planning to put up a blog post
with an implementation of gosper’s algorithm so that people could come here to
simplify their sums. Thankfully, I did eventually find the implementation, which
saved me a bunch of coding! Sage actually aliases over
python’s default sum
function, and will pass off symbolic sums to maxima
where they’re evaluated using tons of powerful techniques (one of which is
gosper’s algorithm). The reason I was having trouble finding a function for this
was (in part) because it’s baked into the sum
function already!
I’m still putting up this post, in part to share this realization with anyone else who didn’t know about it (which probably isn’t many people…), but in part to still provide a place where people can come to simplify sums. In case you don’t have a sage installation on your own computer, you can modify one of the examples below and evaluate your favorite summation here!
Let’s see some quick examples. The syntax sum(f,k,a,b)
corresponds to
$\sum_{k=a}^b f$.
This can solve fairly complex sums. These come from an exercise in A=B (exercise 1d and 1e from chapter 5). After seeing the solutions, I’m definitely glad I didn’t have to work them out by hand!
This has already helped me “in the wild”. There is an mse question which asked about the sum $\sum_{n=0}^\infty \frac{16n^2 + 20n + 7}{(4n+2)!}$. A commenter asks whether OP wants a closed form, or merely a convergence result. The sum certainly looks like it doesn’t admit a nice closed form, but I’ve been deceived before. Instead of wasting a few minutes trying to find a nice closed form (which is what I would have done even a few days ago), we can simply ask sage:
Sage happily computed a closed form for this sum… It just happens to use a bunch of hypergeometric functions! This pretty quickly answers the “does OP want a closed form” question, assuming OP’s professor isn’t a sadist1.
As an aside, in the above example we computed something exactly, but then
used .n()
in order to get a numerical value
(which is often better for getting a sense of things). Since sage will let you
write _
to get the output of the last command, _.n()
is probably my most
typed command. Either that or ascii_art(_)
, which draws an ascii version of
whatever your most recent output was. Since I use sage in a terminal, rather
than a jupyter notebook, this saves me endless parsing related headaches
when it comes to actually reading sage’s output.
If you also find yourself using these commands all the time, I can’t recommend
the following aliases enough. These are part of my init.sage
, and have changed
my life. If you want to see my entire sage configuration, you can find it
(with the rest of my dotfiles)
here.
Before I end this post, there are a few more parting observations that I want to squeeze in.
First, sage can solve recurrences for you as well,
by using either maxima’s solve_rec
or
sympy’s rsolve
. I
have a wrapper in my init.sage
that makes using the latter
slightly more convenient.
Second, if you’re faced with a particularly stubborn sum that sage won’t
simplify for you, you should try using maxima directly. You can actually
do this from inside sage by using maxima.console()
and then loading the
simplify_sum
package. You can see a worked out example
here, and you can see all the
high-power tools that simplify_sum
buys you
here.
-
Rather magically, though, this numerically agrees with $e + \sin(1)$ up to all available digits, according to an inverse symbolic calculator. Sage says this is a fluke (that is, they aren’t actually equal), but it’s an extremely bizarre coincidence. Life is full of mysteries. ↩