Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to write recursive function for calculating the arithmetic mean of a vector.

For $X(n)=\{1,2,3,\ldots, n\}$, the formula is ${\rm Mean}(X(n))=((n-1)\, {\rm Mean}((X(n-1))+X_n)/n$.

My program works in my R-language version, but here in Mathematica it takes in account only the last two number. How can I fix my code?

Meen[x_] := (
   If[Length[x] == 1, 
     Return[x],
     n = Length[x] - 1; 
     y = x[[1 ;; n]]; 
     result = 1/(n + 1)*(n*Meen[x[[1 ;; n]]]  + x[[n + 1]])]
   )

X = {1, 2, 3, 4, 5};
Meen[X]
{9/5}
share|improve this question

4 Answers 4

Here is another way to do it. It is a tail-recursive formulation, so you don't have to worry about exceeding $RecursionLimit.

mean[{}, k___, m_: 0] := m
mean[{most___, last_}, k_: 0, m_: 0] := mean[{most}, k + 1, (k m + last)/(k + 1)]

Test:

SeedRandom[42]; nums = RandomReal[100., 3000];
Mean[nums], mean[nums]}
{50.1012, 50.1012}
share|improve this answer

The problem with your code is, that n is a global variable and changes in each recursion step. This influences calculations on a higher recursion level. To avoid that you need to create a local variable n at each recursion step. You can do this by using for example Module or Block. Leaving your code pretty much untouched the result is:

Meen[x_] := 
 Module[{n}, 
  If[Length[x] == 1, Return[x],(*If condition is TRUE*)
   n = Length[x] - 1;
   result = 1/(n + 1)*(n*Meen[x[[1 ;; n]]] + x[[n + 1]])]]
share|improve this answer

Here is a straightforward way based on the formula you provided:

    mean[{x_}] := x;
    mean[{x_, y___}] := Block[{$RecursionLimit = Infinity}, 
                              (Length[{y}] * mean[{y}] + x)/ Length[{x, y}]]

Usage:

mean[{a, b, c, d}]

Gives:

1/4 (a + b + c + d)

using nums as defined by m_goldberg

mean[nums] == Mean[nums]

True

share|improve this answer

I accept that there are a number of reasons to define this function recursively, including desire to get intermediate results. Mathematica's Mean is very efficient (I appreciate this is likely not the intent). This recursive approach becomes very very slow for data size 1000000. A "recursive" approach (using the method):

mn[u_] := Module[
  {list},
  list = Thread[{u, Range[Length[u]]}];
  First@Fold[((#2[[2]] - 1) #1 + #2)/#2[[2]] &, First@list, Rest@list]]

OnRandomReal[1,1000000] takes 5.9 seconds...compared with 0. for Mean... I hve tried some of the other methods and my machine hungs up but do not take my word for it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.