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|improve this question

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|improve this answer

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|improve this answer
    
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|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.