Re: "mapping" functions over lists, again!
- To: mathgroup at smc.vnet.net
- Subject: [mg96246] Re: "mapping" functions over lists, again!
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Tue, 10 Feb 2009 05:50:30 -0500 (EST)
- Organization: The Open University, Milton Keynes, UK
- References: <gmp0q7$c0j$1@smc.vnet.net>
In article <gmp0q7$c0j$1 at smc.vnet.net>, "Paul Ellsmore" <paul.ellsmore at nanion.co.uk> wrote: [snip] > that is to > say, lists of pairs of real and complex values. Note that I mean a list = > of > lists (four lists in the above case). I need to keep the integrity of = > these > lists, while doing operations on them. > > In particular, I want to be able to turn every pair {real, complex} into > {real, f[complex]}. It was suggested to me that I use Cases, as follows: > > Realpart = Cases[shortTestdata,{r_Real,c_Complex}=A6{r,Re[c]}] . If I = > apply > this to the first list in shortTestdata, i.e {{40,28.0678 +1.20855 > =E4},{43.094,28.0572 +1.29852 =E4},{46.428,28.0553 +1.40023 = > =E4},{50.019,28.0551 > +1.50876 =E4},{53.888,28.0573 +1.62452 =E4},{58.057,28.0565 +1.75026 = > =E4}} I get: > > {{43.094,28.0572},{46.428,28.0553},{50.019,28.0551},{53.888,28.0573},{58.= > 057 > ,28.0565}} > > This seems to miss out the first data pair of the list. Am I making a > mistake with the syntax? Yes, the first pair is not taken in account since it is not of the required form {_Real, _Complex} but of the form {_Integer, _Complex}. Mathematica differentiate *exact* numbers such as 40 from *hardware floating points* such as 40. or 40.0 and assign to them different heads (Integer for the former, Real for the latter). In[1]:= shortTestdata = {{{40, 28.0678 + 1.20855 I}, {43.094, 28.0572 + 1.29852 I}, {46.428, 28.0553 + 1.40023 I}, {50.019, 28.0551 + 1.50876 I}, {53.888, 28.0573 + 1.62452 I}, {58.057, 28.0565 + 1.75026 I}}, {{40, 7.42169 + 0.219859 I}, {43.094, 7.4084 + 0.234353 I}, {46.428, 7.40377 + 0.252135 I}, {50.019, 7.40131 + 0.271599 I}, {53.888, 7.40048 + 0.292062 I}, {58.057, 7.39994 + 0.314501 I}}, {{40, 1685.53 + 0.0480998 I}, {43.094, 1694.69 - 0.0913363 I}, {46.428, 1698.27 - 0.0273182 I}, {50.019, 1699.76 - 0.0491538 I}, {53.888, 1700.52 - 0.217922 I}, {58.057, 1701.16 - 0.242314 I}}, {{40, 1808.7 - 0.00628662 I}, {43.094, 1808.52 - 0.114076 I}, {46.428, 1808.53 - 0.0244589 I}, {50.019, 1808.44 - 0.106166 I}, {53.888, 1808.48 - 0.176297 I}, {58.057, 1808.63 - 0.289451 I}}}; In[2]:= Dimensions[shortTestdata] Out[2]= {4, 6, 2} In[3]:= {shortTestdata[[1, 1]], shortTestdata[[1, 2]]} Out[3]= {{40, 28.0678+ 1.20855 I}, {43.094, 28.0572+ 1.29852 I}} In[4]:= Map[Head, %, {2}] Out[4]= {{Integer, Complex}, {Real, Complex}} (* Your original code misses the first pair *) In[5]:= Cases[shortTestdata[[1]], {r_Real, c_Complex} :> {r, Re[c]}] Out[5]= {{43.094, 28.0572}, {46.428, 28.0553}, {50.019, 28.0551}, {53.888, 28.0573}, {58.057, 28.0565}} (* The following expressions process all six pairs*) In[6]:= Cases[ shortTestdata[[1]], {r : (_Integer | _Real), c_Complex} :> {r, Re[c]}] Out[6]= {{40, 28.0678}, {43.094, 28.0572}, {46.428, 28.0553}, {50.019, 28.0551}, {53.888, 28.0573}, {58.057, 28.0565}} In[7]:= Cases[ shortTestdata[[1]], {r_ /; Head[N[r]] == Real, c_Complex} :> {r, Re[c]}] Out[7]= {{40, 28.0678}, {43.094, 28.0572}, {46.428, 28.0553}, {50.019, 28.0551}, {53.888, 28.0573}, {58.057, 28.0565}} In[8]:= Cases[ N@shortTestdata[[1]], {r_Real, c_Complex} :> {r, Re[c]}] Out[8]= {{40., 28.0678}, {43.094, 28.0572}, {46.428, 28.0553}, {50.019, 28.0551}, {53.888, 28.0573}, {58.057, 28.0565}} > I thought that the following would work for the full lists of lists: > > realpart=Cases[shortTestdata,{r_Real,c_Complex}=A6{r,Re[c]},2] i.e = > apply the > rule to all parts at level 2 of shortTestdata, but I get: [snip] > This still misses the first pair of each list, and now flattens the > structure, so I don=92t know where my four lists start and end any more! = > I > have tried Map with Cases but frankly have no idea what the syntax = > should > look like, and either get error messages or empty lists as output. The > documentation shows no examples of Map on a list of lists, so maybe it = > is > simply not possible? "Not possible?" Are you kidding :-)] For instance, the Infinity level specification, w/o being enclosed within curly braces, tells Cases[] to look for pairs that match the desired specifications regardless of their degree of nesting. For instance, In[11]:= Cases[shortTestdata, {r_ /; Head[N[r]] == Real, c_Complex} :> {r, Re[c]}, Infinity] Out[11]= {{40, 28.0678}, {43.094, 28.0572}, {46.428, 28.0553}, {50.019, 28.0551}, {53.888, 28.0573}, {58.057, 28.0565}, {40, 7.42169}, {43.094, 7.4084}, {46.428, 7.40377}, {50.019, 7.40131}, {53.888, 7.40048}, {58.057, 7.39994}, {40, 1685.53}, {43.094, 1694.69}, {46.428, 1698.27}, {50.019, 1699.76}, {53.888, 1700.52}, {58.057, 1701.16}, {40, 1808.7}, {43.094, 1808.52}, {46.428, 1808.53}, {50.019, 1808.44}, {53.888, 1808.48}, {58.057, 1808.63}} [snip] HTH, --Jean-Marc