Re: New User - Programming

*To*: mathgroup at smc.vnet.net*Subject*: [mg52540] Re: [mg52507] New User - Programming*From*: Daniel Lichtblau <danl at wolfram.com>*Date*: Wed, 1 Dec 2004 05:58:10 -0500 (EST)*References*: <200411301024.FAA01340@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

Dean Williams wrote: > I am a new user who is well and truly stuck. Any help would be greatly > appreciated. > > I have two lists, a and b, that when compared, will produce a third > list of signals. This third list is then summed to get a cumulative > total of the signals. > > The rules are fairly simple. If a = b, the signal is 0, if a > b, the > signal is 1 and finally, if a < b, then the signal is ?1. > > > a={5,6,3,2,8,2}; > b={5,4,1,3,9,4}; > c={a,b}; > > p=0; > > Fun[t_,u_]/;t==u :=0; > Fun[t_,u_]/;t>u:=1; > Fun[t_,u_]/;t<u:=-1; > > signal=Map[ (Fun[#[[1]],#[[2]]])&,Transpose[c]]; > > c4={signal}; > > cumTotal=Flatten[Map[p+={Last[#]} &,Transpose[c4]]]; > > > TableForm[{a,b,signal,total},TableDirections->Row, > TableHeadings->{{"a","b","Signal","Cumm.Total"},None}, > TableSpacing->{4,4,4,4,4}] > > > a b Signal Cum.Total > > 5 5 0 0 > > 6 4 1 1 > > 3 1 1 2 > > 2 3 -1 1 > > 8 9 -1 0 > > 2 4 -1 -1 > > > > > I want to modify slightly how the signal is generated. The rules are > the same except that if the cumulative total is already 1 or -1, then > no new signal is generated unless the new signal would make the > cumulative total move back towards zero. > > Ideally, I am looking to modify my code, so it produces, signal = > {0,1,0,-1,-1,0} and cumTotal = {0,1,1,0,-1,-1}.The maximum size of the > cumulative total need not be 1, but rather any value that is chosen as > a limit. > > This has been causing me a great deal of grief and I would greatly > welcome any help and suggestions. Given my lack of experience, I am > sure that there is a more efficient way to tackle this type of > problem, especially as I am dealing with many large lists. > > Regards > > Dean Williams First, to compute the signal and the accumulated totals you can use much simpler code. a = {5,6,3,2,8,2}; b = {5,4,1,3,9,4}; signal = Sign[a-b] Out[54]= {0, 1, 1, -1, -1, -1} runningTotal[sig_] := FoldList[Plus, First[sig], Rest[sig]] cumTotal = runningTotal[signal] Out[56]= {0, 1, 2, 1, 0, -1} If I understand correctly what it is you require for modifying the signal, then you can do it using the code below, beginning with the original signal and its accumulated totals. It has a simple loop that runs over the accumulated totals, keeping a new "cumulative" offset. It modifies both that offset and the resulting signal (initialized to the original one) appropriately whenever a bound is overstepped. signalTruncation[sig_, cumsig_, lim_] := Module[ {len=Length[sig], cum=0, newsig=sig}, Do [ Which [ cumsig[[j]]+cum>lim, newsig[[j]] = 0; cum--, cumsig[[j]]+cum<-lim, newsig[[j]] = 0; cum++ ]; , {j,len}]; newsig ] signalTruncation[signal, cumTotal, 1] Out[57]= {0, 1, 0, -1, -1, 0} There are no doubt slicker ways to do this. Also faster. For example, if you use large lists that are (or can be coerced to) machine integers or machine real numbers, then use of Compile will help considerably should speed become an issue for signalTruncation. Daniel Lichtblau Wolfram Research