# Adding a piece-wise function and its shifted version by list manipulations

I have a piecewise function represented by two lists,

x= {0, 30, 60, 120, 150, 180};
y= {0, 1, 0, -1, 0};


and the plot of this function is

.

Now I would like to shift this function horizontally by an arbitrary angle and then add the shifted version to the original one. The original one can be thought of as periodic with a fundamental period of 180 degrees. For simplicity, shift it 15 degrees to the right and the sum should be something like this

By my previous convention, this result should be represented by x1= {30, 45, 60, 75, 120, 135, 150, 165}, y1= {0, 1, 2, 1, 0, -1, -2, -1, 0}. My question is, what can be one of the least complicated ways to obtain this result, particularly the vertical value list y1 above, by using list manipulations?

x = {0, 30, 60, 120, 150, 180};
y = {0, 1, 0, -1, 0};

f[z_] := Piecewise @ Transpose @ {y, Less @@@ Insert[z, 2] /@ Partition[x, 2, 1]}
f[z]


Plot[f[z], {z, 0, 180}, Exclusions -> None]


Plot[f[z] + f[z - 15], {z, 0, 180}, Exclusions -> None]


g[z_] := f[z] + f[z - 15]

PiecewiseExpand @ g[z]


args = Join[{0, 180},
z /. (Reduce[Not@Reduce[D[g[z], z] ∈ Reals, z], z] //
ToRules // List)] // Sort // DeleteDuplicates


{0, 30, 45, 60, 75, 120, 135, 150, 165, 180}

g[#] & /@ (RandomReal[#] & /@ Partition[args, 2, 1])


{0, 1, 2, 1, 0, -1, -2, -1, 0}

There's also an undocumented function converting Piecewise to UnitStep (thanks to xzczd):

SimplifyPWToUnitStep @ g[z]


• I'm interesting about how do you dig to get that? – yode Dec 14 '16 at 13:41
• Yep,I have.Thanks. :) – yode Dec 14 '16 at 14:14

You can also use UnitBox, e.g.

f[x_] := UnitBox[(x - 30)/30 - 1/2] - UnitBox[(x - 120)/30 - 1/2]
Plot[f[x] + f[x - 15], {x, 0, 200}]


Update

I add this to address Mr. Wizard's comment. There are many ways and probably better but to get corners:

g[x_] := f[x] + f[x - 15]
pts = {u,
g[u]} /. {ToRules@Reduce[Not[FunctionDomain[D[g[u], u], u]], u]};
{xs, ys} = Transpose[pts]
Plot[g[x], {x, 0, 200},
Epilog -> {Blue, PointSize[0.02], Point[Thread[{xs, 0}]]},
Exclusions -> None]


Correction

To deal with the dfference between the definition of UnitBox and the desired outcome a small offset to get what is aimed for:

ptscorr = {u,
g[u - 0.01]} /. {ToRules@
Reduce[Not[FunctionDomain[D[g[u], u], u]], u]};
{xscorr, yscorr} = Transpose[ptscorr]


yields:

{30, 45, 60, 75, 120, 135, 150, 165}, {0, 1, 2, 1, 0, -1, -2, -1}}

• How would you convert the UnitBox expression into the x1/y1` output shown? – Mr.Wizard Dec 8 '16 at 6:50
• @Mr.Wizard I have updated to address your comment ( I hope). It could be done a few ways but something different. This spider built an elaborate web in my garden and made me think of you. I hope you pass "happy holidays". On a selfish note: I have always wanted to post on the "i've passed 5000" but have never found an interesting enough number and am too inept to game. 40000 was a nice milestone in an otherwise terrible year :) – ubpdqn Dec 8 '16 at 7:11
• You already had my vote but now the answer is even better. I am happy that a wonder of nature makes you think of me. I am not happy to hear that you have had a terrible year. I hope that things have turned around now, whatever the circumstance. – Mr.Wizard Dec 8 '16 at 7:18