rrr@hpdmd48.boi.hp.com (Rudi Rynders) (05/09/91)
/ hpdmd48:comp.lang.apl / kingsley@hpwrce.HP.COM (Kingsley Morse) / 1:05 pm May 8, 1991 / Does anyone know how to do this other than writing a loop? Given a matrix M = 1 2 3 4 5 6 and a vector V = 7 8 I'd like to multiply 1 2 3 by 7, and multiply 4 5 6 by 8. In other words: 1 2 3 x 7 4 5 6 8 The result will be 7 14 21 32 40 48 Instead of writing a loop to do this, does APL have a more concise way? ----------
rrr@hpdmd48.boi.hp.com (Rudi Rynders) (05/09/91)
/ hpdmd48:comp.lang.apl / rrr@hpdmd48.boi.hp.com (Rudi Rynders) / 7:57 am May 9, 1991 / / hpdmd48:comp.lang.apl / kingsley@hpwrce.HP.COM (Kingsley Morse) / 1:05 pm May 8, 1991 / Does anyone know how to do this other than writing a loop? Given a matrix M = 1 2 3 4 5 6 and a vector V = 7 8 I'd like to multiply 1 2 3 by 7, and multiply 4 5 6 by 8. In other words: 1 2 3 x 7 4 5 6 8 The result will be 7 14 21 32 40 48 Instead of writing a loop to do this, does APL have a more concise way? ---------- ----------
rrr@hpdmd48.boi.hp.com (Rudi Rynders) (05/09/91)
Sorry for the spurious previous responses, I flubbed with my editor. I would convert the vector V = 7 8 to a matrix the same size as M and fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8 and then multiply M by VM to get the desired answer. Rudi Rynders (rrr@hpdmd48.boi.hp.com)
kingsley@hpwrce.HP.COM (Kingsley Morse) (05/15/91)
Thank you for replying, Rudi. Here's another solution that works with STSC's APLII for the 386. ^^M,.xV This is the inner product. (I'm writing this from memory; I may have reversed M and V. Now that I think about it, the inner dimensions of M and V are supposed to be the same.) Anyway, first each column of M is multiplied by the corresponding element in V, then each row of that result is catenated with the ",". Because the inner product syntax requires two functions, one before and one after the ".", I used the "," to avoid changing the results of the multiplication, but for some reason, the result of M,.xV is a doubly nested array. The "^" character in the first example is supposed to be an up arrow which means "un-nest this" in STSC's APLII for the 386. I had to un-nest the result twice.
ljdickey@watmath.waterloo.edu (L.J.Dickey) (05/15/91)
In article <15160018@hpdmd48.boi.hp.com> rrr@hpdmd48.boi.hp.com (Rudi Rynders) writes: ... >I would convert the vector V = 7 8 to a matrix the same size as M and >fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8 >and then multiply M by VM to get the desired answer. And, If you choose to use J, you could write M * |: (|. $ M) $ V or in APL, you could do the same thing because |: (|. $ M) $ V is transpose ( reverse rho M) reshape V -- Prof L.J. Dickey, Faculty of Mathematics, U of Waterloo, Canada N2L 3G1 internet: ljdickey@watmath.UWaterloo.ca BITNET/EARN: ljdickey@watdcs obsolescent?: ljdickey@watmath.waterloo.edu UUCP: ljdickey@watmath.UUCP ..!uunet!watmath!ljdickey
hui@yrloc.ipsa.reuter.COM (Roger Hui) (05/15/91)
Rudi Rynders) writes: > Does anyone know how to do this other than writing a loop? Given a matrix > M = 1 2 3 > 4 5 6 > and a vector > V = 7 8 > I'd like to multiply 1 2 3 by 7, and multiply 4 5 6 by 8. In other words: > 1 2 3 x 7 > 4 5 6 8 > The result will be > 7 14 21 > 32 40 48 > Instead of writing a loop to do this, does APL have a more concise way? And he writes subsequently, > Sorry for the spurious previous responses, I flubbed with my editor. > I would convert the vector V = 7 8 to a matrix the same size as M and > fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8 > and then multiply M by VM to get the desired answer. Alternatively, in J, one could write M *"1 0 V . The rank conjunction (") modifies times (*) to work on rank 1 objects on the left and rank 0 objects on the right; that is, multiply vectors of M by scalars of V. Alternatively, one could write M *"_1 V ; that is, multiply items of M by items of V. ----------------------------------------------------------------- Roger Hui Iverson Software Inc., 33 Major Street, Toronto, Ontario M5S 2K9 (416) 925 6096
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (05/15/91)
rrr@hpdmd48.boi.hp.com (Rudi Rynders) writes (I paraphase): >I'd like to 1 2 3 x 7 and get 7 14 21 > 4 5 6 8 32 40 48 >Instead of writing a loop to do this, does APL have a more concise way? We used to call this "Middle Product". In 1973 APL/700's dyadic scalar primitives let you name one axis along which the 'replication' would occur. By default it replicated along the last axis, so MxV would get your answer. APL2 and APLB use the same syntax (axis brackets after the 'x') to name the (one or more) axes in the higher rank argument where the axes of the lower rank argument can be found. (Length 2 vectors are found along the first axis of a 2x3 matrix.) So in these languages you'd say M x[#IO] V. APLB (I'm not sure about APL2) also does a Middle Product operation without axis brackets, it tries to match the trailing axes of its arguments, so transpose V x transpose M would also work, at higher cost. The axis specification only affects the top level of nesting when 'x' is applied as a pervasive function to a pair of nested arrays. To affect deeper levels of the nest, APLB applied this definition of axis bracket, and this default defn to the Each operator. So you'd give bracket specifiers for each level of the nest, and apply them to the primitive and n-1 levels of Each. Needless to say, these are not ISO standard definitions, and axis brackets are considered clumsy in the new streamlined syntax of J. Regards, Greg Jaxon
weg@convx1.ccit.arizona.edu (Eythan Weg) (05/16/91)
In article <1991May15.120900.15736@watmath.waterloo.edu> ljdickey@watmath.waterloo.edu (L.J.Dickey) writes: In article <15160018@hpdmd48.boi.hp.com> rrr@hpdmd48.boi.hp.com (Rudi Rynders) writes: ... >I would convert the vector V = 7 8 to a matrix the same size as M and >fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8 >and then multiply M by VM to get the desired answer. And, If you choose to use J, you could write M * |: (|. $ M) $ V In J I would write M*"1 0 V. Eythan
monardo@cshl.org (Pat Monardo) (05/17/91)
In article <1991May15.134305.10894@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.reuter.COM (Roger Hui) writes: > >Alternatively, in J, one could write M *"1 0 V . The rank conjunction >(") modifies times (*) to work on rank 1 objects on the left and rank 0 >objects on the right; that is, multiply vectors of M by scalars of V. > >Alternatively, one could write M *"_1 V ; that is, multiply items of M >by items of V. amen. and the absurdity of the previous posts should make them reconsider whether the APL they speak has any value at all.
rockwell@socrates.umd.edu (Raul Rockwell) (05/17/91)
Pat Monardo: amen. and the absurdity of the previous posts should make them reconsider whether the APL they speak has any value at all. ahem. Much as I like J, I must point out that APL (and even that FORTRAN or C language :-) does have some value. Specifically, APL runs on my machine, and the machine we use at work. Also, APL runs quite fast (at least the APL we use). I expect that J will *eventually* run APL into the dirt, speedwise, because J seems to be a simpler language, at heart. (And because there is some pretty good talent interested in making J available.) However as things presently stand APL has quite a bit of value that J lacks. (And even when J stablizes and runs fast, there will be people sticking with APL because that's what their applications run in -- and that's nothing compared to people sticking to COBOL for the same reasons). In the words of the famous philosopher: Lighten up, eh? People were having fun. Raul Rockwell
monardo@cshl.org (Pat Monardo) (05/17/91)
In article <ROCKWELL.91May17075620@socrates.umd.edu> rockwell@socrates.umd.edu (Raul Rockwell) writes: > >In the words of the famous philosopher: Lighten up, eh? People were >having fun. > i didnt really intend to be a sour puss. that's not how i am. in fact i dont use APL in any form at all. so i must admit that details of implementations or speed or availability mean nothing to me. just the thought processes (I think about apl a little). maybe i should learn what the 1/2 axis is all about? not! :)
rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) (05/18/91)
In article <1991May17.031707.27992@cshl.org> monardo@cshl.org (Pat Monardo) writes: >In article <1991May15.134305.10894@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.reuter.COM (Roger Hui) writes: >> >>Alternatively, in J, one could write M *"1 0 V . The rank conjunction >>(") modifies times (*) to work on rank 1 objects on the left and rank 0 >>objects on the right; that is, multiply vectors of M by scalars of V. >> >>Alternatively, one could write M *"_1 V ; that is, multiply items of M >>by items of V. > >amen. and the absurdity of the previous posts should make them >reconsider whether the APL they speak has any value at all. Perhaps we should be a bit gentler, and just suggest that those APL dialects of yore have failed to adopt general principles of extension, and have added special cases for many primitives instead, following the lead of the Fortran 90 designers... I think the key to J and rank is that the SAME expression works for ANY verb, whether primitive or user-defined. This is what sets it apart from APL2 and other such dialects of APL. This makes the language easier to learn and use than APL2, simpler to implement, and more general. For example, I think one of the APL2 gurus suggested adding vectors to matrix rows by doing (pardon me if I get this wrong, please) v+[1]m. Swell. Now, replace the + with a user-defined function whose only contents is +, and tell me why: v foo[1] m doesn't work. 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
jaxon@sp27.csrd.uiuc.edu (Greg P. Jaxon) (05/22/91)
rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) writes: >Perhaps we should be a bit gentler, and just suggest that those APL dialects >of yore have failed to adopt general principles of extension, and have >added special cases for many primitives instead, following the lead >of the Fortran 90 designers... I don't see any 'failure' in the quest for generality in 'APLs of yore'. Neither do I see very many 'special case' inventions, although sometimes in a complex web of design issues a general plan is only deliverable in the form of special cases. Axis brackets and index brackets turn out to be clumsy syntax in a pure realm of applicative programming, and the rank operator is an admirable invention. Of course it can be adopted directly into APL, but its usefulness as a language component comes partly from how all its companion primitives are defined. And so it lives most comfortably in J. APL could become J? -- No, the design of APL is essentially complete, the design space split into the APL2 and Dictionary variants, which explored DIFFERENT design goals, both succeeded at their goals to the extent possible within the existing framework of APL. Who was following Fortran 90, Bob? No one I was talking to! APL users could become J users. -- Yup some will, maybe J will be so good that most APLers will switch. That's the way languages and marketplaces evolve. >I think the key to J and rank is that the SAME expression works for ANY >verb, whether primitive or user-defined. This is what sets it apart from >APL2 and other such dialects of APL. This makes the language easier to >learn and use than APL2, simpler to implement, and more general. >For example, I think one of the APL2 gurus suggested adding vectors to >matrix rows by doing (pardon me if I get this wrong, please) v+[1]m. >Swell. Now, replace the + with a user-defined function whose only contents >is +, and tell me why: v foo[1] m doesn't work. The early APL2 prototype defined an axis operator that used the syntax you suggest, and I believe supplied the definition you expect. APL2 was most relentless in introducing the 'principle of substitutability' into the APL language design, so your point has not been lost. I don't think that SUBSTITUTABILITY between primitive things and user-defined things is 'what sets J apart from APL2'. I'd answer that APLB provides two ways for a user to write a 'function whose only contents is +'. 1) $Z is A FOO B [1] Z is A + B$ and then inform the interpreter that its 'rank is 0 0 0' by writing FOO" for +. In APLB, V FOO"[1] M <-> V+"[1]M <-> V+[1]M. 2) Pass + as an operand to a user-defined operator $Z is V (FOO GOO) M. When you say V +GOO M FOO becomes +, and can be treated in the same way that + can. So on line [1] of this operator (or suspended inside it) you can utter the magical incantation V FOO[1] M and get the Middle Product feature built into + to do your work. The issues were not just syntax and its extendability... (P.S. Dave Liebtag: Can APL2 do these two things?) When I was at work on these things the language treated primitives differently from user-defined things because it could know more about the properties of the primitive's definition. It could know the 'rank' in the J sense. It could know the 'identity function', and whether the function was associative, commutative, etc. Rather than ignore these important properties when definining the operators, APL2 was willing to use them where they were available, and wait for a language extension (like rank) that would help a user include these properties when defining his/her own functions. Axis is a syntactic lemon. It'll never make bordeaux wine, but it can make lemonade! Greg Jaxon