Ask Your Question

defining periodic functions

asked 2010-12-08 13:36:18 +0100

updated 2010-12-08 14:08:07 +0100

I'm trying to plot approximations to McCarthy's continuous nowhere differentiable function (PDF file). The definition is like this: first, define a function $g(x)$ to be a triangle wave: $$g(x) = 1+x \ \text{ if } -2 \leq x \leq 0, \quad g(x) = 1-x \ \text{ if } 0 \leq x \leq 2$$ and then require $g$ to be periodic with period 4. Then McCarthy's function is $$f(x) = \sum_{n=1}^{\infty} 2^{-n} g(2^{2^{n}} x).$$

How should I set this up in Sage? If I define g(x) by

def g(x):
    if -2 <= x and x <= 0:
        return 1+x
    elif 0 < x and x <= 2:
        return 1-x
    elif x > 2:
        return g(x-4)
    return g(x+4)

and then try to plot the 4th partial sum for $f(x)$, I get an error about "maximum recursion depth exceeded". I get the same error if I try plot(g, (x, 10000, 10010)). Is there a better way of defining a periodic function like $g$? I guess I can do something like while x>2: x = x-4, etc., but my real question is, can I define such a function symbolically rather than as a Python function?

Edit: my current fastest version of this function is as follows:

def g(float x):
    x = abs(x)
    x = 4.0*(x/4.0 - int(x/4.0))
    if x <= 2:
        return 1-x
    return -3+x

Even if it's not possible to write this symbolically, how can I speed this up?

edit retag flag offensive close merge delete


The link you gave does not seem to be working anymore. The current location seems to be [here](

Andres Caicedo gravatar imageAndres Caicedo ( 2013-11-07 20:31:56 +0100 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2010-12-08 18:39:39 +0100

updated 2010-12-08 18:41:40 +0100

Here are a few minor suggestions for squeezing out a little extra speed in your function.

In the Cython code you wrote above you use the Python abs and int function. This induces coercion of your fast C-data types to slow Python-data types. I suggest starting your speedups by using the C-abs function and <int>, instead.


cdef extern from "math.h":
    double fabs(double)

cpdef double g2(double x):
    x = fabs(x)
    x = 4.0*(x/4.0 - <int>(x/4.0))
    if x <= 2.0:
        return 1.0-x
    return -3.0+x

I tried using floor(fabs(x/4.0)) instead of <int>(x/4.0) but I didn't get any additional speedup. Also, cpdef improves performance if you call this function from Cython code. In particular, the $f(x)$ you define above should be a Cython function as well so you can take full advantage of the Cython speed benefits.

edit flag offensive delete link more

answered 2010-12-08 15:20:19 +0100

kcrisman gravatar image

What I would do, if you really wanted to do this semi-symbolically, is to use Piecewise to create a piecewise function that does $g(x)$ as far out as you need it to go. I guess to plot it out to $n=5$ and $x=1$ would require you to have $g$ out to $2^{32}$... hmm, that seems pretty far!

So you could do this symbolically in Sage, but I don't know that it's actually practical. Probably asking to speed it up would be better. Unfortunately, as you know, piecewise support isn't so hot. It would be great to have piecewise + periodic... sigh.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2010-12-08 13:36:18 +0100

Seen: 1,914 times

Last updated: Dec 08 '10