Figuring out imports required when moving from a .sage to a .py file?

65 views
Skip to first unread message

Tom Kitchen

unread,
Oct 6, 2015, 9:30:19 AM10/6/15
to sage-devel
Hi,

I have recently installed sage from source and am trying to implement fourier transforms. I wrote a piece of sage code which does the job for some function f. 


var('t', 'k','x','a')
assume
(a > 0, k > 0)

# Define the function that that we will transform
f
= e^ - (a * abs(x))

# Apply the transform
def fourier(f,x,k):
    F
= (f * e ^ (-i * k * x)).integral(x, -oo,oo)
   
return(F.full_simplify())

print(fourier(f,x,k))



I then added a function in /src/sage/calculus.py, (E and I because capitals because of how they were imported)

def fourier(f, x, k):
    F
= f * E ** (-I * k * x)
   
return (F).integral(x, -oo,oo).full_simplify()


and I got some errors; first the constants e & i were not defined. I found e easily using the e?? functionality of sage but finding how to import i took a little more time because i?? didn't direct me to pynac.py where it is defined. Now I have a slightly more tricky error which will take a bit of reading on my part to debug (.

Traceback (most recent call last):
  File "test.sage.py", line 17, in <module>
    print(f.fourier(x,k))
  File "sage/symbolic/expression.pyx", line 11365, in sage.symbolic.expression.Expression.fourier (/home/tom/sage/src/build/cythonized/sage/symbolic/expression.cpp:60975)
  File "/home/tom/sage/local/lib/python2.7/site-packages/sage/calculus/calculus.py", line 1413, in fourier
    ex = f * E ** (-I * var(k) * var(x))
  File "sage/symbolic/expression.pyx", line 3572, in sage.symbolic.expression.Expression.__pow__ (/home/tom/sage/src/build/cythonized/sage/symbolic/expression.cpp:22299)
  File "sage/symbolic/expression.pyx", line 2724, in sage.symbolic.expression.Expression.coerce_in (/home/tom/sage/src/build/cythonized/sage/symbolic/expression.cpp:19690)
  File "sage/structure/parent_old.pyx", line 239, in sage.structure.parent_old.Parent._coerce_ (/home/tom/sage/src/build/cythonized/sage/structure/parent_old.c:4448)
  File "sage/structure/parent.pyx", line 1330, in sage.structure.parent.Parent.coerce (/home/tom/sage/src/build/cythonized/sage/structure/parent.c:10924)
  File "sage/structure/element.pxd", line 17, in sage.structure.element.parent_c (/home/tom/sage/src/build/cythonized/sage/structure/parent.c:28387)
TypeError: descriptor 'parent' of 'sage.structure.element.Element' object needs an argum

Is there a better way for me to change my sage code to python code? perhaps a piece of code that tells me which sage dependencies I am using? or can you submit straight up sage code and not even bother to convert it to python?

Travis Scrimshaw

unread,
Oct 6, 2015, 10:14:46 AM10/6/15
to sage-devel
Hey Tom,
   Welcome! I'm actually surprised we don't have this functionality in Sage (at least as a naive implementation)...

For the imports, I think you would be interested in the following:

sage: import_statements(e)
from sage.symbolic.constants import e
sage
: import_statements(i)
from sage.symbolic.all import i

You will likely want to put the import statements at the beginning of calculus/calculus.py with the rest of the imports. Also I believe the lowercase variables are what you want.

Additionally, there is already a ticket about this (6 years ago!) http://trac.sagemath.org/ticket/8338. I would also consider adding a version based upon the Laplace transform as indicated on the ticket and seeing which implementation is faster. Specifically, I would do something like this:

def fourier(x, algorithm=DEFAULT):
   
if algorithm == 'integral':
       
return direct_integral_version
   
elif algorithm == 'laplace':
       
return via_laplace_transform
   
else:
       
raise ValueError("invalid algorithm")

where DEFAULT is whichever algorithm we decide is the default (based upon speed and generality).

Best,
Travis

Travis Scrimshaw

unread,
Oct 6, 2015, 10:17:25 AM10/6/15
to sage-devel
Something else to consider is that Sage has a preparser and that can come into play. To see what the preparser does to commands, you can do this:

sage
: preparse("F = e*x")
'F = e*x'
sage
: preparse("F(x) = e*x")
'__tmp__=var("x"); F = symbolic_expression(e*x).function(x)'

Best,
Travis


Tom Kitchen

unread,
Oct 6, 2015, 10:40:43 AM10/6/15
to sage-devel
Thankyou for all that information. I'm sure I will have some more questions once I have had a chance to chew through all of that.

Simon King

unread,
Oct 7, 2015, 7:35:09 AM10/7/15
to sage-...@googlegroups.com
Hi Tom!

In addition to Travis' reply:

On 2015-10-06, Tom Kitchen <tomkit...@googlemail.com> wrote:
> I have recently installed sage from source and am trying to implement
> fourier transforms. I wrote a piece of sage code which does the job for
> some function f.
>
>
> var('t', 'k','x','a')

As much as I know, just doing var('t') in an interactive session will create
a variable called t *and* will insert it into the global name space, so
that subsequently if the user types "t" then the variable t is returned.

However, that's not possible when you create a .py module. There, you
need to assign the resulting symbolic variables to Python variables, which of
course do not necessarily have the same name as the symbolic variables.
So, you could do
X,Y,Z = var('x', 'y', 'z')
(but probably your symbolic and Python variables should have the same
name, thus, x,y,z=var('x','y','z'))

Best regards,
Simon

Reply all
Reply to author
Forward
0 new messages