MathGroup Archive 2008

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

Search the Archive

Re: Functional programming?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg92032] Re: Functional programming?
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Thu, 18 Sep 2008 06:10:47 -0400 (EDT)
  • Organization: The Open University, Milton Keynes, UK
  • References: <200809130957.FAA03536@smc.vnet.net> <gal3dg$dql$1@smc.vnet.net> <gapf5u$nvq$1@smc.vnet.net> <gaqf3r$dno$1@smc.vnet.net>

David Bailey wrote:
> Jean-Marc Gulliet wrote:
>> peter lindsay wrote:
>>
>>> as an old-timer myself - I'd be very interested in this too,
>>> particularly - as you say - with reference to engineering problems.
>>> I'm afraid my favorite construct was the REPEAT - UNTIL loop, which
>>> should finally ruin any shreds of credibility that I may once have
>>> had...
>>> Peter
>>>
>>> 2008/9/13 AES <siegman at stanford.edu>:
>>>> I suggest it might be instructive if some of the functional programming
>>>> proponents on this group could provide us DO-looping old timers with a
>>>> brief summary or tutorial as to what is really meant by, or involved in,
>>>> "functional programming"?
>>>>
>>>> --- especially as this concept might relate to building programs to do
>>>> calculations involving multi-stage real-world engineering or technical
>>>> problems
>>>>
>>>> --- and especially as it might relate to programs that are going to be
>>>> developed in an evolutionary process and that in the end, rather than
>>>> being built into some long-term library, are maybe only going to be run
>>>> or executed a few times before the person involved (e.g., an engineer,
>>>> or scientist, or other real-world individual, not a "programmer") moves
>>>> on to some other totally different task or assignment.
>>
>> Say we want to compute the mean (average) of all non-zero values for 
>> each row of a two dimensional array. The code must not crash when fed 
>> with data of incorrect format as well as it must handle nicely such 
>> things like divisions by zero.
>>
>> (* Functional / Pattern matching code *)
>>
>> myMean2[array_?VectorQ] := Mean[Select[array, # != 0 &]]
>> myMean2[array_?MatrixQ] := Map[myMean2, array]
>>
>>
>> (* Procedural code *)
>>
>> myMean1[array_] :=
>>   Module[{iter, len, cnt, sum, mean},
>>    sum = 0;
>>    mean = 0;
>>    cnt = 0;
>>    len = Length[array];
>>    If[len != 0,
>>     For[iter = 1, iter <= len, iter = iter + 1,
>>      If[array[[iter]] != 0, sum = sum + array[[iter]]; cnt = cnt + 1];
>>      ];
>>     If[cnt != 0,
>>      mean = sum/cnt;
>>      , mean = "NA";
>>      ];
>>     , mean = "NA";
>>     ];
>>    Return[mean]
>>    ]
>>
>> meanArray[array_] :=
>>   Module[{res, len, dim},
>>    res = {};
>>    len = Length[array];
>>    dim = Depth[array] - 1;
>>    If[dim != 2,
>>     Return["NA"]];
>>    For[iter = 1, iter <= len, iter = iter + 1,
>>     AppendTo[res, myMean1[array[[iter]]]
>>       ];
>>     ];
>>    Return[res]
>>    ]
>>
>>
>> (* Some data and some tests *)
>>
>> data = {{}, {1, 2, 3, 4, 5, 0, 0, 0}, {0, 0, 0}, {1, 2, -10,
>>      3, 4}, {a, b, c}};
>>
>> meanArray[{1, 2, 3, 4, 5, 0, 0, 0}]
>> meanArray[{{1, 2, 3, 4, 5, 0, 0, 0}}]
>> meanArray[data]
>> meanArray[{{{1, 2, 3, 4}, {5, 0, 0, 0}}}]
>>
>> (*
>> Out[6]= "NA"
>>
>> Out[7]= {3}
>>
>> Out[8]= {"NA", 3, "NA", 0, "NA"}
>>
>> Out[9]= "NA"
>> *)
>>
>> myMean2[{1, 2, 3, 4, 5, 0, 0, 0}]
>> myMean2[{{1, 2, 3, 4, 5, 0, 0, 0}}]
>> Map[myMean2, data]
>> Map[myMean2, {{{1, 2, 3, 4}, {5, 0, 0, 0}}}]
>>
>> (*
>> Out[10]= 3
>>
>> Out[11]= {3}
>>
>> Out[12]= {Mean[{}], 3, Mean[{}], 0, Mean[{}]}
>>
>> Out[13]= {{5/2, 5}}
>> *)
>>
>>
>> Regards,
>> -- Jean-Marc
>>
> I think you have chosen a rather favourable example here. Suppose 
> instead that you need to remove every zero together with the preceding 
> element (sweeping from left to right). Realistically, you also probably 
> want to do something, rather than output Mean[{}] for myMean2[{0,0,0}].

Fair enough! Below, I have added a function called "avg" that computes 
the mean, since I did not use the built-in function Mean[] in the 
procedural code. Also, myMean2 now returns "NA" rather than "Mean[{}]" 
to be consistent w/ the procedural version.

In[1]:= avg[
   lst_ /; VectorQ[lst, NumericQ] && Positive[Length[lst]]] := (Plus @@
      lst)/Length[lst]
avg[___] = "NA";

myMean2[array_?VectorQ] := avg[Select[array, # != 0 &]]
myMean2[array_?MatrixQ] := Map[myMean2, array]

data = {{}, {1, 2, 3, 4, 5, 0, 0, 0}, {0, 0, 0}, {1, 2, -10, 3,
     4}, {a, b, c}};
myMean2[{1, 2, 3, 4, 5, 0, 0, 0}]
myMean2[{{1, 2, 3, 4, 5, 0, 0, 0}}]
Map[myMean2, data]
Map[myMean2, {{{1, 2, 3, 4}, {5, 0, 0, 0}}}]

Out[6]= 3

Out[7]= {3}

Out[8]= {"NA", 3, "NA", 0, "NA"}

Out[9]= {{5/2, 5}}

> I would say that users should not be scared away from using procedural 
> code when faced with ad hoc problems of this sort.

I second that.

Best regards,
-- Jean-Marc


  • Prev by Date: blurry ellipse
  • Next by Date: Re: Re: Apparent error integrating product of DiracDelta's
  • Previous by thread: Re: Re: Functional programming?
  • Next by thread: Re: Functional programming?