Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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}

Please Help

P.S: The version I am using is 8.0.4.0

share

3 Answers 3

up vote 6 down vote accepted

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]

piecewise

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.

share

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]

enter image description here

Test it on non-periodic data:

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

enter image description here

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

PiecewiseExpand[f[x, aper]]

enter image description here

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
share
    
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}]

enter image description here

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}]
share

This site is currently not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .