On Thu, Mar 24, 2011 at 7:03 AM, Adrian May
<[email protected]> wrote:
> rand =. _1 1 {~ ?@:(2"0)
> matmul =. (+/ .*)
> avg =. (%&2@:+)
> avgio =. (avg &.>)

Note that parenthesis are unnecessary here.  In essence, J's parsing
rules ensures that:

[a] The phrase on the right hand side of an =. or =: gets the same
syntactic treatment as a phrase in parenthesis.
[b] Thus, a named expression is effectively a parenthesized expression.

Also, I do realize that =. is easier to type than =: but for names
outside of an explicit definition, I much prefer =:   This is because
=., names do not survive a load operation, and loading scripts from
files is the most convenient way to work on J code longer than a
single sentence.

> w =. (><1)&{::
> io =. (<0)&{::
> ifio =. (<0)&{::
> ofio =. (<1)&{::

Note that this boxing and unboxing is irrelevant.

   (><1) is 1
   (<1)&{:: gives the same result as 1&{::

> i =. ifio@io
> o =. ofio@io
> show =. ([(1!:2&2)@('-+'{~>:&0)@(i,o)) NB. looks nicer now
>
> env =. (rand&[)`(reward&[) @. (-:&goal)
> decide =. _1 1 {~ >:&0
> think =. w (] ; decide@matmul) env@o
>
> weightlearn =. learnrate@(ofio */ ifio)@((avgio io)~)
> weightjumble =. (+ jumblerate@rand)
> weightnew =.  (weightlearn + (weightjumble@forgetrate@w@[))
>
> cycle =. ((] ; weightnew) think)
>
> cycle@show ^:30 ((0 0;0 0); 2 2 $ 0)

I get a value error on 'goal' here.

Note that when J parses a sentence with an undefined name, it has to
assume the syntactic class of that name.  So, it treats undefined
names as verbs.  This means that you should put constant definitions
above verb definitions (which might arguably be good practice).  Note
also that when parsed names with noun definitions are replaced with
their values while names with verb definitions are resolved at run
time.

It probably worked for you because you had already defined 'goal'.

For large programs, running the code in a fresh instance of J is a
(perhaps unfortunate) important test.

> goal =. _1 1
> reward =. _1 _1
> learnrate =. 0.5&*
> forgetrate =. 0.5&*
> jumblerate =. 0.2&*

(So I moved this entire block up to the top of my script, and then
changed all the =. to =: so I could inspect the values associated with
the names.  If you want the names to be temporary, though, I can
understand that.)

> I'm still, still confused about how env's rand knows to make two numbers. In
> 1-~2*?@:(2"0), the 2"0 means I want 1s and 0s. It doesn't say anything about
> how many numbers I want.

Actually, it does say something about how many numbers you want,
though the statement is incomplete.

v"0 says you want one array in your result for each number in your
argument.  In this case your result arrays are single numbers, so you
have one random number in your result for each number in your
argument.

> I know that the vector gets presented to (rand&[) but I don't see how or why 
> it makes it down to rand. In (2&*) 3 you don't
> present the 3 to the 2.

You do, however present the 3 to the *

And, watch this:
   2&* 3 5
6 10
  2&* 7 11 13
14 22 26

Notice how for each number you have in your argument, you get a number
in your result?  The same principle applies with (2"0):

   (2"0) 3 5
2 2
   (2"0) 7 11 13
2 2 2

> But look what I get in the terminal:
>
>      rand
> 1 -~ 2 * ?@:(2"0)
> |       (rand&[) (2 2$0)
> 1 1
> 1 1
> |       (rand&[) (2 2$0)
> 1 1
> 1 1
> |       (rand&[) (2 2$0)
> 1 1
> 1 1
> |       (rand&[) (2 2$0)
> 1 1
> 1 1
> |       (rand&[) (2 2$0)
> 1 1
> 1 1
> |       rand (2 2$0)
> 1 1
> 1 1
> |       rand (2 2$0)
> 1 1
> 1 1
> |       rand (2 2$0)
> 1 1
> 1 1
> |       rand (2 2$0)
> 1 1
> 1 1
> |       rand (2 2$0)
> 1 1
> 1 1

Here,  rand (2 2$0) is producing a four by four array made up of _1
and/or 1, and then you are taking the absolute value of that array so
your result is 2 2$1

>   rand 2 2
> _1 _1
>   rand 2 2
> 1 1
>   rand 2 2
> _1 1
>   rand(2 2)
> 1 _1
>   rand(2 2)
> _1 _1
>   rand(2 2)
> 1 _1

Here you are producing two element arrays made up of _1 and/or 1.

>   ?2"0 (2 2$0)
> 1 0
> 0 0
>   ?2"0 (2 2$0)
> 0 1
> 0 0

Here you are producing 2 by 2 arrays made up of 0 and/or 1.

> What on earth is going on there? I have a hunch that my program isn't giving
> random numbers everywhere. I can recognise the symptoms: it takes longer to
> learn and sometimes doesn't at all.

Your program was producing random numbers, but my guess is that you
started editing an expression from an error display and you left in
the decorative | on the left edge, which also happens to be the
absolute value function.

> I now do the vector comparison with -: but why can't I just use = ?

= is -:"0

In other words, -: is true iff the entire arrays match -- they both
must have the same elements and the same shape.  Meanwhile, = does an
element by element comparison:

   2 = 1 2 3
0 1 0
   2 -: 1 2 3
0

> That combiningFn didn't do quite what I wanted. It's supposed to do a matrix
> multiply (nothing's in boxes at that point) then replace everything in the
> answer by its sign. That overall sentence afterwards confused me a bit.
>
> I can't seem to make constants work your way. It barfs when I substitute it
> in. What would I write in weightlearn if learnrate was 0.5&[ ?

Can you expand on these issues a bit?  I am confused myself.

>> addrandom =: 13 : 'y + ?x#~#y'
>
> I'm confused. #y counts the elements in y. y+ adds, ?x rolls. But what's #~
> A lot of these things don't seem to be in the vocabulary. {~ wasn't either.

~ is in the vocabulary
# is in the vocabulary
{ is in the vocabulary

#y means:  give me the number of items in y
x#~#y means:  copy the elements in x based on the number of items in y

x#~#y means the same thing that (#y)#x means

> The incredible thing about this language is that I never needed to call
> anything twice (except accessors). Those forks and hooks did everything I
> could have asked for in a single sentence. And it's eminently readable too.

I have fun with it myself. :)

-- 
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to