# A piecewise function with way too many pieces

I'm currently calculating a periodic square wave current function to feed into a particle accelerator. It's a square wave that ramps up to a certain frequency and then drops back to the base frequency and starts all over.

Between Mathematica and an iterative python script, I managed to get a list of 308 times (between t=0 and t=8.4*10^-6) when the voltage needs to flip from high to low, or the reverse.

Basically, I have a giant CSV from the python script that I have read into Mathematica as a list of values. At t=0, the voltage will be at 5000, and it should flip between 5000 and 0 at each time value in the list.

Is there a better way than using Python to construct a mile-long function using Piecewise that lists all the intervals where it should be on high voltage? Is there a way to make it periodic, so that repeats on modulo (2*Last[b] - Part[b,-2])?

Finally, is there a way to have Mathematica try to calculate the Fourier transform of this ugly piecewise function so that I can more easily port it into MATLAB for use with the function generator?

Python script generating values

Somewhat terrible drawing of this graph (black is my values, red line is where it should become periodic):

How I'm importing:

b = Import["C:\\Users\\user\\Desktop\\calculations\\swaptimes.txt",
"List"]

• You know that SquareWave[] is built-in? – J. M. is away Oct 16 '15 at 18:25
• SquareWave is for constant period- my function's period changes. Read the question. – laudiacay Oct 16 '15 at 18:34
• Can you provide a small list and expected output to get the picture of what you are after? – garej Oct 16 '15 at 18:58
• How does the frequency ramp up? Can it be described in a function? If so then use that function as an argument to SquareWave mentioned by @J.M.isback. – Matariki Oct 16 '15 at 19:02
• @Matariki Right now, I'm generating the list of when to change the voltage with the script in the pastebin. I don't think this could be put into a function, but if you have an idea, hit me. Every number that the function prints is a time that the voltage would need to change. pastebin.com/FyrNBGKz – laudiacay Oct 16 '15 at 19:15

something like this:

 times = Join[{0}, Sort@RandomReal[100, {20}], {100}];
f = Interpolation[
MapIndexed[ {#, 5000 Boole@EvenQ[First@#2]} &, times],
InterpolationOrder -> 0];
Plot[f[x], {x, 0, 100}]


now make periodic: (edit revised so its scaled he same as your data I think)

 tper=8.4*10^-6;
times = Join[{0}, Select[Accumulate@
Sort@RandomReal[{.01, .4} tper, {100}], # < tper &], {tper}];
f = Interpolation[
MapIndexed[{#, 5000 Boole@EvenQ[First@#2]} &, times],
InterpolationOrder -> 0];
g[x_] := f[Mod[x, tper ]]
Plot[g[x], {x, -tper , 2 tper }, PlotPoints -> 1000]


I do not readily see a nice way to compute a FourierTransform of this: I'd suggest you might break that out as a new question.

• I'm not really sure how your code works, but I subbed in my list for times, and got the following error: InterpolatingFunction::dmval: "Input value {0.00204286} lies outside the range of data in the interpolating function. Extrapolation will be used." I am probably making a mistake. – laudiacay Oct 16 '15 at 19:26
• Update: just realized that your (working) code gives this error as well. However, when I run it with my values, it plots nothing anyway. – laudiacay Oct 16 '15 at 19:35
• Be sure to include zero in your list. See my edit, that's what the Join[{0}.. does. – george2079 Oct 16 '15 at 19:36
• Mine looks, well, constant at 5000. – laudiacay Oct 16 '15 at 19:39