# How to express a periodic piecewise linear function in terms of Mod function? or linear combination of Mod?

I am programming a small game (with other programming language) in which I have to use Mod function to express piecewise linear period functions.

In my case, two hard parts I think exist.

(1) The periodic function is linear in the piecewise sence, like the function below. In a full period it is NOT linear.

(2) There are NO powerful function like Piecewise function in Mathematica, and all I can use are some very basic functions including Mod, +,-, *, \, Abs, Floor, Ceiling,Exp,10^,Sin,Cos,Tan,ASin,ACos, ATan,Log and logic control commands If, If Then Else.

(3) After many times trying, I also found another challenging part is related to Mod of a negative number .My piecewise linear periodic function can thake negative integers whose Mod is so confusing to me. I can calculate the Mod of a negative number by hand, but I have no clear idea how it relates to a repeat pattern.

So is it possible to use Mathematica to find something like linear combinations of Mod functions for any periodic piecewise linear function?

For example, the periodic piecewise linear period function like this:

f[x_?IntegerQ] :=
Piecewise[{{-10 x + 2, 1 <= x < 4}, {-5 x + 8, 4 <= x <= 10}}, True]
f[x_?IntegerQ] := f[x + 10] /; x < 1
f[x_?IntegerQ] := f[x - 10] /; x > 10
ListPlot[Table[{x, f[x]}, {x, -9, 20}]]


Any advices are highly appreciated! Thanks :) • What about period = 10; ListPlot[Table[{x, Mod[x, period, 0]}, {x, -9, 20}]]? Jan 24, 2022 at 13:41
• Partly similar to this.
– Syed
Jan 24, 2022 at 13:43
• Thanks, but in my problem the repeated part is a combination of two different linear functions, that is the linear functions on [1,4) and [4,10] are different. Jan 24, 2022 at 13:47
• Does your other programming language's mod() function work exactly like Mod[]? I doubt it: Both Mod[x, m] and Mod[x, m, x0]? Mod[x + m, m] == Mod[x, m], even when -m < x < 0? It seems necessary to know how the functions in both Mathematica and the target language work to know how to solve the problem. Jan 24, 2022 at 17:27
• @MichaelE2 Thanks for you answer, very inspring. Actually, my target programming language is Scratch (scratch.mit.edu), and it dosen't support Mod[x, m, x0] and Mod[x + m, m] == Mod[x, m]. My naive idea is to use a guess form of Mod linear combination to fit the data generated by original piecewise linear function. I will think more on your great answer. Thanks :) Jan 25, 2022 at 1:28

Here's a way to take advantage of Mathematica's code generation capabilities. In particular we take advantage of two internal workhorses, SimplifyPWToUnitStep and ExperimentalOptimizeExpression. You should check to see if your library has a unit step function, and if so, you can just use the output of SimplifyPWToUnitStep, inserting x = Mod[y, 10] for input y, and avoid the rest of the trickery.

(* Auxiliary functions *)
ifArithmeticRules = {
Times[z_, If[c_, a_, b_]] :> With[{i = If @@ {c, a*z, b*z}}, i /; True],
Plus[z_,  If[c_, a_, b_]] :> With[{i = If @@ {c, a+z, b+z}}, i /; True]};
compileToTempVars =
With[{c = #[[1, 1]]}, # /.
Thread[c -> Block[{nnn = 1}, Symbol["tmp" <> ToString[nnn++]] & /@ c]]
] &;

SimplifyPWToUnitStep[
Piecewise[{{-10 x + 2, 1 <= x < 4}, {-5 x + 8, 4 <= x <= 10}}]
] // ReplaceAll[{
x -> Mod[x, 10],             (* adjust if Mod[] != mod() *)
UnitStep -> (Inactive[If][#>=0,1,0]&)  (* is translating UnitStep[] necessary? *)
}] //
ExperimentalOptimizeExpression //
Activate //     (* If had to be Inactive[] for condition to be optimized *)
compileToTempVars //              (* optional: change variable names *)
ReplaceRepeated@ifArithmeticRules  (* not needed if you can use UnitStep[] *)

(*
ExperimentalOptimizedExpression[Block[{tmp1, tmp2, tmp3, tmp4},
tmp1 = Mod[x, 10];
tmp2 = -4 + tmp1;
tmp3 = tmp2 >= 0;
tmp4 = If[tmp3, 1, 0];
If[10 - tmp1 >= 0,
If[-1 + tmp1 >= 0,
-2 (-1 + 5 tmp1) (1 - tmp4) + (8 - 5 tmp1) tmp4,
(8 - 5 tmp1) tmp4],
If[-1 + tmp1 >= 0, -2 (-1 + 5 tmp1) (1 - tmp4),
0
]]]]
*)

• You'll have to adjust Mod[x, 10] if your mod() function works differently. Jan 24, 2022 at 18:13