MathGroup Archive 2009

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

Search the Archive

Re: Can I Map[] this code?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg95987] Re: Can I Map[] this code?
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Sat, 31 Jan 2009 06:43:17 -0500 (EST)
  • Organization: The Open University, Milton Keynes, UK
  • References: <glvk8r$e47$1@smc.vnet.net>

In article <glvk8r$e47$1 at smc.vnet.net>, Andreas <aagas at ix.netcom.com> 
wrote:

> As I have more experience with procedural programming, I'd like to better 
> understand how to use Mathematica's capabilities to do operations to or 
> mapping functions to lists.
> 
> As an example I have two lists of lists:
> 
> values = {{1, 1, 1, 1}, {1.03, 1.01, .90, .87}, {1.15, .987, 1.1, 1}, {.925, 
> 1.1, 1.03, 1}}
> 
> points = {
> {0.0842331, 0.445974, 0.0762394, 0.393553}, 
> {0.0507857, 0.316297, 0.217557, 0.415361}, 
> {0.0772796, 0.715707, 0.0966355, 0.110378}, 
> {0.407287, 0.0992621, 0.294046, 0.199405}, 
> {0.115973, 0.483231, 0.125979, 0.274817}, 
> {0.0819106, 0.64151, 0.0656714, 0.210908}, 
> {0.0240671, 0.164786, 0.230353, 0.580795}, 
> {0.0402821, 0.582524, 0.131371, 0.245823}, 
> {0.374207, 0.242838, 0.0277256, 0.355229}, 
> {0.130812, 0.459584, 0.331101, 0.078503}
> }
> 
> I have a named function:
> 
> function2[point_, value_] := If[value == 0, 0, 1 + ((value - 1) * point)]
> 
> That I want to apply across the elements in the list in a function like the 
> following:
> 
> function1[points_, values_] :=
>  Table[
>   Sum[
>     Sum[
>      function2[points[[j, k]], values[[i, k]]],
>      {k, 1, Length[values[[1]]]}
>      ], {j, 1, Length[points]}
>     ]/Length[points],
>   {i, 1, Length[values]}
>   ]
> 
> function1 works OK.  I just wonder if I can do this kind of calculation more 
> elegantly using something like the Map[] function and how I would do it in a 
> situation like the above.
> 
> I also have a concern about processing speed as the lengths of both lists of 
> lists can get quite large.
> 
> The larger question goes to this.  In what kind of situations should one use 
> iterative functions like Table[], Sum[], etc and when does one better use 
> Map[] or other such functions?  What advantages and disadvantages does either 
> approach have over the other?
> 
> Any guidance much appreciated.

FWIW, 

My philosophy could be summarize as follows: "Write short functions and 
combine them with high level constructs," i.e. think much less in terms 
of computer sciences (3d-array, loop, indices, summation,...) and much 
more in terms of mathematical operations (tensors, ---generalized--- 
inner product, mean,...). Therefore, your code could be written as

    f2 = Function[{p, v}, Boole[v != 0]*(1 + (v - 1)*p)]; 
    f3 = Function[{p, v}, Inner[f2, p, v, Plus]]; 
    f4 = Function[{p, v}, Mean[(f3[#1, v] & ) /@ p]]; 
    f1[p_, v_] := (f4[p, #1] & ) /@ v

Now, have you bothered to *describe* what you try to achieve in words 
(using higher level concepts than loops and indices :-), an even better 
and to the point solution could have been written. Nevertheless, the 
above code works, as you can see below, and is much faster than the 
original solution (and this can be improved).


In[1]:= values = {{1, 1, 1, 1}, {1.03, 1.01, .90, .87}, {1.15, .987, 
    1.1, 1}, {.925, 1.1, 1.03, 1}};

In[2]:= points = {{0.0842331, 0.445974, 0.0762394, 
    0.393553}, {0.0507857, 0.316297, 0.217557, 0.415361}, {0.0772796, 
    0.715707, 0.0966355, 0.110378}, {0.407287, 0.0992621, 0.294046, 
    0.199405}, {0.115973, 0.483231, 0.125979, 0.274817}, {0.0819106, 
    0.64151, 0.0656714, 0.210908}, {0.0240671, 0.164786, 0.230353, 
    0.580795}, {0.0402821, 0.582524, 0.131371, 0.245823}, {0.374207, 
    0.242838, 0.0277256, 0.355229}, {0.130812, 0.459584, 0.331101, 
    0.078503}};


In[3]:= f2 = Function[{p, v}, Boole[v != 0]*(1 + (v - 1)*p)]; 
f3 = Function[{p, v}, Inner[f2, p, v, Plus]]; 
f4 = Function[{p, v}, Mean[(f3[#1, v] & ) /@ p]]; 
f1[points_, values_] := (f4[points, #1] & ) /@ values

f1[points, values]

Out[7]= {4, 3.9551, 4.03137, 4.03591}

In[8]:= function2[point_, value_] := 
 If[value == 0, 0, 1 + ((value - 1)*point)]
function1[points_, values_] :=
 Table[
  Sum[
    Sum[
     function2[points[[j, k]], values[[i, k]]], {k, 1, 
      Length[values[[1]]]}
     ],
    {j, 1, Length[points]}
    ]/Length[points],
  {i, 1, Length[values]}
  ]

function1[points, values]

Out[10]= {4, 3.9551, 4.03137, 4.03591}

Regards,
--Jean-Marc


  • Prev by Date: Re: Re: Re: Re: Significant slow-down with
  • Previous by thread: Re: Can I Map[] this code?
  • Next by thread: voices for version 7 text-to-speech