# Plotting a periodic function

I want to plot a function that is abs(x) for -1<= x <= 1 and repeats to create a sawtooth shaped function. With the code

def h(x):
while x>1:
x=x-2
return abs(x)
h(4.3)


The Sage sell server tells me the value is 0.300000000000000, which is what I want as h(4.3)=h(2.3)=h(.3)=abs(.3) However, when I tried to plot h(x) with

def h(x):
while x>1:
x=x-2
return abs(x)
plot(h(x),x,0,5)


The plot looks like abs(x), so that h(4.3) now appears to be 4.3. What has gone wrong? How can I properly plot the h(x) I want?

EDIT: A points plot gives me the output I am expecting, which is different than plot(h(x),x,0,5).

def h(x):
while x>1:
x=x-2
return abs(x)

points([(x, h(x)) for x in srange(0,5,.01)], pointsize=20)

edit retag close merge delete

Sort by » oldest newest most voted

The way you define h makes it a Python function, so that, when you call h at the floating-point number 4.3, it is evalued by entering twice the while loop and then taking the absolute value of 4.3-2-2, that is 0.3.

However, when you call h at the symbolic expression x, the while loop is not entered since:

sage: bool(x>1)
False


hence, the abs function is called at the symbol x and what is returned is the abs(x) symbolic expression, see:

sage: abs
<built-in function abs>
sage: type(abs)
<class 'builtin_function_or_method'>

sage: abs(x)
abs(x)
sage: type(abs(x))
<class 'sage.symbolic.expression.Expression'>


Hence plot(h(x),x,0,5) is the same as plot(abs(x),x,0,5). The syntax plot(foo,x,0,5) is for plotting symbolic function, which is OK since abs(x) is a symbolic function, but it is not what you expected. If you want the plot function to evaluate the function foo at various floating-points between a and b to make the graphics, the syntax is just plot(foo,a,b), without mentionning any symbol.

Hence, you should simply call

sage: plot(h,0,5)

more

Good explanation! It clears up some misunderstandings I had.

( 2022-08-29 16:18:32 +0100 )edit

Instead of plot(h(x), x, -5, 5), try plot(h, (-5, 5)).

Note: the function may not be what you want for negative x.

One could also define h as a symbolic function without a while loop.

Here are two examples of doing that.

Using the floor function:

sage: h(x) = abs(x - 2 * floor((x + 1) / 2))
sage: plot(h, (-5, 5), aspect_ratio=1)
sage: plot(h(x), (-5, 5), aspect_ratio=1)


Using trigonometric functions:

sage: h(x) = arccos(cos(x*pi))/pi
sage: plot(h, (-5, 5), aspect_ratio=1)
sage: plot(h(x), (-5, 5), aspect_ratio=1)


In this case, both plot(h, (-5, 5)) and plot(h(x), (-5, 5)) give a correct plot.

more

Yes, I was going to add another while loop which kept adding 2 for values <-1 if I needed to graph the negative portion. The h(x) you've defined, though, is different than my h(x) because in mine h(x)>=0.

( 2022-08-30 00:08:29 +0100 )edit
1

Right, I had defined h(x) = x - 2 * floor((x + 1) / 2) but we want abs of that. Fixed now.

( 2022-08-30 15:04:34 +0100 )edit

Nice, +1: I especially like the one using trig functions.

( 2022-08-30 23:33:13 +0100 )edit