MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

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


  • Prev by Date: Re: newbie: explicit function works, "function object" doesn't
  • Next by Date: Re: "mapping" functions over lists, again!
  • Previous by thread: "mapping" functions over lists, again!
  • Next by thread: Re: "mapping" functions over lists, again!