Re: Functional or rules-based equivalent for procedural program

*To*: mathgroup at smc.vnet.net*Subject*: [mg25004] Re: [mg24976] Functional or rules-based equivalent for procedural program*From*: "Tomas Garza" <tgarza at mail.internet.com.mx>*Date*: Fri, 1 Sep 2000 01:09:37 -0400 (EDT)*Sender*: owner-wri-mathgroup at wolfram.com

J. Leko [leko at ix.netcom.com] wrote: > I have a question regarding the type of programming style by which I may > accomplish a task in Mathematica. Mathematica supports three types of > programming: procedural, functional, and rules-based. Like the majority of > people, I was formally taught procedural programming, but am trying to > undo this evil. >:-) > > Here is my situation... > > I am working with a set of all-sky imager (instrument) data. Some years > ago, I created a FORTRAN program which subtracts background intensities > from the data of interest. Here is a brief example of how it works: > > o The first two entries in the background file are at 2:08, and 2:17. > o In the data file, the first four entries are time stamped 2:06, 2:10, > 2:15, and 2:19. > o My algorithm averages the background values taken at these two times, > and then subtracts this from data which falls between these times, namely > 2:10, 2:15. > o The 2:19 data time value falls outside this background range, and would > be handled by the average of the 2:17 and succeeding background times. > > Since the routine is written in FORTRAN, it is obviously procedural. As I > stated above, I am expert in procedural programming, but would like to > become proficient in Mathematica programming. Is there an efficient method > by which I may perform this task in Mathematica using either functional, > or rules-based methods? So far, I guess you needn't go further than elementary list operations. Take these examples of background values and data: In[1]:= bg = Table[Random[Integer, {200, 280}]/100, {20}] // Union // N // Sort Out[1]= {2.08, 2.15, 2.23, 2.3, 2.31, 2.38, 2.4, 2.43, 2.46, 2.49, 2.58, 2.6, 2.61, \ 2.64, 2.65, 2.71, 2.73} In[2]:= data = Table[Random[Integer, {210, 270}]/100, {30}] // Union // N // Sort Out[2]= {2.13, 2.15, 2.21, 2.24, 2.26, 2.28, 2.29, 2.3, 2.31, 2.34, 2.35, 2.38, 2.4, \ 2.41, 2.42, 2.43, 2.44, 2.48, 2.49, 2.54, 2.56, 2.58, 2.62, 2.66} The consecutive averages of background values are In[3]:= avers = (Rest[bg] + Drop[bg, -1])/2 Out[3]= {2.115, 2.19, 2.265, 2.305, 2.345, 2.39, 2.415, 2.445, 2.475, 2.535, 2.59, \ 2.605, 2.625, 2.645, 2.68, 2.72} Now you group the data according to the interval of consecutive background values they belong to: In[4]:= sets = Table[ Select[data, bg[[j]] < # <= bg[[j + 1]] &], {j, 1, Length[bg] - 1}] Out[4]= {{2.13, 2.15}, {2.21}, {2.24, 2.26, 2.28, 2.29, 2.3}, {2.31}, {2.34, 2.35, 2.38}, {2.4}, {2.41, 2.42, 2.43}, {2.44}, {2.48, 2.49}, {2.54, 2.56, 2.58}, {}, {}, {2.62}, {}, {2.66}, {}} Finally, you subtract from each set the corresponding background average and eliminate the empty sets: In[5]:= sets - avers // Flatten Out[5]= {0.015, 0.035, 0.02, -0.025, -0.005, 0.015, 0.025, 0.035, 0.005, -0.005, \ 0.005, 0.035, 0.01, -0.005, 0.005, 0.015, -0.005, 0.005, 0.015, 0.005, 0.025, \ 0.045, -0.005, -0.02} As you can see, only Rest, Drop, Table, Select, Flatten, and list addition, division by a constant, and subtraction were necessary. Tomas Garza Mexico City