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