Creating a nonperiodic function in mathematica

I want to create a non-periodic square wave with values of 1 and -1(not necessarily alternating).

For e.g. I want to convert an arbitrary array like {1,-1,-1,1,-1,1,-1} into a function.

I tried using Piecewise but I don't know how to do this without typing a huge number of conditions.

I also want to add the length of each stack(i.e. the duration for which it is in 1 or -1) e.g. two inputs value={1,-1,-1,1,-1,1,-1} and duration={5,6,1,2,3,8,2}

P.S: The version I am using is 8.0.4.0

-

The edited question indicates that the function is supposed to be defined based on two lists - one for the values and one for their respective durations. Here is how you could do that:

vals = {1, -1, -1, 1, -1, 1, -1};
duration = {5, 6, 1, 2, 3, 8, 2};

f[v_, d_][x_] :=
Piecewise@
Transpose[{v, (#[[1]] <= x < #[[2]] &) /@
Partition[Accumulate[Prepend[d, 0]], 2, 1]}]

Plot[f[vals, duration][x], {x, 0, 40}, ExclusionsStyle -> Automatic,
Frame -> True]


The duration list is treated with Accumulate to get the absolute positions from the durations, and then a list of start and end points for the corresponding absolute intervals is created using Partition with an offset of 1 so that the end point of one interval is the start of the next. Then, Piecewise defines the whole thing as a function.

To plot the function with its vertical jumps displayed as lines, I set ExclusionsStyle -> Automatic.

-

Define a function:

f[x_, dat_] :=  Total@MapThread[#1 UnitBox[x - #2] &, {dat, Range[Length[dat]]}]


Test it on periodic data:

per = Cos /@ Range[0, 10 Pi, Pi]
{1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1}

Plot[f[x, per], {x, -1, 13}, AspectRatio -> 1/5, Filling -> 0]


Test it on non-periodic data:

aper = RandomChoice[{-1, 1}, 50];
Plot[f[x, aper], {x, -1, 53}, AspectRatio -> 1/5, Filling -> 0]


See the magnificent expression behind it - so you don't have to type it by hand ;) -

PiecewiseExpand[f[x, aper]]


In the above formula you can see discrete values 2 and -2 coming from the fact that UnitBox is defined as 1 at both of its boundaries. So the perfect definition of your function would really be with Clip added:

f[x_, dat_] :=  Total@MapThread[#1 UnitBox[x - #2] &, {dat, Range[Length[dat]]}]//Clip

-
Thanks for the answer.. I also want to add the length of each stack(i.e. the duration for which it is in 1 or -1) –  akhileshsk Feb 27 '13 at 7:16

Try Interpolation with InterpolationOrder->0, like so:

Plot[Interpolation[{1, -1, -1, 1, -1, 1, -1},
InterpolationOrder -> 0][x], {x, 1, 7}]


You can generalise and randomise like this:

mysquarewave[n_Integer?Positive] :=
Interpolation[RandomChoice[{-1, 1}, n], InterpolationOrder -> 0]


And then do things like this:

 Plot[mysquarewave[10][x], {x, 1, 10}]

-