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
