# How to fix the “Module” function, for implicit funcitons? [closed]

I wanted to make a function which gives the frequencies of a number in a specific list, when I came accros this problem. This is what I tried:

row = {-1, 1, 2, 3, -1, 1, 2, -1, 1, -1, -2, -3,
1, -1, -2, -3, -4, -5, 1, 2};

frequencyRow =
Round[HistogramList[row, {Min[row] - 1, Max[row] + 1, 1}]];

lengthRow = Map[f, Part[frequencyRow, 1]]

(*{f[-6], f[-5], f[-4], f[-3], f[-2], f[-1], f[0], f[1], f[2], f[3],
f[4]}*)

frequency = Append[Part[frequencyRow, 2], 0]

(*{0, 1, 1, 2, 2, 5, 0, 5, 3, 1, 0}*)

mode[n_] := Module[{f}, {lengthRow = frequency}; f[n]]

mode[2]

>f\$821[2]


(So the implicit fucntions do not give the outcome I want. However;)

mode2[n_] :=
Module[{f}, {{f[-6], f[-5], f[-4], f[-3], f[-2], f[-1], f[0], f[1],
f[2], f[3], f[4]} = {0, 1, 1, 2, 2, 5, 0, 5, 3, 1, 0}}; f[n]]

mode2[2]

(*3*)


(If you use the exact outcome of the functions, the Module function does give the right outcome)

goal = Map[mode2, row]

(*{5, 5, 3, 1, 5, 5, 3, 5, 5, 5, 2, 2, 5, 5, 2, 2, 1, 1, 5, 3}*)


If you know how to fix this to make it work for the implicit functions as well, so I can chance the imput without changing the formula all the time, that would be nice. Or if you see a way to do this proces faster or easier, that would even be better.

-

## closed as off-topic by acl, Öskå, ubpdqn, m_goldberg, JensJul 15 '14 at 19:11

This question appears to be off-topic. The users who voted to close gave this specific reason:

• "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – acl, Öskå, ubpdqn, m_goldberg, Jens
If this question can be reworded to fit the rules in the help center, please edit the question.

Why do you write Part[frequencyRow, 1] like this? Hard to read. Simply frequencyRow[[1]] Just like in Matlab frequencyRow(1) –  Nasser Jul 15 '14 at 9:13
@Nasser I'm still a bit new to this program. But you are very right, that is a lot easier, tnx. –  immaan Jul 15 '14 at 9:19
I understand. If you are from Matlab, then M arrays and matrices are not much different from Matlab's. In M, just use [[ ]] in place of Matlab's (). and in place of : in matlab, there is ;; and in place of end in Matlab, there is -1 (I actually define end=-1 in my code since I also use Matlab, so this way it is less confusing to me) –  Nasser Jul 15 '14 at 9:22
@Nasser tnx. How did you actually found this all out. Because I always go to the help in mathematica, only this gives all these long codes. The short ones are most of the time not reported. –  immaan Jul 15 '14 at 9:28
The entire point of Module is to localise f inside the body. See eg here (or the docs). Why did you use Module here if not for that? –  acl Jul 15 '14 at 10:03

I was somewhat perplexed by your use of Module here, and I don't think you every explicitly stated the reason you are using it, but I am going to assume that you want to prevent e.g. f[-6] from having a global value after your operation is performed. For that you want Block instead of Module. You will also need to Evaluate lengthRow or you will reassign that literal Symbol.

lengthRow = {f[-6], f[-5], f[-4], f[-3], f[-2], f[-1], f[0], f[1], f[2], f[3], f[4]};

frequency = {0, 1, 1, 2, 2, 5, 0, 5, 3, 1, 0};

mode[n_] := Block[{f}, Evaluate[lengthRow] = frequency; f[n]]

mode[2]

3


So we get the correct output, and f[2] is not assigned a global value:

f[2]

f[2]


This is still a fairly clumsy way to handle the specific operation performed by mode but I hope this is helpful generally. For the specific operation you'd be better off with:

rulesmode = Dispatch @ Thread[frequencyRow[[1]] -> frequency];


Which is used with Replace or ReplaceAll:

2 /. rulesmode

3


Or in version 10 using Association:

mode2 = AssociationThread[frequencyRow[[1]] -> frequency]

mode2[2]

3


-

I'd go for Count:

 Count[row, 2]

3


And in case you want to count all elements of your row, you can also use Tally:

Tally[row]


{{-1, 5}, {1, 5}, {2, 3}, {3, 1}, {-2, 2}, {-3, 2}, {-4, 1}, {-5, 1}}

EDIT

Given the OP's updated goal, this should suffice:

row /. Rule @@@ Tally[row]


{5, 5, 3, 1, 5, 5, 3, 5, 5, 5, 2, 2, 5, 5, 2, 2, 1, 1, 5, 3}

EDIT 2

This gives the frequency count of the elements shifted by their overall sign:

row + Sign[row] /. Append[Rule @@@ Tally[row], _Integer -> 0]


{2, 3, 1, 0, 2, 3, 1, 2, 3, 2, 2, 1, 3, 2, 2, 1, 1, 0, 3, 1}

Pretty hard to hit a moving target ...

-
Yes I know this. But I see I did not formulate my goal. I wanted to have the list of frequencies in the end. So the main problem I have is still with the "Module" function, I suppose –  immaan Jul 15 '14 at 9:35
I also tried this goal2 = Table[Count[row, row[[n]]], {n, 1, Length[row]}] ({5, 5, 3, 1, 5, 5, 3, 5, 5, 5, 2, 2, 5, 5, 2, 2, 1, 1, 5, 3}) But it is simply to slow, and if I want to change the formula it gets even more slow –  immaan Jul 15 '14 at 9:37
@immaan I've edited my answer; see if you like it :). –  Teake Nutma Jul 15 '14 at 9:46
I like it very much, since it is a lot faster then goal2. So thank you I can actually use this already. But, as an additional question. The "Module" part would be nice because I also need a list with frequencies of the number in "row" "positive+1" and "negative-1". So where all the "-1" had frequency "5", I then want "2", since "-2" had "2". –  immaan Jul 15 '14 at 10:15
what I did for the negative side (since the oposite side is alike) is this: neg := -row*(Sign[row] - 1)/2; goalN := -Table[ Count[row, neg[[n]] - 1], {n, 1, Length[neg]}]*(Sign[row - 1)/2 {2, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 1, 0, 2, 2, 1, 1, 0, 0, 0} –  immaan Jul 15 '14 at 10:17