I would like to suggest a way for defining non-trigonometric periodic functions. Namely, if f(x) is defined on [a,b], then F(x)=f(x-T*floor((x-a)/T)), where T=b-a, is periodic with period T where the segment of graph of f on [a,b] is repeated. This could be automated with the following code:
Code : Tout sélectionner
gen _periodic(const gen & g,GIAC_CONTEXT) {
    if (g.type==_STRNG && g.subtype==-1) return g;
    if (g.type!=_VECT || g.subtype!=_SEQ__VECT)
        return gentypeerr(contextptr);
    vecteur & gv = *g._VECTptr;
    if (gv.size()!=4 && gv.size()!=2)
        return gensizeerr(contextptr);
    gen & e=gv[0],x,a,b;
    if (e.type!=_SYMB)
        return gentypeerr(contextptr);
    vecteur vars(*_lname(e,contextptr)._VECTptr);
    if (vars.empty())
        return e;
    if (gv.size()==2) {
        if (!gv[1].is_symb_of_sommet(at_equal))
            return gentypeerr(contextptr);
        vecteur & fl=*gv[1]._SYMBptr->feuille._VECTptr;
        if ((x=fl[0]).type!=_IDNT || !fl[1].is_symb_of_sommet(at_interval))
            return gentypeerr(contextptr);
        vecteur & ab=*fl[1]._SYMBptr->feuille._VECTptr;
        a=ab[0];
        b=ab[1];
    }
    else {
        x=gv[1];
        if (x.type!=_IDNT)
            return gentypeerr(contextptr);
        if (find(vars.begin(),vars.end(),x)==vars.end())
            return e;
        a=gv[2];
        b=gv[3];
    }
    gen T(b-a);
    if (!is_strictly_positive(T,contextptr))
        return gentypeerr(contextptr);
    gen p(subst(e,x,x-T*_floor((x-a)/T,contextptr),false,contextptr));
    return _unapply(makesequence(p,x),contextptr);
}
static const char _periodic_s []="periodic";
static define_unary_function_eval (__periodic,&_periodic,_periodic_s);
define_unary_function_ptr5(at_periodic,alias_at_periodic,&__periodic,0,true);Code : Tout sélectionner
periodic(f(x),x,a,b)Code : Tout sélectionner
periodic(f(x),x=a..b)Code : Tout sélectionner
f:=periodic(x^2,x,-1,1);
plot(f(x),x=-5..5)