cs450a03@uc780.umd.edu (04/15/91)
Eythan Weg > A Analla >*** >*** Could some please suggest a generic function to reorder each column >*** of an array in descending order where the array is two dimensional. > [paraphrased slightly] in J, use \:"1&.|:~ array >Incidentally, how does one write this function in APL2? In APL2, you could write a function to do sorting: _ V R <- F Y _ R <- Y[gradedown Y] V then do: transpose mix F each split[quadIO] array You might be able to do something with mix and brackets to avoid the transpose, but I don't know what exactly, off the top of my head. Raul Rockwell
weg@convx1.ccit.arizona.edu (Eythan Weg) (04/15/91)
In article <13APR91.22583472@uc780.umd.edu> cs450a03@uc780.umd.edu (Raul Rockwell) writes: A Analla writes: >Could some please suggest a generic function to reorder each column >of an array in descending order where the array is two dimensional. >I would prefer the solution not be iterative and not require breaking >the columns into separate vectors. Well, in general, if you want to order the columns independently, you are already treating them as separate vectors. If you are using J, I'd suggest something like: \:"1&.|: array [... stuff deleted ] I would think to add just a small ~ in front of array. Without it, you will get the permutations for such reorderings. Raul Rockwell Incidentally, how does one write this function in APL2? Eythan Weg
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (04/17/91)
cs450a03@uc780.umd.edu writes: >>Incidentally, how does one write this function in APL2? > you could write a function F to sort vector >then do: > transpose mix F each split[quadIO] array >You might be able to do something with mix and brackets to avoid the >transpose, but I don't know what exactly, off the top of my head. >Raul Rockwell Easy mix[K] is the left inverse of split[K], so just mix[#IO] F" split[#IO] A. Greg Jaxon
weg@convx1.ccit.arizona.edu (Eythan Weg) (04/18/91)
In article <1991Apr17.151913.4891@csrd.uiuc.edu> jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) writes: cs450a03@uc780.umd.edu writes: >>Incidentally, how does one write this function in APL2? > you could write a function F to sort vector >then do: > transpose mix F each split[quadIO] array >You might be able to do something with mix and brackets to avoid the >transpose, but I don't know what exactly, off the top of my head. >Raul Rockwell Easy mix[K] is the left inverse of split[K], so just mix[#IO] F" split[#IO] A. Greg Jaxon Is this solution correct? Don't you have to insert a new first dimension and therefore the axis for mix should be fractional? Underlying my original question regarding the APL2 method is the sense that you often need auxiliary functions where in J you can do without. Is this a general feeling? Now often you need a subroutine that in J can be part of a main verb, not cluttering the workspace. It pleases me aesthetically that you can work this way. I wonder if using internal or external subroutines have different implications regarding performance. Eythan Weg
cs450a03@uc780.umd.edu (04/18/91)
Ethyn Weg writes; >Underlying my original question regarding the APL2 method is the sense >that you often need auxiliary functions where in J you can do without. >Is this a general feeling? Now often you need a subroutine that in J >can be part of a main verb, not cluttering the workspace. J has a number of design features that allow you to create and use auxiliary functions in-place. Not the least of which is indexing as a function, rather than a syntactic special case. I'd say that in APL2, functions are second rate objects (and operators are third rate). > It pleases me aesthetically that you can work this way. I wonder if >using internal or external subroutines have different implications >regarding performance. By external subroutines do you mean functions bound to a name, as opposed to functions defined dynamically? I think if the problem you are working on can be expressed more concisely, you'd probably also see performance implications. (I'm thinking specifically of language manipulation routines, such as symbolic math routines and partial evaluators such as compilers). Just an opinion though, at this stage. Raul Rockwell
rjfrey@kepler.com (Robert J Frey) (04/18/91)
In article <WEG.91Apr14120440@convx1.convx1.ccit.arizona.edu> weg@convx1.ccit.arizona.edu (Eythan Weg) writes: >In article <13APR91.22583472@uc780.umd.edu> cs450a03@uc780.umd.edu >(Raul Rockwell) writes: > > > A Analla writes: > > >Could some please suggest a generic function to reorder each column > >of an array in descending order where the array is two dimensional. > >Incidentally, how does one write this function in APL2? > >Eythan Weg In Dyalog APL, which is similar to APL2, one could do: A[; gradedown rotate A] This would generalize to simple arrays, character or numeric, of any dimension. If this use of grade(down/up) generalizes like this in APL2, then I might try: A[; gradedown[1] A] because (from what I remember) APL2 is rather general in its use of the axis "operator". I don't know if this last bit works, however. In vanilla APL there are some cases that can be handled pretty simply. For example, if A is a 5 by 10 numeric matrix whose elements are all positive numbers less than or equal to 100, then this does the job: A[; gradedown(5 reshape 100)decode A] This last "solution" has some serious overflow and truncation problems if A results in decoded values which are too large.
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (04/19/91)
>> mix[K] is the left inverse of split[K], so just mix[#IO] F" split[#IO] A. >Is this solution correct? Don't you have to insert a new first dimension >and therefore the axis for mix should be fractional? The axes given to Mix (aka Disclose) name the NEW axs in the result array which will hold the axes of the items of the argument array. If you split them out with enclose[K], you can put them back with disclose[K]. >Underlying my original question regarding the APL2 method is the sense >that you often need auxiliary functions where in J you can do without. >Is this a general feeling? I've only been really annoyed by Indexing not being a 'function' and by '/' no longer being a function. In the sort problem, we only need the auxillary function for the indexing step, call it INX: mix[#IO] INX" grdn" split[#IO] A > I wonder if using >internal or external subroutines have different implications >regarding performance. >Eythan Weg Some: there's less hope of optimizing across the routine boundary. In APLB we found an efficient way to drive user-defined functions under control of primitive operators that made simple fns like INX 10 times faster when driven by (e.g.) the Each operator, than they are when driven by an equivalent loop. - We only enter and exit INX once! Robert Frey suggests: > A[; grdn rotate A] (surely you mean transpose, not rotate/reverse) > A[; grdn[1] A] I'm not sure about the last one, but in either case one permutation vector is being applied to all the columns, the question asks for the columns to be individually sorted so that each one is in descending order. To turn the philosophy discussion around, what do you think about doing the split and mix steps up in the user-accessible data domain? I kind of like seeing those intermediate data organizations, it gives me a handle on what I need to do next. In dictionary APL (and I think in J), more of this work is done silently inside the rank operator, where I'll grant you it can be a lot more efficient; but much more obscure! Greg Jaxon
rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) (04/20/91)
In article <1991Apr17.151913.4891@csrd.uiuc.edu> jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) writes: >cs450a03@uc780.umd.edu writes: > >>>Incidentally, how does one write this function in APL2? >> you could write a function F to sort vector >>then do: >> transpose mix F each split[quadIO] array >>You might be able to do something with mix and brackets to avoid the >>transpose, but I don't know what exactly, off the top of my head. >>Raul Rockwell > This seems to reflect the basic difference in theology between APL2 and the SHARP APL/J world: APL2 uses split or partitioned enclose to create an array of arrays, applies some operation at one level down to each of those results, then uses mix or disclose to restore the data to its original depth. J and SAPL consider the operation to be defined on arrays of some particular rank, and then extends to higher rank arrays in a uniform manner. The Rank conjunction is used with these operations, when needed, to modidy that behavior. Effectively, J applies a different operation to the same data. APL2 applies the same function to different data. I believe that J is going to be easier to optimize for better performance in this area, having done some of that optimization for SHARP APL in the dim past. Robert Bernecky rbe@yrloc.ipsa.reuter.com bernecky@itrchq.itrc.on.ca Snake Island Research Inc (416) 368-6944 FAX: (416) 360-4694 18 Fifth Street, Ward's Island Toronto, Ontario M5J 2B9 Canada
cs450a03@uc780.umd.edu (04/20/91)
Greg Jaxon writes: >To turn the philosophy discussion around, what do you think about >doing the split and mix steps up in the user-accessible data domain? >I kind of like seeing those intermediate data organizations, it gives >me a handle on what I need to do next. I don't think that is much of an issue at all. What I find most annoying about split is that it always forces me to deal with vectors. >In dictionary APL (and I think in J), more of this work is done >silently inside the rank operator, where I'll grant you it can be a >lot more efficient; but much more obscure! Obscure is in the mind of the beholder ;-) Personally, I find the J forms _easier_ to remember, because they have (to me) more of an internal consistency. Also, you can do real well visualising J operators by using innocuous functions like < or ] to see what's happening structurally. Raul Rockwell
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (04/22/91)
> What I find most >annoying about split is that it always forces me to deal with vectors. >Raul Rockwell What are you talking about? Split can accept any positive rank and return any lower rank array, it can even permute axes when splitting them out. Greg Jaxon
rjfrey@kepler.com (Robert J Frey) (04/23/91)
In article <1991Apr19.145007.2201@csrd.uiuc.edu> jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) writes: > >Robert Frey suggests: >> A[; grdn rotate A] (surely you mean transpose, not rotate/reverse) >I'm not sure about the last one, but in either case one permutation >vector is being applied to all the columns, the question asks for >the columns to be individually sorted so that each one is in descending >order. > Hmmm! You sure *are* right; I did mean transpose. As for the original question, I did interpet it to mean sorting the columns as entities, and rereading it, it still looks like it could be taken that way. Your statement "... the columns to be individually sorted ..." isn't ambiguous, though. Without a rank operator or a very general axis "operator" I don't see how most APL's could avoid breaking the array into separate columns, at least implicitly as in "SORTED_ARRAY assign mix[0.1] sort foreach split[1] ARRAY" where the "sort" function is defined in the obvious way.
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (04/27/91)
rjfrey@kepler.com (Robert J Frey) writes: >Without a rank operator or a very general axis "operator" I don't see how most >APL's could avoid breaking the array into separate columns It's horridly inefficient, but you could: $ Z is COLUMN_SORT A;#IO;#CT;T [1] #IO is #CT is 0 [2] T is reverse rho A [3] Z is grdn A is ,A [4] Z is A[transpose T rho Z[grup T[0]|Z]] $ in any ISO standard APL. >SORTED_ARRAY assign mix[0.1] sort foreach split[1] ARRAY This keeps coming up ^^^ does some APL actually define mix using fractional axis numbers? mix[#IO] sort" split[#IO]. This is a good pattern to know just generally, because it covers most uses of the J (APL Dictionary) rank operator.