ASKSAGE: Sage Q&A Forum - Individual question feedhttp://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 22 Feb 2017 15:18:47 -0600Taylor Series With Order (Big O)http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/ I'm trying to replicate some Mathematica code, and I know very little about Mathematica and Sage.
The Mathematica code creates a Taylor series for f(x) about (x0), with degree 5. I was able to replicate that.
x, x0, dt = var('x, x0, dt')
f = function('f')
t = f(x).taylor(x, x0, 5)
Next it does a substitution.
k1 = f(x0)*dt
s = x0 + k1/2
k2 = t.subs(x=s)
The problem is it that it then removes the higher order terms using the big O notation.
k2 = Expand[g[x] \[CapitalDelta]t /. x -> s] + O[\[CapitalDelta]t]^5
It looks like this is available for series and polynomial rings (no clue what those are) in SageMath, but I haven't figured out how to apply it to the Taylor series expansion.
Is there a way to truncate certain order terms off of an expression?
Is there a way to replicate the Taylor series expression I want with `.series()` or polynomial rings?
I tried importing `sage.rings.big_oh` and using `Order()` but neither seemed applicable to the expression I had. I also made half an attempt to recreate a Taylor series with `.series()` but didn't quite get what I was hoping for.
tq = 1/factorial(n)*f(x)*x^n
tq.series(n, 5)
Thanks for the help, both my math and SageMath skills are lacking.Sun, 19 Feb 2017 16:56:02 -0600http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/Answer by nbruin for <p>I'm trying to replicate some Mathematica code, and I know very little about Mathematica and Sage.</p>
<p>The Mathematica code creates a Taylor series for f(x) about (x0), with degree 5. I was able to replicate that.</p>
<pre><code>x, x0, dt = var('x, x0, dt')
f = function('f')
t = f(x).taylor(x, x0, 5)
</code></pre>
<p>Next it does a substitution. </p>
<pre><code>k1 = f(x0)*dt
s = x0 + k1/2
k2 = t.subs(x=s)
</code></pre>
<p>The problem is it that it then removes the higher order terms using the big O notation.</p>
<pre><code>k2 = Expand[g[x] \[CapitalDelta]t /. x -> s] + O[\[CapitalDelta]t]^5
</code></pre>
<p>It looks like this is available for series and polynomial rings (no clue what those are) in SageMath, but I haven't figured out how to apply it to the Taylor series expansion. </p>
<p>Is there a way to truncate certain order terms off of an expression?</p>
<p>Is there a way to replicate the Taylor series expression I want with <code>.series()</code> or polynomial rings?</p>
<p>I tried importing <code>sage.rings.big_oh</code> and using <code>Order()</code> but neither seemed applicable to the expression I had. I also made half an attempt to recreate a Taylor series with <code>.series()</code> but didn't quite get what I was hoping for.</p>
<pre><code>tq = 1/factorial(n)*f(x)*x^n
tq.series(n, 5)
</code></pre>
<p>Thanks for the help, both my math and SageMath skills are lacking.</p>
http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/?answer=36699#post-id-36699While manipulating the expression tree explicitly certainly solves your problem, it might be worthwhile seeing a solution that's a little more general (also: you might want to truncate throughout rather than only at the end, because a lot of time and memory might get devoted to computing the higher order terms that get discarded anyway).
You can get a result by turning the thing into a power series object over SR:
sage: e = x*dt + x*x0*9*dt^2 + x*100*dt^3
sage: R.<DT>=PowerSeriesRing(SR)
Ideally at this point you'd use `e(dt=DT)` to turn the object into what you want. Unfortunately that doesn't work because of the ambiguity of whether R maps into SR or SR into R. It would be nice if coercion could figure out SR mapping into R here, but currently it doesn't. But we can do it manually without having to go all the way to expression tree manipulation:
sage: E=sum(c*DT^i for c,i in e.coefficients(dt)); E
x*DT + 9*x*x0*DT^2 + 100*x*DT^3
Now we have an object that understands big-Oh:
sage: E+O(DT^3)
x*DT + 9*x*x0*DT^2 + O(DT^3)
Wed, 22 Feb 2017 15:18:47 -0600http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/?answer=36699#post-id-36699Answer by douggard for <p>I'm trying to replicate some Mathematica code, and I know very little about Mathematica and Sage.</p>
<p>The Mathematica code creates a Taylor series for f(x) about (x0), with degree 5. I was able to replicate that.</p>
<pre><code>x, x0, dt = var('x, x0, dt')
f = function('f')
t = f(x).taylor(x, x0, 5)
</code></pre>
<p>Next it does a substitution. </p>
<pre><code>k1 = f(x0)*dt
s = x0 + k1/2
k2 = t.subs(x=s)
</code></pre>
<p>The problem is it that it then removes the higher order terms using the big O notation.</p>
<pre><code>k2 = Expand[g[x] \[CapitalDelta]t /. x -> s] + O[\[CapitalDelta]t]^5
</code></pre>
<p>It looks like this is available for series and polynomial rings (no clue what those are) in SageMath, but I haven't figured out how to apply it to the Taylor series expansion. </p>
<p>Is there a way to truncate certain order terms off of an expression?</p>
<p>Is there a way to replicate the Taylor series expression I want with <code>.series()</code> or polynomial rings?</p>
<p>I tried importing <code>sage.rings.big_oh</code> and using <code>Order()</code> but neither seemed applicable to the expression I had. I also made half an attempt to recreate a Taylor series with <code>.series()</code> but didn't quite get what I was hoping for.</p>
<pre><code>tq = 1/factorial(n)*f(x)*x^n
tq.series(n, 5)
</code></pre>
<p>Thanks for the help, both my math and SageMath skills are lacking.</p>
http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/?answer=36692#post-id-36692Decided to just write this myself. Found the expr2tree() function [here](https://trac.sagemath.org/ticket/9329).
x, x0, dt = var('x, x0, dt')
def expr2tree(expr):
if expr.operator() is None:
return expr
else:
return [expr.operator()]+map(expr2tree, expr.operands())
def tree2expr(tree):
args = []
for ea in tree[1:]:
if type(ea) is list:
args.append(tree2expr(ea))
else:
args.append(ea)
return tree[0](*args)
def remove(tree, var, exp):
if type(tree) != list:
return False
if not hasattr(tree[0], '__name__'):
return False
if tree[0].__name__ == 'pow':
if tree[1] == var and tree[2] >= exp:
return True
for ea in tree[1:]:
if remove(ea, var, exp):
return True
return False
def truncate_terms(expr, term):
orig = expr
expr = expr.expand()
tree = expr2tree(expr)
# check is addition
if tree[0].__name__ != 'add_vararg':
return expr
# expand term (eg. dt^5)
term_tree = expr2tree(term)
if term_tree[0].__name__ != 'pow':
return expr
var, exp = term_tree[1:3]
args = []
for ea in tree[1:]:
if not remove(ea, var, exp):
args.append(ea)
return tree2expr([tree[0]] + args)
Test:
e = x*dt + x*x0*9*dt^2 + x*100*dt^3
truncate_terms(e, dt^3)
Output:
9*dt^2*x*x0 + dt*xTue, 21 Feb 2017 18:10:38 -0600http://ask.sagemath.org/question/36665/taylor-series-with-order-big-o/?answer=36692#post-id-36692