I'm playing a bit with the J programming language, and I've tried to create a verb for computing entropy from a list of probabilities (outcomes of an event, formula would be like this in python/pesudocode: -sum([p*log(p,2) for p in ps])
).
The version I've tried using composition (@:
) works, but the one based on hook & fork seems to be doing something else, and I care about why it's doing what it does. I'm trying to grok working with hook and fork, and this case really proves my intuitions are wrong.
Here is the code:
probs =: 0.75 0.25 NB. probabilties
entropy =: +/ @: (- * 2&^.)
entropyWrong =: +/ (- * 2&^.)
entropy probs NB. this is correct
0.811278
entropyWrong probs NB. this is wrong!
1.06128 1.25
0.561278 0.75
NB. shouldn't the following be the same as above (wrong)?
+/ (- * 2&^.) probs
0.811278
The point of my question isn't "how to compute entropy of probabilities in JS", but "why does the entropyWrong
above does what it does and why it's not the same as "it's content" which does the right thing apparently.
The entropyWrong definition is a hook that you are using monadically.
entropyWrong =: +/ (- * 2&^.)
If a monadic hook is represented as (u v) y
then in your case +/
is u and (- * 2&^.)
is v; v is a fork. y of course is probs, the noun argument.
J defines the actions of a monadic hook as equivalent to y u v y
so that u becomes dyadic with y as its left argument and v y as its right argument. This is consistent with J's right to left order of execution.
By the way, forks are defined (f g h) y
where f, g and h are verbs and the result is (f y) g h y
. Each verb can be described as a tine of the fork and the middle tine g is dyadic while f and h are monadic when a fork if applied monadically.
entropy =: +/ @: (- * 2&^.)
is doing something different. Entropy is in form u @: v
and is taking the results of the fork v and applying them monadically to the verb u
If you would like to get rid of the use of @:
in entropy, you can do that by using the verb [:
. When used as the left tine of a fork [:
returns no result and this creates a monadic centre tine instead of a dyadic one.
entropy2=: [: +/ (- * 2&^.) NB. with three verbs this is now a fork
probs =: 0.75 0.25
entropy2 probs
0.811278