# Defining a periodic function.

Hi,

I am a new sage user. I'd like to define simple periodic maps over \R which plot and integrate correctly (eg. a square signal (which of course is discontinuous but which I would still like to be able to plot in a way that makes it clear that the function is not multivalued at discontinuity points)). I tried different approaches none of which gave satisfactory results.

Any hint on how to do that nicely (or what would be the obstacles)?

Thank you

edit retag close merge delete

Sort by » oldest newest most voted

You should tell us about your different approaches, and what was wrong with them. I am not sure whether you ask about defining a function or plotting it. Here would be my direct lazy approach, without more informations about your needs. To define a periodic function, use the .frac() method of real numbers. In your case:

sage: f = lambda x: 1 if RR(x).frac() < 1/2 else 0
sage: plot(f, 0, 4)


If you do not like the vertical line at the discontinuities, you can look at the options of the plot() function:

sage: plot?


In your case, you can try:

sage: plot(f, 0, 4, plot_points='1000', linestyle='', marker='.')


For the integral, since the finction is defined point by points (not a symbolic function), you can do a numerical integration:

sage: numerical_integral(f, 0, 4)
(2.0, 2.2315482794965646e-14)

more

frac() gives a function which is periodic on positive reals. I just adapted your solution to get it periodic on \RR.

f = lambda x: 1 if (x - RR(x).floor()) < 1/2 else 0


I would have liked to be able to define a symbolic function though. Is it doable?

I was also trying to get a function whose plot is correct (without asking it to be pointwise) as it is the case for Piecewise().

Below are some of the things (not chronologically ordred though) I had tried (just for completness as I guess they are just full of beginer's classical mistakes).

f(x)=sum((-1)^k*unit_step(x-k),k,0,infinity)


which does not evaluate

f1(x)=0
f2(x)=1
h=Piecewise([[(-oo,0),f1],[(0,1),f2],[(1,2),f1],[(2,+oo),f1]],x)
h.plot()


returns ValueError: cannot convert float NaN to integer.

f(x)=sum(h(x-2*k),k,0,infinity)


returns ValueError: Value not defined outside of domain.

f(x)=sum(h(x-2*k),k,0,4)


also returns ValueError: Value not defined outside of domain.

I also tried to redefine unit_step:

def echelon_unite(x):
#
if x<0:
hres=0
else:
hres=1
return hres


problem integral(echelon_unite(x),x,-10,3) returns 13

numerical integral returns a coherent result.

Other tentative with incoherent result (still with integrate and not numerical_integral)

  def Periodisation_int(f,a,b):
x = var('x')
h0(x) = (x-b)-(b-a)*floor((x-b)/(b-a))
hres = compose(f,h0)
return hres

sage: g=Periodisation_int(sin,0,1)
sage: integrate(g(x),x,0,2)
-cos(1) + 2
sage: integrate(g(x),x,0,1)
-cos(1) + 1
sage: integrate(g(x),x,1,2)
-1/2*cos(1) + 1


My guess is I was using integrate on inappropriate objects. I would still like to know how to define corresponding symbolic function (if it is possible).

Thanks again,

best regards.

more

The object you get out of Periodisation_int is not a symbolic function, but when you call it with x you get a symbolic expression anyway, so it doesn't really matter (and most symbolic machinery is for expressions anyway). If you really want a symbolic function you can do:

def per(f,a,b):
x = SR.var('x')
CSRx = CallableSymbolicExpressionRing( (x,))
t = f((x-b)-(b-a)*floor((x-b)/(b-a)))
h = CSRx(t)
return h


where the whole bit with CSRx is to actually get a symbolic function (something you can call). I'm not so sure that integrate knows what to do with this symbolic function, though.

more