2
$\begingroup$

I have been working on code for finding the Allan plot of generated white noise, however, I cannot figure out a way to automate it for a different range of numbers. My code is as follows:

WN = WhiteNoiseProcess[NormalDistribution[0, 10]];
data = RandomFunction[WN, {1, 10000}];
m = 50;
points = data["Values"];
yBinLst = Partition[points, m];
meanLst = Mean /@ yBinLst;

allanVar = 
    Sum[(meanLst[[i + 1]] - meanLst[[i]])^2, 
    {i, 1, (Length[meanLst] - 1)}]/(2 (Length[yBinLst] - 1))

I want to be able to run this numerous times for different values of m and create a list of each m value with the the respective allanVar output. I read about Module and Tables, but everything I try gives me errors. As the code is right now, I can manually change the value of m and get different values, however, it is not very efficient.

$\endgroup$
  • $\begingroup$ You could try and turn your allanVar into a function of m: allanVar[m_]:=... $\endgroup$ – MarcoB May 19 '15 at 23:54
  • $\begingroup$ Well, in the time it took me to write that comment and start messing with the code, @MichaelE2 had already written and posted a full answer so I'll refer you to that for what I meant :-) $\endgroup$ – MarcoB May 20 '15 at 0:02
  • $\begingroup$ @MarcoB Thank you as well. I didn't expect such a complete answer so quickly. I posted this question and drove home, by the time I arrived, it had been answered. :O $\endgroup$ – Sean Alto May 20 '15 at 0:53
4
$\begingroup$

Here's a way to define a function that does your computation:

With[{WN = WhiteNoiseProcess[NormalDistribution[0, 10]]},
 aV[m_] := Module[{data, points, yBinLst, meanLst},
   data = RandomFunction[WN, {1, 10000}];
   points = data["Values"];
   yBinLst = Partition[points, m];
   meanLst = Mean /@ yBinLst;;

   Total[Differences[meanLst]^2]/(2 (Length[yBinLst] - 1))
   ]
 ]

Test:

SeedRandom[0];
aV[50]
(*  1.80707  *)

Iterating over values of m with Table

SeedRandom[0];
Table[aV[m], {m, 10, 50, 10}]
(*  {9.153, 4.66112, 3.45167, 2.80704, 1.87839}  *)

Iterating over values of m with Map

SeedRandom[0];
myValuesForM = {12, 33, 37, 50};
aV /@ myValuesForM
(*  {8.58519, 2.76198, 2.63612, 1.91234}  *)

Notes: The Sum is more efficiently computed with the built-in Differences and Total. Also Power (squaring) is vectorized so that squaring the whole list of differences is much more efficient on large amounts of data than squaring each difference separately.


Random obfuscations

Array[aV, 5, {10, 50}] (* where did they come up with this form for the iterator??? *)

myValuesForM /. m_Integer :> aV[m]

ClearAll[aV];
SetAttributes[aV, Listable]; (* makes aV[{a, b,...}] turn into {aV[a], aV[b],...} *)
(* def. above goes here *)
aV[myValuesForM]

...and finally, for those whose think hierarchical grouping is politically incorrect,

myValuesForM ~Part~ # & /* aV ~Array~ Length @ myValuesForM

More substitutes for the OP's Sum[(meanLst[[i + 1]] - meanLst[[i]])^2, {i, 1, (Length[meanLst] - 1)}]/(2 (Length[yBinLst] - 1)):

Norm[Differences[meanLst]]^2 (* from @Guess who it is. *)
#.# &@Differences[meanLst]   (* slightly faster *)
$\endgroup$
  • 1
    $\begingroup$ Norm[Differences[meanLst]]^2 can also be used in place of Total[Differences[meanLst]^2]. $\endgroup$ – J. M. will be back soon May 20 '15 at 0:39
  • $\begingroup$ @Michael E2 I am curious, which is the better option, Map or Table? I have only been working with Mathematica for roughly 2 weeks intensively (which is to say, each step which stumps me, leads me into researching the best method, so intensity is subjective). $\endgroup$ – Sean Alto May 20 '15 at 0:51
  • 1
    $\begingroup$ Actually, after some more musing, why not give aV the Listable attribute? @Sean, Table[] also happens to be usable for the Map[] example: Table[aV[m], {m, myValuesForM}]. $\endgroup$ – J. M. will be back soon May 20 '15 at 1:02
  • 1
    $\begingroup$ @Guesswhoitis. #.# &@Differences[meanLst] is a little faster than both. Sure, why not Listable? $\endgroup$ – Michael E2 May 20 '15 at 2:10
  • 1
    $\begingroup$ @SeanAlto For this application and as a new user, the differences are minor as both are comparably efficient. The most significant difference is the introduction of the dummy variable m in Table (which can have side-effects). Getting familiar with Map (conceptually) gives one a good tool for thinking through problems involving arrays of things. Other differences between Map and Table may be significant in different settings. Try to do this with Table: Map[f, {1, {2}, {{3}, 4}}, {-1}]. $\endgroup$ – Michael E2 May 20 '15 at 2:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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