Michael hktyz2 wrote:
> I am a scientist mainly writing programs in Fortran and C. Mostly, 
> our programs are about computations on arrays. I heard that J is 
> an array programming language so I am interested in that if our 
> programs can be written in J easily.

This presumes an investment of time to understand the language, but
I believe what you heard is true.

(However, note that in some cases we would want to use fortran code 
with J.  This is because more effort has gone into supporting 
fortran for numeric algorithms.  [J may catch up in those areas at 
some point in the future.]  The LAPACK routines are an example of
this.)

Hints:

Think of computations in terms of functions which produce 
array results.

Understand what "verb rank" means.  (Also important are noun rank, 
and the rank conjunction.)  But it's perhaps best if you find 
these definitions for yourself.  (Skill at finding definitions is
also critically important.)

Also, you'll want to understand the various J array operators
which control data composition.

And, of course, ask more questions if you get stuck.

> For example, we write the following Fortran subroutine that 
> updates an array with an averaging operation. We update the value 
> of an array element with the average of its neighbors.
>
> subroutine avg1d (T, a)
>   integer :: T
>   real, dimension (0:T, 1,100) :: a
>   integer :: t
>   integer :: i1
>   do i1 = 1, 100
>    do t = 1, T-1
>      a(t,i1) = (a(t-1,i1)+a(t,i1)+a(t+1,i1))/3
>    end do
>  end do
> end subroutine avg1d

Ok, first off, I'm not a fortran programmer, so please let me know if
I've
misunderstood the above.

As I understand it, argument a is a two dimensional array.  One
dimension
is T+1 and the other dimension is 100

Also, as I understand it, your routine above averages along the first
dimension (the one with T+1 elements), and the other dimension is along
for the ride.

In J, array size is a part of the array, and all indices start from 0.
So, unless we want to go to extra work (or except when we are creating
a specific array), we don't put array size declarations in the code we 
write.

Also, as I mentioned above, it's far easier to write functions which 
produce simple results than it is to update in place.

Thus, in J, I'd be tempted to write:

avg1d=: 3 +\ %&3

Here, %&3 divides my argument array by 3, producing a new array
whose values are a third the values from the original array.
The +\ dyad then sums adjacent groups of 3 (along the first
axis of the array).

Note that the result array has two fewer items along the
first dimension than were originally present.  (With a
minimum result of 0 items).

If you're not yet comfortable with J's tacit expressions, here's
a more verbose definition which accomplishes the same thing:

avg1d=: verb define
 3 +\ y % 3
)

Or, if I was particularly concerned about numeric stability, I'd
do the division after the summation rather than before:

avg1d=: (3 +\ ]) % 3:

Or, the explicit version

avg1d=: verb define
 (3 +\ y) % 3
)

Finally, I think this code would be more elegant if 3 was a parameter 
rather than a hard coded constant:

avg1d=: ([ +/ ]) % [

Or, the explicit version

avg1d=: dyad define
 (x +\ y) % x
)

Or, since the tacit form ([ dyad ]) produces the same result as dyad
by itself:

avg1d=: +/ % [

But note that this last version might produce irrelevant results,
rather than generating an error, if the left argument (typically 3)
is not provided.

Of course, you could simply hard-code 3 into the function definition:
avg1d=: 3&(+/ % [)

This last version would probably be my preferred form, if I really
always wanted to average adjacent elements.

> I read some introductory examples about J. But I still cannot get the 
> idea how this subroutine can be implemented in J. Can anyone give me
> some hints? Or maybe this cannot be done in J easily?

I hope the above provides a few hints.

Note that it is possible to merge the averaged result with the 
unaveraged edge values from the original array, but as this takes
more programming effort, it's not something I'd do lightly.  And, 
if I did need that effect I'd quite likely deal with it at some 
later stage of processing (where it is a meaningful part of the 
functions) -- this would probably save me (and the computer) the
extra effort of producing less meaningful results.

> If this subroutine can be implemented in J. Then my question is can we
> make this subroutine generic with respect to the dimensionality of a? 
> For example, we want to define the following function which is exactly

> the same except it works on arrays with one more dimension.

The above J expressions work on arrays of arbitrary dimension.

-- 
Raul

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

Reply via email to